Unverified Commit 2213e91d authored by Gavin Wood's avatar Gavin Wood Committed by GitHub
Browse files

Introduce Parathreads (runtime) (#341)

* Rest of parathread draft implementation, parachain permissioning.

* Update Substrate

* Update Substrate again

* Integrate weight/fee stuff.

* Council

* Build fixes

* More fixes

* Minor additions

* fix some small errors

* Revert "fix some small errors"

This reverts commit 4fb52c82

.

* Merge fix.

* do_swap -> on_swap

* Update depdendency to polkadot-master

* Fix more merge problems

* Some patching of errors

* Fix storage closure

* Actually fix storage. It builds!

* Tests run... but not successfully.

* Add `run_to_block` to get parachains active to start

* More `run_to_block`

* Fix build

* Queue up changes to threads

* Move registration test

* Fix regsiter/deregister test

* Retry queue.

* Minor refactor

* Refactor to avoid heavy storage items

* Make tests pass

* remove para on deregister, add events

* Remove println

* Fix register/deregister parathread test

* fix merge

* Parathread can be activated test

* Test auction

* Add `Debtors` storage item

I considered putting the debtor information in `ParaInfo`, but it did not make sense to me since this information only applies to parathreads, not `paras` in general.

* remove comment code

* Some new tests

* Fixes for removing threads when scheduled. Tests.

* Test progression of threads.

* Test that reschedule queuing works properly.

* Make test slightly more interesting

* whitespace

* Swap works properly.

* Update locks

* Build

* Rename can_swap

* Add test for funds to be correctly returned after a swap

Swap does not seem to have logic which correctly swaps the debtor account to the new parathread.

* Make tests consistant

* Add check that `PendingSwap` is cleaned up

* Update runtime/src/parachains.rs
Co-Authored-By: asynchronous rob's avatarRobert Habermeier <rphmeier@gmail.com>

* Update runtime/src/registrar.rs
Co-Authored-By: asynchronous rob's avatarRobert Habermeier <rphmeier@gmail.com>

* Some fixes/suggestions from review

* Docs

* Apply suggestions from code review
Co-Authored-By: asynchronous rob's avatarRobert Habermeier <rphmeier@gmail.com>
Co-Authored-By: Shawn Tabrizi's avatarShawn Tabrizi <shawntabrizi@gmail.com>

* Update network/src/gossip.rs
Co-Authored-By: asynchronous rob's avatarRobert Habermeier <rphmeier@gmail.com>

* Rename OnSwap

* Add missing `]`

* Rejig ordering semantics, making everything a bit slower but correct.

* Some Fixes to Parathread Compile (#470)

* Some Fixes

* Fix queue_upward_messages

* Change back to const

* Build fixes

* Fix tests
parent 4d12bd08
Pipeline #53741 passed with stages
in 15 minutes and 26 seconds
......@@ -2773,6 +2773,7 @@ dependencies = [
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"shared_memory 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
"substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
"tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -2805,6 +2806,7 @@ dependencies = [
"libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"polkadot-parachain 0.6.0",
"polkadot-primitives 0.6.0",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
......
......@@ -265,7 +265,8 @@ impl<F, P> ChainContext for (F, P) where
let leaf_id = BlockId::Hash(leaf);
let active_parachains = api.active_parachains(&leaf_id)?;
for para_id in active_parachains {
// TODO: https://github.com/paritytech/polkadot/issues/467
for (para_id, _) in active_parachains {
if let Some(ingress) = api.ingress(&leaf_id, para_id, None)? {
for (_height, _from, queue_root) in ingress.iter() {
with_queue_root(queue_root);
......
......@@ -30,7 +30,7 @@ use polkadot_primitives::{Block, BlockNumber, Hash, Header, BlockId};
use polkadot_primitives::parachain::{
Id as ParaId, Chain, DutyRoster, ParachainHost, TargetedMessage,
ValidatorId, StructuredUnroutedIngress, BlockIngressRoots, Status,
FeeSchedule, HeadData,
FeeSchedule, HeadData, Retriable, CollatorId
};
use parking_lot::Mutex;
use substrate_client::error::Result as ClientResult;
......@@ -177,7 +177,7 @@ impl NetworkService for TestNetwork {
struct ApiData {
validators: Vec<ValidatorId>,
duties: Vec<Chain>,
active_parachains: Vec<ParaId>,
active_parachains: Vec<(ParaId, Option<(CollatorId, Retriable)>)>,
ingress: HashMap<ParaId, StructuredUnroutedIngress>,
}
......@@ -279,7 +279,7 @@ impl ParachainHost<Block> for RuntimeApi {
_: ExecutionContext,
_: Option<()>,
_: Vec<u8>,
) -> ClientResult<NativeOrEncoded<Vec<ParaId>>> {
) -> ClientResult<NativeOrEncoded<Vec<(ParaId, Option<(CollatorId, Retriable)>)>>> {
Ok(NativeOrEncoded::Native(self.data.lock().active_parachains.clone()))
}
......
......@@ -11,6 +11,7 @@ wasmi = { version = "0.4.3", optional = true }
derive_more = { version = "0.14", optional = true }
serde = { version = "1.0", default-features = false, features = [ "derive" ] }
rstd = { package = "sr-std", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
substrate-primitives = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
lazy_static = { version = "1.3.0", optional = true }
parking_lot = { version = "0.7.1", optional = true }
log = { version = "0.4.6", optional = true }
......@@ -33,6 +34,7 @@ std = [
"serde/std",
"rstd/std",
"shared_memory",
"substrate-primitives/std",
"lazy_static",
"parking_lot",
"log"
......
......@@ -54,6 +54,7 @@ pub mod wasm_api;
use rstd::vec::Vec;
use codec::{Encode, Decode};
use substrate_primitives::TypeId;
/// Validation parameters for evaluating the parachain validity function.
// TODO: balance downloads (https://github.com/paritytech/polkadot/issues/220)
......@@ -82,6 +83,16 @@ pub struct ValidationResult {
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize, Debug))]
pub struct Id(u32);
impl TypeId for Id {
const TYPE_ID: [u8; 4] = *b"para";
}
/// Type for determining the active set of parachains.
pub trait ActiveThreads {
/// Return the current ordered set of `Id`s of active parathreads.
fn active_threads() -> Vec<Id>;
}
impl codec::CompactAs for Id {
type As = u32;
fn encode_as(&self) -> &u32 {
......@@ -105,11 +116,19 @@ impl From<u32> for Id {
fn from(x: u32) -> Self { Id(x) }
}
const USER_INDEX_START: u32 = 1000;
/// The ID of the first user (non-system) parachain.
pub const LOWEST_USER_ID: Id = Id(USER_INDEX_START);
impl Id {
/// Convert this Id into its inner representation.
pub fn into_inner(self) -> u32 {
self.0
}
/// Returns `true` if this parachain runs with system-level privileges.
pub fn is_system(&self) -> bool { self.0 < USER_INDEX_START }
}
// TODO: Remove all of this, move sr-primitives::AccountIdConversion to own crate and and use that.
......@@ -191,6 +210,9 @@ pub enum ParachainDispatchOrigin {
/// As the special `Origin::Parachain(ParaId)`. This is good when interacting with parachain-
/// aware modules which need to succinctly verify that the origin is a parachain.
Parachain,
/// As the simple, superuser `Origin::Root`. This can only be done on specially permissioned
/// parachains.
Root,
}
impl rstd::convert::TryFrom<u8> for ParachainDispatchOrigin {
......
......@@ -30,7 +30,7 @@ use primitives::bytes;
use application_crypto::KeyTypeId;
pub use polkadot_parachain::{
Id, AccountIdConversion, ParachainDispatchOrigin, UpwardMessage,
Id, ParachainDispatchOrigin, LOWEST_USER_ID, UpwardMessage,
};
/// The key type ID for a collator key.
......@@ -78,6 +78,67 @@ pub type ValidatorPair = validator_app::Pair;
/// so we define it to be the same type as `SessionKey`. In the future it may have different crypto.
pub type ValidatorSignature = validator_app::Signature;
/// Retriability for a given active para.
#[derive(Clone, Eq, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum Retriable {
/// Ineligible for retry. This means it's either a parachain which is always scheduled anyway or
/// has been removed/swapped.
Never,
/// Eligible for retry; the associated value is the number of retries that the para already had.
WithRetries(u32),
}
/// Type determining the active set of parachains in current block.
pub trait ActiveParas {
/// Return the active set of parachains in current block. This attempts to keep any IDs in the
/// same place between sequential blocks. It is therefore unordered. The second item in the
/// tuple is the required collator ID, if any. If `Some`, then it is invalid to include any
/// other collator's block.
///
/// NOTE: The initial implementation simply concatenates the (ordered) set of (permanent)
/// parachain IDs with the (unordered) set of parathread IDs selected for this block.
fn active_paras() -> Vec<(Id, Option<(CollatorId, Retriable)>)>;
}
/// Description of how often/when this parachain is scheduled for progression.
#[derive(Encode, Decode, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum Scheduling {
/// Scheduled every block.
Always,
/// Scheduled dynamically (i.e. a parathread).
Dynamic,
}
/// Information regarding a deployed parachain/thread.
#[derive(Encode, Decode, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct Info {
/// Scheduling info.
pub scheduling: Scheduling,
}
/// An `Info` value for a standard leased parachain.
pub const PARACHAIN_INFO: Info = Info {
scheduling: Scheduling::Always,
};
/// Auxilliary for when there's an attempt to swapped 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: Id, other: Id) -> 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: Id, other: Id) -> Result<(), &'static str>;
}
/// Identifier for a chain, either one of a number of parachains or the relay chain.
#[derive(Copy, Clone, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
......@@ -432,7 +493,7 @@ substrate_client::decl_runtime_apis! {
/// Get the current duty roster.
fn duty_roster() -> DutyRoster;
/// Get the currently active parachains.
fn active_parachains() -> Vec<Id>;
fn active_parachains() -> Vec<(Id, Option<(CollatorId, Retriable)>)>;
/// Get the given parachain's status.
fn parachain_status(id: Id) -> Option<Status>;
/// Get the given parachain's head code blob.
......
......@@ -53,6 +53,7 @@ timestamp = { package = "srml-timestamp", git = "https://github.com/paritytech/s
treasury = { package = "srml-treasury", git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-master" }
primitives = { package = "polkadot-primitives", path = "../primitives", default-features = false }
polkadot-parachain = { path = "../parachain", default-features = false }
[dev-dependencies]
hex-literal = "0.2.0"
......@@ -79,6 +80,7 @@ std = [
"codec/std",
"inherents/std",
"substrate-primitives/std",
"polkadot-parachain/std",
"client/std",
"offchain-primitives/std",
"rstd/std",
......
......@@ -77,14 +77,16 @@ use sr_primitives::{ModuleId, weights::SimpleDispatchInfo,
use crate::slots;
use codec::{Encode, Decode};
use rstd::vec::Vec;
use crate::parachains::ParachainRegistrar;
use substrate_primitives::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX;
use primitives::parachain::Id as ParaId;
const MODULE_ID: ModuleId = ModuleId(*b"py/cfund");
pub type BalanceOf<T> = <<T as slots::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
pub type NegativeImbalanceOf<T> = <<T as slots::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance;
pub type ParaIdOf<T> = <<T as slots::Trait>::Parachains as ParachainRegistrar<<T as system::Trait>::AccountId>>::ParaId;
pub type BalanceOf<T> =
<<T as slots::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
#[allow(dead_code)]
pub type NegativeImbalanceOf<T> =
<<T as slots::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance;
pub trait Trait: slots::Trait {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
......@@ -117,7 +119,7 @@ pub enum LastContribution<BlockNumber> {
#[derive(Encode, Decode, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct FundInfo<AccountId, Balance, Hash, BlockNumber, ParaId> {
pub struct FundInfo<AccountId, Balance, Hash, BlockNumber> {
/// The parachain that this fund has funded, if there is one. As long as this is `Some`, then
/// the funds may not be withdrawn and the fund cannot be dissolved.
parachain: Option<ParaId>,
......@@ -154,7 +156,7 @@ decl_storage! {
trait Store for Module<T: Trait> as Example {
/// Info on all of the funds.
Funds get(funds):
map FundIndex => Option<FundInfo<T::AccountId, BalanceOf<T>, T::Hash, T::BlockNumber, ParaIdOf<T>>>;
map FundIndex => Option<FundInfo<T::AccountId, BalanceOf<T>, T::Hash, T::BlockNumber>>;
/// The total number of funds that have so far been allocated.
FundCount get(fund_count): FundIndex;
......@@ -172,7 +174,6 @@ decl_event! {
pub enum Event<T> where
<T as system::Trait>::AccountId,
Balance = BalanceOf<T>,
ParaId = ParaIdOf<T>,
{
Created(FundIndex),
Contributed(AccountId, FundIndex, Balance),
......@@ -321,7 +322,7 @@ decl_module! {
/// - `para_id` is the parachain index that this fund won.
fn onboard(origin,
#[compact] index: FundIndex,
#[compact] para_id: ParaIdOf<T>
#[compact] para_id: ParaId
) {
let _ = ensure_signed(origin)?;
......@@ -503,13 +504,14 @@ mod tests {
use srml_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types};
use sr_io::with_externalities;
use substrate_primitives::{H256, Blake2Hasher};
use primitives::parachain::Id as ParaId;
use primitives::parachain::Info as ParaInfo;
// 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 sr_primitives::{
Perbill, Permill, testing::Header,
traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup, ConvertInto},
};
use crate::registrar::Registrar;
impl_outer_origin! {
pub enum Origin for Test {}
......@@ -595,16 +597,16 @@ mod tests {
}
pub struct TestParachains;
impl ParachainRegistrar<u64> for TestParachains {
type ParaId = ParaId;
fn new_id() -> Self::ParaId {
impl Registrar<u64> for TestParachains {
fn new_id() -> ParaId {
PARACHAIN_COUNT.with(|p| {
*p.borrow_mut() += 1;
(*p.borrow() - 1).into()
})
}
fn register_parachain(
id: Self::ParaId,
fn register_para(
id: ParaId,
_info: ParaInfo,
code: Vec<u8>,
initial_head_data: Vec<u8>
) -> Result<(), &'static str> {
......@@ -616,7 +618,7 @@ mod tests {
Ok(())
})
}
fn deregister_parachain(id: Self::ParaId) -> Result<(), &'static str> {
fn deregister_para(id: ParaId) -> Result<(), &'static str> {
PARACHAINS.with(|p| {
if !p.borrow().contains_key(&id.into_inner()) {
panic!("ID doesn't exist")
......
......@@ -24,15 +24,16 @@ mod attestations;
mod claims;
mod parachains;
mod slot_range;
mod registrar;
mod slots;
mod crowdfund;
use rstd::prelude::*;
use codec::{Encode, Decode};
use substrate_primitives::u32_trait::{_1, _2, _3, _4};
use codec::{Encode, Decode};
use primitives::{
AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
parachain, ValidityError,
parachain::{self, ActiveParas}, ValidityError,
};
use client::{
block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult},
......@@ -187,7 +188,7 @@ impl indices::Trait for Runtime {
}
parameter_types! {
pub const ExistentialDeposit: Balance = 10 * CENTS;
pub const ExistentialDeposit: Balance = 100 * CENTS;
pub const TransferFee: Balance = 1 * CENTS;
pub const CreationFee: Balance = 1 * CENTS;
pub const TransactionBaseFee: Balance = 1 * CENTS;
......@@ -221,7 +222,6 @@ impl balances::Trait for Runtime {
parameter_types! {
pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
}
impl timestamp::Trait for Runtime {
type Moment = u64;
type OnTimestampSet = Babe;
......@@ -275,15 +275,15 @@ impl session::Trait for Runtime {
type ShouldEndSession = Babe;
type Event = Event;
type Keys = SessionKeys;
type SelectInitialValidators = Staking;
type ValidatorId = AccountId;
type ValidatorIdOf = staking::StashOf<Self>;
type SelectInitialValidators = Staking;
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
}
impl session::historical::Trait for Runtime {
type FullIdentification = staking::Exposure<AccountId, Balance>;
type FullIdentificationOf = staking::ExposureOf<Self>;
type FullIdentificationOf = staking::ExposureOf<Runtime>;
}
srml_staking_reward_curve::build! {
......@@ -480,6 +480,24 @@ impl parachains::Trait for Runtime {
type Origin = Origin;
type Call = Call;
type ParachainCurrency = Balances;
type ActiveParachains = Registrar;
type Registrar = Registrar;
}
parameter_types! {
pub const ParathreadDeposit: Balance = 500 * DOLLARS;
pub const QueueSize: usize = 2;
pub const MaxRetries: u32 = 3;
}
impl registrar::Trait for Runtime {
type Event = Event;
type Origin = Origin;
type Currency = Balances;
type ParathreadDeposit = ParathreadDeposit;
type SwapAux = Slots;
type QueueSize = QueueSize;
type MaxRetries = MaxRetries;
}
parameter_types!{
......@@ -489,8 +507,8 @@ parameter_types!{
impl slots::Trait for Runtime {
type Event = Event;
type Currency = balances::Module<Self>;
type Parachains = parachains::Module<Self>;
type Currency = Balances;
type Parachains = Registrar;
type LeasePeriod = LeasePeriod;
type EndingPeriod = EndingPeriod;
}
......@@ -553,9 +571,10 @@ construct_runtime!(
// Parachains stuff; slots are disabled (no auctions initially). The rest are safe as they
// have no public dispatchables.
Parachains: parachains::{Module, Call, Storage, Config<T>, Inherent, Origin},
Parachains: parachains::{Module, Call, Storage, Config, Inherent, Origin},
Attestations: attestations::{Module, Call, Storage},
Slots: slots::{Module, Call, Storage, Event<T>},
Registrar: registrar::{Module, Call, Storage, Event, Config<T>},
// Sudo. Usable initially.
// RELEASE: remove this for release build.
......@@ -583,6 +602,7 @@ pub type SignedExtra = (
system::CheckNonce<Runtime>,
system::CheckWeight<Runtime>,
balances::TakeFees<Runtime>,
registrar::LimitParathreadCommits<Runtime>
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
......@@ -653,8 +673,8 @@ impl_runtime_apis! {
fn duty_roster() -> parachain::DutyRoster {
Parachains::calculate_duty_roster().0
}
fn active_parachains() -> Vec<parachain::Id> {
Parachains::active_parachains()
fn active_parachains() -> Vec<(parachain::Id, Option<(parachain::CollatorId, parachain::Retriable)>)> {
Registrar::active_paras()
}
fn parachain_status(id: parachain::Id) -> Option<parachain::Status> {
Parachains::parachain_status(&id)
......
This diff is collapsed.
This diff is collapsed.
......@@ -19,20 +19,21 @@
//! information for commissioning and decommissioning them.
use rstd::{prelude::*, mem::swap, convert::TryInto};
use sr_primitives::traits::{CheckedSub, StaticLookup, Zero, One, CheckedConversion, Hash};
use sr_primitives::traits::{CheckedSub, StaticLookup, Zero, One, CheckedConversion, Hash, AccountIdConversion};
use sr_primitives::weights::SimpleDispatchInfo;
use codec::{Encode, Decode};
use codec::{Encode, Decode, Codec};
use srml_support::{
decl_module, decl_storage, decl_event, ensure,
traits::{Currency, ReservableCurrency, WithdrawReason, ExistenceRequirement, Get},
};
use primitives::parachain::AccountIdConversion;
use crate::parachains::ParachainRegistrar;
use primitives::parachain::{
SwapAux, PARACHAIN_INFO, Id as ParaId
};
use 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 system::Trait>::AccountId>>::Balance;
type ParaIdOf<T> = <<T as Trait>::Parachains as ParachainRegistrar<<T as system::Trait>::AccountId>>::ParaId;
/// The module's configuration trait.
pub trait Trait: system::Trait {
......@@ -43,7 +44,7 @@ pub trait Trait: system::Trait {
type Currency: ReservableCurrency<Self::AccountId>;
/// The parachain registrar type.
type Parachains: ParachainRegistrar<Self::AccountId>;
type Parachains: Registrar<Self::AccountId>;
/// The number of blocks over which an auction may be retroactively ended.
type EndingPeriod: Get<Self::BlockNumber>;
......@@ -74,7 +75,7 @@ pub struct NewBidder<AccountId> {
/// The desired target of a bidder in an auction.
#[derive(Clone, Eq, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum Bidder<AccountId, ParaId> {
pub enum Bidder<AccountId> {
/// An account ID, funds coming from that account.
New(NewBidder<AccountId>),
......@@ -83,7 +84,7 @@ pub enum Bidder<AccountId, ParaId> {
Existing(ParaId),
}
impl<AccountId: Clone, ParaId: AccountIdConversion<AccountId>> Bidder<AccountId, ParaId> {
impl<AccountId: Clone + Default + Codec> Bidder<AccountId> {
/// Get the account that will fund this bid.
fn funding_account(&self) -> AccountId {
match self {
......@@ -110,10 +111,12 @@ pub enum IncomingParachain<AccountId, Hash> {
type LeasePeriodOf<T> = <T as system::Trait>::BlockNumber;
// Winning data type. This encodes the top bidders of each range together with their bid.
type WinningData<T> = [Option<(Bidder<<T as system::Trait>::AccountId, ParaIdOf<T>>, BalanceOf<T>)>; SLOT_RANGE_COUNT];
type WinningData<T> =
[Option<(Bidder<<T as system::Trait>::AccountId>, BalanceOf<T>)>; SLOT_RANGE_COUNT];
// Winners data type. This encodes each of the final winners of a parachain auction, the parachain
// index assigned to them, their winning bid and the range that they won.
type WinnersData<T> = Vec<(Option<NewBidder<<T as system::Trait>::AccountId>>, ParaIdOf<T>, BalanceOf<T>, SlotRange)>;
type WinnersData<T> =
Vec<(Option<NewBidder<<T as system::Trait>::AccountId>>, ParaId, BalanceOf<T>, SlotRange)>;
// This module's storage items.
decl_storage! {
......@@ -122,9 +125,9 @@ decl_storage! {
/// The number of auctions that been started so far.
pub AuctionCounter get(auction_counter): AuctionIndex;
/// All `ParaId` values that are managed by this module. This includes chains that are not
/// yet deployed (but have won an auction in the future).
pub ManagedIds get(managed_ids): Vec<ParaIdOf<T>>;
/// Ordered list of all `ParaId` values that are managed by this module. This includes
/// chains that are not yet deployed (but have won an auction in the future).
pub ManagedIds get(managed_ids): Vec<ParaId>;
/// Various amounts on deposit for each parachain. An entry in `ManagedIds` implies a non-
/// default entry here.
......@@ -139,7 +142,7 @@ decl_storage! {
/// If a parachain doesn't exist *yet* but is scheduled to exist in the future, then it
/// will be left-padded with one or more zeroes to denote the fact that nothing is held on
/// deposit for the non-existent chain currently, but is held at some point in the future.
pub Deposits get(deposits): map ParaIdOf<T> => Vec<BalanceOf<T>>;
pub Deposits get(deposits): map ParaId => Vec<BalanceOf<T>>;
/// Information relating to the current auction, if there is one.
///
......@@ -155,22 +158,37 @@ decl_storage! {
/// Amounts currently reserved in the accounts of the bidders currently winning
/// (sub-)ranges.
pub ReservedAmounts get(reserved_amounts): map Bidder<T::AccountId, ParaIdOf<T>> => Option<BalanceOf<T>>;
pub ReservedAmounts get(reserved_amounts): map Bidder<T::AccountId> => Option<BalanceOf<T>>;
/// The set of Para IDs that have won and need to be on-boarded at an upcoming lease-period.
/// This is cleared out on the first block of the lease period.
pub OnboardQueue get(onboard_queue): map LeasePeriodOf<T> => Vec<ParaIdOf<T>>;
pub OnboardQueue get(onboard_queue): map LeasePeriodOf<T> => Vec<ParaId>;
/// The actual on-boarding information. Only exists when one of the following is true:
/// - It is before the lease period that the parachain should be on-boarded.
/// - The full on-boarding information has not yet been provided and the parachain is not
/// yet due to be off-boarded.
pub Onboarding get(onboarding): map ParaIdOf<T> =>
pub Onboarding get(onboarding): map ParaId =>
Option<(LeasePeriodOf<T>, IncomingParachain<T::AccountId, T::Hash>)>;
/// Off-boarding account; currency held on deposit for the parachain gets placed here if the
/// parachain gets off-boarded; i.e. its lease period is up and it isn't renewed.
pub Offboarding get(offboarding): map ParaIdOf<T> => T::AccountId;
pub Offboarding get(offboarding): map ParaId => T::AccountId;
}
}
impl<T: Trait> SwapAux for Module<T> {
fn ensure_can_swap(one: ParaId, other: ParaId) -> Result<(), &'static str> {
if <Onboarding<T>>::exists(one) || <Onboarding<T>>::exists(other) {
Err("can't swap an undeployed parachain")?
}
Ok(())
}
fn on_swap(one: ParaId, other: ParaId) -> Result<(), &'static str> {
<Offboarding<T>>::swap(one, other);
<Deposits<T>>::swap(one, other);
ManagedIds::mutate(|ids| swap_ordered_existence(ids, one, other));
Ok(())
}
}
......@@ -179,7 +197,7 @@ decl_event!(
AccountId = <T as system::Trait>::AccountId,
BlockNumber = <T as system::Trait>::BlockNumber,
LeasePeriod = LeasePeriodOf<T>,
ParaId = ParaIdOf<T>,
ParaId = ParaId,
Balance = BalanceOf<T>,
{
/// A new lease period is beginning.
......@@ -281,7 +299,7 @@ decl_module! {
/// - `amount` is the amount to bid to be held as deposit for the parachain should the
/// bid win. This amount is held throughout the range.
#[weight = SimpleDispatchInfo::FixedNormal(500_000)]
fn bid(origin,
pub fn bid(origin,
#[compact] sub: SubId,
#[compact] auction_index: AuctionIndex,
#[compact] first_slot: LeasePeriodOf<T>,
......@@ -308,7 +326,7 @@ decl_module! {
/// absolute lease period index value, not an auction-specific offset.
/// - `amount` is the amount to bid to be held as deposit for the parachain should the
/// bid win. This amount is held throughout the range.
#[weight = SimpleDispatchInfo::FixedNormal(500_000)]
#[weight = SimpleDispatchInfo::FixedNormal(500_000)]
fn bid_renew(origin,
#[compact] auction_index: AuctionIndex,
#[compact] first_slot: LeasePeriodOf<T>,
......@@ -316,7 +334,7 @@ decl_module! {