cumulus_client_parachain_inherent/
lib.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Cumulus.
3
4// Cumulus is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Cumulus is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Client side code for generating the parachain inherent.
18
19use codec::Decode;
20use cumulus_primitives_core::{
21	relay_chain::{self, Hash as PHash, HrmpChannelId},
22	ParaId, PersistedValidationData,
23};
24use cumulus_relay_chain_interface::RelayChainInterface;
25
26mod mock;
27
28pub use cumulus_primitives_parachain_inherent::{ParachainInherentData, INHERENT_IDENTIFIER};
29pub use mock::{MockValidationDataInherentDataProvider, MockXcmConfig};
30
31const LOG_TARGET: &str = "parachain-inherent";
32
33/// Collect the relevant relay chain state in form of a proof for putting it into the validation
34/// data inherent.
35async fn collect_relay_storage_proof(
36	relay_chain_interface: &impl RelayChainInterface,
37	para_id: ParaId,
38	relay_parent: PHash,
39) -> Option<sp_state_machine::StorageProof> {
40	use relay_chain::well_known_keys as relay_well_known_keys;
41
42	let ingress_channels = relay_chain_interface
43		.get_storage_by_key(
44			relay_parent,
45			&relay_well_known_keys::hrmp_ingress_channel_index(para_id),
46		)
47		.await
48		.map_err(|e| {
49			tracing::error!(
50				target: LOG_TARGET,
51				relay_parent = ?relay_parent,
52				error = ?e,
53				"Cannot obtain the hrmp ingress channel."
54			)
55		})
56		.ok()?;
57
58	let ingress_channels = ingress_channels
59		.map(|raw| <Vec<ParaId>>::decode(&mut &raw[..]))
60		.transpose()
61		.map_err(|e| {
62			tracing::error!(
63				target: LOG_TARGET,
64				error = ?e,
65				"Cannot decode the hrmp ingress channel index.",
66			)
67		})
68		.ok()?
69		.unwrap_or_default();
70
71	let egress_channels = relay_chain_interface
72		.get_storage_by_key(
73			relay_parent,
74			&relay_well_known_keys::hrmp_egress_channel_index(para_id),
75		)
76		.await
77		.map_err(|e| {
78			tracing::error!(
79				target: LOG_TARGET,
80				error = ?e,
81				"Cannot obtain the hrmp egress channel.",
82			)
83		})
84		.ok()?;
85
86	let egress_channels = egress_channels
87		.map(|raw| <Vec<ParaId>>::decode(&mut &raw[..]))
88		.transpose()
89		.map_err(|e| {
90			tracing::error!(
91				target: LOG_TARGET,
92				error = ?e,
93				"Cannot decode the hrmp egress channel index.",
94			)
95		})
96		.ok()?
97		.unwrap_or_default();
98
99	let mut relevant_keys = vec![
100		relay_well_known_keys::CURRENT_BLOCK_RANDOMNESS.to_vec(),
101		relay_well_known_keys::ONE_EPOCH_AGO_RANDOMNESS.to_vec(),
102		relay_well_known_keys::TWO_EPOCHS_AGO_RANDOMNESS.to_vec(),
103		relay_well_known_keys::CURRENT_SLOT.to_vec(),
104		relay_well_known_keys::ACTIVE_CONFIG.to_vec(),
105		relay_well_known_keys::dmq_mqc_head(para_id),
106		// TODO paritytech/polkadot#6283: Remove all usages of `relay_dispatch_queue_size`
107		// We need to keep this here until all parachains have migrated to
108		// `relay_dispatch_queue_remaining_capacity`.
109		#[allow(deprecated)]
110		relay_well_known_keys::relay_dispatch_queue_size(para_id),
111		relay_well_known_keys::relay_dispatch_queue_remaining_capacity(para_id).key,
112		relay_well_known_keys::hrmp_ingress_channel_index(para_id),
113		relay_well_known_keys::hrmp_egress_channel_index(para_id),
114		relay_well_known_keys::upgrade_go_ahead_signal(para_id),
115		relay_well_known_keys::upgrade_restriction_signal(para_id),
116		relay_well_known_keys::para_head(para_id),
117	];
118	relevant_keys.extend(ingress_channels.into_iter().map(|sender| {
119		relay_well_known_keys::hrmp_channels(HrmpChannelId { sender, recipient: para_id })
120	}));
121	relevant_keys.extend(egress_channels.into_iter().map(|recipient| {
122		relay_well_known_keys::hrmp_channels(HrmpChannelId { sender: para_id, recipient })
123	}));
124
125	relay_chain_interface
126		.prove_read(relay_parent, &relevant_keys)
127		.await
128		.map_err(|e| {
129			tracing::error!(
130				target: LOG_TARGET,
131				relay_parent = ?relay_parent,
132				error = ?e,
133				"Cannot obtain read proof from relay chain.",
134			);
135		})
136		.ok()
137}
138
139pub struct ParachainInherentDataProvider;
140
141impl ParachainInherentDataProvider {
142	/// Create the [`ParachainInherentData`] at the given `relay_parent`.
143	///
144	/// Returns `None` if the creation failed.
145	pub async fn create_at(
146		relay_parent: PHash,
147		relay_chain_interface: &impl RelayChainInterface,
148		validation_data: &PersistedValidationData,
149		para_id: ParaId,
150	) -> Option<ParachainInherentData> {
151		let relay_chain_state =
152			collect_relay_storage_proof(relay_chain_interface, para_id, relay_parent).await?;
153
154		let downward_messages = relay_chain_interface
155			.retrieve_dmq_contents(para_id, relay_parent)
156			.await
157			.map_err(|e| {
158				tracing::error!(
159					target: LOG_TARGET,
160					relay_parent = ?relay_parent,
161					error = ?e,
162					"An error occurred during requesting the downward messages.",
163				);
164			})
165			.ok()?;
166		let horizontal_messages = relay_chain_interface
167			.retrieve_all_inbound_hrmp_channel_contents(para_id, relay_parent)
168			.await
169			.map_err(|e| {
170				tracing::error!(
171					target: LOG_TARGET,
172					relay_parent = ?relay_parent,
173					error = ?e,
174					"An error occurred during requesting the inbound HRMP messages.",
175				);
176			})
177			.ok()?;
178
179		Some(ParachainInherentData {
180			downward_messages,
181			horizontal_messages,
182			validation_data: validation_data.clone(),
183			relay_chain_state,
184		})
185	}
186}