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 322eda8f69
commit 464e54affd
19 changed files with 793 additions and 136 deletions
+1
View File
@@ -25,6 +25,7 @@ pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "m
# Cumulus deps
cumulus-test-runtime = { path = "../runtime" }
cumulus-test-service = { path = "../service" }
cumulus-test-relay-sproof-builder = { path = "../relay-sproof-builder" }
cumulus-primitives = { path = "../../primitives" }
# Polkadot deps
+27 -3
View File
@@ -20,6 +20,7 @@ use cumulus_primitives::{
ValidationData,
};
use cumulus_test_runtime::{Block, GetLastTimestamp};
use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
use polkadot_primitives::v1::BlockNumber as PBlockNumber;
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
use sp_api::ProvideRuntimeApi;
@@ -31,9 +32,13 @@ pub trait InitBlockBuilder {
///
/// This will automatically create and push the inherents for you to make the block
/// valid for the test runtime.
///
/// You can use the relay chain state sproof builder to arrange required relay chain state or
/// just use a default one.
fn init_block_builder(
&self,
validation_data: Option<ValidationData<PBlockNumber>>,
relay_sproof_builder: RelayStateSproofBuilder,
) -> sc_block_builder::BlockBuilder<Block, Client, Backend>;
/// Init a specific block builder at a specific block that works for the test runtime.
@@ -44,6 +49,7 @@ pub trait InitBlockBuilder {
&self,
at: &BlockId<Block>,
validation_data: Option<ValidationData<PBlockNumber>>,
relay_sproof_builder: RelayStateSproofBuilder,
) -> sc_block_builder::BlockBuilder<Block, Client, Backend>;
}
@@ -51,15 +57,21 @@ impl InitBlockBuilder for Client {
fn init_block_builder(
&self,
validation_data: Option<ValidationData<PBlockNumber>>,
relay_sproof_builder: RelayStateSproofBuilder,
) -> BlockBuilder<Block, Client, Backend> {
let chain_info = self.chain_info();
self.init_block_builder_at(&BlockId::Hash(chain_info.best_hash), validation_data)
self.init_block_builder_at(
&BlockId::Hash(chain_info.best_hash),
validation_data,
relay_sproof_builder,
)
}
fn init_block_builder_at(
&self,
at: &BlockId<Block>,
validation_data: Option<ValidationData<PBlockNumber>>,
relay_sproof_builder: RelayStateSproofBuilder,
) -> BlockBuilder<Block, Client, Backend> {
let mut block_builder = self
.new_block_at(at, Default::default(), true)
@@ -76,12 +88,24 @@ impl InitBlockBuilder for Client {
inherent_data
.put_data(sp_timestamp::INHERENT_IDENTIFIER, &timestamp)
.expect("Put timestamp failed");
let (relay_storage_root, relay_chain_state) =
relay_sproof_builder.into_state_root_and_proof();
let mut validation_data = validation_data.unwrap_or_default();
assert_eq!(
validation_data.persisted.relay_storage_root,
Default::default(),
"Overriding the relay storage root is not implemented",
);
validation_data.persisted.relay_storage_root = relay_storage_root;
inherent_data
.put_data(
VALIDATION_DATA_IDENTIFIER,
&ValidationDataType {
validation_data: validation_data.unwrap_or_default(),
relay_chain_state: sp_state_machine::StorageProof::empty(),
validation_data,
relay_chain_state,
},
)
.expect("Put validation function params failed");
+28
View File
@@ -0,0 +1,28 @@
[package]
name = "cumulus-test-relay-sproof-builder"
version = '0.1.0'
authors = ["Parity Technologies <admin@parity.io>"]
edition = '2018'
[dependencies]
# Other dependencies
codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = [ "derive" ] }
# Substrate dependencies
sp-state-machine = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
# Polkadot dependencies
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
# Cumulus dependencies
cumulus-primitives = { path = "../../primitives", default-features = false }
[features]
default = [ "std" ]
std = [
"codec/std",
"sp-state-machine/std",
"sp-runtime/std",
"cumulus-primitives/std",
]
+74
View File
@@ -0,0 +1,74 @@
// Copyright 2021 Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus 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.
// Cumulus 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/>.
use sp_runtime::traits::HashFor;
use sp_state_machine::MemoryDB;
use cumulus_primitives::relay_chain;
/// Builds a sproof (portmanteau of 'spoof' and 'proof') of the relay chain state.
#[derive(Clone)]
pub struct RelayStateSproofBuilder {
pub host_config: cumulus_primitives::AbridgedHostConfiguration,
}
impl Default for RelayStateSproofBuilder {
fn default() -> Self {
RelayStateSproofBuilder {
host_config: cumulus_primitives::AbridgedHostConfiguration {
max_code_size: 2 * 1024 * 1024,
max_head_data_size: 1024 * 1024,
max_upward_queue_count: 8,
max_upward_queue_size: 1024,
max_upward_message_size: 256,
max_upward_message_num_per_candidate: 5,
hrmp_max_message_num_per_candidate: 5,
validation_upgrade_frequency: 6,
validation_upgrade_delay: 6,
},
}
}
}
impl RelayStateSproofBuilder {
pub fn into_state_root_and_proof(
self,
) -> (
polkadot_primitives::v1::Hash,
sp_state_machine::StorageProof,
) {
let (db, root) = MemoryDB::<HashFor<polkadot_primitives::v1::Block>>::default_with_root();
let mut backend = sp_state_machine::TrieBackend::new(db, root);
let mut relevant_keys = vec![];
{
use codec::Encode as _;
let mut insert = |key: Vec<u8>, value: Vec<u8>| {
relevant_keys.push(key.clone());
backend.insert(vec![(None, vec![(key, Some(value))])]);
};
insert(
relay_chain::well_known_keys::ACTIVE_CONFIG.to_vec(),
self.host_config.encode(),
);
}
let root = backend.root().clone();
let proof = sp_state_machine::prove_read(backend, relevant_keys).expect("prove read");
(root, proof)
}
}
+1
View File
@@ -208,6 +208,7 @@ impl pallet_sudo::Config for Runtime {
}
impl cumulus_parachain_upgrade::Config for Runtime {
type SelfParaId = ParachainId;
type Event = Event;
type OnValidationData = ();
}