Adds support for checking the timestamp inherent while validating a block (#494)

* Adds support for checking the timestamp inherent while validating a block

This adds support for checking the timestamp inherent while validating a
block. This will use the relay chain slot number * relay chain slot
duration to calculate a timestamp. This timestamp is used to check the
timestamp in the timestamp inherent.

* Update polkadot-parachains/rococo-runtime/src/lib.rs

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>

* Update polkadot-parachains/statemine-runtime/src/lib.rs

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>

* Update primitives/timestamp/src/lib.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Fix warnings

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
Bastian Köcher
2021-06-16 09:53:47 +01:00
committed by GitHub
parent a84f7866f5
commit d3b4279f14
28 changed files with 826 additions and 522 deletions
Generated
+29 -75
View File
@@ -1413,7 +1413,6 @@ dependencies = [
"cumulus-primitives-core",
"cumulus-test-client",
"cumulus-test-runtime",
"env_logger 0.7.1",
"futures 0.3.14",
"parity-scale-codec",
"parking_lot 0.10.2",
@@ -1431,6 +1430,7 @@ dependencies = [
"sp-keyring",
"sp-runtime",
"sp-state-machine",
"sp-tracing",
"substrate-test-client",
"tracing",
]
@@ -1656,7 +1656,6 @@ dependencies = [
"cumulus-primitives-parachain-inherent",
"cumulus-test-client",
"cumulus-test-relay-sproof-builder",
"env_logger 0.7.1",
"environmental",
"frame-support",
"frame-system",
@@ -1667,10 +1666,7 @@ dependencies = [
"parity-scale-codec",
"polkadot-parachain",
"sc-client-api",
"sc-executor",
"sc-executor-common",
"serde",
"sp-blockchain",
"sp-consensus",
"sp-core",
"sp-externalities",
@@ -1680,9 +1676,9 @@ dependencies = [
"sp-runtime",
"sp-state-machine",
"sp-std",
"sp-tracing",
"sp-trie",
"sp-version",
"substrate-test-runtime-client",
"xcm",
]
@@ -1779,6 +1775,23 @@ dependencies = [
"tracing",
]
[[package]]
name = "cumulus-primitives-timestamp"
version = "0.1.0"
dependencies = [
"cumulus-primitives-core",
"cumulus-test-client",
"cumulus-test-relay-sproof-builder",
"futures 0.3.14",
"parity-scale-codec",
"sp-consensus",
"sp-inherents",
"sp-runtime",
"sp-std",
"sp-timestamp",
"sp-tracing",
]
[[package]]
name = "cumulus-primitives-utility"
version = "0.1.0"
@@ -1807,6 +1820,7 @@ dependencies = [
"cumulus-pallet-xcmp-queue",
"cumulus-ping",
"cumulus-primitives-core",
"cumulus-primitives-timestamp",
"cumulus-primitives-utility",
"frame-executive",
"frame-support",
@@ -1893,14 +1907,18 @@ dependencies = [
"pallet-balances",
"pallet-transaction-payment",
"parity-scale-codec",
"polkadot-parachain",
"polkadot-primitives",
"sc-block-builder",
"sc-consensus",
"sc-executor",
"sc-executor-common",
"sc-service",
"sp-api",
"sp-blockchain",
"sp-core",
"sp-inherents",
"sp-io",
"sp-keyring",
"sp-runtime",
"sp-state-machine",
@@ -1934,6 +1952,7 @@ version = "0.1.0"
dependencies = [
"cumulus-pallet-parachain-system",
"cumulus-primitives-core",
"cumulus-primitives-timestamp",
"frame-executive",
"frame-support",
"frame-system",
@@ -1965,6 +1984,7 @@ version = "0.1.0"
dependencies = [
"cumulus-pallet-parachain-system",
"cumulus-primitives-core",
"cumulus-primitives-timestamp",
"frame-executive",
"frame-support",
"frame-system",
@@ -6574,17 +6594,12 @@ dependencies = [
"jsonrpc-core",
"log",
"nix",
"pallet-sudo",
"parity-scale-codec",
"parking_lot 0.10.2",
"polkadot-cli",
"polkadot-parachain",
"polkadot-primitives",
"polkadot-runtime-common",
"polkadot-service",
"polkadot-test-client",
"polkadot-test-runtime",
"polkadot-test-service",
"rand 0.7.3",
"sc-basic-authorship",
"sc-chain-spec",
@@ -6620,8 +6635,6 @@ dependencies = [
"structopt",
"substrate-build-script-utils",
"substrate-prometheus-endpoint",
"substrate-test-client",
"substrate-test-runtime-client",
"tempfile",
"tokio 0.2.24",
"trie-root 0.15.2",
@@ -10744,6 +10757,7 @@ dependencies = [
"cumulus-pallet-xcmp-queue",
"cumulus-ping",
"cumulus-primitives-core",
"cumulus-primitives-timestamp",
"cumulus-primitives-utility",
"frame-benchmarking",
"frame-executive",
@@ -10832,6 +10846,7 @@ dependencies = [
"cumulus-pallet-xcmp-queue",
"cumulus-ping",
"cumulus-primitives-core",
"cumulus-primitives-timestamp",
"cumulus-primitives-utility",
"frame-benchmarking",
"frame-executive",
@@ -11094,68 +11109,6 @@ dependencies = [
"sp-state-machine",
]
[[package]]
name = "substrate-test-runtime"
version = "2.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#5d89967d7cc12d620bda9c9c042dbf7fcc4beb89"
dependencies = [
"cfg-if 1.0.0",
"frame-support",
"frame-system",
"frame-system-rpc-runtime-api",
"log",
"memory-db",
"pallet-babe",
"pallet-timestamp",
"parity-scale-codec",
"parity-util-mem",
"sc-service",
"serde",
"sp-api",
"sp-application-crypto",
"sp-block-builder",
"sp-consensus-aura",
"sp-consensus-babe",
"sp-core",
"sp-externalities",
"sp-finality-grandpa",
"sp-inherents",
"sp-io",
"sp-keyring",
"sp-offchain",
"sp-runtime",
"sp-runtime-interface",
"sp-session",
"sp-state-machine",
"sp-std",
"sp-transaction-pool",
"sp-trie",
"sp-version",
"substrate-wasm-builder 4.0.0",
"trie-db",
]
[[package]]
name = "substrate-test-runtime-client"
version = "2.0.0"
source = "git+https://github.com/paritytech/substrate?branch=master#5d89967d7cc12d620bda9c9c042dbf7fcc4beb89"
dependencies = [
"futures 0.3.14",
"parity-scale-codec",
"sc-block-builder",
"sc-client-api",
"sc-consensus",
"sc-light",
"sc-service",
"sp-api",
"sp-blockchain",
"sp-consensus",
"sp-core",
"sp-runtime",
"substrate-test-client",
"substrate-test-runtime",
]
[[package]]
name = "substrate-test-utils"
version = "3.0.0"
@@ -12646,6 +12599,7 @@ dependencies = [
"cumulus-pallet-xcmp-queue",
"cumulus-ping",
"cumulus-primitives-core",
"cumulus-primitives-timestamp",
"cumulus-primitives-utility",
"frame-benchmarking",
"frame-executive",
+1
View File
@@ -17,6 +17,7 @@ members = [
"pallets/xcmp-queue",
"primitives/core",
"primitives/parachain-inherent",
"primitives/timestamp",
"primitives/utility",
"polkadot-parachains/",
"polkadot-parachains/pallets/parachain-info",
+1 -1
View File
@@ -42,8 +42,8 @@ cumulus-test-client = { path = "../../test/client" }
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" }
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
# Other dependencies
env_logger = "0.7.1"
async-trait = "0.1.42"
+1 -1
View File
@@ -390,7 +390,7 @@ mod tests {
#[test]
fn collates_produces_a_block_and_storage_proof_does_not_contains_code() {
let _ = env_logger::try_init();
sp_tracing::try_init_simple();
let spawner = TaskExecutor::new();
let para_id = ParaId::from(100);
+9 -8
View File
@@ -36,19 +36,20 @@ log = { version = "0.4.14", default-features = false }
environmental = { version = "1.1.2", default-features = false }
[dev-dependencies]
substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
cumulus-test-relay-sproof-builder = { path = "../../test/relay-sproof-builder" }
# Other Dependencies
hex-literal = "0.2.1"
lazy_static = "1.4"
sc-client-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
# Substrate dependencies
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-executor-common = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" }
# Cumulus dependencies
cumulus-test-client = { path = "../../test/client" }
env_logger = "0.7.1"
cumulus-test-relay-sproof-builder = { path = "../../test/relay-sproof-builder" }
[features]
default = [ "std" ]
+1 -1
View File
@@ -1034,7 +1034,7 @@ pub trait CheckInherents<Block: BlockT> {
/// This function gets passed all the extrinsics of the block, so it is up to the callee to
/// identify the inherents. The `validation_data` can be used to access the
fn check_inherents(
extrinsics: &[Block::Extrinsic],
block: &Block,
validation_data: &RelayChainStateProof,
) -> frame_support::inherent::CheckInherentsResult;
}
@@ -140,7 +140,7 @@ where
)
.expect("Invalid relay chain state proof");
let res = CI::check_inherents(block.extrinsics(), &relay_chain_proof);
let res = CI::check_inherents(&block, &relay_chain_proof);
if !res.ok() {
if log::log_enabled!(log::Level::Error) {
@@ -18,63 +18,30 @@ use codec::{Decode, Encode};
use cumulus_primitives_core::{ParachainBlockData, PersistedValidationData};
use cumulus_test_client::{
runtime::{Block, Hash, Header, UncheckedExtrinsic, WASM_BINARY},
transfer, Client, DefaultTestClientBuilderExt, InitBlockBuilder, LongestChain,
TestClientBuilder, TestClientBuilderExt,
transfer, BlockData, BuildParachainBlockData, Client, DefaultTestClientBuilderExt, HeadData,
InitBlockBuilder, LongestChain, TestClientBuilder, TestClientBuilderExt, ValidationParams,
};
use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
use polkadot_parachain::primitives::{BlockData, HeadData, ValidationParams, ValidationResult};
use sc_executor::{
error::Result, sp_wasm_interface::HostFunctions, WasmExecutionMethod, WasmExecutor,
};
use sp_blockchain::HeaderBackend;
use sp_consensus::SelectChain;
use sp_io::TestExternalities;
use sp_keyring::AccountKeyring::*;
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, Header as HeaderT},
};
use sp_runtime::traits::Header as HeaderT;
use std::{env, process::Command};
fn call_validate_block(
parent_head: Header,
block_data: ParachainBlockData<Block>,
relay_parent_storage_root: Hash,
) -> Result<Header> {
use sc_executor_common::runtime_blob::RuntimeBlob;
let mut ext = TestExternalities::default();
let mut ext_ext = ext.ext();
let params = ValidationParams {
block_data: BlockData(block_data.encode()),
parent_head: HeadData(parent_head.encode()),
relay_parent_number: 1,
relay_parent_storage_root,
}
.encode();
let executor = WasmExecutor::new(
WasmExecutionMethod::Interpreted,
Some(1024),
sp_io::SubstrateHostFunctions::host_functions(),
1,
None,
);
executor
.uncached_call(
RuntimeBlob::uncompress_if_needed(
&WASM_BINARY.expect("You need to build the WASM binaries to run the tests!"),
)
.expect("RuntimeBlob uncompress & parse"),
&mut ext_ext,
false,
"validate_block",
&params,
)
.map(|v| ValidationResult::decode(&mut &v[..]).expect("Decode `ValidationResult`."))
.map(|v| Header::decode(&mut &v.head_data.0[..]).expect("Decode `Header`."))
.map_err(|err| err.into())
) -> cumulus_test_client::ExecutorResult<Header> {
cumulus_test_client::validate_block(
ValidationParams {
block_data: BlockData(block_data.encode()),
parent_head: HeadData(parent_head.encode()),
relay_parent_number: 1,
relay_parent_storage_root,
},
&WASM_BINARY.expect("You need to build the WASM binaries to run the tests!"),
)
.map(|v| Header::decode(&mut &v.head_data.0[..]).expect("Decodes `Header`."))
}
fn create_test_client() -> (Client, LongestChain) {
@@ -85,8 +52,7 @@ fn create_test_client() -> (Client, LongestChain) {
}
struct TestBlockData {
block: Block,
witness: sp_trie::CompactProof,
block: ParachainBlockData<Block>,
validation_data: PersistedValidationData,
}
@@ -97,14 +63,12 @@ fn build_block_with_witness(
sproof_builder: RelayStateSproofBuilder,
) -> TestBlockData {
let (relay_parent_storage_root, _) = sproof_builder.clone().into_state_root_and_proof();
let block_id = BlockId::Hash(client.info().best_hash);
let mut validation_data = PersistedValidationData {
relay_parent_number: 1,
parent_head: parent_head.encode().into(),
..Default::default()
};
let mut builder =
client.init_block_builder_at(&block_id, Some(validation_data.clone()), sproof_builder);
let mut builder = client.init_block_builder(Some(validation_data.clone()), sproof_builder);
validation_data.relay_parent_storage_root = relay_parent_storage_root;
@@ -112,39 +76,29 @@ fn build_block_with_witness(
.into_iter()
.for_each(|e| builder.push(e).unwrap());
let built_block = builder.build().expect("Creates block");
let witness = built_block
.proof
.expect("We enabled proof recording before.")
.into_compact_proof::<<Header as HeaderT>::Hashing>(*parent_head.state_root())
.unwrap();
let block = builder.build_parachain_block(*parent_head.state_root());
TestBlockData {
block: built_block.block,
witness,
block,
validation_data,
}
}
#[test]
fn validate_block_no_extra_extrinsics() {
let _ = env_logger::try_init();
sp_tracing::try_init_simple();
let (client, longest_chain) = create_test_client();
let parent_head = longest_chain.best_chain().expect("Best block exists");
let TestBlockData {
block,
witness,
validation_data,
} = build_block_with_witness(&client, vec![], parent_head.clone(), Default::default());
let (header, extrinsics) = block.deconstruct();
let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness);
let header = block.header().clone();
let res_header = call_validate_block(
parent_head,
block_data,
block,
validation_data.relay_parent_storage_root,
)
.expect("Calls `validate_block`");
@@ -153,7 +107,7 @@ fn validate_block_no_extra_extrinsics() {
#[test]
fn validate_block_with_extra_extrinsics() {
let _ = env_logger::try_init();
sp_tracing::try_init_simple();
let (client, longest_chain) = create_test_client();
let parent_head = longest_chain.best_chain().expect("Best block exists");
@@ -165,7 +119,6 @@ fn validate_block_with_extra_extrinsics() {
let TestBlockData {
block,
witness,
validation_data,
} = build_block_with_witness(
&client,
@@ -173,13 +126,11 @@ fn validate_block_with_extra_extrinsics() {
parent_head.clone(),
Default::default(),
);
let (header, extrinsics) = block.deconstruct();
let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness);
let header = block.header().clone();
let res_header = call_validate_block(
parent_head,
block_data,
block,
validation_data.relay_parent_storage_root,
)
.expect("Calls `validate_block`");
@@ -188,17 +139,16 @@ fn validate_block_with_extra_extrinsics() {
#[test]
fn validate_block_invalid_parent_hash() {
let _ = env_logger::try_init();
sp_tracing::try_init_simple();
if env::var("RUN_TEST").is_ok() {
let (client, longest_chain) = create_test_client();
let parent_head = longest_chain.best_chain().expect("Best block exists");
let TestBlockData {
block,
witness,
validation_data,
} = build_block_with_witness(&client, vec![], parent_head.clone(), Default::default());
let (mut header, extrinsics) = block.deconstruct();
let (mut header, extrinsics, witness) = block.deconstruct();
header.set_parent_hash(Hash::from_low_u64_be(1));
let block_data = ParachainBlockData::new(header, extrinsics, witness);
@@ -222,17 +172,15 @@ fn validate_block_invalid_parent_hash() {
#[test]
fn validate_block_fails_on_invalid_validation_data() {
let _ = env_logger::try_init();
sp_tracing::try_init_simple();
if env::var("RUN_TEST").is_ok() {
let (client, longest_chain) = create_test_client();
let parent_head = longest_chain.best_chain().expect("Best block exists");
let TestBlockData { block, witness, .. } =
let TestBlockData { block, .. } =
build_block_with_witness(&client, vec![], parent_head.clone(), Default::default());
let (header, extrinsics) = block.deconstruct();
let block_data = ParachainBlockData::new(header, extrinsics, witness);
call_validate_block(parent_head, block_data, Hash::random()).unwrap_err();
call_validate_block(parent_head, block, Hash::random()).unwrap_err();
} else {
let output = Command::new(env::current_exe().unwrap())
.args(&[
@@ -252,7 +200,7 @@ fn validate_block_fails_on_invalid_validation_data() {
#[test]
fn check_inherent_fails_on_validate_block_as_expected() {
let _ = env_logger::try_init();
sp_tracing::try_init_simple();
if env::var("RUN_TEST").is_ok() {
let (client, longest_chain) = create_test_client();
@@ -260,7 +208,6 @@ fn check_inherent_fails_on_validate_block_as_expected() {
let TestBlockData {
block,
witness,
validation_data,
} = build_block_with_witness(
&client,
@@ -271,13 +218,10 @@ fn check_inherent_fails_on_validate_block_as_expected() {
..Default::default()
},
);
let (header, extrinsics) = block.deconstruct();
let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness);
call_validate_block(
parent_head,
block_data,
block,
validation_data.relay_parent_storage_root,
)
.unwrap_err();
-11
View File
@@ -92,17 +92,6 @@ rand = "0.7.3"
tempfile = "3.2.0"
tokio = { version = "0.2.13", features = ["macros"] }
# Polkadot dependencies
polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-test-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-test-client = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "master" }
# Substrate dependencies
pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "master" }
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
[features]
default = []
runtime-benchmarks = [
@@ -40,6 +40,7 @@ pallet-aura = { git = "https://github.com/paritytech/substrate", default-feature
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
cumulus-primitives-timestamp = { path = "../../primitives/timestamp", default-features = false }
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue", default-features = false }
cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue", default-features = false }
@@ -93,6 +94,7 @@ std = [
"cumulus-pallet-xcmp-queue/std",
"cumulus-pallet-xcm/std",
"cumulus-primitives-core/std",
"cumulus-primitives-timestamp/std",
"cumulus-primitives-utility/std",
"cumulus-ping/std",
"xcm/std",
+29 -20
View File
@@ -26,7 +26,7 @@ use sp_api::impl_runtime_apis;
use sp_core::OpaqueMetadata;
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{BlakeTwo256, Block as BlockT, AccountIdLookup},
traits::{AccountIdLookup, BlakeTwo256, Block as BlockT},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult,
};
@@ -37,8 +37,8 @@ use sp_version::RuntimeVersion;
// A few exports that help ease life for downstream crates.
pub use frame_support::{
construct_runtime, parameter_types, match_type,
traits::{Randomness, IsInVec, All},
construct_runtime, match_type, parameter_types,
traits::{All, IsInVec, Randomness},
weights::{
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
DispatchClass, IdentityFee, Weight,
@@ -48,24 +48,23 @@ pub use frame_support::{
use frame_system::limits::{BlockLength, BlockWeights};
pub use pallet_balances::Call as BalancesCall;
pub use pallet_timestamp::Call as TimestampCall;
pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
pub use sp_runtime::{Perbill, Permill};
pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
// XCM imports
use pallet_xcm::{EnsureXcm, IsMajorityOfBody, XcmPassthrough};
use polkadot_parachain::primitives::Sibling;
use xcm::v0::{MultiAsset, MultiLocation, MultiLocation::*, Junction::*, BodyId, NetworkId};
use xcm::v0::{BodyId, Junction::*, MultiAsset, MultiLocation, MultiLocation::*, NetworkId, Xcm};
use xcm_builder::{
AccountId32Aliases, CurrencyAdapter, LocationInverter, ParentIsDefault, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SovereignSignedViaLocation, EnsureXcmOrigin, AllowUnpaidExecutionFrom, ParentAsSuperuser,
AllowTopLevelPaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, IsConcrete, NativeAsset,
UsingComponents, SignedToAccountId32,
AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset,
ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
};
use xcm_executor::{Config, XcmExecutor};
use pallet_xcm::{XcmPassthrough, EnsureXcm, IsMajorityOfBody};
use xcm::v0::Xcm;
pub type SessionHandlers = ();
@@ -340,18 +339,16 @@ impl Config for XcmConfig {
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = NativeAsset;
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of ROC
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of ROC
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
type Trader = UsingComponents<IdentityFee<Balance>, RocLocation, AccountId, Balances, ()>;
type ResponseHandler = (); // Don't handle responses for now.
type ResponseHandler = (); // Don't handle responses for now.
}
/// No local origins on this chain are allowed to dispatch XCM sends/executions.
pub type LocalOriginToLocation = (
SignedToAccountId32<Origin, AccountId, RococoNetwork>,
);
pub type LocalOriginToLocation = SignedToAccountId32<Origin, AccountId, RococoNetwork>;
/// The means for routing XCM messages which are not for local execution into the right message
/// queues.
@@ -595,10 +592,22 @@ struct CheckInherents;
impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
fn check_inherents(
_: &[UncheckedExtrinsic],
_: &cumulus_pallet_parachain_system::RelayChainStateProof,
block: &Block,
relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
) -> sp_inherents::CheckInherentsResult {
sp_inherents::CheckInherentsResult::new()
let relay_chain_slot = relay_state_proof
.read_slot()
.expect("Could not read the relay chain slot from the proof");
let inherent_data =
cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
relay_chain_slot,
sp_std::time::Duration::from_secs(6),
)
.create_inherent_data()
.expect("Could not create the timestamp inherent data");
inherent_data.check_extrinsics(&block)
}
}
+16 -16
View File
@@ -26,7 +26,7 @@ use sp_api::impl_runtime_apis;
use sp_core::OpaqueMetadata;
use sp_runtime::{
create_runtime_str, generic,
traits::{BlakeTwo256, Block as BlockT, AccountIdLookup},
traits::{AccountIdLookup, BlakeTwo256, Block as BlockT},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult,
};
@@ -37,8 +37,8 @@ use sp_version::RuntimeVersion;
// A few exports that help ease life for downstream crates.
pub use frame_support::{
construct_runtime, parameter_types, match_type,
traits::{Randomness, All, IsInVec},
construct_runtime, match_type, parameter_types,
traits::{All, IsInVec, Randomness},
weights::{
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
DispatchClass, IdentityFee, Weight,
@@ -53,8 +53,8 @@ pub use sp_runtime::{Perbill, Permill};
// XCM imports
use xcm::v0::{Junction::*, MultiLocation, MultiLocation::*, NetworkId};
use xcm_builder::{
LocationInverter, ParentIsDefault, FixedWeightBounds, AllowUnpaidExecutionFrom,
ParentAsSuperuser, SovereignSignedViaLocation,
AllowUnpaidExecutionFrom, FixedWeightBounds, LocationInverter, ParentAsSuperuser,
ParentIsDefault, SovereignSignedViaLocation,
};
use xcm_executor::{Config, XcmExecutor};
@@ -202,16 +202,16 @@ parameter_types! {
pub struct XcmConfig;
impl Config for XcmConfig {
type Call = Call;
type XcmSender = (); // sending XCM not supported
type AssetTransactor = (); // balances not supported
type XcmSender = (); // sending XCM not supported
type AssetTransactor = (); // balances not supported
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = (); // balances not supported
type IsTeleporter = (); // balances not supported
type IsReserve = (); // balances not supported
type IsTeleporter = (); // balances not supported
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = AllowUnpaidExecutionFrom<JustTheParent>;
type Weigher = FixedWeightBounds<UnitWeightCost, Call>; // balances not supported
type Trader = (); // balances not supported
type ResponseHandler = (); // Don't handle responses for now.
type Weigher = FixedWeightBounds<UnitWeightCost, Call>; // balances not supported
type Trader = (); // balances not supported
type ResponseHandler = (); // Don't handle responses for now.
}
impl cumulus_pallet_xcm::Config for Runtime {
@@ -243,9 +243,9 @@ impl sp_runtime::traits::SignedExtension for DisallowSigned {
type Call = Call;
type AdditionalSigned = ();
type Pre = ();
fn additional_signed(&self)
-> sp_std::result::Result<(), sp_runtime::transaction_validity::TransactionValidityError>
{
fn additional_signed(
&self,
) -> sp_std::result::Result<(), sp_runtime::transaction_validity::TransactionValidityError> {
Ok(())
}
fn validate(
@@ -373,7 +373,7 @@ struct CheckInherents;
impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
fn check_inherents(
_: &[UncheckedExtrinsic],
_: &Block,
_: &cumulus_pallet_parachain_system::RelayChainStateProof,
) -> sp_inherents::CheckInherentsResult {
sp_inherents::CheckInherentsResult::new()
@@ -56,6 +56,7 @@ max-encoded-len = { git = "https://github.com/paritytech/substrate", default-fea
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
cumulus-primitives-timestamp = { path = "../../primitives/timestamp", default-features = false }
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue", default-features = false }
cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue", default-features = false }
@@ -141,6 +142,7 @@ std = [
"cumulus-pallet-xcmp-queue/std",
"cumulus-pallet-xcm/std",
"cumulus-primitives-core/std",
"cumulus-primitives-timestamp/std",
"cumulus-primitives-utility/std",
"cumulus-ping/std",
"xcm/std",
+107 -92
View File
@@ -27,9 +27,9 @@ mod weights;
use sp_api::impl_runtime_apis;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, Block as BlockT};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{AccountIdLookup, BlakeTwo256, Block as BlockT},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult,
};
@@ -39,46 +39,44 @@ use sp_std::prelude::*;
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
use frame_system::{
EnsureOneOf, EnsureRoot, limits::{BlockLength, BlockWeights},
};
use statemint_common::{
BlockNumber, Signature, AccountId, Balance, Index, Hash, AuraId, Header,
NORMAL_DISPATCH_RATIO, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, SLOT_DURATION, HOURS,
};
pub use statemint_common as common;
use statemint_common::impls::DealWithFees;
use codec::{Decode, Encode};
use constants::{currency::*, fee::WeightToFee};
use frame_support::{
construct_runtime, parameter_types, match_type,
traits::{InstanceFilter, All, Filter, MaxEncodedLen},
construct_runtime, match_type, parameter_types,
traits::{All, Filter, InstanceFilter, MaxEncodedLen},
weights::{
constants::{BlockExecutionWeight, ExtrinsicBaseWeight},
DispatchClass, IdentityFee, Weight,
},
RuntimeDebug, PalletId,
PalletId, RuntimeDebug,
};
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureOneOf, EnsureRoot,
};
use sp_runtime::Perbill;
pub use statemint_common as common;
use statemint_common::{
impls::DealWithFees, AccountId, AuraId, Balance, BlockNumber, Hash, Header, Index, Signature,
AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION,
};
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
// Polkadot imports
use pallet_xcm::{EnsureXcm, IsMajorityOfBody, XcmPassthrough};
use polkadot_parachain::primitives::Sibling;
use polkadot_runtime_common::{
BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate,
};
use xcm::v0::{MultiAsset, Junction, MultiLocation, NetworkId, Xcm, BodyId};
use polkadot_runtime_common::{BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate};
use xcm::v0::{BodyId, Junction, MultiAsset, MultiLocation, NetworkId, Xcm};
use xcm_builder::{
AccountId32Aliases, CurrencyAdapter, LocationInverter, ParentIsDefault, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SovereignSignedViaLocation, EnsureXcmOrigin,
AllowTopLevelPaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, IsConcrete, NativeAsset,
AllowUnpaidExecutionFrom, ParentAsSuperuser, SignedToAccountId32, UsingComponents,
AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset,
ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
};
use xcm_executor::{Config, XcmExecutor};
use pallet_xcm::{XcmPassthrough, EnsureXcm, IsMajorityOfBody};
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
@@ -149,9 +147,10 @@ parameter_types! {
pub struct BaseFilter;
impl Filter<Call> for BaseFilter {
fn filter(c: &Call) -> bool {
!matches!(c,
Call::Assets(pallet_assets::Call::create(..)) |
Call::Uniques(pallet_uniques::Call::create(..))
!matches!(
c,
Call::Assets(pallet_assets::Call::create(..))
| Call::Uniques(pallet_uniques::Call::create(..))
)
}
}
@@ -251,7 +250,7 @@ parameter_types! {
}
/// We allow root and the Relay Chain council to execute privileged asset operations.
pub type AssetsForceOrigin = EnsureOneOf<
pub type AssetsForceOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
EnsureXcm<IsMajorityOfBody<KsmLocation, ExecutiveBody>>,
@@ -337,7 +336,9 @@ parameter_types! {
}
/// The type used to represent the kinds of proxying allowed.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen)]
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen,
)]
pub enum ProxyType {
/// Fully permissioned proxy. Can execute any call on behalf of _proxied_.
Any,
@@ -363,67 +364,70 @@ impl InstanceFilter<Call> for ProxyType {
fn filter(&self, c: &Call) -> bool {
match self {
ProxyType::Any => true,
ProxyType::NonTransfer => !matches!(c,
Call::Balances(..) |
Call::Assets(pallet_assets::Call::transfer(..)) |
Call::Assets(pallet_assets::Call::transfer_keep_alive(..)) |
Call::Assets(pallet_assets::Call::force_transfer(..)) |
Call::Assets(pallet_assets::Call::transfer_ownership(..)) |
Call::Assets(pallet_assets::Call::approve_transfer(..)) |
Call::Assets(pallet_assets::Call::transfer_approved(..)) |
Call::Uniques(pallet_uniques::Call::transfer(..)) |
Call::Uniques(pallet_uniques::Call::transfer_ownership(..)) |
Call::Uniques(pallet_uniques::Call::approve_transfer(..))
ProxyType::NonTransfer => !matches!(
c,
Call::Balances(..)
| Call::Assets(pallet_assets::Call::transfer(..))
| Call::Assets(pallet_assets::Call::transfer_keep_alive(..))
| Call::Assets(pallet_assets::Call::force_transfer(..))
| Call::Assets(pallet_assets::Call::transfer_ownership(..))
| Call::Assets(pallet_assets::Call::approve_transfer(..))
| Call::Assets(pallet_assets::Call::transfer_approved(..))
| Call::Uniques(pallet_uniques::Call::transfer(..))
| Call::Uniques(pallet_uniques::Call::transfer_ownership(..))
| Call::Uniques(pallet_uniques::Call::approve_transfer(..))
),
ProxyType::CancelProxy => matches!(c,
Call::Proxy(pallet_proxy::Call::reject_announcement(..)) |
Call::Utility(..) |
Call::Multisig(..)
ProxyType::CancelProxy => matches!(
c,
Call::Proxy(pallet_proxy::Call::reject_announcement(..))
| Call::Utility(..) | Call::Multisig(..)
),
ProxyType::Assets => {
matches!(c, Call::Assets(..) | Call::Utility(..) | Call::Multisig(..) | Call::Uniques(..))
matches!(
c,
Call::Assets(..) | Call::Utility(..) | Call::Multisig(..) | Call::Uniques(..)
)
}
ProxyType::AssetOwner => matches!(c,
Call::Assets(pallet_assets::Call::create(..)) |
Call::Assets(pallet_assets::Call::destroy(..)) |
Call::Assets(pallet_assets::Call::transfer_ownership(..)) |
Call::Assets(pallet_assets::Call::set_team(..)) |
Call::Assets(pallet_assets::Call::set_metadata(..)) |
Call::Assets(pallet_assets::Call::clear_metadata(..)) |
Call::Uniques(pallet_uniques::Call::create(..)) |
Call::Uniques(pallet_uniques::Call::destroy(..)) |
Call::Uniques(pallet_uniques::Call::transfer_ownership(..)) |
Call::Uniques(pallet_uniques::Call::set_team(..)) |
Call::Uniques(pallet_uniques::Call::set_metadata(..)) |
Call::Uniques(pallet_uniques::Call::set_attribute(..)) |
Call::Uniques(pallet_uniques::Call::set_class_metadata(..)) |
Call::Uniques(pallet_uniques::Call::clear_metadata(..)) |
Call::Uniques(pallet_uniques::Call::clear_attribute(..)) |
Call::Uniques(pallet_uniques::Call::clear_class_metadata(..)) |
Call::Utility(..) |
Call::Multisig(..)
ProxyType::AssetOwner => matches!(
c,
Call::Assets(pallet_assets::Call::create(..))
| Call::Assets(pallet_assets::Call::destroy(..))
| Call::Assets(pallet_assets::Call::transfer_ownership(..))
| Call::Assets(pallet_assets::Call::set_team(..))
| Call::Assets(pallet_assets::Call::set_metadata(..))
| Call::Assets(pallet_assets::Call::clear_metadata(..))
| Call::Uniques(pallet_uniques::Call::create(..))
| Call::Uniques(pallet_uniques::Call::destroy(..))
| Call::Uniques(pallet_uniques::Call::transfer_ownership(..))
| Call::Uniques(pallet_uniques::Call::set_team(..))
| Call::Uniques(pallet_uniques::Call::set_metadata(..))
| Call::Uniques(pallet_uniques::Call::set_attribute(..))
| Call::Uniques(pallet_uniques::Call::set_class_metadata(..))
| Call::Uniques(pallet_uniques::Call::clear_metadata(..))
| Call::Uniques(pallet_uniques::Call::clear_attribute(..))
| Call::Uniques(pallet_uniques::Call::clear_class_metadata(..))
| Call::Utility(..) | Call::Multisig(..)
),
ProxyType::AssetManager => matches!(c,
Call::Assets(pallet_assets::Call::mint(..)) |
Call::Assets(pallet_assets::Call::burn(..)) |
Call::Assets(pallet_assets::Call::freeze(..)) |
Call::Assets(pallet_assets::Call::thaw(..)) |
Call::Assets(pallet_assets::Call::freeze_asset(..)) |
Call::Assets(pallet_assets::Call::thaw_asset(..)) |
Call::Uniques(pallet_uniques::Call::mint(..)) |
Call::Uniques(pallet_uniques::Call::burn(..)) |
Call::Uniques(pallet_uniques::Call::freeze(..)) |
Call::Uniques(pallet_uniques::Call::thaw(..)) |
Call::Uniques(pallet_uniques::Call::freeze_class(..)) |
Call::Uniques(pallet_uniques::Call::thaw_class(..)) |
Call::Utility(..) |
Call::Multisig(..)
ProxyType::AssetManager => matches!(
c,
Call::Assets(pallet_assets::Call::mint(..))
| Call::Assets(pallet_assets::Call::burn(..))
| Call::Assets(pallet_assets::Call::freeze(..))
| Call::Assets(pallet_assets::Call::thaw(..))
| Call::Assets(pallet_assets::Call::freeze_asset(..))
| Call::Assets(pallet_assets::Call::thaw_asset(..))
| Call::Uniques(pallet_uniques::Call::mint(..))
| Call::Uniques(pallet_uniques::Call::burn(..))
| Call::Uniques(pallet_uniques::Call::freeze(..))
| Call::Uniques(pallet_uniques::Call::thaw(..))
| Call::Uniques(pallet_uniques::Call::freeze_class(..))
| Call::Uniques(pallet_uniques::Call::thaw_class(..))
| Call::Utility(..) | Call::Multisig(..)
),
ProxyType::Collator => matches!(
c,
Call::CollatorSelection(..) | Call::Utility(..) | Call::Multisig(..)
),
ProxyType::Collator => matches!(c,
Call::CollatorSelection(..) |
Call::Utility(..) |
Call::Multisig(..)
)
}
}
fn is_superset(&self, o: &Self) -> bool {
@@ -557,12 +561,12 @@ impl Config for XcmConfig {
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = NativeAsset;
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of KSM
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of KSM
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
type Trader = UsingComponents<IdentityFee<Balance>, KsmLocation, AccountId, Balances, ()>;
type ResponseHandler = (); // Don't handle responses for now.
type ResponseHandler = (); // Don't handle responses for now.
}
parameter_types! {
@@ -570,9 +574,7 @@ parameter_types! {
}
/// No local origins on this chain are allowed to dispatch XCM sends/executions.
pub type LocalOriginToLocation = (
SignedToAccountId32<Origin, AccountId, RelayNetwork>,
);
pub type LocalOriginToLocation = SignedToAccountId32<Origin, AccountId, RelayNetwork>;
/// The means for routing XCM messages which are not for local execution into the right message
/// queues.
@@ -627,7 +629,8 @@ impl pallet_session::Config for Runtime {
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
type SessionManager = CollatorSelection;
// Essentially just Aura, but lets be pedantic.
type SessionHandler = <opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
type SessionHandler =
<opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
type Keys = opaque::SessionKeys;
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
@@ -901,10 +904,22 @@ struct CheckInherents;
impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
fn check_inherents(
_: &[UncheckedExtrinsic],
_: &cumulus_pallet_parachain_system::RelayChainStateProof,
block: &Block,
relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
) -> sp_inherents::CheckInherentsResult {
sp_inherents::CheckInherentsResult::new()
let relay_chain_slot = relay_state_proof
.read_slot()
.expect("Could not read the relay chain slot from the proof");
let inherent_data =
cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
relay_chain_slot,
sp_std::time::Duration::from_secs(6),
)
.create_inherent_data()
.expect("Could not create the timestamp inherent data");
inherent_data.check_extrinsics(&block)
}
}
@@ -55,6 +55,7 @@ max-encoded-len = { git = "https://github.com/paritytech/substrate", default-fea
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
cumulus-primitives-timestamp = { path = "../../primitives/timestamp", default-features = false }
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue", default-features = false }
cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue", default-features = false }
@@ -138,6 +139,7 @@ std = [
"cumulus-pallet-xcmp-queue/std",
"cumulus-pallet-xcm/std",
"cumulus-primitives-core/std",
"cumulus-primitives-timestamp/std",
"cumulus-primitives-utility/std",
"cumulus-ping/std",
"xcm/std",
@@ -27,9 +27,9 @@ mod weights;
use sp_api::impl_runtime_apis;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, Block as BlockT};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{AccountIdLookup, BlakeTwo256, Block as BlockT},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult,
};
@@ -39,46 +39,44 @@ use sp_std::prelude::*;
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
use frame_system::{
EnsureOneOf, EnsureRoot, limits::{BlockLength, BlockWeights},
};
use statemint_common::{
BlockNumber, Signature, AccountId, Balance, Index, Hash, AuraId, Header,
NORMAL_DISPATCH_RATIO, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, SLOT_DURATION, HOURS,
};
pub use statemint_common as common;
use statemint_common::impls::DealWithFees;
use codec::{Decode, Encode};
use constants::{currency::*, fee::WeightToFee};
use frame_support::{
construct_runtime, parameter_types, match_type,
traits::{InstanceFilter, All, MaxEncodedLen},
construct_runtime, match_type, parameter_types,
traits::{All, InstanceFilter, MaxEncodedLen},
weights::{
constants::{BlockExecutionWeight, ExtrinsicBaseWeight},
DispatchClass, IdentityFee, Weight,
},
RuntimeDebug, PalletId,
PalletId, RuntimeDebug,
};
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureOneOf, EnsureRoot,
};
use sp_runtime::Perbill;
pub use statemint_common as common;
use statemint_common::{
impls::DealWithFees, AccountId, AuraId, Balance, BlockNumber, Hash, Header, Index, Signature,
AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION,
};
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
// Polkadot imports
use pallet_xcm::{EnsureXcm, IsMajorityOfBody, XcmPassthrough};
use polkadot_parachain::primitives::Sibling;
use polkadot_runtime_common::{
BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate,
};
use xcm::v0::{MultiAsset, Junction, MultiLocation, NetworkId, Xcm, BodyId};
use polkadot_runtime_common::{BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate};
use xcm::v0::{BodyId, Junction, MultiAsset, MultiLocation, NetworkId, Xcm};
use xcm_builder::{
AccountId32Aliases, CurrencyAdapter, LocationInverter, ParentIsDefault, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SovereignSignedViaLocation, EnsureXcmOrigin,
AllowTopLevelPaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, IsConcrete, NativeAsset,
AllowUnpaidExecutionFrom, ParentAsSuperuser, SignedToAccountId32, UsingComponents,
AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset,
ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
};
use xcm_executor::{Config, XcmExecutor};
use pallet_xcm::{XcmPassthrough, EnsureXcm, IsMajorityOfBody};
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
@@ -240,7 +238,7 @@ parameter_types! {
}
/// We allow root and the Relay Chain council to execute privileged asset operations.
pub type AssetsForceOrigin = EnsureOneOf<
pub type AssetsForceOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
EnsureXcm<IsMajorityOfBody<DotLocation, ExecutiveBody>>,
@@ -299,7 +297,9 @@ parameter_types! {
}
/// The type used to represent the kinds of proxying allowed.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen)]
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen,
)]
pub enum ProxyType {
/// Fully permissioned proxy. Can execute any call on behalf of _proxied_.
Any,
@@ -325,48 +325,48 @@ impl InstanceFilter<Call> for ProxyType {
fn filter(&self, c: &Call) -> bool {
match self {
ProxyType::Any => true,
ProxyType::NonTransfer => !matches!(c,
Call::Balances(..) |
Call::Assets(pallet_assets::Call::transfer(..)) |
Call::Assets(pallet_assets::Call::transfer_keep_alive(..)) |
Call::Assets(pallet_assets::Call::force_transfer(..)) |
Call::Assets(pallet_assets::Call::transfer_ownership(..)) |
Call::Assets(pallet_assets::Call::approve_transfer(..)) |
Call::Assets(pallet_assets::Call::transfer_approved(..))
ProxyType::NonTransfer => !matches!(
c,
Call::Balances(..)
| Call::Assets(pallet_assets::Call::transfer(..))
| Call::Assets(pallet_assets::Call::transfer_keep_alive(..))
| Call::Assets(pallet_assets::Call::force_transfer(..))
| Call::Assets(pallet_assets::Call::transfer_ownership(..))
| Call::Assets(pallet_assets::Call::approve_transfer(..))
| Call::Assets(pallet_assets::Call::transfer_approved(..))
),
ProxyType::CancelProxy => matches!(c,
Call::Proxy(pallet_proxy::Call::reject_announcement(..)) |
Call::Utility(..) |
Call::Multisig(..)
ProxyType::CancelProxy => matches!(
c,
Call::Proxy(pallet_proxy::Call::reject_announcement(..))
| Call::Utility(..) | Call::Multisig(..)
),
ProxyType::Assets => {
matches!(c, Call::Assets(..) | Call::Utility(..) | Call::Multisig(..))
}
ProxyType::AssetOwner => matches!(c,
Call::Assets(pallet_assets::Call::create(..)) |
Call::Assets(pallet_assets::Call::destroy(..)) |
Call::Assets(pallet_assets::Call::transfer_ownership(..)) |
Call::Assets(pallet_assets::Call::set_team(..)) |
Call::Assets(pallet_assets::Call::set_metadata(..)) |
Call::Assets(pallet_assets::Call::clear_metadata(..)) |
Call::Utility(..) |
Call::Multisig(..)
ProxyType::AssetOwner => matches!(
c,
Call::Assets(pallet_assets::Call::create(..))
| Call::Assets(pallet_assets::Call::destroy(..))
| Call::Assets(pallet_assets::Call::transfer_ownership(..))
| Call::Assets(pallet_assets::Call::set_team(..))
| Call::Assets(pallet_assets::Call::set_metadata(..))
| Call::Assets(pallet_assets::Call::clear_metadata(..))
| Call::Utility(..) | Call::Multisig(..)
),
ProxyType::AssetManager => matches!(c,
Call::Assets(pallet_assets::Call::mint(..)) |
Call::Assets(pallet_assets::Call::burn(..)) |
Call::Assets(pallet_assets::Call::freeze(..)) |
Call::Assets(pallet_assets::Call::thaw(..)) |
Call::Assets(pallet_assets::Call::freeze_asset(..)) |
Call::Assets(pallet_assets::Call::thaw_asset(..)) |
Call::Utility(..) |
Call::Multisig(..)
ProxyType::AssetManager => matches!(
c,
Call::Assets(pallet_assets::Call::mint(..))
| Call::Assets(pallet_assets::Call::burn(..))
| Call::Assets(pallet_assets::Call::freeze(..))
| Call::Assets(pallet_assets::Call::thaw(..))
| Call::Assets(pallet_assets::Call::freeze_asset(..))
| Call::Assets(pallet_assets::Call::thaw_asset(..))
| Call::Utility(..) | Call::Multisig(..)
),
ProxyType::Collator => matches!(
c,
Call::CollatorSelection(..) | Call::Utility(..) | Call::Multisig(..)
),
ProxyType::Collator => matches!(c,
Call::CollatorSelection(..) |
Call::Utility(..) |
Call::Multisig(..)
)
}
}
fn is_superset(&self, o: &Self) -> bool {
@@ -500,12 +500,12 @@ impl Config for XcmConfig {
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = NativeAsset;
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of DOT
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of DOT
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
type Trader = UsingComponents<IdentityFee<Balance>, DotLocation, AccountId, Balances, ()>;
type ResponseHandler = (); // Don't handle responses for now.
type ResponseHandler = (); // Don't handle responses for now.
}
parameter_types! {
@@ -513,9 +513,7 @@ parameter_types! {
}
/// No local origins on this chain are allowed to dispatch XCM sends/executions.
pub type LocalOriginToLocation = (
SignedToAccountId32<Origin, AccountId, RelayNetwork>,
);
pub type LocalOriginToLocation = SignedToAccountId32<Origin, AccountId, RelayNetwork>;
/// The means for routing XCM messages which are not for local execution into the right message
/// queues.
@@ -570,7 +568,8 @@ impl pallet_session::Config for Runtime {
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
type SessionManager = CollatorSelection;
// Essentially just Aura, but lets be pedantic.
type SessionHandler = <opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
type SessionHandler =
<opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
type Keys = opaque::SessionKeys;
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
@@ -831,10 +830,22 @@ struct CheckInherents;
impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
fn check_inherents(
_: &[UncheckedExtrinsic],
_: &cumulus_pallet_parachain_system::RelayChainStateProof,
block: &Block,
relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
) -> sp_inherents::CheckInherentsResult {
sp_inherents::CheckInherentsResult::new()
let relay_chain_slot = relay_state_proof
.read_slot()
.expect("Could not read the relay chain slot from the proof");
let inherent_data =
cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
relay_chain_slot,
sp_std::time::Duration::from_secs(6),
)
.create_inherent_data()
.expect("Could not create the timestamp inherent data");
inherent_data.check_extrinsics(&block)
}
}
@@ -55,6 +55,7 @@ max-encoded-len = { git = "https://github.com/paritytech/substrate", default-fea
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
cumulus-primitives-timestamp = { path = "../../primitives/timestamp", default-features = false }
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue", default-features = false }
cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue", default-features = false }
@@ -138,6 +139,7 @@ std = [
"cumulus-pallet-xcmp-queue/std",
"cumulus-pallet-xcm/std",
"cumulus-primitives-core/std",
"cumulus-primitives-timestamp/std",
"cumulus-primitives-utility/std",
"cumulus-ping/std",
"xcm/std",
+80 -69
View File
@@ -27,9 +27,9 @@ mod weights;
use sp_api::impl_runtime_apis;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, Block as BlockT};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{AccountIdLookup, BlakeTwo256, Block as BlockT},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult,
};
@@ -39,46 +39,44 @@ use sp_std::prelude::*;
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
use frame_system::{
EnsureRoot, limits::{BlockLength, BlockWeights},
};
use statemint_common::{
BlockNumber, Signature, AccountId, Balance, Index, Hash, AuraId, Header,
NORMAL_DISPATCH_RATIO, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, SLOT_DURATION, HOURS,
};
pub use statemint_common as common;
use statemint_common::impls::DealWithFees;
use codec::{Decode, Encode};
use constants::{currency::*, fee::WeightToFee};
use frame_support::{
construct_runtime, parameter_types, match_type,
traits::{InstanceFilter, All, MaxEncodedLen},
construct_runtime, match_type, parameter_types,
traits::{All, InstanceFilter, MaxEncodedLen},
weights::{
constants::{BlockExecutionWeight, ExtrinsicBaseWeight},
DispatchClass, IdentityFee, Weight,
},
RuntimeDebug, PalletId,
PalletId, RuntimeDebug,
};
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureRoot,
};
use sp_runtime::Perbill;
pub use statemint_common as common;
use statemint_common::{
impls::DealWithFees, AccountId, AuraId, Balance, BlockNumber, Hash, Header, Index, Signature,
AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION,
};
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
// Polkadot imports
use pallet_xcm::XcmPassthrough;
use polkadot_parachain::primitives::Sibling;
use polkadot_runtime_common::{
BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate,
};
use xcm::v0::{MultiAsset, Junction, MultiLocation, NetworkId, Xcm};
use polkadot_runtime_common::{BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate};
use xcm::v0::{Junction, MultiAsset, MultiLocation, NetworkId, Xcm};
use xcm_builder::{
AccountId32Aliases, CurrencyAdapter, LocationInverter, ParentIsDefault, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SovereignSignedViaLocation, EnsureXcmOrigin,
AllowTopLevelPaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, IsConcrete, NativeAsset,
AllowUnpaidExecutionFrom, ParentAsSuperuser, SignedToAccountId32, UsingComponents,
AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset,
ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
};
use xcm_executor::{Config, XcmExecutor};
use pallet_xcm::XcmPassthrough;
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
@@ -297,7 +295,9 @@ parameter_types! {
}
/// The type used to represent the kinds of proxying allowed.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen)]
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen,
)]
pub enum ProxyType {
/// Fully permissioned proxy. Can execute any call on behalf of _proxied_.
Any,
@@ -323,48 +323,48 @@ impl InstanceFilter<Call> for ProxyType {
fn filter(&self, c: &Call) -> bool {
match self {
ProxyType::Any => true,
ProxyType::NonTransfer => !matches!(c,
Call::Balances(..) |
Call::Assets(pallet_assets::Call::transfer(..)) |
Call::Assets(pallet_assets::Call::transfer_keep_alive(..)) |
Call::Assets(pallet_assets::Call::force_transfer(..)) |
Call::Assets(pallet_assets::Call::transfer_ownership(..)) |
Call::Assets(pallet_assets::Call::approve_transfer(..)) |
Call::Assets(pallet_assets::Call::transfer_approved(..))
ProxyType::NonTransfer => !matches!(
c,
Call::Balances(..)
| Call::Assets(pallet_assets::Call::transfer(..))
| Call::Assets(pallet_assets::Call::transfer_keep_alive(..))
| Call::Assets(pallet_assets::Call::force_transfer(..))
| Call::Assets(pallet_assets::Call::transfer_ownership(..))
| Call::Assets(pallet_assets::Call::approve_transfer(..))
| Call::Assets(pallet_assets::Call::transfer_approved(..))
),
ProxyType::CancelProxy => matches!(c,
Call::Proxy(pallet_proxy::Call::reject_announcement(..)) |
Call::Utility(..) |
Call::Multisig(..)
ProxyType::CancelProxy => matches!(
c,
Call::Proxy(pallet_proxy::Call::reject_announcement(..))
| Call::Utility(..) | Call::Multisig(..)
),
ProxyType::Assets => {
matches!(c, Call::Assets(..) | Call::Utility(..) | Call::Multisig(..))
}
ProxyType::AssetOwner => matches!(c,
Call::Assets(pallet_assets::Call::create(..)) |
Call::Assets(pallet_assets::Call::destroy(..)) |
Call::Assets(pallet_assets::Call::transfer_ownership(..)) |
Call::Assets(pallet_assets::Call::set_team(..)) |
Call::Assets(pallet_assets::Call::set_metadata(..)) |
Call::Assets(pallet_assets::Call::clear_metadata(..)) |
Call::Utility(..) |
Call::Multisig(..)
ProxyType::AssetOwner => matches!(
c,
Call::Assets(pallet_assets::Call::create(..))
| Call::Assets(pallet_assets::Call::destroy(..))
| Call::Assets(pallet_assets::Call::transfer_ownership(..))
| Call::Assets(pallet_assets::Call::set_team(..))
| Call::Assets(pallet_assets::Call::set_metadata(..))
| Call::Assets(pallet_assets::Call::clear_metadata(..))
| Call::Utility(..) | Call::Multisig(..)
),
ProxyType::AssetManager => matches!(c,
Call::Assets(pallet_assets::Call::mint(..)) |
Call::Assets(pallet_assets::Call::burn(..)) |
Call::Assets(pallet_assets::Call::freeze(..)) |
Call::Assets(pallet_assets::Call::thaw(..)) |
Call::Assets(pallet_assets::Call::freeze_asset(..)) |
Call::Assets(pallet_assets::Call::thaw_asset(..)) |
Call::Utility(..) |
Call::Multisig(..)
ProxyType::AssetManager => matches!(
c,
Call::Assets(pallet_assets::Call::mint(..))
| Call::Assets(pallet_assets::Call::burn(..))
| Call::Assets(pallet_assets::Call::freeze(..))
| Call::Assets(pallet_assets::Call::thaw(..))
| Call::Assets(pallet_assets::Call::freeze_asset(..))
| Call::Assets(pallet_assets::Call::thaw_asset(..))
| Call::Utility(..) | Call::Multisig(..)
),
ProxyType::Collator => matches!(
c,
Call::CollatorSelection(..) | Call::Utility(..) | Call::Multisig(..)
),
ProxyType::Collator => matches!(c,
Call::CollatorSelection(..) |
Call::Utility(..) |
Call::Multisig(..)
)
}
}
fn is_superset(&self, o: &Self) -> bool {
@@ -497,12 +497,12 @@ impl Config for XcmConfig {
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = NativeAsset;
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of WND
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of WND
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
type Trader = UsingComponents<IdentityFee<Balance>, WestendLocation, AccountId, Balances, ()>;
type ResponseHandler = (); // Don't handle responses for now.
type ResponseHandler = (); // Don't handle responses for now.
}
parameter_types! {
@@ -510,9 +510,7 @@ parameter_types! {
}
/// No local origins on this chain are allowed to dispatch XCM sends/executions.
pub type LocalOriginToLocation = (
SignedToAccountId32<Origin, AccountId, RelayNetwork>,
);
pub type LocalOriginToLocation = SignedToAccountId32<Origin, AccountId, RelayNetwork>;
/// The means for routing XCM messages which are not for local execution into the right message
/// queues.
@@ -567,7 +565,8 @@ impl pallet_session::Config for Runtime {
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
type SessionManager = CollatorSelection;
// Essentially just Aura, but lets be pedantic.
type SessionHandler = <opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
type SessionHandler =
<opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
type Keys = opaque::SessionKeys;
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
type WeightInfo = weights::pallet_session::WeightInfo<Runtime>;
@@ -665,7 +664,7 @@ pub type Executive = frame_executive::Executive<
frame_system::ChainContext<Runtime>,
Runtime,
AllPallets,
OnRuntimeUpgrade
OnRuntimeUpgrade,
>;
pub struct OnRuntimeUpgrade;
@@ -831,10 +830,22 @@ struct CheckInherents;
impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
fn check_inherents(
_: &[UncheckedExtrinsic],
_: &cumulus_pallet_parachain_system::RelayChainStateProof,
block: &Block,
relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
) -> sp_inherents::CheckInherentsResult {
sp_inherents::CheckInherentsResult::new()
let relay_chain_slot = relay_state_proof
.read_slot()
.expect("Could not read the relay chain slot from the proof");
let inherent_data =
cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
relay_chain_slot,
sp_std::time::Duration::from_secs(6),
)
.create_inherent_data()
.expect("Could not create the timestamp inherent data");
inherent_data.check_extrinsics(&block)
}
}
+21 -18
View File
@@ -18,22 +18,21 @@
#![cfg_attr(not(feature = "std"), no_std)]
use sp_std::prelude::*;
use codec::{Encode, Decode};
use sp_runtime::{RuntimeDebug, traits::Block as BlockT};
use codec::{Decode, Encode};
use frame_support::weights::Weight;
use sp_runtime::{traits::Block as BlockT, RuntimeDebug};
use sp_std::prelude::*;
pub use polkadot_core_primitives::InboundDownwardMessage;
pub use polkadot_parachain::primitives::{Id as ParaId, UpwardMessage, ValidationParams};
pub use polkadot_primitives::v1::{
PersistedValidationData, AbridgedHostConfiguration, AbridgedHrmpChannel,
AbridgedHostConfiguration, AbridgedHrmpChannel, PersistedValidationData,
};
/// A module that re-exports relevant relay chain definitions.
pub mod relay_chain {
pub use polkadot_core_primitives::*;
pub use polkadot_primitives::v1;
pub use polkadot_primitives::v1::well_known_keys;
pub use polkadot_primitives::{v1, v1::well_known_keys};
}
use relay_chain::BlockNumber as RelayBlockNumber;
@@ -95,13 +94,13 @@ pub trait DmpMessageHandler {
///
/// Also, process messages up to some `max_weight`.
fn handle_dmp_messages(
iter: impl Iterator<Item=(RelayBlockNumber, Vec<u8>)>,
iter: impl Iterator<Item = (RelayBlockNumber, Vec<u8>)>,
max_weight: Weight,
) -> Weight;
}
impl DmpMessageHandler for () {
fn handle_dmp_messages(
iter: impl Iterator<Item=(RelayBlockNumber, Vec<u8>)>,
iter: impl Iterator<Item = (RelayBlockNumber, Vec<u8>)>,
_max_weight: Weight,
) -> Weight {
iter.for_each(drop);
@@ -115,13 +114,13 @@ pub trait XcmpMessageHandler {
/// messages).
///
/// Also, process messages up to some `max_weight`.
fn handle_xcmp_messages<'a, I: Iterator<Item=(ParaId, RelayBlockNumber, &'a [u8])>>(
fn handle_xcmp_messages<'a, I: Iterator<Item = (ParaId, RelayBlockNumber, &'a [u8])>>(
iter: I,
max_weight: Weight,
) -> Weight;
}
impl XcmpMessageHandler for () {
fn handle_xcmp_messages<'a, I: Iterator<Item=(ParaId, RelayBlockNumber, &'a [u8])>>(
fn handle_xcmp_messages<'a, I: Iterator<Item = (ParaId, RelayBlockNumber, &'a [u8])>>(
iter: I,
_max_weight: Weight,
) -> Weight {
@@ -158,15 +157,13 @@ pub enum ChannelStatus {
/// A means of figuring out what outbound XCMP messages should be being sent.
pub trait XcmpMessageSource {
/// Take a single XCMP message from the queue for the given `dest`, if one exists.
fn take_outbound_messages(
maximum_channels: usize,
) -> Vec<(ParaId, Vec<u8>)>;
fn take_outbound_messages(maximum_channels: usize) -> Vec<(ParaId, Vec<u8>)>;
}
impl XcmpMessageSource for () {
fn take_outbound_messages(
_maximum_channels: usize,
) -> Vec<(ParaId, Vec<u8>)> { vec![] }
fn take_outbound_messages(_maximum_channels: usize) -> Vec<(ParaId, Vec<u8>)> {
vec![]
}
}
/// The "quality of service" considerations for message sending.
@@ -191,7 +188,7 @@ pub trait OnValidationData {
///
/// This is send as PoV (proof of validity block) to the relay-chain validators. There it will be
/// passed to the parachain validation Wasm blob to be validated.
#[derive(codec::Encode, codec::Decode)]
#[derive(codec::Encode, codec::Decode, Clone)]
pub struct ParachainBlockData<B: BlockT> {
/// The header of the parachain block.
header: B::Header,
@@ -241,7 +238,13 @@ impl<B: BlockT> ParachainBlockData<B> {
}
/// Deconstruct into the inner parts.
pub fn deconstruct(self) -> (B::Header, sp_std::vec::Vec<B::Extrinsic>, sp_trie::CompactProof) {
pub fn deconstruct(
self,
) -> (
B::Header,
sp_std::vec::Vec<B::Extrinsic>,
sp_trie::CompactProof,
) {
(self.header, self.extrinsics, self.storage_proof)
}
}
+38
View File
@@ -0,0 +1,38 @@
[package]
name = "cumulus-primitives-timestamp"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
description = "Provides timestamp related functionality for parachains."
[dependencies]
# Substrate dependencies
sp-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
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" }
# Cumulus dependencies
cumulus-primitives-core = { path = "../core", default-features = false }
[dev-dependencies]
# Substrate dependencies
sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
# Cumulus dependencies
cumulus-test-client = { path = "../../test/client" }
cumulus-test-relay-sproof-builder = { path = "../../test/relay-sproof-builder" }
# Other deps
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ "derive" ] }
futures = "0.3.5"
[features]
default = [ "std" ]
std = [
"sp-timestamp/std",
"sp-inherents/std",
"sp-std/std",
"cumulus-primitives-core/std",
]
+208
View File
@@ -0,0 +1,208 @@
// 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/>.
//! Cumulus timestamp related primitives.
//!
//! Provides a [`InherentDataProvider`] that should be used in the validation phase of the parachain.
//! It will be used to create the inherent data and that will be used to check the inherents inside
//! the parachain block (in this case the timestamp inherent). As we don't have access to any clock
//! from the runtime the timestamp is always passed as an inherent into the runtime. To check this
//! inherent when validating the block, we will use the relay chain slot. As the relay chain slot
//! is derived from a timestamp, we can easily convert it back to a timestamp by muliplying it with
//! the slot duration. By comparing the relay chain slot derived timestamp with the timestamp we can
//! ensure that the parachain timestamp is reasonable.
#![cfg_attr(not(feature = "std"), no_std)]
use cumulus_primitives_core::relay_chain::v1::Slot;
use sp_inherents::{Error, InherentData};
use sp_std::time::Duration;
pub use sp_timestamp::{InherentType, INHERENT_IDENTIFIER};
/// The inherent data provider for the timestamp.
///
/// This should be used in the runtime when checking the inherents in the validation phase of the
/// parachain.
pub struct InherentDataProvider {
relay_chain_slot: Slot,
relay_chain_slot_duration: Duration,
}
impl InherentDataProvider {
/// Create `Self` from the given relay chain slot and slot duration.
pub fn from_relay_chain_slot_and_duration(
relay_chain_slot: Slot,
relay_chain_slot_duration: Duration,
) -> Self {
Self {
relay_chain_slot,
relay_chain_slot_duration,
}
}
/// Create the inherent data.
pub fn create_inherent_data(&self) -> Result<InherentData, Error> {
let mut inherent_data = InherentData::new();
self.provide_inherent_data(&mut inherent_data)
.map(|_| inherent_data)
}
/// Provide the inherent data into the given `inherent_data`.
pub fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), Error> {
// As the parachain starts building at around `relay_chain_slot + 1` we use that slot to
// calculate the timestamp.
let data: InherentType = ((*self.relay_chain_slot + 1)
* self.relay_chain_slot_duration.as_millis() as u64)
.into();
inherent_data.put_data(INHERENT_IDENTIFIER, &data)
}
}
#[cfg(test)]
mod tests {
use super::*;
use codec::{Decode, Encode};
use cumulus_primitives_core::{relay_chain::Hash as PHash, PersistedValidationData};
use cumulus_test_client::{
runtime::{Block, Header, WASM_BINARY},
BlockData, BuildParachainBlockData, Client, ClientBlockImportExt, ExecutorResult, HeadData,
InitBlockBuilder, ParachainBlockData, TestClientBuilder, TestClientBuilderExt,
ValidationParams,
};
use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
use sp_runtime::{generic::BlockId, traits::Header as HeaderT};
use std::{env, process::Command, str::FromStr};
const SLOT_DURATION: u64 = 6000;
fn call_validate_block(
parent_head: Header,
block_data: ParachainBlockData,
relay_parent_storage_root: PHash,
) -> ExecutorResult<Header> {
cumulus_test_client::validate_block(
ValidationParams {
block_data: BlockData(block_data.encode()),
parent_head: HeadData(parent_head.encode()),
relay_parent_number: 1,
relay_parent_storage_root,
},
&WASM_BINARY.expect("You need to build the WASM binaries to run the tests!"),
)
.map(|v| Header::decode(&mut &v.head_data.0[..]).expect("Decodes `Header`."))
}
fn build_block(
client: &Client,
at: BlockId<Block>,
timestamp: u64,
relay_chain_slot: Slot,
) -> (ParachainBlockData, PHash) {
let sproof_builder = RelayStateSproofBuilder {
current_slot: relay_chain_slot,
..Default::default()
};
let parent_header = client
.header(&at)
.ok()
.flatten()
.expect("Genesis header exists");
let relay_parent_storage_root = sproof_builder.clone().into_state_root_and_proof().0;
let validation_data = PersistedValidationData {
relay_parent_number: 1,
parent_head: parent_header.encode().into(),
..Default::default()
};
let block = client
.init_block_builder_with_timestamp(
&at,
Some(validation_data),
sproof_builder,
timestamp,
)
.build_parachain_block(*parent_header.state_root());
(block, relay_parent_storage_root)
}
#[test]
fn check_timestamp_inherent_works() {
sp_tracing::try_init_simple();
let relay_chain_slot = 2;
if env::var("RUN_TEST").is_ok() {
let mut client = TestClientBuilder::default().build();
let timestamp = u64::from_str(&env::var("TIMESTAMP").expect("TIMESTAMP is set"))
.expect("TIMESTAMP is a valid `u64`");
let block = build_block(&client, BlockId::number(0), SLOT_DURATION, 1.into())
.0
.into_block();
futures::executor::block_on(client.import(sp_consensus::BlockOrigin::Own, block))
.unwrap();
let (block, relay_chain_root) = build_block(
&client,
BlockId::number(1),
timestamp,
relay_chain_slot.into(),
);
let header = call_validate_block(
client
.header(&BlockId::number(1))
.ok()
.flatten()
.expect("Genesis header exists"),
block.clone(),
relay_chain_root,
)
.expect("Calls validate block");
assert_eq!(block.header(), &header);
} else {
let slot_timestamp = relay_chain_slot * SLOT_DURATION;
for (timestamp, res) in &[
(slot_timestamp, true),
(slot_timestamp - 500, true),
(slot_timestamp + 500, true),
(slot_timestamp * 10, false),
] {
let output = Command::new(env::current_exe().unwrap())
.args(&["check_timestamp_inherent_works", "--", "--nocapture"])
.env("RUN_TEST", "1")
.env("TIMESTAMP", timestamp.to_string())
.output()
.expect("Runs the test");
if !res {
assert!(String::from_utf8(output.stderr)
.unwrap()
.contains("Checking inherents failed"));
}
assert!(dbg!(output.status.success()) == *res);
}
}
}
}
+4
View File
@@ -8,6 +8,8 @@ edition = "2018"
sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-executor-common = { git = "https://github.com/paritytech/substrate", branch = "master" }
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
@@ -16,6 +18,7 @@ sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master
sp-test-primitives = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
@@ -31,6 +34,7 @@ cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inh
# Polkadot deps
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master" }
# Other deps
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ "derive" ] }
+102 -43
View File
@@ -15,14 +15,17 @@
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
use crate::{Backend, Client};
use cumulus_primitives_core::PersistedValidationData;
use cumulus_primitives_core::{ParachainBlockData, PersistedValidationData};
use cumulus_primitives_parachain_inherent::{ParachainInherentData, INHERENT_IDENTIFIER};
use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
use cumulus_test_runtime::{Block, GetLastTimestamp};
use cumulus_test_runtime::{Block, GetLastTimestamp, Hash, Header};
use polkadot_primitives::v1::{BlockNumber as PBlockNumber, Hash as PHash};
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
use sp_api::ProvideRuntimeApi;
use sp_runtime::generic::BlockId;
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, Header as HeaderT},
};
/// An extension for the Cumulus test client to init a block builder.
pub trait InitBlockBuilder {
@@ -49,6 +52,70 @@ pub trait InitBlockBuilder {
validation_data: Option<PersistedValidationData<PHash, PBlockNumber>>,
relay_sproof_builder: RelayStateSproofBuilder,
) -> sc_block_builder::BlockBuilder<Block, Client, Backend>;
/// Init a specific block builder that works for the test runtime.
///
/// Same as [`InitBlockBuilder::init_block_builder`] besides that it takes a
/// [`BlockId`] to say which should be the parent block of the block that is being build and
/// it will use the given `timestamp` as input for the timestamp inherent.
fn init_block_builder_with_timestamp(
&self,
at: &BlockId<Block>,
validation_data: Option<PersistedValidationData<PHash, PBlockNumber>>,
relay_sproof_builder: RelayStateSproofBuilder,
timestamp: u64,
) -> sc_block_builder::BlockBuilder<Block, Client, Backend>;
}
fn init_block_builder<'a>(
client: &'a Client,
at: &BlockId<Block>,
validation_data: Option<PersistedValidationData<PHash, PBlockNumber>>,
relay_sproof_builder: RelayStateSproofBuilder,
timestamp: u64,
) -> BlockBuilder<'a, Block, Client, Backend> {
let mut block_builder = client
.new_block_at(at, Default::default(), true)
.expect("Creates new block builder for test runtime");
let mut inherent_data = sp_inherents::InherentData::new();
inherent_data
.put_data(sp_timestamp::INHERENT_IDENTIFIER, &timestamp)
.expect("Put timestamp failed");
let (relay_parent_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.relay_parent_storage_root,
Default::default(),
"Overriding the relay storage root is not implemented",
);
validation_data.relay_parent_storage_root = relay_parent_storage_root;
inherent_data
.put_data(
INHERENT_IDENTIFIER,
&ParachainInherentData {
validation_data,
relay_chain_state,
downward_messages: Default::default(),
horizontal_messages: Default::default(),
},
)
.expect("Put validation function params failed");
let inherents = block_builder
.create_inherents(inherent_data)
.expect("Creates inherents");
inherents
.into_iter()
.for_each(|ext| block_builder.push(ext).expect("Pushes inherent"));
block_builder
}
impl InitBlockBuilder for Client {
@@ -71,11 +138,6 @@ impl InitBlockBuilder for Client {
validation_data: Option<PersistedValidationData<PHash, PBlockNumber>>,
relay_sproof_builder: RelayStateSproofBuilder,
) -> BlockBuilder<Block, Client, Backend> {
let mut block_builder = self
.new_block_at(at, Default::default(), true)
.expect("Creates new block builder for test runtime");
let mut inherent_data = sp_inherents::InherentData::new();
let last_timestamp = self
.runtime_api()
.get_last_timestamp(&at)
@@ -83,41 +145,38 @@ impl InitBlockBuilder for Client {
let timestamp = last_timestamp + cumulus_test_runtime::MinimumPeriod::get();
inherent_data
.put_data(sp_timestamp::INHERENT_IDENTIFIER, &timestamp)
.expect("Put timestamp failed");
init_block_builder(self, at, validation_data, relay_sproof_builder, timestamp)
}
let (relay_parent_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.relay_parent_storage_root,
Default::default(),
"Overriding the relay storage root is not implemented",
);
validation_data.relay_parent_storage_root = relay_parent_storage_root;
inherent_data
.put_data(
INHERENT_IDENTIFIER,
&ParachainInherentData {
validation_data,
relay_chain_state,
downward_messages: Default::default(),
horizontal_messages: Default::default(),
},
)
.expect("Put validation function params failed");
let inherents = block_builder
.create_inherents(inherent_data)
.expect("Creates inherents");
inherents
.into_iter()
.for_each(|ext| block_builder.push(ext).expect("Pushes inherent"));
block_builder
fn init_block_builder_with_timestamp(
&self,
at: &BlockId<Block>,
validation_data: Option<PersistedValidationData<PHash, PBlockNumber>>,
relay_sproof_builder: RelayStateSproofBuilder,
timestamp: u64,
) -> sc_block_builder::BlockBuilder<Block, Client, Backend> {
init_block_builder(self, at, validation_data, relay_sproof_builder, timestamp)
}
}
/// Extension trait for the [`BlockBuilder`](sc_block_builder::BlockBuilder) to build directly a
/// [`ParachainBlockData`].
pub trait BuildParachainBlockData {
/// Directly build the [`ParachainBlockData`] from the block that comes out of the block builder.
fn build_parachain_block(self, parent_state_root: Hash) -> ParachainBlockData<Block>;
}
impl<'a> BuildParachainBlockData for sc_block_builder::BlockBuilder<'a, Block, Client, Backend> {
fn build_parachain_block(self, parent_state_root: Hash) -> ParachainBlockData<Block> {
let built_block = self.build().expect("Builds the block");
let storage_proof = built_block
.proof
.expect("We enabled proof recording before.")
.into_compact_proof::<<Header as HeaderT>::Hashing>(parent_state_root)
.expect("Creates the compact proof");
let (header, extrinsics) = built_block.block.deconstruct();
ParachainBlockData::new(header, extrinsics, storage_proof)
}
}
+41 -6
View File
@@ -1,36 +1,43 @@
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// This file is part of Cumulus.
// Substrate is free software: you can redistribute it and/or modify
// 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.
// Substrate is distributed in the hope that it will be useful,
// 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
//! A Polkadot test client.
//! A Cumulus test client.
mod block_builder;
use codec::Encode;
use codec::{Encode, Decode};
use runtime::{
Balance, Block, BlockHashCount, Call, GenesisConfig, Runtime, Signature, SignedExtra,
SignedPayload, UncheckedExtrinsic, VERSION,
};
use sc_executor::{sp_wasm_interface::HostFunctions, WasmExecutionMethod, WasmExecutor};
use sc_executor_common::runtime_blob::RuntimeBlob;
use sc_service::client;
use sp_blockchain::HeaderBackend;
use sp_core::storage::Storage;
use sp_io::TestExternalities;
use sp_runtime::{generic::Era, BuildStorage, SaturatedConversion};
pub use block_builder::*;
pub use cumulus_test_runtime as runtime;
pub use polkadot_parachain::primitives::{BlockData, HeadData, ValidationParams, ValidationResult};
pub use sc_executor::error::Result as ExecutorResult;
pub use substrate_test_client::*;
pub type ParachainBlockData = cumulus_primitives_core::ParachainBlockData<Block>;
mod local_executor {
use substrate_test_client::sc_executor::native_executor_instance;
native_executor_instance!(
@@ -159,3 +166,31 @@ pub fn transfer(
generate_extrinsic(client, origin, function)
}
/// Call `validate_block` in the given `wasm_blob`.
pub fn validate_block(
validation_params: ValidationParams,
wasm_blob: &[u8],
) -> ExecutorResult<ValidationResult> {
let mut ext = TestExternalities::default();
let mut ext_ext = ext.ext();
let executor = WasmExecutor::new(
WasmExecutionMethod::Interpreted,
Some(1024),
sp_io::SubstrateHostFunctions::host_functions(),
1,
None,
);
executor
.uncached_call(
RuntimeBlob::uncompress_if_needed(wasm_blob).expect("RuntimeBlob uncompress & parse"),
&mut ext_ext,
false,
"validate_block",
&validation_params.encode(),
)
.map(|v| ValidationResult::decode(&mut &v[..]).expect("Decode `ValidationResult`."))
.map_err(|err| err.into())
}
+2
View File
@@ -32,6 +32,7 @@ sp-version = { git = "https://github.com/paritytech/substrate", default-features
# Cumulus dependencies
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
cumulus-primitives-timestamp = { path = "../../primitives/timestamp", default-features = false }
# Polkadot dependencies
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
@@ -45,6 +46,7 @@ std = [
"codec/std",
"cumulus-pallet-parachain-system/std",
"cumulus-primitives-core/std",
"cumulus-primitives-timestamp/std",
"frame-executive/std",
"frame-support/std",
"frame-system/std",
+2
View File
@@ -32,6 +32,7 @@ sp-version = { git = "https://github.com/paritytech/substrate", default-features
# Cumulus dependencies
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
cumulus-primitives-timestamp = { path = "../../primitives/timestamp", default-features = false }
# Polkadot dependencies
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
@@ -45,6 +46,7 @@ std = [
"codec/std",
"cumulus-pallet-parachain-system/std",
"cumulus-primitives-core/std",
"cumulus-primitives-timestamp/std",
"frame-executive/std",
"frame-support/std",
"frame-system/std",
+13 -3
View File
@@ -96,7 +96,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
transaction_version: 1,
};
pub const MILLISECS_PER_BLOCK: u64 = 1000;
pub const MILLISECS_PER_BLOCK: u64 = 6000;
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
@@ -431,7 +431,7 @@ struct CheckInherents;
impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
fn check_inherents(
_: &[UncheckedExtrinsic],
block: &Block,
relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
) -> sp_inherents::CheckInherentsResult {
if relay_state_proof.read_slot().expect("Reads slot") == 1337u64 {
@@ -443,7 +443,17 @@ impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
.expect("Puts error");
res
} else {
sp_inherents::CheckInherentsResult::new()
let relay_chain_slot = relay_state_proof
.read_slot()
.expect("Could not read the relay chain slot from the proof");
let inherent_data =
cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
relay_chain_slot,
sp_std::time::Duration::from_secs(6),
).create_inherent_data().expect("Could not create the timestamp inherent data");
inherent_data.check_extrinsics(&block)
}
}
}
+1 -1
View File
@@ -60,7 +60,7 @@ cumulus-test-relay-validation-worker-provider = { path = "../relay-validation-wo
jsonrpc-core = "15.1.0"
[dev-dependencies]
futures = { version = "0.3.5" }
futures = "0.3.5"
tokio = { version = "0.2.21", features = ["macros"] }
# Polkadot dependencies