Browse Source

initial commit - runtime spec version 4

Mokhtar Naamani 6 years ago
commit
d57bdf16ae
17 changed files with 6505 additions and 0 deletions
  1. 12 0
      .gitignore
  2. 16 0
      CHANGELOG.md
  3. 164 0
      Cargo.toml
  4. 18 0
      build.sh
  5. 16 0
      setup.sh
  6. 170 0
      src/governance/council.rs
  7. 1667 0
      src/governance/election.rs
  8. 97 0
      src/governance/mock.rs
  9. 19 0
      src/governance/mod.rs
  10. 1390 0
      src/governance/proposals.rs
  11. 70 0
      src/governance/sealed_vote.rs
  12. 114 0
      src/governance/stake.rs
  13. 326 0
      src/lib.rs
  14. 41 0
      src/memo.rs
  15. 2360 0
      wasm/Cargo.lock
  16. 22 0
      wasm/Cargo.toml
  17. 3 0
      wasm/src/lib.rs

+ 12 - 0
.gitignore

@@ -0,0 +1,12 @@
+# Generated by Cargo
+# will have compiled files and executables
+**/target/
+
+# Cargo lock file for native runtime - only used for cargo test
+./Cargo.lock
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# JetBrains IDEs
+.idea

+ 16 - 0
CHANGELOG.md

@@ -0,0 +1,16 @@
+### Version 4 - Bug Fixes - March 4th 2019 - `9941dd`
+ - Allow illiquid accounts to pay transaction fees. Fixes unstaking and setting memo, by permitting extrinsics which do not require more than a transaction fee to be accepted into mempool.
+ - Updated Cargo dependencies to use forked substrate repo `github.com/joystream/substrate`
+
+
+ On-chain runtime upgrade performed with sudo `consensus::setCode()`
+
+### Version 3 - Sparta - March 1st 2019 - `1ca4cc`
+  - Basic substrate node - based on substrate `1ca4cc0a16a357782bb1028bb57376594ca232a0`
+  - Block Authoring - only Aura (enabling GRANDPA in future release)
+  - Council Elections
+  - Council Runtime upgrade proposal
+  - Simple PoS validator staking
+  - Memo (account status message)
+
+Used in genesis block for first testnet (Sparta)

+ 164 - 0
Cargo.toml

@@ -0,0 +1,164 @@
+[package]
+authors = ['Joystream']
+edition = '2018'
+name = 'joystream-node-runtime'
+version = '1.0.1'
+
+[features]
+default = ['std']
+std = [
+    'parity-codec/std',
+    'parity-codec-derive/std',
+    'primitives/std',
+    'substrate-client/std',
+    'rstd/std',
+    'runtime-io/std',
+    'srml-support/std',
+    'balances/std',
+    'fees/std',
+    'executive/std',
+    'aura/std',
+    'indices/std',
+    'primitives/std',
+    'system/std',
+    'timestamp/std',
+    'sudo/std',
+    'version/std',
+    'serde_derive',
+    'serde/std',
+    'safe-mix/std',
+    'consensus-aura/std',
+    'staking/std',
+    'session/std',
+]
+[dependencies.aura]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-aura'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.balances]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-balances'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.consensus]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-consensus'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.consensus-aura]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'substrate-consensus-aura-primitives'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.executive]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-executive'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.fees]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-fees'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.indices]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-indices'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.parity-codec]
+default-features = false
+version = '3.0'
+
+[dependencies.parity-codec-derive]
+default-features = false
+version = '3.0'
+
+[dependencies.primitives]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'substrate-primitives'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.rstd]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'sr-std'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.runtime-io]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'sr-io'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.runtime-primitives]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'sr-primitives'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.safe-mix]
+default-features = false
+version = '1.0'
+
+[dependencies.serde]
+default-features = false
+version = '1.0'
+
+[dependencies.serde_derive]
+optional = true
+version = '1.0'
+
+[dependencies.srml-support]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.substrate-client]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.sudo]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-sudo'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.system]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-system'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.timestamp]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-timestamp'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.version]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'sr-version'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.staking]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-staking'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'
+
+[dependencies.session]
+default_features = false
+git = 'https://github.com/joystream/substrate.git'
+package = 'srml-session'
+rev = 'df5e65927780b323482e2e8b5031822f423a032d'

+ 18 - 0
build.sh

@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+set -e
+
+if cargo --version | grep -q "nightly"; then
+	CARGO_CMD="cargo"
+else
+	CARGO_CMD="cargo +nightly"
+fi
+
+pushd wasm/
+
+$CARGO_CMD build --target=wasm32-unknown-unknown --release
+
+for i in joystream_node_runtime_wasm
+do
+	wasm-gc target/wasm32-unknown-unknown/release/$i.wasm target/wasm32-unknown-unknown/release/$i.compact.wasm
+done
+

+ 16 - 0
setup.sh

@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+
+set -e
+
+echo "*** Initialising WASM build environment"
+
+if [ -z $CI_PROJECT_NAME ] ; then
+   rustup update nightly
+   rustup update stable
+fi
+
+rustup target add wasm32-unknown-unknown --toolchain nightly
+
+# Install wasm-gc. It's useful for stripping slimming down wasm binaries.
+command -v wasm-gc || \
+	cargo +nightly install --git https://github.com/alexcrichton/wasm-gc --force

+ 170 - 0
src/governance/council.rs

@@ -0,0 +1,170 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use srml_support::{StorageValue, StorageMap, dispatch::Result, decl_module, decl_event, decl_storage, ensure};
+use srml_support::traits::{Currency};
+use system::{self, ensure_signed};
+use runtime_primitives::traits::{As, Zero};
+use rstd::prelude::*;
+
+pub use super::election::{self, Seats, Seat, CouncilElected};
+pub use super::{ GovernanceCurrency, BalanceOf };
+
+// Hook For announcing that council term has ended
+pub trait CouncilTermEnded {
+    fn council_term_ended();
+}
+
+impl CouncilTermEnded for () {
+    fn council_term_ended() {}
+}
+
+impl<X: CouncilTermEnded> CouncilTermEnded for (X,) {
+    fn council_term_ended() {
+        X::council_term_ended();
+    }
+}
+
+pub trait Trait: system::Trait + GovernanceCurrency {
+    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
+
+    type CouncilTermEnded: CouncilTermEnded;
+}
+
+decl_storage! {
+    trait Store for Module<T: Trait> as Council {
+        ActiveCouncil get(active_council) config(): Seats<T::AccountId, BalanceOf<T>>;
+        TermEndsAt get(term_ends_at) config() : T::BlockNumber = T::BlockNumber::sa(1);
+    }
+}
+
+/// Event for this module.
+decl_event!(
+    pub enum Event<T> where <T as system::Trait>::BlockNumber {
+        CouncilTermEnded(BlockNumber),
+        NewCouncilTermStarted(BlockNumber),
+    }
+);
+
+impl<T: Trait> CouncilElected<Seats<T::AccountId, BalanceOf<T>>, T::BlockNumber> for Module<T> {
+    fn council_elected(seats: Seats<T::AccountId, BalanceOf<T>>, term: T::BlockNumber) {
+        <ActiveCouncil<T>>::put(seats);
+
+        let next_term_ends_at = <system::Module<T>>::block_number() + term;
+        <TermEndsAt<T>>::put(next_term_ends_at);
+        Self::deposit_event(RawEvent::NewCouncilTermStarted(next_term_ends_at));
+    }
+}
+
+impl<T: Trait> Module<T> {
+
+    pub fn is_term_ended() -> bool {
+        <system::Module<T>>::block_number() >= Self::term_ends_at()
+    }
+
+    pub fn is_councilor(sender: &T::AccountId) -> bool {
+        Self::active_council().iter().any(|c| c.member == *sender)
+    }
+}
+
+decl_module! {
+    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+        fn deposit_event<T>() = default;
+
+        fn on_finalise(now: T::BlockNumber) {
+            if now == Self::term_ends_at() {
+                Self::deposit_event(RawEvent::CouncilTermEnded(now));
+                T::CouncilTermEnded::council_term_ended();
+            }
+        }
+
+        // Sudo methods...
+
+        /// Force set a zero staked council. Stakes in existing council will vanish into thin air!
+        fn set_council(accounts: Vec<T::AccountId>) {
+            let new_council: Seats<T::AccountId, BalanceOf<T>> = accounts.into_iter().map(|account| {
+                Seat {
+                    member: account,
+                    stake: BalanceOf::<T>::zero(),
+                    backers: vec![]
+                }
+            }).collect();
+            <ActiveCouncil<T>>::put(new_council);
+        }
+
+        /// Adds a zero staked council member
+        fn add_council_member(account: T::AccountId) {
+            ensure!(!Self::is_councilor(&account), "cannot add same account multiple times");
+            let seat = Seat {
+                member: account,
+                stake: BalanceOf::<T>::zero(),
+                backers: vec![]
+            };
+
+            // add member to existing council
+            <ActiveCouncil<T>>::mutate(|council| council.push(seat));
+        }
+
+        fn remove_council_member(account_to_remove: T::AccountId) {
+            ensure!(Self::is_councilor(&account_to_remove), "account is not a councilor");
+            let filtered_council: Seats<T::AccountId, BalanceOf<T>> = Self::active_council()
+                .into_iter()
+                .filter(|c| c.member != account_to_remove)
+                .collect();
+            <ActiveCouncil<T>>::put(filtered_council);
+        }
+
+        /// Set blocknumber when council term will end
+        fn set_term_ends_at(ends_at: T::BlockNumber) {
+            ensure!(ends_at > <system::Module<T>>::block_number(), "must set future block number");
+            <TermEndsAt<T>>::put(ends_at);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::governance::mock::*;
+    use parity_codec::Encode;
+    use runtime_io::with_externalities;
+    use srml_support::*;
+
+    #[test]
+    fn add_council_member_test() {
+        with_externalities(&mut initial_test_ext(), || {
+            assert!(!Council::is_councilor(&1));
+
+            assert_ok!(Council::add_council_member(1));
+            assert!(Council::is_councilor(&1));
+
+            assert_ok!(Council::add_council_member(2));
+            assert!(Council::is_councilor(&1));
+            assert!(Council::is_councilor(&2));
+        });
+    }
+
+    #[test]
+    fn remove_council_member_test() {
+        with_externalities(&mut initial_test_ext(), || {
+            assert_ok!(Council::add_council_member(1));
+            assert_ok!(Council::add_council_member(2));
+            assert_ok!(Council::add_council_member(3));
+
+            assert_ok!(Council::remove_council_member(2));
+
+            assert!(!Council::is_councilor(&2));
+            assert!(Council::is_councilor(&1));
+            assert!(Council::is_councilor(&3));
+        });
+    }
+
+    #[test]
+    fn set_council_test() {
+        with_externalities(&mut initial_test_ext(), || {
+            assert_ok!(Council::set_council(vec![4,5,6]));
+            assert!(Council::is_councilor(&4));
+            assert!(Council::is_councilor(&5));
+            assert!(Council::is_councilor(&6));
+        });
+    }
+}

+ 1667 - 0
src/governance/election.rs

@@ -0,0 +1,1667 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use rstd::prelude::*;
+use srml_support::{StorageValue, StorageMap, dispatch::Result, decl_module, decl_event, decl_storage, ensure};
+use srml_support::traits::{Currency};
+use system::{self, ensure_signed};
+
+use runtime_primitives::traits::{Hash, As, Zero, /*SimpleArithmetic*/};
+//use {balances};
+
+use rstd::collections::btree_map::BTreeMap;
+use rstd::ops::Add;
+
+use super::stake::Stake;
+use super::sealed_vote::SealedVote;
+
+pub use super::{ GovernanceCurrency, BalanceOf };
+use super::council;
+
+pub trait Trait: system::Trait + council::Trait + GovernanceCurrency {
+    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
+
+    type CouncilElected: CouncilElected<Seats<Self::AccountId, BalanceOf<Self>>, Self::BlockNumber>;
+}
+
+#[derive(Clone, Copy, Encode, Decode)]
+pub enum ElectionStage<BlockNumber> {
+    Announcing(BlockNumber),
+    Voting(BlockNumber),
+    Revealing(BlockNumber),
+}
+
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
+pub struct Seat<AccountId, Balance> {
+    pub member: AccountId,
+    pub stake: Balance,
+    pub backers: Vec<Backer<AccountId, Balance>>,
+}
+
+impl<AccountId, Balance> Seat<AccountId, Balance>
+    where Balance: Add<Output=Balance> + Copy,
+{
+    pub fn calc_total_stake(&self) -> Balance {
+        self.backers.iter().fold(self.stake, |acc, backer| acc + backer.stake)
+    }
+}
+
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
+pub struct Backer<AccountId, Balance> {
+    pub member: AccountId,
+    pub stake: Balance,
+}
+
+pub type Seats<AccountId, Balance> = Vec<Seat<AccountId, Balance>>;
+
+// Hook for setting a new council when it is elected
+pub trait CouncilElected<Elected, Term> {
+    fn council_elected(new_council: Elected, term: Term);
+}
+
+impl<Elected, Term> CouncilElected<Elected, Term> for () {
+    fn council_elected(_new_council: Elected, term: Term) {}
+}
+
+impl<Elected, Term, X: CouncilElected<Elected, Term>> CouncilElected<Elected, Term> for (X,) {
+    fn council_elected(new_council: Elected, term: Term) {
+        X::council_elected(new_council, term);
+    }
+}
+
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
+#[derive(Clone, Copy, Encode, Decode, Default)]
+pub struct TransferableStake<Balance> {
+    seat: Balance,
+    backing: Balance,
+}
+
+decl_storage! {
+    trait Store for Module<T: Trait> as CouncilElection {
+        // Flag for wether to automatically start an election after a council term ends
+        AutoStart get(auto_start) config() : bool = true;
+
+        // Current stage if there is an election running
+        Stage get(stage): Option<ElectionStage<T::BlockNumber>>;
+
+        // The election round
+        Round get(round): u32;
+
+        ExistingStakeHolders get(existing_stake_holders): Vec<T::AccountId>;
+        TransferableStakes get(transferable_stakes): map T::AccountId => TransferableStake<BalanceOf<T>>;
+
+        Applicants get(applicants): Vec<T::AccountId>;
+        ApplicantStakes get(applicant_stakes): map T::AccountId => Stake<BalanceOf<T>>;
+
+        Commitments get(commitments): Vec<T::Hash>;
+
+        // TODO value type of this map looks scary, is there any way to simplify the notation?
+        Votes get(votes): map T::Hash => SealedVote<T::AccountId, Stake<BalanceOf<T>>, T::Hash, T::AccountId>;
+
+        // Current Election Parameters - default "zero" values are not meaningful. Running an election without
+        // settings reasonable values is a bad idea. Parameters can be set in the TriggerElection hook.
+        AnnouncingPeriod get(announcing_period) config(): T::BlockNumber = T::BlockNumber::sa(100);
+        VotingPeriod get(voting_period) config(): T::BlockNumber = T::BlockNumber::sa(100);
+        RevealingPeriod get(revealing_period) config(): T::BlockNumber = T::BlockNumber::sa(100);
+        CouncilSize get(council_size) config(): u32 = 10;
+        CandidacyLimit get (candidacy_limit) config(): u32 = 20;
+        MinCouncilStake get(min_council_stake) config(): BalanceOf<T> = BalanceOf::<T>::sa(100);
+        NewTermDuration get(new_term_duration) config(): T::BlockNumber = T::BlockNumber::sa(1000);
+        MinVotingStake get(min_voting_stake) config(): BalanceOf<T> = BalanceOf::<T>::sa(10);
+    }
+}
+
+/// Event for this module.
+decl_event!(
+    pub enum Event<T> where
+    <T as system::Trait>::BlockNumber,
+    <T as system::Trait>::AccountId,
+    <T as system::Trait>::Hash  {
+        /// A new election started
+        ElectionStarted(),
+        AnnouncingStarted(u32),
+        AnnouncingEnded(),
+        VotingStarted(),
+        VotingEnded(),
+        RevealingStarted(),
+        RevealingEnded(),
+        CouncilElected(BlockNumber),
+        Applied(AccountId),
+        Voted(AccountId, Hash),
+        Revealed(AccountId, Hash, AccountId),
+    }
+);
+
+impl<T: Trait> Module<T> {
+    // HELPERS - IMMUTABLES
+
+    fn council_size_usize() -> usize {
+        Self::council_size() as usize
+    }
+
+    fn candidacy_limit_usize() -> usize {
+        Self::candidacy_limit() as usize
+    }
+
+    fn current_block_number_plus(length: T::BlockNumber) -> T::BlockNumber {
+        <system::Module<T>>::block_number() + length
+    }
+
+    // TODO This method should be moved to Membership module once it's created.
+    fn is_member(sender: T::AccountId) -> bool {
+        !T::Currency::free_balance(&sender).is_zero()
+    }
+
+    // PUBLIC IMMUTABLES
+
+    /// Returns true if an election is running
+    pub fn is_election_running() -> bool {
+        Self::stage().is_some()
+    }
+
+    /// Returns block number at which current stage will end if an election is running.
+    pub fn stage_ends_at() -> Option<T::BlockNumber> {
+        if let Some(stage) = Self::stage() {
+            match stage {
+                ElectionStage::Announcing(ends) => Some(ends),
+                ElectionStage::Voting(ends) => Some(ends),
+                ElectionStage::Revealing(ends) => Some(ends),
+            }
+        } else {
+            None
+        }
+    }
+
+    // PRIVATE MUTABLES
+
+    /// Starts an election. Will fail if an election is already running
+    /// Initializes transferable stakes. Assumes election parameters have already been set.
+    fn start_election(current_council: Seats<T::AccountId, BalanceOf<T>>) -> Result {
+        ensure!(!Self::is_election_running(), "election already in progress");
+        ensure!(Self::existing_stake_holders().len() == 0, "stake holders must be empty");
+        ensure!(Self::applicants().len() == 0, "applicants must be empty");
+        ensure!(Self::commitments().len() == 0, "commitments must be empty");
+
+        // Take snapshot of seat and backing stakes of an existing council
+        // Its important to note that the election system takes ownership of these stakes, and is responsible
+        // to return any unused stake to original owners and the end of the election.
+        Self::initialize_transferable_stakes(current_council);
+
+        Self::deposit_event(RawEvent::ElectionStarted());
+
+        Self::move_to_announcing_stage();
+        Ok(())
+    }
+
+    /// Sets announcing stage. Can be called from any stage and assumes all preparatory work
+    /// for entering the stage has been performed.
+    /// Bumps the election round.
+    fn move_to_announcing_stage() {
+        let next_round = <Round<T>>::mutate(|n| { *n += 1; *n });
+
+        let new_stage_ends_at = Self::current_block_number_plus(Self::announcing_period());
+
+        <Stage<T>>::put(ElectionStage::Announcing(new_stage_ends_at));
+
+        Self::deposit_event(RawEvent::AnnouncingStarted(next_round));
+    }
+
+    /// Sets announcing stage. Can be called from any stage and assumes all preparatory work
+    /// for entering the stage has been performed.
+    fn move_to_voting_stage() {
+        let new_stage_ends_at = Self::current_block_number_plus(Self::voting_period());
+
+        <Stage<T>>::put(ElectionStage::Voting(new_stage_ends_at));
+
+        Self::deposit_event(RawEvent::VotingStarted());
+    }
+
+    /// Sets announcing stage. Can be called from any stage and assumes all preparatory work
+    /// for entering the stage has been performed.
+    fn move_to_revealing_stage() {
+        let new_stage_ends_at = Self::current_block_number_plus(Self::revealing_period());
+
+        <Stage<T>>::put(ElectionStage::Revealing(new_stage_ends_at));
+
+        Self::deposit_event(RawEvent::RevealingStarted());
+    }
+
+    /// Sorts applicants by stake, and returns slice of applicants with least stake. Applicants not
+    /// returned in the slice are the top `len` highest staked.
+    fn find_least_staked_applicants (
+        applicants: &mut Vec<T::AccountId>,
+        len: usize) -> &[T::AccountId]
+    {
+        if len >= applicants.len() {
+            &[]
+        } else {
+            applicants.sort_by_key(|applicant| Self::applicant_stakes(applicant));
+            &applicants[0 .. applicants.len() - len]
+        }
+    }
+
+    fn on_announcing_ended() {
+        let mut applicants = Self::applicants();
+
+        if applicants.len() < Self::council_size_usize() {
+            // Not enough applicants announced candidacy
+            Self::move_to_announcing_stage();
+        } else {
+            // upper limit on applicants that will move to voting stage
+            let limit = rstd::cmp::max(Self::council_size_usize(), Self::candidacy_limit_usize());
+            let applicants_to_drop = Self::find_least_staked_applicants(&mut applicants, limit);
+
+            Self::drop_applicants(applicants_to_drop);
+
+            Self::move_to_voting_stage();
+        }
+    }
+
+    fn on_voting_ended() {
+        Self::move_to_revealing_stage();
+    }
+
+    fn on_revealing_ended() {
+        // tally the revealed votes
+        let mut votes = Vec::new();
+
+        for commitment in Self::commitments().iter() {
+            votes.push(Self::votes(commitment));
+        }
+
+        let mut new_council = Self::tally_votes(&votes);
+
+        // Note here that applicants with zero votes dont appear in the tally.
+        // Is an applicant with some votes but less total stake than another applicant with zero votes
+        // more qualified to be on the council?
+        // Consider implications - if a council can be formed purely by staking are we fine with that?
+
+        for applicant in Self::applicants().iter() {
+            if !new_council.contains_key(applicant) {
+                new_council.insert(applicant.clone(), Seat {
+                    member: applicant.clone(),
+                    stake: Self::applicant_stakes(applicant).total(),
+                    backers: Vec::new(),
+                });
+            }
+        }
+
+        if new_council.len() == Self::council_size_usize() {
+            // all applicants in the tally will form the new council
+        } else if new_council.len() > Self::council_size_usize() {
+            // we have more than enough applicants to form the new council.
+            // select top staked
+            Self::filter_top_staked(&mut new_council, Self::council_size_usize());
+        } else {
+            // Not enough applicants with votes to form a council.
+            // This may happen if we didn't add applicants with zero votes to the tally,
+            // or in future if we allow applicants to withdraw candidacy during voting or revealing stages.
+            // or council size was increased during voting, revealing stages.
+        }
+
+        // unless we want to add more filtering criteria to what is considered a successful election
+        // other than just the minimum stake for candidacy, we have a new council!
+
+        Self::teardown_election (
+            &votes,
+            &new_council,
+            true /* unlock transferable stakes */
+        );
+
+        let new_council = new_council.into_iter().map(|(_, seat)| seat).collect();
+        T::CouncilElected::council_elected(new_council, Self::new_term_duration());
+
+        Self::deposit_event(RawEvent::CouncilElected(<system::Module<T>>::block_number()));
+    }
+
+    fn teardown_election (
+        votes: &Vec<SealedVote<T::AccountId, Stake<BalanceOf<T>>,
+        T::Hash, T::AccountId>>, new_council: &BTreeMap<T::AccountId, Seat<T::AccountId, BalanceOf<T>>>,
+        unlock_ts: bool)
+    {
+        Self::refund_voting_stakes(&votes, &new_council);
+        Self::clear_votes();
+
+        Self::drop_unelected_applicants(&new_council);
+        Self::clear_applicants();
+
+        if unlock_ts {
+            Self::unlock_transferable_stakes();
+        }
+
+        Self::clear_transferable_stakes();
+
+        <Stage<T>>::kill();
+    }
+
+    fn unlock_transferable_stakes() {
+        // move stakes back to account holder's free balance
+        for stakeholder in Self::existing_stake_holders().iter() {
+            let stake = Self::transferable_stakes(stakeholder);
+            if !stake.seat.is_zero() || !stake.backing.is_zero() {
+                T::Currency::unreserve(stakeholder, stake.seat + stake.backing);
+            }
+        }
+    }
+
+    fn clear_transferable_stakes() {
+        for stakeholder in Self::existing_stake_holders() {
+            <TransferableStakes<T>>::remove(stakeholder);
+        }
+
+        <ExistingStakeHolders<T>>::kill();
+    }
+
+    fn clear_applicants() {
+        for applicant in Self::applicants() {
+            <ApplicantStakes<T>>::remove(applicant);
+        }
+        <Applicants<T>>::kill();
+    }
+
+    fn refund_applicant(applicant: &T::AccountId) {
+        let stake = <ApplicantStakes<T>>::get(applicant);
+
+        // return new stake to account's free balance
+        if !stake.new.is_zero() {
+            T::Currency::unreserve(applicant, stake.new);
+        }
+
+        // return unused transferable stake
+        if !stake.transferred.is_zero() {
+            <TransferableStakes<T>>::mutate(applicant, |transferable| (*transferable).seat += stake.transferred);
+        }
+    }
+
+    fn drop_applicants(drop: &[T::AccountId]) {
+        let not_dropped: Vec<T::AccountId> = Self::applicants().into_iter()
+            .filter(|id| !drop.iter().any(|x| *x == *id))
+            .collect();
+
+        for applicant in drop {
+            Self::refund_applicant(applicant);
+            <ApplicantStakes<T>>::remove(applicant);
+        }
+
+        <Applicants<T>>::put(not_dropped);
+    }
+
+    fn drop_unelected_applicants(new_council: &BTreeMap<T::AccountId, Seat<T::AccountId, BalanceOf<T>>>) {
+        let applicants_to_drop: Vec<T::AccountId> = Self::applicants().into_iter()
+            .filter(|applicant| !new_council.contains_key(&applicant))
+            .collect();
+
+        Self::drop_applicants(&applicants_to_drop[..]);
+    }
+
+    fn refund_voting_stakes(
+        sealed_votes: &Vec<SealedVote<T::AccountId, Stake<BalanceOf<T>>, T::Hash, T::AccountId>>,
+        new_council: &BTreeMap<T::AccountId, Seat<T::AccountId, BalanceOf<T>>>)
+    {
+        for sealed_vote in sealed_votes.iter() {
+            // Do a refund if commitment was not revealed, or the vote was for applicant that did
+            // not get elected to the council
+            // TODO critical: shouldn't we slash the stake in such a case? This is the whole idea behid staking on something: people need to decide carefully and be responsible for their bahavior because they can loose their stake
+            // See https://github.com/Joystream/substrate-node-joystream/issues/4
+            let do_refund = match sealed_vote.get_vote() {
+                Some(applicant) => !new_council.contains_key(&applicant),
+                None => true
+            };
+
+            if do_refund {
+                // return new stake to account's free balance
+                let SealedVote { voter, stake, .. } = sealed_vote;
+                if !stake.new.is_zero() {
+                    T::Currency::unreserve(voter, stake.new);
+                }
+
+                // return unused transferable stake
+                if !stake.transferred.is_zero() {
+                    <TransferableStakes<T>>::mutate(voter, |transferable| (*transferable).backing += stake.transferred);
+                }
+            }
+        }
+    }
+
+    fn clear_votes() {
+        for commitment in Self::commitments() {
+            <Votes<T>>::remove(commitment);
+        }
+        <Commitments<T>>::kill();
+    }
+
+    fn tally_votes(sealed_votes: &Vec<SealedVote<T::AccountId, Stake<BalanceOf<T>>, T::Hash, T::AccountId>>) -> BTreeMap<T::AccountId, Seat<T::AccountId, BalanceOf<T>>> {
+        let mut tally: BTreeMap<T::AccountId, Seat<T::AccountId, BalanceOf<T>>> = BTreeMap::new();
+
+        for sealed_vote in sealed_votes.iter() {
+            if let Some(applicant) = sealed_vote.get_vote() {
+                if !tally.contains_key(&applicant) {
+                    // Add new seat
+                    tally.insert(applicant.clone(), Seat {
+                        member: applicant.clone(),
+                        stake: Self::applicant_stakes(applicant).total(),
+                        backers: vec![],
+                    });
+                }
+                if let Some(seat) = tally.get_mut(&applicant) {
+                    // Add backer to existing seat
+                    seat.backers.push(Backer {
+                        member: sealed_vote.voter.clone(),
+                        stake: sealed_vote.stake.total()
+                    });
+                }
+            }
+        }
+
+        tally
+    }
+
+    fn filter_top_staked(tally: &mut BTreeMap<T::AccountId, Seat<T::AccountId, BalanceOf<T>>>, limit: usize) {
+
+        if limit >= tally.len() {
+            return;
+        }
+
+        // use ordering in the applicants vector (not ordering resulting from btreemap iteration)
+        let mut seats: Vec<T::AccountId> = Self::applicants().into_iter()
+            .filter(|id| tally.contains_key(id)).collect();
+
+        // ensure_eq!(seats.len(), tally.len());
+
+        if limit >= seats.len() {
+            // Tally is inconsistent with list of applicants!
+            return;
+        }
+
+        // TODO: order by number of votes, then number of backers
+
+        seats.sort_by_key(|applicant| {
+            tally.get(&applicant).map_or(Zero::zero(), |seat| seat.calc_total_stake())
+        });
+
+        // seats at bottom of list
+        let filtered_out_seats = &seats[0 .. seats.len() - limit];
+
+        for id in filtered_out_seats {
+            tally.remove(id);
+        }
+    }
+
+    /// Checks if the current election stage has ended and calls the stage ended handler
+    fn check_if_stage_is_ending(now: T::BlockNumber) {
+        if let Some(stage) = Self::stage() {
+            match stage {
+                ElectionStage::Announcing(ends) => if ends == now {
+                    Self::deposit_event(RawEvent::AnnouncingEnded());
+                    Self::on_announcing_ended();
+                },
+                ElectionStage::Voting(ends) => if ends == now {
+                    Self::deposit_event(RawEvent::VotingEnded());
+                    Self::on_voting_ended();
+                },
+                ElectionStage::Revealing(ends) => if ends == now {
+                    Self::deposit_event(RawEvent::RevealingEnded());
+                    Self::on_revealing_ended();
+                },
+            }
+        }
+    }
+
+    /// Takes a snapshot of the stakes from the current council
+    fn initialize_transferable_stakes(current_council: Seats<T::AccountId, BalanceOf<T>>) {
+        let mut stakeholder_accounts: Vec<T::AccountId> = Vec::new();
+
+        for seat in current_council.into_iter() {
+            let Seat { member, stake, .. } = seat;
+
+            if <TransferableStakes<T>>::exists(&member) {
+                <TransferableStakes<T>>::mutate(&member, |transferbale_stake| *transferbale_stake = TransferableStake {
+                    seat: transferbale_stake.seat + stake,
+                    backing: transferbale_stake.backing,
+                });
+            } else {
+                <TransferableStakes<T>>::insert(&member, TransferableStake {
+                    seat: stake,
+                    backing: BalanceOf::<T>::zero(),
+                });
+
+                stakeholder_accounts.push(member);
+            }
+
+            for backer in seat.backers.into_iter() {
+                let Backer { member, stake, ..} = backer;
+
+                if <TransferableStakes<T>>::exists(&member) {
+                    <TransferableStakes<T>>::mutate(&member, |transferbale_stake| *transferbale_stake = TransferableStake {
+                        seat: transferbale_stake.seat,
+                        backing: transferbale_stake.backing + stake,
+                    });
+                } else {
+                    <TransferableStakes<T>>::insert(&member, TransferableStake {
+                        seat: BalanceOf::<T>::zero(),
+                        backing: stake,
+                    });
+
+                    stakeholder_accounts.push(member);
+                }
+            }
+        }
+
+        <ExistingStakeHolders<T>>::put(stakeholder_accounts);
+    }
+
+    fn new_stake_reusing_transferable(transferable: &mut BalanceOf<T>, new_stake: BalanceOf<T>) -> Stake<BalanceOf<T>> {
+        let transferred =
+            if *transferable >= new_stake {
+                new_stake
+            } else {
+                *transferable
+            };
+
+        *transferable = *transferable - transferred;
+
+        Stake {
+            new: new_stake - transferred,
+            transferred,
+        }
+    }
+
+    fn try_add_applicant(applicant: T::AccountId, stake: BalanceOf<T>) -> Result {
+        let mut transferable_stake = <TransferableStakes<T>>::get(&applicant);
+
+        let new_stake = Self::new_stake_reusing_transferable(&mut transferable_stake.seat, stake);
+
+        ensure!(T::Currency::can_reserve(&applicant, new_stake.new), "not enough free balance to reserve");
+
+        ensure!(T::Currency::reserve(&applicant, new_stake.new).is_ok(), "failed to reserve applicant stake!");
+
+        let applicant_stake = <ApplicantStakes<T>>::get(&applicant);
+        let total_stake = applicant_stake.add(&new_stake);
+
+        if <TransferableStakes<T>>::exists(&applicant) {
+            <TransferableStakes<T>>::insert(&applicant, transferable_stake);
+        }
+
+        if !<ApplicantStakes<T>>::exists(&applicant) {
+            // insert element at the begining, this gives priority to early applicants
+            // when ordering applicants by stake if stakes are equal
+            <Applicants<T>>::mutate(|applicants| applicants.insert(0, applicant.clone()));
+        }
+
+        <ApplicantStakes<T>>::insert(applicant.clone(), total_stake);
+
+        Ok(())
+    }
+
+    fn try_add_vote(voter: T::AccountId, stake: BalanceOf<T>, commitment: T::Hash) -> Result {
+        ensure!(!<Votes<T>>::exists(commitment), "duplicate commitment");
+
+        let mut transferable_stake = <TransferableStakes<T>>::get(&voter);
+
+        let vote_stake = Self::new_stake_reusing_transferable(&mut transferable_stake.backing, stake);
+
+        ensure!(T::Currency::can_reserve(&voter, vote_stake.new), "not enough free balance to reserve");
+
+        ensure!(T::Currency::reserve(&voter, vote_stake.new).is_ok(), "failed to reserve voting stake!");
+
+        <Commitments<T>>::mutate(|commitments| commitments.push(commitment));
+
+        <Votes<T>>::insert(commitment, SealedVote::new(voter.clone(), vote_stake, commitment));
+
+        if <TransferableStakes<T>>::exists(&voter) {
+            <TransferableStakes<T>>::insert(&voter, transferable_stake);
+        }
+
+        Ok(())
+    }
+
+    fn try_reveal_vote(voter: T::AccountId, commitment: T::Hash, vote_for: T::AccountId, salt: Vec<u8>) -> Result {
+        ensure!(<Votes<T>>::exists(&commitment), "commitment not found");
+
+        let mut sealed_vote = <Votes<T>>::get(&commitment);
+
+        ensure!(sealed_vote.is_not_revealed(), "vote already revealed");
+        // only voter can reveal their own votes
+        ensure!(sealed_vote.is_owned_by(voter), "only voter can reveal vote");
+        ensure!(<ApplicantStakes<T>>::exists(&vote_for), "vote for non-applicant not allowed");
+
+        let mut salt = salt.clone();
+
+        // Tries to unseal, if salt is invalid will return error
+        sealed_vote.unseal(vote_for, &mut salt, <T as system::Trait>::Hashing::hash)?;
+
+        // Update the revealed vote
+        <Votes<T>>::insert(commitment, sealed_vote);
+
+        Ok(())
+    }
+}
+
+decl_module! {
+    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+        fn deposit_event<T>() = default;
+
+        // No origin so this is a priviledged call
+        fn on_finalise(now: T::BlockNumber) {
+            Self::check_if_stage_is_ending(now);
+        }
+
+        // Member can apply during announcing stage only. On first call a minimum stake will need to be provided.
+        // Member can make subsequent calls during announcing stage to increase their stake.
+        fn apply(origin, stake: BalanceOf<T>) {
+            let sender = ensure_signed(origin)?;
+            ensure!(Self::is_member(sender.clone()), "Only members can apply to be on council");
+
+            let stage = Self::stage();
+            ensure!(Self::stage().is_some(), "election not running");
+
+            let is_announcing = match stage.unwrap() {
+                ElectionStage::Announcing(_) => true,
+                _ => false
+            };
+            ensure!(is_announcing, "election not in announcing stage");
+
+            // minimum stake on first attempt to apply
+            if !<ApplicantStakes<T>>::exists(&sender) {
+                ensure!(stake >= Self::min_council_stake(), "minimum stake must be provided");
+            }
+
+            Self::try_add_applicant(sender.clone(), stake)?;
+
+            Self::deposit_event(RawEvent::Applied(sender));
+        }
+
+        fn vote(origin, commitment: T::Hash, stake: BalanceOf<T>) {
+            let sender = ensure_signed(origin)?;
+            ensure!(Self::is_member(sender.clone()), "Only members can vote for an applicant");
+
+            let stage = Self::stage();
+            ensure!(Self::stage().is_some(), "election not running");
+
+            let is_voting = match stage.unwrap() {
+                ElectionStage::Voting(_) => true,
+                _ => false
+            };
+            ensure!(is_voting, "election not in voting stage");
+
+            ensure!(stake >= Self::min_voting_stake(), "voting stake too low");
+            Self::try_add_vote(sender.clone(), stake, commitment)?;
+            Self::deposit_event(RawEvent::Voted(sender, commitment));
+        }
+
+        fn reveal(origin, commitment: T::Hash, vote: T::AccountId, salt: Vec<u8>) {
+            let sender = ensure_signed(origin)?;
+
+            ensure!(salt.len() <= 32, "salt too large"); // at most 256 bits salt
+
+            let stage = Self::stage();
+            ensure!(Self::stage().is_some(), "election not running");
+
+            let is_revealing = match stage.unwrap() {
+                ElectionStage::Revealing(_) => true,
+                _ => false
+            };
+            ensure!(is_revealing, "election not in revealing stage");
+
+            Self::try_reveal_vote(sender.clone(), commitment, vote.clone(), salt)?;
+            Self::deposit_event(RawEvent::Revealed(sender, commitment, vote));
+        }
+
+        fn set_stage_announcing(ends_at: T::BlockNumber) {
+            ensure!(ends_at > <system::Module<T>>::block_number(), "must end at future block number");
+            <Stage<T>>::put(ElectionStage::Announcing(ends_at));
+        }
+
+        fn set_stage_revealing(ends_at: T::BlockNumber) {
+            ensure!(ends_at > <system::Module<T>>::block_number(), "must end at future block number");
+            <Stage<T>>::put(ElectionStage::Revealing(ends_at));
+        }
+
+        fn set_stage_voting(ends_at: T::BlockNumber) {
+            ensure!(ends_at > <system::Module<T>>::block_number(), "must end at future block number");
+            <Stage<T>>::put(ElectionStage::Voting(ends_at));
+        }
+
+        fn set_param_announcing_period(period: T::BlockNumber) {
+            ensure!(!Self::is_election_running(), "cannot change params during election");
+            ensure!(!period.is_zero(), "period cannot be zero");
+            <AnnouncingPeriod<T>>::put(period);
+        }
+        fn set_param_voting_period(period: T::BlockNumber) {
+            ensure!(!Self::is_election_running(), "cannot change params during election");
+            ensure!(!period.is_zero(), "period cannot be zero");
+            <VotingPeriod<T>>::put(period);
+        }
+        fn set_param_revealing_period(period: T::BlockNumber) {
+            ensure!(!Self::is_election_running(), "cannot change params during election");
+            ensure!(!period.is_zero(), "period cannot be zero");
+            <RevealingPeriod<T>>::put(period);
+        }
+        fn set_param_min_council_stake(amount: BalanceOf<T>) {
+            ensure!(!Self::is_election_running(), "cannot change params during election");
+            <MinCouncilStake<T>>::put(amount);
+        }
+        fn set_param_new_term_duration(duration: T::BlockNumber) {
+            ensure!(!Self::is_election_running(), "cannot change params during election");
+            ensure!(!duration.is_zero(), "new term duration cannot be zero");
+            <NewTermDuration<T>>::put(duration);
+        }
+        fn set_param_council_size(council_size: u32) {
+            ensure!(!Self::is_election_running(), "cannot change params during election");
+            ensure!(council_size > 0, "council size cannot be zero");
+            ensure!(council_size <= Self::candidacy_limit(), "council size cannot greater than candidacy limit");
+            <CouncilSize<T>>::put(council_size);
+        }
+        fn set_param_candidacy_limit(limit: u32) {
+            ensure!(!Self::is_election_running(), "cannot change params during election");
+            ensure!(limit >= Self::council_size(), "candidacy limit cannot be less than council size");
+            <CandidacyLimit<T>>::put(limit);
+        }
+        fn set_param_min_voting_stake(amount: BalanceOf<T>) {
+            ensure!(!Self::is_election_running(), "cannot change params during election");
+            <MinVotingStake<T>>::put(amount);
+        }
+
+        fn force_stop_election() {
+            ensure!(Self::is_election_running(), "only running election can be stopped");
+
+            let mut votes = Vec::new();
+            for commitment in Self::commitments() {
+                votes.push(Self::votes(commitment));
+            }
+
+            // no council gets elected
+            let empty_council = BTreeMap::new();
+
+            Self::teardown_election (
+                &votes,
+                &empty_council,
+                false /* do not unlock transferable stakes */
+            );
+        }
+
+        fn force_start_election() {
+            Self::start_election(<council::Module<T>>::active_council())?;
+        }
+
+        fn set_auto_start (flag: bool) {
+            <AutoStart<T>>::put(flag);
+        }
+
+    }
+}
+
+impl<T: Trait> council::CouncilTermEnded for Module<T> {
+    fn council_term_ended() {
+        if Self::auto_start() {
+            if Self::start_election(<council::Module<T>>::active_council()).is_ok() {
+                // emit ElectionStarted
+            } else {
+                // emit ElectionFailedStart
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::governance::mock::*;
+    use parity_codec::Encode;
+    use runtime_io::with_externalities;
+    use srml_support::*;
+
+    #[test]
+    fn election_starts_when_council_term_ends() {
+        with_externalities(&mut initial_test_ext(), || {
+            System::set_block_number(1);
+
+            assert!(Council::is_term_ended());
+            assert!(Election::stage().is_none());
+
+            <Election as council::CouncilTermEnded>::council_term_ended();
+
+            assert!(Election::stage().is_some());
+        });
+    }
+
+    #[test]
+    fn new_stake_reusing_transferable_works() {
+        {
+            let mut transferable = 0;
+            let additional = 100;
+            let new_stake = Election::new_stake_reusing_transferable(&mut transferable, additional);
+            assert_eq!(new_stake.new, 100);
+            assert_eq!(new_stake.transferred, 0);
+        }
+
+        {
+            let mut transferable = 40;
+            let additional = 60;
+            let new_stake = Election::new_stake_reusing_transferable(&mut transferable, additional);
+            assert_eq!(new_stake.new, 20);
+            assert_eq!(new_stake.transferred, 40);
+            assert_eq!(transferable, 0);
+        }
+
+        {
+            let mut transferable = 1000;
+            let additional = 100;
+            let new_stake = Election::new_stake_reusing_transferable(&mut transferable, additional);
+            assert_eq!(new_stake.new, 0);
+            assert_eq!(new_stake.transferred, 100);
+            assert_eq!(transferable, 900);
+        }
+    }
+
+    #[test]
+    fn check_default_params() {
+        // TODO missing test implementation?
+    }
+
+    #[test]
+    fn should_not_start_new_election_if_already_started() {
+        with_externalities(&mut initial_test_ext(), || {
+            assert_ok!(Election::start_election(vec![]));
+            assert_err!(Election::start_election(vec![]), "election already in progress");
+        });
+    }
+
+    fn assert_announcing_period(expected_period: <Test as system::Trait>::BlockNumber) {
+        assert!(Election::is_election_running(), "Election Stage was not set");
+
+        let election_stage = Election::stage().unwrap();
+
+        match election_stage {
+            election::ElectionStage::Announcing(period) => {
+                assert_eq!(period, expected_period, "Election period not set correctly")
+            }
+            _ => {
+                assert!(false, "Election Stage was not correctly set to Announcing")
+            }
+        }
+    }
+
+    #[test]
+    fn start_election_should_work() {
+        with_externalities(&mut initial_test_ext(), || {
+            System::set_block_number(1);
+            <AnnouncingPeriod<Test>>::put(20);
+            let prev_round = Election::round();
+
+            assert_ok!(Election::start_election(vec![]));
+
+            // election round is bumped
+            assert_eq!(Election::round(), prev_round + 1);
+
+            // we enter the announcing stage for a specified period
+            assert_announcing_period(1 + Election::announcing_period());
+        });
+    }
+
+    #[test]
+    fn init_transferable_stake_should_work () {
+        with_externalities(&mut initial_test_ext(), || {
+
+            let existing_council = vec![
+                Seat {
+                    member: 1,
+                    stake: 100,
+                    backers: vec![
+                        Backer {
+                            member: 2,
+                            stake: 50,
+                        },
+                        Backer {
+                            member: 3,
+                            stake: 40,
+                        },
+                        Backer {
+                            member: 10,
+                            stake: 10,
+                        }]
+                },
+
+                Seat {
+                    member: 2,
+                    stake: 200,
+                    backers: vec![
+                        Backer {
+                            member: 1,
+                            stake: 10,
+                        },
+                        Backer {
+                            member: 3,
+                            stake: 60,
+                        },
+                        Backer {
+                            member: 20,
+                            stake: 20,
+                        }]
+                },
+
+                Seat {
+                    member: 3,
+                    stake: 300,
+                    backers: vec![
+                        Backer {
+                            member: 1,
+                            stake: 20,
+                        },
+                        Backer {
+                            member: 2,
+                            stake: 40,
+                        }]
+                }
+            ];
+
+            Election::initialize_transferable_stakes(existing_council);
+            let mut existing_stake_holders = Election::existing_stake_holders();
+            existing_stake_holders.sort();
+            assert_eq!(existing_stake_holders, vec![1,2,3,10,20]);
+
+            assert_eq!(Election::transferable_stakes(&1).seat, 100);
+            assert_eq!(Election::transferable_stakes(&1).backing, 30);
+
+            assert_eq!(Election::transferable_stakes(&2).seat, 200);
+            assert_eq!(Election::transferable_stakes(&2).backing, 90);
+
+            assert_eq!(Election::transferable_stakes(&3).seat, 300);
+            assert_eq!(Election::transferable_stakes(&3).backing, 100);
+
+            assert_eq!(Election::transferable_stakes(&10).seat, 0);
+            assert_eq!(Election::transferable_stakes(&10).backing, 10);
+
+            assert_eq!(Election::transferable_stakes(&20).seat, 0);
+            assert_eq!(Election::transferable_stakes(&20).backing, 20);
+
+        });
+    }
+
+    #[test]
+    fn try_add_applicant_should_work() {
+        with_externalities(&mut initial_test_ext(), || {
+
+            assert!(Election::applicants().len() == 0);
+
+            let applicant = 20 as u64;
+
+            let starting_balance = 1000 as u32;
+            Balances::set_free_balance(&applicant, starting_balance);
+
+            let stake = 100 as u32;
+
+            assert!(Election::try_add_applicant(applicant, stake).is_ok());
+            assert_eq!(Election::applicants(), vec![applicant]);
+
+            assert_eq!(Election::applicant_stakes(applicant).new, stake);
+            assert_eq!(Election::applicant_stakes(applicant).transferred, 0);
+
+            assert_eq!(Balances::free_balance(&applicant), starting_balance - stake);
+        });
+    }
+
+    #[test]
+    fn increasing_applicant_stake_should_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            let applicant = 20 as u64;
+            let starting_stake = 100 as u32;
+
+            <Applicants<Test>>::put(vec![applicant]);
+            <ApplicantStakes<Test>>::insert(applicant, Stake {
+                new: starting_stake,
+                transferred: 0,
+            });
+
+            let additional_stake = 100 as u32;
+            Balances::set_free_balance(&applicant, additional_stake);
+            assert!(Election::try_add_applicant(applicant, additional_stake).is_ok());
+
+            assert_eq!(Election::applicant_stakes(applicant).new, starting_stake + additional_stake);
+            assert_eq!(Election::applicant_stakes(applicant).transferred, 0)
+        });
+    }
+
+    #[test]
+    fn using_transferable_seat_stake_should_work() {
+        with_externalities(&mut initial_test_ext(), || {
+
+            let applicant = 20 as u64;
+            Balances::set_free_balance(&applicant, 5000);
+
+            <ExistingStakeHolders<Test>>::put(vec![applicant]);
+            save_transferable_stake(applicant, TransferableStake {seat: 1000, backing: 0});
+
+            <Applicants<Test>>::put(vec![applicant]);
+            let starting_stake = Stake {
+                new: 100,
+                transferred: 0,
+            };
+            <ApplicantStakes<Test>>::insert(applicant, starting_stake);
+
+            // transferable stake covers new stake
+            assert!(Election::try_add_applicant(applicant, 600).is_ok());
+            assert_eq!(Election::applicant_stakes(applicant).new, starting_stake.new);
+            assert_eq!(Election::applicant_stakes(applicant).transferred, 600);
+            assert_eq!(Election::transferable_stakes(applicant).seat, 400);
+            assert_eq!(Balances::free_balance(applicant), 5000);
+
+            // all remaining transferable stake is consumed and free balance covers remaining stake
+            assert!(Election::try_add_applicant(applicant, 1000).is_ok());
+            assert_eq!(Election::applicant_stakes(applicant).new, starting_stake.new + 600);
+            assert_eq!(Election::applicant_stakes(applicant).transferred, 1000);
+            assert_eq!(Election::transferable_stakes(applicant).seat, 0);
+            assert_eq!(Balances::free_balance(applicant), 4400);
+
+        });
+    }
+
+    #[test]
+    fn moving_to_voting_without_enough_applicants_should_not_work() {
+        with_externalities(&mut initial_test_ext(), || {
+            System::set_block_number(1);
+            <AnnouncingPeriod<Test>>::put(20);
+            <CouncilSize<Test>>::put(10);
+            Election::move_to_announcing_stage();
+            let round = Election::round();
+
+            // add applicants
+            <Applicants<Test>>::put(vec![10,20,30]);
+            let stake = Stake {
+                new: 10,
+                transferred: 0,
+            };
+
+            let applicants = Election::applicants();
+
+            for applicant in applicants.iter() {
+                <ApplicantStakes<Test>>::insert(applicant, stake);
+            }
+
+            // make sure we are testing the condition that we don't have enough applicants
+            assert!(Election::council_size_usize() > applicants.len());
+
+            // try to move to voting stage
+            let ann_ends = Election::stage_ends_at().unwrap();
+            System::set_block_number(ann_ends);
+            Election::on_announcing_ended();
+
+            // A new round should have been started
+            assert_eq!(Election::round(), round + 1);
+
+            // A new announcing period started
+            assert_announcing_period(ann_ends + Election::announcing_period());
+
+            // applicants list should be unchanged..
+            assert_eq!(Election::applicants(), applicants);
+        });
+    }
+
+    #[test]
+    fn top_applicants_move_to_voting_stage() {
+        with_externalities(&mut initial_test_ext(), || {
+            <Applicants<Test>>::put(vec![10, 20, 30, 40]);
+            let mut applicants = Election::applicants();
+
+            for (i, applicant) in applicants.iter().enumerate() {
+                <ApplicantStakes<Test>>::insert(applicant, Stake {
+                    new: (i * 10) as u32,
+                    transferred: 0,
+                });
+            }
+
+            let rejected = Election::find_least_staked_applicants(&mut applicants, 3);
+            assert_eq!(rejected.to_vec(), vec![10]);
+
+            <Applicants<Test>>::put(vec![40, 30, 20, 10]);
+            let mut applicants = Election::applicants();
+
+            for applicant in applicants.iter() {
+                <ApplicantStakes<Test>>::insert(applicant, Stake {
+                    new: 20 as u32,
+                    transferred: 0,
+                });
+            }
+
+            // stable sort is preserving order when two elements are equivalent
+            let rejected = Election::find_least_staked_applicants(&mut applicants, 3);
+            assert_eq!(rejected.to_vec(), vec![40]);
+        });
+    }
+
+    #[test]
+    fn refunding_applicant_stakes_should_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            Balances::set_free_balance(&1, 1000);
+            Balances::set_free_balance(&2, 2000); Balances::set_reserved_balance(&2, 5000);
+            Balances::set_free_balance(&3, 3000); Balances::set_reserved_balance(&3, 5000);
+
+            <Applicants<Test>>::put(vec![1,2,3]);
+
+            save_transferable_stake(1, TransferableStake {seat: 50, backing: 0});
+            save_transferable_stake(2, TransferableStake {seat: 0, backing: 0});
+            save_transferable_stake(3, TransferableStake {seat: 0, backing: 0});
+
+            <ApplicantStakes<Test>>::insert(1, Stake {
+                new: 100,
+                transferred: 200,
+            });
+
+            <ApplicantStakes<Test>>::insert(2, Stake {
+                new: 300,
+                transferred: 400,
+            });
+
+            <ApplicantStakes<Test>>::insert(3, Stake {
+                new: 500,
+                transferred: 600,
+            });
+
+            Election::drop_applicants(&vec![2,3][..]);
+
+            assert_eq!(Election::applicants(), vec![1]);
+
+            assert_eq!(Election::applicant_stakes(1).new, 100);
+            assert_eq!(Election::applicant_stakes(1).transferred, 200);
+            assert_eq!(Election::transferable_stakes(1).seat, 50);
+            assert_eq!(Balances::free_balance(&1), 1000);
+
+            //assert_eq!(Election::applicant_stakes(2), Default::default());
+            assert!(!<ApplicantStakes<Test>>::exists(2));
+            assert_eq!(Election::transferable_stakes(2).seat, 400);
+            assert_eq!(Balances::free_balance(&2), 2300);
+
+            //assert_eq!(Election::applicant_stakes(3), Default::default());
+            assert!(!<ApplicantStakes<Test>>::exists(3));
+            assert_eq!(Election::transferable_stakes(3).seat, 600);
+            assert_eq!(Balances::free_balance(&3), 3500);
+        });
+    }
+
+    #[test]
+    fn voting_should_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            Balances::set_free_balance(&20, 1000);
+            let payload = vec![10u8];
+            let commitment = <Test as system::Trait>::Hashing::hash(&payload[..]);
+
+            assert!(Election::try_add_vote(20, 100, commitment).is_ok());
+
+            assert_eq!(Election::commitments(), vec![commitment]);
+            assert_eq!(Election::votes(commitment).voter, 20);
+            assert_eq!(Election::votes(commitment).commitment, commitment);
+            assert_eq!(Election::votes(commitment).stake, Stake {
+                new: 100,
+                transferred: 0,
+            });
+            assert_eq!(Balances::free_balance(&20), 900);
+        });
+    }
+
+    fn save_transferable_stake(id: u64, stake: TransferableStake<u32>) {
+        <TransferableStakes<Test>>::insert(id, stake);
+    }
+
+    #[test]
+    fn votes_can_be_covered_by_transferable_stake () {
+        with_externalities(&mut initial_test_ext(), || {
+            Balances::set_free_balance(&20, 1000);
+
+            save_transferable_stake(20, TransferableStake {seat: 0, backing: 500});
+
+            let payload = vec![10u8];
+            let commitment = <Test as system::Trait>::Hashing::hash(&payload[..]);
+
+            assert!(Election::try_add_vote(20, 100, commitment).is_ok());
+
+            assert_eq!(Election::commitments(), vec![commitment]);
+            assert_eq!(Election::votes(commitment).voter, 20);
+            assert_eq!(Election::votes(commitment).commitment, commitment);
+            assert_eq!(Election::votes(commitment).stake, Stake {
+                new: 0,
+                transferred: 100,
+            });
+            assert_eq!(Balances::free_balance(&20), 1000);
+        });
+    }
+
+    #[test]
+    fn voting_without_enough_balance_should_not_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            Balances::set_free_balance(&20, 100);
+
+            save_transferable_stake(20, TransferableStake { seat: 0, backing: 500 });
+
+            let payload = vec![10u8];
+            let commitment = <Test as system::Trait>::Hashing::hash(&payload[..]);
+
+            assert!(Election::try_add_vote(20, 1000, commitment).is_err());
+            assert_eq!(Election::commitments(), vec![]);
+            assert!(!<Votes<Test>>::exists(commitment));
+            assert_eq!(Balances::free_balance(&20), 100);
+        });
+    }
+
+    #[test]
+    fn voting_with_existing_commitment_should_not_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            Balances::set_free_balance(&20, 1000);
+
+            save_transferable_stake(20, TransferableStake { seat: 0, backing: 500});
+
+            let payload = vec![10u8];
+            let commitment = <Test as system::Trait>::Hashing::hash(&payload[..]);
+
+            assert!(Election::try_add_vote(20, 100, commitment).is_ok());
+
+            assert_eq!(Election::commitments(), vec![commitment]);
+            assert_eq!(Election::votes(commitment).voter, 20);
+            assert_eq!(Election::votes(commitment).commitment, commitment);
+            assert_eq!(Election::votes(commitment).stake, Stake {
+                new: 0,
+                transferred: 100,
+            });
+            assert_eq!(Balances::free_balance(&20), 1000);
+
+            assert!(Election::try_add_vote(30, 100, commitment).is_err());
+        });
+    }
+
+    fn make_commitment_for_applicant(applicant: <Test as system::Trait>::AccountId, salt: &mut Vec<u8>) -> <Test as system::Trait>::Hash {
+        let mut payload = applicant.encode();
+        payload.append(salt);
+        <Test as system::Trait>::Hashing::hash(&payload[..])
+    }
+
+    #[test]
+    fn revealing_vote_works () {
+        with_externalities(&mut initial_test_ext(), || {
+            let applicant = 20 as u64;
+            let salt = vec![128u8];
+            let commitment = make_commitment_for_applicant(applicant, &mut salt.clone());
+            let voter = 10 as u64;
+
+            <ApplicantStakes<Test>>::insert(&applicant, Stake {new: 0, transferred: 0});
+
+            <Votes<Test>>::insert(&commitment, SealedVote::new(voter, Stake {
+                new: 100, transferred: 0
+            }, commitment));
+
+            assert!(<Votes<Test>>::get(commitment).is_not_revealed());
+            assert!(Election::try_reveal_vote(voter, commitment, applicant, salt).is_ok());
+            assert_eq!(<Votes<Test>>::get(commitment).get_vote().unwrap(), applicant);
+        });
+    }
+
+    #[test]
+    fn revealing_with_bad_salt_should_not_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            let applicant = 20 as u64;
+            let salt = vec![128u8];
+            let commitment = make_commitment_for_applicant(applicant, &mut salt.clone());
+            let voter = 10 as u64;
+
+            <ApplicantStakes<Test>>::insert(&applicant, Stake {new: 0, transferred: 0});
+
+            <Votes<Test>>::insert(&commitment, SealedVote::new(voter, Stake {
+                new: 100, transferred: 0
+            }, commitment));
+
+            assert!(<Votes<Test>>::get(commitment).is_not_revealed());
+            assert!(Election::try_reveal_vote(voter, commitment, applicant, vec![]).is_err());
+            assert!(<Votes<Test>>::get(commitment).is_not_revealed());
+        });
+    }
+
+    #[test]
+    fn revealing_non_matching_commitment_should_not_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            let applicant = 20 as u64;
+            let salt = vec![128u8];
+            let commitment = make_commitment_for_applicant(100, &mut salt.clone());
+            let voter = 10 as u64;
+
+            <ApplicantStakes<Test>>::insert(&applicant, Stake {new: 0, transferred: 0});
+
+            assert!(Election::try_reveal_vote(voter, commitment, applicant, vec![]).is_err());
+        });
+    }
+
+    #[test]
+    fn revealing_for_non_applicant_should_not_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            let applicant = 20 as u64;
+            let salt = vec![128u8];
+            let commitment = make_commitment_for_applicant(applicant, &mut salt.clone());
+            let voter = 10 as u64;
+
+            <Votes<Test>>::insert(&commitment, SealedVote::new(voter, Stake {
+                new: 100, transferred: 0
+            }, commitment));
+
+            assert!(<Votes<Test>>::get(commitment).is_not_revealed());
+            assert!(Election::try_reveal_vote(voter, commitment, applicant, vec![]).is_err());
+            assert!(<Votes<Test>>::get(commitment).is_not_revealed());
+        });
+    }
+
+    #[test]
+    fn revealing_by_non_committer_should_not_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            let applicant = 20 as u64;
+            let salt = vec![128u8];
+            let commitment = make_commitment_for_applicant(applicant, &mut salt.clone());
+            let voter = 10 as u64;
+            let not_voter = 100 as u64;
+
+            <ApplicantStakes<Test>>::insert(&applicant, Stake {new: 0, transferred: 0});
+
+            <Votes<Test>>::insert(&commitment, SealedVote::new(voter, Stake {
+                new: 100, transferred: 0
+            }, commitment));
+
+            assert!(<Votes<Test>>::get(commitment).is_not_revealed());
+            assert!(Election::try_reveal_vote(not_voter, commitment, applicant, salt).is_err());
+            assert!(<Votes<Test>>::get(commitment).is_not_revealed());
+        });
+    }
+
+    pub fn mock_votes (mock: Vec<(u64, u32, u32, u64)>) -> Vec<SealedVote<u64, Stake<u32>, primitives::H256, u64>> {
+        let commitment = make_commitment_for_applicant(1, &mut vec![0u8]);
+
+        mock.into_iter().map(|(voter, stake_ref, stake_tran, applicant)| SealedVote::new_unsealed(voter as u64, Stake {
+            new: stake_ref as u32, transferred: stake_tran as u32
+        }, commitment, applicant as u64)).collect()
+    }
+
+
+    #[test]
+    fn vote_tallying_should_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            let votes = mock_votes(vec![
+            //  (voter, stake[new], stake[transferred], applicant)
+                (10, 100, 0, 100),
+                (10, 150, 0, 100),
+
+                (10, 500, 0, 200),
+                (20, 200, 0, 200),
+
+                (30, 300, 0, 300),
+                (30, 400, 0, 300),
+            ]);
+
+            let tally = Election::tally_votes(&votes);
+
+            assert_eq!(tally.len(), 3);
+
+            assert_eq!(tally.get(&100).unwrap().member, 100);
+            assert_eq!(tally.get(&100).unwrap().backers, vec![
+                Backer {
+                    member: 10 as u64,
+                    stake: 100 as u32,
+                },
+                Backer {
+                    member: 10 as u64,
+                    stake: 150 as u32,
+                },
+            ]);
+
+            assert_eq!(tally.get(&200).unwrap().member, 200);
+            assert_eq!(tally.get(&200).unwrap().backers, vec![
+                Backer {
+                    member: 10 as u64,
+                    stake: 500 as u32,
+                },
+                Backer {
+                    member: 20 as u64,
+                    stake: 200 as u32,
+                }
+            ]);
+
+            assert_eq!(tally.get(&300).unwrap().member, 300);
+            assert_eq!(tally.get(&300).unwrap().backers, vec![
+                Backer {
+                    member: 30 as u64,
+                    stake: 300 as u32,
+                },
+                Backer {
+                    member: 30 as u64,
+                    stake: 400 as u32,
+                }
+            ]);
+        });
+    }
+
+   #[test]
+    fn filter_top_staked_applicants_should_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            // filter_top_staked depends on order of applicants
+            <Applicants<Test>>::put(vec![100, 200, 300]);
+
+            {
+                let votes = mock_votes(vec![
+                //  (voter, stake[new], stake[transferred], applicant)
+                    (10, 100, 0, 100),
+                    (10, 150, 0, 100),
+
+                    (10, 500, 0, 200),
+                    (20, 200, 0, 200),
+
+                    (30, 300, 0, 300),
+                    (30, 400, 0, 300),
+                ]);
+
+                let mut tally = Election::tally_votes(&votes);
+                assert_eq!(tally.len(), 3);
+                Election::filter_top_staked(&mut tally, 3);
+                assert_eq!(tally.len(), 3);
+            }
+
+            {
+                let votes = mock_votes(vec![
+                //  (voter, stake[new], stake[transferred], applicant)
+                    (10, 100, 0, 100),
+                    (10, 150, 0, 100),
+
+                    (10, 500, 0, 200),
+                    (20, 200, 0, 200),
+
+                    (30, 300, 0, 300),
+                    (30, 400, 0, 300),
+                ]);
+
+                let mut tally = Election::tally_votes(&votes);
+                assert_eq!(tally.len(), 3);
+                Election::filter_top_staked(&mut tally, 2);
+                assert_eq!(tally.len(), 2);
+                assert!(tally.get(&200).is_some());
+                assert!(tally.get(&300).is_some());
+            }
+        });
+    }
+
+    #[test]
+    fn drop_unelected_applicants_should_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            <Applicants<Test>>::put(vec![100, 200, 300]);
+
+            Balances::set_free_balance(&100, 1000); Balances::set_reserved_balance(&100, 1000);
+
+            <ApplicantStakes<Test>>::insert(100, Stake {
+                new: 20 as u32,
+                transferred: 50 as u32,
+            });
+
+            save_transferable_stake(100, TransferableStake {seat:100, backing: 0});
+
+            let mut new_council: BTreeMap<u64, Seat<u64, u32>> = BTreeMap::new();
+            new_council.insert(200 as u64, Seat{ member: 200 as u64, stake: 0 as u32, backers: vec![]});
+            new_council.insert(300 as u64, Seat{ member: 300 as u64, stake: 0 as u32, backers: vec![]});
+
+            Election::drop_unelected_applicants(&new_council);
+
+            // applicant dropped
+            assert_eq!(Election::applicants(), vec![200, 300]);
+            assert!(!<ApplicantStakes<Test>>::exists(100));
+
+            // and refunded
+            assert_eq!(Election::transferable_stakes(100).seat, 150);
+            assert_eq!(Balances::free_balance(&100), 1020);
+            assert_eq!(Balances::reserved_balance(&100), 980);
+        });
+    }
+
+
+    #[test]
+    fn refunding_voting_stakes_should_work () {
+        with_externalities(&mut initial_test_ext(), || {
+            // voters' balances
+            Balances::set_free_balance(&10, 1000); Balances::set_reserved_balance(&10, 5000);
+            Balances::set_free_balance(&20, 2000); Balances::set_reserved_balance(&20, 5000);
+            Balances::set_free_balance(&30, 3000); Balances::set_reserved_balance(&30, 5000);
+
+            save_transferable_stake(10, TransferableStake {seat: 0, backing: 100});
+            save_transferable_stake(20, TransferableStake {seat: 0, backing: 200});
+            save_transferable_stake(30, TransferableStake {seat: 0, backing: 300});
+
+            let votes = mock_votes(vec![
+            //  (voter, stake[new], stake[transferred], applicant)
+                (10, 100, 20, 100),
+                (20, 200, 40, 100),
+                (30, 300, 60, 100),
+
+                (10, 500, 70, 200),
+                (20, 600, 80, 200),
+                (30, 700, 90, 200),
+
+                (10,  800, 100, 300),
+                (20,  900, 120, 300),
+                (30, 1000, 140, 300),
+            ]);
+
+            let mut new_council: BTreeMap<u64, Seat<u64, u32>> = BTreeMap::new();
+            new_council.insert(200 as u64, Seat{ member: 200 as u64, stake: 0 as u32, backers: vec![]});
+            new_council.insert(300 as u64, Seat{ member: 300 as u64, stake: 0 as u32, backers: vec![]});
+
+            Election::refund_voting_stakes(&votes, &new_council);
+
+            assert_eq!(Balances::free_balance(&10), 1100); assert_eq!(Balances::reserved_balance(&10), 4900);
+            assert_eq!(Balances::free_balance(&20), 2200); assert_eq!(Balances::reserved_balance(&20), 4800);
+            assert_eq!(Balances::free_balance(&30), 3300); assert_eq!(Balances::reserved_balance(&30), 4700);
+
+            assert_eq!(Election::transferable_stakes(10).backing, 120);
+            assert_eq!(Election::transferable_stakes(20).backing, 240);
+            assert_eq!(Election::transferable_stakes(30).backing, 360);
+        });
+    }
+
+    #[test]
+    fn unlock_transferable_stakes_should_work () {
+       with_externalities(&mut initial_test_ext(), || {
+            <ExistingStakeHolders<Test>>::put(vec![10,20,30]);
+
+            Balances::set_free_balance(&10, 1000); Balances::set_reserved_balance(&10, 5000);
+            save_transferable_stake(10, TransferableStake {seat: 50, backing: 100});
+
+            Balances::set_free_balance(&20, 2000); Balances::set_reserved_balance(&20, 5000);
+            save_transferable_stake(20, TransferableStake {seat: 60, backing: 200});
+
+            Balances::set_free_balance(&30, 3000); Balances::set_reserved_balance(&30, 5000);
+            save_transferable_stake(30, TransferableStake {seat: 70, backing: 300});
+
+            Election::unlock_transferable_stakes();
+
+            assert_eq!(Balances::free_balance(&10), 1150);
+            assert_eq!(Balances::free_balance(&20), 2260);
+            assert_eq!(Balances::free_balance(&30), 3370);
+       });
+    }
+
+    #[test]
+    fn council_elected_hook_should_work() {
+        with_externalities(&mut initial_test_ext(), || {
+
+            let mut new_council: BTreeMap<u64, Seat<u64, u32>> = BTreeMap::new();
+            new_council.insert(200 as u64, Seat{ member: 200 as u64, stake: 10 as u32, backers: vec![]});
+            new_council.insert(300 as u64, Seat{ member: 300 as u64, stake: 20 as u32, backers: vec![]});
+
+            assert_eq!(Council::active_council().len(), 0);
+
+            let new_council = new_council.into_iter().map(|(_, seat)| seat.clone()).collect();
+            <Test as election::Trait>::CouncilElected::council_elected(new_council, 10);
+
+            assert_eq!(Council::active_council().len(), 2);
+        });
+    }
+
+    #[test]
+    fn simulation() {
+        with_externalities(&mut initial_test_ext(), || {
+            assert_eq!(Council::active_council().len(), 0);
+            assert!(Election::stage().is_none());
+
+            <CouncilSize<Test>>::put(10);
+            <MinCouncilStake<Test>>::put(50);
+            <AnnouncingPeriod<Test>>::put(10);
+            <VotingPeriod<Test>>::put(10);
+            <RevealingPeriod<Test>>::put(10);
+            <CandidacyLimit<Test>>::put(20);
+            <NewTermDuration<Test>>::put(100);
+            <MinVotingStake<Test>>::put(10);
+
+            for i in 1..30 {
+                Balances::set_free_balance(&(i as u64), 50000);
+            }
+
+            System::set_block_number(1);
+            assert_ok!(Election::start_election(vec![]));
+
+            for i in 1..20 {
+                if i < 21 {
+                    assert!(Election::apply(Origin::signed(i), 150).is_ok());
+                } else {
+                    assert!(Election::apply(Origin::signed(i + 1000), 150).is_err()); // not enough free balance
+                    assert!(Election::apply(Origin::signed(i), 20).is_err()); // not enough minimum stake
+                }
+            }
+
+            let n = 1 + Election::announcing_period();
+            System::set_block_number(n);
+            Election::on_finalise(n);
+
+            for i in 1..20 {
+                assert!(Election::vote(Origin::signed(i), make_commitment_for_applicant(i, &mut vec![40u8]), 100).is_ok());
+
+                assert!(Election::vote(Origin::signed(i), make_commitment_for_applicant(i, &mut vec![41u8]), 100).is_ok());
+
+                assert!(Election::vote(Origin::signed(i), make_commitment_for_applicant(i + 1000, &mut vec![42u8]), 100).is_ok());
+            }
+
+            let n = n + Election::voting_period();
+            System::set_block_number(n);
+            Election::on_finalise(n);
+
+            for i in 1..20 {
+                assert!(Election::reveal(Origin::signed(i), make_commitment_for_applicant(i, &mut vec![40u8]), i, vec![40u8]).is_ok());
+                //wrong salt
+                assert!(Election::reveal(Origin::signed(i), make_commitment_for_applicant(i, &mut vec![41u8]), i, vec![]).is_err());
+                //vote not for valid applicant
+                assert!(Election::reveal(Origin::signed(i), make_commitment_for_applicant(i + 1000, &mut vec![42u8]), i + 1000, vec![42u8]).is_err());
+            }
+
+            let n = n + Election::revealing_period();
+            System::set_block_number(n);
+            Election::on_finalise(n);
+
+            assert_eq!(Council::active_council().len(), Election::council_size_usize());
+            for (i, seat) in Council::active_council().iter().enumerate() {
+                assert_eq!(seat.member, (i + 1) as u64);
+            }
+            assert!(Election::stage().is_none());
+
+            // When council term ends.. start a new election.
+            assert_ok!(Election::start_election(vec![]));
+        });
+    }
+}

+ 97 - 0
src/governance/mock.rs

@@ -0,0 +1,97 @@
+#![cfg(test)]
+
+use rstd::prelude::*;
+pub use super::{election, council, proposals, GovernanceCurrency};
+pub use system;
+
+pub use primitives::{H256, Blake2Hasher};
+pub use runtime_primitives::{
+    BuildStorage,
+    traits::{BlakeTwo256, OnFinalise, IdentityLookup},
+    testing::{Digest, DigestItem, Header, UintAuthorityId}
+};
+
+use srml_support::impl_outer_origin;
+
+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 Header = Header;
+    type Event = ();
+    type Log = DigestItem;
+    type Lookup = IdentityLookup<u64>;
+}
+impl timestamp::Trait for Test {
+    type Moment = u64;
+    type OnTimestampSet = ();
+}
+impl consensus::Trait for Test {
+    type SessionKey = UintAuthorityId;
+    type InherentOfflineReport = ();
+    type Log = DigestItem;
+}
+impl council::Trait for Test {
+    type Event = ();
+
+    type CouncilTermEnded = (Election,);
+}
+impl election::Trait for Test {
+    type Event = ();
+
+    type CouncilElected = (Council,);
+}
+impl proposals::Trait for Test {
+    type Event = ();
+}
+impl balances::Trait for Test {
+    type Event = ();
+
+    /// The balance of an account.
+    type Balance = u32;
+
+    /// A function which is invoked when the free-balance has fallen below the existential deposit and
+    /// has been reduced to zero.
+    ///
+    /// Gives a chance to clean up resources associated with the given account.
+    type OnFreeBalanceZero = ();
+
+    /// Handler for when a new account is created.
+    type OnNewAccount = ();
+
+    /// A function that returns true iff a given account can transfer its funds to another account.
+    type EnsureAccountLiquid = ();
+}
+
+impl GovernanceCurrency for Test {
+    type Currency = balances::Module<Self>;
+}
+
+// TODO add a Hook type to capture TriggerElection and CouncilElected hooks
+
+// This function basically just builds a genesis storage key/value store according to
+// our desired mockup.
+pub fn initial_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
+    let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
+
+    runtime_io::TestExternalities::new(t)
+}
+
+pub type Election = election::Module<Test>;
+pub type Council = council::Module<Test>;
+pub type Proposals = proposals::Module<Test>;
+pub type System = system::Module<Test>;
+pub type Balances = balances::Module<Test>;

+ 19 - 0
src/governance/mod.rs

@@ -0,0 +1,19 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use srml_support::traits::{Currency, ArithmeticType};
+use system;
+
+pub mod election;
+pub mod council;
+pub mod proposals;
+
+mod stake;
+mod sealed_vote;
+
+pub trait GovernanceCurrency: system::Trait + Sized {
+    type Currency: ArithmeticType + Currency<<Self as system::Trait>::AccountId, Balance=BalanceOf<Self>>;
+}
+
+pub type BalanceOf<T> = <<T as GovernanceCurrency>::Currency as ArithmeticType>::Type;
+
+mod mock;

+ 1390 - 0
src/governance/proposals.rs

@@ -0,0 +1,1390 @@
+use srml_support::{StorageValue, StorageMap, dispatch::Result, decl_module, decl_event, decl_storage, ensure};
+use srml_support::traits::{Currency};
+use primitives::{storage::well_known_keys};
+use runtime_primitives::traits::{As, Hash, Zero};
+use runtime_io::print;
+use {balances, system::{self, ensure_signed}};
+use rstd::prelude::*;
+
+use super::council;
+pub use super::{ GovernanceCurrency, BalanceOf };
+
+const DEFAULT_APPROVAL_QUORUM: u32 = 60;
+const DEFAULT_MIN_STAKE: u64 = 100;
+const DEFAULT_CANCELLATION_FEE: u64 = 5;
+const DEFAULT_REJECTION_FEE: u64 = 10;
+
+const DEFAULT_VOTING_PERIOD_IN_DAYS: u64 = 10;
+const DEFAULT_VOTING_PERIOD_IN_SECS: u64 = DEFAULT_VOTING_PERIOD_IN_DAYS * 24 * 60 * 60;
+
+const DEFAULT_NAME_MAX_LEN: u32 = 100;
+const DEFAULT_DESCRIPTION_MAX_LEN: u32 = 10_000;
+const DEFAULT_WASM_CODE_MAX_LEN: u32 = 2_000_000;
+
+const MSG_STAKE_IS_TOO_LOW: &str = "Stake is too low";
+const MSG_STAKE_IS_GREATER_THAN_BALANCE: &str = "Balance is too low to be staked";
+const MSG_ONLY_MEMBERS_CAN_PROPOSE: &str = "Only members can make a proposal";
+const MSG_ONLY_COUNCILORS_CAN_VOTE: &str = "Only councilors can vote on proposals";
+const MSG_PROPOSAL_NOT_FOUND: &str = "This proposal does not exist";
+const MSG_PROPOSAL_EXPIRED: &str = "Voting period is expired for this proposal";
+const MSG_PROPOSAL_FINALIZED: &str = "Proposal is finalized already";
+const MSG_YOU_ALREADY_VOTED: &str = "You have already voted on this proposal";
+const MSG_YOU_DONT_OWN_THIS_PROPOSAL: &str = "You do not own this proposal";
+const MSG_PROPOSAL_STATUS_ALREADY_UPDATED: &str = "Proposal status has been updated already";
+const MSG_EMPTY_NAME_PROVIDED: &str = "Proposal cannot have an empty name";
+const MSG_EMPTY_DESCRIPTION_PROVIDED: &str = "Proposal cannot have an empty description";
+const MSG_EMPTY_WASM_CODE_PROVIDED: &str = "Proposal cannot have an empty WASM code";
+const MSG_TOO_LONG_NAME: &str = "Name is too long";
+const MSG_TOO_LONG_DESCRIPTION: &str = "Description is too long";
+const MSG_TOO_LONG_WASM_CODE: &str = "WASM code is too big";
+
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq)]
+pub enum ProposalStatus {
+    /// A new proposal that is available for voting.
+    Active,
+    /// If cancelled by a proposer.
+    Cancelled,
+    /// Not enough votes and voting period expired.
+    Expired,
+    /// To clear the quorum requirement, the percentage of council members with revealed votes
+    /// must be no less than the quorum value for the given proposal type.
+    Approved,
+    Rejected,
+    /// If all revealed votes are slashes, then the proposal is rejected,
+    /// and the proposal stake is slashed.
+    Slashed,
+}
+
+impl Default for ProposalStatus {
+    fn default() -> Self {
+        ProposalStatus::Active
+    }
+}
+
+use self::ProposalStatus::*;
+
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq)]
+pub enum VoteKind {
+    /// Signals presence, but unwillingness to cast judgment on substance of vote.
+    Abstain,
+    /// Pass, an alternative or a ranking, for binary, multiple choice
+    /// and ranked choice propositions, respectively.
+    Approve,
+    /// Against proposal.
+    Reject,
+    /// Against the proposal, and slash proposal stake.
+    Slash,
+}
+
+impl Default for VoteKind {
+    fn default() -> Self {
+        VoteKind::Abstain
+    }
+}
+
+use self::VoteKind::*;
+
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
+/// Proposal for node runtime update.
+pub struct RuntimeUpgradeProposal<AccountId, Balance, BlockNumber, Hash> {
+    id: u32,
+    proposer: AccountId,
+    stake: Balance,
+    name: Vec<u8>,
+    description: Vec<u8>,
+    wasm_hash: Hash,
+    proposed_at: BlockNumber,
+    status: ProposalStatus,
+}
+
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
+pub struct TallyResult<BlockNumber> {
+    proposal_id: u32,
+    abstentions: u32,
+    approvals: u32,
+    rejections: u32,
+    slashes: u32,
+    status: ProposalStatus,
+    finalized_at: BlockNumber,
+}
+
+pub trait Trait: timestamp::Trait + council::Trait + GovernanceCurrency {
+    /// The overarching event type.
+    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
+}
+
+decl_event!(
+    pub enum Event<T>
+    where
+        <T as system::Trait>::Hash,
+        <T as system::Trait>::BlockNumber,
+        <T as system::Trait>::AccountId
+    {
+        // New events
+
+        /// Params:
+        /// * Account id of a member who proposed.
+        /// * Id of a newly created proposal after it was saved in storage.
+        ProposalCreated(AccountId, u32),
+        ProposalCanceled(AccountId, u32),
+        ProposalStatusUpdated(u32, ProposalStatus),
+
+        /// Params:
+        /// * Voter - an account id of a councilor.
+        /// * Id of a proposal.
+        /// * Kind of vote.
+        Voted(AccountId, u32, VoteKind),
+
+        TallyFinalized(TallyResult<BlockNumber>),
+
+        /// * Hash - hash of wasm code of runtime update.
+        RuntimeUpdated(u32, Hash),
+
+        /// Root cancelled proposal
+        ProposalVetoed(u32),
+    }
+);
+
+decl_storage! {
+    trait Store for Module<T: Trait> as Proposals {
+
+        // Parameters (defaut values could be exported to config):
+
+        // TODO rename 'approval_quorum' -> 'quorum_percent' ?!
+        /// A percent (up to 100) of the council participants
+        /// that must vote affirmatively in order to pass.
+        ApprovalQuorum get(approval_quorum) config(): u32 = DEFAULT_APPROVAL_QUORUM;
+
+        /// Minimum amount of a balance to be staked in order to make a proposal.
+        MinStake get(min_stake) config(): BalanceOf<T> =
+            BalanceOf::<T>::sa(DEFAULT_MIN_STAKE);
+
+        /// A fee to be slashed (burn) in case a proposer decides to cancel a proposal.
+        CancellationFee get(cancellation_fee) config(): BalanceOf<T> =
+            BalanceOf::<T>::sa(DEFAULT_CANCELLATION_FEE);
+
+        /// A fee to be slashed (burn) in case a proposal was rejected.
+        RejectionFee get(rejection_fee) config(): BalanceOf<T> =
+            BalanceOf::<T>::sa(DEFAULT_REJECTION_FEE);
+
+        /// Max duration of proposal in blocks until it will be expired if not enough votes.
+        VotingPeriod get(voting_period) config(): T::BlockNumber =
+            T::BlockNumber::sa(DEFAULT_VOTING_PERIOD_IN_SECS /
+            <timestamp::Module<T>>::block_period().as_());
+
+        NameMaxLen get(name_max_len) config(): u32 = DEFAULT_NAME_MAX_LEN;
+        DescriptionMaxLen get(description_max_len) config(): u32 = DEFAULT_DESCRIPTION_MAX_LEN;
+        WasmCodeMaxLen get(wasm_code_max_len) config(): u32 = DEFAULT_WASM_CODE_MAX_LEN;
+
+        // Persistent state (always relevant, changes constantly):
+
+        /// Count of all proposals that have been created.
+        ProposalCount get(proposal_count): u32;
+
+        /// Get proposal details by its id.
+        Proposals get(proposals): map u32 => RuntimeUpgradeProposal<T::AccountId, BalanceOf<T>, T::BlockNumber, T::Hash>;
+
+        /// Ids of proposals that are open for voting (have not been finalized yet).
+        ActiveProposalIds get(active_proposal_ids): Vec<u32> = vec![];
+
+        /// Get WASM code of runtime upgrade by hash of its content.
+        WasmCodeByHash get(wasm_code_by_hash): map T::Hash => Vec<u8>;
+
+        VotesByProposal get(votes_by_proposal): map u32 => Vec<(T::AccountId, VoteKind)>;
+
+        // TODO Rethink: this can be replaced with: votes_by_proposal.find(|vote| vote.0 == proposer)
+        VoteByAccountAndProposal get(vote_by_account_and_proposal): map (T::AccountId, u32) => VoteKind;
+
+        TallyResults get(tally_results): map u32 => TallyResult<T::BlockNumber>;
+    }
+}
+
+decl_module! {
+    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+
+        fn deposit_event<T>() = default;
+
+        /// Use next code to create a proposal from Substrate UI's web console:
+        /// ```js
+        /// post({ sender: runtime.indices.ss58Decode('F7Gh'), call: calls.proposals.createProposal(2500, "0x123", "0x456", "0x789") }).tie(console.log)
+        /// ```
+        fn create_proposal(
+            origin,
+            stake: BalanceOf<T>,
+            name: Vec<u8>,
+            description: Vec<u8>,
+            wasm_code: Vec<u8>
+        ) {
+
+            let proposer = ensure_signed(origin)?;
+            ensure!(Self::is_member(proposer.clone()), MSG_ONLY_MEMBERS_CAN_PROPOSE);
+            ensure!(stake >= Self::min_stake(), MSG_STAKE_IS_TOO_LOW);
+
+            ensure!(!name.is_empty(), MSG_EMPTY_NAME_PROVIDED);
+            ensure!(name.len() as u32 <= Self::name_max_len(), MSG_TOO_LONG_NAME);
+
+            ensure!(!description.is_empty(), MSG_EMPTY_DESCRIPTION_PROVIDED);
+            ensure!(description.len() as u32 <= Self::description_max_len(), MSG_TOO_LONG_DESCRIPTION);
+
+            ensure!(!wasm_code.is_empty(), MSG_EMPTY_WASM_CODE_PROVIDED);
+            ensure!(wasm_code.len() as u32 <= Self::wasm_code_max_len(), MSG_TOO_LONG_WASM_CODE);
+
+            // Lock proposer's stake:
+            T::Currency::reserve(&proposer, stake)
+                .map_err(|_| MSG_STAKE_IS_GREATER_THAN_BALANCE)?;
+
+            let proposal_id = Self::proposal_count() + 1;
+            <ProposalCount<T>>::put(proposal_id);
+
+            // See in substrate repo @ srml/contract/src/wasm/code_cache.rs:73
+            let wasm_hash = T::Hashing::hash(&wasm_code);
+
+            let new_proposal = RuntimeUpgradeProposal {
+                id: proposal_id,
+                proposer: proposer.clone(),
+                stake,
+                name,
+                description,
+                wasm_hash,
+                proposed_at: Self::current_block(),
+                status: Active
+            };
+
+            if !<WasmCodeByHash<T>>::exists(wasm_hash) {
+              <WasmCodeByHash<T>>::insert(wasm_hash, wasm_code);
+            }
+            <Proposals<T>>::insert(proposal_id, new_proposal);
+            <ActiveProposalIds<T>>::mutate(|ids| ids.push(proposal_id));
+            Self::deposit_event(RawEvent::ProposalCreated(proposer.clone(), proposal_id));
+
+            // Auto-vote with Approve if proposer is a councilor:
+            if Self::is_councilor(&proposer) {
+                Self::_process_vote(proposer, proposal_id, Approve)?;
+            }
+        }
+
+        /// Use next code to create a proposal from Substrate UI's web console:
+        /// ```js
+        /// post({ sender: runtime.indices.ss58Decode('F7Gh'), call: calls.proposals.voteOnProposal(1, { option: "Approve", _type: "VoteKind" }) }).tie(console.log)
+        /// ```
+        fn vote_on_proposal(origin, proposal_id: u32, vote: VoteKind) {
+            let voter = ensure_signed(origin)?;
+            ensure!(Self::is_councilor(&voter), MSG_ONLY_COUNCILORS_CAN_VOTE);
+
+            ensure!(<Proposals<T>>::exists(proposal_id), MSG_PROPOSAL_NOT_FOUND);
+            let proposal = Self::proposals(proposal_id);
+
+            ensure!(proposal.status == Active, MSG_PROPOSAL_FINALIZED);
+
+            let not_expired = !Self::is_voting_period_expired(proposal.proposed_at);
+            ensure!(not_expired, MSG_PROPOSAL_EXPIRED);
+
+            let did_not_vote_before = !<VoteByAccountAndProposal<T>>::exists((voter.clone(), proposal_id));
+            ensure!(did_not_vote_before, MSG_YOU_ALREADY_VOTED);
+
+            Self::_process_vote(voter, proposal_id, vote)?;
+        }
+
+        // TODO add 'reason' why a proposer wants to cancel (UX + feedback)?
+        /// Cancel a proposal by its original proposer. Some fee will be withdrawn from his balance.
+        fn cancel_proposal(origin, proposal_id: u32) {
+            let proposer = ensure_signed(origin)?;
+
+            ensure!(<Proposals<T>>::exists(proposal_id), MSG_PROPOSAL_NOT_FOUND);
+            let proposal = Self::proposals(proposal_id);
+
+            ensure!(proposer == proposal.proposer, MSG_YOU_DONT_OWN_THIS_PROPOSAL);
+            ensure!(proposal.status == Active, MSG_PROPOSAL_FINALIZED);
+
+            // Spend some minimum fee on proposer's balance for canceling a proposal
+            let fee = Self::cancellation_fee();
+            let _ = T::Currency::slash_reserved(&proposer, fee);
+
+            // Return unspent part of remaining staked deposit (after taking some fee)
+            let left_stake = proposal.stake - fee;
+            let _ = T::Currency::unreserve(&proposer, left_stake);
+
+            Self::_update_proposal_status(proposal_id, Cancelled)?;
+            Self::deposit_event(RawEvent::ProposalCanceled(proposer, proposal_id));
+        }
+
+        // Called on every block
+        fn on_finalise(n: T::BlockNumber) {
+            if let Err(e) = Self::end_block(n) {
+                print(e);
+            }
+        }
+
+        /// Cancel a proposal and return stake without slashing
+        fn veto_proposal(proposal_id: u32) {
+            ensure!(<Proposals<T>>::exists(proposal_id), MSG_PROPOSAL_NOT_FOUND);
+            let proposal = Self::proposals(proposal_id);
+            ensure!(proposal.status == Active, MSG_PROPOSAL_FINALIZED);
+
+            let _ = T::Currency::unreserve(&proposal.proposer, proposal.stake);
+
+            Self::_update_proposal_status(proposal_id, Cancelled)?;
+
+            Self::deposit_event(RawEvent::ProposalVetoed(proposal_id));
+        }
+
+        fn set_approval_quorum(new_value: u32) {
+            ensure!(new_value > 0, "approval quorom must be greater than zero");
+            <ApprovalQuorum<T>>::put(new_value);
+        }
+    }
+}
+
+impl<T: Trait> Module<T> {
+
+    fn current_block() -> T::BlockNumber {
+        <system::Module<T>>::block_number()
+    }
+
+    // TODO This method should be moved to Membership module once it's created.
+    fn is_member(sender: T::AccountId) -> bool {
+        !T::Currency::free_balance(&sender).is_zero()
+    }
+
+    fn is_councilor(sender: &T::AccountId) -> bool {
+        <council::Module<T>>::is_councilor(sender)
+    }
+
+    fn councilors_count() -> u32 {
+        <council::Module<T>>::active_council().len() as u32
+    }
+
+    fn approval_quorum_seats() -> u32 {
+        (Self::approval_quorum() * Self::councilors_count()) / 100
+    }
+
+    fn is_voting_period_expired(proposed_at: T::BlockNumber) -> bool {
+        Self::current_block() >= proposed_at + Self::voting_period()
+    }
+
+    fn _process_vote(voter: T::AccountId, proposal_id: u32, vote: VoteKind) -> Result {
+        let new_vote = (voter.clone(), vote.clone());
+        if <VotesByProposal<T>>::exists(proposal_id) {
+            // Append a new vote to other votes on this proposal:
+            <VotesByProposal<T>>::mutate(proposal_id, |votes| votes.push(new_vote));
+        } else {
+            // This is the first vote on this proposal:
+            <VotesByProposal<T>>::insert(proposal_id, vec![new_vote]);
+        }
+        <VoteByAccountAndProposal<T>>::insert((voter.clone(), proposal_id), &vote);
+        Self::deposit_event(RawEvent::Voted(voter, proposal_id, vote));
+        Ok(())
+    }
+
+    fn end_block(now: T::BlockNumber) -> Result {
+
+        // TODO refactor this method
+
+        // TODO iterate over not expired proposals and tally
+
+          Self::tally()?;
+          // TODO approve or reject a proposal
+
+        Ok(())
+    }
+
+    /// Get the voters for the current proposal.
+    pub fn tally(/* proposal_id: u32 */) -> Result {
+
+        let councilors: u32 = Self::councilors_count();
+        let quorum: u32 = Self::approval_quorum_seats();
+
+        for &proposal_id in Self::active_proposal_ids().iter() {
+            let votes = Self::votes_by_proposal(proposal_id);
+            let mut abstentions: u32 = 0;
+            let mut approvals: u32 = 0;
+            let mut rejections: u32 = 0;
+            let mut slashes: u32 = 0;
+
+            for (_, vote) in votes.iter() {
+                match vote {
+                    Abstain => abstentions += 1,
+                    Approve => approvals += 1,
+                    Reject => rejections += 1,
+                    Slash => slashes += 1,
+                }
+            }
+
+            let proposal = Self::proposals(proposal_id);
+            let is_expired = Self::is_voting_period_expired(proposal.proposed_at);
+
+            // We need to check that the council is not empty because otherwise,
+            // if there is no votes on a proposal it will be counted as if
+            // all 100% (zero) councilors voted on the proposal and should be approved.
+
+            let non_empty_council = councilors > 0;
+            let all_councilors_voted = non_empty_council && votes.len() as u32 == councilors;
+            let all_councilors_slashed = non_empty_council && slashes == councilors;
+            let quorum_reached = quorum > 0 && approvals >= quorum;
+
+            // Don't approve a proposal right after quorum reached
+            // if not all councilors casted their votes.
+            // Instead let other councilors cast their vote
+            // up until the proposal's expired.
+
+            let new_status: Option<ProposalStatus> =
+                if all_councilors_slashed {
+                    Some(Slashed)
+                } else if all_councilors_voted {
+                    if quorum_reached {
+                        Some(Approved)
+                    } else {
+                        Some(Rejected)
+                    }
+                } else if is_expired {
+                    if quorum_reached {
+                        Some(Approved)
+                    } else {
+                        // Proposal has been expired and quorum not reached.
+                        Some(Expired)
+                    }
+                } else {
+                    // Councilors still have time to vote on this proposal.
+                    None
+                };
+
+            // TODO move next block outside of tally to 'end_block'
+            if let Some(status) = new_status {
+                Self::_update_proposal_status(proposal_id, status.clone())?;
+                let tally_result = TallyResult {
+                    proposal_id,
+                    abstentions,
+                    approvals,
+                    rejections,
+                    slashes,
+                    status,
+                    finalized_at: Self::current_block(),
+                };
+                <TallyResults<T>>::insert(proposal_id, &tally_result);
+                Self::deposit_event(RawEvent::TallyFinalized(tally_result));
+            }
+        }
+
+        Ok(())
+    }
+
+    /// Updates proposal status and removes proposal from active ids.
+    fn _update_proposal_status(proposal_id: u32, new_status: ProposalStatus) -> Result {
+        let all_active_ids = Self::active_proposal_ids();
+        let all_len = all_active_ids.len();
+        let other_active_ids: Vec<u32> = all_active_ids
+            .into_iter()
+            .filter(|&id| id != proposal_id)
+            .collect();
+
+        let not_found_in_active = other_active_ids.len() == all_len;
+        if not_found_in_active {
+            // Seems like this proposal's status has been updated and removed from active.
+            Err(MSG_PROPOSAL_STATUS_ALREADY_UPDATED)
+        } else {
+            let pid = proposal_id.clone();
+            match new_status {
+                Slashed => Self::_slash_proposal(pid)?,
+                Rejected | Expired => Self::_reject_proposal(pid)?,
+                Approved => Self::_approve_proposal(pid)?,
+                Active | Cancelled => { /* nothing */ },
+            }
+            <ActiveProposalIds<T>>::put(other_active_ids);
+            <Proposals<T>>::mutate(proposal_id, |p| p.status = new_status.clone());
+            Self::deposit_event(RawEvent::ProposalStatusUpdated(proposal_id, new_status));
+            Ok(())
+        }
+    }
+
+    /// Slash a proposal. The staked deposit will be slashed.
+    fn _slash_proposal(proposal_id: u32) -> Result {
+        let proposal = Self::proposals(proposal_id);
+
+        // Slash proposer's stake:
+        let _ = T::Currency::slash_reserved(&proposal.proposer, proposal.stake);
+
+        Ok(())
+    }
+
+    /// Reject a proposal. The staked deposit will be returned to a proposer.
+    fn _reject_proposal(proposal_id: u32) -> Result {
+        let proposal = Self::proposals(proposal_id);
+        let proposer = proposal.proposer;
+
+        // Spend some minimum fee on proposer's balance to prevent spamming attacks:
+        let fee = Self::rejection_fee();
+        let _ = T::Currency::slash_reserved(&proposer, fee);
+
+        // Return unspent part of remaining staked deposit (after taking some fee):
+        let left_stake = proposal.stake - fee;
+        let _ = T::Currency::unreserve(&proposer, left_stake);
+
+        Ok(())
+    }
+
+    /// Approve a proposal. The staked deposit will be returned.
+    fn _approve_proposal(proposal_id: u32) -> Result {
+        let proposal = Self::proposals(proposal_id);
+        let wasm_code = Self::wasm_code_by_hash(proposal.wasm_hash);
+
+        // Return staked deposit to proposer:
+        let _ = T::Currency::unreserve(&proposal.proposer, proposal.stake);
+
+        // Update wasm code of node's runtime:
+        <consensus::Module<T>>::set_code(wasm_code)?;
+
+        Self::deposit_event(RawEvent::RuntimeUpdated(proposal_id, proposal.wasm_hash));
+
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+    use runtime_io::with_externalities;
+    use primitives::{H256, Blake2Hasher};
+    // The testing primitives are very useful for avoiding having to work with signatures
+    // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
+    use runtime_primitives::{
+        BuildStorage,
+        traits::{BlakeTwo256, OnFinalise, IdentityLookup},
+        testing::{Digest, DigestItem, Header, UintAuthorityId}
+    };
+    use system::{EventRecord, Phase};
+    use srml_support::*;
+
+    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 consensus::Trait for Test {
+        type SessionKey = UintAuthorityId;
+        type InherentOfflineReport = ();
+        type Log = DigestItem;
+    }
+
+    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<u64>;
+        type Header = Header;
+        type Event = ();
+        type Log = DigestItem;
+    }
+
+    impl balances::Trait for Test {
+        type Balance = u64;
+        type OnFreeBalanceZero = ();
+        type OnNewAccount = ();
+        type EnsureAccountLiquid = ();
+        type Event = ();
+    }
+
+    impl timestamp::Trait for Test {
+        type Moment = u64;
+        type OnTimestampSet = ();
+    }
+
+    impl council::Trait for Test {
+        type Event = ();
+        type CouncilTermEnded = ();
+    }
+
+    impl GovernanceCurrency for Test {
+        type Currency = balances::Module<Self>;
+    }
+
+    impl Trait for Test {
+        type Event = ();
+    }
+
+    type System = system::Module<Test>;
+    type Balances = balances::Module<Test>;
+    type Proposals = Module<Test>;
+
+    const COUNCILOR1: u64 = 1;
+    const COUNCILOR2: u64 = 2;
+    const COUNCILOR3: u64 = 3;
+    const COUNCILOR4: u64 = 4;
+    const COUNCILOR5: u64 = 5;
+
+    const PROPOSER1: u64 = 11;
+    const PROPOSER2: u64 = 12;
+
+    const NOT_COUNCILOR: u64 = 22;
+
+    const ALL_COUNCILORS: [u64; 5] = [
+        COUNCILOR1,
+        COUNCILOR2,
+        COUNCILOR3,
+        COUNCILOR4,
+        COUNCILOR5
+    ];
+
+    // TODO Figure out how to test Events in test... (low priority)
+    // mod proposals {
+    //     pub use ::Event;
+    // }
+    // impl_outer_event!{
+    //     pub enum TestEvent for Test {
+    //         balances<T>,system<T>,proposals<T>,
+    //     }
+    // }
+
+    // This function basically just builds a genesis storage key/value store according to
+    // our desired mockup.
+    fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
+        let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
+        // We use default for brevity, but you can configure as desired if needed.
+        t.extend(balances::GenesisConfig::<Test>::default().build_storage().unwrap().0);
+
+        let council_mock: council::Seats<u64, u64> =
+            ALL_COUNCILORS.iter().map(|&c| council::Seat {
+                member: c,
+                stake: 0u64,
+                backers: vec![],
+            }).collect();
+
+        t.extend(council::GenesisConfig::<Test>{
+            active_council: council_mock,
+            term_ends_at: 0,
+        }.build_storage().unwrap().0);
+
+        // t.extend(GenesisConfig::<Test>{
+        //     // Here we can override defaults.
+        // }.build_storage().unwrap().0);
+
+        t.into()
+    }
+
+    /// A shortcut to get minimum stake in tests.
+    fn min_stake() -> u64 {
+        Proposals::min_stake()
+    }
+
+    /// A shortcut to get cancellation fee in tests.
+    fn cancellation_fee() -> u64 {
+        Proposals::cancellation_fee()
+    }
+
+    /// A shortcut to get rejection fee in tests.
+    fn rejection_fee() -> u64 {
+        Proposals::rejection_fee()
+    }
+
+    /// Initial balance of Proposer 1.
+    fn initial_balance() -> u64 {
+        (min_stake() as f64 * 2.5) as u64
+    }
+
+    fn name() -> Vec<u8> {
+        b"Proposal Name".to_vec()
+    }
+
+    fn description() -> Vec<u8> {
+        b"Proposal Description".to_vec()
+    }
+
+    fn wasm_code() -> Vec<u8> {
+        b"Proposal Wasm Code".to_vec()
+    }
+
+    fn _create_default_proposal() -> Result {
+        _create_proposal(None, None, None, None, None)
+    }
+
+    fn _create_proposal(
+        origin: Option<u64>,
+        stake: Option<u64>,
+        name: Option<Vec<u8>>,
+        description: Option<Vec<u8>>,
+        wasm_code: Option<Vec<u8>>
+    ) -> Result {
+        Proposals::create_proposal(
+            Origin::signed(origin.unwrap_or(PROPOSER1)),
+            stake.unwrap_or(min_stake()),
+            name.unwrap_or(self::name()),
+            description.unwrap_or(self::description()),
+            wasm_code.unwrap_or(self::wasm_code())
+        )
+    }
+
+    fn get_runtime_code() -> Option<Vec<u8>> {
+        storage::unhashed::get_raw(well_known_keys::CODE)
+    }
+
+    macro_rules! assert_runtime_code_empty {
+        () => { assert_eq!(get_runtime_code(), None) }
+    }
+
+    macro_rules! assert_runtime_code {
+        ($code:expr) => { assert_eq!(get_runtime_code(), Some($code)) }
+    }
+
+    #[test]
+    fn check_default_values() {
+        with_externalities(&mut new_test_ext(), || {
+            assert_eq!(Proposals::approval_quorum(), DEFAULT_APPROVAL_QUORUM);
+            assert_eq!(Proposals::min_stake(), DEFAULT_MIN_STAKE);
+            assert_eq!(Proposals::cancellation_fee(), DEFAULT_CANCELLATION_FEE);
+            assert_eq!(Proposals::rejection_fee(), DEFAULT_REJECTION_FEE);
+            assert_eq!(Proposals::name_max_len(), DEFAULT_NAME_MAX_LEN);
+            assert_eq!(Proposals::description_max_len(), DEFAULT_DESCRIPTION_MAX_LEN);
+            assert_eq!(Proposals::wasm_code_max_len(), DEFAULT_WASM_CODE_MAX_LEN);
+            assert_eq!(Proposals::proposal_count(), 0);
+            assert!(Proposals::active_proposal_ids().is_empty());
+        });
+    }
+
+    #[test]
+    fn member_create_proposal() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+            assert_eq!(Proposals::active_proposal_ids().len(), 1);
+            assert_eq!(Proposals::active_proposal_ids()[0], 1);
+
+            let wasm_hash = BlakeTwo256::hash(&wasm_code());
+            let expected_proposal = RuntimeUpgradeProposal {
+                id: 1,
+                proposer: PROPOSER1,
+                stake: min_stake(),
+                name: name(),
+                description: description(),
+                wasm_hash,
+                proposed_at: 1,
+                status: Active
+            };
+            assert_eq!(Proposals::proposals(1), expected_proposal);
+
+            // Check that stake amount has been locked on proposer's balance:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - min_stake());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), min_stake());
+
+            // TODO expect event ProposalCreated(AccountId, u32)
+        });
+    }
+
+    #[test]
+    fn not_member_cannot_create_proposal() {
+        with_externalities(&mut new_test_ext(), || {
+            // In this test a proposer has an empty balance
+            // thus he is not considered as a member.
+            assert_eq!(_create_default_proposal(),
+                Err(MSG_ONLY_MEMBERS_CAN_PROPOSE));
+        });
+    }
+
+    #[test]
+    fn cannot_create_proposal_with_small_stake() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_eq!(_create_proposal(
+                None, Some(min_stake() - 1), None, None, None),
+                Err(MSG_STAKE_IS_TOO_LOW));
+
+            // Check that balances remain unchanged afer a failed attempt to create a proposal:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+        });
+    }
+
+    #[test]
+    fn cannot_create_proposal_when_stake_is_greater_than_balance() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_eq!(_create_proposal(
+                None, Some(initial_balance() + 1), None, None, None),
+                Err(MSG_STAKE_IS_GREATER_THAN_BALANCE));
+
+            // Check that balances remain unchanged afer a failed attempt to create a proposal:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+        });
+    }
+
+    #[test]
+    fn cannot_create_proposal_with_empty_values() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            // Empty name:
+            assert_eq!(_create_proposal(
+                None, None, Some(vec![]), None, None),
+                Err(MSG_EMPTY_NAME_PROVIDED));
+
+            // Empty description:
+            assert_eq!(_create_proposal(
+                None, None, None, Some(vec![]), None),
+                Err(MSG_EMPTY_DESCRIPTION_PROVIDED));
+
+            // Empty WASM code:
+            assert_eq!(_create_proposal(
+                None, None, None, None, Some(vec![])),
+                Err(MSG_EMPTY_WASM_CODE_PROVIDED));
+        });
+    }
+
+    #[test]
+    fn cannot_create_proposal_with_too_long_values() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            // Too long name:
+            assert_eq!(_create_proposal(
+                None, None, Some(too_long_name()), None, None),
+                Err(MSG_TOO_LONG_NAME));
+
+            // Too long description:
+            assert_eq!(_create_proposal(
+                None, None, None, Some(too_long_description()), None),
+                Err(MSG_TOO_LONG_DESCRIPTION));
+
+            // Too long WASM code:
+            assert_eq!(_create_proposal(
+                None, None, None, None, Some(too_long_wasm_code())),
+                Err(MSG_TOO_LONG_WASM_CODE));
+        });
+    }
+
+    fn too_long_name() -> Vec<u8> {
+        vec![65; Proposals::name_max_len() as usize + 1]
+    }
+
+    fn too_long_description() -> Vec<u8> {
+        vec![65; Proposals::description_max_len() as usize + 1]
+    }
+
+    fn too_long_wasm_code() -> Vec<u8> {
+        vec![65; Proposals::wasm_code_max_len() as usize + 1]
+    }
+
+    // -------------------------------------------------------------------
+    // Cancellation
+
+    #[test]
+    fn owner_cancel_proposal() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+            assert_ok!(Proposals::cancel_proposal(Origin::signed(PROPOSER1), 1));
+            assert_eq!(Proposals::proposals(1).status, Cancelled);
+            assert!(Proposals::active_proposal_ids().is_empty());
+
+            // Check that proposer's balance reduced by cancellation fee and other part of his stake returned to his balance:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - cancellation_fee());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+
+            // TODO expect event ProposalCancelled(AccountId, u32)
+        });
+    }
+
+    #[test]
+    fn owner_cannot_cancel_proposal_if_its_finalized() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+            assert_ok!(Proposals::cancel_proposal(Origin::signed(PROPOSER1), 1));
+            assert_eq!(Proposals::proposals(1).status, Cancelled);
+
+            // Get balances updated after cancelling a proposal:
+            let updated_free_balance = Balances::free_balance(PROPOSER1);
+            let updated_reserved_balance = Balances::reserved_balance(PROPOSER1);
+
+            assert_eq!(Proposals::cancel_proposal(Origin::signed(PROPOSER1), 1),
+                Err(MSG_PROPOSAL_FINALIZED));
+
+            // Check that proposer's balance and locked stake haven't been changed:
+            assert_eq!(Balances::free_balance(PROPOSER1), updated_free_balance);
+            assert_eq!(Balances::reserved_balance(PROPOSER1), updated_reserved_balance);
+        });
+    }
+
+    #[test]
+    fn not_owner_cannot_cancel_proposal() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::set_free_balance(&PROPOSER2, initial_balance());
+            Balances::increase_total_stake_by(initial_balance() * 2);
+            assert_ok!(_create_default_proposal());
+            assert_eq!(Proposals::cancel_proposal(Origin::signed(PROPOSER2), 1),
+                Err(MSG_YOU_DONT_OWN_THIS_PROPOSAL));
+        });
+    }
+
+    // -------------------------------------------------------------------
+    // Voting
+
+    #[test]
+    fn councilor_vote_on_proposal() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+            assert_ok!(_create_default_proposal());
+
+            assert_ok!(Proposals::vote_on_proposal(
+                Origin::signed(COUNCILOR1), 1, Approve));
+
+            // Check that a vote has been saved:
+            assert_eq!(Proposals::votes_by_proposal(1), vec![(COUNCILOR1, Approve)]);
+            assert_eq!(Proposals::vote_by_account_and_proposal((COUNCILOR1, 1)), Approve);
+
+            // TODO expect event Voted(PROPOSER1, 1, Approve)
+        });
+    }
+
+    #[test]
+    fn councilor_cannot_vote_on_proposal_twice() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+            assert_ok!(_create_default_proposal());
+
+            assert_ok!(Proposals::vote_on_proposal(
+                Origin::signed(COUNCILOR1), 1, Approve));
+            assert_eq!(Proposals::vote_on_proposal(
+                Origin::signed(COUNCILOR1), 1, Approve),
+                Err(MSG_YOU_ALREADY_VOTED));
+        });
+    }
+
+    #[test]
+    fn autovote_with_approve_when_councilor_creates_proposal() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&COUNCILOR1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+            assert_ok!(_create_proposal(
+                Some(COUNCILOR1), None, None, None, None
+            ));
+
+            // Check that a vote has been sent automatically,
+            // such as the proposer is a councilor:
+            assert_eq!(Proposals::votes_by_proposal(1), vec![(COUNCILOR1, Approve)]);
+            assert_eq!(Proposals::vote_by_account_and_proposal((COUNCILOR1, 1)), Approve);
+        });
+    }
+
+    #[test]
+    fn not_councilor_cannot_vote_on_proposal() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+            assert_ok!(_create_default_proposal());
+            assert_eq!(Proposals::vote_on_proposal(
+                Origin::signed(NOT_COUNCILOR), 1, Approve),
+                Err(MSG_ONLY_COUNCILORS_CAN_VOTE));
+        });
+    }
+
+    #[test]
+    fn councilor_cannot_vote_on_proposal_if_it_has_been_cancelled() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+            assert_ok!(_create_default_proposal());
+            assert_ok!(Proposals::cancel_proposal(Origin::signed(PROPOSER1), 1));
+            assert_eq!(Proposals::vote_on_proposal(
+                Origin::signed(COUNCILOR1), 1, Approve),
+                Err(MSG_PROPOSAL_FINALIZED));
+        });
+    }
+
+    #[test]
+    fn councilor_cannot_vote_on_proposal_if_tally_has_been_finalized() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+
+            // All councilors vote with 'Approve' on proposal:
+            let mut expected_votes: Vec<(u64, VoteKind)> = vec![];
+            for &councilor in ALL_COUNCILORS.iter() {
+                expected_votes.push((councilor, Approve));
+                assert_ok!(Proposals::vote_on_proposal(Origin::signed(councilor), 1, Approve));
+                assert_eq!(Proposals::vote_by_account_and_proposal((councilor, 1)), Approve);
+            }
+            assert_eq!(Proposals::votes_by_proposal(1), expected_votes);
+
+            System::set_block_number(2);
+            Proposals::on_finalise(2);
+
+            assert!(Proposals::active_proposal_ids().is_empty());
+            assert_eq!(Proposals::proposals(1).status, Approved);
+
+            // Try to vote on finalized proposal:
+            assert_eq!(Proposals::vote_on_proposal(
+                Origin::signed(COUNCILOR1), 1, Reject),
+                Err(MSG_PROPOSAL_FINALIZED));
+        });
+    }
+
+    // -------------------------------------------------------------------
+    // Tally + Outcome:
+
+    #[test]
+    fn approve_proposal_when_all_councilors_approved_it() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+
+            // All councilors approved:
+            let mut expected_votes: Vec<(u64, VoteKind)> = vec![];
+            for &councilor in ALL_COUNCILORS.iter() {
+                expected_votes.push((councilor, Approve));
+                assert_ok!(Proposals::vote_on_proposal(Origin::signed(councilor), 1, Approve));
+                assert_eq!(Proposals::vote_by_account_and_proposal((councilor, 1)), Approve);
+            }
+            assert_eq!(Proposals::votes_by_proposal(1), expected_votes);
+
+            assert_runtime_code_empty!();
+
+            System::set_block_number(2);
+            Proposals::on_finalise(2);
+
+            // Check that runtime code has been updated after proposal approved.
+            assert_runtime_code!(wasm_code());
+
+            assert!(Proposals::active_proposal_ids().is_empty());
+            assert_eq!(Proposals::proposals(1).status, Approved);
+            assert_eq!(Proposals::tally_results(1), TallyResult {
+                proposal_id: 1,
+                abstentions: 0,
+                approvals: ALL_COUNCILORS.len() as u32,
+                rejections: 0,
+                slashes: 0,
+                status: Approved,
+                finalized_at: 2
+            });
+
+            // Check that proposer's stake has been added back to his balance:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+
+            // TODO expect event ProposalStatusUpdated(1, Approved)
+        });
+    }
+
+    #[test]
+    fn approve_proposal_when_all_councilors_voted_and_only_quorum_approved() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+
+            // Only a quorum of councilors approved, others rejected:
+            let councilors = Proposals::councilors_count();
+            let approvals = Proposals::approval_quorum_seats();
+            let rejections = councilors - approvals;
+            for i in 0..councilors as usize {
+                let vote = if (i as u32) < approvals { Approve } else { Reject };
+                assert_ok!(Proposals::vote_on_proposal(
+                    Origin::signed(ALL_COUNCILORS[i]), 1, vote));
+            }
+            assert_eq!(Proposals::votes_by_proposal(1).len() as u32, councilors);
+
+            assert_runtime_code_empty!();
+
+            System::set_block_number(2);
+            Proposals::on_finalise(2);
+
+            // Check that runtime code has been updated after proposal approved.
+            assert_runtime_code!(wasm_code());
+
+            assert!(Proposals::active_proposal_ids().is_empty());
+            assert_eq!(Proposals::proposals(1).status, Approved);
+            assert_eq!(Proposals::tally_results(1), TallyResult {
+                proposal_id: 1,
+                abstentions: 0,
+                approvals: approvals,
+                rejections: rejections,
+                slashes: 0,
+                status: Approved,
+                finalized_at: 2
+            });
+
+            // Check that proposer's stake has been added back to his balance:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+
+            // TODO expect event ProposalStatusUpdated(1, Approved)
+        });
+    }
+
+    #[test]
+    fn approve_proposal_when_voting_period_expired_if_only_quorum_voted() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+
+            // Only quorum of councilors approved, other councilors didn't vote:
+            let approvals = Proposals::approval_quorum_seats();
+            for i in 0..approvals as usize {
+                let vote = if (i as u32) < approvals { Approve } else { Slash };
+                assert_ok!(Proposals::vote_on_proposal(
+                    Origin::signed(ALL_COUNCILORS[i]), 1, vote));
+            }
+            assert_eq!(Proposals::votes_by_proposal(1).len() as u32, approvals);
+
+            assert_runtime_code_empty!();
+
+            let expiration_block = System::block_number() + Proposals::voting_period();
+            System::set_block_number(2);
+            Proposals::on_finalise(2);
+
+            // Check that runtime code has NOT been updated yet,
+            // because not all councilors voted and voting period is not expired yet.
+            assert_runtime_code_empty!();
+
+            System::set_block_number(expiration_block);
+            Proposals::on_finalise(expiration_block);
+
+            // Check that runtime code has been updated after proposal approved.
+            assert_runtime_code!(wasm_code());
+
+            assert!(Proposals::active_proposal_ids().is_empty());
+            assert_eq!(Proposals::proposals(1).status, Approved);
+            assert_eq!(Proposals::tally_results(1), TallyResult {
+                proposal_id: 1,
+                abstentions: 0,
+                approvals: approvals,
+                rejections: 0,
+                slashes: 0,
+                status: Approved,
+                finalized_at: expiration_block
+            });
+
+            // Check that proposer's stake has been added back to his balance:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+
+            // TODO expect event ProposalStatusUpdated(1, Approved)
+        });
+    }
+
+    #[test]
+    fn reject_proposal_when_all_councilors_voted_and_quorum_not_reached() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+
+            // Less than a quorum of councilors approved, while others abstained:
+            let councilors = Proposals::councilors_count();
+            let approvals = Proposals::approval_quorum_seats() - 1;
+            let abstentions = councilors - approvals;
+            for i in 0..councilors as usize {
+                let vote = if (i as u32) < approvals { Approve } else { Abstain };
+                assert_ok!(Proposals::vote_on_proposal(
+                    Origin::signed(ALL_COUNCILORS[i]), 1, vote));
+            }
+            assert_eq!(Proposals::votes_by_proposal(1).len() as u32, councilors);
+
+            assert_runtime_code_empty!();
+
+            System::set_block_number(2);
+            Proposals::on_finalise(2);
+
+            // Check that runtime code has NOT been updated after proposal slashed.
+            assert_runtime_code_empty!();
+
+            assert!(Proposals::active_proposal_ids().is_empty());
+            assert_eq!(Proposals::proposals(1).status, Rejected);
+            assert_eq!(Proposals::tally_results(1), TallyResult {
+                proposal_id: 1,
+                abstentions: abstentions,
+                approvals: approvals,
+                rejections: 0,
+                slashes: 0,
+                status: Rejected,
+                finalized_at: 2
+            });
+
+            // Check that proposer's balance reduced by burnt stake:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - rejection_fee());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+
+            // TODO expect event ProposalStatusUpdated(1, Rejected)
+        });
+    }
+
+    #[test]
+    fn reject_proposal_when_all_councilors_rejected_it() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+
+            // All councilors rejected:
+            let mut expected_votes: Vec<(u64, VoteKind)> = vec![];
+            for &councilor in ALL_COUNCILORS.iter() {
+                expected_votes.push((councilor, Reject));
+                assert_ok!(Proposals::vote_on_proposal(Origin::signed(councilor), 1, Reject));
+                assert_eq!(Proposals::vote_by_account_and_proposal((councilor, 1)), Reject);
+            }
+            assert_eq!(Proposals::votes_by_proposal(1), expected_votes);
+
+            assert_runtime_code_empty!();
+
+            System::set_block_number(2);
+            Proposals::on_finalise(2);
+
+            // Check that runtime code has NOT been updated after proposal rejected.
+            assert_runtime_code_empty!();
+
+            assert!(Proposals::active_proposal_ids().is_empty());
+            assert_eq!(Proposals::proposals(1).status, Rejected);
+            assert_eq!(Proposals::tally_results(1), TallyResult {
+                proposal_id: 1,
+                abstentions: 0,
+                approvals: 0,
+                rejections: ALL_COUNCILORS.len() as u32,
+                slashes: 0,
+                status: Rejected,
+                finalized_at: 2
+            });
+
+            // Check that proposer's balance reduced by burnt stake:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - rejection_fee());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+
+            // TODO expect event ProposalStatusUpdated(1, Rejected)
+        });
+    }
+
+    #[test]
+    fn slash_proposal_when_all_councilors_slashed_it() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+
+            // All councilors slashed:
+            let mut expected_votes: Vec<(u64, VoteKind)> = vec![];
+            for &councilor in ALL_COUNCILORS.iter() {
+                expected_votes.push((councilor, Slash));
+                assert_ok!(Proposals::vote_on_proposal(Origin::signed(councilor), 1, Slash));
+                assert_eq!(Proposals::vote_by_account_and_proposal((councilor, 1)), Slash);
+            }
+            assert_eq!(Proposals::votes_by_proposal(1), expected_votes);
+
+            assert_runtime_code_empty!();
+
+            System::set_block_number(2);
+            Proposals::on_finalise(2);
+
+            // Check that runtime code has NOT been updated after proposal slashed.
+            assert_runtime_code_empty!();
+
+            assert!(Proposals::active_proposal_ids().is_empty());
+            assert_eq!(Proposals::proposals(1).status, Slashed);
+            assert_eq!(Proposals::tally_results(1), TallyResult {
+                proposal_id: 1,
+                abstentions: 0,
+                approvals: 0,
+                rejections: 0,
+                slashes: ALL_COUNCILORS.len() as u32,
+                status: Slashed,
+                finalized_at: 2
+            });
+
+            // Check that proposer's balance reduced by burnt stake:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - min_stake());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+
+            // TODO expect event ProposalStatusUpdated(1, Slashed)
+            // TODO fix: event log assertion doesn't work and return empty event in every record
+            // assert_eq!(*System::events().last().unwrap(),
+            //     EventRecord {
+            //         phase: Phase::ApplyExtrinsic(0),
+            //         event: RawEvent::ProposalStatusUpdated(1, Slashed),
+            //     }
+            // );
+        });
+    }
+
+    // In this case a proposal will be marked as 'Expired'
+    // and it will be processed in the same way as if it has been rejected.
+    #[test]
+    fn expire_proposal_when_not_all_councilors_voted_and_quorum_not_reached() {
+        with_externalities(&mut new_test_ext(), || {
+            Balances::set_free_balance(&PROPOSER1, initial_balance());
+            Balances::increase_total_stake_by(initial_balance());
+
+            assert_ok!(_create_default_proposal());
+
+            // Less than a quorum of councilors approved:
+            let approvals = Proposals::approval_quorum_seats() - 1;
+            for i in 0..approvals as usize {
+                let vote = if (i as u32) < approvals { Approve } else { Slash };
+                assert_ok!(Proposals::vote_on_proposal(
+                    Origin::signed(ALL_COUNCILORS[i]), 1, vote));
+            }
+            assert_eq!(Proposals::votes_by_proposal(1).len() as u32, approvals);
+
+            assert_runtime_code_empty!();
+
+            let expiration_block = System::block_number() + Proposals::voting_period();
+            System::set_block_number(expiration_block);
+            Proposals::on_finalise(expiration_block);
+
+            // Check that runtime code has NOT been updated after proposal slashed.
+            assert_runtime_code_empty!();
+
+            assert!(Proposals::active_proposal_ids().is_empty());
+            assert_eq!(Proposals::proposals(1).status, Expired);
+            assert_eq!(Proposals::tally_results(1), TallyResult {
+                proposal_id: 1,
+                abstentions: 0,
+                approvals: approvals,
+                rejections: 0,
+                slashes: 0,
+                status: Expired,
+                finalized_at: expiration_block
+            });
+
+            // Check that proposer's balance reduced by burnt stake:
+            assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - rejection_fee());
+            assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
+
+            // TODO expect event ProposalStatusUpdated(1, Rejected)
+        });
+    }
+}

+ 70 - 0
src/governance/sealed_vote.rs

@@ -0,0 +1,70 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use srml_support::{ensure};
+use parity_codec::Encode;
+use rstd::vec::Vec;
+
+#[derive(Clone, Copy, Encode, Decode, Default)]
+pub struct SealedVote<AccountId, Stake, Hash, Vote>
+    where Vote: Encode, Hash: PartialEq, AccountId: PartialEq
+{
+  pub voter: AccountId,
+  pub commitment: Hash, // 32 bytes - salted hash of serialized Vote
+  pub stake: Stake,
+  vote: Option<Vote>, // will be set when unsealing
+}
+
+impl<AccountId, Stake, Hash, Vote> SealedVote<AccountId, Stake, Hash, Vote>
+    where Vote: Encode, Hash: PartialEq, AccountId: PartialEq
+{
+    pub fn new(voter: AccountId, stake: Stake, commitment: Hash) -> SealedVote<AccountId, Stake, Hash, Vote> {
+        SealedVote {
+            voter,
+            commitment,
+            stake,
+            vote: None,
+        }
+    }
+
+    pub fn new_unsealed(voter: AccountId, stake: Stake, commitment: Hash, vote: Vote) -> SealedVote<AccountId, Stake, Hash, Vote> {
+        SealedVote {
+            voter,
+            commitment,
+            stake,
+            vote: Some(vote),
+        }
+    }
+
+    pub fn unseal(&mut self, vote: Vote, salt: &mut Vec<u8>, hasher: fn(&[u8]) -> Hash) -> Result<(), &'static str> {
+        // only unseal once
+        ensure!(self.is_not_revealed(), "vote already unsealed");
+
+        // seralize the vote and append the salt
+        let mut payload = vote.encode();
+        payload.append(salt);
+
+        // hash the payload, if it matches the commitment it is a valid revealing of the vote
+        if self.commitment == hasher(&payload) {
+            self.vote = Some(vote);
+            Ok(())
+        } else {
+            Err("invalid salt")
+        }
+    }
+
+    pub fn get_vote(&self) -> &Option<Vote> {
+        &self.vote
+    }
+
+    pub fn is_owned_by(&self, someone: AccountId) -> bool {
+        someone == self.voter
+    }
+
+    pub fn is_revealed(&self) -> bool {
+        self.vote.is_some()
+    }
+
+    pub fn is_not_revealed(&self) -> bool {
+        self.vote.is_none()
+    }
+}

+ 114 - 0
src/governance/stake.rs

@@ -0,0 +1,114 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use rstd::cmp::Ordering;
+use runtime_primitives::traits::{SimpleArithmetic};
+
+#[derive(Encode, Decode, Clone, Copy, Default, Debug)]
+pub struct Stake<Balance>
+    where Balance: Copy + SimpleArithmetic,
+{
+    pub new: Balance,
+    pub transferred: Balance,
+}
+
+impl<Balance> Stake<Balance>
+    where Balance: Copy + SimpleArithmetic,
+{
+    pub fn total(&self) -> Balance {
+        self.new + self.transferred
+    }
+
+    pub fn add(&self, v: &Self) -> Self {
+        Self {
+            new: self.new + v.new,
+            transferred: self.transferred + v.transferred
+        }
+    }
+}
+
+impl<T: Copy + SimpleArithmetic> PartialOrd for Stake<T> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(&other))
+    }
+}
+
+impl<T: Copy + SimpleArithmetic> Ord for Stake<T> {
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.total().cmp(&other.total())
+    }
+}
+
+impl<T: Copy + SimpleArithmetic> PartialEq for Stake<T> {
+    fn eq(&self, other: &Self) -> bool {
+        self.total() == other.total()
+    }
+}
+
+impl<T: Copy + SimpleArithmetic> Eq for Stake<T> {}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn total() {
+        let a: u128 = 4;
+        let b: u128 = 5;
+        let s = Stake {
+            new: a,
+            transferred: b,
+        };
+        assert_eq!(a + b, s.total());
+    }
+
+    #[test]
+    fn adding() {
+        let a1: u128 = 3; let b1: u128 = 2;
+        let a2: u128 = 5; let b2: u128 = 7;
+
+        let s1 = Stake {
+            new: a1,
+            transferred: b1,
+        };
+
+        let s2 = Stake {
+            new: a2,
+            transferred: b2,
+        };
+
+        let sum = s1.add(&s2);
+
+        assert_eq!(sum.new, 8);
+        assert_eq!(sum.transferred, 9);
+    }
+
+    #[test]
+    fn equality() {
+        let a1: u128 = 3; let b1: u128 = 2;
+        let a2: u128 = 2; let b2: u128 = 3;
+        let a3: u128 = 10; let b3: u128 = 10;
+
+        let s1 = Stake {
+            new: a1,
+            transferred: b1,
+        };
+
+        let s2 = s1;
+
+        assert_eq!(s1, s2);
+
+        let s3 = Stake {
+            new: a2,
+            transferred: b2,
+        };
+
+        assert_eq!(s1, s3);
+
+        let s4 = Stake {
+            new: a3,
+            transferred: b3,
+        };
+
+        assert_ne!(s1, s4);
+    }
+}

+ 326 - 0
src/lib.rs

@@ -0,0 +1,326 @@
+//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+#![cfg_attr(not(feature = "std"), feature(alloc))]
+// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
+#![recursion_limit="256"]
+
+#[cfg(feature = "std")]
+#[macro_use]
+extern crate serde_derive;
+
+use substrate_client as client;
+
+#[macro_use]
+extern crate parity_codec_derive;
+
+pub mod governance;
+use governance::{election, council, proposals};
+mod memo;
+
+use rstd::prelude::*;
+#[cfg(feature = "std")]
+use primitives::bytes;
+use primitives::{Ed25519AuthorityId, OpaqueMetadata};
+use runtime_primitives::{
+	ApplyResult, transaction_validity::TransactionValidity, Ed25519Signature, generic,
+	traits::{self, Convert, BlakeTwo256, Block as BlockT, StaticLookup}, create_runtime_str
+};
+use client::{
+	block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api},
+	runtime_api, impl_runtime_apis
+};
+use version::RuntimeVersion;
+#[cfg(feature = "std")]
+use version::NativeVersion;
+
+// A few exports that help ease life for downstream crates.
+#[cfg(any(feature = "std", test))]
+pub use runtime_primitives::BuildStorage;
+pub use consensus::Call as ConsensusCall;
+pub use timestamp::Call as TimestampCall;
+pub use balances::Call as BalancesCall;
+pub use runtime_primitives::{Permill, Perbill};
+pub use timestamp::BlockPeriod;
+pub use srml_support::{StorageValue, construct_runtime};
+
+/// Alias to Ed25519 pubkey that identifies an account on the chain.
+pub type AccountId = primitives::H256;
+
+/// A hash of some data used by the chain.
+pub type Hash = primitives::H256;
+
+/// Index of a block number in the chain.
+pub type BlockNumber = u64;
+
+/// Index of an account's extrinsic in the chain.
+pub type Nonce = u64;
+
+/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
+/// the specifics of the runtime. They can then be made to be agnostic over specific formats
+/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
+/// to even the core datastructures.
+pub mod opaque {
+	use super::*;
+
+	/// Opaque, encoded, unchecked extrinsic.
+	#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
+	#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
+	pub struct UncheckedExtrinsic(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
+	impl traits::Extrinsic for UncheckedExtrinsic {
+		fn is_signed(&self) -> Option<bool> {
+			None
+		}
+	}
+	/// Opaque block header type.
+	pub type Header = generic::Header<BlockNumber, BlakeTwo256, generic::DigestItem<Hash, Ed25519AuthorityId>>;
+	/// Opaque block type.
+	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+	/// Opaque block identifier type.
+	pub type BlockId = generic::BlockId<Block>;
+	/// Opaque session key type.
+	pub type SessionKey = Ed25519AuthorityId;
+}
+
+/// This runtime version.
+pub const VERSION: RuntimeVersion = RuntimeVersion {
+	spec_name: create_runtime_str!("joystream-node"),
+	impl_name: create_runtime_str!("joystream-node"),
+	authoring_version: 3,
+	spec_version: 4,
+	impl_version: 0,
+	apis: RUNTIME_API_VERSIONS,
+};
+
+/// The version infromation used to identify this runtime when compiled natively.
+#[cfg(feature = "std")]
+pub fn native_version() -> NativeVersion {
+	NativeVersion {
+		runtime_version: VERSION,
+		can_author_with: Default::default(),
+	}
+}
+
+impl system::Trait for Runtime {
+	/// The identifier used to distinguish between accounts.
+	type AccountId = AccountId;
+	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
+	type Lookup = Indices;
+	/// The index type for storing how many extrinsics an account has signed.
+	type Index = Nonce;
+	/// The index type for blocks.
+	type BlockNumber = BlockNumber;
+	/// The type for hashing blocks and tries.
+	type Hash = Hash;
+	/// The hashing algorithm used.
+	type Hashing = BlakeTwo256;
+	/// The header digest type.
+	type Digest = generic::Digest<Log>;
+	/// The header type.
+	type Header = generic::Header<BlockNumber, BlakeTwo256, Log>;
+	/// The ubiquitous event type.
+	type Event = Event;
+	/// The ubiquitous log type.
+	type Log = Log;
+	/// The ubiquitous origin type.
+	type Origin = Origin;
+}
+
+impl aura::Trait for Runtime {
+	type HandleReport = aura::StakingSlasher<Runtime>;
+}
+
+impl consensus::Trait for Runtime {
+	/// The identifier we use to refer to authorities.
+	type SessionKey = Ed25519AuthorityId;
+	// The aura module handles offline-reports internally
+	// rather than using an explicit report system.
+	type InherentOfflineReport = ();
+	/// The ubiquitous log type.
+	type Log = Log;
+}
+
+/// Session key conversion.
+pub struct SessionKeyConversion;
+impl Convert<AccountId, Ed25519AuthorityId> for SessionKeyConversion {
+	fn convert(a: AccountId) -> Ed25519AuthorityId {
+		a.to_fixed_bytes().into()
+	}
+}
+
+impl session::Trait for Runtime {
+	type ConvertAccountIdToSessionKey = SessionKeyConversion;
+	type OnSessionChange = (Staking, );
+	type Event = Event;
+}
+
+impl indices::Trait for Runtime {
+	/// The type for recording indexing into the account enumeration. If this ever overflows, there
+	/// will be problems!
+	type AccountIndex = u32;
+	/// Use the standard means of resolving an index hint from an id.
+	type ResolveHint = indices::SimpleResolveHint<Self::AccountId, Self::AccountIndex>;
+	/// Determine whether an account is dead.
+	type IsDeadAccount = Balances;
+	/// The uniquitous event type.
+	type Event = Event;
+}
+
+impl timestamp::Trait for Runtime {
+	/// A timestamp: seconds since the unix epoch.
+	type Moment = u64;
+	type OnTimestampSet = Aura;
+}
+
+impl balances::Trait for Runtime {
+	/// The type for recording an account's balance.
+	type Balance = u128;
+	/// What to do if an account's free balance gets zeroed.
+	type OnFreeBalanceZero = Staking;
+	/// What to do if a new account is created.
+	type OnNewAccount = Indices;
+	/// Restrict whether an account can transfer funds. We don't place any further restrictions.
+	type EnsureAccountLiquid = Staking;
+	/// The uniquitous event type.
+	type Event = Event;
+}
+
+impl fees::Trait for Runtime {
+	type TransferAsset = Balances;
+	type Event = Event;
+}
+
+impl sudo::Trait for Runtime {
+	/// The uniquitous event type.
+	type Event = Event;
+	type Proposal = Call;
+}
+
+impl staking::Trait for Runtime {
+	type Currency = balances::Module<Self>;
+	type OnRewardMinted = ();
+	type Event = Event;
+}
+
+impl governance::GovernanceCurrency for Runtime {
+	type Currency = balances::Module<Self>;
+}
+
+impl governance::proposals::Trait for Runtime {
+	type Event = Event;
+}
+
+impl governance::election::Trait for Runtime {
+	type Event = Event;
+	type CouncilElected = (Council,);
+}
+
+impl governance::council::Trait for Runtime {
+	type Event = Event;
+	type CouncilTermEnded = (CouncilElection,);
+}
+
+impl memo::Trait for Runtime {
+	type Event = Event;
+}
+
+construct_runtime!(
+	pub enum Runtime with Log(InternalLog: DigestItem<Hash, Ed25519AuthorityId>) where
+		Block = Block,
+		NodeBlock = opaque::Block,
+		UncheckedExtrinsic = UncheckedExtrinsic
+	{
+		System: system::{default, Log(ChangesTrieRoot)},
+		Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
+		Consensus: consensus::{Module, Call, Storage, Config<T>, Log(AuthoritiesChange), Inherent},
+		Aura: aura::{Module, Inherent(Timestamp)},
+		Indices: indices,
+		Balances: balances,
+		Session: session,
+		Staking: staking::{default, OfflineWorker},
+		Fees: fees::{Module, Storage, Config<T>, Event<T>},
+		Sudo: sudo,
+		Proposals: proposals::{Module, Call, Storage, Event<T>, Config<T>},
+		CouncilElection: election::{Module, Call, Storage, Event<T>, Config<T>},
+		Council: council::{Module, Call, Storage, Event<T>, Config<T>},
+		Memo: memo::{Module, Call, Storage, Event<T>},
+	}
+);
+
+/// The type used as a helper for interpreting the sender of transactions.
+type Context = system::ChainContext<Runtime>;
+/// The address format for describing accounts.
+type Address = <Indices as StaticLookup>::Source;
+/// Block header type as expected by this runtime.
+pub type Header = generic::Header<BlockNumber, BlakeTwo256, Log>;
+/// Block type as expected by this runtime.
+pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+/// BlockId type as expected by this runtime.
+pub type BlockId = generic::BlockId<Block>;
+/// Unchecked extrinsic type as expected by this runtime.
+pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic<Address, Nonce, Call, Ed25519Signature>;
+/// Extrinsic type that has already been checked.
+pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
+/// Executive: handles dispatch to the various modules.
+pub type Executive = executive::Executive<Runtime, Block, Context, Fees, AllModules>;
+
+// Implement our runtime API endpoints. This is just a bunch of proxying.
+impl_runtime_apis! {
+	impl runtime_api::Core<Block> for Runtime {
+		fn version() -> RuntimeVersion {
+			VERSION
+		}
+
+		fn authorities() -> Vec<Ed25519AuthorityId> {
+			Consensus::authorities()
+		}
+
+		fn execute_block(block: Block) {
+			Executive::execute_block(block)
+		}
+
+		fn initialise_block(header: &<Block as BlockT>::Header) {
+			Executive::initialise_block(header)
+		}
+	}
+
+	impl runtime_api::Metadata<Block> for Runtime {
+		fn metadata() -> OpaqueMetadata {
+			Runtime::metadata().into()
+		}
+	}
+
+	impl block_builder_api::BlockBuilder<Block> for Runtime {
+		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
+			Executive::apply_extrinsic(extrinsic)
+		}
+
+		fn finalise_block() -> <Block as BlockT>::Header {
+			Executive::finalise_block()
+		}
+
+		fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
+			data.create_extrinsics()
+		}
+
+		fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
+			data.check_extrinsics(&block)
+		}
+
+		fn random_seed() -> <Block as BlockT>::Hash {
+			System::random_seed()
+		}
+	}
+
+	impl runtime_api::TaggedTransactionQueue<Block> for Runtime {
+		fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
+			Executive::validate_transaction(tx)
+		}
+	}
+
+	impl consensus_aura::AuraApi<Block> for Runtime {
+		fn slot_duration() -> u64 {
+			Aura::slot_duration()
+		}
+	}
+}

+ 41 - 0
src/memo.rs

@@ -0,0 +1,41 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use srml_support::{StorageMap, dispatch::Result, decl_module, decl_storage, decl_event, ensure};
+use srml_support::traits::{Currency};
+use runtime_primitives::traits::{Zero};
+use system::{self, ensure_signed};
+use rstd::prelude::*;
+use crate::governance::GovernanceCurrency;
+
+pub trait Trait: system::Trait + GovernanceCurrency {
+    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
+}
+
+decl_storage! {
+    trait Store for Module<T: Trait> as Memo {
+        Memo get(memo) : map T::AccountId => Vec<u8>;
+        MaxMemoLength get(max_memo_length) : u32 = 4096;
+    }
+}
+
+decl_event! {
+    pub enum Event<T> where <T as system::Trait>::AccountId {
+        MemoUpdated(AccountId),
+    }
+}
+
+decl_module! {
+    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+        fn deposit_event<T>() = default;
+
+        fn update_memo(origin, memo: Vec<u8>) {
+            let sender = ensure_signed(origin)?;
+
+            ensure!(!T::Currency::total_balance(&sender).is_zero(), "account must have a balance");
+            ensure!(memo.len() as u32 <= Self::max_memo_length(), "memo too long");
+
+            <Memo<T>>::insert(sender.clone(), memo);
+            Self::deposit_event(RawEvent::MemoUpdated(sender));
+        }
+    }
+}

+ 2360 - 0
wasm/Cargo.lock

@@ -0,0 +1,2360 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "arrayref"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "arrayvec"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "autocfg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "backtrace"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "base58"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "bitflags"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "blake2-rfc"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "block-padding"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "byte-tools"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "byte-tools"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "byteorder"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "bytes"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cfg-if"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "chrono"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "clear_on_drop"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "cloudabi"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "constant_time_eq"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "crossbeam"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 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)",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-queue"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crunchy"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "crunchy"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "crypto-mac"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "curve25519-dalek"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "digest"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "digest"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ed25519-dalek"
+version = "1.0.0-pre.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "elastic-array"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "environmental"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "error-chain"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "failure"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "fake-simd"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "fixed-hash"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "fuchsia-cprng"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "fuchsia-zircon"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fuchsia-zircon-sys"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "futures"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "generic-array"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "hash-db"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "hash256-std-hasher"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "heapsize"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "hex-literal"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "hex-literal-impl"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "hmac"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "hmac-drbg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "httparse"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "idna"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "impl-codec"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "impl-serde"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "integer-sqrt"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "iovec"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "joystream-node-runtime"
+version = "1.0.1"
+dependencies = [
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "safe-mix 1.0.0 (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)",
+ "sr-io 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-version 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-aura 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-balances 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-consensus 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-executive 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-fees 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-indices 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-session 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-staking 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-sudo 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-timestamp 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-client 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-consensus-aura-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "joystream-node-runtime-wasm"
+version = "1.0.1"
+dependencies = [
+ "joystream-node-runtime 1.0.1",
+]
+
+[[package]]
+name = "keccak"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "kernel32-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "kvdb"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d"
+dependencies = [
+ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "lazycell"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "libc"
+version = "0.2.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "libsecp256k1"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "log"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "matches"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "memoffset"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "memory-db"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "memory_units"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "merlin"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mio"
+version = "0.6.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mio-extras"
+version = "2.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mio-uds"
+version = "0.6.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "miow"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "net2"
+version = "0.2.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "nodrop"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "num-integer"
+version = "0.1.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "num_cpus"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "once_cell"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "opaque-debug"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "openssl"
+version = "0.10.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "owning_ref"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "parity-bytes"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d"
+
+[[package]]
+name = "parity-codec"
+version = "3.1.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)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "parity-codec-derive"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+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)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "parity-wasm"
+version = "0.31.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "paste"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "paste-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro-hack 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "paste-impl"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro-hack 0.5.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.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "primitive-types"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "impl-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "uint 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proc-macro-hack"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.4"
+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.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proc-macro-hack-impl"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "proc-macro2"
+version = "0.4.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "0.6.11"
+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)",
+]
+
+[[package]]
+name = "rand"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rand_hc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_isaac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_jitter"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_os"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_xorshift"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rdrand"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.1.51"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "ring"
+version = "0.14.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rustc-hex"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ryu"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "safe-mix"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "schnorrkel"
+version = "0.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "merlin 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sha3 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "scopeguard"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "serde"
+version = "1.0.89"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "serde_derive"
+version = "1.0.89"
+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.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "sha1"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "sha2"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "sha2"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "sha3"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "slog"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "slog-async"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "slog-json"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "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)",
+ "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "slog-scope"
+version = "4.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "smallvec"
+version = "0.6.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "spin"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "sr-api-macros"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+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)",
+ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "sr-io"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-state-machine 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-trie 0.4.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "sr-primitives"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+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)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (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)",
+ "sr-io 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "sr-std"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "sr-version"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (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)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-aura"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-staking 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-timestamp 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-inherents 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-balances"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-keyring 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-consensus"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (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)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-inherents 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-executive"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-io 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-fees"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-io 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-indices"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-io 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-keyring 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-metadata"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (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)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-session"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-consensus 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-timestamp 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-staking"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-consensus 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-session 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-keyring 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-sudo"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support-procedural 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-support"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "paste 0.1.4 (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)",
+ "sr-io 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-metadata 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support-procedural 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-inherents 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-support-procedural"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-api-macros 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support-procedural-tools 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "srml-support-procedural-tools"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+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)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "srml-support-procedural-tools-derive 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "srml-support-procedural-tools-derive"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "srml-system"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "safe-mix 1.0.0 (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)",
+ "sr-io 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "srml-timestamp"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-consensus 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-inherents 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "static_assertions"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "substrate-client"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "error-chain 0.12.0 (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.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.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)",
+ "sr-api-macros 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-version 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-consensus-common 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-executor 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-inherents 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-keyring 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-state-machine 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-telemetry 0.3.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-trie 0.4.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "substrate-consensus-aura-primitives"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "substrate-client 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "substrate-consensus-common"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+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.25 (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.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-version 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-inherents 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "substrate-executor"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+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)",
+ "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)",
+ "parity-codec 3.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)",
+ "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)",
+ "sr-io 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-version 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-panic-handler 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-serializer 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-state-machine 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-trie 0.4.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "substrate-inherents"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.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)",
+ "sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "substrate-keyring"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+]
+
+[[package]]
+name = "substrate-panic-handler"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+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)",
+]
+
+[[package]]
+name = "substrate-primitives"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+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)",
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hash256-std-hasher 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "primitive-types 0.2.1 (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)",
+ "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "schnorrkel 0.0.0 (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)",
+ "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "twox-hash 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "substrate-serializer"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+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)",
+]
+
+[[package]]
+name = "substrate-state-machine"
+version = "0.1.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hex-literal 0.1.3 (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.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)",
+ "substrate-panic-handler 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "substrate-trie 0.4.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)",
+ "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "trie-root 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "substrate-telemetry"
+version = "0.3.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+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)",
+ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slog-scope 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "substrate-trie"
+version = "0.4.0"
+source = "git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d#df5e65927780b323482e2e8b5031822f423a032d"
+dependencies = [
+ "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "trie-root 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "subtle"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "syn"
+version = "0.15.27"
+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.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "take_mut"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "thread_local"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "time"
+version = "0.1.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tiny-keccak"
+version = "1.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)",
+]
+
+[[package]]
+name = "tokio"
+version = "0.1.16"
+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.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-fs 0.1.6 (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-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-threadpool 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)",
+ "tokio-udp 0.1.3 (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 = "tokio-codec"
+version = "0.1.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.25 (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 = "tokio-current-thread"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-executor"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-fs"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-io"
+version = "0.1.12"
+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.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-reactor"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "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)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-sync"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-tcp"
+version = "0.1.3"
+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.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (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)",
+]
+
+[[package]]
+name = "tokio-threadpool"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-timer"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-udp"
+version = "0.1.3"
+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.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (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-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-uds"
+version = "0.2.5"
+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.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-uds 0.6.7 (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-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "toml"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "trie-db"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "trie-root"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "twox-hash"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "typenum"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "uint"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "untrusted"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "url"
+version = "1.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "wasmi"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "winapi"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "winapi-build"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "ws"
+version = "0.7.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ws2_32-sys"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[metadata]
+"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
+"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
+"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 base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
+"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
+"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
+"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814"
+"checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d"
+"checksum block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d75255892aeb580d3c566f213a2b6fdc1c66667839f45719ee1d30ebf2aea591"
+"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
+"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
+"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
+"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
+"checksum cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "d01c69d08ff207f231f07196e30f84c70f1c815b04f980f8b7b01ff01f05eb92"
+"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
+"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
+"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17"
+"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
+"checksum crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4c7ea749d9fb09e23c5cb17e3b70650860553a0e2744e38446b1803bf7db94"
+"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
+"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
+"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
+"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4"
+"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
+"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
+"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
+"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2"
+"checksum crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "779015233ac67d65098614aec748ac1c756ab6677fa2e14cf8b37c08dfed1198"
+"checksum curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1f8a6fc0376eb52dc18af94915cc04dfdf8353746c0e8c550ae683a0815e5c1"
+"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 ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86"
+"checksum elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "073be79b6538296faf81c631872676600616073817dd9a440c477ad09b408983"
+"checksum environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db746025e3ea695bfa0ae744dbacd5fcfc8db51b9760cf8bd0ab69708bb93c49"
+"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
+"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
+"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
+"checksum fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a557e80084b05c32b455963ff565a9de6f2866da023d6671705c6aff6f65e01c"
+"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
+"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
+"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
+"checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2"
+"checksum hash-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b03501f6e1a2a97f1618879aba3156f14ca2847faa530c4e28859638bd11483"
+"checksum hash256-std-hasher 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5c13dbac3cc50684760f54af18545c9e80fb75e93a3e586d71ebdc13138f6a4"
+"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
+"checksum hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "27455ce8b4a6666c87220e4b59c9a83995476bdadc10197905e61dbe906e36fa"
+"checksum hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d340b6514f232f6db1bd16db65302a5278a04fef9ce867cb932e7e5fa21130a"
+"checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a"
+"checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2"
+"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83"
+"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
+"checksum impl-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2050d823639fbeae26b2b5ba09aca8907793117324858070ade0673c49f793b"
+"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56"
+"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903"
+"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
+"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
+"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
+"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
+"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "<none>"
+"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.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1"
+"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.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
+"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
+"checksum memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94da53143d45f6bad3753f532e56ad57a6a26c0ca6881794583310c7cb4c885f"
+"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
+"checksum merlin 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "83c2dda19c01176e8e7148f7bdb88bbdf215a8db0641f89fc40e4b81736aeda5"
+"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432"
+"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
+"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
+"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
+"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
+"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
+"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
+"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
+"checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37"
+"checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409"
+"checksum openssl 0.10.19 (registry+https://github.com/rust-lang/crates.io-index)" = "84321fb9004c3bce5611188a644d6171f895fa2889d155927d528782edb21c5d"
+"checksum openssl-sys 0.9.42 (registry+https://github.com/rust-lang/crates.io-index)" = "cb534d752bf98cf363b473950659ac2546517f9c6be9723771614ab3f03bbc9e"
+"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
+"checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "<none>"
+"checksum parity-codec 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67a4d27831e31e27f1454d6e3d3bb34bcac6bf7ad7032eed0ad0070dc8cf55c1"
+"checksum parity-codec-derive 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "864e9f66b58c0b38f0d6b511b6576afa2b678ae801b64220553bced57ac12df9"
+"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc"
+"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
+"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
+"checksum paste 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f50392d1265092fbee9273414cc40eb6d47d307bd66222c477bb8450c8504f9d"
+"checksum paste-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3cd512fe3a55e8933b2dcad913e365639db86d512e4004c3084b86864d9467a"
+"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
+"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
+"checksum primitive-types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edb92f1ebfc177432c03287b15d48c202e6e2c95993a7af3ba039abb43b1492e"
+"checksum proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4c6cf4e5b00300d151dfffae39f529dfa5188f42eeb14201229aa420d6aad10c"
+"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8"
+"checksum proc-macro-hack 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3e90aa19cd73dedc2d0e1e8407473f073d735fef0ab521438de6da8ee449ab66"
+"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a"
+"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
+"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
+"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
+"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
+"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
+"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
+"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
+"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
+"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
+"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832"
+"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
+"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
+"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
+"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
+"checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c"
+"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
+"checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8"
+"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
+"checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347"
+"checksum schnorrkel 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe554f318830b48e5da8ab1ccb1ffd02b79228364dac7766b7cd1ec461ca5116"
+"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
+"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 serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "92514fb95f900c9b5126e32d020f5c6d40564c27a5ea6d1d7d9f157a96623560"
+"checksum serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6eabf4b5914e88e24eea240bb7c9f9a2cbc1bbbe8d961d381975ec3c6b806c"
+"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
+"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
+"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a"
+"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
+"checksum sha3 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34a5e54083ce2b934bf059fdf38e7330a154177e029ab6c4e18638f2f624053a"
+"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+"checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e"
+"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f"
+"checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a"
+"checksum slog-scope 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "60c04b4726fa04595ccf2c2dad7bcd15474242c4c5e109a8a376e8a2c9b1539a"
+"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
+"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55"
+"checksum sr-api-macros 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum sr-io 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum sr-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum sr-std 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum sr-version 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-aura 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-balances 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-consensus 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-executive 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-fees 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-indices 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-metadata 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-session 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-staking 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-sudo 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-support 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-support-procedural 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-support-procedural-tools 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-support-procedural-tools-derive 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-system 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum srml-timestamp 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"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 substrate-client 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-consensus-aura-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-consensus-common 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-executor 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-inherents 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-keyring 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-panic-handler 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-primitives 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-serializer 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-state-machine 0.1.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-telemetry 0.3.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum substrate-trie 0.4.0 (git+https://github.com/joystream/substrate.git?rev=df5e65927780b323482e2e8b5031822f423a032d)" = "<none>"
+"checksum subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "702662512f3ddeb74a64ce2fbbf3707ee1b6bb663d28bb054e0779bbc720d926"
+"checksum syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)" = "525bd55255f03c816e5d7f615587bd13030c7103354fadb104993dcee6a788ec"
+"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
+"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
+"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
+"checksum tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9175261fbdb60781fcd388a4d6cc7e14764a2b629a7ad94abb439aed223a44f"
+"checksum tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fcaabb3cec70485d0df6e9454fe514393ad1c4070dee8915f11041e95630b230"
+"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f"
+"checksum tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c756b04680eea21902a46fca4e9f410a2332c04995af590e07ff262e2193a9a3"
+"checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0"
+"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af"
+"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
+"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce"
+"checksum tokio-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1bf2b9dac2a0509b5cfd1df5aa25eafacb616a42a491a13604d6bbeab4486363"
+"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
+"checksum tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "742e511f6ce2298aeb86fc9ea0d8df81c2388c6ebae3dc8a7316e8c9df0df801"
+"checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6"
+"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92"
+"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445"
+"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
+"checksum trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7319e28ca295f27359d944a682f7f65b419158bf1590c92cadc0000258d788"
+"checksum trie-root 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c6fef2705af3258ec46a7e22286090394a44216201a1cf7d04b78db825e543"
+"checksum twox-hash 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "555cd4909480122bbbf21e34faac4cb08a171f324775670447ed116726c474af"
+"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
+"checksum uint 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7780bb27fd8a22295e0d9d53ae3be253f715a0dccb1808527f478f1c2603708"
+"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
+"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
+"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f"
+"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
+"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
+"checksum wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21ef487a11df1ed468cf613c78798c26282da5c30e9d49f824872d4c77b47d1d"
+"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
+"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+"checksum ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "329d3e6dd450a9c5c73024e1047f0be7e24121a68484eb0b5368977bee3cf8c3"
+"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"

+ 22 - 0
wasm/Cargo.toml

@@ -0,0 +1,22 @@
+[profile.release]
+lto = true
+panic = 'abort'
+
+[workspace]
+members = []
+
+[lib]
+crate-type = ['cdylib']
+
+[features]
+default = []
+std = ['joystream-node-runtime/std']
+[dependencies.joystream-node-runtime]
+default-features = false
+path = '..'
+
+[package]
+authors = ['Joystream']
+edition = '2018'
+name = 'joystream-node-runtime-wasm'
+version = '1.0.1'

+ 3 - 0
wasm/src/lib.rs

@@ -0,0 +1,3 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub use joystream_node_runtime::*;