Remove v0 parachains runtime (#1501)

* remove v0 parachains modules and switch to v1 primitives

* get tests compiling for runtime-common

* remove registrar module

* Add a dummy module

* remove runtime-parachains

* mostly remove old parachains code from polkadot-runtime

* remove slots::Trait implementation

* remove sp_std prelude import

* add a ZeroSizedTypeDifferentiator to dummy

* finish porting over polkadot runtime

* ZeroSizedTypeDifferentiator was actually unnecessary

* westend

* kusama

* test-runtime (no dummy modules)

* fix warning

* fix chain-specs

* fix test-service

* test-client

* remove dead import

* remove unused needed_extrinsics parameter

* runtimes compile

* remove rococo-v0

* remove remaining references to Rococo

* bump versions
This commit is contained in:
Robert Habermeier
2020-08-13 15:55:27 +02:00
committed by GitHub
parent e6688620b5
commit 57aef8eef5
34 changed files with 415 additions and 8140 deletions
-214
View File
@@ -1,214 +0,0 @@
// Copyright 2019-2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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/>.
//! A module for tracking all attestations that fell on a given candidate receipt.
//!
//! In the future, it is planned that this module will handle dispute resolution
//! as well.
use sp_std::prelude::*;
use codec::{Encode, Decode};
use frame_support::{
decl_storage, decl_module, decl_error, ensure,
dispatch::DispatchResult,
traits::Get,
weights::DispatchClass,
};
use primitives::v0::{Hash, AttestedCandidate, AbridgedCandidateReceipt, Id as ParaId};
use sp_runtime::RuntimeDebug;
use sp_staking::SessionIndex;
use inherents::{ProvideInherent, InherentData, MakeFatalError, InherentIdentifier};
use frame_system::ensure_none;
/// Parachain blocks included in a recent relay-chain block.
#[derive(Encode, Decode)]
pub struct IncludedBlocks<T: Trait> {
/// The actual relay chain block number where blocks were included.
pub actual_number: T::BlockNumber,
/// The session index at this block.
pub session: SessionIndex,
/// The randomness seed at this block.
pub random_seed: [u8; 32],
/// All parachain IDs active at this block.
pub active_parachains: Vec<ParaId>,
/// Hashes of the parachain candidates included at this block.
pub para_blocks: Vec<Hash>,
}
/// Attestations kept over time on a parachain block.
#[derive(Encode, Decode)]
pub struct BlockAttestations<T: Trait> {
receipt: AbridgedCandidateReceipt,
valid: Vec<T::AccountId>, // stash account ID of voter.
invalid: Vec<T::AccountId>, // stash account ID of voter.
}
/// Additional attestations on a parachain block, after it was included.
#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug)]
pub struct MoreAttestations;
/// Something which processes rewards for received attestations.
pub trait RewardAttestation {
/// Reward immediate attestations on parachain blocks. The argument is an iterable of
/// validator indices of the attesting validators.
fn reward_immediate(validator_indices: impl IntoIterator<Item=u32>);
}
impl RewardAttestation for () {
fn reward_immediate(validator_indices: impl IntoIterator<Item=u32>) {
// ensure side-effecting iterators do work.
for _ in validator_indices {}
}
}
impl<T: pallet_staking::Trait> RewardAttestation for pallet_staking::Module<T> {
fn reward_immediate(validator_indices: impl IntoIterator<Item=u32>) {
use pallet_staking::SessionInterface;
// The number of points to reward for a validity statement.
// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#payment-details
const STAKING_REWARD_POINTS: u32 = 20;
let validators = T::SessionInterface::validators();
let validator_rewards = validator_indices.into_iter()
.filter_map(|i| validators.get(i as usize).cloned())
.map(|v| (v, STAKING_REWARD_POINTS));
Self::reward_by_ids(validator_rewards);
}
}
pub trait Trait: pallet_session::Trait {
/// How many blocks ago we're willing to accept attestations for.
type AttestationPeriod: Get<Self::BlockNumber>;
/// Get a list of the validators' underlying identities.
type ValidatorIdentities: Get<Vec<Self::AccountId>>;
/// Hook for rewarding validators upon attesting.
type RewardAttestation: RewardAttestation;
}
decl_storage! {
trait Store for Module<T: Trait> as Attestations {
/// A mapping from modular block number (n % AttestationPeriod)
/// to session index and the list of candidate hashes.
pub RecentParaBlocks: map hasher(twox_64_concat) T::BlockNumber => Option<IncludedBlocks<T>>;
/// Attestations on a recent parachain block.
pub ParaBlockAttestations:
double_map hasher(twox_64_concat) T::BlockNumber, hasher(identity) Hash
=> Option<BlockAttestations<T>>;
// Did we already have more attestations included in this block?
DidUpdate: bool;
}
}
decl_error! {
pub enum Error for Module<T: Trait> {
/// More attestations can be added only once in a block.
TooManyAttestations,
}
}
decl_module! {
/// Parachain-attestations module.
pub struct Module<T: Trait> for enum Call where origin: <T as frame_system::Trait>::Origin {
type Error = Error<T>;
/// Provide candidate receipts for parachains, in ascending order by id.
#[weight = (0, DispatchClass::Mandatory)]
fn more_attestations(origin, _more: MoreAttestations) -> DispatchResult {
ensure_none(origin)?;
ensure!(!DidUpdate::exists(), Error::<T>::TooManyAttestations);
DidUpdate::put(true);
Ok(())
}
fn on_finalize(_n: T::BlockNumber) {
DidUpdate::kill();
}
}
}
impl<T: Trait> Module<T> {
/// Update recent candidates to contain the already-checked parachain candidates.
pub(crate) fn note_included(heads: &[AttestedCandidate], para_blocks: IncludedBlocks<T>) {
let attestation_period = T::AttestationPeriod::get();
let mod_num = para_blocks.actual_number % attestation_period;
// clear old entry that was in this place.
if let Some(old_entry) = <RecentParaBlocks<T>>::take(&mod_num) {
<ParaBlockAttestations<T>>::remove_prefix(&old_entry.actual_number);
}
let validators = T::ValidatorIdentities::get();
// make new entry.
for (head, hash) in heads.iter().zip(&para_blocks.para_blocks) {
let mut valid = Vec::new();
let invalid = Vec::new();
{
let attesting_indices = head.validator_indices
.iter()
.enumerate()
.filter(|(_, bit)| **bit)
.inspect(|&(auth_index, _)| {
if let Some(stash_id) = validators.get(auth_index) {
valid.push(stash_id.clone());
}
})
.map(|(i, _)| i as u32);
T::RewardAttestation::reward_immediate(attesting_indices);
}
let summary = BlockAttestations {
receipt: head.candidate().clone(),
valid,
invalid,
};
<ParaBlockAttestations<T>>::insert(&para_blocks.actual_number, hash, &summary);
}
<RecentParaBlocks<T>>::insert(&mod_num, &para_blocks);
}
}
/// An identifier for inherent data that provides after-the-fact attestations
/// on already included parachain blocks.
pub const MORE_ATTESTATIONS_IDENTIFIER: InherentIdentifier = *b"par-atts";
pub type InherentType = MoreAttestations;
impl<T: Trait> ProvideInherent for Module<T> {
type Call = Call<T>;
type Error = MakeFatalError<inherents::Error>;
const INHERENT_IDENTIFIER: InherentIdentifier = MORE_ATTESTATIONS_IDENTIFIER;
fn create_inherent(data: &InherentData) -> Option<Self::Call> {
data.get_data::<InherentType>(&MORE_ATTESTATIONS_IDENTIFIER)
.ok()
.and_then(|x| x.map(Call::more_attestations))
}
}
+1 -1
View File
@@ -35,7 +35,7 @@ use sp_runtime::{
TransactionSource, TransactionValidityError,
},
};
use primitives::v0::ValidityError;
use primitives::v1::ValidityError;
type CurrencyOf<T> = <<T as Trait>::VestingSchedule as VestingSchedule<<T as frame_system::Trait>::AccountId>>::Currency;
type BalanceOf<T> = <CurrencyOf<T> as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
+4 -8
View File
@@ -79,7 +79,7 @@ use sp_runtime::{ModuleId,
use crate::slots;
use codec::{Encode, Decode};
use sp_std::vec::Vec;
use primitives::v0::{Id as ParaId, HeadData};
use primitives::v1::{Id as ParaId, HeadData};
pub type BalanceOf<T> =
<<T as slots::Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
@@ -568,14 +568,14 @@ mod tests {
};
use frame_support::traits::{Contains, ContainsLengthBound};
use sp_core::H256;
use primitives::v0::{Info as ParaInfo, Id as ParaId, Scheduling, ValidationCode};
use primitives::v1::{Id as ParaId, ValidationCode};
// The testing primitives are very useful for avoiding having to work with signatures
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
use sp_runtime::{
Perbill, Permill, Percent, testing::Header, DispatchResult,
traits::{BlakeTwo256, IdentityLookup},
};
use crate::registrar::Registrar;
use crate::slots::Registrar;
impl_outer_origin! {
pub enum Origin for Test {}
@@ -699,13 +699,9 @@ mod tests {
code_size <= MAX_CODE_SIZE
}
fn para_info(_id: ParaId) -> Option<ParaInfo> {
Some(ParaInfo { scheduling: Scheduling::Always })
}
fn register_para(
id: ParaId,
_info: ParaInfo,
_parachain: bool,
code: ValidationCode,
initial_head_data: HeadData,
) -> DispatchResult {
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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/>.
//! A dummy module for holding place of modules in a runtime.
use frame_support::{decl_module, decl_storage};
pub trait Trait<I: Instance = DefaultInstance>: frame_system::Trait { }
decl_module! {
pub struct Module<T: Trait<I>, I: Instance = DefaultInstance> for enum Call where origin: T::Origin {
}
}
decl_storage! {
trait Store for Module<T: Trait<I>, I: Instance = DefaultInstance> as Dummy { }
}
+2 -2
View File
@@ -26,8 +26,8 @@ pub struct ToAuthor<R>(sp_std::marker::PhantomData<R>);
impl<R> OnUnbalanced<NegativeImbalance<R>> for ToAuthor<R>
where
R: pallet_balances::Trait + pallet_authorship::Trait,
<R as frame_system::Trait>::AccountId: From<primitives::v0::AccountId>,
<R as frame_system::Trait>::AccountId: Into<primitives::v0::AccountId>,
<R as frame_system::Trait>::AccountId: From<primitives::v1::AccountId>,
<R as frame_system::Trait>::AccountId: Into<primitives::v1::AccountId>,
<R as frame_system::Trait>::Event: From<pallet_balances::RawEvent<
<R as frame_system::Trait>::AccountId,
<R as pallet_balances::Trait>::Balance,
+32 -6
View File
@@ -18,18 +18,17 @@
#![cfg_attr(not(feature = "std"), no_std)]
pub mod attestations;
pub mod claims;
pub mod parachains;
pub mod slot_range;
pub mod registrar;
pub mod slots;
pub mod crowdfund;
pub mod purchase;
pub mod impls;
pub mod paras_sudo_wrapper;
use primitives::v0::BlockNumber;
pub mod dummy;
use primitives::v1::{BlockNumber, ValidatorId};
use sp_runtime::{Perquintill, Perbill, FixedPointNumber, traits::Saturating};
use frame_support::{
parameter_types, traits::{Currency},
@@ -45,8 +44,6 @@ pub use pallet_staking::StakerStatus;
pub use sp_runtime::BuildStorage;
pub use pallet_timestamp::Call as TimestampCall;
pub use pallet_balances::Call as BalancesCall;
pub use attestations::{Call as AttestationsCall, MORE_ATTESTATIONS_IDENTIFIER};
pub use parachains::Call as ParachainsCall;
/// Implementations of some helper traits passed into runtime modules as associated types.
pub use impls::{CurrencyToVoteHandler, ToAuthor};
@@ -92,6 +89,35 @@ pub type SlowAdjustingFeeUpdate<R> = TargetedFeeAdjustment<
MinimumMultiplier
>;
/// A placeholder since there is currently no provided session key handler for parachain validator
/// keys.
pub struct ParachainSessionKeyPlaceholder<T>(sp_std::marker::PhantomData<T>);
impl<T> sp_runtime::BoundToRuntimeAppPublic for ParachainSessionKeyPlaceholder<T> {
type Public = ValidatorId;
}
impl<T: pallet_session::Trait>
pallet_session::OneSessionHandler<T::AccountId> for ParachainSessionKeyPlaceholder<T>
{
type Key = ValidatorId;
fn on_genesis_session<'a, I: 'a>(_validators: I) where
I: Iterator<Item = (&'a T::AccountId, ValidatorId)>,
T::AccountId: 'a
{
}
fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I) where
I: Iterator<Item = (&'a T::AccountId, ValidatorId)>,
T::AccountId: 'a
{
}
fn on_disabled(_: usize) { }
}
#[cfg(test)]
mod multiplier_tests {
use super::*;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+65 -11
View File
@@ -28,11 +28,10 @@ use frame_support::{
traits::{Currency, ReservableCurrency, WithdrawReason, ExistenceRequirement, Get, Randomness},
weights::{DispatchClass, Weight},
};
use primitives::v0::{
SwapAux, PARACHAIN_INFO, Id as ParaId, ValidationCode, HeadData,
use primitives::v1::{
Id as ParaId, ValidationCode, HeadData,
};
use frame_system::{ensure_signed, ensure_root};
use crate::registrar::{Registrar, swap_ordered_existence};
use crate::slot_range::{SlotRange, SLOT_RANGE_COUNT};
type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
@@ -58,6 +57,50 @@ pub trait Trait: frame_system::Trait {
type Randomness: Randomness<Self::Hash>;
}
/// Parachain registration API.
pub trait Registrar<AccountId> {
/// Create a new unique parachain identity for later registration.
fn new_id() -> ParaId;
/// Checks whether the given initial head data size falls within the limit.
fn head_data_size_allowed(head_data_size: u32) -> bool;
/// Checks whether the given validation code falls within the limit.
fn code_size_allowed(code_size: u32) -> bool;
/// Register a parachain with given `code` and `initial_head_data`. `id` must not yet be registered or it will
/// result in a error.
///
/// This does not enforce any code size or initial head data limits, as these
/// are governable and parameters for parachain initialization are often
/// determined long ahead-of-time. Not checking these values ensures that changes to limits
/// do not invalidate in-progress auction winners.
fn register_para(
id: ParaId,
_parachain: bool,
code: ValidationCode,
initial_head_data: HeadData,
) -> DispatchResult;
/// Deregister a parachain with given `id`. If `id` is not currently registered, an error is returned.
fn deregister_para(id: ParaId) -> DispatchResult;
}
/// Auxilliary for when there's an attempt to swap two parachains/parathreads.
pub trait SwapAux {
/// Result describing whether it is possible to swap two parachains. Doesn't mutate state.
fn ensure_can_swap(one: ParaId, other: ParaId) -> Result<(), &'static str>;
/// Updates any needed state/references to enact a logical swap of two parachains. Identity,
/// code and `head_data` remain equivalent for all parachains/threads, however other properties
/// such as leases, deposits held and thread/chain nature are swapped.
///
/// May only be called on a state that `ensure_can_swap` has previously returned `Ok` for: if this is
/// not the case, the result is undefined. May only return an error if `ensure_can_swap` also returns
/// an error.
fn on_swap(one: ParaId, other: ParaId) -> Result<(), &'static str>;
}
/// A sub-bidder identifier. Used to distinguish between different logical bidders coming from the
/// same account ID.
pub type SubId = u32;
@@ -187,6 +230,21 @@ decl_storage! {
}
}
/// Swap the existence of two items, provided by value, within an ordered list.
///
/// If neither item exists, or if both items exist this will do nothing. If exactly one of the
/// items exists, then it will be removed and the other inserted.
fn swap_ordered_existence<T: PartialOrd + Ord + Copy>(ids: &mut [T], one: T, other: T) {
let maybe_one_pos = ids.binary_search(&one);
let maybe_other_pos = ids.binary_search(&other);
match (maybe_one_pos, maybe_other_pos) {
(Ok(one_pos), Err(_)) => ids[one_pos] = other,
(Err(_), Ok(other_pos)) => ids[other_pos] = one,
_ => return,
};
ids.sort();
}
impl<T: Trait> SwapAux for Module<T> {
fn ensure_can_swap(one: ParaId, other: ParaId) -> Result<(), &'static str> {
if <Onboarding<T>>::contains_key(one) || <Onboarding<T>>::contains_key(other) {
@@ -470,7 +528,7 @@ decl_module! {
// parachain for its immediate start.
<Onboarding<T>>::remove(&para_id);
let _ = T::Parachains::
register_para(para_id, PARACHAIN_INFO, code, initial_head_data);
register_para(para_id, true, code, initial_head_data);
}
Ok(())
@@ -719,7 +777,7 @@ impl<T: Trait> Module<T> {
// The chain's deployment data is set; go ahead and register it, and remove the
// now-redundant on-boarding entry.
let _ = T::Parachains::
register_para(para_id.clone(), PARACHAIN_INFO, code, initial_head_data);
register_para(para_id.clone(), true, code, initial_head_data);
// ^^ not much we can do if it fails for some reason.
<Onboarding<T>>::remove(para_id)
}
@@ -890,7 +948,7 @@ mod tests {
traits::{OnInitialize, OnFinalize}
};
use pallet_balances;
use primitives::v0::{BlockNumber, Header, Id as ParaId, Info as ParaInfo, Scheduling};
use primitives::v1::{BlockNumber, Header, Id as ParaId};
impl_outer_origin! {
pub enum Origin for Test {}
@@ -974,13 +1032,9 @@ mod tests {
code_size <= MAX_CODE_SIZE
}
fn para_info(_id: ParaId) -> Option<ParaInfo> {
Some(ParaInfo { scheduling: Scheduling::Always })
}
fn register_para(
id: ParaId,
_info: ParaInfo,
_parachain: bool,
code: ValidationCode,
initial_head_data: HeadData,
) -> DispatchResult {