mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 16:31:07 +00:00
Enhance decl storage (#777)
* enhance macro decl_storage() * update the state root hash * fix one comment
This commit is contained in:
Generated
+1
@@ -2712,6 +2712,7 @@ dependencies = [
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-io 0.1.0",
|
||||
"sr-primitives 0.1.0",
|
||||
"sr-std 0.1.0",
|
||||
"substrate-metadata 0.1.0",
|
||||
]
|
||||
|
||||
+1
@@ -522,6 +522,7 @@ dependencies = [
|
||||
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-io 0.1.0",
|
||||
"sr-primitives 0.1.0",
|
||||
"sr-std 0.1.0",
|
||||
"substrate-metadata 0.1.0",
|
||||
]
|
||||
|
||||
@@ -249,7 +249,8 @@ mod tests {
|
||||
offline_slash_grace: 0,
|
||||
}),
|
||||
democracy: Some(Default::default()),
|
||||
council: Some(Default::default()),
|
||||
council_seats: Some(Default::default()),
|
||||
council_voting: Some(Default::default()),
|
||||
timestamp: Some(Default::default()),
|
||||
treasury: Some(Default::default()),
|
||||
contract: Some(Default::default()),
|
||||
@@ -290,9 +291,9 @@ mod tests {
|
||||
1,
|
||||
GENESIS_HASH.into(),
|
||||
if support_changes_trie {
|
||||
hex!("9a7fe864529934ebb5915a855b0270f729803510bc12763c5c6fb87d3e231c17").into()
|
||||
hex!("ffa85ed1832eae3e25e684d4f993ff0b5e8b6ac4d7ba0f40a5fb0114fda22f3d").into()
|
||||
} else {
|
||||
hex!("ee335055cb0c93b108ceed0431129d93b11796ab88d89efe81a29e8c6a1f270f").into()
|
||||
hex!("98971908b8923d07944cdf7ee658c203d17042ef447169adbdfec8160cfabcad").into()
|
||||
},
|
||||
if support_changes_trie {
|
||||
Some(hex!("1f8f44dcae8982350c14dee720d34b147e73279f5a2ce1f9781195a991970978").into())
|
||||
@@ -316,7 +317,7 @@ mod tests {
|
||||
construct_block(
|
||||
2,
|
||||
block1(false).1,
|
||||
hex!("1db5d091b6efdf41dfd5294aa7a3ceb616fc1e0b95d3ee614f4d4af16e841195").into(),
|
||||
hex!("eef4ca8018e0511f89b7cee1e07796aa710a50accc8b1e52082d05cd8c8b6e24").into(),
|
||||
None,
|
||||
vec![
|
||||
CheckedExtrinsic {
|
||||
@@ -339,7 +340,7 @@ mod tests {
|
||||
construct_block(
|
||||
1,
|
||||
GENESIS_HASH.into(),
|
||||
hex!("6408d8740fbd31b234032678e9f91608fcccf83b0f900c63d52390dcbcd601a0").into(),
|
||||
hex!("acc03af5b3972deaf9dde4dfd99c5614a5360454313681b6fc299d1644ae8a59").into(),
|
||||
None,
|
||||
vec![
|
||||
CheckedExtrinsic {
|
||||
@@ -621,7 +622,7 @@ mod tests {
|
||||
let b = construct_block(
|
||||
1,
|
||||
GENESIS_HASH.into(),
|
||||
hex!("062f87b5ba0e96e4a7dcc41afe56a2df7f65a975415a6c1b0e8e92c330124f8f").into(),
|
||||
hex!("21fb6fb965f012ae3c6e521b71b5b57d6df17c738c52f202ec2809ca235eb082").into(),
|
||||
None,
|
||||
vec![
|
||||
CheckedExtrinsic {
|
||||
|
||||
@@ -65,6 +65,8 @@ use runtime_primitives::generic;
|
||||
use runtime_primitives::traits::{Convert, BlakeTwo256, DigestItem};
|
||||
use version::{RuntimeVersion, ApiId};
|
||||
use council::{motions as council_motions, voting as council_voting};
|
||||
#[cfg(feature = "std")]
|
||||
use council::seats as council_seats;
|
||||
#[cfg(any(feature = "std", test))]
|
||||
use version::NativeVersion;
|
||||
|
||||
@@ -215,9 +217,10 @@ construct_runtime!(
|
||||
Session: session,
|
||||
Staking: staking,
|
||||
Democracy: democracy,
|
||||
Council: council,
|
||||
CouncilVoting: council_voting::{Module, Call, Storage, Event<T>},
|
||||
Council: council::{Module, Call, Storage, Event<T>},
|
||||
CouncilVoting: council_voting,
|
||||
CouncilMotions: council_motions::{Module, Call, Storage, Event<T>, Origin},
|
||||
CouncilSeats: council_seats::{Config},
|
||||
Treasury: treasury,
|
||||
Contract: contract::{Module, Call, Config, Event<T>},
|
||||
}
|
||||
|
||||
Generated
+1
@@ -748,6 +748,7 @@ dependencies = [
|
||||
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-io 0.1.0",
|
||||
"sr-primitives 0.1.0",
|
||||
"sr-std 0.1.0",
|
||||
"substrate-metadata 0.1.0",
|
||||
]
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Substrate chain configurations.
|
||||
|
||||
use primitives::{AuthorityId, ed25519};
|
||||
use node_runtime::{GenesisConfig, ConsensusConfig, CouncilConfig, DemocracyConfig,
|
||||
use node_runtime::{GenesisConfig, ConsensusConfig, CouncilSeatsConfig, CouncilVotingConfig, DemocracyConfig,
|
||||
SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig,
|
||||
ContractConfig, Permill, Perbill};
|
||||
use service::ChainSpec;
|
||||
@@ -84,7 +84,7 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
voting_period: 5 * MINUTES, // 3 days to discuss & vote on an active referendum
|
||||
minimum_deposit: 50 * DOLLARS, // 12000 as the minimum deposit for a referendum
|
||||
}),
|
||||
council: Some(CouncilConfig {
|
||||
council_seats: Some(CouncilSeatsConfig {
|
||||
active_council: vec![],
|
||||
candidacy_bond: 10 * DOLLARS,
|
||||
voter_bond: 1 * DOLLARS,
|
||||
@@ -96,6 +96,8 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
desired_seats: 0,
|
||||
inactive_grace_period: 1, // one additional vote should go by before an inactive voter can be reaped.
|
||||
|
||||
}),
|
||||
council_voting: Some(CouncilVotingConfig {
|
||||
cooloff_period: 4 * DAYS,
|
||||
voting_period: 1 * DAYS,
|
||||
}),
|
||||
@@ -179,7 +181,7 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
|
||||
voting_period: 18,
|
||||
minimum_deposit: 10,
|
||||
}),
|
||||
council: Some(CouncilConfig {
|
||||
council_seats: Some(CouncilSeatsConfig {
|
||||
active_council: endowed_accounts.iter()
|
||||
.filter(|a| initial_authorities.iter().find(|&b| a.0 == b.0).is_none())
|
||||
.map(|a| (a.clone(), 1000000)).collect(),
|
||||
@@ -192,7 +194,8 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
|
||||
term_duration: 1000000,
|
||||
desired_seats: (endowed_accounts.len() - initial_authorities.len()) as u32,
|
||||
inactive_grace_period: 1,
|
||||
|
||||
}),
|
||||
council_voting: Some(CouncilVotingConfig {
|
||||
cooloff_period: 75,
|
||||
voting_period: 20,
|
||||
}),
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
// Copyright 2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Substrate is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Build a balances genesis block.
|
||||
|
||||
#![cfg(feature = "std")]
|
||||
|
||||
use rstd::prelude::*;
|
||||
use codec::Encode;
|
||||
use runtime_support::{StorageValue, StorageMap};
|
||||
use primitives::traits::{Zero, As};
|
||||
use primitives;
|
||||
use super::{Trait, ENUM_SET_SIZE, EnumSet, NextEnumSet, CreationFee, TransferFee,
|
||||
ReclaimRebate, ExistentialDeposit, TransactionByteFee, TransactionBaseFee, TotalIssuance,
|
||||
FreeBalance};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
pub balances: Vec<(T::AccountId, T::Balance)>,
|
||||
pub transaction_base_fee: T::Balance,
|
||||
pub transaction_byte_fee: T::Balance,
|
||||
pub transfer_fee: T::Balance,
|
||||
pub creation_fee: T::Balance,
|
||||
pub reclaim_rebate: T::Balance,
|
||||
pub existential_deposit: T::Balance,
|
||||
}
|
||||
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
balances: vec![],
|
||||
transaction_base_fee: T::Balance::sa(0),
|
||||
transaction_byte_fee: T::Balance::sa(0),
|
||||
transfer_fee: T::Balance::sa(0),
|
||||
creation_fee: T::Balance::sa(0),
|
||||
existential_deposit: T::Balance::sa(0),
|
||||
reclaim_rebate: T::Balance::sa(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
|
||||
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
|
||||
let total_issuance: T::Balance = self.balances.iter().fold(Zero::zero(), |acc, &(_, n)| acc + n);
|
||||
|
||||
let mut r: primitives::StorageMap = map![
|
||||
Self::hash(<NextEnumSet<T>>::key()).to_vec() => T::AccountIndex::sa(self.balances.len() / ENUM_SET_SIZE).encode(),
|
||||
Self::hash(<TransactionBaseFee<T>>::key()).to_vec() => self.transaction_base_fee.encode(),
|
||||
Self::hash(<TransactionByteFee<T>>::key()).to_vec() => self.transaction_byte_fee.encode(),
|
||||
Self::hash(<TransferFee<T>>::key()).to_vec() => self.transfer_fee.encode(),
|
||||
Self::hash(<CreationFee<T>>::key()).to_vec() => self.creation_fee.encode(),
|
||||
Self::hash(<ExistentialDeposit<T>>::key()).to_vec() => self.existential_deposit.encode(),
|
||||
Self::hash(<ReclaimRebate<T>>::key()).to_vec() => self.reclaim_rebate.encode(),
|
||||
Self::hash(<TotalIssuance<T>>::key()).to_vec() => total_issuance.encode()
|
||||
];
|
||||
|
||||
let ids: Vec<_> = self.balances.iter().map(|x| x.0.clone()).collect();
|
||||
for i in 0..(ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE {
|
||||
r.insert(Self::hash(&<EnumSet<T>>::key_for(T::AccountIndex::sa(i))).to_vec(),
|
||||
ids[i * ENUM_SET_SIZE..ids.len().min((i + 1) * ENUM_SET_SIZE)].to_owned().encode());
|
||||
}
|
||||
for (who, value) in self.balances.into_iter() {
|
||||
r.insert(Self::hash(&<FreeBalance<T>>::key_for(who)).to_vec(), value.encode());
|
||||
}
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,6 @@ extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate srml_support as runtime_support;
|
||||
|
||||
#[cfg_attr(feature = "std", macro_use)]
|
||||
extern crate sr_std as rstd;
|
||||
|
||||
#[macro_use]
|
||||
@@ -54,10 +53,6 @@ mod mock;
|
||||
|
||||
pub mod address;
|
||||
mod tests;
|
||||
mod genesis_config;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use genesis_config::GenesisConfig;
|
||||
|
||||
/// Number of account IDs stored per enum set.
|
||||
const ENUM_SET_SIZE: usize = 64;
|
||||
@@ -114,7 +109,7 @@ pub trait Trait: system::Trait {
|
||||
type Balance: Parameter + SimpleArithmetic + Codec + Default + Copy + As<Self::AccountIndex> + As<usize> + As<u64>;
|
||||
/// Type used for storing an account's index; implies the maximum number of accounts the system
|
||||
/// can hold.
|
||||
type AccountIndex: Parameter + Member + Codec + SimpleArithmetic + As<u8> + As<u16> + As<u32> + As<u64> + As<usize> + Copy;
|
||||
type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + As<u8> + As<u16> + As<u32> + As<u64> + As<usize> + Copy;
|
||||
/// A function which is invoked when the free-balance has fallen below the existential deposit and
|
||||
/// has been reduced to zero.
|
||||
///
|
||||
@@ -153,20 +148,24 @@ decl_event!(
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as Balances {
|
||||
/// The total amount of stake on the system.
|
||||
pub TotalIssuance get(total_issuance): required T::Balance;
|
||||
pub TotalIssuance get(total_issuance) build(|config: &GenesisConfig<T>| {
|
||||
config.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n)
|
||||
}): T::Balance;
|
||||
/// The minimum amount allowed to keep an account open.
|
||||
pub ExistentialDeposit get(existential_deposit): required T::Balance;
|
||||
pub ExistentialDeposit get(existential_deposit) config(): T::Balance;
|
||||
/// The amount credited to a destination's account whose index was reclaimed.
|
||||
pub ReclaimRebate get(reclaim_rebate): required T::Balance;
|
||||
pub ReclaimRebate get(reclaim_rebate) config(): T::Balance;
|
||||
/// The fee required to make a transfer.
|
||||
pub TransferFee get(transfer_fee): required T::Balance;
|
||||
pub TransferFee get(transfer_fee) config(): T::Balance;
|
||||
/// The fee required to create an account. At least as big as ReclaimRebate.
|
||||
pub CreationFee get(creation_fee): required T::Balance;
|
||||
pub CreationFee get(creation_fee) config(): T::Balance;
|
||||
|
||||
/// The next free enumeration set.
|
||||
pub NextEnumSet get(next_enum_set): required T::AccountIndex;
|
||||
pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig<T>| {
|
||||
T::AccountIndex::sa(config.balances.len() / ENUM_SET_SIZE)
|
||||
}): T::AccountIndex;
|
||||
/// The enumeration sets.
|
||||
pub EnumSet get(enum_set): default map [ T::AccountIndex => Vec<T::AccountId> ];
|
||||
pub EnumSet get(enum_set): map T::AccountIndex => Vec<T::AccountId>;
|
||||
|
||||
/// The 'free' balance of a given account.
|
||||
///
|
||||
@@ -179,13 +178,13 @@ decl_storage! {
|
||||
///
|
||||
/// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets
|
||||
/// collapsed to zero if it ever becomes less than `ExistentialDeposit`.
|
||||
pub FreeBalance get(free_balance): default map [ T::AccountId => T::Balance ];
|
||||
pub FreeBalance get(free_balance) build(|config: &GenesisConfig<T>| config.balances.clone()): map T::AccountId => T::Balance;
|
||||
|
||||
/// The amount of the balance of a given account that is exterally reserved; this can still get
|
||||
/// The amount of the balance of a given account that is externally reserved; this can still get
|
||||
/// slashed, but gets slashed last of all.
|
||||
///
|
||||
/// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens
|
||||
/// that are still 'owned' by the account holder, but which are unspendable. (This is different
|
||||
/// that are still 'owned' by the account holder, but which are suspendable. (This is different
|
||||
/// and wholly unrelated to the `Bondage` system used in the staking module.)
|
||||
///
|
||||
/// When this balance falls below the value of `ExistentialDeposit`, then this 'reserve account'
|
||||
@@ -193,15 +192,25 @@ decl_storage! {
|
||||
///
|
||||
/// `system::AccountNonce` is also deleted if `FreeBalance` is also zero (it also gets
|
||||
/// collapsed to zero if it ever becomes less than `ExistentialDeposit`.
|
||||
pub ReservedBalance get(reserved_balance): default map [ T::AccountId => T::Balance ];
|
||||
pub ReservedBalance get(reserved_balance): map T::AccountId => T::Balance;
|
||||
|
||||
|
||||
// Payment stuff.
|
||||
|
||||
/// The fee to be paid for making a transaction; the base.
|
||||
pub TransactionBaseFee get(transaction_base_fee): required T::Balance;
|
||||
pub TransactionBaseFee get(transaction_base_fee) config(): T::Balance;
|
||||
/// The fee to be paid for making a transaction; the per-byte portion.
|
||||
pub TransactionByteFee get(transaction_byte_fee): required T::Balance;
|
||||
pub TransactionByteFee get(transaction_byte_fee) config(): T::Balance;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(balances): Vec<(T::AccountId, T::Balance)>;
|
||||
build(|storage: &mut primitives::StorageMap, config: &GenesisConfig<T>| {
|
||||
let ids: Vec<_> = config.balances.iter().map(|x| x.0.clone()).collect();
|
||||
for i in 0..(ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE {
|
||||
storage.insert(GenesisConfig::<T>::hash(&<EnumSet<T>>::key_for(T::AccountIndex::sa(i))).to_vec(),
|
||||
ids[i * ENUM_SET_SIZE..ids.len().min((i + 1) * ENUM_SET_SIZE)].to_owned().encode());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Conensus module for runtime; manages the authority set ready for the native code.
|
||||
//! Consensus module for runtime; manages the authority set ready for the native code.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
@@ -118,7 +118,23 @@ decl_storage! {
|
||||
trait Store for Module<T: Trait> as Consensus {
|
||||
// Authorities set actual at the block execution start. IsSome only if
|
||||
// the set has been changed.
|
||||
OriginalAuthorities: Vec<T::SessionKey>;
|
||||
OriginalAuthorities: Option<Vec<T::SessionKey>>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(authorities): Vec<T::SessionKey>;
|
||||
#[serde(with = "substrate_primitives::bytes")]
|
||||
config(code): Vec<u8>;
|
||||
|
||||
build(|storage: &mut primitives::StorageMap, config: &GenesisConfig<T>| {
|
||||
use codec::{Encode, KeyedVec};
|
||||
|
||||
let auth_count = config.authorities.len() as u32;
|
||||
config.authorities.iter().enumerate().for_each(|(i, v)| {
|
||||
storage.insert((i as u32).to_keyed_vec(well_known_keys::AUTHORITY_PREFIX), v.encode());
|
||||
});
|
||||
storage.insert(well_known_keys::AUTHORITY_COUNT.to_vec(), auth_count.encode());
|
||||
storage.insert(well_known_keys::CODE.to_vec(), config.code.clone());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,37 +248,3 @@ impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
pub authorities: Vec<T::SessionKey>,
|
||||
#[serde(with = "substrate_primitives::bytes")]
|
||||
pub code: Vec<u8>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
authorities: vec![],
|
||||
code: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
|
||||
{
|
||||
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
|
||||
use codec::{Encode, KeyedVec};
|
||||
let auth_count = self.authorities.len() as u32;
|
||||
let mut r: primitives::StorageMap = self.authorities.into_iter().enumerate().map(|(i, v)|
|
||||
((i as u32).to_keyed_vec(well_known_keys::AUTHORITY_PREFIX), v.encode())
|
||||
).collect();
|
||||
r.insert(well_known_keys::AUTHORITY_COUNT.to_vec(), auth_count.encode());
|
||||
r.insert(well_known_keys::CODE.to_vec(), self.code);
|
||||
Ok(r.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
// Copyright 2018 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Substrate is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Build the contract module part of the genesis block storage.
|
||||
|
||||
#![cfg(feature = "std")]
|
||||
|
||||
use {Trait, ContractFee, CallBaseFee, CreateBaseFee, GasPrice, MaxDepth, BlockGasLimit};
|
||||
|
||||
use runtime_primitives;
|
||||
use runtime_primitives::traits::As;
|
||||
use runtime_io::twox_128;
|
||||
use runtime_support::StorageValue;
|
||||
use codec::Encode;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
pub contract_fee: T::Balance,
|
||||
pub call_base_fee: T::Gas,
|
||||
pub create_base_fee: T::Gas,
|
||||
pub gas_price: T::Balance,
|
||||
pub max_depth: u32,
|
||||
pub block_gas_limit: T::Gas,
|
||||
}
|
||||
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
contract_fee: T::Balance::sa(21),
|
||||
call_base_fee: T::Gas::sa(135),
|
||||
create_base_fee: T::Gas::sa(175),
|
||||
gas_price: T::Balance::sa(1),
|
||||
max_depth: 100,
|
||||
block_gas_limit: T::Gas::sa(1_000_000),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> runtime_primitives::BuildStorage for GenesisConfig<T> {
|
||||
fn build_storage(self) -> ::std::result::Result<runtime_primitives::StorageMap, String> {
|
||||
Ok(map![
|
||||
twox_128(<ContractFee<T>>::key()).to_vec() => self.contract_fee.encode(),
|
||||
twox_128(<CallBaseFee<T>>::key()).to_vec() => self.call_base_fee.encode(),
|
||||
twox_128(<CreateBaseFee<T>>::key()).to_vec() => self.create_base_fee.encode(),
|
||||
twox_128(<GasPrice<T>>::key()).to_vec() => self.gas_price.encode(),
|
||||
twox_128(<MaxDepth<T>>::key()).to_vec() => self.max_depth.encode(),
|
||||
twox_128(<BlockGasLimit<T>>::key()).to_vec() => self.block_gas_limit.encode()
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ extern crate parity_codec as codec;
|
||||
extern crate sr_io as runtime_io;
|
||||
extern crate sr_sandbox as sandbox;
|
||||
|
||||
#[macro_use]
|
||||
#[cfg_attr(not(feature = "std"), macro_use)]
|
||||
extern crate sr_std as rstd;
|
||||
|
||||
extern crate srml_balances as balances;
|
||||
@@ -93,13 +93,9 @@ mod exec;
|
||||
mod vm;
|
||||
mod gas;
|
||||
|
||||
mod genesis_config;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use genesis_config::GenesisConfig;
|
||||
use exec::ExecutionContext;
|
||||
use account_db::{AccountDb, OverlayAccountDb};
|
||||
use double_map::StorageDoubleMap;
|
||||
@@ -188,22 +184,22 @@ decl_event! {
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as Contract {
|
||||
/// The fee required to create a contract. At least as big as staking's ReclaimRebate.
|
||||
ContractFee get(contract_fee): required T::Balance;
|
||||
ContractFee get(contract_fee) config(): T::Balance = T::Balance::sa(21);
|
||||
/// The fee charged for a call into a contract.
|
||||
CallBaseFee get(call_base_fee): required T::Gas;
|
||||
CallBaseFee get(call_base_fee) config(): T::Gas = T::Gas::sa(135);
|
||||
/// The fee charged for a create of a contract.
|
||||
CreateBaseFee get(create_base_fee): required T::Gas;
|
||||
CreateBaseFee get(create_base_fee) config(): T::Gas = T::Gas::sa(175);
|
||||
/// The price of one unit of gas.
|
||||
GasPrice get(gas_price): required T::Balance;
|
||||
GasPrice get(gas_price) config(): T::Balance = T::Balance::sa(1);
|
||||
/// The maximum nesting level of a call/create stack.
|
||||
MaxDepth get(max_depth): required u32;
|
||||
MaxDepth get(max_depth) config(): u32 = 100;
|
||||
/// The maximum amount of gas that could be expended per block.
|
||||
BlockGasLimit get(block_gas_limit): required T::Gas;
|
||||
BlockGasLimit get(block_gas_limit) config(): T::Gas = T::Gas::sa(1_000_000);
|
||||
/// Gas spent so far in this block.
|
||||
GasSpent get(gas_spent): default T::Gas;
|
||||
GasSpent get(gas_spent): T::Gas;
|
||||
|
||||
/// The code associated with an account.
|
||||
pub CodeOf: default map [ T::AccountId => Vec<u8> ]; // TODO Vec<u8> values should be optimised to not do a length prefix.
|
||||
pub CodeOf: map T::AccountId => Vec<u8>; // TODO Vec<u8> values should be optimised to not do a length prefix.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ extern crate hex_literal;
|
||||
extern crate parity_codec as codec;
|
||||
#[macro_use] extern crate parity_codec_derive;
|
||||
extern crate substrate_primitives;
|
||||
#[macro_use] extern crate sr_std as rstd;
|
||||
#[cfg_attr(not(feature = "std"), macro_use)]
|
||||
extern crate sr_std as rstd;
|
||||
extern crate sr_io as runtime_io;
|
||||
#[macro_use] extern crate srml_support;
|
||||
extern crate sr_primitives as primitives;
|
||||
@@ -40,86 +41,12 @@ extern crate srml_balances as balances;
|
||||
extern crate srml_democracy as democracy;
|
||||
extern crate srml_system as system;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use rstd::prelude::*;
|
||||
#[cfg(feature = "std")]
|
||||
use primitives::traits::As;
|
||||
#[cfg(feature = "std")]
|
||||
use srml_support::StorageValue;
|
||||
|
||||
pub mod voting;
|
||||
pub mod motions;
|
||||
pub mod seats;
|
||||
|
||||
pub use seats::{Trait, Module, RawEvent, Event, VoteIndex};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig<T: seats::Trait> {
|
||||
// for the voting onto the council
|
||||
pub candidacy_bond: T::Balance,
|
||||
pub voter_bond: T::Balance,
|
||||
pub present_slash_per_voter: T::Balance,
|
||||
pub carry_count: u32,
|
||||
pub active_council: Vec<(T::AccountId, T::BlockNumber)>,
|
||||
pub approval_voting_period: T::BlockNumber,
|
||||
pub presentation_duration: T::BlockNumber,
|
||||
pub desired_seats: u32,
|
||||
pub term_duration: T::BlockNumber,
|
||||
pub inactive_grace_period: T::BlockNumber,
|
||||
|
||||
// for the council's votes.
|
||||
pub cooloff_period: T::BlockNumber,
|
||||
pub voting_period: T::BlockNumber,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: seats::Trait + voting::Trait + motions::Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
candidacy_bond: T::Balance::sa(9),
|
||||
voter_bond: T::Balance::sa(0),
|
||||
present_slash_per_voter: T::Balance::sa(1),
|
||||
carry_count: 2,
|
||||
inactive_grace_period: T::BlockNumber::sa(1),
|
||||
active_council: vec![],
|
||||
approval_voting_period: T::BlockNumber::sa(1000),
|
||||
presentation_duration: T::BlockNumber::sa(1000),
|
||||
desired_seats: 0,
|
||||
term_duration: T::BlockNumber::sa(5),
|
||||
cooloff_period: T::BlockNumber::sa(1000),
|
||||
voting_period: T::BlockNumber::sa(3),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: seats::Trait + voting::Trait + motions::Trait> primitives::BuildStorage for GenesisConfig<T>
|
||||
{
|
||||
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
|
||||
use codec::Encode;
|
||||
|
||||
Ok(map![
|
||||
Self::hash(<seats::CandidacyBond<T>>::key()).to_vec() => self.candidacy_bond.encode(),
|
||||
Self::hash(<seats::VotingBond<T>>::key()).to_vec() => self.voter_bond.encode(),
|
||||
Self::hash(<seats::PresentSlashPerVoter<T>>::key()).to_vec() => self.present_slash_per_voter.encode(),
|
||||
Self::hash(<seats::CarryCount<T>>::key()).to_vec() => self.carry_count.encode(),
|
||||
Self::hash(<seats::PresentationDuration<T>>::key()).to_vec() => self.presentation_duration.encode(),
|
||||
Self::hash(<seats::VotingPeriod<T>>::key()).to_vec() => self.approval_voting_period.encode(),
|
||||
Self::hash(<seats::TermDuration<T>>::key()).to_vec() => self.term_duration.encode(),
|
||||
Self::hash(<seats::DesiredSeats<T>>::key()).to_vec() => self.desired_seats.encode(),
|
||||
Self::hash(<seats::InactiveGracePeriod<T>>::key()).to_vec() => self.inactive_grace_period.encode(),
|
||||
Self::hash(<seats::ActiveCouncil<T>>::key()).to_vec() => self.active_council.encode(),
|
||||
|
||||
Self::hash(<voting::CooloffPeriod<T>>::key()).to_vec() => self.cooloff_period.encode(),
|
||||
Self::hash(<voting::VotingPeriod<T>>::key()).to_vec() => self.voting_period.encode(),
|
||||
Self::hash(<voting::Proposals<T>>::key()).to_vec() => vec![0u8; 0].encode()
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
// These re-exports are here for a reason, edit with care
|
||||
@@ -205,7 +132,7 @@ mod tests {
|
||||
voting_period: 3,
|
||||
minimum_deposit: 1,
|
||||
}.build_storage().unwrap());
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
t.extend(seats::GenesisConfig::<Test> {
|
||||
candidacy_bond: 9,
|
||||
voter_bond: 3,
|
||||
present_slash_per_voter: 1,
|
||||
@@ -220,6 +147,8 @@ mod tests {
|
||||
presentation_duration: 2,
|
||||
desired_seats: 2,
|
||||
term_duration: 5,
|
||||
}.build_storage().unwrap());
|
||||
t.extend(voting::GenesisConfig::<Test> {
|
||||
cooloff_period: 2,
|
||||
voting_period: 1,
|
||||
}.build_storage().unwrap());
|
||||
|
||||
@@ -75,13 +75,17 @@ decl_module! {
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as CouncilMotions {
|
||||
/// The (hashes of) the active proposals.
|
||||
pub Proposals get(proposals): default Vec<T::Hash>;
|
||||
pub Proposals get(proposals): Vec<T::Hash>;
|
||||
/// Actual proposal for a given hash, if it's current.
|
||||
pub ProposalOf get(proposal_of): map [ T::Hash => <T as Trait>::Proposal ];
|
||||
pub ProposalOf get(proposal_of): map T::Hash => Option< <T as Trait>::Proposal >;
|
||||
/// Votes for a given proposal: (required_yes_votes, yes_voters, no_voters).
|
||||
pub Voting get(voting): map [ T::Hash => (ProposalIndex, u32, Vec<T::AccountId>, Vec<T::AccountId>) ];
|
||||
pub Voting get(voting): map T::Hash => Option<(ProposalIndex, u32, Vec<T::AccountId>, Vec<T::AccountId>)>;
|
||||
/// Proposals so far.
|
||||
pub ProposalCount get(proposal_count): default u32;
|
||||
pub ProposalCount get(proposal_count): u32;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(_marker): ::std::marker::PhantomData<T>;
|
||||
build(|_, _| {});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,53 +104,53 @@ decl_storage! {
|
||||
|
||||
// parameters
|
||||
/// How much should be locked up in order to submit one's candidacy.
|
||||
pub CandidacyBond get(candidacy_bond): required T::Balance;
|
||||
pub CandidacyBond get(candidacy_bond) config(): T::Balance = T::Balance::sa(9);
|
||||
/// How much should be locked up in order to be able to submit votes.
|
||||
pub VotingBond get(voting_bond): required T::Balance;
|
||||
pub VotingBond get(voting_bond) config(voter_bond): T::Balance;
|
||||
/// The punishment, per voter, if you provide an invalid presentation.
|
||||
pub PresentSlashPerVoter get(present_slash_per_voter): required T::Balance;
|
||||
pub PresentSlashPerVoter get(present_slash_per_voter) config(): T::Balance = T::Balance::sa(1);
|
||||
/// How many runners-up should have their approvals persist until the next vote.
|
||||
pub CarryCount get(carry_count): required u32;
|
||||
pub CarryCount get(carry_count) config(): u32 = 2;
|
||||
/// How long to give each top candidate to present themselves after the vote ends.
|
||||
pub PresentationDuration get(presentation_duration): required T::BlockNumber;
|
||||
pub PresentationDuration get(presentation_duration) config(): T::BlockNumber = T::BlockNumber::sa(1000);
|
||||
/// How many votes need to go by after a voter's last vote before they can be reaped if their
|
||||
/// approvals are moot.
|
||||
pub InactiveGracePeriod get(inactivity_grace_period): required VoteIndex;
|
||||
pub InactiveGracePeriod get(inactivity_grace_period) config(inactive_grace_period): VoteIndex = 1;
|
||||
/// How often (in blocks) to check for new votes.
|
||||
pub VotingPeriod get(voting_period): required T::BlockNumber;
|
||||
pub VotingPeriod get(voting_period) config(approval_voting_period): T::BlockNumber = T::BlockNumber::sa(1000);
|
||||
/// How long each position is active for.
|
||||
pub TermDuration get(term_duration): required T::BlockNumber;
|
||||
pub TermDuration get(term_duration) config(): T::BlockNumber = T::BlockNumber::sa(5);
|
||||
/// Number of accounts that should be sitting on the council.
|
||||
pub DesiredSeats get(desired_seats): required u32;
|
||||
pub DesiredSeats get(desired_seats) config(): u32;
|
||||
|
||||
// permanent state (always relevant, changes only at the finalisation of voting)
|
||||
/// The current council. When there's a vote going on, this should still be used for executive
|
||||
/// matters.
|
||||
pub ActiveCouncil get(active_council): default Vec<(T::AccountId, T::BlockNumber)>;
|
||||
pub ActiveCouncil get(active_council) config(): Vec<(T::AccountId, T::BlockNumber)>;
|
||||
/// The total number of votes that have happened or are in progress.
|
||||
pub VoteCount get(vote_index): default VoteIndex;
|
||||
pub VoteCount get(vote_index): VoteIndex;
|
||||
|
||||
// persistent state (always relevant, changes constantly)
|
||||
/// The last cleared vote index that this voter was last active at.
|
||||
pub ApprovalsOf get(approvals_of): default map [ T::AccountId => Vec<bool> ];
|
||||
pub ApprovalsOf get(approvals_of): map T::AccountId => Vec<bool>;
|
||||
/// The vote index and list slot that the candidate `who` was registered or `None` if they are not
|
||||
/// currently registered.
|
||||
pub RegisterInfoOf get(candidate_reg_info): map [ T::AccountId => (VoteIndex, u32) ];
|
||||
pub RegisterInfoOf get(candidate_reg_info): map T::AccountId => Option<(VoteIndex, u32)>;
|
||||
/// The last cleared vote index that this voter was last active at.
|
||||
pub LastActiveOf get(voter_last_active): map [ T::AccountId => VoteIndex ];
|
||||
pub LastActiveOf get(voter_last_active): map T::AccountId => Option<VoteIndex>;
|
||||
/// The present voter list.
|
||||
pub Voters get(voters): default Vec<T::AccountId>;
|
||||
pub Voters get(voters): Vec<T::AccountId>;
|
||||
/// The present candidate list.
|
||||
pub Candidates get(candidates): default Vec<T::AccountId>; // has holes
|
||||
pub CandidateCount get(candidate_count): default u32;
|
||||
pub Candidates get(candidates): Vec<T::AccountId>; // has holes
|
||||
pub CandidateCount get(candidate_count): u32;
|
||||
|
||||
// temporary state (only relevant during finalisation/presentation)
|
||||
/// The accounts holding the seats that will become free on the next tally.
|
||||
pub NextFinalise get(next_finalise): (T::BlockNumber, u32, Vec<T::AccountId>);
|
||||
pub NextFinalise get(next_finalise): Option<(T::BlockNumber, u32, Vec<T::AccountId>)>;
|
||||
/// The stakes as they were at the point that the vote ended.
|
||||
pub SnapshotedStakes get(snapshoted_stakes): required Vec<T::Balance>;
|
||||
pub SnapshotedStakes get(snapshoted_stakes): Vec<T::Balance>;
|
||||
/// Get the leaderboard if we;re in the presentation phase.
|
||||
pub Leaderboard get(leaderboard): Vec<(T::Balance, T::AccountId)>; // ORDERED low -> high
|
||||
pub Leaderboard get(leaderboard): Option<Vec<(T::Balance, T::AccountId)> >; // ORDERED low -> high
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
use rstd::prelude::*;
|
||||
use rstd::borrow::Borrow;
|
||||
use primitives::traits::{OnFinalise, Hash};
|
||||
use primitives::traits::{OnFinalise, Hash, As};
|
||||
use runtime_io::print;
|
||||
use srml_support::dispatch::Result;
|
||||
use srml_support::{StorageValue, StorageMap, IsSubType};
|
||||
@@ -43,20 +43,20 @@ decl_module! {
|
||||
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as CouncilVoting {
|
||||
pub CooloffPeriod get(cooloff_period): required T::BlockNumber;
|
||||
pub VotingPeriod get(voting_period): required T::BlockNumber;
|
||||
pub Proposals get(proposals): required Vec<(T::BlockNumber, T::Hash)>; // ordered by expiry.
|
||||
pub ProposalOf get(proposal_of): map [ T::Hash => T::Proposal ];
|
||||
pub ProposalVoters get(proposal_voters): default map [ T::Hash => Vec<T::AccountId> ];
|
||||
pub CouncilVoteOf get(vote_of): map [ (T::Hash, T::AccountId) => bool ];
|
||||
pub VetoedProposal get(veto_of): map [ T::Hash => (T::BlockNumber, Vec<T::AccountId>) ];
|
||||
pub CooloffPeriod get(cooloff_period) config(): T::BlockNumber = T::BlockNumber::sa(1000);
|
||||
pub VotingPeriod get(voting_period) config(): T::BlockNumber = T::BlockNumber::sa(3);
|
||||
pub Proposals get(proposals) build(|_| vec![0u8; 0]): Vec<(T::BlockNumber, T::Hash)>; // ordered by expiry.
|
||||
pub ProposalOf get(proposal_of): map T::Hash => Option<T::Proposal>;
|
||||
pub ProposalVoters get(proposal_voters): map T::Hash => Vec<T::AccountId>;
|
||||
pub CouncilVoteOf get(vote_of): map (T::Hash, T::AccountId) => Option<bool>;
|
||||
pub VetoedProposal get(veto_of): map T::Hash => Option<(T::BlockNumber, Vec<T::AccountId>)>;
|
||||
}
|
||||
}
|
||||
|
||||
/// An event in this module.
|
||||
decl_event!(
|
||||
pub enum Event<T> where <T as system::Trait>::Hash {
|
||||
/// A voting tally has happened for a referendum cancelation vote.
|
||||
/// A voting tally has happened for a referendum cancellation vote.
|
||||
/// Last three are yes, no, abstain counts.
|
||||
TallyCancelation(Hash, u32, u32, u32),
|
||||
/// A voting tally has happened for a referendum vote.
|
||||
|
||||
@@ -27,7 +27,7 @@ extern crate serde_derive;
|
||||
|
||||
#[macro_use]
|
||||
extern crate parity_codec_derive;
|
||||
#[macro_use]
|
||||
#[cfg_attr(not(feature = "std"), macro_use)]
|
||||
extern crate sr_std as rstd;
|
||||
#[macro_use]
|
||||
extern crate srml_support;
|
||||
@@ -74,31 +74,31 @@ decl_storage! {
|
||||
trait Store for Module<T: Trait> as Democracy {
|
||||
|
||||
/// The number of (public) proposals that have been made so far.
|
||||
pub PublicPropCount get(public_prop_count): default PropIndex;
|
||||
pub PublicPropCount get(public_prop_count) build(|_| 0 as PropIndex) : PropIndex;
|
||||
/// The public proposals. Unsorted.
|
||||
pub PublicProps get(public_props): default Vec<(PropIndex, T::Proposal, T::AccountId)>;
|
||||
pub PublicProps get(public_props): Vec<(PropIndex, T::Proposal, T::AccountId)>;
|
||||
/// Those who have locked a deposit.
|
||||
pub DepositOf get(deposit_of): map [ PropIndex => (T::Balance, Vec<T::AccountId>) ];
|
||||
pub DepositOf get(deposit_of): map PropIndex => Option<(T::Balance, Vec<T::AccountId>)>;
|
||||
/// How often (in blocks) new public referenda are launched.
|
||||
pub LaunchPeriod get(launch_period): required T::BlockNumber;
|
||||
pub LaunchPeriod get(launch_period) config(): T::BlockNumber = T::BlockNumber::sa(1000);
|
||||
/// The minimum amount to be used as a deposit for a public referendum proposal.
|
||||
pub MinimumDeposit get(minimum_deposit): required T::Balance;
|
||||
pub MinimumDeposit get(minimum_deposit) config(): T::Balance;
|
||||
|
||||
/// How often (in blocks) to check for new votes.
|
||||
pub VotingPeriod get(voting_period): required T::BlockNumber;
|
||||
pub VotingPeriod get(voting_period) config(): T::BlockNumber = T::BlockNumber::sa(1000);
|
||||
|
||||
/// The next free referendum index, aka the number of referendums started so far.
|
||||
pub ReferendumCount get(referendum_count): required ReferendumIndex;
|
||||
pub ReferendumCount get(referendum_count) build(|_| 0 as ReferendumIndex): ReferendumIndex;
|
||||
/// The next referendum index that should be tallied.
|
||||
pub NextTally get(next_tally): required ReferendumIndex;
|
||||
pub NextTally get(next_tally) build(|_| 0 as ReferendumIndex): ReferendumIndex;
|
||||
/// Information concerning any given referendum.
|
||||
pub ReferendumInfoOf get(referendum_info): map [ ReferendumIndex => (T::BlockNumber, T::Proposal, VoteThreshold) ];
|
||||
pub ReferendumInfoOf get(referendum_info): map ReferendumIndex => Option<(T::BlockNumber, T::Proposal, VoteThreshold)>;
|
||||
|
||||
/// Get the voters for the current proposal.
|
||||
pub VotersFor get(voters_for): default map [ ReferendumIndex => Vec<T::AccountId> ];
|
||||
pub VotersFor get(voters_for): map ReferendumIndex => Vec<T::AccountId>;
|
||||
|
||||
/// Get the vote, if Some, of `who`.
|
||||
pub VoteOf get(vote_of): map [ (ReferendumIndex, T::AccountId) => bool ];
|
||||
pub VoteOf get(vote_of): map (ReferendumIndex, T::AccountId) => Option<bool>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,55 +311,6 @@ impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
pub launch_period: T::BlockNumber,
|
||||
pub voting_period: T::BlockNumber,
|
||||
pub minimum_deposit: T::Balance,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> GenesisConfig<T> {
|
||||
pub fn new() -> Self {
|
||||
GenesisConfig {
|
||||
launch_period: T::BlockNumber::sa(1),
|
||||
voting_period: T::BlockNumber::sa(1),
|
||||
minimum_deposit: T::Balance::sa(1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
launch_period: T::BlockNumber::sa(1000),
|
||||
voting_period: T::BlockNumber::sa(1000),
|
||||
minimum_deposit: T::Balance::sa(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
|
||||
{
|
||||
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
|
||||
use codec::Encode;
|
||||
|
||||
Ok(map![
|
||||
Self::hash(<LaunchPeriod<T>>::key()).to_vec() => self.launch_period.encode(),
|
||||
Self::hash(<VotingPeriod<T>>::key()).to_vec() => self.voting_period.encode(),
|
||||
Self::hash(<MinimumDeposit<T>>::key()).to_vec() => self.minimum_deposit.encode(),
|
||||
Self::hash(<ReferendumCount<T>>::key()).to_vec() => (0 as ReferendumIndex).encode(),
|
||||
Self::hash(<NextTally<T>>::key()).to_vec() => (0 as ReferendumIndex).encode(),
|
||||
Self::hash(<PublicPropCount<T>>::key()).to_vec() => (0 as PropIndex).encode()
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
// Assert macros used in tests.
|
||||
#[cfg_attr(feature = "std", macro_use)]
|
||||
extern crate sr_std;
|
||||
|
||||
// Needed for tests (`with_externalities`).
|
||||
@@ -88,7 +87,7 @@ pub trait Trait: balances::Trait {
|
||||
// Information about where this dispatch initiated from is provided as the first argument
|
||||
// "origin". As such functions must always look like:
|
||||
//
|
||||
// `fn foo(origin, bar: Bar, baz: Baz) -> Result = 0;`
|
||||
// `fn foo(origin, bar: Bar, baz: Baz) -> Result;`
|
||||
//
|
||||
// The `Result` is required as part of the syntax (and expands to the conventional dispatch
|
||||
// result of `Result<(), &'static str>`).
|
||||
@@ -134,23 +133,20 @@ decl_storage! {
|
||||
// keep things around between blocks.
|
||||
trait Store for Module<T: Trait> as Example {
|
||||
// Any storage declarations of the form:
|
||||
// `pub? Name get(getter_name)? : [required | default]? <type>;`
|
||||
// `pub? Name get(getter_name)? [config()|config(myname)] [build(|_| {...})] : <type> (= <new_default_value>)?;`
|
||||
// where `<type>` is either:
|
||||
// - `Type` (a basic value item); or
|
||||
// - `map [ KeyType => ValueType ]` (a map item).
|
||||
// - `map KeyType => ValueType` (a map item).
|
||||
//
|
||||
// Note that there are two optional modifiers for the storage type declaration.
|
||||
// - `Foo: u32`:
|
||||
// - `Foo: Option<u32>`:
|
||||
// - `Foo::put(1); Foo::get()` returns `Some(1)`;
|
||||
// - `Foo::kill(); Foo::get()` returns `None`.
|
||||
// - `Foo: required u32`:
|
||||
// - `Foo::put(1); Foo::get()` returns `1`;
|
||||
// - `Foo::kill(); Foo::get()` panics.
|
||||
// - `Foo: default u32`:
|
||||
// - `Foo: u32`:
|
||||
// - `Foo::put(1); Foo::get()` returns `1`;
|
||||
// - `Foo::kill(); Foo::get()` returns `0` (u32::default()).
|
||||
// e.g. Foo: u32;
|
||||
// e.g. pub Bar get(bar): default map [ T::AccountId => Vec<(T::Balance, u64)> ];
|
||||
// e.g. pub Bar get(bar): map T::AccountId => Vec<(T::Balance, u64)>;
|
||||
//
|
||||
// For basic value items, you'll get a type which implements
|
||||
// `runtime_support::StorageValue`. For map items, you'll get a type which
|
||||
@@ -159,10 +155,10 @@ decl_storage! {
|
||||
// If they have a getter (`get(getter_name)`), then your module will come
|
||||
// equipped with `fn getter_name() -> Type` for basic value items or
|
||||
// `fn getter_name(key: KeyType) -> ValueType` for map items.
|
||||
Dummy get(dummy): T::Balance;
|
||||
Dummy get(dummy) config(): Option<T::Balance>;
|
||||
|
||||
// this one uses the default, we'll demonstrate the usage of 'mutate' API.
|
||||
Foo get(foo): default T::Balance;
|
||||
Foo get(foo) config(): T::Balance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,47 +276,6 @@ impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
/// The genesis block configuration type. This is a simple default-capable struct that
|
||||
/// contains any fields with which this module can be configured at genesis time.
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
/// A value with which to initialise the Dummy storage item.
|
||||
pub dummy: T::Balance,
|
||||
pub foo: T::Balance,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
dummy: Default::default(),
|
||||
foo: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This expresses the specific key/value pairs that must be placed in storage in order
|
||||
// to initialise the module and properly reflect the configuration.
|
||||
//
|
||||
// Ideally this would re-use the `::put` logic in the storage item type for introducing
|
||||
// the values into the `StorageMap` (which is just a `HashMap<Vec<u8>, Vec<u8>>`). That
|
||||
// is not yet in place, though, so for now we do everything "manually", using `hash`,
|
||||
// `::key()` and `.to_vec()` for the key and `.encode()` for the value.
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: Trait> runtime_primitives::BuildStorage for GenesisConfig<T>
|
||||
{
|
||||
fn build_storage(self) -> ::std::result::Result<runtime_primitives::StorageMap, String> {
|
||||
use codec::Encode;
|
||||
Ok(map![
|
||||
Self::hash(<Dummy<T>>::key()).to_vec() => self.dummy.encode(),
|
||||
Self::hash(<Foo<T>>::key()).to_vec() => self.foo.encode()
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -256,9 +256,8 @@ pub enum StorageFunctionType {
|
||||
#[derive(Clone, PartialEq, Eq, Encode)]
|
||||
#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))]
|
||||
pub enum StorageFunctionModifier {
|
||||
None,
|
||||
Optional,
|
||||
Default,
|
||||
Required,
|
||||
}
|
||||
|
||||
/// All metadata about the outer dispatch.
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
#[cfg_attr(feature = "std", macro_use)]
|
||||
extern crate sr_std as rstd;
|
||||
|
||||
#[macro_use]
|
||||
@@ -87,23 +86,23 @@ decl_storage! {
|
||||
trait Store for Module<T: Trait> as Session {
|
||||
|
||||
/// The current set of validators.
|
||||
pub Validators get(validators): required Vec<T::AccountId>;
|
||||
pub Validators get(validators) config(): Vec<T::AccountId>;
|
||||
/// Current length of the session.
|
||||
pub SessionLength get(length): required T::BlockNumber;
|
||||
pub SessionLength get(length) config(session_length): T::BlockNumber = T::BlockNumber::sa(1000);
|
||||
/// Current index of the session.
|
||||
pub CurrentIndex get(current_index): required T::BlockNumber;
|
||||
pub CurrentIndex get(current_index) build(|_| T::BlockNumber::sa(0)): T::BlockNumber;
|
||||
/// Timestamp when current session started.
|
||||
pub CurrentStart get(current_start): required T::Moment;
|
||||
pub CurrentStart get(current_start) build(|_| T::Moment::zero()): T::Moment;
|
||||
|
||||
/// New session is being forced is this entry exists; in which case, the boolean value is whether
|
||||
/// the new session should be considered a normal rotation (rewardable) or exceptional (slashable).
|
||||
pub ForcingNewSession get(forcing_new_session): bool;
|
||||
pub ForcingNewSession get(forcing_new_session): Option<bool>;
|
||||
/// Block at which the session length last changed.
|
||||
LastLengthChange: T::BlockNumber;
|
||||
LastLengthChange: Option<T::BlockNumber>;
|
||||
/// The next key for a given validator.
|
||||
NextKeyFor: map [ T::AccountId => T::SessionKey ];
|
||||
NextKeyFor: map T::AccountId => Option<T::SessionKey>;
|
||||
/// The next session length.
|
||||
NextSessionLength: T::BlockNumber;
|
||||
NextSessionLength: Option<T::BlockNumber>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,41 +233,6 @@ impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
pub session_length: T::BlockNumber,
|
||||
pub validators: Vec<T::AccountId>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
use primitives::traits::As;
|
||||
GenesisConfig {
|
||||
session_length: T::BlockNumber::sa(1000),
|
||||
validators: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
|
||||
{
|
||||
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
|
||||
use codec::Encode;
|
||||
use primitives::traits::As;
|
||||
Ok(map![
|
||||
Self::hash(<SessionLength<T>>::key()).to_vec() => self.session_length.encode(),
|
||||
Self::hash(<CurrentIndex<T>>::key()).to_vec() => T::BlockNumber::sa(0).encode(),
|
||||
Self::hash(<CurrentStart<T>>::key()).to_vec() => T::Moment::zero().encode(),
|
||||
Self::hash(<Validators<T>>::key()).to_vec() => self.validators.encode()
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
// Copyright 2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Substrate is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Build a staking genesis block.
|
||||
|
||||
#![cfg(feature = "std")]
|
||||
|
||||
use rstd::prelude::*;
|
||||
use codec::Encode;
|
||||
use runtime_support::StorageValue;
|
||||
use primitives::traits::As;
|
||||
use primitives::{self, Perbill};
|
||||
use super::{Trait, Intentions, CurrentEra, OfflineSlashGrace, MinimumValidatorCount,
|
||||
BondingDuration, SessionsPerEra, ValidatorCount, SessionReward, OfflineSlash,
|
||||
CurrentSessionReward, CurrentOfflineSlash};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
pub sessions_per_era: T::BlockNumber,
|
||||
pub current_era: T::BlockNumber,
|
||||
pub intentions: Vec<T::AccountId>,
|
||||
pub validator_count: u32,
|
||||
pub minimum_validator_count: u32,
|
||||
pub bonding_duration: T::BlockNumber,
|
||||
pub session_reward: Perbill,
|
||||
pub offline_slash: Perbill,
|
||||
pub current_session_reward: T::Balance,
|
||||
pub current_offline_slash: T::Balance,
|
||||
pub offline_slash_grace: u32,
|
||||
}
|
||||
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
sessions_per_era: T::BlockNumber::sa(1000),
|
||||
current_era: T::BlockNumber::sa(0),
|
||||
intentions: vec![],
|
||||
validator_count: 0,
|
||||
minimum_validator_count: 0,
|
||||
bonding_duration: T::BlockNumber::sa(1000),
|
||||
session_reward: Perbill::from_billionths(60),
|
||||
offline_slash: Perbill::from_fraction(0.001),
|
||||
current_session_reward: T::Balance::sa(0),
|
||||
current_offline_slash: T::Balance::sa(0),
|
||||
offline_slash_grace: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
|
||||
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
|
||||
Ok(map![
|
||||
Self::hash(<Intentions<T>>::key()).to_vec() => self.intentions.encode(),
|
||||
Self::hash(<SessionsPerEra<T>>::key()).to_vec() => self.sessions_per_era.encode(),
|
||||
Self::hash(<ValidatorCount<T>>::key()).to_vec() => self.validator_count.encode(),
|
||||
Self::hash(<MinimumValidatorCount<T>>::key()).to_vec() => self.minimum_validator_count.encode(),
|
||||
Self::hash(<BondingDuration<T>>::key()).to_vec() => self.bonding_duration.encode(),
|
||||
Self::hash(<CurrentEra<T>>::key()).to_vec() => self.current_era.encode(),
|
||||
Self::hash(<SessionReward<T>>::key()).to_vec() => self.session_reward.encode(),
|
||||
Self::hash(<OfflineSlash<T>>::key()).to_vec() => self.offline_slash.encode(),
|
||||
Self::hash(<CurrentSessionReward<T>>::key()).to_vec() => self.current_session_reward.encode(),
|
||||
Self::hash(<CurrentOfflineSlash<T>>::key()).to_vec() => self.current_offline_slash.encode(),
|
||||
Self::hash(<OfflineSlashGrace<T>>::key()).to_vec() => self.offline_slash_grace.encode()
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate srml_support as runtime_support;
|
||||
|
||||
#[cfg_attr(feature = "std", macro_use)]
|
||||
extern crate sr_std as rstd;
|
||||
|
||||
#[macro_use]
|
||||
@@ -62,12 +61,8 @@ use system::ensure_signed;
|
||||
mod mock;
|
||||
|
||||
mod tests;
|
||||
mod genesis_config;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use genesis_config::GenesisConfig;
|
||||
|
||||
const DEFAULT_MINIMUM_VALIDATOR_COUNT: usize = 4;
|
||||
const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4;
|
||||
|
||||
#[derive(PartialEq, Clone)]
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
@@ -83,7 +78,7 @@ pub enum LockStatus<BlockNumber: Parameter> {
|
||||
pub struct ValidatorPrefs<Balance> {
|
||||
/// Validator should ensure this many more slashes than is necessary before being unstaked.
|
||||
pub unstake_threshold: u32,
|
||||
// Reward that validator takes up-front; only the rest is split between themself and nominators.
|
||||
// Reward that validator takes up-front; only the rest is split between themselves and nominators.
|
||||
pub validator_payment: Balance,
|
||||
}
|
||||
|
||||
@@ -140,53 +135,53 @@ decl_storage! {
|
||||
trait Store for Module<T: Trait> as Staking {
|
||||
|
||||
/// The ideal number of staking participants.
|
||||
pub ValidatorCount get(validator_count): required u32;
|
||||
pub ValidatorCount get(validator_count) config(): u32;
|
||||
/// Minimum number of staking participants before emergency conditions are imposed.
|
||||
pub MinimumValidatorCount: u32;
|
||||
pub MinimumValidatorCount get(minimum_validator_count) config(): u32 = DEFAULT_MINIMUM_VALIDATOR_COUNT;
|
||||
/// The length of a staking era in sessions.
|
||||
pub SessionsPerEra get(sessions_per_era): required T::BlockNumber;
|
||||
pub SessionsPerEra get(sessions_per_era) config(): T::BlockNumber = T::BlockNumber::sa(1000);
|
||||
/// Maximum reward, per validator, that is provided per acceptable session.
|
||||
pub SessionReward get(session_reward): required Perbill;
|
||||
pub SessionReward get(session_reward) config(): Perbill = Perbill::from_billionths(60);
|
||||
/// Slash, per validator that is taken for the first time they are found to be offline.
|
||||
pub OfflineSlash get(offline_slash): required Perbill;
|
||||
pub OfflineSlash get(offline_slash) config(): Perbill = Perbill::from_millionths(1000); // Perbill::from_fraction() is only for std, so use from_millionths().
|
||||
/// Number of instances of offline reports before slashing begins for validators.
|
||||
pub OfflineSlashGrace get(offline_slash_grace): default u32;
|
||||
pub OfflineSlashGrace get(offline_slash_grace) config(): u32;
|
||||
/// The length of the bonding duration in blocks.
|
||||
pub BondingDuration get(bonding_duration): required T::BlockNumber;
|
||||
pub BondingDuration get(bonding_duration) config(): T::BlockNumber = T::BlockNumber::sa(1000);
|
||||
|
||||
/// The current era index.
|
||||
pub CurrentEra get(current_era): required T::BlockNumber;
|
||||
pub CurrentEra get(current_era) config(): T::BlockNumber;
|
||||
/// Preferences that a validator has.
|
||||
pub ValidatorPreferences get(validator_preferences): default map [ T::AccountId => ValidatorPrefs<T::Balance> ];
|
||||
pub ValidatorPreferences get(validator_preferences): map T::AccountId => ValidatorPrefs<T::Balance>;
|
||||
/// All the accounts with a desire to stake.
|
||||
pub Intentions get(intentions): default Vec<T::AccountId>;
|
||||
pub Intentions get(intentions) config(): Vec<T::AccountId>;
|
||||
/// All nominator -> nominee relationships.
|
||||
pub Nominating get(nominating): map [ T::AccountId => T::AccountId ];
|
||||
pub Nominating get(nominating): map T::AccountId => Option<T::AccountId>;
|
||||
/// Nominators for a particular account.
|
||||
pub NominatorsFor get(nominators_for): default map [ T::AccountId => Vec<T::AccountId> ];
|
||||
pub NominatorsFor get(nominators_for): map T::AccountId => Vec<T::AccountId>;
|
||||
/// Nominators for a particular account that is in action right now.
|
||||
pub CurrentNominatorsFor get(current_nominators_for): default map [ T::AccountId => Vec<T::AccountId> ];
|
||||
pub CurrentNominatorsFor get(current_nominators_for): map T::AccountId => Vec<T::AccountId>;
|
||||
|
||||
/// Maximum reward, per validator, that is provided per acceptable session.
|
||||
pub CurrentSessionReward get(current_session_reward): default T::Balance;
|
||||
pub CurrentSessionReward get(current_session_reward) config(): T::Balance;
|
||||
/// Slash, per validator that is taken for the first time they are found to be offline.
|
||||
pub CurrentOfflineSlash get(current_offline_slash): default T::Balance;
|
||||
pub CurrentOfflineSlash get(current_offline_slash) config(): T::Balance;
|
||||
|
||||
/// The next value of sessions per era.
|
||||
pub NextSessionsPerEra get(next_sessions_per_era): T::BlockNumber;
|
||||
pub NextSessionsPerEra get(next_sessions_per_era): Option<T::BlockNumber>;
|
||||
/// The session index at which the era length last changed.
|
||||
pub LastEraLengthChange get(last_era_length_change): default T::BlockNumber;
|
||||
pub LastEraLengthChange get(last_era_length_change): T::BlockNumber;
|
||||
|
||||
/// The highest and lowest staked validator slashable balances.
|
||||
pub StakeRange get(stake_range): default PairOf<T::Balance>;
|
||||
pub StakeRange get(stake_range): PairOf<T::Balance>;
|
||||
|
||||
/// The block at which the `who`'s funds become entirely liquid.
|
||||
pub Bondage get(bondage): default map [ T::AccountId => T::BlockNumber ];
|
||||
pub Bondage get(bondage): map T::AccountId => T::BlockNumber;
|
||||
/// The number of times a given validator has been reported offline. This gets decremented by one each era that passes.
|
||||
pub SlashCount get(slash_count): default map [ T::AccountId => u32 ];
|
||||
pub SlashCount get(slash_count): map T::AccountId => u32;
|
||||
|
||||
/// We are forcing a new era.
|
||||
pub ForcingNewEra get(forcing_new_era): ();
|
||||
pub ForcingNewEra get(forcing_new_era): Option<()>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,11 +194,6 @@ impl<T: Trait> Module<T> {
|
||||
|
||||
// PUBLIC IMMUTABLES
|
||||
|
||||
/// MinimumValidatorCount getter, introduces a default.
|
||||
pub fn minimum_validator_count() -> usize {
|
||||
<MinimumValidatorCount<T>>::get().map(|v| v as usize).unwrap_or(DEFAULT_MINIMUM_VALIDATOR_COUNT)
|
||||
}
|
||||
|
||||
/// The length of a staking era in blocks.
|
||||
pub fn era_length() -> T::BlockNumber {
|
||||
Self::sessions_per_era() * <session::Module<T>>::length()
|
||||
@@ -256,7 +246,7 @@ impl<T: Trait> Module<T> {
|
||||
fn unstake(origin: T::Origin, intentions_index: u32) -> Result {
|
||||
let who = ensure_signed(origin)?;
|
||||
// unstake fails in degenerate case of having too few existing staked parties
|
||||
if Self::intentions().len() <= Self::minimum_validator_count() {
|
||||
if Self::intentions().len() <= Self::minimum_validator_count() as usize {
|
||||
return Err("cannot unstake when there are too few staked participants")
|
||||
}
|
||||
Self::apply_unstake(&who, intentions_index as usize)
|
||||
@@ -375,7 +365,7 @@ impl<T: Trait> Module<T> {
|
||||
fn slash_validator(v: &T::AccountId, slash: T::Balance) {
|
||||
// skip the slash in degenerate case of having only 4 staking participants despite having a larger
|
||||
// desired number of validators (validator_count).
|
||||
if Self::intentions().len() <= Self::minimum_validator_count() {
|
||||
if Self::intentions().len() <= Self::minimum_validator_count() as usize {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -490,7 +480,7 @@ impl<T: Trait> Module<T> {
|
||||
|
||||
// Avoid reevaluate validator set if it would leave us with fewer than the minimum
|
||||
// needed validators
|
||||
if intentions.len() < Self::minimum_validator_count() {
|
||||
if intentions.len() < Self::minimum_validator_count() as usize {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ parity-codec = { version = "2.0", default-features = false }
|
||||
substrate-metadata = { path = "../metadata", default-features = false }
|
||||
sr-std = { path = "../../core/sr-std", default-features = false }
|
||||
sr-io = { path = "../../core/sr-io", default-features = false }
|
||||
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
|
||||
mashup = "0.1.7"
|
||||
|
||||
[dev-dependencies]
|
||||
@@ -26,6 +27,7 @@ std = [
|
||||
"sr-io/std",
|
||||
"parity-codec/std",
|
||||
"sr-std/std",
|
||||
"sr-primitives/std",
|
||||
"substrate-metadata/std",
|
||||
]
|
||||
nightly = []
|
||||
|
||||
@@ -29,6 +29,8 @@ extern crate serde;
|
||||
|
||||
extern crate sr_std as rstd;
|
||||
extern crate sr_io as runtime_io;
|
||||
#[cfg(feature = "std")]
|
||||
pub extern crate sr_primitives as runtime_primitives;
|
||||
extern crate substrate_metadata;
|
||||
|
||||
extern crate mashup;
|
||||
|
||||
@@ -188,7 +188,11 @@ mod tests {
|
||||
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as TestStorage {
|
||||
StorageMethod : u32;
|
||||
StorageMethod : Option<u32>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(_marker) : ::std::marker::PhantomData<T>;
|
||||
build(|_, _| {});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,7 +316,7 @@ mod tests {
|
||||
functions: DecodeDifferent::Encode(&[
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("StorageMethod"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
modifier: StorageFunctionModifier::Optional,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -179,19 +179,35 @@ impl From<RawLog<substrate_primitives::H256>> for primitives::testing::DigestIte
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as System {
|
||||
|
||||
pub AccountNonce get(account_nonce): default map [ T::AccountId => T::Index ];
|
||||
pub AccountNonce get(account_nonce): map T::AccountId => T::Index;
|
||||
|
||||
ExtrinsicCount: u32;
|
||||
pub BlockHash get(block_hash): required map [ T::BlockNumber => T::Hash ];
|
||||
ExtrinsicData get(extrinsic_data): required map [ u32 => Vec<u8> ];
|
||||
RandomSeed get(random_seed): required T::Hash;
|
||||
ExtrinsicCount: Option<u32>;
|
||||
pub BlockHash get(block_hash) build(|_| vec![(T::BlockNumber::zero(), [69u8; 32])]): map T::BlockNumber => T::Hash;
|
||||
ExtrinsicData get(extrinsic_data): map u32 => Vec<u8>;
|
||||
RandomSeed get(random_seed) build(|_| [0u8; 32]): T::Hash;
|
||||
/// The current block number being processed. Set by `execute_block`.
|
||||
Number get(block_number): required T::BlockNumber;
|
||||
ParentHash get(parent_hash): required T::Hash;
|
||||
ExtrinsicsRoot get(extrinsics_root): required T::Hash;
|
||||
Digest get(digest): default T::Digest;
|
||||
Number get(block_number) build(|_| 1u64): T::BlockNumber;
|
||||
ParentHash get(parent_hash) build(|_| [69u8; 32]): T::Hash;
|
||||
ExtrinsicsRoot get(extrinsics_root): T::Hash;
|
||||
Digest get(digest): T::Digest;
|
||||
|
||||
Events get(events): default Vec<EventRecord<T::Event>>;
|
||||
Events get(events): Vec<EventRecord<T::Event>>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(changes_trie_config): Option<ChangesTrieConfiguration>;
|
||||
config(_phantom): ::std::marker::PhantomData<T>;
|
||||
|
||||
build(|storage: &mut primitives::StorageMap, config: &GenesisConfig<T>| {
|
||||
use codec::Encode;
|
||||
|
||||
storage.insert(well_known_keys::EXTRINSIC_INDEX.to_vec(), 0u32.encode());
|
||||
|
||||
if let Some(ref changes_trie_config) = config.changes_trie_config {
|
||||
storage.insert(
|
||||
well_known_keys::CHANGES_TRIE_CONFIG.to_vec(),
|
||||
changes_trie_config.encode());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,52 +412,6 @@ impl<T: Trait> BlockNumberToHash for Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
/// Changes trie configuration.
|
||||
pub changes_trie_config: Option<ChangesTrieConfiguration>,
|
||||
/// Marker for 'storing' T.
|
||||
pub _phantom: ::std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
changes_trie_config: Default::default(),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
|
||||
{
|
||||
fn build_storage(self) -> Result<primitives::StorageMap, String> {
|
||||
use codec::Encode;
|
||||
|
||||
let mut storage: primitives::StorageMap = map![
|
||||
Self::hash(&<BlockHash<T>>::key_for(T::BlockNumber::zero())).to_vec() => [69u8; 32].encode(),
|
||||
Self::hash(<Number<T>>::key()).to_vec() => 1u64.encode(),
|
||||
Self::hash(<ParentHash<T>>::key()).to_vec() => [69u8; 32].encode(),
|
||||
Self::hash(<RandomSeed<T>>::key()).to_vec() => [0u8; 32].encode()
|
||||
];
|
||||
|
||||
storage.insert(well_known_keys::EXTRINSIC_INDEX.to_vec(), 0u32.encode());
|
||||
|
||||
if let Some(changes_trie_config) = self.changes_trie_config {
|
||||
storage.insert(
|
||||
well_known_keys::CHANGES_TRIE_CONFIG.to_vec(),
|
||||
changes_trie_config.encode());
|
||||
}
|
||||
|
||||
Ok(storage)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg_attr(any(feature = "std", test), macro_use)]
|
||||
extern crate sr_std as rstd;
|
||||
|
||||
#[macro_use]
|
||||
@@ -78,12 +77,12 @@ decl_module! {
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as Timestamp {
|
||||
/// Current time for the current block.
|
||||
pub Now get(now): required T::Moment;
|
||||
pub Now get(now) build(|_| T::Moment::sa(0)): T::Moment;
|
||||
/// The minimum (and advised) period between blocks.
|
||||
pub BlockPeriod get(block_period): required T::Moment;
|
||||
pub BlockPeriod get(block_period) config(period): T::Moment = T::Moment::sa(5);
|
||||
|
||||
/// Did the timestamp get updated in this block?
|
||||
DidUpdate: default bool;
|
||||
DidUpdate: bool;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,37 +134,6 @@ impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration of a genesis block for the timestamp module.
|
||||
#[cfg(any(feature = "std", test))]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
/// The minimum (and advised) period between blocks.
|
||||
pub period: T::Moment,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
period: T::Moment::sa(5),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> runtime_primitives::BuildStorage for GenesisConfig<T>
|
||||
{
|
||||
fn build_storage(self) -> ::std::result::Result<runtime_primitives::StorageMap, String> {
|
||||
use codec::Encode;
|
||||
Ok(map![
|
||||
Self::hash(<BlockPeriod<T>>::key()).to_vec() => self.period.encode(),
|
||||
Self::hash(<Now<T>>::key()).to_vec() => T::Moment::sa(0).encode()
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg_attr(feature = "std", macro_use)]
|
||||
extern crate sr_std as rstd;
|
||||
|
||||
#[macro_use]
|
||||
@@ -107,30 +106,30 @@ decl_storage! {
|
||||
|
||||
/// Proportion of funds that should be bonded in order to place a proposal. An accepted
|
||||
/// proposal gets these back. A rejected proposal doesn't.
|
||||
ProposalBond get(proposal_bond): required Permill;
|
||||
ProposalBond get(proposal_bond) config(): Permill;
|
||||
|
||||
/// Minimum amount of funds that should be placed in a deposit for making a proposal.
|
||||
ProposalBondMinimum get(proposal_bond_minimum): required T::Balance;
|
||||
ProposalBondMinimum get(proposal_bond_minimum) config(): T::Balance;
|
||||
|
||||
/// Period between successive spends.
|
||||
SpendPeriod get(spend_period): required T::BlockNumber;
|
||||
SpendPeriod get(spend_period) config(): T::BlockNumber = runtime_primitives::traits::One::one();
|
||||
|
||||
/// Percentage of spare funds (if any) that are burnt per spend period.
|
||||
Burn get(burn): required Permill;
|
||||
Burn get(burn) config(): Permill;
|
||||
|
||||
// State...
|
||||
|
||||
/// Total funds available to this module for spending.
|
||||
Pot get(pot): default T::Balance;
|
||||
Pot get(pot): T::Balance;
|
||||
|
||||
/// Number of proposals that have been made.
|
||||
ProposalCount get(proposal_count): default ProposalIndex;
|
||||
ProposalCount get(proposal_count): ProposalIndex;
|
||||
|
||||
/// Proposals that have been made.
|
||||
Proposals get(proposals): map [ ProposalIndex => Proposal<T::AccountId, T::Balance> ];
|
||||
Proposals get(proposals): map ProposalIndex => Option<Proposal<T::AccountId, T::Balance>>;
|
||||
|
||||
/// Proposal indices that have been approved but not yet awarded.
|
||||
Approvals get(approvals): default Vec<ProposalIndex>;
|
||||
Approvals get(approvals): Vec<ProposalIndex>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,45 +286,6 @@ impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
/// The genesis block configuration type. This is a simple default-capable struct that
|
||||
/// contains any fields with which this module can be configured at genesis time.
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
pub proposal_bond: Permill,
|
||||
pub proposal_bond_minimum: T::Balance,
|
||||
pub spend_period: T::BlockNumber,
|
||||
pub burn: Permill,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
proposal_bond: Default::default(),
|
||||
proposal_bond_minimum: Default::default(),
|
||||
spend_period: runtime_primitives::traits::One::one(),
|
||||
burn: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: Trait> runtime_primitives::BuildStorage for GenesisConfig<T>
|
||||
{
|
||||
fn build_storage(self) -> ::std::result::Result<runtime_primitives::StorageMap, String> {
|
||||
use codec::Encode;
|
||||
Ok(map![
|
||||
Self::hash(<ProposalBond<T>>::key()).to_vec() => self.proposal_bond.encode(),
|
||||
Self::hash(<ProposalBondMinimum<T>>::key()).to_vec() => self.proposal_bond_minimum.encode(),
|
||||
Self::hash(<SpendPeriod<T>>::key()).to_vec() => self.spend_period.encode(),
|
||||
Self::hash(<Burn<T>>::key()).to_vec() => self.burn.encode()
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user