From 8fda50ee6f2ca950046f5f593f4ef79660106b4b Mon Sep 17 00:00:00 2001 From: Gavin Wood <gavin@parity.io> Date: Thu, 29 Apr 2021 18:21:48 +0200 Subject: [PATCH] Strip down Shell to bare minimum (#421) * Strip down shell * Fixes * Fixes * Fixes * Fixes --- cumulus/Cargo.lock | 5 - cumulus/pallets/parachain-system/src/lib.rs | 39 ++- .../shell-runtime/Cargo.toml | 9 - .../shell-runtime/src/lib.rs | 255 +++++------------- cumulus/rococo-parachains/src/chain_spec.rs | 1 - 5 files changed, 106 insertions(+), 203 deletions(-) diff --git a/cumulus/Cargo.lock b/cumulus/Cargo.lock index df232e2f075..80c659a30cb 100644 --- a/cumulus/Cargo.lock +++ b/cumulus/Cargo.lock @@ -1554,11 +1554,6 @@ dependencies = [ "hex", "hex-literal 0.3.1", "log", - "pallet-balances", - "pallet-randomness-collective-flip", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-xcm", "parachain-info", "parity-scale-codec", "polkadot-parachain", diff --git a/cumulus/pallets/parachain-system/src/lib.rs b/cumulus/pallets/parachain-system/src/lib.rs index 7fec98c2656..aa21fbc9a54 100644 --- a/cumulus/pallets/parachain-system/src/lib.rs +++ b/cumulus/pallets/parachain-system/src/lib.rs @@ -49,6 +49,11 @@ use cumulus_primitives_core::{ }; use cumulus_primitives_parachain_inherent::ParachainInherentData; use relay_state_snapshot::MessagingStateSnapshot; +use sp_runtime::transaction_validity::{ + TransactionSource, TransactionValidity, InvalidTransaction, ValidTransaction, + TransactionLongevity, +}; +use sp_runtime::DispatchError; mod relay_state_snapshot; #[macro_use] @@ -261,10 +266,7 @@ decl_module! { #[weight = 1_000_000] fn enact_authorized_upgrade(_origin, code: Vec<u8>) -> DispatchResultWithPostInfo { // No ensure origin on purpose. We validate by checking the code vs hash in storage. - let required_hash = AuthorizedUpgrade::<T>::get() - .ok_or(Error::<T>::NothingAuthorized)?; - let actual_hash = T::Hashing::hash(&code[..]); - ensure!(actual_hash == required_hash, Error::<T>::Unauthorized); + Self::validate_authorized_upgrade(&code[..])?; Self::set_code_impl(code)?; AuthorizedUpgrade::<T>::kill(); Ok(Pays::No.into()) @@ -403,6 +405,35 @@ decl_module! { } } +impl<T: Config> Module<T> { + fn validate_authorized_upgrade(code: &[u8]) -> Result<T::Hash, DispatchError> { + let required_hash = AuthorizedUpgrade::<T>::get() + .ok_or(Error::<T>::NothingAuthorized)?; + let actual_hash = T::Hashing::hash(&code[..]); + ensure!(actual_hash == required_hash, Error::<T>::Unauthorized); + Ok(actual_hash) + } +} + +impl<T: Config> sp_runtime::traits::ValidateUnsigned for Module<T> { + type Call = Call<T>; + + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { + if let Call::enact_authorized_upgrade(ref code) = call { + if let Ok(hash) = Self::validate_authorized_upgrade(code) { + return Ok(ValidTransaction { + priority: 100, + requires: vec![], + provides: vec![hash.as_ref().to_vec()], + longevity: TransactionLongevity::max_value(), + propagate: true, + }) + } + } + Err(InvalidTransaction::Call.into()) + } +} + impl<T: Config> GetChannelInfo for Module<T> { fn get_channel_status(id: ParaId) -> ChannelStatus { // Note, that we are using `relevant_messaging_state` which may be from the previous diff --git a/cumulus/rococo-parachains/shell-runtime/Cargo.toml b/cumulus/rococo-parachains/shell-runtime/Cargo.toml index 0aab8e91c24..0bf45acd0dc 100644 --- a/cumulus/rococo-parachains/shell-runtime/Cargo.toml +++ b/cumulus/rococo-parachains/shell-runtime/Cargo.toml @@ -27,10 +27,6 @@ sp-inherents = { git = "https://github.com/paritytech/substrate", default-featur frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } -pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } -pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } -pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } # Cumulus dependencies cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false } @@ -44,7 +40,6 @@ polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-f xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } xcm-builder = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } -pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } [dev-dependencies] hex = "0.4.3" @@ -73,10 +68,6 @@ std = [ "frame-support/std", "frame-executive/std", "frame-system/std", - "pallet-balances/std", - "pallet-randomness-collective-flip/std", - "pallet-timestamp/std", - "pallet-transaction-payment/std", "parachain-info/std", "rococo-parachain-primitives/std", "cumulus-pallet-parachain-system/std", diff --git a/cumulus/rococo-parachains/shell-runtime/src/lib.rs b/cumulus/rococo-parachains/shell-runtime/src/lib.rs index 83ff647b480..38396508f54 100644 --- a/cumulus/rococo-parachains/shell-runtime/src/lib.rs +++ b/cumulus/rococo-parachains/shell-runtime/src/lib.rs @@ -26,7 +26,7 @@ use rococo_parachain_primitives::*; use sp_api::impl_runtime_apis; use sp_core::OpaqueMetadata; use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, + create_runtime_str, generic, traits::{BlakeTwo256, Block as BlockT, AccountIdLookup}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, @@ -38,7 +38,7 @@ use sp_version::RuntimeVersion; // A few exports that help ease life for downstream crates. pub use frame_support::{ - construct_runtime, parameter_types, + construct_runtime, parameter_types, match_type, traits::{Randomness, All, IsInVec}, weights::{ constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, @@ -47,28 +47,18 @@ pub use frame_support::{ StorageValue, }; use frame_system::limits::{BlockLength, BlockWeights}; -pub use pallet_balances::Call as BalancesCall; -pub use pallet_timestamp::Call as TimestampCall; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; // XCM imports -use polkadot_parachain::primitives::Sibling; -use xcm::v0::{Junction, MultiLocation, NetworkId}; +use xcm::v0::{Junction::*, MultiLocation, MultiLocation::*, NetworkId}; use xcm_builder::{ - AccountId32Aliases, CurrencyAdapter, LocationInverter, ParentIsDefault, RelayChainAsNative, - SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, - SovereignSignedViaLocation, FixedRateOfConcreteFungible, EnsureXcmOrigin, - AllowTopLevelPaidExecutionFrom, TakeWeightCredit, FixedWeightBounds, IsConcrete, NativeAsset, - AllowUnpaidExecutionFrom, ParentAsSuperuser, + LocationInverter, ParentIsDefault, FixedWeightBounds, AllowUnpaidExecutionFrom, + ParentAsSuperuser, SovereignSignedViaLocation, }; use xcm_executor::{Config, XcmExecutor}; -impl_opaque_keys! { - pub struct SessionKeys {} -} - /// This runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("shell"), @@ -80,20 +70,6 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { transaction_version: 1, }; -pub const MILLISECS_PER_BLOCK: u64 = 6000; - -pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; - -pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES; - -// These time units are defined in number of blocks. -pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); -pub const HOURS: BlockNumber = MINUTES * 60; -pub const DAYS: BlockNumber = HOURS * 24; - -// 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. -pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); - /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { @@ -103,7 +79,7 @@ pub fn native_version() -> NativeVersion { } } -/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers. +/// We assume that ~10% of the block weight is consumed by `on_initialize` handlers. /// This is used to limit the maximal weight of a single extrinsic. const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10); /// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used @@ -165,7 +141,7 @@ impl frame_system::Config for Runtime { type Version = Version; /// Converts a module to an index of this module in the runtime. type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData<Balance>; + type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); type DbWeight = (); @@ -178,46 +154,8 @@ impl frame_system::Config for Runtime { } parameter_types! { - pub const MinimumPeriod: u64 = SLOT_DURATION / 2; -} - -impl pallet_timestamp::Config for Runtime { - /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} - -parameter_types! { - pub const ExistentialDeposit: u128 = 500; - pub const TransferFee: u128 = 0; - pub const CreationFee: u128 = 0; - pub const TransactionByteFee: u128 = 1; - pub const MaxLocks: u32 = 50; -} - -impl pallet_balances::Config for Runtime { - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type Event = Event; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); - type MaxLocks = MaxLocks; -} - -impl pallet_transaction_payment::Config for Runtime { - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, ()>; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = IdentityFee<Balance>; - type FeeMultiplierUpdate = (); -} - -parameter_types! { - pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; + // We do anything the parent chain tells us in this runtime. + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT; } impl cumulus_pallet_parachain_system::Config for Runtime { @@ -225,124 +163,68 @@ impl cumulus_pallet_parachain_system::Config for Runtime { type OnValidationData = (); type SelfParaId = parachain_info::Module<Runtime>; type DownwardMessageHandlers = CumulusXcm; - type OutboundXcmpMessageSource = XcmpQueue; - type XcmpMessageHandler = XcmpQueue; - type ReservedXcmpWeight = ReservedXcmpWeight; + type OutboundXcmpMessageSource = (); + type XcmpMessageHandler = (); + type ReservedXcmpWeight = (); } impl parachain_info::Config for Runtime {} parameter_types! { - pub const RococoLocation: MultiLocation = MultiLocation::X1(Junction::Parent); + pub const RococoLocation: MultiLocation = X1(Parent); pub const RococoNetwork: NetworkId = NetworkId::Polkadot; - pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); - pub Ancestry: MultiLocation = Junction::Parachain( - ParachainInfo::parachain_id().into() - ).into(); + pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used -/// when determining ownership of accounts for asset transacting and when attempting to use XCM -/// `Transact` in order to determine the dispatch Origin. -pub type LocationToAccountId = ( - // The parent (Relay-chain) origin converts to the default `AccountId`. - ParentIsDefault<AccountId>, - // Sibling parachain origins convert to AccountId via the `ParaId::into`. - SiblingParachainConvertsVia<Sibling, AccountId>, - // Straight up local `AccountId32` origins just alias directly to `AccountId`. - AccountId32Aliases<RococoNetwork, AccountId>, -); - -/// Means for transacting assets on this chain. -pub type LocalAssetTransactor = CurrencyAdapter< - // Use this currency: - Balances, - // Use this currency when it is a fungible asset matching the given location or name: - IsConcrete<RococoLocation>, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: - LocationToAccountId, - // Our chain's account ID type (we can't get away without mentioning it explicitly): - AccountId, ->; - /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, /// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can -/// biases the kind of local `Origin` it will become. +/// bias the kind of local `Origin` it will become. pub type XcmOriginToTransactDispatchOrigin = ( // Sovereign account converter; this attempts to derive an `AccountId` from the origin location // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for // foreign chains who want to have a local sovereign account on this chain which they control. - SovereignSignedViaLocation<LocationToAccountId, Origin>, - // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when - // recognised. - RelayChainAsNative<RelayChainOrigin, Origin>, - // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when - // recognised. - SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>, + SovereignSignedViaLocation<ParentIsDefault<AccountId>, Origin>, // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a // transaction from the Root origin. ParentAsSuperuser<Origin>, - // Native signed account converter; this just converts an `AccountId32` origin into a normal - // `Origin::Signed` origin of the same 32-byte value. - SignedAccountId32AsNative<RococoNetwork, Origin>, ); -parameter_types! { - pub UnitWeightCost: Weight = 1_000; +match_type! { + pub type JustTheParent: impl Contains<MultiLocation> = { X1(Parent) }; } parameter_types! { - // 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight. - // TODO: Should take the actual weight price. This is just 1_000 ROC per second of weight. - pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::X1(Junction::Parent), 1_000); - pub AllowUnpaidFrom: Vec<MultiLocation> = vec![ MultiLocation::X1(Junction::Parent) ]; + // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate. + pub UnitWeightCost: Weight = 1_000_000; } -pub type Barrier = ( - TakeWeightCredit, - AllowTopLevelPaidExecutionFrom<All<MultiLocation>>, - AllowUnpaidExecutionFrom<IsInVec<AllowUnpaidFrom>>, // <- Parent gets free execution -); +pub struct NoTrader; +impl xcm_executor::traits::WeightTrader for NoTrader { + fn new() -> Self { NoTrader } + fn buy_weight(&mut self, _: Weight, _: xcm_executor::Assets) + -> Result<xcm_executor::Assets, xcm::v0::Error> + { + Err(xcm::v0::Error::Unimplemented) + } +} pub struct XcmConfig; impl Config for XcmConfig { type Call = Call; - type XcmSender = XcmRouter; - // How to withdraw and deposit an asset. - type AssetTransactor = LocalAssetTransactor; + type XcmSender = (); // sending XCM not supported + type AssetTransactor = (); // balances not supported type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = NativeAsset; - type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of ROC + type IsReserve = (); // balances not supported + type IsTeleporter = (); // balances not supported type LocationInverter = LocationInverter<Ancestry>; - type Barrier = Barrier; - type Weigher = FixedWeightBounds<UnitWeightCost, Call>; - type Trader = FixedRateOfConcreteFungible<WeightPrice, ()>; + type Barrier = AllowUnpaidExecutionFrom<JustTheParent>; + type Weigher = FixedWeightBounds<UnitWeightCost, Call>; // balances not supported + type Trader = NoTrader; // balances not supported type ResponseHandler = (); // Don't handle responses for now. } parameter_types! { - pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10; -} - -/// No local origins on this chain are allowed to dispatch XCM sends/executions. -pub type LocalOriginToLocation = (); - -/// The means for routing XCM messages which are not for local execution into the right message -/// queues. -pub type XcmRouter = ( - // Two routers - use UMP to communicate with the relay chain: - cumulus_primitives_utility::ParentAsUmp<ParachainSystem>, - // ..and XCMP to communicate with the sibling chains. - XcmpQueue, -); - -impl pallet_xcm::Config for Runtime { - type Event = Event; - type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>; - type XcmRouter = XcmRouter; - type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>; - type XcmExecuteFilter = All<(MultiLocation, xcm::v0::Xcm<Call>)>; - type XcmExecutor = XcmExecutor<XcmConfig>; + pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 2; } impl cumulus_pallet_xcm::Config for Runtime { @@ -351,12 +233,6 @@ impl cumulus_pallet_xcm::Config for Runtime { type MaxWeight = MaxDownwardMessageWeight; } -impl cumulus_pallet_xcmp_queue::Config for Runtime { - type Event = Event; - type XcmExecutor = XcmExecutor<XcmConfig>; - type ChannelInfo = ParachainSystem; -} - construct_runtime! { pub enum Runtime where Block = Block, @@ -364,20 +240,40 @@ construct_runtime! { UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Storage, Config, Event<T>}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>}, - RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Call, Storage}, - ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage}, + ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>, ValidateUnsigned}, ParachainInfo: parachain_info::{Pallet, Storage, Config}, - // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>}, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin}, + // DMP handler. CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin}, } } +/// Simple implementation which fails any transaction which is signed. +#[derive(Eq, PartialEq, Clone, Default, sp_core::RuntimeDebug, codec::Encode, codec::Decode)] +pub struct DisallowSigned; +impl sp_runtime::traits::SignedExtension for DisallowSigned { + const IDENTIFIER: &'static str = "DisallowSigned"; + type AccountId = AccountId; + type Call = Call; + type AdditionalSigned = (); + type Pre = (); + fn additional_signed(&self) + -> sp_std::result::Result<(), sp_runtime::transaction_validity::TransactionValidityError> + { + Ok(()) + } + fn validate( + &self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &sp_runtime::traits::DispatchInfoOf<Self::Call>, + _len: usize, + ) -> TransactionValidity { + let i = sp_runtime::transaction_validity::InvalidTransaction::BadProof; + Err(sp_runtime::transaction_validity::TransactionValidityError::Invalid(i)) + } +} + /// The address format for describing accounts. pub type Address = sp_runtime::MultiAddress<AccountId, ()>; /// Block header type as expected by this runtime. @@ -389,14 +285,7 @@ pub type SignedBlock = generic::SignedBlock<Block>; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId<Block>; /// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( - frame_system::CheckSpecVersion<Runtime>, - frame_system::CheckGenesis<Runtime>, - frame_system::CheckEra<Runtime>, - frame_system::CheckNonce<Runtime>, - frame_system::CheckWeight<Runtime>, - pallet_transaction_payment::ChargeTransactionPayment<Runtime>, -); +pub type SignedExtra = DisallowSigned; /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>; /// Extrinsic type that has already been checked. @@ -451,7 +340,7 @@ impl_runtime_apis! { } fn random_seed() -> <Block as BlockT>::Hash { - RandomnessCollectiveFlip::random_seed().0 + System::parent_hash() } } @@ -471,14 +360,12 @@ impl_runtime_apis! { } impl sp_session::SessionKeys<Block> for Runtime { - fn decode_session_keys( - encoded: Vec<u8>, - ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) + fn decode_session_keys(_: Vec<u8>) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> { + Some(Vec::new()) } - fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> { - SessionKeys::generate(seed) + fn generate_session_keys(_: Option<Vec<u8>>) -> Vec<u8> { + Vec::new() } } } diff --git a/cumulus/rococo-parachains/src/chain_spec.rs b/cumulus/rococo-parachains/src/chain_spec.rs index b07f5d5cab0..4f3cf3bc42d 100644 --- a/cumulus/rococo-parachains/src/chain_spec.rs +++ b/cumulus/rococo-parachains/src/chain_spec.rs @@ -173,7 +173,6 @@ fn shell_testnet_genesis(parachain_id: ParaId) -> shell_runtime::GenesisConfig { .to_vec(), changes_trie_config: Default::default(), }, - pallet_balances: shell_runtime::BalancesConfig::default(), parachain_info: shell_runtime::ParachainInfoConfig { parachain_id }, } } -- GitLab