From 32f9519743eddbe759c5758b0dbd5c9a0b2ce765 Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Sat, 25 May 2019 13:34:23 +0200
Subject: [PATCH] Parachain auctions (#239)

* Slots module

* Integrate slots

* More drafting

* Minor updates

* Update parachains to use trati

* More build fixes

* Full code now compiles

* Add renew bid function

* Implement calculate_winner

* Warning remove

* Update gitignore

* Test framework

* Tests

* Further testing

* More tests, new parameterisation.

* Fix and new test

* Thread-safe tests

* Test off-boarding and a fix.

* Test onboarding

* Allow late onboarding.

* Another test and fix

* Avoid println in nostd

* Compact representation of paraids

* Introduce documentation.

* Introduce events.

* Additional test and fix

* Additional test

* Tidy up line lengths.

* Remove printlns

* Use later substrate utils.

* Fix build/test

* Make slots work with latest substrate

* Update runtime/src/slot_range.rs

Co-Authored-By: Robert Habermeier <rphmeier@gmail.com>

* Update runtime/src/slots.rs

Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com>

* Update runtime/src/slots.rs

Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com>

* Polish logic

* Rewind to earlier substrate master

* Remove dead code.
---
 polkadot/Cargo.lock                       |   22 +-
 polkadot/parachain/Cargo.toml             |    4 +-
 polkadot/parachain/src/lib.rs             |   63 +-
 polkadot/primitives/src/parachain.rs      |    2 +-
 polkadot/runtime/src/claims.rs            |    3 +-
 polkadot/runtime/src/lib.rs               |   16 +
 polkadot/runtime/src/parachains.rs        |  105 +-
 polkadot/runtime/src/slot_range.rs        |  154 +++
 polkadot/runtime/src/slots.rs             | 1459 +++++++++++++++++++++
 polkadot/runtime/wasm/Cargo.lock          |  340 +++--
 polkadot/test-parachains/adder/Cargo.toml |    4 +-
 11 files changed, 1935 insertions(+), 237 deletions(-)
 create mode 100644 polkadot/runtime/src/slot_range.rs
 create mode 100644 polkadot/runtime/src/slots.rs

diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock
index 4b32aeeff48..359e139ddc3 100644
--- a/polkadot/Cargo.lock
+++ b/polkadot/Cargo.lock
@@ -1362,10 +1362,10 @@ dependencies = [
  "libp2p-ping 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libp2p-plaintext 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libp2p-ratelimit 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-secio 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-secio 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libp2p-tcp 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libp2p-uds 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-wasm-ext 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-wasm-ext 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libp2p-websocket 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libp2p-yamux 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1603,7 +1603,7 @@ dependencies = [
 
 [[package]]
 name = "libp2p-secio"
-version = "0.8.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1616,11 +1616,11 @@ dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "protobuf 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1658,13 +1658,13 @@ dependencies = [
 
 [[package]]
 name = "libp2p-wasm-ext"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "wasm-bindgen-futures 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2095,6 +2095,11 @@ dependencies = [
  "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "parity-send-wrapper"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "parity-wasm"
 version = "0.31.3"
@@ -5120,10 +5125,10 @@ dependencies = [
 "checksum libp2p-ping 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b3bb3328d206ad3061e863f179a211fc978d7bce05f90440ed6b8a6a9d17ced"
 "checksum libp2p-plaintext 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b23a8ece138f448572c5ff781d62323a954f1f681c303e6553368026764b0ae"
 "checksum libp2p-ratelimit 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55918f058f118d72d83f9a976f12e02e54c8616ddfc795c779c4801a5042a44f"
-"checksum libp2p-secio 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9bff57806e0f71832cc02b5dea1010e5f1a9d16393fd104a4b64e4aaae40d885"
+"checksum libp2p-secio 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ea5c0636053e01575d6269b6112f9239e9d35ca861e3e5c7d6970a07f9e1682a"
 "checksum libp2p-tcp 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3629f9a667d9f5acb5876df59cf3b547250e340131c47587f9ace7c517f21327"
 "checksum libp2p-uds 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d65c15f89c0607d4a334664d759e54e847e1856a73ea78e7bb6a75e6f4039010"
-"checksum libp2p-wasm-ext 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dff6c81d0f46261a6327219349753aefd3a92021a1e6102185fa112cfcddca97"
+"checksum libp2p-wasm-ext 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "318d727d5e8e0fe3bb70aacbf99bde57334eae9559deff447edd993422dc0f03"
 "checksum libp2p-websocket 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04451aa166aa2040293f44c1c27144b65500e4a2ebbb723dfe732f39436eccbd"
 "checksum libp2p-yamux 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5369165359bea84e7ebe73f37b6240f31f8d924ce6710be3d8e1fa678985c9b8"
 "checksum librocksdb-sys 5.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7dfb546562f9b450237bb8df7a31961849ee9fb1186d9e356db1d7a6b7609ff2"
@@ -5170,6 +5175,7 @@ dependencies = [
 "checksum parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00a486fd383382ddcb2de928364b1f82571c1e48274fc43b7667a4738ee4056c"
 "checksum parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18a130a727008cfcd1068a28439fe939897ccad28664422aeca65b384d6de6d0"
 "checksum parity-multihash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e8eab0287ccde7821e337a124dc5a4f1d6e4c25d10cc91e3f9361615dd95076"
+"checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f"
 "checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc"
 "checksum parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2fec5048fba72a2e01baeb0d08089db79aead4b57e2443df172fb1840075a233"
 "checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac"
diff --git a/polkadot/parachain/Cargo.toml b/polkadot/parachain/Cargo.toml
index c60634d03bb..46c48b307b9 100644
--- a/polkadot/parachain/Cargo.toml
+++ b/polkadot/parachain/Cargo.toml
@@ -5,8 +5,8 @@ authors = ["Parity Technologies <admin@parity.io>"]
 description = "Types and utilities for creating and working with parachains"
 
 [dependencies]
-parity-codec = { version = "3.0", default-features = false }
-parity-codec-derive = { version = "3.0", default-features = false }
+parity-codec = { version = "3.5", default-features = false }
+parity-codec-derive = { version = "3.3", default-features = false }
 wasmi = { version = "0.4.3", optional = true }
 error-chain = { version = "0.12", optional = true }
 serde = { version = "1.0", default-features = false }
diff --git a/polkadot/parachain/src/lib.rs b/polkadot/parachain/src/lib.rs
index 323e241a76c..bd0b4182119 100644
--- a/polkadot/parachain/src/lib.rs
+++ b/polkadot/parachain/src/lib.rs
@@ -77,6 +77,21 @@ pub mod wasm_executor;
 #[cfg(feature = "wasm-api")]
 pub mod wasm_api;
 
+use codec::{Encode, Decode};
+
+struct TrailingZeroInput<'a>(&'a [u8]);
+impl<'a> codec::Input for TrailingZeroInput<'a> {
+	fn read(&mut self, into: &mut [u8]) -> usize {
+		let len = into.len().min(self.0.len());
+		into[..len].copy_from_slice(&self.0[..len]);
+		for i in &mut into[len..] {
+			*i = 0;
+		}
+		self.0 = &self.0[len..];
+		len
+	}
+}
+
 /// Validation parameters for evaluating the parachain validity function.
 // TODO: balance downloads (https://github.com/paritytech/polkadot/issues/220)
 #[derive(PartialEq, Eq, Decode)]
@@ -100,10 +115,56 @@ pub struct ValidationResult {
 }
 
 /// Unique identifier of a parachain.
-#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Encode, Decode)]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Default, Clone, Copy, Encode, Decode)]
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
 pub struct Id(u32);
 
+impl codec::CompactAs for Id {
+	type As = u32;
+	fn encode_as(&self) -> &u32 {
+		&self.0
+	}
+	fn decode_from(x: u32) -> Self {
+		Self(x)
+	}
+}
+impl From<codec::Compact<Id>> for Id {
+	fn from(x: codec::Compact<Id>) -> Id {
+		x.0
+	}
+}
+
+/// This type can be converted into and possibly from an AccountId (which itself is generic).
+pub trait AccountIdConversion<AccountId>: Sized {
+	/// Convert into an account ID. This is infallible.
+	fn into_account(&self) -> AccountId;
+
+	/// Try to convert an account ID into this type. Might not succeed.
+	fn try_from_account(a: &AccountId) -> Option<Self>;
+}
+
+/// Format is b"para" ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing zeroes to fill AccountId.
+impl<T: Encode + Decode + Default> AccountIdConversion<T> for Id {
+	fn into_account(&self) -> T {
+		(b"para", self).using_encoded(|b|
+			T::decode(&mut TrailingZeroInput(b))
+		).unwrap_or_default()
+	}
+
+	fn try_from_account(x: &T) -> Option<Self> {
+		x.using_encoded(|d| {
+			if &d[0..4] != b"para" { return None }
+			let mut cursor = &d[4..];
+			let result = Decode::decode(&mut cursor)?;
+			if cursor.iter().all(|x| *x == 0) {
+				Some(result)
+			} else {
+				None
+			}
+		})
+	}
+}
+
 impl From<Id> for u32 {
 	fn from(x: Id) -> Self { x.0 }
 }
diff --git a/polkadot/primitives/src/parachain.rs b/polkadot/primitives/src/parachain.rs
index 756c3e2a0bb..01b426aef86 100644
--- a/polkadot/primitives/src/parachain.rs
+++ b/polkadot/primitives/src/parachain.rs
@@ -24,7 +24,7 @@ use super::Hash;
 use primitives::bytes;
 use primitives::ed25519;
 
-pub use polkadot_parachain::Id;
+pub use polkadot_parachain::{Id, AccountIdConversion};
 
 /// Identity that collators use.
 pub type CollatorId = ed25519::Public;
diff --git a/polkadot/runtime/src/claims.rs b/polkadot/runtime/src/claims.rs
index 9bb46e617d2..555ca6dccd9 100644
--- a/polkadot/runtime/src/claims.rs
+++ b/polkadot/runtime/src/claims.rs
@@ -50,6 +50,7 @@ impl EcdsaSignature {
 		r[64] = self.2 as u8;
 		r
 	}
+	#[cfg(test)]
 	pub fn from_blob(blob: &[u8; 65]) -> Self {
 		let mut r = Self([0u8; 32], [0u8; 32], 0);
 		r.0[..].copy_from_slice(&blob[0..32]);
@@ -148,7 +149,7 @@ mod tests {
 	use tiny_keccak::keccak256;
 	use super::*;
 
-	use sr_io::{self as runtime_io, with_externalities};
+	use sr_io::with_externalities;
 	use substrate_primitives::{H256, Blake2Hasher};
 	use codec::{Decode, Encode};
 	// The testing primitives are very useful for avoiding having to work with signatures
diff --git a/polkadot/runtime/src/lib.rs b/polkadot/runtime/src/lib.rs
index ee372b7920d..2e67257db3a 100644
--- a/polkadot/runtime/src/lib.rs
+++ b/polkadot/runtime/src/lib.rs
@@ -76,6 +76,8 @@ extern crate substrate_trie;
 mod curated_grandpa;
 mod parachains;
 mod claims;
+mod slot_range;
+mod slots;
 
 use rstd::prelude::*;
 use substrate_primitives::u32_trait::{_2, _4};
@@ -252,6 +254,19 @@ impl grandpa::Trait for Runtime {
 
 impl parachains::Trait for Runtime {}
 
+parameter_types!{
+	pub const LeasePeriod: BlockNumber = 100000;
+	pub const EndingPeriod: BlockNumber = 1000;
+}
+
+impl slots::Trait for Runtime {
+	type Event = Event;
+	type Currency = balances::Module<Self>;
+	type Parachains = parachains::Module<Self>;
+	type LeasePeriod = LeasePeriod;
+	type EndingPeriod = EndingPeriod;
+}
+
 impl curated_grandpa::Trait for Runtime { }
 
 impl sudo::Trait for Runtime {
@@ -283,6 +298,7 @@ construct_runtime!(
 		CouncilSeats: council_seats::{Config<T>},
 		Treasury: treasury,
 		Parachains: parachains::{Module, Call, Storage, Config<T>, Inherent},
+		Slots: slots::{Module, Call, Storage, Event<T>},
 		Sudo: sudo,
 	}
 );
diff --git a/polkadot/runtime/src/parachains.rs b/polkadot/runtime/src/parachains.rs
index c88126a703b..fae21166786 100644
--- a/polkadot/runtime/src/parachains.rs
+++ b/polkadot/runtime/src/parachains.rs
@@ -17,16 +17,16 @@
 //! Main parachains logic. For now this is just the determination of which validators do what.
 
 use rstd::prelude::*;
-use codec::Decode;
+use codec::{Decode, HasCompact};
 
 use bitvec::BigEndian;
-use sr_primitives::traits::{Hash as HashT, BlakeTwo256};
-use primitives::Hash;
-use primitives::parachain::{Id as ParaId, Chain, DutyRoster, AttestedCandidate, Statement};
+use sr_primitives::traits::{Hash as HashT, BlakeTwo256, Member};
+use primitives::{Hash, parachain::{Id as ParaId, Chain, DutyRoster, AttestedCandidate, Statement, AccountIdConversion}};
 use {system, session};
 
-use srml_support::{StorageValue, StorageMap, storage::hashed::generator};
-use srml_support::dispatch::Result;
+use srml_support::{StorageValue, StorageMap, Parameter, dispatch::Result};
+#[cfg(feature = "std")]
+use srml_support::storage::hashed::generator;
 
 use inherents::{ProvideInherent, InherentData, RuntimeString, MakeFatalError, InherentIdentifier};
 
@@ -38,7 +38,64 @@ use rstd::marker::PhantomData;
 
 use system::ensure_none;
 
-pub trait Trait: session::Trait {}
+/// Parachain registration API.
+pub trait ParachainRegistrar<AccountId> {
+	/// An identifier for a parachain.
+	type ParaId: Member + Parameter + Default + AccountIdConversion<AccountId> + Copy + HasCompact;
+
+	/// Create a new unique parachain identity for later registration.
+	fn new_id() -> Self::ParaId;
+
+	/// Register a parachain with given `code` and `initial_head_data`. `id` must not yet be registered or it will
+	/// result in a error.
+	fn register_parachain(id: Self::ParaId, code: Vec<u8>, initial_head_data: Vec<u8>) -> Result;
+
+	/// Deregister a parachain with given `id`. If `id` is not currently registered, an error is returned.
+	fn deregister_parachain(id: Self::ParaId) -> Result;
+}
+
+impl<T: Trait> ParachainRegistrar<T::AccountId> for Module<T> {
+	type ParaId = ParaId;
+	fn new_id() -> ParaId {
+		<NextFreeId<T>>::mutate(|n| { let r = *n; *n = ParaId::from(u32::from(*n) + 1); r })
+	}
+	fn register_parachain(id: ParaId, code: Vec<u8>, initial_head_data: Vec<u8>) -> Result {
+		let mut parachains = Self::active_parachains();
+		match parachains.binary_search(&id) {
+			Ok(_) => fail!("Parachain already exists"),
+			Err(idx) => parachains.insert(idx, id),
+		}
+
+		<Code<T>>::insert(id, code);
+		<Parachains<T>>::put(parachains);
+		<Heads<T>>::insert(id, initial_head_data);
+
+		Ok(())
+	}
+	fn deregister_parachain(id: ParaId) -> Result {
+		let mut parachains = Self::active_parachains();
+		match parachains.binary_search(&id) {
+			Ok(idx) => { parachains.remove(idx); }
+			Err(_) => return Ok(()),
+		}
+
+		<Code<T>>::remove(id);
+		<Heads<T>>::remove(id);
+
+		// clear all routing entries to and from other parachains.
+		for other in parachains.iter().cloned() {
+			<Routing<T>>::remove((id, other));
+			<Routing<T>>::remove((other, id));
+		}
+
+		<Parachains<T>>::put(parachains);
+
+		Ok(())
+	}
+}
+
+pub trait Trait: session::Trait {
+}
 
 // result of <NodeCodec<Blake2Hasher> as trie_db::NodeCodec<Blake2Hasher>>::hashed_null_node()
 const EMPTY_TRIE_ROOT: [u8; 32] = [
@@ -59,6 +116,9 @@ decl_storage! {
 
 		// Did the parachain heads get updated in this block?
 		DidUpdate: bool;
+
+		/// The next unused ParaId value.
+		NextFreeId: ParaId;
 	}
 	add_extra_genesis {
 		config(parachains): Vec<(ParaId, Vec<u8>, Vec<u8>)>;
@@ -137,39 +197,12 @@ decl_module! {
 		/// Register a parachain with given code.
 		/// Fails if given ID is already used.
 		pub fn register_parachain(id: ParaId, code: Vec<u8>, initial_head_data: Vec<u8>) -> Result {
-			let mut parachains = Self::active_parachains();
-			match parachains.binary_search(&id) {
-				Ok(_) => fail!("Parachain already exists"),
-				Err(idx) => parachains.insert(idx, id),
-			}
-
-			<Code<T>>::insert(id, code);
-			<Parachains<T>>::put(parachains);
-			<Heads<T>>::insert(id, initial_head_data);
-
-			Ok(())
+			<Self as ParachainRegistrar<T::AccountId>>::register_parachain(id, code, initial_head_data)
 		}
 
 		/// Deregister a parachain with given id
 		pub fn deregister_parachain(id: ParaId) -> Result {
-			let mut parachains = Self::active_parachains();
-			match parachains.binary_search(&id) {
-				Ok(idx) => { parachains.remove(idx); }
-				Err(_) => return Ok(()),
-			}
-
-			<Code<T>>::remove(id);
-			<Heads<T>>::remove(id);
-
-			// clear all routing entries to and from other parachains.
-			for other in parachains.iter().cloned() {
-				<Routing<T>>::remove((id, other));
-				<Routing<T>>::remove((other, id));
-			}
-
-			<Parachains<T>>::put(parachains);
-
-			Ok(())
+			<Self as ParachainRegistrar<T::AccountId>>::deregister_parachain(id)
 		}
 
 		fn on_finalize(_n: T::BlockNumber) {
diff --git a/polkadot/runtime/src/slot_range.rs b/polkadot/runtime/src/slot_range.rs
new file mode 100644
index 00000000000..4394995785c
--- /dev/null
+++ b/polkadot/runtime/src/slot_range.rs
@@ -0,0 +1,154 @@
+// Copyright 2019 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/>.
+
+//! The SlotRange struct which succinctly handles the ten values that
+//! represent all sub ranges between 0 and 3 inclusive.
+
+use rstd::{result, ops::Add, convert::{TryFrom, TryInto}};
+use sr_primitives::traits::CheckedSub;
+
+/// Total number of possible sub ranges of slots.
+pub const SLOT_RANGE_COUNT: usize = 10;
+
+/// A compactly represented sub-range from the series (0, 1, 2, 3).
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode)]
+#[repr(u8)]
+pub enum SlotRange {
+	/// Sub range from index 0 to index 0 inclusive.
+	ZeroZero = 0,
+	/// Sub range from index 0 to index 1 inclusive.
+	ZeroOne = 1,
+	/// Sub range from index 0 to index 2 inclusive.
+	ZeroTwo = 2,
+	/// Sub range from index 0 to index 3 inclusive.
+	ZeroThree = 3,
+	/// Sub range from index 1 to index 1 inclusive.
+	OneOne = 4,
+	/// Sub range from index 1 to index 2 inclusive.
+	OneTwo = 5,
+	/// Sub range from index 1 to index 3 inclusive.
+	OneThree = 6,
+	/// Sub range from index 2 to index 2 inclusive.
+	TwoTwo = 7,
+	/// Sub range from index 2 to index 3 inclusive.
+	TwoThree = 8,
+	/// Sub range from index 3 to index 3 inclusive.
+	ThreeThree = 9,     // == SLOT_RANGE_COUNT - 1
+}
+
+#[cfg(feature = "std")]
+impl std::fmt::Debug for SlotRange {
+	fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
+		let p = self.as_pair();
+		write!(fmt, "[{}..{}]", p.0, p.1)
+	}
+}
+
+impl SlotRange {
+	pub fn new_bounded<
+		Index: Add<Output=Index> + CheckedSub + Copy + Ord + From<u32> + TryInto<u32>
+	>(
+		initial: Index,
+		first: Index,
+		last: Index
+	) -> result::Result<Self, &'static str> {
+		if first > last || first < initial || last > initial + 3.into() {
+			return Err("Invalid range for this auction")
+		}
+		let count: u32 = last.checked_sub(&first)
+			.ok_or("range ends before it begins")?
+			.try_into()
+			.map_err(|_| "range too big")?;
+		let first: u32 = first.checked_sub(&initial)
+			.ok_or("range begins too early")?
+			.try_into()
+			.map_err(|_| "start too far")?;
+		match first {
+			0 => match count {
+				0 => Some(SlotRange::ZeroZero),
+				1 => Some(SlotRange::ZeroOne),
+				2 => Some(SlotRange::ZeroTwo),
+				3 => Some(SlotRange::ZeroThree),
+				_ => None,
+			},
+			1 => match count {
+				0 => Some(SlotRange::OneOne),
+				1 => Some(SlotRange::OneTwo),
+				2 => Some(SlotRange::OneThree),
+				_ => None
+			},
+			2 => match count { 0 => Some(SlotRange::TwoTwo), 1 => Some(SlotRange::TwoThree), _ => None },
+			3 => match count { 0 => Some(SlotRange::ThreeThree), _ => None },
+			_ => return Err("range begins too late"),
+		}.ok_or("range ends too late")
+	}
+
+	pub fn as_pair(&self) -> (u8, u8) {
+		match self {
+			SlotRange::ZeroZero => (0, 0),
+			SlotRange::ZeroOne => (0, 1),
+			SlotRange::ZeroTwo => (0, 2),
+			SlotRange::ZeroThree => (0, 3),
+			SlotRange::OneOne => (1, 1),
+			SlotRange::OneTwo => (1, 2),
+			SlotRange::OneThree => (1, 3),
+			SlotRange::TwoTwo => (2, 2),
+			SlotRange::TwoThree => (2, 3),
+			SlotRange::ThreeThree => (3, 3),
+		}
+	}
+
+	pub fn intersects(&self, other: SlotRange) -> bool {
+		let a = self.as_pair();
+		let b = other.as_pair();
+		b.0 <= a.1 && a.0 <= b.1
+//		== !(b.0 > a.1 || a.0 > b.1)
+	}
+
+	pub fn len(&self) -> usize {
+		match self {
+			SlotRange::ZeroZero => 1,
+			SlotRange::ZeroOne => 2,
+			SlotRange::ZeroTwo => 3,
+			SlotRange::ZeroThree => 4,
+			SlotRange::OneOne => 1,
+			SlotRange::OneTwo => 2,
+			SlotRange::OneThree => 3,
+			SlotRange::TwoTwo => 1,
+			SlotRange::TwoThree => 2,
+			SlotRange::ThreeThree => 1,
+		}
+	}
+}
+
+impl TryFrom<usize> for SlotRange {
+	type Error = ();
+	fn try_from(x: usize) -> Result<SlotRange, ()> {
+		Ok(match x {
+			0 => SlotRange::ZeroZero,
+			1 => SlotRange::ZeroOne,
+			2 => SlotRange::ZeroTwo,
+			3 => SlotRange::ZeroThree,
+			4 => SlotRange::OneOne,
+			5 => SlotRange::OneTwo,
+			6 => SlotRange::OneThree,
+			7 => SlotRange::TwoTwo,
+			8 => SlotRange::TwoThree,
+			9 => SlotRange::ThreeThree,
+			_ => return Err(()),
+		})
+	}
+}
diff --git a/polkadot/runtime/src/slots.rs b/polkadot/runtime/src/slots.rs
new file mode 100644
index 00000000000..e7dd60a5aed
--- /dev/null
+++ b/polkadot/runtime/src/slots.rs
@@ -0,0 +1,1459 @@
+// Copyright 2019 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/>.
+
+//! Auctioning system to determine the set of Parachains in operation. This includes logic for the
+//! auctioning mechanism, for locking balance as part of the "payment", and to provide the requisite
+//! information for commissioning and decommissioning them.
+
+use rstd::{prelude::*, mem::swap, convert::TryInto};
+use sr_primitives::traits::{CheckedSub, StaticLookup, Zero, One, CheckedConversion, Hash};
+use codec::Decode;
+use srml_support::{decl_module, decl_storage, decl_event, StorageValue, StorageMap,
+	traits::{Currency, ReservableCurrency, WithdrawReason, ExistenceRequirement, Get}};
+use primitives::parachain::AccountIdConversion;
+use crate::parachains::ParachainRegistrar;
+use system::ensure_signed;
+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 {
+	/// The overarching event type.
+	type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
+
+	/// The currency type used for bidding.
+	type Currency: ReservableCurrency<Self::AccountId>;
+
+	/// The parachain registrar type.
+	type Parachains: ParachainRegistrar<Self::AccountId>;
+
+	/// The number of blocks over which an auction may be retroactively ended.
+	type EndingPeriod: Get<Self::BlockNumber>;
+
+	/// The number of blocks over which a single period lasts.
+	type LeasePeriod: Get<Self::BlockNumber>;
+}
+
+/// A sub-bidder identifier. Used to distinguish between different logical bidders coming from the
+/// same account ID.
+pub type SubId = u32;
+/// An auction index. We count auctions in this type.
+pub type AuctionIndex = u32;
+
+/// A bidder identifier, which is just the combination of an account ID and a sub-bidder ID.
+/// This is called `NewBidder` in order to distinguish between bidders that would deploy a *new*
+/// parachain and pre-existing parachains bidding to renew themselves.
+#[derive(Clone, Eq, PartialEq, Encode, Decode)]
+#[cfg_attr(feature = "std", derive(Debug))]
+pub struct NewBidder<AccountId> {
+	/// The bidder's account ID; this is the account that funds the bid.
+	who: AccountId,
+	/// An additional ID to allow the same account ID (and funding source) to have multiple
+	/// logical bidders.
+	sub: SubId,
+}
+
+/// 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> {
+	/// An account ID, funds coming from that account.
+	New(NewBidder<AccountId>),
+
+	/// An existing parachain, funds coming from the amount locked as part of a previous bid topped
+	/// up with funds administered by the parachain.
+	Existing(ParaId),
+}
+
+impl<AccountId: Clone, ParaId: AccountIdConversion<AccountId>> Bidder<AccountId, ParaId> {
+	/// Get the account that will fund this bid.
+	fn funding_account(&self) -> AccountId {
+		match self {
+			Bidder::New(new_bidder) => new_bidder.who.clone(),
+			Bidder::Existing(para_id) => para_id.into_account(),
+		}
+	}
+}
+
+/// Information regarding a parachain that will be deployed.
+///
+/// We store either the bidder that will be able to set the final deployment information or the
+/// information itself.
+#[derive(Clone, Eq, PartialEq, Encode, Decode)]
+#[cfg_attr(feature = "std", derive(Debug))]
+pub enum IncomingParachain<AccountId, Hash> {
+	/// Deploy information not yet set; just the bidder identity.
+	Unset(NewBidder<AccountId>),
+	/// Deploy information set only by code hash; so we store the code hash and head data.
+	Fixed { code_hash: Hash, initial_head_data: Vec<u8> },
+	/// Deploy information fully set; so we store the code and head data.
+	Deploy { code: Vec<u8>, initial_head_data: Vec<u8> },
+}
+
+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];
+// 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)>;
+
+/// This module's storage items.
+decl_storage! {
+	trait Store for Module<T: Trait> as Slots {
+
+		/// 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>>;
+
+		/// Various amounts on deposit for each parachain. An entry in `ManagedIds` implies a non-
+		/// default entry here.
+		///
+		/// The actual amount locked on its behalf at any time is the maximum item in this list. The
+		/// first item in the list is the amount locked for the current Lease Period. Following
+		/// items are for the subsequent lease periods.
+		///
+		/// The default value (an empty list) implies that the parachain no longer exists (or never
+		/// existed) as far as this module is concerned.
+		///
+		/// 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>>;
+
+		/// Information relating to the current auction, if there is one.
+		///
+		/// The first item in the tuple is the lease period index that the first of the four
+		/// contiguous lease periods on auction is for. The second is the block number when the
+		/// auction will "begin to end", i.e. the first block of the Ending Period of the auction.
+		pub AuctionInfo get(auction_info): Option<(LeasePeriodOf<T>, T::BlockNumber)>;
+
+		/// The winning bids for each of the 10 ranges at each block in the final Ending Period of
+		/// the current auction. The map's key is the 0-based index into the Ending Period. The
+		/// first block of the ending period is 0; the last is `EndingPeriod - 1`.
+		pub Winning get(winning): map T::BlockNumber => Option<WinningData<T>>;
+
+		/// 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>>;
+
+		/// 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>>;
+
+		/// 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> =>
+			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;
+	}
+}
+
+decl_event!(
+	pub enum Event<T> where
+		AccountId = <T as system::Trait>::AccountId,
+		BlockNumber = <T as system::Trait>::BlockNumber,
+		LeasePeriod = LeasePeriodOf<T>,
+		ParaId = ParaIdOf<T>,
+		Balance = BalanceOf<T>,
+	{
+		/// A new lease period is beginning.
+		NewLeasePeriod(LeasePeriod),
+		/// An auction started. Provides its index and the block number where it will begin to
+		/// close and the first lease period of the quadruplet that is auctioned.
+		AuctionStarted(AuctionIndex, LeasePeriod, BlockNumber),
+		/// An auction ended. All funds become unreserved.
+		AuctionClosed(AuctionIndex),
+		/// Someone won the right to deploy a parachain. Balance amount is deducted for deposit.
+		WonDeploy(NewBidder<AccountId>, SlotRange, ParaId, Balance),
+		/// An existing parachain won the right to continue.
+		WonRenewal(ParaId, SlotRange, Balance, Balance),
+		/// Funds were reserved for a winning bid. First balance is the extra amount reserved.
+		/// Second is the total.
+		Reserved(AccountId, Balance, Balance),
+		/// Funds were unreserved since bidder is no longer active.
+		Unreserved(AccountId, Balance),
+	}
+);
+
+decl_module! {
+	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+		fn deposit_event<T>() = default;
+
+		fn on_initialize(n: T::BlockNumber) {
+			let lease_period = T::LeasePeriod::get();
+			let lease_period_index: LeasePeriodOf<T> = (n / lease_period).into();
+
+			// Check to see if an auction just ended.
+			if let Some((winning_ranges, auction_lease_period_index)) = Self::check_auction_end(n) {
+				// Auction is ended now. We have the winning ranges and the lease period index which
+				// acts as the offset. Handle it.
+				Self::manage_auction_end(
+					lease_period_index,
+					auction_lease_period_index,
+					winning_ranges,
+				);
+			}
+			// If we're beginning a new lease period then handle that, too.
+			if (n % lease_period).is_zero() {
+				Self::manage_lease_period_start(lease_period_index);
+			}
+		}
+
+		fn on_finalize(now: T::BlockNumber) {
+			// If the current auction is in it ending period, then ensure that the (sub-)range
+			// winner information is duplicated from the previous block in case no bids happened
+			// in this block.
+			if let Some(offset) = Self::is_ending(now) {
+				if !<Winning<T>>::exists(&offset) {
+					<Winning<T>>::insert(offset,
+						offset.checked_sub(&One::one())
+							.and_then(<Winning<T>>::get)
+							.unwrap_or_default()
+					);
+				}
+			}
+		}
+
+		/// Create a new auction.
+		///
+		/// This can only happen when there isn't already an auction in progress and may only be
+		/// called by the root origin. Accepts the `duration` of this auction and the
+		/// `lease_period_index` of the initial lease period of the four that are to be auctioned.
+		fn new_auction(
+			#[compact] duration: T::BlockNumber,
+			#[compact] lease_period_index: LeasePeriodOf<T>
+		) {
+			ensure!(!Self::is_in_progress(), "auction already in progress");
+			ensure!(lease_period_index >= Self::lease_period_index(), "lease period in past");
+
+			// Bump the counter.
+			let n = <AuctionCounter<T>>::mutate(|n| { *n += 1; *n });
+
+			// Set the information.
+			let ending = <system::Module<T>>::block_number() + duration;
+			<AuctionInfo<T>>::put((lease_period_index, ending));
+
+			Self::deposit_event(RawEvent::AuctionStarted(n, lease_period_index, ending))
+		}
+
+		/// Make a new bid from an account (including a parachain account) for deploying a new
+		/// parachain.
+		///
+		/// Multiple simultaneous bids from the same bidder are allowed only as long as all active
+		/// bids overlap each other (i.e. are mutually exclusive). Bids cannot be redacted.
+		///
+		/// - `sub` is the sub-bidder ID, allowing for multiple competing bids to be made by (and
+		/// funded by) the same account.
+		/// - `auction_index` is the index of the auction to bid on. Should just be the present
+		/// value of `AuctionCounter`.
+		/// - `first_slot` is the first lease period index of the range to bid on. This is the
+		/// absolute lease period index value, not an auction-specific offset.
+		/// - `last_slot` is the last lease period index of the range to bid on. This is the
+		/// 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.
+		fn bid(origin,
+			#[compact] sub: SubId,
+			#[compact] auction_index: AuctionIndex,
+			#[compact] first_slot: LeasePeriodOf<T>,
+			#[compact] last_slot: LeasePeriodOf<T>,
+			#[compact] amount: BalanceOf<T>
+		) {
+			let who = ensure_signed(origin)?;
+			let bidder = Bidder::New(NewBidder{who: who.clone(), sub});
+			Self::handle_bid(bidder, auction_index, first_slot, last_slot, amount)?;
+		}
+
+		/// Make a new bid from a parachain account for renewing that (pre-existing) parachain.
+		///
+		/// The origin *must* be a parachain account.
+		///
+		/// Multiple simultaneous bids from the same bidder are allowed only as long as all active
+		/// bids overlap each other (i.e. are mutually exclusive). Bids cannot be redacted.
+		///
+		/// - `auction_index` is the index of the auction to bid on. Should just be the present
+		/// value of `AuctionCounter`.
+		/// - `first_slot` is the first lease period index of the range to bid on. This is the
+		/// absolute lease period index value, not an auction-specific offset.
+		/// - `last_slot` is the last lease period index of the range to bid on. This is the
+		/// 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.
+		fn bid_renew(origin,
+			#[compact] auction_index: AuctionIndex,
+			#[compact] first_slot: LeasePeriodOf<T>,
+			#[compact] last_slot: LeasePeriodOf<T>,
+			#[compact] amount: BalanceOf<T>
+		) {
+			let who = ensure_signed(origin)?;
+			let para_id = <ParaIdOf<T>>::try_from_account(&who)
+				.ok_or("account is not a parachain")?;
+			let bidder = Bidder::Existing(para_id);
+			Self::handle_bid(bidder, auction_index, first_slot, last_slot, amount)?;
+		}
+
+		/// Set the off-boarding information for a parachain.
+		///
+		/// The origin *must* be a parachain account.
+		///
+		/// - `dest` is the destination account to receive the parachain's deposit.
+		fn set_offboarding(origin, dest: <T::Lookup as StaticLookup>::Source) {
+			let who = ensure_signed(origin)?;
+			let dest = T::Lookup::lookup(dest)?;
+			let para_id = <ParaIdOf<T>>::try_from_account(&who)
+				.ok_or("not a parachain origin")?;
+			<Offboarding<T>>::insert(para_id, dest);
+		}
+
+		/// Set the deploy information for a successful bid to deploy a new parachain.
+		///
+		/// - `origin` must be the successful bidder account.
+		/// - `sub` is the sub-bidder ID of the bidder.
+		/// - `para_id` is the parachain ID allotted to the winning bidder.
+		/// - `code_hash` is the hash of the parachain's Wasm validation function.
+		/// - `initial_head_data` is the parachain's initial head data.
+		fn fix_deploy_data(origin,
+			#[compact] sub: SubId,
+			#[compact] para_id: ParaIdOf<T>,
+			code_hash: T::Hash,
+			initial_head_data: Vec<u8>
+		) {
+			let who = ensure_signed(origin)?;
+			let (starts, details) = <Onboarding<T>>::get(&para_id)
+				.ok_or("parachain id not in onboarding")?;
+			if let IncomingParachain::Unset(ref nb) = details {
+				ensure!(nb.who == who && nb.sub == sub, "parachain not registered by origin");
+			} else {
+				return Err("already registered")
+			}
+			let item = (starts, IncomingParachain::Fixed{code_hash, initial_head_data});
+			<Onboarding<T>>::insert(&para_id, item);
+		}
+
+		/// Note a new parachain's code.
+		///
+		/// This must be called after `fix_deploy_data` and `code` must be the preimage of the
+		/// `code_hash` passed there for the same `para_id`.
+		///
+		/// This may be called before or after the beginning of the parachain's first lease period.
+		/// If called before then the parachain will become active at the first block of its
+		/// starting lease period. If after, then it will become active immediately after this call.
+		///
+		/// - `_origin` is irrelevant.
+		/// - `para_id` is the parachain ID whose code will be elaborated.
+		/// - `code` is the preimage of the registered `code_hash` of `para_id`.
+		fn elaborate_deploy_data(_origin, #[compact] para_id: ParaIdOf<T>, code: Vec<u8>) {
+			let (starts, details) = <Onboarding<T>>::get(&para_id)
+				.ok_or("parachain id not in onboarding")?;
+			if let IncomingParachain::Fixed{code_hash, initial_head_data} = details {
+				ensure!(<T as system::Trait>::Hashing::hash(&code) == code_hash, "code not doesn't correspond to hash");
+				if starts > Self::lease_period_index() {
+					// Hasn't yet begun. Replace the on-boarding entry with the new information.
+					let item = (starts, IncomingParachain::Deploy{code, initial_head_data});
+					<Onboarding<T>>::insert(&para_id, item);
+				} else {
+					// Should have already begun. Remove the on-boarding entry and register the
+					// parachain for its immediate start.
+					<Onboarding<T>>::remove(&para_id);
+					let _ = T::Parachains::register_parachain(para_id, code, initial_head_data);
+				}
+			} else {
+				return Err("deploy data not yet fixed")
+			}
+		}
+	}
+}
+
+impl<T: Trait> Module<T> {
+	/// Deposit currently held for a particular parachain that we administer.
+	fn deposit_held(para_id: &ParaIdOf<T>) -> BalanceOf<T> {
+		<Deposits<T>>::get(para_id).into_iter().max().unwrap_or_else(Zero::zero)
+	}
+
+	/// True if an auction is in progress.
+	fn is_in_progress() -> bool {
+		<AuctionInfo<T>>::exists()
+	}
+
+	/// Returns `Some(n)` if the now block is part of the ending period of an auction, where `n`
+	/// represents how far into the ending period this block is. Otherwise, returns `None`.
+	fn is_ending(now: T::BlockNumber) -> Option<T::BlockNumber> {
+		if let Some((_, early_end)) = <AuctionInfo<T>>::get() {
+			if let Some(after_early_end) = now.checked_sub(&early_end) {
+				if after_early_end < T::EndingPeriod::get() {
+					return Some(after_early_end)
+				}
+			}
+		}
+		None
+	}
+
+	/// Returns the current lease period.
+	fn lease_period_index() -> LeasePeriodOf<T> {
+		(<system::Module<T>>::block_number() / T::LeasePeriod::get()).into()
+	}
+
+	/// Some when the auction's end is known (with the end block number). None if it is unknown.
+	/// If `Some` then the block number must be at most the previous block and at least the
+	/// previous block minus `T::EndingPeriod::get()`.
+	///
+	/// This mutates the state, cleaning up `AuctionInfo` and `Winning` in the case of an auction
+	/// ending. An immediately subsequent call with the same argument will always return `None`.
+	fn check_auction_end(now: T::BlockNumber) -> Option<(WinningData<T>, LeasePeriodOf<T>)> {
+		if let Some((lease_period_index, early_end)) = <AuctionInfo<T>>::get() {
+			if early_end + T::EndingPeriod::get() == now {
+				// Just ended!
+				let ending_period = T::EndingPeriod::get();
+				let offset = T::BlockNumber::decode(&mut<system::Module<T>>::random_seed().as_ref())
+					.expect("secure hashes always bigger than block numbers; qed") % ending_period;
+				let res = <Winning<T>>::get(offset).unwrap_or_default();
+				let mut i = T::BlockNumber::zero();
+				while i < ending_period {
+					<Winning<T>>::remove(i);
+					i += One::one();
+				}
+				<AuctionInfo<T>>::kill();
+				return Some((res, lease_period_index))
+			}
+		}
+		None
+	}
+
+	/// Auction just ended. We have the current lease period, the auction's lease period (which
+	/// is guaranteed to be at least the current period) and the bidders that were winning each
+	/// range at the time of the auction's close.
+	fn manage_auction_end(
+		lease_period_index: LeasePeriodOf<T>,
+		auction_lease_period_index: LeasePeriodOf<T>,
+		winning_ranges: WinningData<T>,
+	) {
+		// First, unreserve all amounts that were reserved for the bids. We will later deduct the
+		// amounts from the bidders that ended up being assigned the slot so there's no need to
+		// special-case them here.
+		for (bidder, _) in winning_ranges.iter().filter_map(|x| x.as_ref()) {
+			if let Some(amount) = <ReservedAmounts<T>>::take(bidder) {
+				T::Currency::unreserve(&bidder.funding_account(), amount);
+			}
+		}
+
+		// Next, calculate the winning combination of slots and thus the final winners of the
+		// auction.
+		let winners = Self::calculate_winners(winning_ranges, T::Parachains::new_id);
+
+		Self::deposit_event(RawEvent::AuctionClosed(Self::auction_counter()));
+
+		// Go through those winners and deduct their bid, updating our table of deposits
+		// accordingly.
+		for (maybe_new_deploy, para_id, amount, range) in winners.into_iter() {
+			match maybe_new_deploy {
+				Some(bidder) => {
+					// For new deployments we ensure the full amount is deducted. This should always
+					// succeed as we just unreserved the same amount above.
+					if T::Currency::withdraw(
+						&bidder.who,
+						amount,
+						WithdrawReason::Fee,
+						ExistenceRequirement::AllowDeath
+					).is_err() {
+						continue;
+					}
+
+					// Add para IDs of any chains that will be newly deployed to our set of managed
+					// IDs
+					<ManagedIds<T>>::mutate(|m| m.push(para_id));
+
+					Self::deposit_event(RawEvent::WonDeploy(bidder.clone(), range, para_id, amount));
+
+					// Add a deployment record so we know to on-board them at the appropriate
+					// juncture.
+					let begin_offset = <LeasePeriodOf<T>>::from(range.as_pair().0 as u32);
+					let begin_lease_period = auction_lease_period_index + begin_offset;
+					<OnboardQueue<T>>::mutate(begin_lease_period, |starts| starts.push(para_id));
+					let entry = (begin_lease_period, IncomingParachain::Unset(bidder));
+					<Onboarding<T>>::insert(&para_id, entry);
+				}
+				None => {
+					// For renewals, reserve any extra on top of what we already have held
+					// on deposit for their chain.
+					let extra = if let Some(additional) =
+						amount.checked_sub(&Self::deposit_held(&para_id))
+					{
+						if T::Currency::withdraw(
+							&para_id.into_account(),
+							additional,
+							WithdrawReason::Fee,
+							ExistenceRequirement::AllowDeath
+						).is_err() {
+							continue;
+						}
+						additional
+					} else {
+						Default::default()
+					};
+					Self::deposit_event(RawEvent::WonRenewal(para_id, range, amount, extra));
+				}
+			}
+
+			// Finally, we update the deposit held so it is `amount` for the new lease period
+			// indices that were won in the auction.
+			let maybe_offset = auction_lease_period_index
+				.checked_sub(&lease_period_index)
+				.and_then(|x| x.checked_into::<usize>());
+			if let Some(offset) = maybe_offset {
+				// Should always succeed; for it to fail it would mean we auctioned a lease period
+				// that already ended.
+
+				// The lease period index range (begin, end) that newly belongs to this parachain
+				// ID. We need to ensure that it features in `Deposits` to prevent it from being
+				// reaped too early (any managed parachain whose `Deposits` set runs low will be
+				// removed).
+				let pair = range.as_pair();
+				let pair = (pair.0 as usize + offset, pair.1 as usize + offset);
+				<Deposits<T>>::mutate(para_id, |d| {
+					// Left-pad with zeroes as necessary.
+					if d.len() < pair.0 {
+						d.resize_with(pair.0, Default::default);
+					}
+					// Then place the deposit values for as long as the chain should exist.
+					for i in pair.0 ..= pair.1 {
+						if d.len() > i {
+							// The chain bought the same lease period twice. Just take the maximum.
+							d[i] = d[i].max(amount);
+						} else if d.len() == i {
+							d.push(amount);
+						} else {
+							unreachable!("earlier resize means it must be >= i; qed")
+						}
+					}
+				});
+			}
+		}
+	}
+
+	/// A new lease period is beginning. We're at the start of the first block of it.
+	///
+	/// We need to on-board and off-board parachains as needed. We should also handle reducing/
+	/// returning deposits.
+	fn manage_lease_period_start(lease_period_index: LeasePeriodOf<T>) {
+		Self::deposit_event(RawEvent::NewLeasePeriod(lease_period_index));
+		// First, bump off old deposits and decommission any managed chains that are coming
+		// to a close.
+		<ManagedIds<T>>::mutate(|ids| {
+			let new = ids.drain(..).filter(|id| {
+				let mut d = <Deposits<T>>::get(id);
+				if !d.is_empty() {
+					// ^^ should always be true, since we would have deleted the entry otherwise.
+
+					if d.len() == 1 {
+						// Just one entry, which corresponds to the now-ended lease period. Time
+						// to decommission this chain.
+						if <Onboarding<T>>::take(id).is_none() {
+							// Only unregister it if it was actually registered in the first place.
+							// If the on-boarding entry still existed, then it was never actually
+							// commissioned.
+							let _ = T::Parachains::deregister_parachain(id.clone());
+						}
+						// Return the full deposit to the off-boarding account.
+						T::Currency::deposit_creating(&<Offboarding<T>>::take(id), d[0]);
+						// Remove the now-empty deposits set and don't keep the ID around.
+						<Deposits<T>>::remove(id);
+						false
+					} else {
+						// The parachain entry is continuing into the next lease period.
+						// We need to pop the first deposit entry, which corresponds to the now-
+						// ended lease period.
+						let outgoing = d[0];
+						d.remove(0);
+						<Deposits<T>>::insert(id, &d);
+						// Then we need to get the new amount that should continue to be held on
+						// deposit for the parachain.
+						let new_held = d.into_iter().max().unwrap_or_default();
+						// If this is less than what we were holding previously, then return it
+						// to the parachain itself.
+						if let Some(rebate) = outgoing.checked_sub(&new_held) {
+							T::Currency::deposit_creating(
+								&id.into_account(),
+								rebate
+							);
+						}
+						// We keep this entry around until the next lease period.
+						true
+					}
+				} else {
+					false
+				}
+			}).collect::<Vec<_>>();
+			*ids = new;
+		});
+
+		// Deploy any new chains that are due to be commissioned.
+		for para_id in <OnboardQueue<T>>::take(lease_period_index) {
+			if let Some((_, IncomingParachain::Deploy{code, initial_head_data}))
+				= <Onboarding<T>>::get(&para_id)
+			{
+				// The chain's deployment data is set; go ahead and register it, and remove the
+				// now-redundant on-boarding entry.
+				let _ = T::Parachains::register_parachain(para_id.clone(), code, initial_head_data);
+				// ^^ not much we can do if it fails for some reason.
+				<Onboarding<T>>::remove(para_id)
+			}
+		}
+	}
+
+	/// Actually place a bid in the current auction.
+	///
+	/// - `bidder`: The account that will be funding this bid.
+	/// - `auction_index`: The auction index of the bid. For this to succeed, must equal
+	/// the current value of `AuctionCounter`.
+	/// - `first_slot`: The first lease period index of the range to be bid on.
+	/// - `last_slot`: The last lease period index of the range to be bid on (inclusive).
+	/// - `amount`: The total amount to be the bid for deposit over the range.
+	fn handle_bid(
+		bidder: Bidder<T::AccountId, ParaIdOf<T>>,
+		auction_index: u32,
+		first_slot: LeasePeriodOf<T>,
+		last_slot: LeasePeriodOf<T>,
+		amount: BalanceOf<T>
+	) -> Result<(), &'static str> {
+		// Bidding on latest auction.
+		ensure!(auction_index == <AuctionCounter<T>>::get(), "not current auction");
+		// Assume it's actually an auction (this should never fail because of above).
+		let (first_lease_period, _) = <AuctionInfo<T>>::get().ok_or("not an auction")?;
+
+		// Our range.
+		let range = SlotRange::new_bounded(first_lease_period, first_slot, last_slot)?;
+		// Range as an array index.
+		let range_index = range as u8 as usize;
+		// The offset into the auction ending set.
+		let offset = Self::is_ending(<system::Module<T>>::block_number()).unwrap_or_default();
+		// The current winning ranges.
+		let mut current_winning = <Winning<T>>::get(offset)
+			.or_else(|| offset.checked_sub(&One::one()).and_then(<Winning<T>>::get))
+			.unwrap_or_default();
+		// If this bid beat the previous winner of our range.
+		if current_winning[range_index].as_ref().map_or(true, |last| amount > last.1) {
+			// This must overlap with all existing ranges that we're winning on or it's invalid.
+			ensure!(current_winning.iter()
+				.enumerate()
+				.all(|(i, x)| x.as_ref().map_or(true, |(w, _)|
+					w != &bidder || range.intersects(i.try_into()
+						.expect("array has SLOT_RANGE_COUNT items; index never reaches that value; qed")
+					)
+				)),
+				"bidder winning non-intersecting range"
+			);
+
+			// Ok; we are the new winner of this range - reserve the additional amount and record.
+
+			// Get the amount already held on deposit on our behalf if this is a renewal bid from
+			// an existing parachain.
+			let deposit_held = if let Bidder::Existing(ref bidder_para_id) = bidder {
+				Self::deposit_held(bidder_para_id)
+			} else {
+				Zero::zero()
+			};
+			// Get the amount already reserved in any prior and still active bids by us.
+			let already_reserved =
+				<ReservedAmounts<T>>::get(&bidder).unwrap_or_default() + deposit_held;
+			// If these don't already cover the bid...
+			if let Some(additional) = amount.checked_sub(&already_reserved) {
+				// ...then reserve some more funds from their account, failing if there's not
+				// enough funds.
+				T::Currency::reserve(&bidder.funding_account(), additional)?;
+				// ...and record the amount reserved.
+				<ReservedAmounts<T>>::insert(&bidder, amount);
+
+				Self::deposit_event(RawEvent::Reserved(
+					bidder.funding_account(),
+					additional,
+					amount
+				));
+			}
+
+			// Return any funds reserved for the previous winner if they no longer have any active
+			// bids.
+			let mut outgoing_winner = Some((bidder, amount));
+			swap(&mut current_winning[range_index], &mut outgoing_winner);
+			if let Some((who, _)) = outgoing_winner {
+				if current_winning.iter()
+					.filter_map(Option::as_ref)
+					.all(|&(ref other, _)| other != &who)
+				{
+					// Previous bidder is no longer winning any ranges: unreserve their funds.
+					if let Some(amount) = <ReservedAmounts<T>>::take(&who) {
+						// It really should be reserved; there's not much we can do here on fail.
+						let _ = T::Currency::unreserve(&who.funding_account(), amount);
+
+						Self::deposit_event(RawEvent::Unreserved(who.funding_account(), amount));
+					}
+				}
+			}
+			// Update the range winner.
+			<Winning<T>>::insert(offset, &current_winning);
+		}
+		Ok(())
+	}
+
+	/// Calculate the final winners from the winning slots.
+	///
+	/// This is a simple dynamic programming algorithm designed by Al, the original code is at:
+	/// https://github.com/w3f/consensus/blob/master/NPoS/auctiondynamicthing.py
+	fn calculate_winners(
+		mut winning: WinningData<T>,
+		new_id: impl Fn() -> ParaIdOf<T>
+	) -> WinnersData<T> {
+		let winning_ranges = {
+			let mut best_winners_ending_at:
+				[(Vec<SlotRange>, BalanceOf<T>); 4] = Default::default();
+			let best_bid = |range: SlotRange| {
+				winning[range as u8 as usize].as_ref()
+					.map(|(_, amount)| *amount * (range.len() as u32).into())
+			};
+			for i in 0..4 {
+				let r = SlotRange::new_bounded(0, 0, i as u32).expect("`i < 4`; qed");
+				if let Some(bid) = best_bid(r) {
+					best_winners_ending_at[i] = (vec![r], bid);
+				}
+				for j in 0..i {
+					let r = SlotRange::new_bounded(0, j as u32 + 1, i as u32)
+						.expect("`i < 4`; `j < i`; `j + 1 < 4`; qed");
+					if let Some(mut bid) = best_bid(r) {
+						bid += best_winners_ending_at[j].1;
+						if bid > best_winners_ending_at[i].1 {
+							let mut new_winners = best_winners_ending_at[j].0.clone();
+							new_winners.push(r);
+							best_winners_ending_at[i] = (new_winners, bid);
+						}
+					} else {
+						if best_winners_ending_at[j].1 > best_winners_ending_at[i].1 {
+							best_winners_ending_at[i] = best_winners_ending_at[j].clone();
+						}
+					}
+				}
+			}
+			let [_, _, _, (winning_ranges, _)] = best_winners_ending_at;
+			winning_ranges
+		};
+
+		winning_ranges.into_iter().map(|r| {
+			let mut final_winner = (Bidder::Existing(Default::default()), Default::default());
+			swap(&mut final_winner, winning[r as u8 as usize].as_mut()
+				.expect("none values are filtered out in previous logic; qed"));
+			let (slot_winner, bid) = final_winner;
+			match slot_winner {
+				Bidder::New(new_bidder) => (Some(new_bidder), new_id(), bid, r),
+				Bidder::Existing(para_id) => (None, para_id, bid, r),
+			}
+		}).collect::<Vec<_>>()
+	}
+}
+
+
+/// tests for this module
+#[cfg(test)]
+mod tests {
+	use super::*;
+	use std::{result::Result, collections::HashMap, cell::RefCell};
+
+	use substrate_primitives::{Blake2Hasher, H256};
+	use sr_io::with_externalities;
+	use sr_primitives::{
+		BuildStorage,
+		traits::{BlakeTwo256, Hash, IdentityLookup, OnInitialize, OnFinalize},
+		testing::{Digest, DigestItem, Header}
+	};
+	use srml_support::{impl_outer_origin, assert_ok};
+	use balances;
+	use primitives::parachain::Id as ParaId;
+
+	impl_outer_origin! {
+		pub enum Origin for Test {}
+	}
+
+	// For testing the module, we construct most of a mock runtime. This means
+	// first constructing a configuration type (`Test`) which `impl`s each of the
+	// configuration traits of modules we want to use.
+	#[derive(Clone, Eq, PartialEq)]
+	pub struct Test;
+	impl system::Trait for Test {
+		type Origin = Origin;
+		type Index = u64;
+		type BlockNumber = u64;
+		type Hash = H256;
+		type Hashing = BlakeTwo256;
+		type Digest = Digest;
+		type AccountId = u64;
+		type Lookup = IdentityLookup<Self::AccountId>;
+		type Header = Header;
+		type Event = ();
+		type Log = DigestItem;
+	}
+
+	impl balances::Trait for Test {
+		type Balance = u64;
+		type OnFreeBalanceZero = ();
+		type OnNewAccount = ();
+		type TransactionPayment = ();
+		type TransferPayment = ();
+		type DustRemoval = ();
+		type Event = ();
+	}
+
+	thread_local! {
+		pub static PARACHAIN_COUNT: RefCell<u32> = RefCell::new(0);
+		pub static PARACHAINS:
+			RefCell<HashMap<u32, (Vec<u8>, Vec<u8>)>> = RefCell::new(HashMap::new());
+	}
+
+	pub struct TestParachains;
+	impl ParachainRegistrar<u64> for TestParachains {
+		type ParaId = ParaId;
+		fn new_id() -> Self::ParaId {
+			PARACHAIN_COUNT.with(|p| {
+				*p.borrow_mut() += 1;
+				(*p.borrow() - 1).into()
+			})
+		}
+		fn register_parachain(
+			id: Self::ParaId,
+			code: Vec<u8>,
+			initial_head_data: Vec<u8>
+		) -> Result<(), &'static str> {
+			PARACHAINS.with(|p| {
+				if p.borrow().contains_key(&id.into_inner()) {
+					panic!("ID already exists")
+				}
+				p.borrow_mut().insert(id.into_inner(), (code, initial_head_data));
+				Ok(())
+			})
+		}
+		fn deregister_parachain(id: Self::ParaId) -> Result<(), &'static str> {
+			PARACHAINS.with(|p| {
+				if !p.borrow().contains_key(&id.into_inner()) {
+					panic!("ID doesn't exist")
+				}
+				p.borrow_mut().remove(&id.into_inner());
+				Ok(())
+			})
+		}
+	}
+
+	fn reset_count() {
+		PARACHAIN_COUNT.with(|p| *p.borrow_mut() = 0);
+	}
+
+	fn with_parachains<T>(f: impl FnOnce(&HashMap<u32, (Vec<u8>, Vec<u8>)>) -> T) -> T {
+		PARACHAINS.with(|p| f(&*p.borrow()))
+	}
+
+	parameter_types!{
+		pub const LeasePeriod: u64 = 10;
+		pub const EndingPeriod: u64 = 3;
+	}
+
+	impl Trait for Test {
+		type Event = ();
+		type Currency = Balances;
+		type Parachains = TestParachains;
+		type LeasePeriod = LeasePeriod;
+		type EndingPeriod = EndingPeriod;
+	}
+
+	type System = system::Module<Test>;
+	type Balances = balances::Module<Test>;
+	type Slots = Module<Test>;
+
+	// This function basically just builds a genesis storage key/value store according to
+	// our desired mock up.
+	fn new_test_ext() -> sr_io::TestExternalities<Blake2Hasher> {
+		let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
+		t.extend(balances::GenesisConfig::<Test>{
+			transaction_base_fee: 0,
+			transaction_byte_fee: 0,
+			balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
+			existential_deposit: 0,
+			transfer_fee: 0,
+			creation_fee: 0,
+			vesting: vec![],
+		}.build_storage().unwrap().0);
+		t.into()
+	}
+
+	fn run_to_block(n: u64) {
+		while System::block_number() < n {
+			Slots::on_finalize(System::block_number());
+			Balances::on_finalize(System::block_number());
+			System::on_finalize(System::block_number());
+			System::set_block_number(System::block_number() + 1);
+			System::on_initialize(System::block_number());
+			Balances::on_initialize(System::block_number());
+			Slots::on_initialize(System::block_number());
+		}
+	}
+
+	#[test]
+	fn basic_setup_works() {
+		with_externalities(&mut new_test_ext(), || {
+			assert_eq!(Slots::auction_counter(), 0);
+			assert_eq!(Slots::deposit_held(&0u32.into()), 0);
+			assert_eq!(Slots::is_in_progress(), false);
+			assert_eq!(Slots::is_ending(System::block_number()), None);
+
+			run_to_block(10);
+
+			assert_eq!(Slots::auction_counter(), 0);
+			assert_eq!(Slots::deposit_held(&0u32.into()), 0);
+			assert_eq!(Slots::is_in_progress(), false);
+			assert_eq!(Slots::is_ending(System::block_number()), None);
+		});
+	}
+
+	#[test]
+	fn can_start_auction() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+
+			assert_ok!(Slots::new_auction(5, 1));
+
+			assert_eq!(Slots::auction_counter(), 1);
+			assert_eq!(Slots::is_in_progress(), true);
+			assert_eq!(Slots::is_ending(System::block_number()), None);
+		});
+	}
+
+	#[test]
+	fn auction_proceeds_correctly() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+
+			assert_ok!(Slots::new_auction(5, 1));
+
+			assert_eq!(Slots::auction_counter(), 1);
+			assert_eq!(Slots::is_in_progress(), true);
+			assert_eq!(Slots::is_ending(System::block_number()), None);
+
+			run_to_block(2);
+			assert_eq!(Slots::is_in_progress(), true);
+			assert_eq!(Slots::is_ending(System::block_number()), None);
+
+			run_to_block(3);
+			assert_eq!(Slots::is_in_progress(), true);
+			assert_eq!(Slots::is_ending(System::block_number()), None);
+
+			run_to_block(4);
+			assert_eq!(Slots::is_in_progress(), true);
+			assert_eq!(Slots::is_ending(System::block_number()), None);
+
+			run_to_block(5);
+			assert_eq!(Slots::is_in_progress(), true);
+			assert_eq!(Slots::is_ending(System::block_number()), None);
+
+			run_to_block(6);
+			assert_eq!(Slots::is_in_progress(), true);
+			assert_eq!(Slots::is_ending(System::block_number()), Some(0));
+
+			run_to_block(7);
+			assert_eq!(Slots::is_in_progress(), true);
+			assert_eq!(Slots::is_ending(System::block_number()), Some(1));
+
+			run_to_block(8);
+			assert_eq!(Slots::is_in_progress(), true);
+			assert_eq!(Slots::is_ending(System::block_number()), Some(2));
+
+			run_to_block(9);
+			assert_eq!(Slots::is_in_progress(), false);
+			assert_eq!(Slots::is_ending(System::block_number()), None);
+		});
+	}
+
+	#[test]
+	fn can_win_auction() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+
+			assert_ok!(Slots::new_auction(5, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 4, 1));
+			assert_eq!(Balances::reserved_balance(&1), 1);
+			assert_eq!(Balances::free_balance(&1), 9);
+
+			run_to_block(9);
+			assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
+			assert_eq!(Slots::onboarding(&0.into()),
+				Some((1, IncomingParachain::Unset(NewBidder { who: 1, sub: 0 })))
+			);
+			assert_eq!(Slots::deposit_held(&0.into()), 1);
+			assert_eq!(Balances::reserved_balance(&1), 0);
+			assert_eq!(Balances::free_balance(&1), 9);
+		});
+	}
+
+	#[test]
+	fn offboarding_works() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+			assert_ok!(Slots::new_auction(5, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 4, 1));
+
+			run_to_block(9);
+			assert_eq!(Slots::deposit_held(&0.into()), 1);
+			assert_eq!(Slots::deposits(&0.into())[0], 0);
+
+			run_to_block(49);
+			assert_eq!(Slots::deposit_held(&0.into()), 1);
+			assert_ok!(Slots::set_offboarding(Origin::signed(ParaId::from(0).into_account()), 10));
+
+			run_to_block(50);
+			assert_eq!(Slots::deposit_held(&0.into()), 0);
+			assert_eq!(Balances::free_balance(&10), 1);
+		});
+	}
+
+	#[test]
+	fn onboarding_works() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+			assert_ok!(Slots::new_auction(5, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 4, 1));
+
+			run_to_block(9);
+			let h = BlakeTwo256::hash(&[42u8][..]);
+			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, vec![69]));
+			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![42]));
+
+			run_to_block(10);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 1);
+				assert_eq!(p[&0], (vec![42], vec![69]));
+			});
+		});
+	}
+
+	#[test]
+	fn late_onboarding_works() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+			assert_ok!(Slots::new_auction(5, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 4, 1));
+
+			run_to_block(10);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 0);
+			});
+
+			run_to_block(11);
+			let h = BlakeTwo256::hash(&[42u8][..]);
+			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, vec![69]));
+			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![42]));
+			with_parachains(|p| {
+				assert_eq!(p.len(), 1);
+				assert_eq!(p[&0], (vec![42], vec![69]));
+			});
+		});
+	}
+
+	#[test]
+	fn under_bidding_works() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+			assert_ok!(Slots::new_auction(5, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 4, 5));
+			assert_ok!(Slots::bid(Origin::signed(2), 0, 1, 1, 4, 1));
+			assert_eq!(Balances::reserved_balance(&2), 0);
+			assert_eq!(Balances::free_balance(&2), 20);
+			assert_eq!(
+				Slots::winning(0).unwrap()[SlotRange::ZeroThree as u8 as usize],
+				Some((Bidder::New(NewBidder{who: 1, sub: 0}), 5))
+			);
+		});
+	}
+
+	#[test]
+	fn should_choose_best_combination() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+			assert_ok!(Slots::new_auction(5, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 1, 1));
+			assert_ok!(Slots::bid(Origin::signed(2), 0, 1, 2, 3, 1));
+			assert_ok!(Slots::bid(Origin::signed(3), 0, 1, 4, 4, 2));
+			assert_ok!(Slots::bid(Origin::signed(1), 1, 1, 1, 4, 1));
+			run_to_block(9);
+			assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
+			assert_eq!(
+				Slots::onboarding(&0.into()),
+				Some((1, IncomingParachain::Unset(NewBidder { who: 1, sub: 0 })))
+			);
+			assert_eq!(Slots::onboard_queue(2), vec![1.into()]);
+			assert_eq!(
+				Slots::onboarding(&1.into()),
+				Some((2, IncomingParachain::Unset(NewBidder { who: 2, sub: 0 })))
+			);
+			assert_eq!(Slots::onboard_queue(4), vec![2.into()]);
+			assert_eq!(
+				Slots::onboarding(&2.into()),
+				Some((4, IncomingParachain::Unset(NewBidder { who: 3, sub: 0 })))
+			);
+		});
+	}
+
+	#[test]
+	fn independent_bids_should_fail() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+			assert_ok!(Slots::new_auction(1, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 2, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 2, 4, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 2, 2, 1));
+			assert_noop!(
+				Slots::bid(Origin::signed(1), 0, 1, 3, 3, 1),
+				"bidder winning non-intersecting range"
+			);
+		});
+	}
+
+	#[test]
+	fn multiple_onboards_offboards_should_work() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+			assert_ok!(Slots::new_auction(1, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 1, 1));
+			assert_ok!(Slots::bid(Origin::signed(2), 0, 1, 2, 3, 1));
+			assert_ok!(Slots::bid(Origin::signed(3), 0, 1, 4, 4, 1));
+
+			run_to_block(5);
+			assert_ok!(Slots::new_auction(1, 1));
+			assert_ok!(Slots::bid(Origin::signed(4), 1, 2, 1, 2, 1));
+			assert_ok!(Slots::bid(Origin::signed(5), 1, 2, 3, 4, 1));
+
+			run_to_block(9);
+			assert_eq!(Slots::onboard_queue(1), vec![0.into(), 3.into()]);
+			assert_eq!(
+				Slots::onboarding(&0.into()),
+				Some((1, IncomingParachain::Unset(NewBidder { who: 1, sub: 0 })))
+			);
+			assert_eq!(
+				Slots::onboarding(&3.into()),
+				Some((1, IncomingParachain::Unset(NewBidder { who: 4, sub: 1 })))
+			);
+			assert_eq!(Slots::onboard_queue(2), vec![1.into()]);
+			assert_eq!(
+				Slots::onboarding(&1.into()),
+				Some((2, IncomingParachain::Unset(NewBidder { who: 2, sub: 0 })))
+			);
+			assert_eq!(Slots::onboard_queue(3), vec![4.into()]);
+			assert_eq!(
+				Slots::onboarding(&4.into()),
+				Some((3, IncomingParachain::Unset(NewBidder { who: 5, sub: 1 })))
+			);
+			assert_eq!(Slots::onboard_queue(4), vec![2.into()]);
+			assert_eq!(
+				Slots::onboarding(&2.into()),
+				Some((4, IncomingParachain::Unset(NewBidder { who: 3, sub: 0 })))
+			);
+
+			for &(para, sub, acc) in &[(0, 0, 1), (1, 0, 2), (2, 0, 3), (3, 1, 4), (4, 1, 5)] {
+				let h = BlakeTwo256::hash(&[acc][..]);
+				assert_ok!(Slots::fix_deploy_data(Origin::signed(acc as _), sub, para.into(), h, vec![acc]));
+				assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), para.into(), vec![acc]));
+			}
+
+			run_to_block(10);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 2);
+				assert_eq!(p[&0], (vec![1], vec![1]));
+				assert_eq!(p[&3], (vec![4], vec![4]));
+			});
+			run_to_block(20);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 2);
+				assert_eq!(p[&1], (vec![2], vec![2]));
+				assert_eq!(p[&3], (vec![4], vec![4]));
+			});
+			run_to_block(30);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 2);
+				assert_eq!(p[&1], (vec![2], vec![2]));
+				assert_eq!(p[&4], (vec![5], vec![5]));
+			});
+			run_to_block(40);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 2);
+				assert_eq!(p[&2], (vec![3], vec![3]));
+				assert_eq!(p[&4], (vec![5], vec![5]));
+			});
+			run_to_block(50);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 0);
+			});
+		});
+	}
+
+	#[test]
+	fn extensions_should_work() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+			assert_ok!(Slots::new_auction(5, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 1, 1));
+
+			run_to_block(9);
+			assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
+
+			run_to_block(10);
+			let h = BlakeTwo256::hash(&[1u8][..]);
+			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, vec![1]));
+			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![1]));
+
+			assert_ok!(Slots::new_auction(5, 2));
+			assert_ok!(Slots::bid_renew(Origin::signed(ParaId::from(0).into_account()), 2, 2, 2, 1));
+
+			with_parachains(|p| {
+				assert_eq!(p.len(), 1);
+				assert_eq!(p[&0], (vec![1], vec![1]));
+			});
+
+			run_to_block(20);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 1);
+				assert_eq!(p[&0], (vec![1], vec![1]));
+			});
+			assert_ok!(Slots::new_auction(5, 2));
+			assert_ok!(Balances::transfer(Origin::signed(1), ParaId::from(0).into_account(), 1));
+			assert_ok!(Slots::bid_renew(Origin::signed(ParaId::from(0).into_account()), 3, 3, 3, 2));
+
+			run_to_block(30);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 1);
+				assert_eq!(p[&0], (vec![1], vec![1]));
+			});
+
+			run_to_block(40);
+			with_parachains(|p| {
+				assert_eq!(p.len(), 0);
+			});
+		});
+	}
+
+	#[test]
+	fn renewal_with_lower_value_should_work() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+			assert_ok!(Slots::new_auction(5, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 1, 5));
+
+			run_to_block(9);
+			assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
+
+			run_to_block(10);
+			let h = BlakeTwo256::hash(&[1u8][..]);
+			assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, vec![1]));
+			assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![1]));
+
+			assert_ok!(Slots::new_auction(5, 2));
+			assert_ok!(Slots::bid_renew(Origin::signed(ParaId::from(0).into_account()), 2, 2, 2, 3));
+
+			run_to_block(20);
+			assert_eq!(Balances::free_balance(&ParaId::from(0).into_account()), 2);
+
+			assert_ok!(Slots::new_auction(5, 2));
+			assert_ok!(Slots::bid_renew(Origin::signed(ParaId::from(0).into_account()), 3, 3, 3, 4));
+
+			run_to_block(30);
+			assert_eq!(Balances::free_balance(&ParaId::from(0).into_account()), 1);
+		});
+	}
+
+	#[test]
+	fn can_win_incomplete_auction() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+
+			assert_ok!(Slots::new_auction(5, 1));
+			assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 4, 4, 5));
+
+			run_to_block(9);
+			assert_eq!(Slots::onboard_queue(1), vec![]);
+			assert_eq!(Slots::onboard_queue(2), vec![]);
+			assert_eq!(Slots::onboard_queue(3), vec![]);
+			assert_eq!(Slots::onboard_queue(4), vec![0.into()]);
+			assert_eq!(Slots::onboarding(
+				&0.into()),
+				Some((4, IncomingParachain::Unset(NewBidder { who: 1, sub: 0 })))
+			);
+			assert_eq!(Slots::deposit_held(&0.into()), 5);
+		});
+	}
+
+	#[test]
+	fn multiple_bids_work_pre_ending() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+
+			assert_ok!(Slots::new_auction(5, 1));
+
+			for i in 1..6 {
+				run_to_block(i);
+				assert_ok!(Slots::bid(Origin::signed(i), 0, 1, 1, 4, i));
+				for j in 1..6 {
+					assert_eq!(Balances::reserved_balance(&j), if j == i { j } else { 0 });
+					assert_eq!(Balances::free_balance(&j), if j == i { j * 9 } else { j * 10 });
+				}
+			}
+
+			run_to_block(9);
+			assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
+			assert_eq!(
+				Slots::onboarding(&0.into()),
+				Some((1, IncomingParachain::Unset(NewBidder { who: 5, sub: 0 })))
+			);
+			assert_eq!(Slots::deposit_held(&0.into()), 5);
+			assert_eq!(Balances::reserved_balance(&5), 0);
+			assert_eq!(Balances::free_balance(&5), 45);
+		});
+	}
+
+	#[test]
+	fn multiple_bids_work_post_ending() {
+		with_externalities(&mut new_test_ext(), || {
+			run_to_block(1);
+
+			assert_ok!(Slots::new_auction(5, 1));
+
+			for i in 1..6 {
+				run_to_block(i + 3);
+				assert_ok!(Slots::bid(Origin::signed(i), 0, 1, 1, 4, i));
+				for j in 1..6 {
+					assert_eq!(Balances::reserved_balance(&j), if j == i { j } else { 0 });
+					assert_eq!(Balances::free_balance(&j), if j == i { j * 9 } else { j * 10 });
+				}
+			}
+
+			run_to_block(9);
+			assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
+			assert_eq!(Slots::onboarding(
+				&0.into()),
+				Some((1, IncomingParachain::Unset(NewBidder { who: 3, sub: 0 })))
+			);
+			assert_eq!(Slots::deposit_held(&0.into()), 3);
+			assert_eq!(Balances::reserved_balance(&3), 0);
+			assert_eq!(Balances::free_balance(&3), 27);
+		});
+	}
+
+	#[test]
+	fn incomplete_calculate_winners_works() {
+		let winning = [
+			None,
+			None,
+			None,
+			None,
+			None,
+			None,
+			None,
+			None,
+			None,
+			Some((Bidder::New(NewBidder{who: 1, sub: 0}), 1)),
+		];
+		let winners = vec![
+			(Some(NewBidder{who: 1, sub: 0}), 0.into(), 1, SlotRange::ThreeThree)
+		];
+
+		assert_eq!(Slots::calculate_winners(winning, TestParachains::new_id), winners);
+	}
+
+	#[test]
+	fn first_incomplete_calculate_winners_works() {
+		let winning = [
+			Some((Bidder::New(NewBidder{who: 1, sub: 0}), 1)),
+			None,
+			None,
+			None,
+			None,
+			None,
+			None,
+			None,
+			None,
+			None,
+		];
+		let winners = vec![
+			(Some(NewBidder{who: 1, sub: 0}), 0.into(), 1, SlotRange::ZeroZero)
+		];
+
+		assert_eq!(Slots::calculate_winners(winning, TestParachains::new_id), winners);
+	}
+
+	#[test]
+	fn calculate_winners_works() {
+		let mut winning = [
+			/*0..0*/
+			Some((Bidder::New(NewBidder{who: 2, sub: 0}), 2)),
+			/*0..1*/
+			None,
+			/*0..2*/
+			None,
+			/*0..3*/
+			Some((Bidder::New(NewBidder{who: 1, sub: 0}), 1)),
+			/*1..1*/
+			Some((Bidder::New(NewBidder{who: 3, sub: 0}), 1)),
+			/*1..2*/
+			None,
+			/*1..3*/
+			None,
+			/*2..2*/
+			//Some((Bidder::New(NewBidder{who: 4, sub: 0}), 1)),
+			Some((Bidder::New(NewBidder{who: 1, sub: 0}), 53)),
+			/*2..3*/
+			None,
+			/*3..3*/
+			Some((Bidder::New(NewBidder{who: 5, sub: 0}), 1)),
+		];
+		let winners = vec![
+			(Some(NewBidder{who: 2,sub: 0}), 0.into(), 2, SlotRange::ZeroZero),
+			(Some(NewBidder{who: 3,sub: 0}), 1.into(), 1, SlotRange::OneOne),
+			(Some(NewBidder{who: 1,sub: 0}), 2.into(), 53, SlotRange::TwoTwo),
+			(Some(NewBidder{who: 5,sub: 0}), 3.into(), 1, SlotRange::ThreeThree)
+		];
+
+		assert_eq!(Slots::calculate_winners(winning.clone(), TestParachains::new_id), winners);
+
+		reset_count();
+		winning[SlotRange::ZeroThree as u8 as usize] = Some((Bidder::New(NewBidder{who: 1, sub: 0}), 2));
+		let winners = vec![
+			(Some(NewBidder{who: 2,sub: 0}), 0.into(), 2, SlotRange::ZeroZero),
+			(Some(NewBidder{who: 3,sub: 0}), 1.into(), 1, SlotRange::OneOne),
+			(Some(NewBidder{who: 1,sub: 0}), 2.into(), 53, SlotRange::TwoTwo),
+			(Some(NewBidder{who: 5,sub: 0}), 3.into(), 1, SlotRange::ThreeThree)
+		];
+		assert_eq!(Slots::calculate_winners(winning.clone(), TestParachains::new_id), winners);
+
+		reset_count();
+		winning[SlotRange::ZeroOne as u8 as usize] = Some((Bidder::New(NewBidder{who: 4, sub: 0}), 3));
+		let winners = vec![
+			(Some(NewBidder{who: 4,sub: 0}), 0.into(), 3, SlotRange::ZeroOne),
+			(Some(NewBidder{who: 1,sub: 0}), 1.into(), 53, SlotRange::TwoTwo),
+			(Some(NewBidder{who: 5,sub: 0}), 2.into(), 1, SlotRange::ThreeThree)
+		];
+		assert_eq!(Slots::calculate_winners(winning.clone(), TestParachains::new_id), winners);
+	}
+}
diff --git a/polkadot/runtime/wasm/Cargo.lock b/polkadot/runtime/wasm/Cargo.lock
index 8e0428ecd99..251c02b15f9 100644
--- a/polkadot/runtime/wasm/Cargo.lock
+++ b/polkadot/runtime/wasm/Cargo.lock
@@ -119,11 +119,6 @@ dependencies = [
  "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "base-x"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "base58"
 version = "0.1.0"
@@ -487,11 +482,6 @@ dependencies = [
  "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "discard"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "dns-parser"
 version = "0.8.0"
@@ -891,41 +881,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libp2p"
-version = "0.7.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core-derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-dns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-floodsub 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-identify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-kad 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-mdns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-mplex 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-noise 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-ping 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-plaintext 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-ratelimit 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-secio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-tcp 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-uds 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-yamux 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core-derive 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-dns 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-floodsub 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-identify 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-kad 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-mdns 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-mplex 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-noise 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-ping 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-plaintext 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-ratelimit 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-secio 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-tcp 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-uds 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-wasm-ext 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-yamux 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-multihash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "stdweb 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libp2p-core"
-version = "0.7.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "asn1_der 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -936,6 +927,7 @@ dependencies = [
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "multistream-select 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -946,21 +938,20 @@ dependencies = [
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libp2p-core-derive"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -969,20 +960,19 @@ dependencies = [
 
 [[package]]
 name = "libp2p-dns"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libp2p-floodsub"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -990,7 +980,7 @@ dependencies = [
  "cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "protobuf 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1001,13 +991,13 @@ dependencies = [
 
 [[package]]
 name = "libp2p-identify"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1015,14 +1005,14 @@ dependencies = [
  "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libp2p-kad"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1032,7 +1022,7 @@ dependencies = [
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-multihash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1042,20 +1032,20 @@ dependencies = [
  "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libp2p-mdns"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1063,20 +1053,20 @@ dependencies = [
  "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libp2p-mplex"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1086,14 +1076,16 @@ dependencies = [
 
 [[package]]
 name = "libp2p-noise"
-version = "0.5.0"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "protobuf 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1104,41 +1096,42 @@ dependencies = [
 
 [[package]]
 name = "libp2p-ping"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libp2p-plaintext"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libp2p-ratelimit"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aio-limited 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1146,7 +1139,7 @@ dependencies = [
 
 [[package]]
 name = "libp2p-secio"
-version = "0.7.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1157,13 +1150,13 @@ dependencies = [
  "hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "protobuf 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1175,14 +1168,14 @@ dependencies = [
 
 [[package]]
 name = "libp2p-tcp"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tk-listen 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1190,23 +1183,36 @@ dependencies = [
 
 [[package]]
 name = "libp2p-uds"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "libp2p-wasm-ext"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-futures 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "libp2p-yamux"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1518,6 +1524,11 @@ dependencies = [
  "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "parity-send-wrapper"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "parity-wasm"
 version = "0.31.3"
@@ -2044,15 +2055,6 @@ name = "scopeguard"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "secp256k1"
-version = "0.12.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "semver"
 version = "0.9.0"
@@ -2219,7 +2221,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 [[package]]
 name = "sr-api-macros"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2231,7 +2233,7 @@ dependencies = [
 [[package]]
 name = "sr-io"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2248,7 +2250,7 @@ dependencies = [
 [[package]]
 name = "sr-primitives"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2263,7 +2265,7 @@ dependencies = [
 [[package]]
 name = "sr-std"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2271,7 +2273,7 @@ dependencies = [
 [[package]]
 name = "sr-version"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2283,7 +2285,7 @@ dependencies = [
 [[package]]
 name = "srml-aura"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
@@ -2299,7 +2301,7 @@ dependencies = [
 [[package]]
 name = "srml-balances"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2314,7 +2316,7 @@ dependencies = [
 [[package]]
 name = "srml-consensus"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2329,7 +2331,7 @@ dependencies = [
 [[package]]
 name = "srml-council"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2346,7 +2348,7 @@ dependencies = [
 [[package]]
 name = "srml-democracy"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2361,7 +2363,7 @@ dependencies = [
 [[package]]
 name = "srml-executive"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2375,7 +2377,7 @@ dependencies = [
 [[package]]
 name = "srml-finality-tracker"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2389,7 +2391,7 @@ dependencies = [
 [[package]]
 name = "srml-grandpa"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2407,7 +2409,7 @@ dependencies = [
 [[package]]
 name = "srml-indices"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2424,7 +2426,7 @@ dependencies = [
 [[package]]
 name = "srml-metadata"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2435,7 +2437,7 @@ dependencies = [
 [[package]]
 name = "srml-session"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2451,7 +2453,7 @@ dependencies = [
 [[package]]
 name = "srml-staking"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2469,10 +2471,11 @@ dependencies = [
 [[package]]
 name = "srml-sudo"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-io 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
  "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
  "sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
  "srml-support 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
@@ -2483,7 +2486,7 @@ dependencies = [
 [[package]]
 name = "srml-support"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2501,7 +2504,7 @@ dependencies = [
 [[package]]
 name = "srml-support-procedural"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2513,7 +2516,7 @@ dependencies = [
 [[package]]
 name = "srml-support-procedural-tools"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2525,7 +2528,7 @@ dependencies = [
 [[package]]
 name = "srml-support-procedural-tools-derive"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2535,7 +2538,7 @@ dependencies = [
 [[package]]
 name = "srml-system"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2550,7 +2553,7 @@ dependencies = [
 [[package]]
 name = "srml-timestamp"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2564,7 +2567,7 @@ dependencies = [
 [[package]]
 name = "srml-treasury"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2590,50 +2593,6 @@ name = "static_slice"
 version = "0.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "stdweb"
-version = "0.4.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "stdweb-internal-macros 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "stdweb-internal-runtime 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "stdweb-derive"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "stdweb-internal-macros"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "base-x 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "stdweb-internal-runtime"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "stream-cipher"
 version = "0.3.0"
@@ -2672,7 +2631,7 @@ dependencies = [
 [[package]]
 name = "substrate-client"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2700,7 +2659,7 @@ dependencies = [
 [[package]]
 name = "substrate-consensus-aura-primitives"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
  "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
@@ -2709,7 +2668,7 @@ dependencies = [
 [[package]]
 name = "substrate-consensus-authorities"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
@@ -2724,15 +2683,16 @@ dependencies = [
 [[package]]
 name = "substrate-consensus-common"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
- "libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libp2p 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
+ "sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
  "sr-version 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
  "substrate-inherents 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)",
@@ -2742,7 +2702,7 @@ dependencies = [
 [[package]]
 name = "substrate-executor"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2765,7 +2725,7 @@ dependencies = [
 [[package]]
 name = "substrate-finality-grandpa-primitives"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
@@ -2777,7 +2737,7 @@ dependencies = [
 [[package]]
 name = "substrate-inherents"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2788,7 +2748,7 @@ dependencies = [
 [[package]]
 name = "substrate-keyring"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
@@ -2800,7 +2760,7 @@ dependencies = [
 [[package]]
 name = "substrate-offchain-primitives"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
  "substrate-client 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
@@ -2809,7 +2769,7 @@ dependencies = [
 [[package]]
 name = "substrate-panic-handler"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2818,7 +2778,7 @@ dependencies = [
 [[package]]
 name = "substrate-primitives"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2846,7 +2806,7 @@ dependencies = [
 [[package]]
 name = "substrate-serializer"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2855,7 +2815,7 @@ dependencies = [
 [[package]]
 name = "substrate-state-machine"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2871,7 +2831,7 @@ dependencies = [
 [[package]]
 name = "substrate-telemetry"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2889,7 +2849,7 @@ dependencies = [
 [[package]]
 name = "substrate-trie"
 version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#173c19518539643ddef85761bd6b22252fa5c238"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-master#6d38263434aba843585c7dc8744fc89703be90b5"
 dependencies = [
  "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3405,6 +3365,18 @@ dependencies = [
  "weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "wasm-timer"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "web-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "wasmi"
 version = "0.4.4"
@@ -3553,7 +3525,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
 "checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4"
 "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
-"checksum base-x 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d55aa264e822dbafa12db4d54767aff17c6ba55ea2d8559b3e17392c7d000e5d"
 "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
 "checksum bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebecac13b3c745150d7b6c3ea7572d372f09d627c2077e893bf26c5c7f70d282"
 "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
@@ -3600,7 +3571,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbe9f11be34f800b3ecaaed0ec9ec2e015d1d0ba0c8644c1310f73d6e8994615"
 "checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a"
 "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
-"checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
 "checksum dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea"
 "checksum ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86"
 "checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
@@ -3653,23 +3623,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
 "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 "checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917"
-"checksum libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0231edab431064b30b7749484a39735eb36492cef4658c372c9059e58c3003aa"
-"checksum libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a3bad2ed26297112847678683dd221473a0d44297250b61f004e1b35e72493"
-"checksum libp2p-core-derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f765f103b680cbed910b02bfdbdcfce5b1142899c93e51acb960bf59b6f81b1"
-"checksum libp2p-dns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b129d20cc8cbb6ce5da8361045649c024659173e246c5dfbf20ae06071c046a"
-"checksum libp2p-floodsub 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70d68816b8435d6788399416eb2f0a6974fb1d15c4be5c30141f87c8e81746df"
-"checksum libp2p-identify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "718ca645a065fd70855ca6042a7df686c24cd21add750c37a82c811fbd1e5c43"
-"checksum libp2p-kad 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bbe27c623a6a720efd5d704347838972062f89149a9c3cd149748da60bdcd3e0"
-"checksum libp2p-mdns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9bc1a5d85f4812cae6367b49a432763fe28997bac7c530dc55b70ec18a78aa7"
-"checksum libp2p-mplex 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe5a858342a1cc89464474f7edc4bae1da649b9c823a3e04d9fb494493601746"
-"checksum libp2p-noise 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc6b5185c50a52a12e7bbe2ee7799059e24de4e52ab25edbfd26c8ab8515d317"
-"checksum libp2p-ping 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7905c1431ad115bee83405770629a27d6f17153ad02ec9670a7347998ef20e22"
-"checksum libp2p-plaintext 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc17626763ded57da8fed73187c2d9f6ebb89d30838673c430315bf560c7e4db"
-"checksum libp2p-ratelimit 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2409d08b809ab1a74269597f7da2829d117cc11b9ed3343af33fc20831619726"
-"checksum libp2p-secio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258cdc6742945c8f6402997bbbf36733588e2db18e5a0014da6d46e3ccfb92cf"
-"checksum libp2p-tcp 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b5691e2ba2720d42bd1e93d6b90239fa9235c1956ef6a5f1dd499a7ae2767be"
-"checksum libp2p-uds 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ab0b9ca050105fd94229c48911c0c84aef4d6b86a53d1b6df81d938354e47e"
-"checksum libp2p-yamux 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6ff51a5b2056bacee1c9f2ed8455cdf3c5c619261ddb4efc783119130aaf52"
+"checksum libp2p 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141ab3f96adc87c8cb847b1cf790e0fbce0b03e3dabfdd3b72fe23d36fc005de"
+"checksum libp2p-core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1514593f2aced40b257565cf2edc63b4cc2f06241a2f3e5a4fe275e0c4d55e85"
+"checksum libp2p-core-derive 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f6f5543deedf4d89931a74d3897b63be19a62d5cb675efaa4c669a4aa0ab12"
+"checksum libp2p-dns 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9db88ba58601f4528ef5e5e5414e142b19d5813bdaa685e683ef5a44ed23606b"
+"checksum libp2p-floodsub 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "260689f26ab2161a1fde9617c53699f78e4ab25fd77c4b07a25b97fca74c5c6d"
+"checksum libp2p-identify 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1281e58168ed62cf2e9bfe127908a0ec277cf48cbb3dec5b1a68b58ea6332171"
+"checksum libp2p-kad 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd8ab542edc493fa7a9f9b7f93dc4ee0b384e1f9e2a3397ce0056ffe30a0ea21"
+"checksum libp2p-mdns 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f009594f78d952c57f452be237650025acd4ef17c5cc8eda4c6466ba196e5688"
+"checksum libp2p-mplex 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ccfb9869daccfb9d3938eda8821146e85105a8c874f14393cdb57543afeceb38"
+"checksum libp2p-noise 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d3dce2ec4fcb3a2cc748c02d61f7e76486df9c7b09e8ccb4d9f81befce207de"
+"checksum libp2p-ping 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b3bb3328d206ad3061e863f179a211fc978d7bce05f90440ed6b8a6a9d17ced"
+"checksum libp2p-plaintext 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b23a8ece138f448572c5ff781d62323a954f1f681c303e6553368026764b0ae"
+"checksum libp2p-ratelimit 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55918f058f118d72d83f9a976f12e02e54c8616ddfc795c779c4801a5042a44f"
+"checksum libp2p-secio 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ea5c0636053e01575d6269b6112f9239e9d35ca861e3e5c7d6970a07f9e1682a"
+"checksum libp2p-tcp 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3629f9a667d9f5acb5876df59cf3b547250e340131c47587f9ace7c517f21327"
+"checksum libp2p-uds 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d65c15f89c0607d4a334664d759e54e847e1856a73ea78e7bb6a75e6f4039010"
+"checksum libp2p-wasm-ext 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "318d727d5e8e0fe3bb70aacbf99bde57334eae9559deff447edd993422dc0f03"
+"checksum libp2p-yamux 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5369165359bea84e7ebe73f37b6240f31f8d924ce6710be3d8e1fa678985c9b8"
 "checksum libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "688e8d65e495567c2c35ea0001b26b9debf0b4ea11f8cccc954233b75fc3428a"
 "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
@@ -3704,6 +3675,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00a486fd383382ddcb2de928364b1f82571c1e48274fc43b7667a4738ee4056c"
 "checksum parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18a130a727008cfcd1068a28439fe939897ccad28664422aeca65b384d6de6d0"
 "checksum parity-multihash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e8eab0287ccde7821e337a124dc5a4f1d6e4c25d10cc91e3f9361615dd95076"
+"checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f"
 "checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc"
 "checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac"
 "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
@@ -3755,7 +3727,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347"
 "checksum schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5eff518f9bed3d803a0d002af0ab96339b0ebbedde3bec98a684986134b7a39"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
-"checksum secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfaccd3a23619349e0878d9a241f34b1982343cdf67367058cd7d078d326b63e"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4"
@@ -3803,10 +3774,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
 "checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5"
 "checksum static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "92a7e0c5e3dfb52e8fbe0e63a1b947bbb17b4036408b151353c4491374931362"
-"checksum stdweb 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a3edad410e603184d656e2abded5fd4d3d6e93d5763d21130dbaf99795db74eb"
-"checksum stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e21ebd9179de08f2300a65454268a17ea3de204627458588c84319c4def3930"
-"checksum stdweb-internal-macros 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1635afd059cbfac7d5b1274f0c44cec110c1e013c48e8bbc22e07e52696cf887"
-"checksum stdweb-internal-runtime 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a2a2f4a2eb556337b2d1a302630bbddf989ae383c70393e89b48152b9896cbda"
 "checksum stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8861bc80f649f5b4c9bd38b696ae9af74499d479dbfb327f0607de6b326a36bc"
 "checksum strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1810e25f576e7ffce1ff5243b37066da5ded0310b3274c20baaeccb1145b2806"
 "checksum strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "572a2f4e53dd4c3483fd79e5cc10ddd773a3acb1169bbfe8762365e107110579"
@@ -3879,6 +3846,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum wasm-bindgen-macro-support 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "fba68375ef8f095c4a169c093c95ed2e1b5e44f7872f3bcbcafe2c51b4a80480"
 "checksum wasm-bindgen-shared 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "321949f4d7f7bf7a49dccd464bdc46581b180f761d9505e4943926d50b2a4a64"
 "checksum wasm-bindgen-webidl 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c2c2b45b827f96657beea954a5430d37da4cf477d2874595f5f0a6ad027980"
+"checksum wasm-timer 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad9ac33c834103916e373d648adf65f58c83fb3d8a0f3e6b9a64bca7253a4dca"
 "checksum wasmi 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f6a891b45c79e9f96fb66cc84a057211ef9cd2e5e8d093f3dbbd480e146a8758"
 "checksum web-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "47ad2ecfe3793a87a0aa49562ad6f01cb3af3c870213283bc60032ec8dd7e62a"
 "checksum weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26a4c67f132386d965390b8a734d5d10adbcd30eb5cc74bd9229af8b83f10044"
diff --git a/polkadot/test-parachains/adder/Cargo.toml b/polkadot/test-parachains/adder/Cargo.toml
index 1056bd2cbcb..118fccd73d5 100644
--- a/polkadot/test-parachains/adder/Cargo.toml
+++ b/polkadot/test-parachains/adder/Cargo.toml
@@ -6,6 +6,6 @@ description = "Test parachain which adds to a number as its state transition"
 
 [dependencies]
 polkadot-parachain = { path = "../../parachain/", default-features = false }
-parity-codec = { version = "3.0", default-features = false }
-parity-codec-derive = { version = "3.0", default-features = false }
+parity-codec = { version = "3.5", default-features = false }
+parity-codec-derive = { version = "3.3", default-features = false }
 tiny-keccak = "1.4"
-- 
GitLab