Inform the PVF with the latest relevant relay chain state (#279)

* Update polkadot

* Extend cumulus primitives with some relay chain exports

Follow https://github.com/paritytech/polkadot/pull/2194 to see the
polkadot PR

* collator: collect the state proof

This commit changes cumulus-collator so that it takes the relay chain
state at the relay parent and creates a storage proof that contains all
the required data for PVF.

* parachain-upgrade: use the proofs instead

This change is needed to make cumulus logic to not longer depend on the
transient validation data. As part of this change, in order to preserve
the current behavior `code_upgrade_allowed` now is computed on the
parachain side, rather than provided by polkadot.

Turned out that this requires to know the self parachain id so it was
added where needed.

* message-broker: use relay state to track limits

this should make sending messages safe from accidentally running over
the relay chain limits that were previously unknown.

* Update polkadot

So that `relay_storage_root` is available through `ValidationParams`

* Check `relay_storage_root` matches expected

Check that `relay_storage_root` submitted by the collator matches the
one that we receive in `validate_block` through `ValidationParams`

* Add a missing check for `dmq_mqc_head` while we are at it

* Update polkadot

* Fix tests that use the relay storage root

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update message-broker/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Remove unneeded (&_)

* Fix unwraps

* Polish basti's suggestion

* Fix merge

* Bring back the System::can_set_code check

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Sergei Shulepov
2021-01-13 14:40:26 +01:00
committed by GitHub
parent af07b819d1
commit b424d0f5e1
19 changed files with 793 additions and 136 deletions
+83 -9
View File
@@ -20,7 +20,7 @@ use cumulus_network::WaitToAnnounce;
use cumulus_primitives::{
inherents::{self, VALIDATION_DATA_IDENTIFIER},
well_known_keys, InboundDownwardMessage, InboundHrmpMessage, OutboundHrmpMessage,
ValidationData,
ValidationData, relay_chain,
};
use cumulus_runtime::ParachainBlockData;
@@ -42,7 +42,7 @@ use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProt
use polkadot_overseer::OverseerHandler;
use polkadot_primitives::v1::{
Block as PBlock, BlockData, BlockNumber as PBlockNumber, CollatorPair, Hash as PHash, HeadData,
Id as ParaId, PoV, UpwardMessage,
Id as ParaId, PoV, UpwardMessage, HrmpChannelId,
};
use polkadot_service::RuntimeApiCollection;
@@ -99,10 +99,10 @@ where
PF: Environment<Block> + 'static + Send,
PF::Proposer: Send,
BI: BlockImport<
Block,
Error = ConsensusError,
Transaction = <PF::Proposer as Proposer<Block>>::Transaction,
> + Send
Block,
Error = ConsensusError,
Transaction = <PF::Proposer as Proposer<Block>>::Transaction,
> + Send
+ Sync
+ 'static,
BS: BlockBackend<Block>,
@@ -195,6 +195,79 @@ where
.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: "cumulus-collator",
"Cannot obtain the state of the relay chain at `{:?}`: {:?}",
relay_parent,
e,
)
})
.ok()?;
let egress_channels = relay_parent_state_backend
.storage(&relay_well_known_keys::hrmp_egress_channel_index(
self.para_id,
))
.map_err(|e| {
error!(
target: "cumulus-collator",
"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: "cumulus-collator",
"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::relay_dispatch_queue_size(
self.para_id,
));
relevant_keys.push(relay_well_known_keys::hrmp_egress_channel_index(
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: "cumulus-collator",
"Failed to collect required relay chain state storage proof at `{:?}`: {:?}",
relay_parent,
e,
)
})
.ok()
}
/// Get the inherent data with validation function parameters injected
fn inherent_data(
&mut self,
@@ -214,8 +287,7 @@ where
.ok()?;
let validation_data = {
// TODO: Actual proof is to be created in the upcoming PRs.
let relay_chain_state = sp_state_machine::StorageProof::empty();
let relay_chain_state = self.collect_relay_storage_proof(relay_parent)?;
inherents::ValidationDataType {
validation_data: validation_data.clone(),
relay_chain_state,
@@ -680,7 +752,9 @@ mod tests {
_: RecordProof,
) -> Self::Proposal {
let block_id = BlockId::Hash(self.header.hash());
let builder = self.client.init_block_builder_at(&block_id, None);
let builder = self
.client
.init_block_builder_at(&block_id, None, Default::default());
let (block, storage_changes, proof) =
builder.build().expect("Creates block").into_inner();