mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 04:41:03 +00:00
Move parachain inherent data into its own crate (#326)
This renames and moves the `SystemInherentData` into its own crate. The struct is now called `ParachainInherentData`. Besides moving the struct, this also moves the code for creating this struct into this crate.
This commit is contained in:
Generated
+20
-2
@@ -1075,6 +1075,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cumulus-client-network",
|
"cumulus-client-network",
|
||||||
"cumulus-primitives-core",
|
"cumulus-primitives-core",
|
||||||
|
"cumulus-primitives-parachain-inherent",
|
||||||
"cumulus-test-client",
|
"cumulus-test-client",
|
||||||
"cumulus-test-runtime",
|
"cumulus-test-runtime",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
@@ -1188,6 +1189,7 @@ name = "cumulus-pallet-parachain-system"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cumulus-primitives-core",
|
"cumulus-primitives-core",
|
||||||
|
"cumulus-primitives-parachain-inherent",
|
||||||
"cumulus-test-client",
|
"cumulus-test-client",
|
||||||
"cumulus-test-relay-sproof-builder",
|
"cumulus-test-relay-sproof-builder",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
@@ -1241,18 +1243,34 @@ dependencies = [
|
|||||||
"polkadot-core-primitives",
|
"polkadot-core-primitives",
|
||||||
"polkadot-parachain",
|
"polkadot-parachain",
|
||||||
"polkadot-primitives",
|
"polkadot-primitives",
|
||||||
"sp-core",
|
|
||||||
"sp-inherents",
|
|
||||||
"sp-runtime",
|
"sp-runtime",
|
||||||
"sp-std",
|
"sp-std",
|
||||||
"sp-trie",
|
"sp-trie",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cumulus-primitives-parachain-inherent"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"cumulus-primitives-core",
|
||||||
|
"parity-scale-codec",
|
||||||
|
"sc-client-api",
|
||||||
|
"sp-api",
|
||||||
|
"sp-core",
|
||||||
|
"sp-inherents",
|
||||||
|
"sp-runtime",
|
||||||
|
"sp-state-machine",
|
||||||
|
"sp-std",
|
||||||
|
"sp-trie",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cumulus-test-client"
|
name = "cumulus-test-client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cumulus-primitives-core",
|
"cumulus-primitives-core",
|
||||||
|
"cumulus-primitives-parachain-inherent",
|
||||||
"cumulus-test-relay-sproof-builder",
|
"cumulus-test-relay-sproof-builder",
|
||||||
"cumulus-test-runtime",
|
"cumulus-test-runtime",
|
||||||
"cumulus-test-service",
|
"cumulus-test-service",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ members = [
|
|||||||
"pallets/parachain-system",
|
"pallets/parachain-system",
|
||||||
"pallets/xcm-handler",
|
"pallets/xcm-handler",
|
||||||
"primitives/core",
|
"primitives/core",
|
||||||
|
"primitives/parachain-inherent",
|
||||||
"rococo-parachains/",
|
"rococo-parachains/",
|
||||||
"rococo-parachains/pallets/parachain-info",
|
"rococo-parachains/pallets/parachain-info",
|
||||||
"rococo-parachains/primitives",
|
"rococo-parachains/primitives",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ polkadot-node-subsystem = { git = "https://github.com/paritytech/polkadot", bran
|
|||||||
# Cumulus dependencies
|
# Cumulus dependencies
|
||||||
cumulus-client-network = { path = "../network" }
|
cumulus-client-network = { path = "../network" }
|
||||||
cumulus-primitives-core = { path = "../../primitives/core" }
|
cumulus-primitives-core = { path = "../../primitives/core" }
|
||||||
|
cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent" }
|
||||||
|
|
||||||
# Other dependencies
|
# Other dependencies
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
|
|||||||
@@ -18,10 +18,9 @@
|
|||||||
|
|
||||||
use cumulus_client_network::WaitToAnnounce;
|
use cumulus_client_network::WaitToAnnounce;
|
||||||
use cumulus_primitives_core::{
|
use cumulus_primitives_core::{
|
||||||
inherents, ParachainBlockData,
|
well_known_keys, OutboundHrmpMessage, ParachainBlockData, PersistedValidationData,
|
||||||
well_known_keys, InboundDownwardMessage, InboundHrmpMessage, OutboundHrmpMessage,
|
|
||||||
PersistedValidationData, relay_chain,
|
|
||||||
};
|
};
|
||||||
|
use cumulus_primitives_parachain_inherent::ParachainInherentData;
|
||||||
|
|
||||||
use sc_client_api::{BlockBackend, StateBackend};
|
use sc_client_api::{BlockBackend, StateBackend};
|
||||||
use sp_consensus::{
|
use sp_consensus::{
|
||||||
@@ -41,7 +40,7 @@ use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProt
|
|||||||
use polkadot_overseer::OverseerHandler;
|
use polkadot_overseer::OverseerHandler;
|
||||||
use polkadot_primitives::v1::{
|
use polkadot_primitives::v1::{
|
||||||
Block as PBlock, BlockData, BlockNumber as PBlockNumber, CollatorPair, Hash as PHash, HeadData,
|
Block as PBlock, BlockData, BlockNumber as PBlockNumber, CollatorPair, Hash as PHash, HeadData,
|
||||||
Id as ParaId, PoV, UpwardMessage, HrmpChannelId,
|
Id as ParaId, PoV, UpwardMessage,
|
||||||
};
|
};
|
||||||
use polkadot_service::RuntimeApiCollection;
|
use polkadot_service::RuntimeApiCollection;
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ use log::{debug, error, info, trace};
|
|||||||
|
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
|
|
||||||
use std::{collections::BTreeMap, marker::PhantomData, sync::Arc, time::Duration};
|
use std::{marker::PhantomData, sync::Arc, time::Duration};
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
@@ -101,10 +100,10 @@ where
|
|||||||
PF: Environment<Block> + 'static + Send,
|
PF: Environment<Block> + 'static + Send,
|
||||||
PF::Proposer: Send,
|
PF::Proposer: Send,
|
||||||
BI: BlockImport<
|
BI: BlockImport<
|
||||||
Block,
|
Block,
|
||||||
Error = ConsensusError,
|
Error = ConsensusError,
|
||||||
Transaction = <PF::Proposer as Proposer<Block>>::Transaction,
|
Transaction = <PF::Proposer as Proposer<Block>>::Transaction,
|
||||||
> + Send
|
> + Send
|
||||||
+ Sync
|
+ Sync
|
||||||
+ 'static,
|
+ 'static,
|
||||||
BS: BlockBackend<Block>,
|
BS: BlockBackend<Block>,
|
||||||
@@ -150,161 +149,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the whole contents of the downward message queue for the parachain we are collating
|
|
||||||
/// for.
|
|
||||||
///
|
|
||||||
/// Returns `None` in case of an error.
|
|
||||||
fn retrieve_dmq_contents(&self, relay_parent: PHash) -> Option<Vec<InboundDownwardMessage>> {
|
|
||||||
self.polkadot_client
|
|
||||||
.runtime_api()
|
|
||||||
.dmq_contents_with_context(
|
|
||||||
&BlockId::hash(relay_parent),
|
|
||||||
sp_core::ExecutionContext::Importing,
|
|
||||||
self.para_id,
|
|
||||||
)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"An error occured during requesting the downward messages for {}: {:?}",
|
|
||||||
relay_parent, e,
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns channels contents for each inbound HRMP channel addressed to the parachain we are
|
|
||||||
/// collating for.
|
|
||||||
///
|
|
||||||
/// Empty channels are also included.
|
|
||||||
fn retrieve_all_inbound_hrmp_channel_contents(
|
|
||||||
&self,
|
|
||||||
relay_parent: PHash,
|
|
||||||
) -> Option<BTreeMap<ParaId, Vec<InboundHrmpMessage>>> {
|
|
||||||
self.polkadot_client
|
|
||||||
.runtime_api()
|
|
||||||
.inbound_hrmp_channels_contents_with_context(
|
|
||||||
&BlockId::hash(relay_parent),
|
|
||||||
sp_core::ExecutionContext::Importing,
|
|
||||||
self.para_id,
|
|
||||||
)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"An error occured during requesting the inbound HRMP messages for {}: {:?}",
|
|
||||||
relay_parent, e,
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Collect the relevant relay chain state in form of a proof for putting it into the validation
|
|
||||||
/// data inherent.
|
|
||||||
fn collect_relay_storage_proof(
|
|
||||||
&self,
|
|
||||||
relay_parent: PHash,
|
|
||||||
) -> Option<sp_state_machine::StorageProof> {
|
|
||||||
use relay_chain::well_known_keys as relay_well_known_keys;
|
|
||||||
|
|
||||||
let relay_parent_state_backend = self
|
|
||||||
.polkadot_backend
|
|
||||||
.state_at(BlockId::Hash(relay_parent))
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"Cannot obtain the state of the relay chain at `{:?}`: {:?}",
|
|
||||||
relay_parent,
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()?;
|
|
||||||
|
|
||||||
let ingress_channels = relay_parent_state_backend
|
|
||||||
.storage(&relay_well_known_keys::hrmp_ingress_channel_index(
|
|
||||||
self.para_id,
|
|
||||||
))
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"Cannot obtain the hrmp ingress channel index: {:?}",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()?;
|
|
||||||
let ingress_channels = ingress_channels
|
|
||||||
.map(|raw| <Vec<ParaId>>::decode(&mut &raw[..]))
|
|
||||||
.transpose()
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"Cannot decode the hrmp ingress channel index: {:?}",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()?
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let egress_channels = relay_parent_state_backend
|
|
||||||
.storage(&relay_well_known_keys::hrmp_egress_channel_index(
|
|
||||||
self.para_id,
|
|
||||||
))
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"Cannot obtain the hrmp egress channel index: {:?}",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()?;
|
|
||||||
let egress_channels = egress_channels
|
|
||||||
.map(|raw| <Vec<ParaId>>::decode(&mut &raw[..]))
|
|
||||||
.transpose()
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"Cannot decode the hrmp egress channel index: {:?}",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()?
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let mut relevant_keys = vec![];
|
|
||||||
relevant_keys.push(relay_well_known_keys::ACTIVE_CONFIG.to_vec());
|
|
||||||
relevant_keys.push(relay_well_known_keys::dmq_mqc_head(self.para_id));
|
|
||||||
relevant_keys.push(relay_well_known_keys::relay_dispatch_queue_size(
|
|
||||||
self.para_id,
|
|
||||||
));
|
|
||||||
relevant_keys.push(relay_well_known_keys::hrmp_ingress_channel_index(
|
|
||||||
self.para_id,
|
|
||||||
));
|
|
||||||
relevant_keys.push(relay_well_known_keys::hrmp_egress_channel_index(
|
|
||||||
self.para_id,
|
|
||||||
));
|
|
||||||
relevant_keys.extend(ingress_channels.into_iter().map(|sender| {
|
|
||||||
relay_well_known_keys::hrmp_channels(HrmpChannelId {
|
|
||||||
sender,
|
|
||||||
recipient: self.para_id,
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
relevant_keys.extend(egress_channels.into_iter().map(|recipient| {
|
|
||||||
relay_well_known_keys::hrmp_channels(HrmpChannelId {
|
|
||||||
sender: self.para_id,
|
|
||||||
recipient,
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
|
|
||||||
sp_state_machine::prove_read(relay_parent_state_backend, relevant_keys)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"Failed to collect required relay chain state storage proof at `{:?}`: {:?}",
|
|
||||||
relay_parent,
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the inherent data with validation function parameters injected
|
/// Get the inherent data with validation function parameters injected
|
||||||
fn inherent_data(
|
fn inherent_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -317,36 +161,28 @@ where
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!(
|
error!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Failed to create inherent data: {:?}",
|
"Failed to create inherent data: {:?}", e,
|
||||||
e,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
let system_inherent_data = {
|
let parachain_inherent_data = ParachainInherentData::create_at(
|
||||||
let relay_chain_state = self.collect_relay_storage_proof(relay_parent)?;
|
relay_parent,
|
||||||
let downward_messages = self.retrieve_dmq_contents(relay_parent)?;
|
&*self.polkadot_client,
|
||||||
let horizontal_messages =
|
&*self.polkadot_backend,
|
||||||
self.retrieve_all_inbound_hrmp_channel_contents(relay_parent)?;
|
validation_data,
|
||||||
|
self.para_id,
|
||||||
inherents::SystemInherentData {
|
)?;
|
||||||
downward_messages,
|
|
||||||
horizontal_messages,
|
|
||||||
validation_data: validation_data.clone(),
|
|
||||||
relay_chain_state,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inherent_data
|
inherent_data
|
||||||
.put_data(
|
.put_data(
|
||||||
inherents::SYSTEM_INHERENT_IDENTIFIER,
|
cumulus_primitives_parachain_inherent::INHERENT_IDENTIFIER,
|
||||||
&system_inherent_data,
|
¶chain_inherent_data,
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!(
|
error!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Failed to put the system inherent into inherent data: {:?}",
|
"Failed to put the system inherent into inherent data: {:?}", e,
|
||||||
e,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.ok()?;
|
.ok()?;
|
||||||
@@ -371,8 +207,7 @@ where
|
|||||||
Ok(BlockStatus::InChainPruned) => {
|
Ok(BlockStatus::InChainPruned) => {
|
||||||
error!(
|
error!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Skipping candidate production, because block `{:?}` is already pruned!",
|
"Skipping candidate production, because block `{:?}` is already pruned!", hash,
|
||||||
hash,
|
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -394,8 +229,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
debug!(
|
debug!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Skipping candidate production, because block `{:?}` is unknown.",
|
"Skipping candidate production, because block `{:?}` is unknown.", hash,
|
||||||
hash,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
@@ -403,9 +237,7 @@ where
|
|||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Failed to get block status of `{:?}`: {:?}",
|
"Failed to get block status of `{:?}`: {:?}", hash, e,
|
||||||
hash,
|
|
||||||
e,
|
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -425,39 +257,45 @@ where
|
|||||||
let state = match self.backend.state_at(BlockId::Hash(block_hash)) {
|
let state = match self.backend.state_at(BlockId::Hash(block_hash)) {
|
||||||
Ok(state) => state,
|
Ok(state) => state,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(target: LOG_TARGET, "Failed to get state of the freshly built block: {:?}", e);
|
error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
"Failed to get state of the freshly built block: {:?}", e
|
||||||
|
);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
state.inspect_state(|| {
|
state.inspect_state(|| {
|
||||||
let upward_messages = sp_io::storage::get(well_known_keys::UPWARD_MESSAGES);
|
let upward_messages = sp_io::storage::get(well_known_keys::UPWARD_MESSAGES);
|
||||||
let upward_messages = match upward_messages.map(|v| Vec::<UpwardMessage>::decode(&mut &v[..])) {
|
let upward_messages =
|
||||||
Some(Ok(msgs)) => msgs,
|
match upward_messages.map(|v| Vec::<UpwardMessage>::decode(&mut &v[..])) {
|
||||||
Some(Err(e)) => {
|
Some(Ok(msgs)) => msgs,
|
||||||
error!(target: LOG_TARGET, "Failed to decode upward messages from the build block: {:?}", e);
|
Some(Err(e)) => {
|
||||||
return None
|
error!(
|
||||||
},
|
target: LOG_TARGET,
|
||||||
None => Vec::new(),
|
"Failed to decode upward messages from the build block: {:?}", e
|
||||||
};
|
);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
None => Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
let new_validation_code = sp_io::storage::get(well_known_keys::NEW_VALIDATION_CODE);
|
let new_validation_code = sp_io::storage::get(well_known_keys::NEW_VALIDATION_CODE);
|
||||||
|
|
||||||
let processed_downward_messages = sp_io::storage::get(well_known_keys::PROCESSED_DOWNWARD_MESSAGES);
|
let processed_downward_messages =
|
||||||
let processed_downward_messages = match processed_downward_messages
|
sp_io::storage::get(well_known_keys::PROCESSED_DOWNWARD_MESSAGES);
|
||||||
.map(|v| u32::decode(&mut &v[..]))
|
let processed_downward_messages =
|
||||||
{
|
match processed_downward_messages.map(|v| u32::decode(&mut &v[..])) {
|
||||||
Some(Ok(processed_cnt)) => processed_cnt,
|
Some(Ok(processed_cnt)) => processed_cnt,
|
||||||
Some(Err(e)) => {
|
Some(Err(e)) => {
|
||||||
error!(
|
error!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Failed to decode the count of processed downward messages: {:?}",
|
"Failed to decode the count of processed downward messages: {:?}", e
|
||||||
e
|
);
|
||||||
);
|
return None;
|
||||||
return None
|
}
|
||||||
}
|
None => 0,
|
||||||
None => 0,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let horizontal_messages = sp_io::storage::get(well_known_keys::HRMP_OUTBOUND_MESSAGES);
|
let horizontal_messages = sp_io::storage::get(well_known_keys::HRMP_OUTBOUND_MESSAGES);
|
||||||
let horizontal_messages = match horizontal_messages
|
let horizontal_messages = match horizontal_messages
|
||||||
@@ -467,10 +305,9 @@ where
|
|||||||
Some(Err(e)) => {
|
Some(Err(e)) => {
|
||||||
error!(
|
error!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Failed to decode the horizontal messages: {:?}",
|
"Failed to decode the horizontal messages: {:?}", e
|
||||||
e
|
|
||||||
);
|
);
|
||||||
return None
|
return None;
|
||||||
}
|
}
|
||||||
None => Vec::new(),
|
None => Vec::new(),
|
||||||
};
|
};
|
||||||
@@ -481,10 +318,9 @@ where
|
|||||||
Some(Err(e)) => {
|
Some(Err(e)) => {
|
||||||
error!(
|
error!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Failed to decode the HRMP watermark: {:?}",
|
"Failed to decode the HRMP watermark: {:?}", e
|
||||||
e
|
|
||||||
);
|
);
|
||||||
return None
|
return None;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// If the runtime didn't set `HRMP_WATERMARK`, then it means no messages were
|
// If the runtime didn't set `HRMP_WATERMARK`, then it means no messages were
|
||||||
@@ -514,14 +350,16 @@ where
|
|||||||
) -> Option<Collation> {
|
) -> Option<Collation> {
|
||||||
trace!(target: LOG_TARGET, "Producing candidate");
|
trace!(target: LOG_TARGET, "Producing candidate");
|
||||||
|
|
||||||
let last_head =
|
let last_head = match Block::Header::decode(&mut &validation_data.parent_head.0[..]) {
|
||||||
match Block::Header::decode(&mut &validation_data.parent_head.0[..]) {
|
Ok(x) => x,
|
||||||
Ok(x) => x,
|
Err(e) => {
|
||||||
Err(e) => {
|
error!(
|
||||||
error!(target: LOG_TARGET, "Could not decode the head data: {:?}", e);
|
target: LOG_TARGET,
|
||||||
return None;
|
"Could not decode the head data: {:?}", e
|
||||||
}
|
);
|
||||||
};
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let last_head_hash = last_head.hash();
|
let last_head_hash = last_head.hash();
|
||||||
if !self.check_block_status(last_head_hash, &last_head) {
|
if !self.check_block_status(last_head_hash, &last_head) {
|
||||||
@@ -539,13 +377,7 @@ where
|
|||||||
|
|
||||||
let proposer = proposer_future
|
let proposer = proposer_future
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| error!(target: LOG_TARGET, "Could not create proposer: {:?}", e,))
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"Could not create proposer: {:?}",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
let inherent_data = self.inherent_data(&validation_data, relay_parent)?;
|
let inherent_data = self.inherent_data(&validation_data, relay_parent)?;
|
||||||
@@ -563,13 +395,7 @@ where
|
|||||||
RecordProof::Yes,
|
RecordProof::Yes,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| error!(target: LOG_TARGET, "Proposing failed: {:?}", e,))
|
||||||
error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
"Proposing failed: {:?}",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
let proof = match proof {
|
let proof = match proof {
|
||||||
@@ -619,8 +445,7 @@ where
|
|||||||
b.storage_proof().encode().len() as f64 / 1024f64,
|
b.storage_proof().encode().len() as f64 / 1024f64,
|
||||||
);
|
);
|
||||||
|
|
||||||
let collation =
|
let collation = self.build_collation(b, block_hash, validation_data.relay_parent_number)?;
|
||||||
self.build_collation(b, block_hash, validation_data.relay_parent_number)?;
|
|
||||||
let pov_hash = collation.proof_of_validity.hash();
|
let pov_hash = collation.proof_of_validity.hash();
|
||||||
|
|
||||||
self.wait_to_announce
|
self.wait_to_announce
|
||||||
@@ -629,9 +454,7 @@ where
|
|||||||
|
|
||||||
info!(
|
info!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Produced proof-of-validity candidate {:?} from block {:?}.",
|
"Produced proof-of-validity candidate {:?} from block {:?}.", pov_hash, block_hash,
|
||||||
pov_hash,
|
|
||||||
block_hash,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Some(collation)
|
Some(collation)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ description = "Base pallet for cumulus-based parachains"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
# Cumulus dependencies
|
# Cumulus dependencies
|
||||||
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
|
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
|
||||||
|
cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent", default-features = false }
|
||||||
|
|
||||||
# Polkadot dependencies
|
# Polkadot dependencies
|
||||||
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, features = [ "wasm-api" ], branch = "master" }
|
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, features = [ "wasm-api" ], branch = "master" }
|
||||||
@@ -68,4 +69,5 @@ std = [
|
|||||||
"frame-system/std",
|
"frame-system/std",
|
||||||
"frame-executive/std",
|
"frame-executive/std",
|
||||||
"cumulus-primitives-core/std",
|
"cumulus-primitives-core/std",
|
||||||
|
"cumulus-primitives-parachain-inherent/std",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -28,13 +28,13 @@
|
|||||||
//! Users must ensure that they register this pallet as an inherent provider.
|
//! Users must ensure that they register this pallet as an inherent provider.
|
||||||
|
|
||||||
use cumulus_primitives_core::{
|
use cumulus_primitives_core::{
|
||||||
inherents::{SystemInherentData, SYSTEM_INHERENT_IDENTIFIER},
|
|
||||||
relay_chain,
|
relay_chain,
|
||||||
well_known_keys::{self, NEW_VALIDATION_CODE, VALIDATION_DATA},
|
well_known_keys::{self, NEW_VALIDATION_CODE, VALIDATION_DATA},
|
||||||
AbridgedHostConfiguration, DownwardMessageHandler, HrmpMessageHandler, HrmpMessageSender,
|
AbridgedHostConfiguration, DownwardMessageHandler, HrmpMessageHandler, HrmpMessageSender,
|
||||||
InboundDownwardMessage, InboundHrmpMessage, OnValidationData, OutboundHrmpMessage, ParaId,
|
InboundDownwardMessage, InboundHrmpMessage, OnValidationData, OutboundHrmpMessage, ParaId,
|
||||||
PersistedValidationData, UpwardMessage, UpwardMessageSender,
|
PersistedValidationData, UpwardMessage, UpwardMessageSender,
|
||||||
};
|
};
|
||||||
|
use cumulus_primitives_parachain_inherent::ParachainInherentData;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
decl_error, decl_event, decl_module, decl_storage,
|
decl_error, decl_event, decl_module, decl_storage,
|
||||||
dispatch::DispatchResult,
|
dispatch::DispatchResult,
|
||||||
@@ -166,11 +166,11 @@ decl_module! {
|
|||||||
/// As a side effect, this function upgrades the current validation function
|
/// As a side effect, this function upgrades the current validation function
|
||||||
/// if the appropriate time has come.
|
/// if the appropriate time has come.
|
||||||
#[weight = (0, DispatchClass::Mandatory)]
|
#[weight = (0, DispatchClass::Mandatory)]
|
||||||
fn set_validation_data(origin, data: SystemInherentData) -> DispatchResult {
|
fn set_validation_data(origin, data: ParachainInherentData) -> DispatchResult {
|
||||||
ensure_none(origin)?;
|
ensure_none(origin)?;
|
||||||
assert!(!DidUpdateValidationData::exists(), "ValidationData must be updated only once in a block");
|
assert!(!DidUpdateValidationData::exists(), "ValidationData must be updated only once in a block");
|
||||||
|
|
||||||
let SystemInherentData {
|
let ParachainInherentData {
|
||||||
validation_data: vfp,
|
validation_data: vfp,
|
||||||
relay_chain_state,
|
relay_chain_state,
|
||||||
downward_messages,
|
downward_messages,
|
||||||
@@ -798,11 +798,12 @@ impl<T: Config> HrmpMessageSender for Module<T> {
|
|||||||
impl<T: Config> ProvideInherent for Module<T> {
|
impl<T: Config> ProvideInherent for Module<T> {
|
||||||
type Call = Call<T>;
|
type Call = Call<T>;
|
||||||
type Error = sp_inherents::MakeFatalError<()>;
|
type Error = sp_inherents::MakeFatalError<()>;
|
||||||
const INHERENT_IDENTIFIER: InherentIdentifier = SYSTEM_INHERENT_IDENTIFIER;
|
const INHERENT_IDENTIFIER: InherentIdentifier =
|
||||||
|
cumulus_primitives_parachain_inherent::INHERENT_IDENTIFIER;
|
||||||
|
|
||||||
fn create_inherent(data: &InherentData) -> Option<Self::Call> {
|
fn create_inherent(data: &InherentData) -> Option<Self::Call> {
|
||||||
let data: SystemInherentData = data
|
let data: ParachainInherentData = data
|
||||||
.get_data(&SYSTEM_INHERENT_IDENTIFIER)
|
.get_data(&Self::INHERENT_IDENTIFIER)
|
||||||
.ok()
|
.ok()
|
||||||
.flatten()
|
.flatten()
|
||||||
.expect("validation function params are always injected into inherent data; qed");
|
.expect("validation function params are always injected into inherent data; qed");
|
||||||
@@ -1029,7 +1030,7 @@ mod tests {
|
|||||||
persisted_validation_data_hook:
|
persisted_validation_data_hook:
|
||||||
Option<Box<dyn Fn(&BlockTests, RelayChainBlockNumber, &mut PersistedValidationData)>>,
|
Option<Box<dyn Fn(&BlockTests, RelayChainBlockNumber, &mut PersistedValidationData)>>,
|
||||||
inherent_data_hook:
|
inherent_data_hook:
|
||||||
Option<Box<dyn Fn(&BlockTests, RelayChainBlockNumber, &mut SystemInherentData)>>,
|
Option<Box<dyn Fn(&BlockTests, RelayChainBlockNumber, &mut ParachainInherentData)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockTests {
|
impl BlockTests {
|
||||||
@@ -1089,7 +1090,7 @@ mod tests {
|
|||||||
|
|
||||||
fn with_inherent_data<F>(mut self, f: F) -> Self
|
fn with_inherent_data<F>(mut self, f: F) -> Self
|
||||||
where
|
where
|
||||||
F: 'static + Fn(&BlockTests, RelayChainBlockNumber, &mut SystemInherentData),
|
F: 'static + Fn(&BlockTests, RelayChainBlockNumber, &mut ParachainInherentData),
|
||||||
{
|
{
|
||||||
self.inherent_data_hook = Some(Box::new(f));
|
self.inherent_data_hook = Some(Box::new(f));
|
||||||
self
|
self
|
||||||
@@ -1142,7 +1143,7 @@ mod tests {
|
|||||||
// to storage; they must also be included in the inherent data.
|
// to storage; they must also be included in the inherent data.
|
||||||
let inherent_data = {
|
let inherent_data = {
|
||||||
let mut inherent_data = InherentData::default();
|
let mut inherent_data = InherentData::default();
|
||||||
let mut system_inherent_data = SystemInherentData {
|
let mut system_inherent_data = ParachainInherentData {
|
||||||
validation_data: vfp.clone(),
|
validation_data: vfp.clone(),
|
||||||
relay_chain_state,
|
relay_chain_state,
|
||||||
downward_messages: Default::default(),
|
downward_messages: Default::default(),
|
||||||
@@ -1152,7 +1153,10 @@ mod tests {
|
|||||||
hook(self, *n as RelayChainBlockNumber, &mut system_inherent_data);
|
hook(self, *n as RelayChainBlockNumber, &mut system_inherent_data);
|
||||||
}
|
}
|
||||||
inherent_data
|
inherent_data
|
||||||
.put_data(SYSTEM_INHERENT_IDENTIFIER, &system_inherent_data)
|
.put_data(
|
||||||
|
cumulus_primitives_parachain_inherent::INHERENT_IDENTIFIER,
|
||||||
|
&system_inherent_data,
|
||||||
|
)
|
||||||
.expect("failed to put VFP inherent");
|
.expect("failed to put VFP inherent");
|
||||||
inherent_data
|
inherent_data
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,33 +6,27 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Substrate dependencies
|
# Substrate dependencies
|
||||||
sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
|
||||||
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
|
||||||
sp-trie = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
sp-trie = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
|
||||||
# Polkadot dependencies
|
# Polkadot dependencies
|
||||||
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||||
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||||
|
polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||||
|
|
||||||
# Other dependencies
|
# Other dependencies
|
||||||
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ "derive" ] }
|
|
||||||
impl-trait-for-tuples = "0.2.1"
|
impl-trait-for-tuples = "0.2.1"
|
||||||
|
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ "derive" ] }
|
||||||
# Polkadot dependencies
|
|
||||||
polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "std" ]
|
default = [ "std" ]
|
||||||
std = [
|
std = [
|
||||||
"sp-std/std",
|
|
||||||
"codec/std",
|
"codec/std",
|
||||||
|
"sp-std/std",
|
||||||
"polkadot-primitives/std",
|
"polkadot-primitives/std",
|
||||||
"polkadot-parachain/std",
|
"polkadot-parachain/std",
|
||||||
"sp-inherents/std",
|
|
||||||
"polkadot-core-primitives/std",
|
"polkadot-core-primitives/std",
|
||||||
"sp-runtime/std",
|
"sp-runtime/std",
|
||||||
"sp-core/std",
|
|
||||||
"sp-trie/std",
|
"sp-trie/std",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -39,37 +39,6 @@ pub type InboundHrmpMessage = polkadot_primitives::v1::InboundHrmpMessage<relay_
|
|||||||
/// And outbound HRMP message
|
/// And outbound HRMP message
|
||||||
pub type OutboundHrmpMessage = polkadot_primitives::v1::OutboundHrmpMessage<ParaId>;
|
pub type OutboundHrmpMessage = polkadot_primitives::v1::OutboundHrmpMessage<ParaId>;
|
||||||
|
|
||||||
/// Identifiers and types related to Cumulus Inherents
|
|
||||||
pub mod inherents {
|
|
||||||
use super::{InboundDownwardMessage, InboundHrmpMessage, ParaId};
|
|
||||||
use sp_inherents::InherentIdentifier;
|
|
||||||
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};
|
|
||||||
|
|
||||||
/// The identifier for the parachain-system inherent.
|
|
||||||
pub const SYSTEM_INHERENT_IDENTIFIER: InherentIdentifier = *b"sysi1337";
|
|
||||||
|
|
||||||
/// The payload that system inherent carries.
|
|
||||||
#[derive(codec::Encode, codec::Decode, sp_core::RuntimeDebug, Clone, PartialEq)]
|
|
||||||
pub struct SystemInherentData {
|
|
||||||
pub validation_data: crate::PersistedValidationData,
|
|
||||||
/// A storage proof of a predefined set of keys from the relay-chain.
|
|
||||||
///
|
|
||||||
/// Specifically this witness contains the data for:
|
|
||||||
///
|
|
||||||
/// - active host configuration as per the relay parent,
|
|
||||||
/// - the relay dispatch queue sizes
|
|
||||||
/// - the list of egress HRMP channels (in the list of recipients form)
|
|
||||||
/// - the metadata for the egress HRMP channels
|
|
||||||
pub relay_chain_state: sp_trie::StorageProof,
|
|
||||||
/// Downward messages in the order they were sent.
|
|
||||||
pub downward_messages: Vec<InboundDownwardMessage>,
|
|
||||||
/// HRMP messages grouped by channels. The messages in the inner vec must be in order they
|
|
||||||
/// were sent. In combination with the rule of no more than one message in a channel per block,
|
|
||||||
/// this means `sent_at` is **strictly** greater than the previous one (if any).
|
|
||||||
pub horizontal_messages: BTreeMap<ParaId, Vec<InboundHrmpMessage>>,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Well known keys for values in the storage.
|
/// Well known keys for values in the storage.
|
||||||
pub mod well_known_keys {
|
pub mod well_known_keys {
|
||||||
/// The storage key for the upward messages.
|
/// The storage key for the upward messages.
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
[package]
|
||||||
|
name = "cumulus-primitives-parachain-inherent"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# Substrate dependencies
|
||||||
|
sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
||||||
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
||||||
|
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
||||||
|
sp-trie = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
||||||
|
|
||||||
|
# Cumulus dependencies
|
||||||
|
cumulus-primitives-core = { path = "../core", default-features = false }
|
||||||
|
|
||||||
|
# Other dependencies
|
||||||
|
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ "derive" ] }
|
||||||
|
tracing = { version = "0.1.22", optional = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "std" ]
|
||||||
|
std = [
|
||||||
|
"codec/std",
|
||||||
|
"cumulus-primitives-core/std",
|
||||||
|
"sp-inherents/std",
|
||||||
|
"sp-core/std",
|
||||||
|
"sp-trie/std",
|
||||||
|
"sp-std/std",
|
||||||
|
"sp-state-machine",
|
||||||
|
"tracing",
|
||||||
|
"sp-runtime",
|
||||||
|
"sc-client-api",
|
||||||
|
"sp-api",
|
||||||
|
]
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
// Copyright 2021 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Cumulus.
|
||||||
|
|
||||||
|
// 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Client side code for generating the parachain inherent.
|
||||||
|
|
||||||
|
use crate::ParachainInherentData;
|
||||||
|
use codec::Decode;
|
||||||
|
use cumulus_primitives_core::{
|
||||||
|
relay_chain::{
|
||||||
|
self,
|
||||||
|
v1::{HrmpChannelId, ParachainHost},
|
||||||
|
Block as PBlock, Hash as PHash,
|
||||||
|
},
|
||||||
|
InboundDownwardMessage, InboundHrmpMessage, ParaId, PersistedValidationData,
|
||||||
|
};
|
||||||
|
use sc_client_api::Backend;
|
||||||
|
use sp_api::ProvideRuntimeApi;
|
||||||
|
use sp_runtime::generic::BlockId;
|
||||||
|
use sp_state_machine::Backend as _;
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
const LOG_TARGET: &str = "parachain-inherent";
|
||||||
|
|
||||||
|
/// Returns the whole contents of the downward message queue for the parachain we are collating
|
||||||
|
/// for.
|
||||||
|
///
|
||||||
|
/// Returns `None` in case of an error.
|
||||||
|
fn retrieve_dmq_contents<PClient>(
|
||||||
|
polkadot_client: &PClient,
|
||||||
|
para_id: ParaId,
|
||||||
|
relay_parent: PHash,
|
||||||
|
) -> Option<Vec<InboundDownwardMessage>>
|
||||||
|
where
|
||||||
|
PClient: ProvideRuntimeApi<PBlock>,
|
||||||
|
PClient::Api: ParachainHost<PBlock>,
|
||||||
|
{
|
||||||
|
polkadot_client
|
||||||
|
.runtime_api()
|
||||||
|
.dmq_contents_with_context(
|
||||||
|
&BlockId::hash(relay_parent),
|
||||||
|
sp_core::ExecutionContext::Importing,
|
||||||
|
para_id,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
relay_parent = ?relay_parent,
|
||||||
|
error = ?e,
|
||||||
|
"An error occured during requesting the downward messages.",
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns channels contents for each inbound HRMP channel addressed to the parachain we are
|
||||||
|
/// collating for.
|
||||||
|
///
|
||||||
|
/// Empty channels are also included.
|
||||||
|
fn retrieve_all_inbound_hrmp_channel_contents<PClient>(
|
||||||
|
polkadot_client: &PClient,
|
||||||
|
para_id: ParaId,
|
||||||
|
relay_parent: PHash,
|
||||||
|
) -> Option<BTreeMap<ParaId, Vec<InboundHrmpMessage>>>
|
||||||
|
where
|
||||||
|
PClient: ProvideRuntimeApi<PBlock>,
|
||||||
|
PClient::Api: ParachainHost<PBlock>,
|
||||||
|
{
|
||||||
|
polkadot_client
|
||||||
|
.runtime_api()
|
||||||
|
.inbound_hrmp_channels_contents_with_context(
|
||||||
|
&BlockId::hash(relay_parent),
|
||||||
|
sp_core::ExecutionContext::Importing,
|
||||||
|
para_id,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
relay_parent = ?relay_parent,
|
||||||
|
error = ?e,
|
||||||
|
"An error occured during requesting the inbound HRMP messages.",
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Collect the relevant relay chain state in form of a proof for putting it into the validation
|
||||||
|
/// data inherent.
|
||||||
|
fn collect_relay_storage_proof(
|
||||||
|
polkadot_backend: &impl Backend<PBlock>,
|
||||||
|
para_id: ParaId,
|
||||||
|
relay_parent: PHash,
|
||||||
|
) -> Option<sp_state_machine::StorageProof> {
|
||||||
|
use relay_chain::well_known_keys as relay_well_known_keys;
|
||||||
|
|
||||||
|
let relay_parent_state_backend = polkadot_backend
|
||||||
|
.state_at(BlockId::Hash(relay_parent))
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
relay_parent = ?relay_parent,
|
||||||
|
error = ?e,
|
||||||
|
"Cannot obtain the state of the relay chain.",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
let ingress_channels = relay_parent_state_backend
|
||||||
|
.storage(&relay_well_known_keys::hrmp_ingress_channel_index(para_id))
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
error = ?e,
|
||||||
|
"Cannot obtain the hrmp ingress channel index."
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
let ingress_channels = ingress_channels
|
||||||
|
.map(|raw| <Vec<ParaId>>::decode(&mut &raw[..]))
|
||||||
|
.transpose()
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
error = ?e,
|
||||||
|
"Cannot decode the hrmp ingress channel index.",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()?
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let egress_channels = relay_parent_state_backend
|
||||||
|
.storage(&relay_well_known_keys::hrmp_egress_channel_index(para_id))
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
error = ?e,
|
||||||
|
"Cannot obtain the hrmp egress channel index.",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()?;
|
||||||
|
let egress_channels = egress_channels
|
||||||
|
.map(|raw| <Vec<ParaId>>::decode(&mut &raw[..]))
|
||||||
|
.transpose()
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
error = ?e,
|
||||||
|
"Cannot decode the hrmp egress channel index.",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()?
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let mut relevant_keys = vec![];
|
||||||
|
relevant_keys.push(relay_well_known_keys::ACTIVE_CONFIG.to_vec());
|
||||||
|
relevant_keys.push(relay_well_known_keys::dmq_mqc_head(para_id));
|
||||||
|
relevant_keys.push(relay_well_known_keys::relay_dispatch_queue_size(para_id));
|
||||||
|
relevant_keys.push(relay_well_known_keys::hrmp_ingress_channel_index(para_id));
|
||||||
|
relevant_keys.push(relay_well_known_keys::hrmp_egress_channel_index(para_id));
|
||||||
|
relevant_keys.extend(ingress_channels.into_iter().map(|sender| {
|
||||||
|
relay_well_known_keys::hrmp_channels(HrmpChannelId {
|
||||||
|
sender,
|
||||||
|
recipient: para_id,
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
relevant_keys.extend(egress_channels.into_iter().map(|recipient| {
|
||||||
|
relay_well_known_keys::hrmp_channels(HrmpChannelId {
|
||||||
|
sender: para_id,
|
||||||
|
recipient,
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
|
sp_state_machine::prove_read(relay_parent_state_backend, relevant_keys)
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
relay_parent = ?relay_parent,
|
||||||
|
error = ?e,
|
||||||
|
"Failed to collect required relay chain state storage proof.",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParachainInherentData {
|
||||||
|
/// Create the [`ParachainInherentData`] at the given `relay_parent`.
|
||||||
|
///
|
||||||
|
/// Returns `None` if the creation failed.
|
||||||
|
pub fn create_at<PClient>(
|
||||||
|
relay_parent: PHash,
|
||||||
|
polkadot_client: &PClient,
|
||||||
|
polkadot_backend: &impl Backend<PBlock>,
|
||||||
|
validation_data: &PersistedValidationData,
|
||||||
|
para_id: ParaId,
|
||||||
|
) -> Option<ParachainInherentData>
|
||||||
|
where
|
||||||
|
PClient: ProvideRuntimeApi<PBlock>,
|
||||||
|
PClient::Api: ParachainHost<PBlock>,
|
||||||
|
{
|
||||||
|
let relay_chain_state = collect_relay_storage_proof(polkadot_backend, para_id, relay_parent)?;
|
||||||
|
let downward_messages = retrieve_dmq_contents(polkadot_client, para_id, relay_parent)?;
|
||||||
|
let horizontal_messages =
|
||||||
|
retrieve_all_inbound_hrmp_channel_contents(polkadot_client, para_id, relay_parent)?;
|
||||||
|
|
||||||
|
Some(ParachainInherentData {
|
||||||
|
downward_messages,
|
||||||
|
horizontal_messages,
|
||||||
|
validation_data: validation_data.clone(),
|
||||||
|
relay_chain_state,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2021 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Cumulus.
|
||||||
|
|
||||||
|
// 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Cumulus parachain inherent
|
||||||
|
//!
|
||||||
|
//! The [`ParachainInherentData`] is the data that is passed by the collator to the parachain runtime.
|
||||||
|
//! The runtime will use this data to execute messages from other parachains/the relay chain or to
|
||||||
|
//! read data from the relay chain state. When the parachain is validated by a parachain validator on
|
||||||
|
//! the relay chain, this data is checked for correctnes. If the data passed by the collator to the
|
||||||
|
//! runtime isn't correct, the parachain candidate is considered invalid.
|
||||||
|
//!
|
||||||
|
//! Use [`ParachainInherentData::create_at`] to create the [`ParachainInherentData`] at a given
|
||||||
|
//! relay chain block to include it in a parachain block.
|
||||||
|
|
||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
use cumulus_primitives_core::{
|
||||||
|
InboundDownwardMessage, InboundHrmpMessage, ParaId, PersistedValidationData,
|
||||||
|
};
|
||||||
|
|
||||||
|
use sp_inherents::InherentIdentifier;
|
||||||
|
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
mod client_side;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub use client_side::*;
|
||||||
|
|
||||||
|
/// The identifier for the parachain inherent.
|
||||||
|
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"sysi1337";
|
||||||
|
|
||||||
|
/// The inherent data that is passed by the collator to the parachain runtime.
|
||||||
|
#[derive(codec::Encode, codec::Decode, sp_core::RuntimeDebug, Clone, PartialEq)]
|
||||||
|
pub struct ParachainInherentData {
|
||||||
|
pub validation_data: PersistedValidationData,
|
||||||
|
/// A storage proof of a predefined set of keys from the relay-chain.
|
||||||
|
///
|
||||||
|
/// Specifically this witness contains the data for:
|
||||||
|
///
|
||||||
|
/// - active host configuration as per the relay parent,
|
||||||
|
/// - the relay dispatch queue sizes
|
||||||
|
/// - the list of egress HRMP channels (in the list of recipients form)
|
||||||
|
/// - the metadata for the egress HRMP channels
|
||||||
|
pub relay_chain_state: sp_trie::StorageProof,
|
||||||
|
/// Downward messages in the order they were sent.
|
||||||
|
pub downward_messages: Vec<InboundDownwardMessage>,
|
||||||
|
/// HRMP messages grouped by channels. The messages in the inner vec must be in order they
|
||||||
|
/// were sent. In combination with the rule of no more than one message in a channel per block,
|
||||||
|
/// this means `sent_at` is **strictly** greater than the previous one (if any).
|
||||||
|
pub horizontal_messages: BTreeMap<ParaId, Vec<InboundHrmpMessage>>,
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ cumulus-test-runtime = { path = "../runtime" }
|
|||||||
cumulus-test-service = { path = "../service" }
|
cumulus-test-service = { path = "../service" }
|
||||||
cumulus-test-relay-sproof-builder = { path = "../relay-sproof-builder" }
|
cumulus-test-relay-sproof-builder = { path = "../relay-sproof-builder" }
|
||||||
cumulus-primitives-core = { path = "../../primitives/core" }
|
cumulus-primitives-core = { path = "../../primitives/core" }
|
||||||
|
cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent" }
|
||||||
|
|
||||||
# Polkadot deps
|
# Polkadot deps
|
||||||
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" }
|
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" }
|
||||||
|
|||||||
@@ -15,11 +15,10 @@
|
|||||||
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{Backend, Client};
|
use crate::{Backend, Client};
|
||||||
use cumulus_primitives_core::{
|
use cumulus_primitives_core::PersistedValidationData;
|
||||||
inherents::{SystemInherentData, SYSTEM_INHERENT_IDENTIFIER}, PersistedValidationData,
|
use cumulus_primitives_parachain_inherent::{ParachainInherentData, INHERENT_IDENTIFIER};
|
||||||
};
|
|
||||||
use cumulus_test_runtime::{Block, GetLastTimestamp};
|
|
||||||
use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
|
use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
|
||||||
|
use cumulus_test_runtime::{Block, GetLastTimestamp};
|
||||||
use polkadot_primitives::v1::BlockNumber as PBlockNumber;
|
use polkadot_primitives::v1::BlockNumber as PBlockNumber;
|
||||||
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
|
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
|
||||||
use sp_api::ProvideRuntimeApi;
|
use sp_api::ProvideRuntimeApi;
|
||||||
@@ -101,8 +100,8 @@ impl InitBlockBuilder for Client {
|
|||||||
|
|
||||||
inherent_data
|
inherent_data
|
||||||
.put_data(
|
.put_data(
|
||||||
SYSTEM_INHERENT_IDENTIFIER,
|
INHERENT_IDENTIFIER,
|
||||||
&SystemInherentData {
|
&ParachainInherentData {
|
||||||
validation_data,
|
validation_data,
|
||||||
relay_chain_state,
|
relay_chain_state,
|
||||||
downward_messages: Default::default(),
|
downward_messages: Default::default(),
|
||||||
|
|||||||
Reference in New Issue
Block a user