diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index 4f4a414d7a222ede157c6175b686da8538b74730..dd81690e5f2d40dc6ef90328c8a1ea8a5a8e2540 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -333,6 +333,18 @@ dependencies = [
  "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "ethbloom"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fixed-hash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "ethcore-bigint"
 version = "0.2.1"
@@ -460,6 +472,28 @@ dependencies = [
  "uint 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "ethereum-types"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ethbloom 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fixed-hash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "uint 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ethereum-types-serialize"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "ethkey"
 version = "0.3.0"
@@ -1091,6 +1125,7 @@ dependencies = [
  "polkadot-collator 0.1.0",
  "polkadot-primitives 0.1.0",
  "polkadot-statement-table 0.1.0",
+ "polkadot-transaction-pool 0.1.0",
  "substrate-bft 0.1.0",
  "substrate-codec 0.1.0",
  "substrate-primitives 0.1.0",
@@ -1152,6 +1187,20 @@ dependencies = [
  "substrate-primitives 0.1.0",
 ]
 
+[[package]]
+name = "polkadot-transaction-pool"
+version = "0.1.0"
+dependencies = [
+ "ed25519 0.1.0",
+ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ethereum-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "polkadot-api 0.1.0",
+ "polkadot-primitives 0.1.0",
+ "substrate-codec 0.1.0",
+ "substrate-primitives 0.1.0",
+ "transaction-pool 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "polkadot-validator"
 version = "0.1.0"
@@ -1439,6 +1488,11 @@ name = "smallvec"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "smallvec"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "smallvec"
 version = "0.6.0"
@@ -1825,6 +1879,17 @@ name = "traitobject"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "transaction-pool"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ethereum-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "triehash"
 version = "0.1.0"
@@ -2044,6 +2109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
 "checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
 "checksum ethbloom 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5f7fb5d27fb017f21c15d1e0b953831b58581c9942a5e5614fd2b6603697b7"
+"checksum ethbloom 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f240172b976e2421fa5485e45cd45287bbdb56d742aa3a1d77005c49071a8518"
 "checksum ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb5af77e74a8f70e9c3337e069c37bc82178ef1b459c02091f73c4ad5281eb5"
 "checksum ethcore-bytes 0.1.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
 "checksum ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3977c772cd6c5c22e1c7cfa208e4c3b746bd6c3a6c8eeec0999a6b2103015ad5"
@@ -2053,6 +2119,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum ethcore-network 1.9.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
 "checksum ethcrypto 0.1.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
 "checksum ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2adaa5b8ceafcce0bc3a68ef116ca5702958cc97d70a6eb008aeddb569b092b3"
+"checksum ethereum-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5cff74129deda8a155b729cad1a22dc3cdd08115abd1165079c519d0cab6917a"
+"checksum ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac59a21a9ce98e188f3dace9eb67a6c4a3c67ec7fbc7218cb827852679dc002"
 "checksum ethkey 0.3.0 (git+https://github.com/paritytech/parity.git)" = "<none>"
 "checksum fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)" = "<none>"
 "checksum fixed-hash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21c520ebc46522d519aec9cba2b7115d49cea707d771b772c46bec61aa0daeb8"
@@ -2150,6 +2218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d"
 "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
+"checksum smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4f357e8cd37bf8822e1b964e96fd39e2cb5a0424f8aaa284ccaccc2162411c"
 "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
 "checksum snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
 "checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
@@ -2170,6 +2239,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
 "checksum tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6131e780037787ff1b3f8aad9da83bca02438b72277850dd6ad0d455e0e20efc"
 "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
+"checksum transaction-pool 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23303835df389f9c34ad45cacf392304193f974faaf48c30a4ece2b03da0ed57"
 "checksum triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9291c7f0fae44858b5e087dd462afb382354120003778f1695b44aab98c7abd7"
 "checksum twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "475352206e7a290c5fccc27624a163e8d0d115f7bb60ca18a64fc9ce056d7435"
 "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
diff --git a/substrate/Cargo.toml b/substrate/Cargo.toml
index e56f0ddcd135f37dd49cd65d25b641fd2e0df077..635370e2dfcb8be558134b90d6243fa85ea81c4b 100644
--- a/substrate/Cargo.toml
+++ b/substrate/Cargo.toml
@@ -21,6 +21,7 @@ members = [
 	"polkadot/primitives",
 	"polkadot/runtime",
 	"polkadot/statement-table",
+	"polkadot/transaction-pool",
 	"polkadot/validator",
 	"substrate/bft",
 	"substrate/client",
diff --git a/substrate/demo/runtime/src/lib.rs b/substrate/demo/runtime/src/lib.rs
index f42d16016a4d07cb04662c0e2c0a0e5412fbcf04..110061ee7c4c5080be992ce93cbbd528ef112c30 100644
--- a/substrate/demo/runtime/src/lib.rs
+++ b/substrate/demo/runtime/src/lib.rs
@@ -18,7 +18,7 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
-extern crate substrate_runtime_std as rstd;
+#[macro_use] extern crate substrate_runtime_std as rstd;
 #[macro_use] extern crate substrate_runtime_io as runtime_io;
 extern crate substrate_runtime_support as runtime_support;
 #[cfg(all(feature = "std", test))] extern crate substrate_keyring as keyring;
diff --git a/substrate/demo/runtime/wasm/Cargo.lock b/substrate/demo/runtime/wasm/Cargo.lock
index 245ae29a7ac6aaed2cb1573d7dc53f66082cdd35..a415dd58eb92f6e8aed7d52d1a9544bdf4bd9e4a 100644
--- a/substrate/demo/runtime/wasm/Cargo.lock
+++ b/substrate/demo/runtime/wasm/Cargo.lock
@@ -104,6 +104,7 @@ name = "demo-runtime"
 version = "0.1.0"
 dependencies = [
  "demo-primitives 0.1.0",
+ "integer-sqrt 0.1.0 (git+https://github.com/paritytech/integer-sqrt-rs.git)",
  "substrate-codec 0.1.0",
  "substrate-primitives 0.1.0",
  "substrate-runtime-io 0.1.0",
@@ -243,6 +244,11 @@ dependencies = [
  "proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "integer-sqrt"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/integer-sqrt-rs.git#f4cf61482096dc98c1273f46a10849d182b4c23c"
+
 [[package]]
 name = "isatty"
 version = "0.1.6"
@@ -830,6 +836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
 "checksum hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd546ef520ab3745f1aae5f2cdc6de9e6498e94d1ab138b9eb3ddfbf335847fb"
 "checksum hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2ea76da4c7f1a54d01d54985566d3fdd960b2bbd7b970da024821c883c2d9631"
+"checksum integer-sqrt 0.1.0 (git+https://github.com/paritytech/integer-sqrt-rs.git)" = "<none>"
 "checksum isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f2a233726c7bb76995cec749d59582e5664823b7245d4970354408f1d79a7a2"
 "checksum keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f300c1f149cd9ca5214eed24f6e713a597517420fb8b15499824aa916259ec1"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
diff --git a/substrate/demo/runtime/wasm/Cargo.toml b/substrate/demo/runtime/wasm/Cargo.toml
index 04d8999e275d7c12a814aaf09f790c5cfe97a5b5..436c482015cba32e5d7c1d0303e7a47412b5dae7 100644
--- a/substrate/demo/runtime/wasm/Cargo.toml
+++ b/substrate/demo/runtime/wasm/Cargo.toml
@@ -13,7 +13,7 @@ substrate-runtime-io = { path = "../../../substrate/runtime-io", default-feature
 substrate-runtime-support = { path = "../../../substrate/runtime-support", default-features = false }
 substrate-primitives = { path = "../../../substrate/primitives", default-features = false }
 demo-primitives = { path = "../../primitives", default-features = false }
-integer-sqrt = "0.1.0"
+integer-sqrt = { git = "https://github.com/paritytech/integer-sqrt-rs.git", branch = "master" }
 
 [features]
 default = []
diff --git a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm
index 437bbeb5de2b9a6c42b58d75b9b4b6041d749fdd..f542540c93e1ab432c2fed89067e577220d80c48 100644
Binary files a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm and b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm differ
diff --git a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm
index 98838fcf5013dd87ef37bfad8d0df2ff81071c9f..8ecf2b7224ed72d40b1bee2ca4d924177a099644 100644
Binary files a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm and b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm differ
diff --git a/substrate/polkadot/api/src/lib.rs b/substrate/polkadot/api/src/lib.rs
index 0ffb55233acfed6b6ffcf51fd2519ca650081218..2eeb0cd06d0d3f365c546dd392e53ba54117dbdc 100644
--- a/substrate/polkadot/api/src/lib.rs
+++ b/substrate/polkadot/api/src/lib.rs
@@ -36,7 +36,7 @@ use polkadot_runtime::runtime;
 use polkadot_executor::Executor as LocalDispatch;
 use substrate_executor::{NativeExecutionDispatch, NativeExecutor};
 use state_machine::OverlayedChanges;
-use primitives::{AccountId, SessionKey, Timestamp};
+use primitives::{AccountId, SessionKey, Timestamp, TxOrder};
 use primitives::block::{Id as BlockId, Block, Header, Body};
 use primitives::transaction::UncheckedTransaction;
 use primitives::parachain::DutyRoster;
@@ -85,6 +85,7 @@ impl From<client::error::Error> for Error {
 	}
 }
 
+/// A builder for blocks.
 pub trait BlockBuilder: Sized {
 	/// Push a non-inherent transaction.
 	fn push_transaction(&mut self, transaction: UncheckedTransaction) -> Result<()>;
@@ -93,40 +94,64 @@ pub trait BlockBuilder: Sized {
 	fn bake(self) -> Block;
 }
 
+/// A checked block identifier.
+pub trait CheckedBlockId: Clone {
+	/// Yield the underlying block ID.
+	fn block_id(&self) -> &BlockId;
+}
+
 /// Trait encapsulating the Polkadot API.
 ///
 /// All calls should fail when the exact runtime is unknown.
 pub trait PolkadotApi {
+	/// A checked block ID. Used to avoid redundancy of code check.
+	type CheckedBlockId: CheckedBlockId;
+	/// The type used to build blocks.
 	type BlockBuilder: BlockBuilder;
 
+	/// Check whether requests at the given block ID can be served.
+	///
+	/// It should not be possible to instantiate this type without going
+	/// through this function.
+	fn check_id(&self, id: BlockId) -> Result<Self::CheckedBlockId>;
+
 	/// Get session keys at a given block.
-	fn session_keys(&self, at: &BlockId) -> Result<Vec<SessionKey>>;
+	fn session_keys(&self, at: &Self::CheckedBlockId) -> Result<Vec<SessionKey>>;
 
 	/// Get validators at a given block.
-	fn validators(&self, at: &BlockId) -> Result<Vec<AccountId>>;
+	fn validators(&self, at: &Self::CheckedBlockId) -> Result<Vec<AccountId>>;
 
 	/// Get the authority duty roster at a block.
-	fn duty_roster(&self, at: &BlockId) -> Result<DutyRoster>;
+	fn duty_roster(&self, at: &Self::CheckedBlockId) -> Result<DutyRoster>;
 
 	/// Get the timestamp registered at a block.
-	fn timestamp(&self, at: &BlockId) -> Result<Timestamp>;
+	fn timestamp(&self, at: &Self::CheckedBlockId) -> Result<Timestamp>;
+
+	/// Get the nonce of an account at a block.
+	fn nonce(&self, at: &Self::CheckedBlockId, account: AccountId) -> Result<TxOrder>;
+
 
 	/// Evaluate a block and see if it gives an error.
-	fn evaluate_block(&self, at: &BlockId, block: Block) -> Result<()>;
+	fn evaluate_block(&self, at: &Self::CheckedBlockId, block: Block) -> Result<()>;
 
 	/// Create a block builder on top of the parent block.
-	fn build_block(&self, parent: &BlockId, timestamp: u64) -> Result<Self::BlockBuilder>;
+	fn build_block(&self, parent: &Self::CheckedBlockId, timestamp: u64) -> Result<Self::BlockBuilder>;
+}
+
+/// A checked block ID used for the substrate-client implementation of CheckedBlockId;
+#[derive(Debug, Clone, Copy)]
+pub struct CheckedId(BlockId);
+
+impl CheckedBlockId for CheckedId {
+	fn block_id(&self) -> &BlockId {
+		&self.0
+	}
 }
 
 // set up the necessary scaffolding to execute the runtime.
 macro_rules! with_runtime {
 	($client: ident, $at: expr, $exec: expr) => {{
-		// bail if the code is not the same as the natively linked.
-		if $client.code_at($at)? != LocalDispatch::native_equivalent() {
-			bail!(ErrorKind::UnknownRuntime);
-		}
-
-		$client.state_at($at).map_err(Error::from).and_then(|state| {
+		$client.state_at($at.block_id()).map_err(Error::from).and_then(|state| {
 			let mut changes = Default::default();
 			let mut ext = state_machine::Ext {
 				overlay: &mut changes,
@@ -141,33 +166,44 @@ macro_rules! with_runtime {
 impl<B: Backend> PolkadotApi for Client<B, NativeExecutor<LocalDispatch>>
 	where ::client::error::Error: From<<<B as Backend>::State as state_machine::backend::Backend>::Error>
 {
+	type CheckedBlockId = CheckedId;
 	type BlockBuilder = ClientBlockBuilder<B::State>;
 
-	fn session_keys(&self, at: &BlockId) -> Result<Vec<SessionKey>> {
+	fn check_id(&self, id: BlockId) -> Result<CheckedId> {
+		// bail if the code is not the same as the natively linked.
+		if self.code_at(&id)? != LocalDispatch::native_equivalent() {
+			bail!(ErrorKind::UnknownRuntime);
+		}
+
+		Ok(CheckedId(id))
+	}
+
+	fn session_keys(&self, at: &CheckedId) -> Result<Vec<SessionKey>> {
 		with_runtime!(self, at, ::runtime::consensus::authorities)
 	}
 
-	fn validators(&self, at: &BlockId) -> Result<Vec<AccountId>> {
+	fn validators(&self, at: &CheckedId) -> Result<Vec<AccountId>> {
 		with_runtime!(self, at, ::runtime::session::validators)
 	}
 
-	fn duty_roster(&self, at: &BlockId) -> Result<DutyRoster> {
+	fn duty_roster(&self, at: &CheckedId) -> Result<DutyRoster> {
 		with_runtime!(self, at, ::runtime::parachains::calculate_duty_roster)
 	}
 
-	fn timestamp(&self, at: &BlockId) -> Result<Timestamp> {
+	fn timestamp(&self, at: &CheckedId) -> Result<Timestamp> {
 		with_runtime!(self, at, ::runtime::timestamp::get)
 	}
 
-	fn evaluate_block(&self, at: &BlockId, block: Block) -> Result<()> {
+	fn evaluate_block(&self, at: &CheckedId, block: Block) -> Result<()> {
 		with_runtime!(self, at, || ::runtime::system::internal::execute_block(block))
 	}
 
-	fn build_block(&self, parent: &BlockId, timestamp: Timestamp) -> Result<Self::BlockBuilder> {
-		if self.code_at(parent)? != LocalDispatch::native_equivalent() {
-			bail!(ErrorKind::UnknownRuntime);
-		}
+	fn nonce(&self, at: &Self::CheckedBlockId, account: AccountId) -> Result<TxOrder> {
+		with_runtime!(self, at, || ::runtime::system::nonce(account))
+	}
 
+	fn build_block(&self, parent: &CheckedId, timestamp: Timestamp) -> Result<Self::BlockBuilder> {
+		let parent = parent.block_id();
 		let header = Header {
 			parent_hash: self.block_hash_from_id(parent)?.ok_or(ErrorKind::UnknownBlock(*parent))?,
 			number: self.block_number_from_id(parent)?.ok_or(ErrorKind::UnknownBlock(*parent))? + 1,
@@ -316,23 +352,24 @@ mod tests {
 	#[test]
 	fn gets_session_and_validator_keys() {
 		let client = client();
-		assert_eq!(client.session_keys(&BlockId::Number(0)).unwrap(), validators());
-		assert_eq!(client.validators(&BlockId::Number(0)).unwrap(), validators());
+		let id = client.check_id(BlockId::Number(0)).unwrap();
+		assert_eq!(client.session_keys(&id).unwrap(), validators());
+		assert_eq!(client.validators(&id).unwrap(), validators());
 	}
 
 	#[test]
 	fn build_block() {
 		let client = client();
 
-		let block_builder = client.build_block(&BlockId::Number(0), 1_000_000).unwrap();
+		let id = client.check_id(BlockId::Number(0)).unwrap();
+		let block_builder = client.build_block(&id, 1_000_000).unwrap();
 		let block = block_builder.bake();
 
 		assert_eq!(block.header.number, 1);
 	}
 
 	#[test]
-	fn cannot_build_block_on_unknown_parent() {
-		let client = client();
-		assert!(client.build_block(&BlockId::Number(100), 1_000_000).is_err());
+	fn fails_to_check_id_for_unknown_block() {
+		assert!(client().check_id(BlockId::Number(100)).is_err());
 	}
 }
diff --git a/substrate/polkadot/consensus/Cargo.toml b/substrate/polkadot/consensus/Cargo.toml
index 298d6478700eebae3808823df46b0559719d49bc..60c8009b7c9d5652afe89b0dfbe49341b0fe9746 100644
--- a/substrate/polkadot/consensus/Cargo.toml
+++ b/substrate/polkadot/consensus/Cargo.toml
@@ -13,6 +13,7 @@ polkadot-api = { path = "../api" }
 polkadot-collator = { path = "../collator" }
 polkadot-primitives = { path = "../primitives" }
 polkadot-statement-table = { path = "../statement-table" }
+polkadot-transaction-pool = { path = "../transaction-pool" }
 substrate-bft = { path = "../../substrate/bft" }
 substrate-codec = { path = "../../substrate/codec" }
 substrate-primitives = { path = "../../substrate/primitives" }
diff --git a/substrate/polkadot/consensus/src/error.rs b/substrate/polkadot/consensus/src/error.rs
index 648072ef0b7b38b98e0768004446ecde5920302c..4d1387d17e1d4e0a14e84c30a5df0fe10ded7355 100644
--- a/substrate/polkadot/consensus/src/error.rs
+++ b/substrate/polkadot/consensus/src/error.rs
@@ -41,6 +41,13 @@ error_chain! {
 			description("Proposal had wrong parent hash."),
 			display("Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got),
 		}
+		ProposalTooLarge(size: usize) {
+			description("Proposal exceeded the maximum size."),
+			display(
+				"Proposal exceeded the maximum size of {} by {} bytes.",
+				::MAX_TRANSACTIONS_SIZE, ::MAX_TRANSACTIONS_SIZE.saturating_sub(*size)
+			),
+		}
 	}
 }
 
diff --git a/substrate/polkadot/consensus/src/lib.rs b/substrate/polkadot/consensus/src/lib.rs
index ef00318209757d96bc67193337952f6f7f541e4b..7321948dd773432f2fe09d24c1f9577d5d685290 100644
--- a/substrate/polkadot/consensus/src/lib.rs
+++ b/substrate/polkadot/consensus/src/lib.rs
@@ -37,6 +37,7 @@ extern crate polkadot_api;
 extern crate polkadot_collator as collator;
 extern crate polkadot_statement_table as table;
 extern crate polkadot_primitives;
+extern crate polkadot_transaction_pool as transaction_pool;
 extern crate substrate_bft as bft;
 extern crate substrate_codec as codec;
 extern crate substrate_primitives as primitives;
@@ -56,6 +57,7 @@ use polkadot_primitives::block::Block as PolkadotBlock;
 use polkadot_primitives::parachain::{Id as ParaId, DutyRoster, BlockData, Extrinsic, CandidateReceipt};
 use primitives::block::{Block as SubstrateBlock, Header as SubstrateHeader, HeaderHash, Id as BlockId};
 use primitives::AuthorityId;
+use transaction_pool::TransactionPool;
 
 use futures::prelude::*;
 use futures::future;
@@ -65,6 +67,9 @@ pub use self::error::{ErrorKind, Error};
 
 mod error;
 
+// block size limit.
+const MAX_TRANSACTIONS_SIZE: usize = 4 * 1024 * 1024;
+
 /// A handle to a statement table router.
 pub trait TableRouter {
 	/// Errors when fetching data from the network.
@@ -455,6 +460,8 @@ fn make_group_info(roster: DutyRoster, authorities: &[AuthorityId]) -> Result<Ha
 pub struct ProposerFactory<C, N> {
 	/// The client instance.
 	pub client: Arc<C>,
+	/// The transaction pool.
+	pub transaction_pool: Arc<Mutex<TransactionPool>>,
 	/// The backing network handle.
 	pub network: N,
 }
@@ -465,7 +472,9 @@ impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N>
 
 	fn init(&self, parent_header: &SubstrateHeader, authorities: &[AuthorityId], sign_with: Arc<ed25519::Pair>) -> Result<Self::Proposer, Error> {
 		let parent_hash = parent_header.hash();
-		let duty_roster = self.client.duty_roster(&BlockId::Hash(parent_hash))?;
+
+		let checked_id = self.client.check_id(BlockId::Hash(parent_hash))?;
+		let duty_roster = self.client.duty_roster(&checked_id)?;
 
 		let group_info = make_group_info(duty_roster, authorities)?;
 		let table = Arc::new(SharedTable::new(group_info, sign_with, parent_hash));
@@ -474,9 +483,11 @@ impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N>
 		// TODO [PoC-2]: kick off collation process.
 		Ok(Proposer {
 			parent_hash,
+			parent_id: checked_id,
 			_table: table,
 			_router: router,
 			client: self.client.clone(),
+			transaction_pool: self.transaction_pool.clone(),
 		})
 	}
 }
@@ -490,9 +501,11 @@ fn current_timestamp() -> Timestamp {
 }
 
 /// The Polkadot proposer logic.
-pub struct Proposer<C, R> {
+pub struct Proposer<C: PolkadotApi, R> {
 	parent_hash: HeaderHash,
+	parent_id: C::CheckedBlockId,
 	client: Arc<C>,
+	transaction_pool: Arc<Mutex<TransactionPool>>,
 	_table: Arc<SharedTable>,
 	_router: R,
 }
@@ -503,14 +516,45 @@ impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
 	type Evaluate = Result<bool, Error>;
 
 	fn propose(&self) -> Result<SubstrateBlock, Error> {
+		use transaction_pool::Ready;
+
 		// TODO: handle case when current timestamp behind that in state.
-		let polkadot_block = self.client.build_block(
-			&BlockId::Hash(self.parent_hash),
+		let mut block_builder = self.client.build_block(
+			&self.parent_id,
 			current_timestamp()
-		)?.bake();
+		)?;
+
+		let readiness_evaluator = Ready::create(self.parent_id.clone(), &*self.client);
+
+		{
+			let mut pool = self.transaction_pool.lock();
+			let mut unqueue_invalid = Vec::new();
+			let mut pending_size = 0;
+			for pending in pool.pending(readiness_evaluator.clone()) {
+				// skip and cull transactions which are too large.
+				if pending.encoded_size() > MAX_TRANSACTIONS_SIZE {
+					unqueue_invalid.push(pending.hash().clone());
+					continue
+				}
 
-		// TODO: integrate transaction queue and `push_transaction`s.
+				if pending_size + pending.encoded_size() >= MAX_TRANSACTIONS_SIZE { break }
 
+				match block_builder.push_transaction(pending.as_transaction().clone()) {
+					Ok(()) => {
+						pending_size += pending.encoded_size();
+					}
+					Err(_) => {
+						unqueue_invalid.push(pending.hash().clone());
+					}
+				}
+			}
+
+			for tx_hash in unqueue_invalid {
+				pool.remove(&tx_hash, false);
+			}
+		}
+
+		let polkadot_block = block_builder.bake();
 		let substrate_block = Slicable::decode(&mut polkadot_block.encode().as_slice())
 			.expect("polkadot blocks defined to serialize to substrate blocks correctly; qed");
 
@@ -519,7 +563,7 @@ impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
 
 	// TODO: certain kinds of errors here should lead to a misbehavior report.
 	fn evaluate(&self, proposal: &SubstrateBlock) -> Result<bool, Error> {
-		evaluate_proposal(proposal, &*self.client, current_timestamp(), &self.parent_hash)
+		evaluate_proposal(proposal, &*self.client, current_timestamp(), &self.parent_hash, &self.parent_id)
 	}
 }
 
@@ -528,6 +572,7 @@ fn evaluate_proposal<C: PolkadotApi>(
 	client: &C,
 	now: Timestamp,
 	parent_hash: &HeaderHash,
+	parent_id: &C::CheckedBlockId,
 ) -> Result<bool, Error> {
 	const MAX_TIMESTAMP_DRIFT: Timestamp = 4;
 
@@ -535,6 +580,14 @@ fn evaluate_proposal<C: PolkadotApi>(
 	let proposal = PolkadotBlock::decode(&mut &encoded[..])
 		.ok_or_else(|| ErrorKind::ProposalNotForPolkadot)?;
 
+	let transactions_size = proposal.body.transactions.iter().fold(0, |a, tx| {
+		a + Slicable::encode(tx).len()
+	});
+
+	if transactions_size > MAX_TRANSACTIONS_SIZE {
+		bail!(ErrorKind::ProposalTooLarge(transactions_size))
+	}
+
 	if proposal.header.parent_hash != *parent_hash {
 		bail!(ErrorKind::WrongParentHash(*parent_hash, proposal.header.parent_hash));
 	}
@@ -551,6 +604,6 @@ fn evaluate_proposal<C: PolkadotApi>(
 	}
 
 	// execute the block.
-	client.evaluate_block(&BlockId::Hash(*parent_hash), proposal)?;
+	client.evaluate_block(parent_id, proposal)?;
 	Ok(true)
 }
diff --git a/substrate/polkadot/primitives/src/transaction.rs b/substrate/polkadot/primitives/src/transaction.rs
index d0b5ab9557f4f7101b7bb39b9a469299e8bf9412..3d4095b86c8d7661f84985958504a957a5134a31 100644
--- a/substrate/polkadot/primitives/src/transaction.rs
+++ b/substrate/polkadot/primitives/src/transaction.rs
@@ -237,7 +237,10 @@ impl Function {
 	///
 	/// Transactions containing inherent functions should not be signed.
 	pub fn is_inherent(&self) -> bool {
-		self.inherent_index().is_some()
+		match *self {
+			Function::Inherent(_) => true,
+			_ => false,
+		}
 	}
 
 	/// If this function is inherent, returns the index it should occupy
@@ -370,6 +373,11 @@ impl UncheckedTransaction {
 		}
 	}
 
+	/// Whether this transaction invokes an inherent function.
+	pub fn is_inherent(&self) -> bool {
+		self.transaction.function.is_inherent()
+	}
+
 	/// Create a new inherent-style transaction from the given function.
 	pub fn inherent(function: InherentFunction) -> Self {
 		UncheckedTransaction {
diff --git a/substrate/polkadot/runtime/src/api.rs b/substrate/polkadot/runtime/src/api.rs
index b8371a5da8531a2207f6e746b4c5efd094eb84e6..7ce51381e9d78f56d7d1169ddf57b1eafc6159af 100644
--- a/substrate/polkadot/runtime/src/api.rs
+++ b/substrate/polkadot/runtime/src/api.rs
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use runtime::{system, parachains, consensus, session, timestamp};
+use runtime::{system, parachains, consensus, session};
 
 impl_stubs!(
 	execute_block => |block| system::internal::execute_block(block),
@@ -24,5 +24,6 @@ impl_stubs!(
 	validators => |()| session::validators(),
 	authorities => |()| consensus::authorities(),
 	duty_roster => |()| parachains::calculate_duty_roster(),
-	get_timestamp => |()| timestamp::get()
+	timestamp => |()| ::runtime::timestamp::get(),
+	nonce => |account_id| system::nonce(account_id)
 );
diff --git a/substrate/polkadot/runtime/src/lib.rs b/substrate/polkadot/runtime/src/lib.rs
index 4059a16551632ca04d7f498a1a7051612ee972d2..16379cac8e41188e7d0cb1ab49d05fc1ea9e8552 100644
--- a/substrate/polkadot/runtime/src/lib.rs
+++ b/substrate/polkadot/runtime/src/lib.rs
@@ -31,9 +31,9 @@ extern crate polkadot_primitives;
 
 #[cfg(test)] #[macro_use] extern crate hex_literal;
 
+pub mod api;
 pub mod environment;
 pub mod runtime;
-pub mod api;
 
 #[cfg(feature = "std")] pub mod genesismap;
 
diff --git a/substrate/polkadot/runtime/src/runtime/system.rs b/substrate/polkadot/runtime/src/runtime/system.rs
index b9d28cf18e5ff13fdfa3d16ad6d9d76561b31ce7..aa6cfc45ce7120ac6389137eef15df5edf3932fd 100644
--- a/substrate/polkadot/runtime/src/runtime/system.rs
+++ b/substrate/polkadot/runtime/src/runtime/system.rs
@@ -17,19 +17,26 @@
 //! System manager: Handles all of the top-level stuff; executing block/transaction, setting code
 //! and depositing logs.
 
-use rstd::prelude::*;
 use rstd::mem;
-use runtime_io::{print, storage_root, enumerated_trie_root};
+use rstd::prelude::*;
+
 use codec::{KeyedVec, Slicable};
-use runtime_support::{Hashable, storage};
 use environment::with_env;
-use polkadot_primitives::{AccountId, Hash, TxOrder, BlockNumber, Block, Header,
-	UncheckedTransaction, Function, InherentFunction, Log};
+use polkadot_primitives::{
+	AccountId, Hash, TxOrder, BlockNumber, Block, Header,
+	UncheckedTransaction, Function, InherentFunction, Log
+};
+
+use runtime_io::{print, storage_root, enumerated_trie_root};
+use runtime_support::{Hashable, storage};
 use runtime::{staking, session};
 
-const NONCE_OF: &[u8] = b"sys:non:";
-const BLOCK_HASH_AT: &[u8] = b"sys:old:";
-const TEMP_TRANSACTION_NUMBER: &[u8] = b"temp:txcount:";
+/// Prefixes account ID and stores u64 nonce.
+pub const NONCE_OF: &[u8] = b"sys:non:";
+/// Prefixes block number and stores hash of that block.
+pub const BLOCK_HASH_AT: &[u8] = b"sys:old:";
+/// Stores the temporary current transaction number.
+pub const TEMP_TRANSACTION_NUMBER: &[u8] = b"temp:txcount";
 
 /// The current block number being processed. Set by `execute_block`.
 pub fn block_number() -> BlockNumber {
@@ -53,8 +60,6 @@ pub mod privileged {
 pub mod internal {
 	use super::*;
 
-	struct CheckedTransaction(UncheckedTransaction);
-
 	/// Deposits a log and ensures it matches the blocks log data.
 	pub fn deposit_log(log: Log) {
 		with_env(|e| e.digest.logs.push(log));
@@ -141,6 +146,12 @@ pub mod internal {
 	}
 }
 
+/// Get an account's current nonce.
+pub fn nonce(account: AccountId) -> TxOrder {
+	let nonce_key = account.to_keyed_vec(NONCE_OF);
+	storage::get_or(&nonce_key, 0)
+}
+
 /// Dispatch a function.
 fn dispatch_function(function: &Function, transactor: &AccountId) {
 	match *function {
diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm
index 89ed90c99d157f4a0c948badd83877df0da103b8..1a7785d62623f53de0c64cb75a2aff30a273585f 100644
Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm differ
diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm
index 3ca31b5a116ebe29af9c12b951b1df74e97bbd28..7528a02d42f7c13ae4826476215bacb482f7c9c3 100644
Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm differ
diff --git a/substrate/polkadot/transaction-pool/Cargo.toml b/substrate/polkadot/transaction-pool/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..51271feece3b0105c7f5a59025ef2485b5a83774
--- /dev/null
+++ b/substrate/polkadot/transaction-pool/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "polkadot-transaction-pool"
+version = "0.1.0"
+authors = ["Parity Technologies <admin@parity.io>"]
+
+[dependencies]
+transaction-pool = "1.9.0"
+error-chain = "0.11"
+polkadot-api = { path = "../api" }
+polkadot-primitives = { path = "../primitives" }
+substrate-primitives = { path = "../../substrate/primitives" }
+substrate-codec = { path = "../../substrate/codec" }
+ed25519 = { path = "../../substrate/ed25519" }
+ethereum-types = "0.2"
diff --git a/substrate/polkadot/transaction-pool/src/lib.rs b/substrate/polkadot/transaction-pool/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4ab327bd18ade62401f35fbd5a895fb0b0247f47
--- /dev/null
+++ b/substrate/polkadot/transaction-pool/src/lib.rs
@@ -0,0 +1,298 @@
+// Copyright 2017 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/>.
+
+extern crate transaction_pool;
+extern crate polkadot_api;
+extern crate polkadot_primitives as primitives;
+extern crate substrate_primitives as substrate_primitives;
+extern crate substrate_codec as codec;
+extern crate ed25519;
+extern crate ethereum_types;
+
+#[macro_use]
+extern crate error_chain;
+
+use std::collections::HashMap;
+use std::cmp::Ordering;
+use std::sync::Arc;
+
+use polkadot_api::PolkadotApi;
+use primitives::AccountId;
+use primitives::transaction::UncheckedTransaction;
+use transaction_pool::{Pool, Readiness};
+use transaction_pool::scoring::{Change, Choice};
+
+// TODO: make queue generic over hash and sender so we don't need ethereum-types
+pub use ethereum_types::{Address as TruncatedAccountId, H256 as TransactionHash};
+pub use transaction_pool::{Options, Status, LightStatus, NoopListener, VerifiedTransaction as VerifiedTransactionOps};
+
+/// Truncate an account ID to 160 bits.
+pub fn truncate_id(id: &AccountId) -> TruncatedAccountId {
+	TruncatedAccountId::from_slice(&id[..20])
+}
+
+/// Iterator over pending transactions.
+pub type PendingIterator<'a, C> =
+	transaction_pool::PendingIterator<'a, VerifiedTransaction, Ready<'a, C>, Scoring, NoopListener>;
+
+error_chain! {
+	errors {
+		/// Attempted to queue an inherent transaction.
+		IsInherent(tx: UncheckedTransaction) {
+			description("Inherent transactions cannot be queued."),
+			display("Inehrent transactions cannot be queued."),
+		}
+		/// Attempted to queue a transaction with bad signature.
+		BadSignature(tx: UncheckedTransaction) {
+			description("Transaction had bad signature."),
+			display("Transaction had bad signature."),
+		}
+		/// Import error.
+		Import(err: Box<::std::error::Error + Send>) {
+			description("Error importing transaction"),
+			display("Error importing transaction: {}", err.description()),
+		}
+	}
+}
+
+/// A verified transaction which should be includable and non-inherent.
+#[derive(Debug, Clone)]
+pub struct VerifiedTransaction {
+	inner: UncheckedTransaction,
+	hash: TransactionHash,
+	address: TruncatedAccountId,
+	insertion_id: u64,
+	encoded_size: usize,
+}
+
+impl VerifiedTransaction {
+	/// Attempt to verify a transaction.
+	fn create(tx: UncheckedTransaction, insertion_id: u64) -> Result<Self> {
+		if tx.is_inherent() {
+			bail!(ErrorKind::IsInherent(tx))
+		}
+
+		let message = codec::Slicable::encode(&tx);
+		if ed25519::verify(&*tx.signature, &message, &tx.transaction.signed[..]) {
+			// TODO: make transaction-pool use generic types.
+			let hash = substrate_primitives::hashing::blake2_256(&message);
+			let address = truncate_id(&tx.transaction.signed);
+			Ok(VerifiedTransaction {
+				inner: tx,
+				hash: hash.into(),
+				encoded_size: message.len(),
+				address,
+				insertion_id,
+			})
+		} else {
+			Err(ErrorKind::BadSignature(tx).into())
+		}
+	}
+
+	/// Access the underlying transaction.
+	pub fn as_transaction(&self) -> &UncheckedTransaction {
+		self.as_ref()
+	}
+
+	/// Consume the verified transaciton, yielding the unchecked counterpart.
+	pub fn into_inner(self) -> UncheckedTransaction {
+		self.inner
+	}
+
+	/// Get the 256-bit hash of this transaction.
+	pub fn hash(&self) -> &TransactionHash {
+		&self.hash
+	}
+
+	/// Get the truncated account ID of the sender of this transaction.
+	pub fn sender(&self) -> &TruncatedAccountId {
+		&self.address
+	}
+
+	/// Get encoded size of the transaction.
+	pub fn encoded_size(&self) -> usize {
+		self.encoded_size
+	}
+}
+
+impl AsRef<UncheckedTransaction> for VerifiedTransaction {
+	fn as_ref(&self) -> &UncheckedTransaction {
+		&self.inner
+	}
+}
+
+impl transaction_pool::VerifiedTransaction for VerifiedTransaction {
+	fn hash(&self) -> &TransactionHash {
+		&self.hash
+	}
+
+	fn sender(&self) -> &TruncatedAccountId {
+		&self.address
+	}
+
+	fn mem_usage(&self) -> usize {
+		1 // TODO
+	}
+
+	fn insertion_id(&self) -> u64 {
+		self.insertion_id
+	}
+}
+
+/// Scoring implementation for polkadot transactions.
+pub struct Scoring;
+
+impl transaction_pool::Scoring<VerifiedTransaction> for Scoring {
+	type Score = u64;
+
+	fn compare(&self, old: &VerifiedTransaction, other: &VerifiedTransaction) -> Ordering {
+		old.inner.transaction.nonce.cmp(&other.inner.transaction.nonce)
+	}
+
+	fn choose(&self, _old: &VerifiedTransaction, _new: &VerifiedTransaction) -> Choice {
+		Choice::InsertNew
+	}
+
+	fn update_scores(
+		&self,
+		txs: &[Arc<VerifiedTransaction>],
+		scores: &mut [Self::Score],
+		_change: Change
+	) {
+		for i in 0..txs.len() {
+			// all the same score since there are no fees.
+			// TODO: prioritize things like misbehavior or fishermen reports
+			scores[i] = 1;
+		}
+	}
+	fn should_replace(&self, _old: &VerifiedTransaction, _new: &VerifiedTransaction) -> bool {
+		false // no fees to determine which is better.
+	}
+}
+
+/// Readiness evaluator for polkadot transactions.
+pub struct Ready<'a, T: 'a + PolkadotApi> {
+	at_block: T::CheckedBlockId,
+	api_handle: &'a T,
+	known_nonces: HashMap<AccountId, ::primitives::TxOrder>,
+}
+
+impl<'a, T: 'a + PolkadotApi> Clone for Ready<'a, T> {
+	fn clone(&self) -> Self {
+		Ready {
+			at_block: self.at_block.clone(),
+			api_handle: self.api_handle,
+			known_nonces: self.known_nonces.clone(),
+		}
+	}
+}
+
+impl<'a, T: 'a + PolkadotApi> Ready<'a, T> {
+	/// Create a new readiness evaluator at the given block. Requires that
+	/// the ID has already been checked for local corresponding and available state.
+	pub fn create(at: T::CheckedBlockId, client: &'a T) -> Self {
+		Ready {
+			at_block: at,
+			api_handle: client,
+			known_nonces: HashMap::new(),
+		}
+	}
+}
+
+impl<'a, T: 'a + PolkadotApi> transaction_pool::Ready<VerifiedTransaction> for Ready<'a, T> {
+	fn is_ready(&mut self, tx: &VerifiedTransaction) -> Readiness {
+		let sender = tx.inner.transaction.signed;
+
+		// TODO: find a way to handle nonce error properly -- will need changes to
+		// transaction-pool trait.
+		let (api_handle, at_block) = (&self.api_handle, &self.at_block);
+		let next_nonce = self.known_nonces.entry(sender)
+			.or_insert_with(|| api_handle.nonce(at_block, sender).ok().unwrap_or_else(u64::max_value));
+
+		*next_nonce += 1;
+
+		match tx.inner.transaction.nonce.cmp(&next_nonce) {
+			Ordering::Greater => Readiness::Future,
+			Ordering::Equal => Readiness::Ready,
+			Ordering::Less => Readiness::Stalled,
+		}
+	}
+}
+
+/// The polkadot transaction pool.
+///
+/// Wraps a `transaction-pool::Pool`.
+pub struct TransactionPool {
+	inner: transaction_pool::Pool<VerifiedTransaction, Scoring>,
+	insertion_index: u64, // TODO: use AtomicU64 when it stabilizes
+}
+
+impl TransactionPool {
+	/// Create a new transaction pool.
+	pub fn new(options: Options) -> Self {
+		TransactionPool {
+			inner: Pool::new(NoopListener, Scoring, options),
+			insertion_index: 0,
+		}
+	}
+
+	/// Verify and import a transaction into the pool.
+	pub fn import(&mut self, tx: UncheckedTransaction) -> Result<Arc<VerifiedTransaction>> {
+		let insertion_index = self.insertion_index;
+		self.insertion_index += 1;
+
+		let verified = VerifiedTransaction::create(tx, insertion_index)?;
+
+		// TODO: just use a foreign link when the error type is made public.
+		self.inner.import(verified)
+			.map_err(|e| ErrorKind::Import(Box::new(e)))
+			.map_err(Into::into)
+	}
+
+	/// Clear the pool.
+	pub fn clear(&mut self) {
+		self.inner.clear();
+	}
+
+	/// Remove from the pool.
+	pub fn remove(&mut self, hash: &TransactionHash, is_valid: bool) -> Option<Arc<VerifiedTransaction>> {
+		self.inner.remove(hash, is_valid)
+	}
+
+	/// Cull transactions from the queue.
+	pub fn cull<T: PolkadotApi>(&mut self, senders: Option<&[TruncatedAccountId]>, ready: Ready<T>) -> usize {
+		self.inner.cull(senders, ready)
+	}
+
+	/// Get an iterator of pending transactions.
+	pub fn pending<'a, T: 'a + PolkadotApi>(&'a self, ready: Ready<'a, T>) -> PendingIterator<'a, T> {
+		self.inner.pending(ready)
+	}
+
+	/// Get the full status of the queue (including readiness)
+	pub fn status<T: PolkadotApi>(&self, ready: Ready<T>) -> Status {
+		self.inner.status(ready)
+	}
+
+	/// Returns light status of the pool.
+	pub fn light_status(&self) -> LightStatus {
+		self.inner.light_status()
+	}
+}
+
+#[cfg(test)]
+mod tests {
+}
diff --git a/substrate/substrate/codec/src/slicable.rs b/substrate/substrate/codec/src/slicable.rs
index 74b165ec4ccee6761fb1a690634cdfe515e221dc..0304b51003765d70956b17b323b61d692e086b78 100644
--- a/substrate/substrate/codec/src/slicable.rs
+++ b/substrate/substrate/codec/src/slicable.rs
@@ -118,7 +118,7 @@ impl Slicable for Vec<u64> {
 		u32::decode(input).and_then(move |len| {
 			let len = len as usize;
 			let mut vec = Vec::with_capacity(len);
-			for i in 0..len {
+			for _ in 0..len {
 				vec.push(u64::decode(input)?);
 			}
 			Some(vec)
diff --git a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm
index c9ad192e0171feeb0fcf555593cc787f68dcd8b2..fc34a3fd55082e7011646e99b1fc54c7d4fda632 100644
Binary files a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ
diff --git a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm
index f9ce2b147d7e4ee8a5df653cadaabf98235f751a..c27b24b0c21ae7094dd821cf5309d28a5a547c52 100644
Binary files a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm and b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm differ