From 188332cc4b86b337be8b752881a392324ed67bba Mon Sep 17 00:00:00 2001
From: Robert Habermeier <rphmeier@gmail.com>
Date: Thu, 1 Feb 2018 11:13:55 +0100
Subject: [PATCH] extract out all primitives

---
 substrate/primitives/src/block.rs             | 25 +++++-
 substrate/primitives/src/hashing.rs           |  8 +-
 substrate/primitives/src/hexdisplay.rs        |  2 +-
 substrate/primitives/src/lib.rs               | 41 +++++++--
 substrate/primitives/src/parachain.rs         |  4 +-
 substrate/primitives/src/proposal.rs          | 89 +++++++++++++++++++
 substrate/primitives/src/runtime_function.rs  | 54 +++++++++++
 substrate/primitives/src/transaction.rs       | 61 +++++++++++++
 substrate/primitives/src/validator.rs         | 20 -----
 substrate/runtime-std/Cargo.toml              |  4 +-
 substrate/runtime-std/src/lib.rs              | 48 +++++++++-
 substrate/runtime-std/with_std.rs             | 14 +--
 substrate/runtime-std/without_std.rs          |  2 +
 .../polkadot/src/primitives/digest.rs         |  2 +-
 .../polkadot/src/primitives/proposal.rs       | 32 -------
 .../polkadot/src/runtime/governance.rs        | 30 +++++++
 .../polkadot/src/runtime/system.rs            | 37 +++++++-
 17 files changed, 386 insertions(+), 87 deletions(-)
 create mode 100644 substrate/primitives/src/proposal.rs
 create mode 100644 substrate/primitives/src/runtime_function.rs
 create mode 100644 substrate/primitives/src/transaction.rs

diff --git a/substrate/primitives/src/block.rs b/substrate/primitives/src/block.rs
index eb2c7785c26..26639d7d2e3 100644
--- a/substrate/primitives/src/block.rs
+++ b/substrate/primitives/src/block.rs
@@ -16,9 +16,10 @@
 
 //! Block and header type definitions.
 
-use bytes;
+use bytes::{self, Vec};
 use hash::H256;
 use parachain;
+use transaction::UncheckedTransaction;
 
 /// Used to refer to a block number.
 pub type Number = u64;
@@ -33,6 +34,22 @@ pub type TransactionHash = H256;
 #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
 pub struct Log(#[serde(with="bytes")] pub Vec<u8>);
 
+/// A Polkadot relay chain block.
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+pub struct Block {
+	/// The block header.
+	pub header: Header,
+	/// All relay-chain transactions.
+	pub transactions: Vec<UncheckedTransaction>,
+}
+
+/// The digest of a block, useful for light-clients.
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Digest {
+	/// All logs that have happened in the block.
+	pub logs: Vec<Log>,
+}
+
 /// A relay chain block header.
 ///
 /// https://github.com/w3f/polkadot-spec/blob/master/spec.md#header
@@ -46,10 +63,12 @@ pub struct Header {
 	pub number: Number,
 	/// State root after this transition.
 	pub state_root: H256,
+	/// The root of the trie that represents this block's transactions, indexed by a 32-byte integer.
+	pub transaction_root: H256,
 	/// Parachain activity bitfield
 	pub parachain_activity: parachain::Activity,
-	/// Logs (generated by execution)
-	pub logs: Vec<Log>,
+	/// The digest of activity on the block.
+	pub digest: Digest,
 }
 
 /// A relay chain block body.
diff --git a/substrate/primitives/src/hashing.rs b/substrate/primitives/src/hashing.rs
index e1a4f84a996..8534cf4d98f 100644
--- a/substrate/primitives/src/hashing.rs
+++ b/substrate/primitives/src/hashing.rs
@@ -57,7 +57,7 @@ pub fn blake2_128(data: &[u8]) -> [u8; 16] {
 
 /// Do a XX 128-bit hash and place result in `dest`.
 pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) {
-	use ::std::hash::Hasher;
+	use ::core::hash::Hasher;
 	let mut h0 = twox_hash::XxHash::with_seed(0);
 	let mut h1 = twox_hash::XxHash::with_seed(1);
 	h0.write(data);
@@ -71,14 +71,14 @@ pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) {
 
 /// Do a XX 128-bit hash and return result.
 pub fn twox_128(data: &[u8]) -> [u8; 16] {
-	let mut r: [u8; 16] = unsafe { ::std::mem::uninitialized() };
+	let mut r: [u8; 16] = [0; 16];
 	twox_128_into(data, &mut r);
 	r
 }
 
 /// Do a XX 256-bit hash and place result in `dest`.
 pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) {
-	use ::std::hash::Hasher;
+	use ::core::hash::Hasher;
 	use byteorder::{ByteOrder, LittleEndian};
 	let mut h0 = twox_hash::XxHash::with_seed(0);
 	let mut h1 = twox_hash::XxHash::with_seed(1);
@@ -100,7 +100,7 @@ pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) {
 
 /// Do a XX 256-bit hash and return result.
 pub fn twox_256(data: &[u8]) -> [u8; 32] {
-	let mut r: [u8; 32] = unsafe { ::std::mem::uninitialized() };
+	let mut r: [u8; 32] = [0; 32];
 	twox_256_into(data, &mut r);
 	r
 }
diff --git a/substrate/primitives/src/hexdisplay.rs b/substrate/primitives/src/hexdisplay.rs
index 2e8bd3d15b1..42db2212870 100644
--- a/substrate/primitives/src/hexdisplay.rs
+++ b/substrate/primitives/src/hexdisplay.rs
@@ -25,7 +25,7 @@ impl<'a> HexDisplay<'a> {
 }
 
 impl<'a> ::core::fmt::Display for HexDisplay<'a> {
-	fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
+	fn fmt(&self, fmtr: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
 		for byte in self.0 {
 			try!( fmtr.write_fmt(format_args!("{:02x}", byte)));
 		}
diff --git a/substrate/primitives/src/lib.rs b/substrate/primitives/src/lib.rs
index c69554b8a75..00ceee2d548 100644
--- a/substrate/primitives/src/lib.rs
+++ b/substrate/primitives/src/lib.rs
@@ -53,23 +53,48 @@ extern crate alloc;
 mod bytes;
 pub mod block;
 pub mod contract;
+pub mod ed25519;
 pub mod hash;
+pub mod hashing;
+pub mod hexdisplay;
 pub mod parachain;
+pub mod proposal;
+pub mod runtime_function;
+pub mod transaction;
 pub mod uint;
 pub mod validator;
-pub mod ed25519;
-pub mod hexdisplay;
-pub mod hashing;
-
-/// Alias to 160-bit hash when used in the context of an account address.
-pub type Address = hash::H160;
-/// Alias to 520-bit hash when used in the context of a signature.
-pub type Signature = hash::H512;
 
 pub use self::hash::{H160, H256};
 pub use self::uint::{U256, U512};
 pub use hashing::{blake2_256, twox_128, twox_256};
 
+/// Virtual account ID that represents the idea of a dispatch/statement being signed by everybody
+/// (who matters). Essentially this means that a majority of validators have decided it is
+/// "correct".
+pub const EVERYBODY: AccountId = [255u8; 32];
+
+/// Alias to Ed25519 pubkey that identifies an account.
+pub type AccountId = [u8; 32];
+
+/// The Ed25519 pub key of an session that belongs to an authority. This is used as what the
+/// external environment/consensus algorithm calls an "authority".
+pub type SessionKey = AccountId;
+
+/// Indentifier for a chain.
+pub type ChainID = u64;
+
+/// Index of a block in the chain.
+pub type BlockNumber = u64;
+
+/// Index of a transaction.
+pub type TxOrder = u64;
+
+/// A hash of some data.
+pub type Hash = [u8; 32];
+
+/// Alias to 520-bit hash when used in the context of a signature.
+pub type Signature = hash::H512;
+
 /// A hash function.
 pub fn hash(data: &[u8]) -> hash::H256 {
 	blake2_256(data).into()
diff --git a/substrate/primitives/src/parachain.rs b/substrate/primitives/src/parachain.rs
index d2f6e765e5d..360b7bacdda 100644
--- a/substrate/primitives/src/parachain.rs
+++ b/substrate/primitives/src/parachain.rs
@@ -57,11 +57,11 @@ pub struct CandidateReceipt {
 	/// The ID of the parachain this is a candidate for.
 	pub parachain_index: Id,
 	/// The collator's account ID
-	pub collator: ::Address,
+	pub collator: ::AccountId,
 	/// The head-data
 	pub head_data: HeadData,
 	/// Balance uploads to the relay chain.
-	pub balance_uploads: Vec<(::Address, ::uint::U256)>,
+	pub balance_uploads: Vec<(::AccountId, ::uint::U256)>,
 	/// Egress queue roots.
 	pub egress_queue_roots: Vec<(Id, ::hash::H256)>,
 	/// Fees paid from the chain to the relay chain validators
diff --git a/substrate/primitives/src/proposal.rs b/substrate/primitives/src/proposal.rs
new file mode 100644
index 00000000000..f8f39c815bc
--- /dev/null
+++ b/substrate/primitives/src/proposal.rs
@@ -0,0 +1,89 @@
+// 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/>.
+
+//! Proposals for relay-chain governance.
+//!
+//! This describes a combination of a function ID and data that can be used to call into
+//! an internal function.
+
+use bytes;
+
+/// Internal functions that can be dispatched to.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
+#[repr(u8)]
+pub enum InternalFunction {
+	/// Set the system's code.
+	SystemSetCode = 0,
+	/// Set the number of sessions per era.
+	StakingSetSessionsPerEra = 1,
+	/// Set the minimum bonding duration for staking.
+	StakingSetBondingDuration = 2,
+	/// Set the validator count for staking.
+	StakingSetValidatorCount = 3,
+	/// Set the per-mille of validator approval required for governance changes.
+	GovernanceSetApprovalPpmRequired = 4,
+	/// Set the session length.
+	SessionSetLength = 5,
+}
+
+impl InternalFunction {
+	/// Derive `Some` value from a `u8`, or `None` if it's invalid.
+	pub fn from_u8(value: u8) -> Option<InternalFunction> {
+		use self::*;
+		let functions = [
+			InternalFunction::SystemSetCode,
+			InternalFunction::StakingSetSessionsPerEra,
+			InternalFunction::StakingSetBondingDuration,
+			InternalFunction::StakingSetValidatorCount,
+			InternalFunction::GovernanceSetApprovalPpmRequired,
+			InternalFunction::SessionSetLength
+		];
+		if (value as usize) < functions.len() {
+			Some(functions[value as usize])
+		} else {
+			None
+		}
+	}
+}
+
+/// An internal function.
+#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Proposal {
+	/// The privileged function to call.
+	pub function: InternalFunction,
+	/// The serialised data to call it with.
+	#[serde(with = "bytes")]
+	pub input_data: Vec<u8>,
+}
+
+#[cfg(test)]
+mod test {
+	use super::*;
+	use support::StaticHexInto;
+
+	#[test]
+	fn slicing_should_work() {
+		let p = Proposal {
+			function: InternalFunction::SystemSetCode,
+			input_data: b"Hello world".to_vec(),
+		};
+		let v = p.to_vec();
+		assert_eq!(v, "000b00000048656c6c6f20776f726c64".convert::<Vec<u8>>());
+
+		let o = Proposal::from_slice(&v).unwrap();
+		assert_eq!(p, o);
+	}
+}
diff --git a/substrate/primitives/src/runtime_function.rs b/substrate/primitives/src/runtime_function.rs
new file mode 100644
index 00000000000..0104447f022
--- /dev/null
+++ b/substrate/primitives/src/runtime_function.rs
@@ -0,0 +1,54 @@
+// 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/>.
+
+//! Polkadot runtime functions.
+//! This describes a function that can be called from an external transaction.
+
+/// Public functions that can be dispatched to.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
+#[repr(u8)]
+pub enum Function {
+	/// Staking subsystem: begin staking.
+	StakingStake = 0,
+	/// Staking subsystem: stop staking.
+	StakingUnstake = 1,
+	/// Staking subsystem: transfer stake.
+	StakingTransfer = 2,
+	/// Set temporary session key as a validator.
+	SessionSetKey = 3,
+	/// Set the timestamp.
+	TimestampSet = 4,
+	/// Make a proposal for the governance system.
+	GovernancePropose = 5,
+	/// Approve a proposal for the governance system.
+	GovernanceApprove = 6,
+}
+
+impl Function {
+	/// Derive `Some` value from a `u8`, or `None` if it's invalid.
+	pub fn from_u8(value: u8) -> Option<Function> {
+		match value {
+			0 => Some(Function::StakingStake),
+			1 => Some(Function::StakingUnstake),
+			2 => Some(Function::StakingTransfer),
+			3 => Some(Function::SessionSetKey),
+			4 => Some(Function::TimestampSet),
+			5 => Some(Function::GovernancePropose),
+			6 => Some(Function::GovernanceApprove),
+			_ => None,
+		}
+	}
+}
diff --git a/substrate/primitives/src/transaction.rs b/substrate/primitives/src/transaction.rs
new file mode 100644
index 00000000000..eb3e823c582
--- /dev/null
+++ b/substrate/primitives/src/transaction.rs
@@ -0,0 +1,61 @@
+// 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/>.
+
+//! Transaction type.
+
+use bytes::{self, Vec};
+use runtime_function::Function;
+
+#[cfg(feature = "std")]
+use std::fmt;
+
+#[cfg(not(feature = "std"))]
+use alloc::fmt;
+
+/// A vetted and verified transaction from the external world.
+#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
+pub struct Transaction {
+	/// Who signed it (note this is not a signature).
+	pub signed: ::AccountId,
+	/// The number of transactions have come before from the same signer.
+	pub nonce: ::TxOrder,
+	/// The function that should be called.
+	pub function: Function,
+	/// Serialised input data to the function.
+	#[serde(with = "bytes")]
+	pub input_data: Vec<u8>,
+}
+
+/// A transactions right from the external world. Unchecked.
+#[derive(Eq, Clone, Serialize, Deserialize)]
+pub struct UncheckedTransaction {
+	/// The actual transaction information.
+	pub transaction: Transaction,
+	/// The signature; should be an Ed25519 signature applied to the serialised `transaction` field.
+	pub signature: ::Signature,
+}
+
+impl PartialEq for UncheckedTransaction {
+	fn eq(&self, other: &Self) -> bool {
+		self.signature.iter().eq(other.signature.iter()) && self.transaction == other.transaction
+	}
+}
+
+impl fmt::Debug for UncheckedTransaction {
+	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+		write!(f, "UncheckedTransaction({:?})", self.transaction)
+	}
+}
diff --git a/substrate/primitives/src/validator.rs b/substrate/primitives/src/validator.rs
index 6e8a7dc6e84..4f7d60b7217 100644
--- a/substrate/primitives/src/validator.rs
+++ b/substrate/primitives/src/validator.rs
@@ -44,26 +44,6 @@ pub struct ValidationResult {
 	pub balance_uploads: Vec<BalanceUpload>,
 }
 
-// TODO [ToDr] This shouldn't be here!
-/// Validator logic.
-pub trait Validator {
-	/// Validation error.
-	type Error: ::std::error::Error;
-
-	/// Validates if the provided proof holds given a current ingress queue.
-	///
-	/// In case of success produces egress posts.
-	fn validate(
-		&self,
-		code: &[u8],
-		// TODO [ToDr] actually consolidate
-		consolidated_ingress: &[(u64, Vec<parachain::Message>)],
-		balance_downloads: &[BalanceDownload],
-		block_data: &parachain::BlockData,
-		previous_head_data: &parachain::HeadData,
-	) -> Result<ValidationResult, Self::Error>;
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
diff --git a/substrate/runtime-std/Cargo.toml b/substrate/runtime-std/Cargo.toml
index 8a672e93a46..c3f0eaf5088 100644
--- a/substrate/runtime-std/Cargo.toml
+++ b/substrate/runtime-std/Cargo.toml
@@ -12,11 +12,11 @@ pwasm-alloc = { path = "../wasm-runtime/pwasm-alloc", version = "0.1" }
 pwasm-libc = { path = "../wasm-runtime/pwasm-libc", version = "0.1" }
 environmental = { path = "../environmental", version = "0.1", optional = true }
 polkadot-state-machine = { path = "../state-machine", version = "0.1", optional = true }
-polkadot-primitives = { path = "../primitives", version = "0.1", optional = true }
+polkadot-primitives = { path = "../primitives", version = "0.1", default_features = false }
 triehash = { version = "0.1", optional = true }
 
 [features]
 default = ["std"]
-std = ["environmental", "polkadot-state-machine", "polkadot-primitives", "triehash"]
+std = ["environmental", "polkadot-state-machine", "triehash", "polkadot-primitives/std"]
 nightly = []
 strict = []
diff --git a/substrate/runtime-std/src/lib.rs b/substrate/runtime-std/src/lib.rs
index ab3bbe95809..c789de3aea2 100644
--- a/substrate/runtime-std/src/lib.rs
+++ b/substrate/runtime-std/src/lib.rs
@@ -28,8 +28,6 @@ include!("../with_std.rs");
 #[cfg(not(feature = "std"))]
 include!("../without_std.rs");
 
-
-
 /// Prelude of common useful imports.
 ///
 /// This should include only things which are in the normal std prelude.
@@ -37,3 +35,49 @@ pub mod prelude {
 	pub use ::vec::Vec;
 	pub use ::boxed::Box;
 }
+
+/// Type definitions and helpers for transactions.
+pub mod transaction {
+	pub use primitives::transaction::{Transaction, UncheckedTransaction};
+
+	#[cfg(feature = "std")]
+	use std::ops;
+
+	#[cfg(not(feature = "std"))]
+	use core::ops;
+
+	/// A type-safe indicator that a transaction has been checked.
+	#[derive(Debug, PartialEq, Eq, Clone)]
+	pub struct CheckedTransaction(UncheckedTransaction);
+
+	impl CheckedTransaction {
+		/// Get a reference to the checked signature.
+		pub fn signature(&self) -> &[u8; 64] {
+			&self.0.signature
+		}
+	}
+
+	impl ops::Deref for CheckedTransaction {
+		type Target = Transaction;
+
+		fn deref(&self) -> &Transaction {
+			&self.0.transaction
+		}
+	}
+
+	/// Check the signature on a transaction.
+	///
+	/// On failure, return the transaction back.
+	pub fn check(tx: UncheckedTransaction) -> Result<CheckedTransaction, UncheckedTransaction> {
+		// TODO: requires canonical serialization of transaction.
+		let msg = unimplemented!();
+		if ed25519_verify(&tx.signature, &msg, &tx.transaction.signed) {
+			Ok(CheckedTransaction(tx))
+		} else {
+			Err(tx)
+		}
+	}
+}
+/// Check a transaction
+pub struct CheckedTransaction(primitives::UncheckedTransaction);
+
diff --git a/substrate/runtime-std/with_std.rs b/substrate/runtime-std/with_std.rs
index 19a3cd04a3a..d66eb914192 100644
--- a/substrate/runtime-std/with_std.rs
+++ b/substrate/runtime-std/with_std.rs
@@ -14,7 +14,6 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-
 #[macro_use]
 extern crate environmental;
 
@@ -32,18 +31,14 @@ pub use std::boxed;
 pub use std::slice;
 pub use std::mem;
 
+// re-export hashing functions.
+pub use primitives::{blake2_256, twox_128, twox_256};
+
 pub use polkadot_state_machine::{Externalities, ExternalitiesError, TestExternalities};
 use primitives::hexdisplay::HexDisplay;
 
 // TODO: use the real error, not NoError.
 
-#[derive(Debug)]
-/// As it says - an empty type we use for errors.
-pub struct NoError;
-impl fmt::Display for NoError {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "") }
-}
-
 environmental!(ext : trait Externalities);
 
 /// Get `key` from storage and return a `Vec`, empty if there's a problem.
@@ -97,9 +92,6 @@ pub fn enumerated_trie_root(serialised_values: &[&[u8]]) -> [u8; 32] {
 	triehash::ordered_trie_root(serialised_values.iter().map(|s| s.to_vec())).0
 }
 
-/// Conduct a Keccak-256 hash of the given data.
-pub use primitives::{blake2_256, twox_128, twox_256};
-
 /// Verify a ed25519 signature.
 pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool {
 	ed25519::verify(&sig[..], msg, &pubkey[..])
diff --git a/substrate/runtime-std/without_std.rs b/substrate/runtime-std/without_std.rs
index d49bcdbcaa9..939b9f0d27a 100644
--- a/substrate/runtime-std/without_std.rs
+++ b/substrate/runtime-std/without_std.rs
@@ -6,6 +6,8 @@ extern crate pwasm_libc;
 #[cfg(feature = "nightly")]
 extern crate pwasm_alloc;
 
+extern crate polkadot_primitives as primitives;;
+
 pub use alloc::vec;
 pub use alloc::boxed;
 pub use alloc::rc;
diff --git a/substrate/wasm-runtime/polkadot/src/primitives/digest.rs b/substrate/wasm-runtime/polkadot/src/primitives/digest.rs
index 10f36aef4f9..8b9095a8830 100644
--- a/substrate/wasm-runtime/polkadot/src/primitives/digest.rs
+++ b/substrate/wasm-runtime/polkadot/src/primitives/digest.rs
@@ -18,9 +18,9 @@
 
 use runtime_std::prelude::*;
 
+/// The digest of a block, useful for light-clients.
 #[derive(Clone, Default)]
 #[cfg_attr(feature = "std", derive(PartialEq, Debug))]
-/// The digest of a block, useful for light-clients.
 pub struct Digest {
 	/// All logs that have happened in the block.
 	pub logs: Vec<Vec<u8>>,
diff --git a/substrate/wasm-runtime/polkadot/src/primitives/proposal.rs b/substrate/wasm-runtime/polkadot/src/primitives/proposal.rs
index a4c9b5f8051..b823391fb8e 100644
--- a/substrate/wasm-runtime/polkadot/src/primitives/proposal.rs
+++ b/substrate/wasm-runtime/polkadot/src/primitives/proposal.rs
@@ -85,38 +85,6 @@ impl Slicable for Proposal {
 	}
 }
 
-impl Proposal {
-	pub fn enact(&self) {
-		let mut params = StreamReader::new(&self.input_data);
-		match self.function {
-			InternalFunction::SystemSetCode => {
-				let code: Vec<u8> = params.read().unwrap();
-				system::privileged::set_code(&code);
-			}
-			InternalFunction::StakingSetSessionsPerEra => {
-				let value = params.read().unwrap();
-				staking::privileged::set_sessions_per_era(value);
-			}
-			InternalFunction::StakingSetBondingDuration => {
-				let value = params.read().unwrap();
-				staking::privileged::set_bonding_duration(value);
-			}
-			InternalFunction::StakingSetValidatorCount => {
-				let value = params.read().unwrap();
-				staking::privileged::set_validator_count(value);
-			}
-			InternalFunction::GovernanceSetApprovalPpmRequired => {
-				let value = params.read().unwrap();
-				governance::privileged::set_approval_ppm_required(value);
-			}
-			InternalFunction::SessionSetLength => {
-				let value = params.read().unwrap();
-				session::privileged::set_length(value);
-			}
-		}
-	}
-}
-
 #[cfg(test)]
 mod test {
 	use super::*;
diff --git a/substrate/wasm-runtime/polkadot/src/runtime/governance.rs b/substrate/wasm-runtime/polkadot/src/runtime/governance.rs
index 49605ce3eff..c50255ea1ec 100644
--- a/substrate/wasm-runtime/polkadot/src/runtime/governance.rs
+++ b/substrate/wasm-runtime/polkadot/src/runtime/governance.rs
@@ -109,6 +109,36 @@ pub mod internal {
 			}
 		}
 	}
+
+	fn enact_proposal(proposal: Proposal) {
+		let mut params = StreamReader::new(&self.input_data);
+		match self.function {
+			InternalFunction::SystemSetCode => {
+				let code: Vec<u8> = params.read().unwrap();
+				system::privileged::set_code(&code);
+			}
+			InternalFunction::StakingSetSessionsPerEra => {
+				let value = params.read().unwrap();
+				staking::privileged::set_sessions_per_era(value);
+			}
+			InternalFunction::StakingSetBondingDuration => {
+				let value = params.read().unwrap();
+				staking::privileged::set_bonding_duration(value);
+			}
+			InternalFunction::StakingSetValidatorCount => {
+				let value = params.read().unwrap();
+				staking::privileged::set_validator_count(value);
+			}
+			InternalFunction::GovernanceSetApprovalPpmRequired => {
+				let value = params.read().unwrap();
+				governance::privileged::set_approval_ppm_required(value);
+			}
+			InternalFunction::SessionSetLength => {
+				let value = params.read().unwrap();
+				session::privileged::set_length(value);
+			}
+		}
+	}
 }
 
 #[cfg(test)]
diff --git a/substrate/wasm-runtime/polkadot/src/runtime/system.rs b/substrate/wasm-runtime/polkadot/src/runtime/system.rs
index 8df20f138e7..7a919ae58e0 100644
--- a/substrate/wasm-runtime/polkadot/src/runtime/system.rs
+++ b/substrate/wasm-runtime/polkadot/src/runtime/system.rs
@@ -49,6 +49,8 @@ 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: &[u8]) {
 		with_env(|e| {
@@ -115,7 +117,40 @@ pub mod internal {
 		storage::put(&nonce_key, &(expected_nonce + 1));
 
 		// decode parameters and dispatch
-		tx.function.dispatch(&tx.signed, &tx.input_data);
+		dispatch_function(&tx.function, &tx.signed, &tx.input_data);
+	}
+
+	fn dispatch_function(function: &Function, transactor: &AccountId, data: &[u8]) {
+		let mut params = ::runtime_codec::StreamReader::new(data);
+		match *self {
+			Function::StakingStake => {
+				staking::public::stake(transactor);
+			}
+			Function::StakingUnstake => {
+				staking::public::unstake(transactor);
+			}
+			Function::StakingTransfer => {
+				let dest = params.read().unwrap();
+				let value = params.read().unwrap();
+				staking::public::transfer(transactor, &dest, value);
+			}
+			Function::SessionSetKey => {
+				let session = params.read().unwrap();
+				session::public::set_key(transactor, &session);
+			}
+			Function::TimestampSet => {
+				let t = params.read().unwrap();
+				timestamp::public::set(t);
+			}
+			Function::GovernancePropose => {
+				let proposal = params.read().unwrap();
+				governance::public::propose(transactor, &proposal);
+			}
+			Function::GovernanceApprove => {
+				let era_index = params.read().unwrap();
+				governance::public::approve(transactor, era_index);
+			}
+		}
 	}
 }
 
-- 
GitLab