mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 19:01:08 +00:00
Split Indices module from Balances (#1404)
* Indices module * Remove indices stuff from balances * Rejob node, move Lookup into system. * Fix up some modules. * Fix democracy tests * Fix staking tests * Fix more tests * Final test fixes * Bump runtime versions * Assets uses compact dispatchers * Contracts module uses indexed addressing * Democracy has more compact encoding * Example now demonstrates compact eencoding * Sudo uses indexed address * Upgrade key also uses indexed lookups * Assets more compact types. * Fix test * Rebuild runtime, whitespace * Remove TOODs * Remove TODOs * Add a couple of tests back to balances. * Update lib.rs * Update lib.rs
This commit is contained in:
Generated
+28
@@ -1752,6 +1752,7 @@ dependencies = [
|
||||
"srml-consensus 0.1.0",
|
||||
"srml-contract 0.1.0",
|
||||
"srml-grandpa 0.1.0",
|
||||
"srml-indices 0.1.0",
|
||||
"srml-session 0.1.0",
|
||||
"srml-staking 0.1.0",
|
||||
"srml-support 0.1.0",
|
||||
@@ -1805,6 +1806,7 @@ dependencies = [
|
||||
"srml-democracy 0.1.0",
|
||||
"srml-executive 0.1.0",
|
||||
"srml-grandpa 0.1.0",
|
||||
"srml-indices 0.1.0",
|
||||
"srml-session 0.1.0",
|
||||
"srml-staking 0.1.0",
|
||||
"srml-sudo 0.1.0",
|
||||
@@ -2344,6 +2346,11 @@ dependencies = [
|
||||
"redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref_thread_local"
|
||||
version = "0.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.2.11"
|
||||
@@ -2871,6 +2878,7 @@ dependencies = [
|
||||
"sr-primitives 0.1.0",
|
||||
"sr-std 0.1.0",
|
||||
"srml-balances 0.1.0",
|
||||
"srml-indices 0.1.0",
|
||||
"srml-support 0.1.0",
|
||||
"srml-system 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
@@ -2895,6 +2903,25 @@ dependencies = [
|
||||
"substrate-primitives 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-indices"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ref_thread_local 0.0.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.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-io 0.1.0",
|
||||
"sr-primitives 0.1.0",
|
||||
"sr-std 0.1.0",
|
||||
"srml-support 0.1.0",
|
||||
"srml-system 0.1.0",
|
||||
"substrate-keyring 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-metadata"
|
||||
version = "0.1.0"
|
||||
@@ -4693,6 +4720,7 @@ dependencies = [
|
||||
"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356"
|
||||
"checksum redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)" = "52ee9a534dc1301776eff45b4fa92d2c39b1d8c3d3357e6eb593e0d795506fc2"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d813022b2e00774a48eaf43caaa3c20b45f040ba8cbf398e2e8911a06668dbe6"
|
||||
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
|
||||
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
|
||||
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
|
||||
|
||||
+11
-10
@@ -33,10 +33,20 @@ members = [
|
||||
"core/primitives",
|
||||
"core/rpc",
|
||||
"core/rpc-servers",
|
||||
"core/serializer",
|
||||
"core/service",
|
||||
"core/service/test",
|
||||
"core/sr-api-macros",
|
||||
"core/sr-io",
|
||||
"core/sr-primitives",
|
||||
"core/sr-sandbox",
|
||||
"core/sr-std",
|
||||
"core/sr-version",
|
||||
"core/state-machine",
|
||||
"core/test-runtime",
|
||||
"core/telemetry",
|
||||
"core/trie",
|
||||
"core/keystore",
|
||||
"core/transaction-pool",
|
||||
"core/transaction-pool/graph",
|
||||
"srml/support",
|
||||
@@ -53,8 +63,8 @@ members = [
|
||||
"srml/example",
|
||||
"srml/executive",
|
||||
"srml/grandpa",
|
||||
"srml/indices",
|
||||
"srml/metadata",
|
||||
"core/sr-primitives",
|
||||
"srml/session",
|
||||
"srml/staking",
|
||||
"srml/sudo",
|
||||
@@ -62,15 +72,6 @@ members = [
|
||||
"srml/timestamp",
|
||||
"srml/treasury",
|
||||
"srml/upgrade-key",
|
||||
"core/serializer",
|
||||
"core/service",
|
||||
"core/service/test",
|
||||
"core/sr-api-macros",
|
||||
"core/state-machine",
|
||||
"core/test-runtime",
|
||||
"core/telemetry",
|
||||
"core/trie",
|
||||
"core/keystore",
|
||||
"node/cli",
|
||||
"node/executor",
|
||||
"node/primitives",
|
||||
|
||||
@@ -28,7 +28,7 @@ use primitives::Blake2Hasher;
|
||||
use primitives::storage::well_known_keys;
|
||||
|
||||
/// Default num of pages for the heap
|
||||
const DEFAULT_HEAP_PAGES :u64 = 1024;
|
||||
const DEFAULT_HEAP_PAGES: u64 = 1024;
|
||||
|
||||
// For the internal Runtime Cache:
|
||||
// Is it compatible enough to run this natively or do we need to fall back on the WasmModule
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Primitives for the runtime modules.
|
||||
|
||||
use rstd::prelude::*;
|
||||
use rstd::{self, result};
|
||||
use rstd::{self, result, marker::PhantomData};
|
||||
use runtime_io;
|
||||
#[cfg(feature = "std")] use std::fmt::{Debug, Display};
|
||||
#[cfg(feature = "std")] use serde::{Serialize, de::DeserializeOwned};
|
||||
@@ -54,7 +54,7 @@ pub trait Verify {
|
||||
/// Some sort of check on the origin is performed by this object.
|
||||
pub trait EnsureOrigin<OuterOrigin> {
|
||||
type Success;
|
||||
fn ensure_origin(o: OuterOrigin) -> Result<Self::Success, &'static str>;
|
||||
fn ensure_origin(o: OuterOrigin) -> result::Result<Self::Success, &'static str>;
|
||||
}
|
||||
|
||||
/// Means of changing one type into another in a manner dependent on the source type.
|
||||
@@ -67,6 +67,31 @@ pub trait Lookup {
|
||||
fn lookup(&self, s: Self::Source) -> result::Result<Self::Target, &'static str>;
|
||||
}
|
||||
|
||||
/// Means of changing one type into another in a manner dependent on the source type.
|
||||
/// This variant is different to `Lookup` in that it doesn't (can cannot) require any
|
||||
/// context.
|
||||
pub trait StaticLookup {
|
||||
/// Type to lookup from.
|
||||
type Source: Codec + Clone + PartialEq + MaybeDebug;
|
||||
/// Type to lookup into.
|
||||
type Target;
|
||||
/// Attempt a lookup.
|
||||
fn lookup(s: Self::Source) -> result::Result<Self::Target, &'static str>;
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct IdentityLookup<T>(PhantomData<T>);
|
||||
impl<T: Codec + Clone + PartialEq + MaybeDebug> StaticLookup for IdentityLookup<T> {
|
||||
type Source = T;
|
||||
type Target = T;
|
||||
fn lookup(x: T) -> result::Result<T, &'static str> { Ok(x) }
|
||||
}
|
||||
impl<T> Lookup for IdentityLookup<T> {
|
||||
type Source = T;
|
||||
type Target = T;
|
||||
fn lookup(&self, x: T) -> result::Result<T, &'static str> { Ok(x) }
|
||||
}
|
||||
|
||||
/// Get the "current" block number.
|
||||
pub trait CurrentHeight {
|
||||
/// The type of the block number.
|
||||
|
||||
+4
-4
@@ -1085,7 +1085,7 @@ dependencies = [
|
||||
"substrate-serializer 0.1.0",
|
||||
"substrate-state-machine 0.1.0",
|
||||
"substrate-trie 0.4.0",
|
||||
"wasmi 0.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]]
|
||||
@@ -1118,7 +1118,7 @@ dependencies = [
|
||||
"sr-std 0.1.0",
|
||||
"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.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1487,7 +1487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wasmi"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1696,7 +1696,7 @@ dependencies = [
|
||||
"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 void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum wasmi 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a60b9508cff2b7c27ed41200dd668806280740fadc8c88440e9c88625e84f1a"
|
||||
"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"
|
||||
|
||||
BIN
Binary file not shown.
@@ -20,7 +20,7 @@ use primitives::{Ed25519AuthorityId, ed25519};
|
||||
use node_primitives::AccountId;
|
||||
use node_runtime::{ConsensusConfig, CouncilSeatsConfig, CouncilVotingConfig, DemocracyConfig,
|
||||
SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig,
|
||||
SudoConfig, ContractConfig, GrandpaConfig, Permill, Perbill};
|
||||
SudoConfig, ContractConfig, GrandpaConfig, IndicesConfig, Permill, Perbill};
|
||||
pub use node_runtime::GenesisConfig;
|
||||
use substrate_service;
|
||||
|
||||
@@ -68,7 +68,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
existential_deposit: 1 * DOLLARS,
|
||||
transfer_fee: 1 * CENTS,
|
||||
creation_fee: 1 * CENTS,
|
||||
reclaim_rebate: 1 * CENTS,
|
||||
}),
|
||||
indices: Some(IndicesConfig {
|
||||
ids: endowed_accounts.clone(),
|
||||
}),
|
||||
session: Some(SessionConfig {
|
||||
validators: initial_authorities.iter().cloned().map(Into::into).collect(),
|
||||
@@ -184,13 +186,15 @@ pub fn testnet_genesis(
|
||||
authorities: initial_authorities.clone(),
|
||||
}),
|
||||
system: None,
|
||||
indices: Some(IndicesConfig {
|
||||
ids: endowed_accounts.iter().map(|x| x.0.into()).collect(),
|
||||
}),
|
||||
balances: Some(BalancesConfig {
|
||||
transaction_base_fee: 1,
|
||||
transaction_byte_fee: 0,
|
||||
existential_deposit: 500,
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
balances: endowed_accounts.iter().map(|&k| (k.into(), (1 << 60))).collect(),
|
||||
}),
|
||||
session: Some(SessionConfig {
|
||||
|
||||
@@ -29,6 +29,7 @@ srml-timestamp = { path = "../../srml/timestamp" }
|
||||
srml-treasury = { path = "../../srml/treasury" }
|
||||
srml-contract = { path = "../../srml/contract" }
|
||||
srml-grandpa = { path = "../../srml/grandpa" }
|
||||
srml-indices = { path = "../../srml/indices" }
|
||||
wabt = "~0.7.4"
|
||||
|
||||
[features]
|
||||
|
||||
@@ -37,6 +37,7 @@ extern crate node_runtime;
|
||||
#[cfg(test)] extern crate srml_treasury as treasury;
|
||||
#[cfg(test)] extern crate srml_contract as contract;
|
||||
#[cfg(test)] extern crate srml_grandpa as grandpa;
|
||||
#[cfg(test)] extern crate srml_indices as indices;
|
||||
#[cfg(test)] extern crate node_primitives;
|
||||
#[cfg(test)] extern crate parity_codec as codec;
|
||||
#[cfg(test)] extern crate sr_io as runtime_io;
|
||||
@@ -62,12 +63,12 @@ mod tests {
|
||||
use node_primitives::{Hash, BlockNumber, AccountId};
|
||||
use runtime_primitives::traits::{Header as HeaderT, Digest as DigestT};
|
||||
use runtime_primitives::{generic, generic::Era, ApplyOutcome, ApplyError, ApplyResult, Perbill};
|
||||
use {balances, staking, session, system, consensus, timestamp, treasury, contract};
|
||||
use {balances, indices, staking, session, system, consensus, timestamp, treasury, contract};
|
||||
use contract::ContractAddressFor;
|
||||
use system::{EventRecord, Phase};
|
||||
use node_runtime::{Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances,
|
||||
BuildStorage, GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, System,
|
||||
SystemConfig, GrandpaConfig, Event, Log};
|
||||
SystemConfig, GrandpaConfig, IndicesConfig, Event, Log};
|
||||
use wabt;
|
||||
|
||||
const BLOATY_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.wasm");
|
||||
@@ -94,7 +95,7 @@ mod tests {
|
||||
let pair = Pair::from(Keyring::from_public(Public::from_raw(signed.clone().into())).unwrap());
|
||||
let signature = pair.sign(&payload.encode()).into();
|
||||
UncheckedExtrinsic {
|
||||
signature: Some((balances::address::Address::Id(signed), signature, payload.0, era)),
|
||||
signature: Some((indices::address::Address::Id(signed), signature, payload.0, era)),
|
||||
function: payload.1,
|
||||
}
|
||||
}
|
||||
@@ -130,7 +131,7 @@ mod tests {
|
||||
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<indices::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||
]);
|
||||
|
||||
@@ -151,7 +152,7 @@ mod tests {
|
||||
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<indices::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||
]);
|
||||
|
||||
@@ -172,7 +173,7 @@ mod tests {
|
||||
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<indices::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||
]);
|
||||
|
||||
@@ -197,7 +198,7 @@ mod tests {
|
||||
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<indices::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||
]);
|
||||
|
||||
@@ -224,6 +225,9 @@ mod tests {
|
||||
}) } else { None },
|
||||
..Default::default()
|
||||
}),
|
||||
indices: Some(IndicesConfig {
|
||||
ids: vec![alice(), charlie()],
|
||||
}),
|
||||
balances: Some(BalancesConfig {
|
||||
balances: vec![
|
||||
(alice(), 111),
|
||||
@@ -234,7 +238,6 @@ mod tests {
|
||||
existential_deposit: 0,
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
}),
|
||||
session: Some(SessionConfig {
|
||||
session_length: 2,
|
||||
@@ -312,13 +315,13 @@ mod tests {
|
||||
1,
|
||||
GENESIS_HASH.into(),
|
||||
if support_changes_trie {
|
||||
hex!("22e7fc466d555b9dce285425081d89751b2063243684979df3840b3ac7e8ecdc").into()
|
||||
hex!("e2dc1ed62a3878e084c49baef3eed4bc462caaa1ee9db0763eaa8d39d1affc7e").into()
|
||||
} else {
|
||||
hex!("7395363e53e682984f817fb1d5a862c5ce8b817375c06270d7a39be7097ad953").into()
|
||||
hex!("7dad66de05ab6391ece9db092288cb39ba723f7f5d0b69b507b753fc92c98b8e").into()
|
||||
},
|
||||
if support_changes_trie {
|
||||
vec![changes_trie_log(
|
||||
hex!("cda28e5c630db8eb0e4309b58ce504597c6cbb59bda43fd65e96bb2be73a4586").into(),
|
||||
hex!("f254b62df0bfef049e010a7a0d6f176d73cc5d9710fa945b4e48f519c8d3a291").into(),
|
||||
)]
|
||||
} else {
|
||||
vec![]
|
||||
@@ -340,7 +343,7 @@ mod tests {
|
||||
construct_block(
|
||||
2,
|
||||
block1(false).1,
|
||||
hex!("66b9625c9c824de867815215528fe43014d50af7fb95c8da120910c220a46f6b").into(),
|
||||
hex!("f085a4077d071d3334f7553bcc3f10d97fd612e25c6df5c8f94151bbe557e24a").into(),
|
||||
vec![ // session changes here, so we add a grandpa change signal log.
|
||||
Log::from(::grandpa::RawLog::AuthoritiesChangeSignal(0, vec![
|
||||
(Keyring::One.to_raw_public().into(), 1),
|
||||
@@ -369,7 +372,7 @@ mod tests {
|
||||
construct_block(
|
||||
1,
|
||||
GENESIS_HASH.into(),
|
||||
hex!("66dfdf3a0ef93ec49ec36c0a65fe328d085a865c2382397b2cd6468e391f2f51").into(),
|
||||
hex!("1d47422645f5fa3d79cff9ab5cd69ee62919c909860f063bdaf18eda834baa05").into(),
|
||||
vec![],
|
||||
vec![
|
||||
CheckedExtrinsic {
|
||||
@@ -400,7 +403,14 @@ mod tests {
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::balances(balances::RawEvent::NewAccount(bob(), 2, balances::NewAccountOutcome::NoHint))
|
||||
event: Event::indices(indices::RawEvent::NewAccountIndex(bob(), 2))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::balances(balances::RawEvent::NewAccount(
|
||||
hex!["d7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9"].into(),
|
||||
69
|
||||
))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
@@ -659,7 +669,7 @@ mod tests {
|
||||
let b = construct_block(
|
||||
1,
|
||||
GENESIS_HASH.into(),
|
||||
hex!("8197608e90fff1f7d92b35381169242d081779b1718c910689f2589a8ac09b44").into(),
|
||||
hex!("c442a475a16805d20c326f1134fe5a9656511ed7e1a7f0c7dae2dfc8612e418b").into(),
|
||||
vec![],
|
||||
vec![
|
||||
CheckedExtrinsic {
|
||||
@@ -675,7 +685,7 @@ mod tests {
|
||||
CheckedExtrinsic {
|
||||
signed: Some((charlie(), 1)),
|
||||
function: Call::Contract(
|
||||
contract::Call::call::<Runtime>(addr, 10.into(), 10_000.into(), vec![0x00, 0x01, 0x02, 0x03])
|
||||
contract::Call::call::<Runtime>(indices::address::Address::Id(addr), 10.into(), 10_000.into(), vec![0x00, 0x01, 0x02, 0x03])
|
||||
),
|
||||
},
|
||||
]
|
||||
@@ -741,7 +751,7 @@ mod tests {
|
||||
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<indices::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||
]);
|
||||
|
||||
@@ -763,7 +773,7 @@ mod tests {
|
||||
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(<indices::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
|
||||
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
|
||||
]);
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ parity-codec = { version = "2.1", default-features = false }
|
||||
substrate-primitives = { path = "../../core/primitives", default-features = false }
|
||||
substrate-client = { path = "../../core/client", default-features = false }
|
||||
sr-std = { path = "../../core/sr-std", default-features = false }
|
||||
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
|
||||
sr-version = { path = "../../core/sr-version", default-features = false }
|
||||
srml-support = { path = "../../srml/support", default-features = false }
|
||||
srml-aura = { path = "../../srml/aura", default-features = false }
|
||||
srml-balances = { path = "../../srml/balances", default-features = false }
|
||||
@@ -19,7 +21,8 @@ srml-contract = { path = "../../srml/contract", default-features = false }
|
||||
srml-council = { path = "../../srml/council", default-features = false }
|
||||
srml-democracy = { path = "../../srml/democracy", default-features = false }
|
||||
srml-executive = { path = "../../srml/executive", default-features = false }
|
||||
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
|
||||
srml-grandpa = { path = "../../srml/grandpa", default-features = false }
|
||||
srml-indices = { path = "../../srml/indices", default-features = false }
|
||||
srml-session = { path = "../../srml/session", default-features = false }
|
||||
srml-staking = { path = "../../srml/staking", default-features = false }
|
||||
srml-system = { path = "../../srml/system", default-features = false }
|
||||
@@ -27,8 +30,6 @@ srml-timestamp = { path = "../../srml/timestamp", default-features = false }
|
||||
srml-treasury = { path = "../../srml/treasury", default-features = false }
|
||||
srml-sudo = { path = "../../srml/sudo", default-features = false }
|
||||
srml-upgrade-key = { path = "../../srml/upgrade-key", default-features = false }
|
||||
srml-grandpa = { path = "../../srml/grandpa", default-features = false }
|
||||
sr-version = { path = "../../core/sr-version", default-features = false }
|
||||
node-primitives = { path = "../primitives", default-features = false }
|
||||
substrate-consensus-aura-primitives = { path = "../../core/consensus/aura/primitives", default-features = false }
|
||||
rustc-hex = { version = "1.0", optional = true }
|
||||
@@ -42,6 +43,7 @@ std = [
|
||||
"parity-codec/std",
|
||||
"substrate-primitives/std",
|
||||
"sr-std/std",
|
||||
"sr-primitives/std",
|
||||
"srml-support/std",
|
||||
"srml-balances/std",
|
||||
"srml-consensus/std",
|
||||
@@ -50,7 +52,7 @@ std = [
|
||||
"srml-democracy/std",
|
||||
"srml-executive/std",
|
||||
"srml-grandpa/std",
|
||||
"sr-primitives/std",
|
||||
"srml-indices/std",
|
||||
"srml-session/std",
|
||||
"srml-staking/std",
|
||||
"srml-system/std",
|
||||
|
||||
@@ -45,6 +45,7 @@ extern crate srml_council as council;
|
||||
extern crate srml_democracy as democracy;
|
||||
extern crate srml_executive as executive;
|
||||
extern crate srml_grandpa as grandpa;
|
||||
extern crate srml_indices as indices;
|
||||
extern crate srml_session as session;
|
||||
extern crate srml_staking as staking;
|
||||
extern crate srml_sudo as sudo;
|
||||
@@ -69,7 +70,8 @@ use runtime_primitives::{ApplyResult, CheckInherentError, BasicInherentData};
|
||||
use runtime_primitives::transaction_validity::TransactionValidity;
|
||||
use runtime_primitives::generic;
|
||||
use runtime_primitives::traits::{
|
||||
Convert, BlakeTwo256, Block as BlockT, DigestFor, NumberFor, ProvideInherent
|
||||
Convert, BlakeTwo256, Block as BlockT, DigestFor, NumberFor, ProvideInherent,
|
||||
StaticLookup
|
||||
};
|
||||
use version::RuntimeVersion;
|
||||
use council::{motions as council_motions, voting as council_voting};
|
||||
@@ -96,8 +98,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("node"),
|
||||
impl_name: create_runtime_str!("substrate-node"),
|
||||
authoring_version: 10,
|
||||
spec_version: 15,
|
||||
impl_version: 15,
|
||||
spec_version: 16,
|
||||
impl_version: 16,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
};
|
||||
|
||||
@@ -118,6 +120,7 @@ impl system::Trait for Runtime {
|
||||
type Hashing = BlakeTwo256;
|
||||
type Digest = generic::Digest<Log>;
|
||||
type AccountId = AccountId;
|
||||
type Lookup = Indices;
|
||||
type Header = generic::Header<BlockNumber, BlakeTwo256, Log>;
|
||||
type Event = Event;
|
||||
type Log = Log;
|
||||
@@ -127,10 +130,17 @@ impl aura::Trait for Runtime {
|
||||
type HandleReport = aura::StakingSlasher<Runtime>;
|
||||
}
|
||||
|
||||
impl indices::Trait for Runtime {
|
||||
type AccountIndex = AccountIndex;
|
||||
type IsDeadAccount = Balances;
|
||||
type ResolveHint = indices::SimpleResolveHint<Self::AccountId, Self::AccountIndex>;
|
||||
type Event = Event;
|
||||
}
|
||||
|
||||
impl balances::Trait for Runtime {
|
||||
type Balance = Balance;
|
||||
type AccountIndex = AccountIndex;
|
||||
type OnFreeBalanceZero = ((Staking, Contract), Democracy);
|
||||
type OnNewAccount = Indices;
|
||||
type EnsureAccountLiquid = (Staking, Democracy);
|
||||
type Event = Event;
|
||||
}
|
||||
@@ -222,6 +232,7 @@ construct_runtime!(
|
||||
Aura: aura::{Module},
|
||||
Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
|
||||
Consensus: consensus::{Module, Call, Storage, Config<T>, Log(AuthoritiesChange), Inherent},
|
||||
Indices: indices,
|
||||
Balances: balances,
|
||||
Session: session,
|
||||
Staking: staking,
|
||||
@@ -238,10 +249,7 @@ construct_runtime!(
|
||||
);
|
||||
|
||||
/// The address format for describing accounts.
|
||||
pub use balances::address::Address as RawAddress;
|
||||
|
||||
/// The address format for describing accounts.
|
||||
pub type Address = balances::Address<Runtime>;
|
||||
pub 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.
|
||||
@@ -255,7 +263,7 @@ pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic<Address,
|
||||
/// Extrinsic type that has already been checked.
|
||||
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Index, Call>;
|
||||
/// Executive: handles dispatch to the various modules.
|
||||
pub type Executive = executive::Executive<Runtime, Block, balances::ChainContext<Runtime>, Balances, AllModules>;
|
||||
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Balances, AllModules>;
|
||||
|
||||
impl_runtime_apis! {
|
||||
impl client_api::Core<Block> for Runtime {
|
||||
|
||||
Generated
+24
-5
@@ -499,6 +499,7 @@ dependencies = [
|
||||
"srml-democracy 0.1.0",
|
||||
"srml-executive 0.1.0",
|
||||
"srml-grandpa 0.1.0",
|
||||
"srml-indices 0.1.0",
|
||||
"srml-session 0.1.0",
|
||||
"srml-staking 0.1.0",
|
||||
"srml-sudo 0.1.0",
|
||||
@@ -1010,7 +1011,7 @@ dependencies = [
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-std 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"wasmi 0.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]]
|
||||
@@ -1175,6 +1176,24 @@ dependencies = [
|
||||
"substrate-primitives 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-indices"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-codec-derive 2.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.81 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-io 0.1.0",
|
||||
"sr-primitives 0.1.0",
|
||||
"sr-std 0.1.0",
|
||||
"srml-support 0.1.0",
|
||||
"srml-system 0.1.0",
|
||||
"substrate-keyring 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-metadata"
|
||||
version = "0.1.0"
|
||||
@@ -1445,7 +1464,7 @@ dependencies = [
|
||||
"substrate-serializer 0.1.0",
|
||||
"substrate-state-machine 0.1.0",
|
||||
"substrate-trie 0.4.0",
|
||||
"wasmi 0.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]]
|
||||
@@ -1490,7 +1509,7 @@ dependencies = [
|
||||
"sr-std 0.1.0",
|
||||
"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.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1831,7 +1850,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wasmi"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2043,7 +2062,7 @@ dependencies = [
|
||||
"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 void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum wasmi 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a60b9508cff2b7c27ed41200dd668806280740fadc8c88440e9c88625e84f1a"
|
||||
"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"
|
||||
|
||||
BIN
Binary file not shown.
@@ -46,7 +46,8 @@ extern crate sr_primitives as primitives;
|
||||
extern crate srml_system as system;
|
||||
|
||||
use runtime_support::{StorageValue, StorageMap, Parameter};
|
||||
use primitives::traits::{Member, SimpleArithmetic, Zero};
|
||||
use codec::{Compact, HasCompact};
|
||||
use primitives::traits::{Member, SimpleArithmetic, Zero, StaticLookup};
|
||||
use system::ensure_signed;
|
||||
|
||||
pub trait Trait: system::Trait {
|
||||
@@ -66,8 +67,9 @@ decl_module! {
|
||||
/// Issue a new class of fungible assets. There are, and will only ever be, `total`
|
||||
/// such assets and they'll all belong to the `origin` initially. It will have an
|
||||
/// identifier `AssetId` instance: this will be specified in the `Issued` event.
|
||||
fn issue(origin, total: T::Balance) {
|
||||
fn issue(origin, total: <T::Balance as HasCompact>::Type) {
|
||||
let origin = ensure_signed(origin)?;
|
||||
let total = total.into();
|
||||
|
||||
let id = Self::next_asset_id();
|
||||
<NextAssetId<T>>::mutate(|id| *id += 1);
|
||||
@@ -79,10 +81,17 @@ decl_module! {
|
||||
}
|
||||
|
||||
/// Move some assets from one holder to another.
|
||||
fn transfer(origin, id: AssetId, target: T::AccountId, amount: T::Balance) {
|
||||
fn transfer(origin,
|
||||
id: Compact<AssetId>,
|
||||
target: <T::Lookup as StaticLookup>::Source,
|
||||
amount: <T::Balance as HasCompact>::Type
|
||||
) {
|
||||
let origin = ensure_signed(origin)?;
|
||||
let id = id.into();
|
||||
let origin_account = (id, origin.clone());
|
||||
let origin_balance = <Balances<T>>::get(&origin_account);
|
||||
let target = T::Lookup::lookup(target)?;
|
||||
let amount = amount.into();
|
||||
ensure!(!amount.is_zero(), "transfer amount should be non-zero");
|
||||
ensure!(origin_balance >= amount, "origin account balance must be greater than or equal to the transfer amount");
|
||||
|
||||
@@ -92,8 +101,9 @@ decl_module! {
|
||||
}
|
||||
|
||||
/// Destroy any assets of `id` owned by `origin`.
|
||||
fn destroy(origin, id: AssetId) {
|
||||
fn destroy(origin, id: Compact<AssetId>) {
|
||||
let origin = ensure_signed(origin)?;
|
||||
let id = id.into();
|
||||
let balance = <Balances<T>>::take((id, origin.clone()));
|
||||
ensure!(!balance.is_zero(), "origin balance should be non-zero");
|
||||
|
||||
@@ -151,7 +161,11 @@ mod tests {
|
||||
use substrate_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 required.
|
||||
use primitives::{BuildStorage, traits::{BlakeTwo256}, testing::{Digest, DigestItem, Header}};
|
||||
use primitives::{
|
||||
BuildStorage,
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
testing::{Digest, DigestItem, Header}
|
||||
};
|
||||
|
||||
impl_outer_origin! {
|
||||
pub enum Origin for Test {}
|
||||
@@ -170,6 +184,7 @@ mod tests {
|
||||
type Hashing = BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
type Log = DigestItem;
|
||||
@@ -189,7 +204,7 @@ mod tests {
|
||||
#[test]
|
||||
fn issuing_asset_units_to_issuer_should_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100));
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 100);
|
||||
});
|
||||
}
|
||||
@@ -197,16 +212,16 @@ mod tests {
|
||||
#[test]
|
||||
fn querying_total_supply_should_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100));
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 100);
|
||||
assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50));
|
||||
assert_ok!(Assets::transfer(Origin::signed(1), 0.into(), 2, 50.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 50);
|
||||
assert_eq!(Assets::balance(0, 2), 50);
|
||||
assert_ok!(Assets::transfer(Origin::signed(2), 0, 3, 31));
|
||||
assert_ok!(Assets::transfer(Origin::signed(2), 0.into(), 3, 31.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 50);
|
||||
assert_eq!(Assets::balance(0, 2), 19);
|
||||
assert_eq!(Assets::balance(0, 3), 31);
|
||||
assert_ok!(Assets::destroy(Origin::signed(3), 0));
|
||||
assert_ok!(Assets::destroy(Origin::signed(3), 0.into()));
|
||||
assert_eq!(Assets::total_supply(0), 69);
|
||||
});
|
||||
}
|
||||
@@ -214,9 +229,9 @@ mod tests {
|
||||
#[test]
|
||||
fn transferring_amount_above_available_balance_should_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100));
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 100);
|
||||
assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50));
|
||||
assert_ok!(Assets::transfer(Origin::signed(1), 0.into(), 2, 50.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 50);
|
||||
assert_eq!(Assets::balance(0, 2), 50);
|
||||
});
|
||||
@@ -225,50 +240,50 @@ mod tests {
|
||||
#[test]
|
||||
fn transferring_amount_less_than_available_balance_should_not_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100));
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 100);
|
||||
assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50));
|
||||
assert_ok!(Assets::transfer(Origin::signed(1), 0.into(), 2, 50.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 50);
|
||||
assert_eq!(Assets::balance(0, 2), 50);
|
||||
assert_ok!(Assets::destroy(Origin::signed(1), 0));
|
||||
assert_ok!(Assets::destroy(Origin::signed(1), 0.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 0);
|
||||
assert_noop!(Assets::transfer(Origin::signed(1), 0, 1, 50), "origin account balance must be greater than or equal to the transfer amount");
|
||||
assert_noop!(Assets::transfer(Origin::signed(1), 0.into(), 1, 50.into()), "origin account balance must be greater than or equal to the transfer amount");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transferring_less_than_one_unit_should_not_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100));
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 100);
|
||||
assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 0), "transfer amount should be non-zero");
|
||||
assert_noop!(Assets::transfer(Origin::signed(1), 0.into(), 2, 0.into()), "transfer amount should be non-zero");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transferring_more_units_than_total_supply_should_not_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100));
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 100);
|
||||
assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 101), "origin account balance must be greater than or equal to the transfer amount");
|
||||
assert_noop!(Assets::transfer(Origin::signed(1), 0.into(), 2, 101.into()), "origin account balance must be greater than or equal to the transfer amount");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn destroying_asset_balance_with_positive_balance_should_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100));
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100.into()));
|
||||
assert_eq!(Assets::balance(0, 1), 100);
|
||||
assert_ok!(Assets::destroy(Origin::signed(1), 0));
|
||||
assert_ok!(Assets::destroy(Origin::signed(1), 0.into()));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn destroying_asset_balance_with_zero_balance_should_not_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100));
|
||||
assert_ok!(Assets::issue(Origin::signed(1), 100.into()));
|
||||
assert_eq!(Assets::balance(0, 2), 0);
|
||||
assert_noop!(Assets::destroy(Origin::signed(2), 0), "origin balance should be non-zero");
|
||||
assert_noop!(Assets::destroy(Origin::signed(2), 0.into()), "origin balance should be non-zero");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use primitives::{BuildStorage, testing::{Digest, DigestItem, Header, UintAuthorityId}};
|
||||
use primitives::{BuildStorage, traits::IdentityLookup, testing::{Digest, DigestItem, Header, UintAuthorityId}};
|
||||
use runtime_io;
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use {Trait, Module, consensus, system, timestamp};
|
||||
@@ -46,6 +46,7 @@ impl system::Trait for Test {
|
||||
type Hashing = ::primitives::traits::BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
type Log = DigestItem;
|
||||
|
||||
@@ -43,27 +43,16 @@ extern crate substrate_primitives;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use rstd::{cmp, result};
|
||||
use codec::{Encode, Decode, Codec, Input, Output, HasCompact};
|
||||
use codec::{Codec, HasCompact};
|
||||
use runtime_support::{StorageValue, StorageMap, Parameter};
|
||||
use runtime_support::dispatch::Result;
|
||||
use primitives::traits::{Zero, One, SimpleArithmetic, MakePayment,
|
||||
As, Lookup, Member, CheckedAdd, CheckedSub, CurrentHeight, BlockNumberToHash};
|
||||
use address::Address as RawAddress;
|
||||
use system::ensure_signed;
|
||||
use primitives::traits::{Zero, SimpleArithmetic, MakePayment,
|
||||
As, StaticLookup, Member, CheckedAdd, CheckedSub};
|
||||
use system::{IsDeadAccount, OnNewAccount, ensure_signed};
|
||||
|
||||
mod mock;
|
||||
|
||||
pub mod address;
|
||||
mod tests;
|
||||
|
||||
/// Number of account IDs stored per enum set.
|
||||
const ENUM_SET_SIZE: usize = 64;
|
||||
|
||||
/// The byte to identify intention to reclaim an existing account index.
|
||||
const RECLAIM_INDEX_MAGIC: usize = 0x69;
|
||||
|
||||
pub type Address<T> = RawAddress<<T as system::Trait>::AccountId, <T as Trait>::AccountIndex>;
|
||||
|
||||
/// The account with the given id was killed.
|
||||
pub trait OnFreeBalanceZero<AccountId> {
|
||||
/// The account was the given id was killed.
|
||||
@@ -117,16 +106,17 @@ impl<AccountId> EnsureAccountLiquid<AccountId> for () {
|
||||
|
||||
pub trait Trait: system::Trait {
|
||||
/// The balance of an account.
|
||||
type Balance: Parameter + Member + 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 + Default + SimpleArithmetic + As<u8> + As<u16> + As<u32> + As<u64> + As<usize> + Copy;
|
||||
type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + As<usize> + As<u64>;
|
||||
|
||||
/// 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: OnFreeBalanceZero<Self::AccountId>;
|
||||
|
||||
/// Handler for when a new account is created.
|
||||
type OnNewAccount: OnNewAccount<Self::AccountId>;
|
||||
|
||||
/// A function that returns true iff a given account can transfer its funds to another account.
|
||||
type EnsureAccountLiquid: EnsureAccountLiquid<Self::AccountId>;
|
||||
|
||||
@@ -141,12 +131,12 @@ decl_module! {
|
||||
/// Transfer some liquid free balance to another staker.
|
||||
pub fn transfer(
|
||||
origin,
|
||||
dest: RawAddress<T::AccountId, T::AccountIndex>,
|
||||
dest: <T::Lookup as StaticLookup>::Source,
|
||||
value: <T::Balance as HasCompact>::Type
|
||||
) {
|
||||
let transactor = ensure_signed(origin)?;
|
||||
|
||||
let dest = Self::lookup(dest)?;
|
||||
let dest = T::Lookup::lookup(dest)?;
|
||||
let value = value.into();
|
||||
let from_balance = Self::free_balance(&transactor);
|
||||
let to_balance = Self::free_balance(&dest);
|
||||
@@ -183,11 +173,11 @@ decl_module! {
|
||||
|
||||
/// Set the balances of a given account.
|
||||
fn set_balance(
|
||||
who: RawAddress<T::AccountId, T::AccountIndex>,
|
||||
who: <T::Lookup as StaticLookup>::Source,
|
||||
free: <T::Balance as HasCompact>::Type,
|
||||
reserved: <T::Balance as HasCompact>::Type
|
||||
) {
|
||||
let who = Self::lookup(who)?;
|
||||
let who = T::Lookup::lookup(who)?;
|
||||
Self::set_free_balance(&who, free.into());
|
||||
Self::set_reserved_balance(&who, reserved.into());
|
||||
}
|
||||
@@ -197,11 +187,10 @@ decl_module! {
|
||||
decl_event!(
|
||||
pub enum Event<T> where
|
||||
<T as system::Trait>::AccountId,
|
||||
<T as Trait>::AccountIndex,
|
||||
<T as Trait>::Balance
|
||||
{
|
||||
/// A new account was created.
|
||||
NewAccount(AccountId, AccountIndex, NewAccountOutcome),
|
||||
NewAccount(AccountId, Balance),
|
||||
/// An account was reaped.
|
||||
ReapedAccount(AccountId),
|
||||
/// Transfer succeeded (from, to, value, fees).
|
||||
@@ -217,20 +206,11 @@ decl_storage! {
|
||||
}): T::Balance;
|
||||
/// The minimum amount allowed to keep an account open.
|
||||
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) config(): T::Balance;
|
||||
/// The fee required to make a transfer.
|
||||
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) config(): T::Balance;
|
||||
|
||||
/// The next free enumeration set.
|
||||
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): map T::AccountIndex => Vec<T::AccountId>;
|
||||
|
||||
/// The 'free' balance of a given account.
|
||||
///
|
||||
/// This is the only balance that matters in terms of most operations on tokens. It is
|
||||
@@ -268,25 +248,9 @@ decl_storage! {
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(balances): Vec<(T::AccountId, T::Balance)>;
|
||||
build(|storage: &mut primitives::StorageMap, _: &mut primitives::ChildrenStorageMap, 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());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Whatever happened about the hint given when creating the new account.
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
#[derive(Encode, Decode, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum NewAccountOutcome {
|
||||
NoHint,
|
||||
GoodHint,
|
||||
BadHint,
|
||||
}
|
||||
|
||||
/// Outcome of a balance update.
|
||||
pub enum UpdateBalanceOutcome {
|
||||
/// Account balance was simply updated.
|
||||
@@ -319,30 +283,6 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Lookup an T::AccountIndex to get an Id, if there's one there.
|
||||
pub fn lookup_index(index: T::AccountIndex) -> Option<T::AccountId> {
|
||||
let enum_set_size = Self::enum_set_size();
|
||||
let set = Self::enum_set(index / enum_set_size);
|
||||
let i: usize = (index % enum_set_size).as_();
|
||||
set.get(i).map(|x| x.clone())
|
||||
}
|
||||
|
||||
/// `true` if the account `index` is ready for reclaim.
|
||||
pub fn can_reclaim(try_index: T::AccountIndex) -> bool {
|
||||
let enum_set_size = Self::enum_set_size();
|
||||
let try_set = Self::enum_set(try_index / enum_set_size);
|
||||
let i = (try_index % enum_set_size).as_();
|
||||
i < try_set.len() && Self::total_balance(&try_set[i]).is_zero()
|
||||
}
|
||||
|
||||
/// Lookup an address to get an Id, if there's one there.
|
||||
pub fn lookup_address(a: address::Address<T::AccountId, T::AccountIndex>) -> Option<T::AccountId> {
|
||||
match a {
|
||||
address::Address::Id(i) => Some(i),
|
||||
address::Address::Index(i) => Self::lookup_index(i),
|
||||
}
|
||||
}
|
||||
|
||||
//PUBLIC MUTABLES (DANGEROUS)
|
||||
|
||||
/// Set the free balance of an account to some new value.
|
||||
@@ -399,22 +339,14 @@ impl<T: Trait> Module<T> {
|
||||
// account is reaped).
|
||||
// NOTE: This is orthogonal to the `Bondage` value that an account has, a high
|
||||
// value of which makes even the `free_balance` unspendable.
|
||||
// TODO: enforce this for the other balance-altering functions.
|
||||
if balance < ed {
|
||||
Self::set_free_balance(who, balance);
|
||||
UpdateBalanceOutcome::AccountKilled
|
||||
} else {
|
||||
if !<FreeBalance<T>>::exists(who) {
|
||||
let outcome = Self::new_account(&who, balance);
|
||||
let credit = match outcome {
|
||||
NewAccountOutcome::GoodHint => balance + <Module<T>>::reclaim_rebate(),
|
||||
_ => balance,
|
||||
};
|
||||
Self::set_free_balance(who, credit);
|
||||
Self::increase_total_stake_by(credit - balance);
|
||||
} else {
|
||||
Self::set_free_balance(who, balance);
|
||||
Self::new_account(&who, balance);
|
||||
}
|
||||
Self::set_free_balance(who, balance);
|
||||
|
||||
UpdateBalanceOutcome::Updated
|
||||
}
|
||||
@@ -550,82 +482,10 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn enum_set_size() -> T::AccountIndex {
|
||||
T::AccountIndex::sa(ENUM_SET_SIZE)
|
||||
}
|
||||
|
||||
/// Register a new account (with existential balance).
|
||||
fn new_account(who: &T::AccountId, balance: T::Balance) -> NewAccountOutcome {
|
||||
let enum_set_size = Self::enum_set_size();
|
||||
let next_set_index = Self::next_enum_set();
|
||||
let reclaim_index_magic = T::AccountIndex::sa(RECLAIM_INDEX_MAGIC);
|
||||
let reclaim_index_modulus = T::AccountIndex::sa(256usize);
|
||||
let quantization = T::AccountIndex::sa(256usize);
|
||||
|
||||
// A little easter-egg for reclaiming dead indexes..
|
||||
let ret = {
|
||||
// we quantise the number of accounts so it stays constant over a reasonable
|
||||
// period of time.
|
||||
let quantized_account_count: T::AccountIndex = (next_set_index * enum_set_size / quantization + One::one()) * quantization;
|
||||
// then modify the starting balance to be modulo this to allow it to potentially
|
||||
// identify an account index for reuse.
|
||||
let maybe_try_index = balance % <T::Balance as As<T::AccountIndex>>::sa(quantized_account_count * reclaim_index_modulus);
|
||||
let maybe_try_index = As::<T::AccountIndex>::as_(maybe_try_index);
|
||||
|
||||
// this identifier must end with magic byte 0x69 to trigger this check (a minor
|
||||
// optimisation to ensure we don't check most unintended account creations).
|
||||
if maybe_try_index % reclaim_index_modulus == reclaim_index_magic {
|
||||
// reuse is probably intended. first, remove magic byte.
|
||||
let try_index = maybe_try_index / reclaim_index_modulus;
|
||||
|
||||
// then check to see if this balance identifies a dead account index.
|
||||
let set_index = try_index / enum_set_size;
|
||||
let mut try_set = Self::enum_set(set_index);
|
||||
let item_index = (try_index % enum_set_size).as_();
|
||||
if item_index < try_set.len() {
|
||||
if Self::total_balance(&try_set[item_index]).is_zero() {
|
||||
// yup - this index refers to a dead account. can be reused.
|
||||
try_set[item_index] = who.clone();
|
||||
<EnumSet<T>>::insert(set_index, try_set);
|
||||
|
||||
Self::deposit_event(RawEvent::NewAccount(who.clone(), try_index, NewAccountOutcome::GoodHint));
|
||||
|
||||
return NewAccountOutcome::GoodHint
|
||||
}
|
||||
}
|
||||
NewAccountOutcome::BadHint
|
||||
} else {
|
||||
NewAccountOutcome::NoHint
|
||||
}
|
||||
};
|
||||
|
||||
// insert normally as a back up
|
||||
let mut set_index = next_set_index;
|
||||
// defensive only: this loop should never iterate since we keep NextEnumSet up to date later.
|
||||
let mut set = loop {
|
||||
let set = Self::enum_set(set_index);
|
||||
if set.len() < ENUM_SET_SIZE {
|
||||
break set;
|
||||
}
|
||||
set_index += One::one();
|
||||
};
|
||||
|
||||
let index = T::AccountIndex::sa(set_index.as_() * ENUM_SET_SIZE + set.len());
|
||||
|
||||
// update set.
|
||||
set.push(who.clone());
|
||||
|
||||
// keep NextEnumSet up to date
|
||||
if set.len() == ENUM_SET_SIZE {
|
||||
<NextEnumSet<T>>::put(set_index + One::one());
|
||||
}
|
||||
|
||||
// write set.
|
||||
<EnumSet<T>>::insert(set_index, set);
|
||||
|
||||
Self::deposit_event(RawEvent::NewAccount(who.clone(), index, ret));
|
||||
|
||||
ret
|
||||
fn new_account(who: &T::AccountId, balance: T::Balance) {
|
||||
T::OnNewAccount::on_new_account(&who);
|
||||
Self::deposit_event(RawEvent::NewAccount(who.clone(), balance.clone()));
|
||||
}
|
||||
|
||||
fn reap_account(who: &T::AccountId) {
|
||||
@@ -667,43 +527,6 @@ impl<T: Trait> Module<T> {
|
||||
<TotalIssuance<T>>::put(v);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup(a: address::Address<T::AccountId, T::AccountIndex>) -> result::Result<T::AccountId, &'static str> {
|
||||
match a {
|
||||
address::Address::Id(i) => Ok(i),
|
||||
address::Address::Index(i) => <Module<T>>::lookup_index(i).ok_or("invalid account index"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChainContext<T>(::rstd::marker::PhantomData<T>);
|
||||
impl<T> Default for ChainContext<T> {
|
||||
fn default() -> Self {
|
||||
ChainContext(::rstd::marker::PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Lookup for ChainContext<T> {
|
||||
type Source = address::Address<T::AccountId, T::AccountIndex>;
|
||||
type Target = T::AccountId;
|
||||
fn lookup(&self, a: Self::Source) -> result::Result<Self::Target, &'static str> {
|
||||
<Module<T>>::lookup(a)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> CurrentHeight for ChainContext<T> {
|
||||
type BlockNumber = T::BlockNumber;
|
||||
fn current_height(&self) -> Self::BlockNumber {
|
||||
<system::Module<T>>::block_number()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> BlockNumberToHash for ChainContext<T> {
|
||||
type BlockNumber = T::BlockNumber;
|
||||
type Hash = T::Hash;
|
||||
fn block_number_to_hash(&self, n: Self::BlockNumber) -> Option<Self::Hash> {
|
||||
Some(<system::Module<T>>::block_hash(n))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> MakePayment<T::AccountId> for Module<T> {
|
||||
@@ -718,3 +541,9 @@ impl<T: Trait> MakePayment<T::AccountId> for Module<T> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> IsDeadAccount<T::AccountId> for Module<T> {
|
||||
fn is_dead_account(who: &T::AccountId) -> bool {
|
||||
Self::total_balance(who).is_zero()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#![cfg(test)]
|
||||
|
||||
use primitives::BuildStorage;
|
||||
use primitives::testing::{Digest, DigestItem, Header};
|
||||
use primitives::{traits::{IdentityLookup}, testing::{Digest, DigestItem, Header}};
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use runtime_io;
|
||||
use {GenesisConfig, Module, Trait, system};
|
||||
@@ -39,14 +39,15 @@ impl system::Trait for Runtime {
|
||||
type Hashing = ::primitives::traits::BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
type Log = DigestItem;
|
||||
}
|
||||
impl Trait for Runtime {
|
||||
type Balance = u64;
|
||||
type AccountIndex = u64;
|
||||
type OnFreeBalanceZero = ();
|
||||
type OnNewAccount = ();
|
||||
type EnsureAccountLiquid = ();
|
||||
type Event = ();
|
||||
}
|
||||
@@ -103,7 +104,6 @@ impl ExtBuilder {
|
||||
existential_deposit: self.existential_deposit,
|
||||
transfer_fee: self.transfer_fee,
|
||||
creation_fee: self.creation_fee,
|
||||
reclaim_rebate: 0,
|
||||
}.build_storage().unwrap().0);
|
||||
t.into()
|
||||
}
|
||||
|
||||
@@ -22,67 +22,6 @@ use super::*;
|
||||
use mock::{Balances, ExtBuilder, Runtime, System};
|
||||
use runtime_io::with_externalities;
|
||||
|
||||
#[test]
|
||||
fn reward_should_work() {
|
||||
with_externalities(&mut ExtBuilder::default().monied(true).build(), || {
|
||||
assert_eq!(Balances::total_balance(&1), 10);
|
||||
assert_ok!(Balances::reward(&1, 10));
|
||||
assert_eq!(Balances::total_balance(&1), 20);
|
||||
assert_eq!(<TotalIssuance<Runtime>>::get(), 110);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indexing_lookup_should_work() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(10)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
assert_eq!(Balances::lookup_index(0), Some(1));
|
||||
assert_eq!(Balances::lookup_index(1), Some(2));
|
||||
assert_eq!(Balances::lookup_index(2), Some(3));
|
||||
assert_eq!(Balances::lookup_index(3), Some(4));
|
||||
assert_eq!(Balances::lookup_index(4), None);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_indexing_on_new_accounts_should_work() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(10)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
assert_eq!(Balances::lookup_index(4), None);
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 5.into(), 10.into()));
|
||||
assert_eq!(Balances::lookup_index(4), Some(5));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_indexing_on_new_accounts_should_work2() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(10)
|
||||
.creation_fee(50)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
assert_eq!(Balances::lookup_index(4), None);
|
||||
// account 1 has 256 * 10 = 2560, account 5 is not exist, ext_deposit is 10, value is 10
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 5.into(), 10.into()));
|
||||
assert_eq!(Balances::lookup_index(4), Some(5));
|
||||
|
||||
assert_eq!(Balances::free_balance(&1), 256 * 10 - 10 - 50); // 10 is value, 50 is creation_free
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_indexing_on_new_accounts_should_not_work2() {
|
||||
with_externalities(
|
||||
@@ -92,18 +31,64 @@ fn default_indexing_on_new_accounts_should_not_work2() {
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
assert_eq!(Balances::lookup_index(4), None);
|
||||
assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist
|
||||
// account 1 has 256 * 10 = 2560, account 5 is not exist, ext_deposit is 10, value is 9, not satisfies for ext_deposit
|
||||
assert_noop!(
|
||||
Balances::transfer(Some(1).into(), 5.into(), 9.into()),
|
||||
Balances::transfer(Some(1).into(), 5, 9.into()),
|
||||
"value too low to create account"
|
||||
);
|
||||
assert_eq!(Balances::lookup_index(4), None); // account 5 should not exist
|
||||
assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist
|
||||
assert_eq!(Balances::free_balance(&1), 256 * 10);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserved_balance_should_prevent_reclaim_count() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(256 * 1)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
System::inc_account_nonce(&2);
|
||||
assert_eq!(Balances::is_dead_account(&2), false);
|
||||
assert_eq!(Balances::is_dead_account(&5), true);
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 20);
|
||||
|
||||
assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved
|
||||
assert_eq!(Balances::free_balance(&2), 0); // "free" account deleted."
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 19 + 1); // reserve still exists.
|
||||
assert_eq!(Balances::is_dead_account(&2), false);
|
||||
assert_eq!(System::account_nonce(&2), 1);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 5, (256 * 1 + 0x69).into())); // account 4 tries to take index 1 for account 5.
|
||||
assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::is_dead_account(&5), false);
|
||||
|
||||
assert_eq!(Balances::slash(&2, 256 * 18 + 2), None); // account 2 gets slashed
|
||||
assert_eq!(Balances::total_balance(&2), 0); // "reserve" account reduced to 255 (below ED) so account deleted
|
||||
assert_eq!(System::account_nonce(&2), 0); // nonce zero
|
||||
assert_eq!(Balances::is_dead_account(&2), true);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 6, (256 * 1 + 0x69).into())); // account 4 tries to take index 1 again for account 6.
|
||||
assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::is_dead_account(&6), false);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn reward_should_work() {
|
||||
with_externalities(&mut ExtBuilder::default().monied(true).build(), || {
|
||||
assert_eq!(Balances::total_balance(&1), 10);
|
||||
assert_ok!(Balances::reward(&1, 10));
|
||||
assert_eq!(Balances::total_balance(&1), 20);
|
||||
assert_eq!(<TotalIssuance<Runtime>>::get(), 110);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dust_account_removal_should_work() {
|
||||
with_externalities(
|
||||
@@ -116,7 +101,7 @@ fn dust_account_removal_should_work() {
|
||||
assert_eq!(System::account_nonce(&2), 1);
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 20);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(2).into(), 5.into(), (256 * 10 + 1).into())); // index 1 (account 2) becomes zombie
|
||||
assert_ok!(Balances::transfer(Some(2).into(), 5, (256 * 10 + 1).into())); // index 1 (account 2) becomes zombie
|
||||
assert_eq!(Balances::total_balance(&2), 0);
|
||||
assert_eq!(Balances::total_balance(&5), 256 * 10 + 1);
|
||||
assert_eq!(System::account_nonce(&2), 0);
|
||||
@@ -136,7 +121,7 @@ fn dust_account_removal_should_work2() {
|
||||
System::inc_account_nonce(&2);
|
||||
assert_eq!(System::account_nonce(&2), 1);
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 20);
|
||||
assert_ok!(Balances::transfer(Some(2).into(), 5.into(), (256 * 10).into())); // index 1 (account 2) becomes zombie for 256*10 + 50(fee) < 256 * 10 (ext_deposit)
|
||||
assert_ok!(Balances::transfer(Some(2).into(), 5, (256 * 10).into())); // index 1 (account 2) becomes zombie for 256*10 + 50(fee) < 256 * 10 (ext_deposit)
|
||||
assert_eq!(Balances::total_balance(&2), 0);
|
||||
assert_eq!(Balances::total_balance(&5), 256 * 10);
|
||||
assert_eq!(System::account_nonce(&2), 0);
|
||||
@@ -144,118 +129,6 @@ fn dust_account_removal_should_work2() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reclaim_indexing_on_new_accounts_should_work() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(256 * 1)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
assert_eq!(Balances::lookup_index(1), Some(2));
|
||||
assert_eq!(Balances::lookup_index(4), None);
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 20);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(2).into(), 5.into(), (256 * 20).into())); // account 2 becomes zombie freeing index 1 for reclaim)
|
||||
assert_eq!(Balances::total_balance(&2), 0);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(5).into(), 6.into(), (256 * 1 + 0x69).into())); // account 6 takes index 1.
|
||||
assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::lookup_index(1), Some(6));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reclaim_indexing_on_new_accounts_should_work2() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(256 * 1)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
assert_eq!(Balances::lookup_index(1), Some(2));
|
||||
assert_eq!(Balances::lookup_index(4), None);
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 20);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(2).into(), 5.into(), (256 * 20 - 50).into())); // account 2 becomes zombie freeing index 1 for reclaim) 50 is creation fee
|
||||
assert_eq!(Balances::total_balance(&2), 0);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(5).into(), 6.into(), (256 * 1 + 0x69).into())); // account 6 takes index 1.
|
||||
assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::lookup_index(1), Some(6));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserved_balance_should_prevent_reclaim_count() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(256 * 1)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
System::inc_account_nonce(&2);
|
||||
assert_eq!(Balances::lookup_index(1), Some(2));
|
||||
assert_eq!(Balances::lookup_index(4), None);
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 20);
|
||||
|
||||
assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved
|
||||
assert_eq!(Balances::free_balance(&2), 0); // "free" account deleted."
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 19 + 1); // reserve still exists.
|
||||
assert_eq!(System::account_nonce(&2), 1);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 5.into(), (256 * 1 + 0x69).into())); // account 4 tries to take index 1 for account 5.
|
||||
assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::lookup_index(1), Some(2)); // but fails.
|
||||
assert_eq!(System::account_nonce(&2), 1);
|
||||
|
||||
assert_eq!(Balances::slash(&2, 256 * 18 + 2), None); // account 2 gets slashed
|
||||
assert_eq!(Balances::total_balance(&2), 0); // "free" account deleted."
|
||||
assert_eq!(System::account_nonce(&2), 0);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 6.into(), (256 * 1 + 0x69).into())); // account 4 tries to take index 1 again for account 6.
|
||||
assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::lookup_index(1), Some(6)); // and succeeds.
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserved_balance_should_prevent_reclaim_count2() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(256 * 1)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
System::inc_account_nonce(&2);
|
||||
assert_eq!(Balances::lookup_index(1), Some(2));
|
||||
assert_eq!(Balances::lookup_index(4), None);
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 20);
|
||||
|
||||
assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved
|
||||
assert_eq!(Balances::free_balance(&2), 0); // "free" account deleted."
|
||||
assert_eq!(Balances::total_balance(&2), 256 * 19 + 1); // reserve still exists.
|
||||
assert_eq!(System::account_nonce(&2), 1);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 5.into(), (256 * 1 + 0x69).into())); // account 4 tries to take index 1 for account 5.
|
||||
assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::lookup_index(1), Some(2)); // but fails.
|
||||
assert_eq!(System::account_nonce(&2), 1);
|
||||
|
||||
assert_eq!(Balances::slash(&2, 256 * 18 + 2), None); // account 2 gets slashed
|
||||
assert_eq!(Balances::total_balance(&2), 0); // "free" account deleted."
|
||||
assert_eq!(System::account_nonce(&2), 0);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 6.into(), (256 * 1 + 0x69).into())); // account 4 tries to take index 1 again for account 6.
|
||||
assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::lookup_index(1), Some(6)); // and succeeds.
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn balance_works() {
|
||||
with_externalities(&mut ExtBuilder::default().build(), || {
|
||||
@@ -274,7 +147,7 @@ fn balance_transfer_works() {
|
||||
with_externalities(&mut ExtBuilder::default().build(), || {
|
||||
Balances::set_free_balance(&1, 111);
|
||||
Balances::increase_total_stake_by(111);
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 2.into(), 69.into()));
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 2, 69.into()));
|
||||
assert_eq!(Balances::total_balance(&1), 42);
|
||||
assert_eq!(Balances::total_balance(&2), 69);
|
||||
});
|
||||
@@ -313,7 +186,7 @@ fn balance_transfer_when_reserved_should_not_work() {
|
||||
with_externalities(&mut ExtBuilder::default().build(), || {
|
||||
Balances::set_free_balance(&1, 111);
|
||||
assert_ok!(Balances::reserve(&1, 69));
|
||||
assert_noop!(Balances::transfer(Some(1).into(), 2.into(), 69.into()), "balance too low to send value");
|
||||
assert_noop!(Balances::transfer(Some(1).into(), 2, 69.into()), "balance too low to send value");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -444,7 +317,7 @@ fn transferring_too_high_value_should_not_panic() {
|
||||
<FreeBalance<Runtime>>::insert(2, 1);
|
||||
|
||||
assert_err!(
|
||||
Balances::transfer(Some(1).into(), 2.into(), u64::max_value().into()),
|
||||
Balances::transfer(Some(1).into(), 2, u64::max_value().into()),
|
||||
"destination balance too high to receive value"
|
||||
);
|
||||
|
||||
@@ -472,7 +345,7 @@ fn account_removal_on_free_too_low() {
|
||||
// Transfer funds from account 1 of such amount that after this transfer
|
||||
// the balance of account 1 will be below the exsistential threshold.
|
||||
// This should lead to the removal of all balance of this account.
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 2.into(), 20.into()));
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 2, 20.into()));
|
||||
|
||||
// Verify free balance removal of account 1.
|
||||
assert_eq!(Balances::free_balance(&1), 0);
|
||||
@@ -492,7 +365,7 @@ fn transfer_overflow_isnt_exploitable() {
|
||||
let evil_value = u64::max_value() - 49;
|
||||
|
||||
assert_err!(
|
||||
Balances::transfer(Some(1).into(), 5.into(), evil_value.into()),
|
||||
Balances::transfer(Some(1).into(), 5, evil_value.into()),
|
||||
"got overflow after adding a fee to value"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use primitives::{BuildStorage, testing::{Digest, DigestItem, Header, UintAuthorityId}};
|
||||
use primitives::{BuildStorage, traits::IdentityLookup, testing::{Digest, DigestItem, Header, UintAuthorityId}};
|
||||
use runtime_io;
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use {GenesisConfig, Trait, Module, system};
|
||||
@@ -44,6 +44,7 @@ impl system::Trait for Test {
|
||||
type Hashing = ::primitives::traits::BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
type Log = DigestItem;
|
||||
|
||||
@@ -97,7 +97,7 @@ use account_db::{AccountDb, OverlayAccountDb};
|
||||
use rstd::prelude::*;
|
||||
use rstd::marker::PhantomData;
|
||||
use codec::{Codec, HasCompact};
|
||||
use runtime_primitives::traits::{Hash, As, SimpleArithmetic};
|
||||
use runtime_primitives::traits::{Hash, As, SimpleArithmetic, StaticLookup};
|
||||
use runtime_support::dispatch::Result;
|
||||
use runtime_support::{Parameter, StorageMap, StorageValue, StorageDoubleMap};
|
||||
use system::ensure_signed;
|
||||
@@ -152,7 +152,7 @@ decl_module! {
|
||||
/// Make a call to a specified account, optionally transferring some balance.
|
||||
fn call(
|
||||
origin,
|
||||
dest: T::AccountId,
|
||||
dest: <T::Lookup as StaticLookup>::Source,
|
||||
value: <T::Balance as HasCompact>::Type,
|
||||
gas_limit: <T::Gas as HasCompact>::Type,
|
||||
data: Vec<u8>
|
||||
@@ -160,6 +160,7 @@ decl_module! {
|
||||
let origin = ensure_signed(origin)?;
|
||||
let value = value.into();
|
||||
let gas_limit = gas_limit.into();
|
||||
let dest = T::Lookup::lookup(dest)?;
|
||||
|
||||
// Pay for the gas upfront.
|
||||
//
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
use runtime_io::with_externalities;
|
||||
use runtime_primitives::testing::{Digest, DigestItem, H256, Header};
|
||||
use runtime_primitives::traits::{BlakeTwo256};
|
||||
use runtime_primitives::traits::{BlakeTwo256, IdentityLookup};
|
||||
use runtime_primitives::BuildStorage;
|
||||
use runtime_support::{StorageMap, StorageDoubleMap};
|
||||
use substrate_primitives::{Blake2Hasher};
|
||||
@@ -50,14 +50,15 @@ impl system::Trait for Test {
|
||||
type Hashing = BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = MetaEvent;
|
||||
type Log = DigestItem;
|
||||
}
|
||||
impl balances::Trait for Test {
|
||||
type Balance = u64;
|
||||
type AccountIndex = u64;
|
||||
type OnFreeBalanceZero = Contract;
|
||||
type OnNewAccount = ();
|
||||
type EnsureAccountLiquid = ();
|
||||
type Event = MetaEvent;
|
||||
}
|
||||
@@ -129,7 +130,6 @@ impl ExtBuilder {
|
||||
existential_deposit: self.existential_deposit,
|
||||
transfer_fee: self.transfer_fee,
|
||||
creation_fee: self.creation_fee,
|
||||
reclaim_rebate: 0,
|
||||
}.build_storage()
|
||||
.unwrap().0,
|
||||
);
|
||||
@@ -224,8 +224,7 @@ fn contract_transfer() {
|
||||
event: MetaEvent::balances(
|
||||
balances::RawEvent::NewAccount(
|
||||
CONTRACT_SHOULD_TRANSFER_TO,
|
||||
0,
|
||||
balances::NewAccountOutcome::NoHint
|
||||
6
|
||||
)
|
||||
),
|
||||
},
|
||||
@@ -544,8 +543,7 @@ fn contract_create() {
|
||||
event: MetaEvent::balances(
|
||||
balances::RawEvent::NewAccount(
|
||||
derived_address,
|
||||
0,
|
||||
balances::NewAccountOutcome::NoHint
|
||||
3
|
||||
)
|
||||
),
|
||||
},
|
||||
@@ -704,7 +702,7 @@ fn account_removal_removes_storage() {
|
||||
// the balance of account 1 is will be below than exsistential threshold.
|
||||
//
|
||||
// This should lead to the removal of all storage associated with this account.
|
||||
assert_ok!(Balances::transfer(Origin::signed(1), 2.into(), 20.into()));
|
||||
assert_ok!(Balances::transfer(Origin::signed(1), 2, 20.into()));
|
||||
|
||||
// Verify that all entries from account 1 is removed, while
|
||||
// entries from account 2 is in place.
|
||||
|
||||
@@ -50,7 +50,7 @@ mod tests {
|
||||
pub use runtime_io::with_externalities;
|
||||
pub use substrate_primitives::H256;
|
||||
pub use primitives::BuildStorage;
|
||||
pub use primitives::traits::{BlakeTwo256};
|
||||
pub use primitives::traits::{BlakeTwo256, IdentityLookup};
|
||||
pub use primitives::testing::{Digest, DigestItem, Header};
|
||||
pub use substrate_primitives::{Blake2Hasher};
|
||||
pub use {seats, motions, voting};
|
||||
@@ -85,14 +85,15 @@ mod tests {
|
||||
type Hashing = BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = Event;
|
||||
type Log = DigestItem;
|
||||
}
|
||||
impl balances::Trait for Test {
|
||||
type Balance = u64;
|
||||
type AccountIndex = u64;
|
||||
type OnFreeBalanceZero = ();
|
||||
type OnNewAccount = ();
|
||||
type EnsureAccountLiquid = ();
|
||||
type Event = Event;
|
||||
}
|
||||
@@ -121,7 +122,6 @@ mod tests {
|
||||
existential_deposit: 0,
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(democracy::GenesisConfig::<Test>{
|
||||
launch_period: 1,
|
||||
|
||||
@@ -220,7 +220,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn set_balance_proposal(value: u64) -> Call {
|
||||
Call::Balances(balances::Call::set_balance(balances::address::Address::Id(42), value.into(), 0.into()))
|
||||
Call::Balances(balances::Call::set_balance(42, value.into(), 0.into()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -237,7 +237,7 @@ mod tests {
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), 3))
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), 3))
|
||||
}
|
||||
]);
|
||||
});
|
||||
@@ -290,11 +290,11 @@ mod tests {
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), 2))
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), 2))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Voted(1, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), false, 0, 1))
|
||||
event: OuterEvent::motions(RawEvent::Voted(1, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), false, 0, 1))
|
||||
}
|
||||
]);
|
||||
});
|
||||
@@ -312,15 +312,15 @@ mod tests {
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), 3))
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), 3))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Voted(2, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), false, 1, 1))
|
||||
event: OuterEvent::motions(RawEvent::Voted(2, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), false, 1, 1))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Disapproved(hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into()))
|
||||
event: OuterEvent::motions(RawEvent::Disapproved(hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into()))
|
||||
}
|
||||
]);
|
||||
});
|
||||
@@ -338,19 +338,19 @@ mod tests {
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), 2))
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), 2))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Voted(2, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), true, 2, 0))
|
||||
event: OuterEvent::motions(RawEvent::Voted(2, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), true, 2, 0))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Approved(hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into()))
|
||||
event: OuterEvent::motions(RawEvent::Approved(hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into()))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::motions(RawEvent::Executed(hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), false))
|
||||
event: OuterEvent::motions(RawEvent::Executed(hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), false))
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
|
||||
use rstd::prelude::*;
|
||||
use codec::{Compact, HasCompact};
|
||||
use primitives::traits::{Zero, One, As};
|
||||
use primitives::traits::{Zero, One, As, StaticLookup};
|
||||
use runtime_io::print;
|
||||
use srml_support::{StorageValue, StorageMap, dispatch::Result};
|
||||
use democracy;
|
||||
use balances::{self, address::Address};
|
||||
use balances;
|
||||
use system::{self, ensure_signed};
|
||||
|
||||
// no polynomial attacks:
|
||||
@@ -127,14 +127,14 @@ decl_module! {
|
||||
fn reap_inactive_voter(
|
||||
origin,
|
||||
reporter_index: Compact<u32>,
|
||||
who: Address<T::AccountId, T::AccountIndex>,
|
||||
who: <T::Lookup as StaticLookup>::Source,
|
||||
who_index: Compact<u32>,
|
||||
assumed_vote_index: Compact<VoteIndex>
|
||||
) {
|
||||
let reporter = ensure_signed(origin)?;
|
||||
let assumed_vote_index: VoteIndex = assumed_vote_index.into();
|
||||
|
||||
let who = <balances::Module<T>>::lookup(who)?;
|
||||
let who = T::Lookup::lookup(who)?;
|
||||
ensure!(!Self::presentation_active(), "cannot reap during presentation period");
|
||||
ensure!(Self::voter_last_active(&reporter).is_some(), "reporter must be a voter");
|
||||
let last_active = Self::voter_last_active(&who).ok_or("target for inactivity cleanup must be active")?;
|
||||
@@ -226,7 +226,7 @@ decl_module! {
|
||||
/// `signed` should have at least
|
||||
fn present_winner(
|
||||
origin,
|
||||
candidate: Address<T::AccountId, T::AccountIndex>,
|
||||
candidate: <T::Lookup as StaticLookup>::Source,
|
||||
total: <T::Balance as HasCompact>::Type,
|
||||
index: Compact<VoteIndex>
|
||||
) -> Result {
|
||||
@@ -235,7 +235,7 @@ decl_module! {
|
||||
ensure!(!total.is_zero(), "stake deposited to present winner and be added to leaderboard should be non-zero");
|
||||
let index: VoteIndex = index.into();
|
||||
|
||||
let candidate = <balances::Module<T>>::lookup(candidate)?;
|
||||
let candidate = T::Lookup::lookup(candidate)?;
|
||||
ensure!(index == Self::vote_index(), "index not current");
|
||||
let (_, _, expiring) = Self::next_finalise().ok_or("cannot present outside of presentation period")?;
|
||||
let stakes = Self::snapshoted_stakes();
|
||||
@@ -288,8 +288,8 @@ decl_module! {
|
||||
/// Remove a particular member. A tally will happen instantly (if not already in a presentation
|
||||
/// period) to fill the seat if removal means that the desired members are not met.
|
||||
/// This is effective immediately.
|
||||
fn remove_member(who: Address<T::AccountId, T::AccountIndex>) {
|
||||
let who = <balances::Module<T>>::lookup(who)?;
|
||||
fn remove_member(who: <T::Lookup as StaticLookup>::Source) {
|
||||
let who = T::Lookup::lookup(who)?;
|
||||
let new_council: Vec<(T::AccountId, T::BlockNumber)> = Self::active_council()
|
||||
.into_iter()
|
||||
.filter(|i| i.0 != who)
|
||||
@@ -874,8 +874,8 @@ mod tests {
|
||||
|
||||
System::set_block_number(6);
|
||||
assert!(Council::presentation_active());
|
||||
assert_eq!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()), Ok(()));
|
||||
assert_eq!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()), Ok(()));
|
||||
assert_eq!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()), Ok(()));
|
||||
assert_eq!(Council::present_winner(Origin::signed(4), 5, 50.into(), 0.into()), Ok(()));
|
||||
assert_eq!(Council::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)]));
|
||||
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
@@ -900,7 +900,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_noop!(Council::present_winner(Origin::signed(4), 2.into(), 0.into(), 0.into()), "stake deposited to present winner and be added to leaderboard should be non-zero");
|
||||
assert_noop!(Council::present_winner(Origin::signed(4), 2, 0.into(), 0.into()), "stake deposited to present winner and be added to leaderboard should be non-zero");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -917,9 +917,9 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()));
|
||||
assert_eq!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()), Err("duplicate presentation"));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 0.into()));
|
||||
assert_eq!(Council::present_winner(Origin::signed(4), 5, 50.into(), 0.into()), Err("duplicate presentation"));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
assert_eq!(Council::active_council(), vec![(5, 11), (2, 11)]);
|
||||
@@ -936,7 +936,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(8);
|
||||
@@ -945,12 +945,12 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(10);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 1.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
assert_ok!(Council::reap_inactive_voter(Origin::signed(5),
|
||||
(Council::voters().iter().position(|&i| i == 5).unwrap() as u32).into(),
|
||||
2.into(), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2, (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2.into()
|
||||
));
|
||||
|
||||
@@ -970,7 +970,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(8);
|
||||
@@ -979,7 +979,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(10);
|
||||
assert_noop!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 1.into()), "candidate must not form a duplicated member if elected");
|
||||
assert_noop!(Council::present_winner(Origin::signed(4), 2, 20.into(), 1.into()), "candidate must not form a duplicated member if elected");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -992,7 +992,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(8);
|
||||
@@ -1001,7 +1001,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(10);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 1.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(11);
|
||||
@@ -1009,7 +1009,7 @@ mod tests {
|
||||
|
||||
assert_ok!(Council::reap_inactive_voter(Origin::signed(5),
|
||||
(Council::voters().iter().position(|&i| i == 5).unwrap() as u32).into(),
|
||||
2.into(), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2, (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2.into()
|
||||
));
|
||||
|
||||
@@ -1029,7 +1029,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(8);
|
||||
@@ -1038,12 +1038,12 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(10);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 1.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
assert_noop!(Council::reap_inactive_voter(Origin::signed(2),
|
||||
42.into(),
|
||||
2.into(), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2, (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2.into()
|
||||
), "bad reporter index");
|
||||
});
|
||||
@@ -1058,7 +1058,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(8);
|
||||
@@ -1067,12 +1067,12 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(10);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 1.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
assert_noop!(Council::reap_inactive_voter(Origin::signed(2),
|
||||
(Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2.into(), 42.into(),
|
||||
2, 42.into(),
|
||||
2.into()
|
||||
), "bad target index");
|
||||
});
|
||||
@@ -1093,10 +1093,10 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3, 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4, 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 0.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(8);
|
||||
@@ -1104,8 +1104,8 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(10);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3, 30.into(), 1.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
assert_eq!(Council::vote_index(), 2);
|
||||
@@ -1115,7 +1115,7 @@ mod tests {
|
||||
|
||||
assert_ok!(Council::reap_inactive_voter(Origin::signed(4),
|
||||
(Council::voters().iter().position(|&i| i == 4).unwrap() as u32).into(),
|
||||
2.into(),
|
||||
2,
|
||||
(Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2.into()
|
||||
));
|
||||
@@ -1135,7 +1135,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(8);
|
||||
@@ -1144,12 +1144,12 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(10);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 1.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
assert_noop!(Council::reap_inactive_voter(Origin::signed(4),
|
||||
0.into(),
|
||||
2.into(), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2, (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(),
|
||||
2.into()
|
||||
), "reporter must be a voter");
|
||||
});
|
||||
@@ -1172,10 +1172,10 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 1.into(), 60.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 1, 60.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3, 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4, 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 0.into()));
|
||||
|
||||
assert_eq!(Council::leaderboard(), Some(vec![
|
||||
(30, 3),
|
||||
@@ -1184,7 +1184,7 @@ mod tests {
|
||||
(60, 1)
|
||||
]));
|
||||
|
||||
assert_noop!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()), "candidate not worthy of leaderboard");
|
||||
assert_noop!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()), "candidate not worthy of leaderboard");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1205,11 +1205,11 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 1.into(), 60.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 2, 20.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 1, 60.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3, 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4, 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 0.into()));
|
||||
|
||||
assert_eq!(Council::leaderboard(), Some(vec![
|
||||
(30, 3),
|
||||
@@ -1225,7 +1225,7 @@ mod tests {
|
||||
with_externalities(&mut new_test_ext(false), || {
|
||||
System::set_block_number(4);
|
||||
assert!(!Council::presentation_active());
|
||||
assert_noop!(Council::present_winner(Origin::signed(5), 5.into(), 1.into(), 0.into()), "cannot present outside of presentation period");
|
||||
assert_noop!(Council::present_winner(Origin::signed(5), 5, 1.into(), 0.into()), "cannot present outside of presentation period");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1240,7 +1240,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_noop!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 1.into()), "index not current");
|
||||
assert_noop!(Council::present_winner(Origin::signed(4), 2, 20.into(), 1.into()), "index not current");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1259,7 +1259,7 @@ mod tests {
|
||||
System::set_block_number(6);
|
||||
assert_eq!(Balances::free_balance(&1), 1);
|
||||
assert_eq!(Balances::reserved_balance(&1), 9);
|
||||
assert_noop!(Council::present_winner(Origin::signed(1), 1.into(), 20.into(), 0.into()), "presenter must have sufficient slashable funds");
|
||||
assert_noop!(Council::present_winner(Origin::signed(1), 1, 20.into(), 0.into()), "presenter must have sufficient slashable funds");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1277,7 +1277,7 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_err!(Council::present_winner(Origin::signed(4), 2.into(), 80.into(), 0.into()), "incorrect total");
|
||||
assert_err!(Council::present_winner(Origin::signed(4), 2, 80.into(), 0.into()), "incorrect total");
|
||||
|
||||
assert_eq!(Balances::total_balance(&4), 38);
|
||||
});
|
||||
@@ -1304,7 +1304,7 @@ mod tests {
|
||||
|
||||
System::set_block_number(6);
|
||||
assert!(Council::presentation_active());
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 1.into(), 60.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 1, 60.into(), 0.into()));
|
||||
// leaderboard length is the empty seats plus the carry count (i.e. 5 + 2), where those
|
||||
// to be carried are the lowest and stored in lowest indexes
|
||||
assert_eq!(Council::leaderboard(), Some(vec![
|
||||
@@ -1313,9 +1313,9 @@ mod tests {
|
||||
(0, 0),
|
||||
(60, 1)
|
||||
]));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3, 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4, 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 0.into()));
|
||||
assert_eq!(Council::leaderboard(), Some(vec![
|
||||
(30, 3),
|
||||
(40, 4),
|
||||
@@ -1361,10 +1361,10 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(6);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 1.into(), 60.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 1, 60.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3, 30.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4, 40.into(), 0.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 5, 50.into(), 0.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(8);
|
||||
@@ -1373,8 +1373,8 @@ mod tests {
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
System::set_block_number(10);
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 90.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 3, 90.into(), 1.into()));
|
||||
assert_ok!(Council::present_winner(Origin::signed(4), 4, 40.into(), 1.into()));
|
||||
assert_ok!(Council::end_block(System::block_number()));
|
||||
|
||||
assert!(!Council::presentation_active());
|
||||
|
||||
@@ -259,7 +259,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn set_balance_proposal(value: u64) -> Call {
|
||||
Call::Balances(balances::Call::set_balance(balances::address::Address::Id(42), value.into(), 0.into()))
|
||||
Call::Balances(balances::Call::set_balance(42, value.into(), 0.into()))
|
||||
}
|
||||
|
||||
fn cancel_referendum_proposal(id: u32) -> Call {
|
||||
|
||||
@@ -154,9 +154,9 @@ decl_module! {
|
||||
}
|
||||
|
||||
/// Cancel a proposal queued for enactment.
|
||||
pub fn cancel_queued(when: T::BlockNumber, which: u32) -> Result {
|
||||
let which = which as usize;
|
||||
<DispatchQueue<T>>::mutate(when, |items| if items.len() > which { items[which] = None });
|
||||
pub fn cancel_queued(when: <T::BlockNumber as HasCompact>::Type, which: Compact<u32>) -> Result {
|
||||
let which = u32::from(which) as usize;
|
||||
<DispatchQueue<T>>::mutate(when.into(), |items| if items.len() > which { items[which] = None });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ mod tests {
|
||||
use runtime_io::with_externalities;
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use primitives::BuildStorage;
|
||||
use primitives::traits::{BlakeTwo256};
|
||||
use primitives::traits::{BlakeTwo256, IdentityLookup};
|
||||
use primitives::testing::{Digest, DigestItem, Header};
|
||||
|
||||
const AYE: Vote = Vote(-1);
|
||||
@@ -469,14 +469,15 @@ mod tests {
|
||||
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 AccountIndex = u64;
|
||||
type OnFreeBalanceZero = ();
|
||||
type OnNewAccount = ();
|
||||
type EnsureAccountLiquid = ();
|
||||
type Event = ();
|
||||
}
|
||||
@@ -498,7 +499,6 @@ mod tests {
|
||||
existential_deposit: 0,
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
launch_period: 1,
|
||||
@@ -555,7 +555,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn set_balance_proposal(value: u64) -> Call {
|
||||
Call::Balances(balances::Call::set_balance(balances::address::Address::Id(42), value.into(), 0.into()))
|
||||
Call::Balances(balances::Call::set_balance(42, value.into(), 0.into()))
|
||||
}
|
||||
|
||||
fn propose_set_balance(who: u64, value: u64, locked: u64) -> super::Result {
|
||||
|
||||
@@ -50,6 +50,7 @@ extern crate srml_system as system;
|
||||
// might find it useful).
|
||||
extern crate srml_balances as balances;
|
||||
|
||||
use codec::HasCompact;
|
||||
use support::{StorageValue, dispatch::Result};
|
||||
use system::ensure_signed;
|
||||
|
||||
@@ -177,9 +178,9 @@ decl_module! {
|
||||
// without worrying about gameability or attack scenarios.
|
||||
// If you not specify `Result` explicitly as return value, it will be added automatically
|
||||
// for you and `Ok(())` will be returned.
|
||||
fn set_dummy(new_value: T::Balance) {
|
||||
fn set_dummy(new_value: <T::Balance as HasCompact>::Type) {
|
||||
// Put the new value into storage.
|
||||
<Dummy<T>>::put(new_value);
|
||||
<Dummy<T>>::put(new_value.into());
|
||||
}
|
||||
|
||||
// The signature could also look like: `fn on_finalise()`
|
||||
@@ -269,7 +270,7 @@ mod tests {
|
||||
// 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 sr_primitives::{
|
||||
BuildStorage, traits::{BlakeTwo256, OnFinalise}, testing::{Digest, DigestItem, Header}
|
||||
BuildStorage, traits::{BlakeTwo256, OnFinalise, IdentityLookup}, testing::{Digest, DigestItem, Header}
|
||||
};
|
||||
|
||||
impl_outer_origin! {
|
||||
@@ -289,14 +290,15 @@ mod tests {
|
||||
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 AccountIndex = u64;
|
||||
type OnFreeBalanceZero = ();
|
||||
type OnNewAccount = ();
|
||||
type EnsureAccountLiquid = ();
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ srml-system = { path = "../system", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
substrate-primitives = { path = "../../core/primitives" }
|
||||
srml-indices = { path = "../indices" }
|
||||
srml-balances = { path = "../balances" }
|
||||
|
||||
[features]
|
||||
|
||||
@@ -275,7 +275,7 @@ mod tests {
|
||||
use runtime_io::with_externalities;
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use primitives::BuildStorage;
|
||||
use primitives::traits::{Header as HeaderT, BlakeTwo256};
|
||||
use primitives::traits::{Header as HeaderT, BlakeTwo256, IdentityLookup};
|
||||
use primitives::testing::{Digest, DigestItem, Header, Block};
|
||||
use system;
|
||||
|
||||
@@ -301,20 +301,21 @@ mod tests {
|
||||
type Hashing = BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = MetaEvent;
|
||||
type Log = DigestItem;
|
||||
}
|
||||
impl balances::Trait for Runtime {
|
||||
type Balance = u64;
|
||||
type AccountIndex = u64;
|
||||
type OnFreeBalanceZero = ();
|
||||
type OnNewAccount = ();
|
||||
type EnsureAccountLiquid = ();
|
||||
type Event = MetaEvent;
|
||||
}
|
||||
|
||||
type TestXt = primitives::testing::TestXt<Call<Runtime>>;
|
||||
type Executive = super::Executive<Runtime, Block<TestXt>, balances::ChainContext<Runtime>, balances::Module<Runtime>, ()>;
|
||||
type Executive = super::Executive<Runtime, Block<TestXt>, system::ChainContext<Runtime>, balances::Module<Runtime>, ()>;
|
||||
|
||||
#[test]
|
||||
fn balance_transfer_dispatch_works() {
|
||||
@@ -326,9 +327,8 @@ mod tests {
|
||||
existential_deposit: 0,
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
}.build_storage().unwrap().0);
|
||||
let xt = primitives::testing::TestXt(Some(1), 0, Call::transfer(2.into(), 69.into()));
|
||||
let xt = primitives::testing::TestXt(Some(1), 0, Call::transfer(2, 69.into()));
|
||||
let mut t = runtime_io::TestExternalities::<Blake2Hasher>::new(t);
|
||||
with_externalities(&mut t, || {
|
||||
Executive::initialise_block(&Header::new(1, H256::default(), H256::default(),
|
||||
@@ -352,7 +352,7 @@ mod tests {
|
||||
header: Header {
|
||||
parent_hash: [69u8; 32].into(),
|
||||
number: 1,
|
||||
state_root: hex!("d9e26179ed13b3df01e71ad0bf622d56f2066a63e04762a83c0ae9deeb4da1d0").into(),
|
||||
state_root: hex!("49cd58a254ccf6abc4a023d9a22dcfc421e385527a250faec69f8ad0d8ed3e48").into(),
|
||||
extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(),
|
||||
digest: Digest { logs: vec![], },
|
||||
},
|
||||
@@ -386,7 +386,7 @@ mod tests {
|
||||
header: Header {
|
||||
parent_hash: [69u8; 32].into(),
|
||||
number: 1,
|
||||
state_root: hex!("d9e26179ed13b3df01e71ad0bf622d56f2066a63e04762a83c0ae9deeb4da1d0").into(),
|
||||
state_root: hex!("49cd58a254ccf6abc4a023d9a22dcfc421e385527a250faec69f8ad0d8ed3e48").into(),
|
||||
extrinsics_root: [0u8; 32].into(),
|
||||
digest: Digest { logs: vec![], },
|
||||
},
|
||||
@@ -398,7 +398,7 @@ mod tests {
|
||||
#[test]
|
||||
fn bad_extrinsic_not_inserted() {
|
||||
let mut t = new_test_ext();
|
||||
let xt = primitives::testing::TestXt(Some(1), 42, Call::transfer(33.into(), 69.into()));
|
||||
let xt = primitives::testing::TestXt(Some(1), 42, Call::transfer(33, 69.into()));
|
||||
with_externalities(&mut t, || {
|
||||
Executive::initialise_block(&Header::new(1, H256::default(), H256::default(), [69u8; 32].into(), Digest::default()));
|
||||
assert!(Executive::apply_extrinsic(xt).is_err());
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use primitives::{BuildStorage, testing::{Digest, DigestItem, Header}};
|
||||
use primitives::{BuildStorage, traits::IdentityLookup, testing::{Digest, DigestItem, Header}};
|
||||
use primitives::generic::DigestItem as GenDigestItem;
|
||||
use runtime_io;
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
@@ -51,6 +51,7 @@ impl system::Trait for Test {
|
||||
type Hashing = ::primitives::traits::BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = TestEvent;
|
||||
type Log = DigestItem;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
[package]
|
||||
name = "srml-indices"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
hex-literal = "0.1.0"
|
||||
serde = { version = "1.0", default-features = false }
|
||||
safe-mix = { version = "1.0", default-features = false}
|
||||
parity-codec = { version = "2.1", default-features = false }
|
||||
parity-codec-derive = { version = "2.1", default-features = false }
|
||||
substrate-keyring = { path = "../../core/keyring", optional = true }
|
||||
substrate-primitives = { path = "../../core/primitives", 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 }
|
||||
srml-support = { path = "../support", default-features = false }
|
||||
srml-system = { path = "../system", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
ref_thread_local = "0.0"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"serde/std",
|
||||
"safe-mix/std",
|
||||
"substrate-keyring",
|
||||
"parity-codec/std",
|
||||
"parity-codec-derive/std",
|
||||
"substrate-primitives/std",
|
||||
"sr-std/std",
|
||||
"sr-io/std",
|
||||
"srml-support/std",
|
||||
"sr-primitives/std",
|
||||
"srml-system/std",
|
||||
]
|
||||
@@ -0,0 +1,222 @@
|
||||
// Copyright 2017-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/>.
|
||||
|
||||
//! Balances: Handles setting and retrieval of free balance,
|
||||
//! retrieving total balance, reserve and unreserve balance,
|
||||
//! repatriating a reserved balance to a beneficiary account that exists,
|
||||
//! transfering a balance between accounts (when not reserved),
|
||||
//! slashing an account balance, account removal, rewards,
|
||||
//! lookup of an index to reclaim an account (when not balance not reserved),
|
||||
//! increasing total stake.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate srml_support as runtime_support;
|
||||
|
||||
extern crate sr_std as rstd;
|
||||
|
||||
#[macro_use]
|
||||
extern crate parity_codec_derive;
|
||||
|
||||
extern crate parity_codec as codec;
|
||||
extern crate sr_primitives as primitives;
|
||||
extern crate srml_system as system;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate ref_thread_local;
|
||||
#[cfg(test)]
|
||||
extern crate sr_io as runtime_io;
|
||||
#[cfg(test)]
|
||||
extern crate substrate_primitives;
|
||||
|
||||
use rstd::{prelude::*, result, marker::PhantomData};
|
||||
use codec::{Encode, Decode, Codec, Input, Output};
|
||||
use runtime_support::{StorageValue, StorageMap, Parameter};
|
||||
use primitives::traits::{One, SimpleArithmetic, As, StaticLookup, Member};
|
||||
use address::Address as RawAddress;
|
||||
use system::{IsDeadAccount, OnNewAccount};
|
||||
|
||||
mod mock;
|
||||
|
||||
pub mod address;
|
||||
mod tests;
|
||||
|
||||
/// Number of account IDs stored per enum set.
|
||||
const ENUM_SET_SIZE: usize = 64;
|
||||
|
||||
pub type Address<T> = RawAddress<<T as system::Trait>::AccountId, <T as Trait>::AccountIndex>;
|
||||
|
||||
/// Turn an Id into an Index, or None for the purpose of getting
|
||||
/// a hint at a possibly desired index.
|
||||
pub trait ResolveHint<AccountId: Encode, AccountIndex: As<usize>> {
|
||||
/// Turn an Id into an Index, or None for the purpose of getting
|
||||
/// a hint at a possibly desired index.
|
||||
fn resolve_hint(who: &AccountId) -> Option<AccountIndex>;
|
||||
}
|
||||
|
||||
/// Simple encode-based resolve hint implemenntation.
|
||||
pub struct SimpleResolveHint<AccountId, AccountIndex>(PhantomData<(AccountId, AccountIndex)>);
|
||||
impl<AccountId: Encode, AccountIndex: As<usize>> ResolveHint<AccountId, AccountIndex> for SimpleResolveHint<AccountId, AccountIndex> {
|
||||
fn resolve_hint(who: &AccountId) -> Option<AccountIndex> {
|
||||
Some(AccountIndex::sa(who.using_encoded(|e| e[0] as usize + e[1] as usize * 256)))
|
||||
}
|
||||
}
|
||||
|
||||
/// The module's config trait.
|
||||
pub trait Trait: system::Trait {
|
||||
/// Type used for storing an account's index; implies the maximum number of accounts the system
|
||||
/// can hold.
|
||||
type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + As<u8> + As<u16> + As<u32> + As<u64> + As<usize> + Copy;
|
||||
|
||||
/// Whether an account is dead or not.
|
||||
type IsDeadAccount: IsDeadAccount<Self::AccountId>;
|
||||
|
||||
/// How to turn an id into an index.
|
||||
type ResolveHint: ResolveHint<Self::AccountId, Self::AccountIndex>;
|
||||
|
||||
/// The overarching event type.
|
||||
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
|
||||
fn deposit_event<T>() = default;
|
||||
}
|
||||
}
|
||||
|
||||
decl_event!(
|
||||
pub enum Event<T> where
|
||||
<T as system::Trait>::AccountId,
|
||||
<T as Trait>::AccountIndex
|
||||
{
|
||||
/// A new account was created.
|
||||
NewAccountIndex(AccountId, AccountIndex),
|
||||
}
|
||||
);
|
||||
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as Indices {
|
||||
/// The next free enumeration set.
|
||||
pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig<T>| {
|
||||
T::AccountIndex::sa(config.ids.len() / ENUM_SET_SIZE)
|
||||
}): T::AccountIndex;
|
||||
|
||||
/// The enumeration sets.
|
||||
pub EnumSet get(enum_set): map T::AccountIndex => Vec<T::AccountId>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(ids): Vec<T::AccountId>;
|
||||
build(|storage: &mut primitives::StorageMap, _: &mut primitives::ChildrenStorageMap, config: &GenesisConfig<T>| {
|
||||
for i in 0..(config.ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE {
|
||||
storage.insert(GenesisConfig::<T>::hash(&<EnumSet<T>>::key_for(T::AccountIndex::sa(i))).to_vec(),
|
||||
config.ids[i * ENUM_SET_SIZE..config.ids.len().min((i + 1) * ENUM_SET_SIZE)].to_owned().encode());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
// PUBLIC IMMUTABLES
|
||||
|
||||
/// Lookup an T::AccountIndex to get an Id, if there's one there.
|
||||
pub fn lookup_index(index: T::AccountIndex) -> Option<T::AccountId> {
|
||||
let enum_set_size = Self::enum_set_size();
|
||||
let set = Self::enum_set(index / enum_set_size);
|
||||
let i: usize = (index % enum_set_size).as_();
|
||||
set.get(i).map(|x| x.clone())
|
||||
}
|
||||
|
||||
/// `true` if the account `index` is ready for reclaim.
|
||||
pub fn can_reclaim(try_index: T::AccountIndex) -> bool {
|
||||
let enum_set_size = Self::enum_set_size();
|
||||
let try_set = Self::enum_set(try_index / enum_set_size);
|
||||
let i = (try_index % enum_set_size).as_();
|
||||
i < try_set.len() && T::IsDeadAccount::is_dead_account(&try_set[i])
|
||||
}
|
||||
|
||||
/// Lookup an address to get an Id, if there's one there.
|
||||
pub fn lookup_address(a: address::Address<T::AccountId, T::AccountIndex>) -> Option<T::AccountId> {
|
||||
match a {
|
||||
address::Address::Id(i) => Some(i),
|
||||
address::Address::Index(i) => Self::lookup_index(i),
|
||||
}
|
||||
}
|
||||
|
||||
// PUBLIC MUTABLES (DANGEROUS)
|
||||
|
||||
fn enum_set_size() -> T::AccountIndex {
|
||||
T::AccountIndex::sa(ENUM_SET_SIZE)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> OnNewAccount<T::AccountId> for Module<T> {
|
||||
fn on_new_account(who: &T::AccountId) {
|
||||
let enum_set_size = Self::enum_set_size();
|
||||
let next_set_index = Self::next_enum_set();
|
||||
|
||||
if let Some(try_index) = T::ResolveHint::resolve_hint(who) {
|
||||
// then check to see if this account id identifies a dead account index.
|
||||
let set_index = try_index / enum_set_size;
|
||||
let mut try_set = Self::enum_set(set_index);
|
||||
let item_index = (try_index % enum_set_size).as_();
|
||||
if item_index < try_set.len() {
|
||||
if T::IsDeadAccount::is_dead_account(&try_set[item_index]) {
|
||||
// yup - this index refers to a dead account. can be reused.
|
||||
try_set[item_index] = who.clone();
|
||||
<EnumSet<T>>::insert(set_index, try_set);
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// insert normally as a back up
|
||||
let mut set_index = next_set_index;
|
||||
// defensive only: this loop should never iterate since we keep NextEnumSet up to date later.
|
||||
let mut set = loop {
|
||||
let set = Self::enum_set(set_index);
|
||||
if set.len() < ENUM_SET_SIZE {
|
||||
break set;
|
||||
}
|
||||
set_index += One::one();
|
||||
};
|
||||
|
||||
let index = T::AccountIndex::sa(set_index.as_() * ENUM_SET_SIZE + set.len());
|
||||
|
||||
// update set.
|
||||
set.push(who.clone());
|
||||
|
||||
// keep NextEnumSet up to date
|
||||
if set.len() == ENUM_SET_SIZE {
|
||||
<NextEnumSet<T>>::put(set_index + One::one());
|
||||
}
|
||||
|
||||
// write set.
|
||||
<EnumSet<T>>::insert(set_index, set);
|
||||
|
||||
Self::deposit_event(RawEvent::NewAccountIndex(who.clone(), index));
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> StaticLookup for Module<T> {
|
||||
type Source = address::Address<T::AccountId, T::AccountIndex>;
|
||||
type Target = T::AccountId;
|
||||
fn lookup(a: Self::Source) -> result::Result<Self::Target, &'static str> {
|
||||
Self::lookup_address(a).ok_or("invalid account index")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// 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/>.
|
||||
|
||||
//! Test utilities
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use std::collections::HashSet;
|
||||
use ref_thread_local::RefThreadLocal;
|
||||
use primitives::BuildStorage;
|
||||
use primitives::testing::{Digest, DigestItem, Header};
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use runtime_io;
|
||||
use {GenesisConfig, Module, Trait, system};
|
||||
use super::{IsDeadAccount, OnNewAccount, ResolveHint};
|
||||
|
||||
impl_outer_origin!{
|
||||
pub enum Origin for Runtime {}
|
||||
}
|
||||
|
||||
ref_thread_local! {
|
||||
static managed ALIVE: HashSet<u64> = HashSet::new();
|
||||
}
|
||||
|
||||
pub fn make_account(who: u64) {
|
||||
ALIVE.borrow_mut().insert(who);
|
||||
Indices::on_new_account(&who);
|
||||
}
|
||||
|
||||
pub fn kill_account(who: u64) {
|
||||
ALIVE.borrow_mut().remove(&who);
|
||||
}
|
||||
|
||||
pub struct TestIsDeadAccount {}
|
||||
impl IsDeadAccount<u64> for TestIsDeadAccount {
|
||||
fn is_dead_account(who: &u64) -> bool {
|
||||
!ALIVE.borrow_mut().contains(who)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TestResolveHint;
|
||||
impl ResolveHint<u64, u64> for TestResolveHint {
|
||||
fn resolve_hint(who: &u64) -> Option<u64> {
|
||||
if *who < 256 {
|
||||
None
|
||||
} else {
|
||||
Some(*who - 256)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Runtime;
|
||||
impl system::Trait for Runtime {
|
||||
type Origin = Origin;
|
||||
type Index = u64;
|
||||
type BlockNumber = u64;
|
||||
type Hash = H256;
|
||||
type Hashing = ::primitives::traits::BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = Indices;
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
type Log = DigestItem;
|
||||
}
|
||||
impl Trait for Runtime {
|
||||
type AccountIndex = u64;
|
||||
type IsDeadAccount = TestIsDeadAccount;
|
||||
type ResolveHint = TestResolveHint;
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
pub fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
{
|
||||
let mut h = ALIVE.borrow_mut();
|
||||
h.clear();
|
||||
for i in 1..5 { h.insert(i); }
|
||||
}
|
||||
|
||||
let mut t = system::GenesisConfig::<Runtime>::default().build_storage().unwrap().0;
|
||||
t.extend(GenesisConfig::<Runtime> {
|
||||
ids: vec![1, 2, 3, 4]
|
||||
}.build_storage().unwrap().0);
|
||||
t.into()
|
||||
}
|
||||
|
||||
pub type Indices = Module<Runtime>;
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright 2017-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/>.
|
||||
|
||||
//! Tests for the module.
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use super::*;
|
||||
use mock::{Indices, new_test_ext, make_account, kill_account, TestIsDeadAccount};
|
||||
use runtime_io::with_externalities;
|
||||
|
||||
#[test]
|
||||
fn indexing_lookup_should_work() {
|
||||
with_externalities(
|
||||
&mut new_test_ext(),
|
||||
|| {
|
||||
assert_eq!(Indices::lookup_index(0), Some(1));
|
||||
assert_eq!(Indices::lookup_index(1), Some(2));
|
||||
assert_eq!(Indices::lookup_index(2), Some(3));
|
||||
assert_eq!(Indices::lookup_index(3), Some(4));
|
||||
assert_eq!(Indices::lookup_index(4), None);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_indexing_on_new_accounts_should_work() {
|
||||
with_externalities(
|
||||
&mut new_test_ext(),
|
||||
|| {
|
||||
assert_eq!(Indices::lookup_index(4), None);
|
||||
make_account(5);
|
||||
assert_eq!(Indices::lookup_index(4), Some(5));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reclaim_indexing_on_new_accounts_should_work() {
|
||||
with_externalities(
|
||||
&mut new_test_ext(),
|
||||
|| {
|
||||
assert_eq!(Indices::lookup_index(1), Some(2));
|
||||
assert_eq!(Indices::lookup_index(4), None);
|
||||
|
||||
kill_account(2); // index 1 no longer locked to id 2
|
||||
|
||||
make_account(1 + 256); // id 257 takes index 1.
|
||||
assert_eq!(Indices::lookup_index(1), Some(257));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alive_account_should_prevent_reclaim() {
|
||||
with_externalities(
|
||||
&mut new_test_ext(),
|
||||
|| {
|
||||
assert!(!TestIsDeadAccount::is_dead_account(&2));
|
||||
assert_eq!(Indices::lookup_index(1), Some(2));
|
||||
assert_eq!(Indices::lookup_index(4), None);
|
||||
|
||||
make_account(1 + 256); // id 257 takes index 1.
|
||||
assert_eq!(Indices::lookup_index(4), Some(257));
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -237,7 +237,7 @@ mod tests {
|
||||
use runtime_io::with_externalities;
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use primitives::BuildStorage;
|
||||
use primitives::traits::BlakeTwo256;
|
||||
use primitives::traits::{BlakeTwo256, IdentityLookup};
|
||||
use primitives::testing::{Digest, DigestItem, Header, UintAuthorityId, ConvertUintAuthorityId};
|
||||
|
||||
impl_outer_origin!{
|
||||
@@ -260,6 +260,7 @@ mod tests {
|
||||
type Hashing = BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
type Log = DigestItem;
|
||||
|
||||
@@ -45,14 +45,12 @@ extern crate sr_io as runtime_io;
|
||||
#[cfg(test)]
|
||||
extern crate srml_timestamp as timestamp;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use rstd::cmp;
|
||||
use rstd::{prelude::*, cmp};
|
||||
use codec::{HasCompact, Compact};
|
||||
use runtime_support::{Parameter, StorageValue, StorageMap};
|
||||
use runtime_support::dispatch::Result;
|
||||
use runtime_support::{Parameter, StorageValue, StorageMap, dispatch::Result};
|
||||
use session::OnSessionChange;
|
||||
use primitives::{Perbill, traits::{Zero, One, Bounded, As}};
|
||||
use balances::{address::Address, OnDilution};
|
||||
use primitives::{Perbill, traits::{Zero, One, Bounded, As, StaticLookup}};
|
||||
use balances::OnDilution;
|
||||
use system::ensure_signed;
|
||||
|
||||
mod mock;
|
||||
@@ -130,9 +128,9 @@ decl_module! {
|
||||
Self::apply_unstake(&who, intentions_index as usize)
|
||||
}
|
||||
|
||||
fn nominate(origin, target: Address<T::AccountId, T::AccountIndex>) {
|
||||
fn nominate(origin, target: <T::Lookup as StaticLookup>::Source) {
|
||||
let who = ensure_signed(origin)?;
|
||||
let target = <balances::Module<T>>::lookup(target)?;
|
||||
let target = T::Lookup::lookup(target)?;
|
||||
|
||||
ensure!(Self::nominating(&who).is_none(), "Cannot nominate if already nominating.");
|
||||
ensure!(Self::intentions().iter().find(|&t| t == &who).is_none(), "Cannot nominate if already staked.");
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use primitives::BuildStorage;
|
||||
use primitives::Perbill;
|
||||
use primitives::{traits::IdentityLookup, BuildStorage, Perbill};
|
||||
use primitives::testing::{Digest, DigestItem, Header, UintAuthorityId, ConvertUintAuthorityId};
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use runtime_io;
|
||||
@@ -46,14 +45,15 @@ impl system::Trait for Test {
|
||||
type Hashing = ::primitives::traits::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 AccountIndex = u64;
|
||||
type OnFreeBalanceZero = Staking;
|
||||
type OnNewAccount = ();
|
||||
type EnsureAccountLiquid = Staking;
|
||||
type Event = ();
|
||||
}
|
||||
@@ -109,7 +109,6 @@ pub fn new_test_ext(
|
||||
existential_deposit: ext_deposit,
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
sessions_per_era,
|
||||
|
||||
@@ -38,7 +38,7 @@ fn note_null_offline_should_work() {
|
||||
#[test]
|
||||
fn invulnerability_should_work() {
|
||||
with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || {
|
||||
Staking::set_invulnerables(vec![10]);
|
||||
assert_ok!(Staking::set_invulnerables(vec![10]));
|
||||
Balances::set_free_balance(&10, 70);
|
||||
assert_eq!(Staking::offline_slash_grace(), 0);
|
||||
assert_eq!(Staking::slash_count(&10), 0);
|
||||
@@ -284,7 +284,7 @@ fn staking_should_work() {
|
||||
|
||||
// Block 5: Transfer stake from highest to lowest. No change yet.
|
||||
System::set_block_number(5);
|
||||
assert_ok!(Balances::transfer(Origin::signed(4), 1.into(), 40.into()));
|
||||
assert_ok!(Balances::transfer(Origin::signed(4), 1, 40.into()));
|
||||
Session::check_rotate_session(System::block_number());
|
||||
|
||||
// Block 6: Lowest now validator.
|
||||
@@ -317,7 +317,7 @@ fn nominating_and_rewards_should_work() {
|
||||
assert_ok!(Staking::stake(Origin::signed(1)));
|
||||
assert_ok!(Staking::stake(Origin::signed(2)));
|
||||
assert_ok!(Staking::stake(Origin::signed(3)));
|
||||
assert_ok!(Staking::nominate(Origin::signed(4), 1.into()));
|
||||
assert_ok!(Staking::nominate(Origin::signed(4), 1));
|
||||
Session::check_rotate_session(System::block_number());
|
||||
assert_eq!(Staking::current_era(), 1);
|
||||
assert_eq!(Session::validators(), vec![1, 3]); // 4 + 1, 3
|
||||
@@ -339,7 +339,7 @@ fn nominating_and_rewards_should_work() {
|
||||
System::set_block_number(3);
|
||||
assert_ok!(Staking::stake(Origin::signed(4)));
|
||||
assert_ok!(Staking::unstake(Origin::signed(3), (Staking::intentions().iter().position(|&x| x == 3).unwrap() as u32).into()));
|
||||
assert_ok!(Staking::nominate(Origin::signed(3), 1.into()));
|
||||
assert_ok!(Staking::nominate(Origin::signed(3), 1));
|
||||
Session::check_rotate_session(System::block_number());
|
||||
assert_eq!(Session::validators(), vec![1, 4]);
|
||||
assert_eq!(Balances::total_balance(&1), 16);
|
||||
@@ -361,7 +361,7 @@ fn rewards_with_off_the_table_should_work() {
|
||||
with_externalities(&mut new_test_ext(0, 1, 1, 0, true, 10), || {
|
||||
System::set_block_number(1);
|
||||
assert_ok!(Staking::stake(Origin::signed(1)));
|
||||
assert_ok!(Staking::nominate(Origin::signed(2), 1.into()));
|
||||
assert_ok!(Staking::nominate(Origin::signed(2), 1));
|
||||
assert_ok!(Staking::stake(Origin::signed(3)));
|
||||
Session::check_rotate_session(System::block_number());
|
||||
assert_eq!(Session::validators(), vec![1, 3]); // 1 + 2, 3
|
||||
@@ -397,8 +397,8 @@ fn nominating_slashes_should_work() {
|
||||
System::set_block_number(4);
|
||||
assert_ok!(Staking::stake(Origin::signed(1)));
|
||||
assert_ok!(Staking::stake(Origin::signed(3)));
|
||||
assert_ok!(Staking::nominate(Origin::signed(2), 3.into()));
|
||||
assert_ok!(Staking::nominate(Origin::signed(4), 1.into()));
|
||||
assert_ok!(Staking::nominate(Origin::signed(2), 3));
|
||||
assert_ok!(Staking::nominate(Origin::signed(4), 1));
|
||||
Session::check_rotate_session(System::block_number());
|
||||
|
||||
assert_eq!(Staking::current_era(), 1);
|
||||
@@ -426,10 +426,10 @@ fn double_staking_should_fail() {
|
||||
System::set_block_number(1);
|
||||
assert_ok!(Staking::stake(Origin::signed(1)));
|
||||
assert_noop!(Staking::stake(Origin::signed(1)), "Cannot stake if already staked.");
|
||||
assert_noop!(Staking::nominate(Origin::signed(1), 1.into()), "Cannot nominate if already staked.");
|
||||
assert_ok!(Staking::nominate(Origin::signed(2), 1.into()));
|
||||
assert_noop!(Staking::nominate(Origin::signed(1), 1), "Cannot nominate if already staked.");
|
||||
assert_ok!(Staking::nominate(Origin::signed(2), 1));
|
||||
assert_noop!(Staking::stake(Origin::signed(2)), "Cannot stake if already nominating.");
|
||||
assert_noop!(Staking::nominate(Origin::signed(2), 1.into()), "Cannot nominate if already nominating.");
|
||||
assert_noop!(Staking::nominate(Origin::signed(2), 1), "Cannot nominate if already nominating.");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -506,7 +506,7 @@ fn staking_balance_transfer_when_bonded_should_not_work() {
|
||||
with_externalities(&mut new_test_ext(0, 1, 3, 1, false, 0), || {
|
||||
Balances::set_free_balance(&1, 111);
|
||||
assert_ok!(Staking::stake(Origin::signed(1)));
|
||||
assert_noop!(Balances::transfer(Origin::signed(1), 2.into(), 69.into()), "cannot transfer illiquid funds");
|
||||
assert_noop!(Balances::transfer(Origin::signed(1), 2, 69.into()), "cannot transfer illiquid funds");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ extern crate srml_system as system;
|
||||
extern crate srml_consensus as consensus;
|
||||
|
||||
use sr_std::prelude::*;
|
||||
use sr_primitives::traits::StaticLookup;
|
||||
use support::{StorageValue, Parameter, Dispatchable};
|
||||
use system::ensure_signed;
|
||||
|
||||
@@ -60,10 +61,11 @@ decl_module! {
|
||||
Self::deposit_event(RawEvent::Sudid(ok));
|
||||
}
|
||||
|
||||
fn set_key(origin, new: T::AccountId) {
|
||||
fn set_key(origin, new: <T::Lookup as StaticLookup>::Source) {
|
||||
// This is a public call, so we ensure that the origin is some signed account.
|
||||
let sender = ensure_signed(origin)?;
|
||||
ensure!(sender == Self::key(), "only the current sudo key can change the sudo key");
|
||||
let new = T::Lookup::lookup(new)?;
|
||||
|
||||
Self::deposit_event(RawEvent::KeyChanged(Self::key()));
|
||||
<Key<T>>::put(new);
|
||||
|
||||
@@ -38,7 +38,7 @@ extern crate safe_mix;
|
||||
use rstd::prelude::*;
|
||||
use primitives::traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, Zero, One, Bounded, Lookup,
|
||||
Hash, Member, MaybeDisplay, EnsureOrigin, Digest as DigestT, As, CurrentHeight, BlockNumberToHash,
|
||||
MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug};
|
||||
MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup};
|
||||
use substrate_primitives::storage::well_known_keys;
|
||||
use runtime_support::{storage, StorageValue, StorageMap, Parameter};
|
||||
use safe_mix::TripletMix;
|
||||
@@ -52,6 +52,28 @@ use runtime_io::{twox_128, TestExternalities, Blake2Hasher};
|
||||
#[cfg(any(feature = "std", test))]
|
||||
use substrate_primitives::ChangesTrieConfiguration;
|
||||
|
||||
/// Handler for when a new account has been created.
|
||||
pub trait OnNewAccount<AccountId> {
|
||||
/// A new account `who` has been registered.
|
||||
fn on_new_account(who: &AccountId);
|
||||
}
|
||||
|
||||
impl<AccountId> OnNewAccount<AccountId> for () {
|
||||
fn on_new_account(_who: &AccountId) {}
|
||||
}
|
||||
|
||||
/// Determinator to say whether a given account is unused.
|
||||
pub trait IsDeadAccount<AccountId> {
|
||||
/// Is the given account dead?
|
||||
fn is_dead_account(who: &AccountId) -> bool;
|
||||
}
|
||||
|
||||
impl<AccountId> IsDeadAccount<AccountId> for () {
|
||||
fn is_dead_account(_who: &AccountId) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute the extrinsics root of a list of extrinsics.
|
||||
pub fn extrinsics_root<H: Hash, E: codec::Encode>(extrinsics: &[E]) -> H::Output {
|
||||
extrinsics_data_root::<H>(extrinsics.iter().map(codec::Encode::encode).collect())
|
||||
@@ -71,6 +93,7 @@ pub trait Trait: 'static + Eq + Clone {
|
||||
type Hashing: Hash<Output = Self::Hash>;
|
||||
type Digest: Parameter + Member + MaybeSerializeDebugButNotDeserialize + Default + traits::Digest<Hash = Self::Hash>;
|
||||
type AccountId: Parameter + Member + MaybeSerializeDebug + MaybeDisplay + Ord + Default;
|
||||
type Lookup: StaticLookup<Target = Self::AccountId>;
|
||||
type Header: Parameter + traits::Header<
|
||||
Number = Self::BlockNumber,
|
||||
Hash = Self::Hash,
|
||||
@@ -400,10 +423,10 @@ impl<T> Default for ChainContext<T> {
|
||||
}
|
||||
|
||||
impl<T: Trait> Lookup for ChainContext<T> {
|
||||
type Source = T::AccountId;
|
||||
type Target = T::AccountId;
|
||||
type Source = <T::Lookup as StaticLookup>::Source;
|
||||
type Target = <T::Lookup as StaticLookup>::Target;
|
||||
fn lookup(&self, s: Self::Source) -> rstd::result::Result<Self::Target, &'static str> {
|
||||
Ok(s)
|
||||
<T::Lookup as StaticLookup>::lookup(s)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,7 +451,7 @@ mod tests {
|
||||
use runtime_io::with_externalities;
|
||||
use substrate_primitives::H256;
|
||||
use primitives::BuildStorage;
|
||||
use primitives::traits::BlakeTwo256;
|
||||
use primitives::traits::{BlakeTwo256, IdentityLookup};
|
||||
use primitives::testing::{Digest, DigestItem, Header};
|
||||
|
||||
impl_outer_origin!{
|
||||
@@ -445,6 +468,7 @@ mod tests {
|
||||
type Hashing = BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = u16;
|
||||
type Log = DigestItem;
|
||||
|
||||
@@ -195,7 +195,7 @@ mod tests {
|
||||
use runtime_io::{with_externalities, TestExternalities};
|
||||
use substrate_primitives::H256;
|
||||
use runtime_primitives::BuildStorage;
|
||||
use runtime_primitives::traits::BlakeTwo256;
|
||||
use runtime_primitives::traits::{BlakeTwo256, IdentityLookup};
|
||||
use runtime_primitives::testing::{Digest, DigestItem, Header, UintAuthorityId};
|
||||
|
||||
impl_outer_origin! {
|
||||
@@ -212,6 +212,7 @@ mod tests {
|
||||
type Hashing = BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<u64>;
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
type Log = DigestItem;
|
||||
|
||||
@@ -40,9 +40,9 @@ extern crate srml_balances as balances;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use runtime_support::{StorageValue, StorageMap};
|
||||
use runtime_primitives::{Permill, traits::{Zero, EnsureOrigin}};
|
||||
use runtime_primitives::{Permill, traits::{Zero, EnsureOrigin, StaticLookup}};
|
||||
use codec::{HasCompact, Compact};
|
||||
use balances::{OnDilution, address::Address};
|
||||
use balances::OnDilution;
|
||||
use system::ensure_signed;
|
||||
|
||||
/// Our module's configuration trait. All our types and consts go in here. If the
|
||||
@@ -75,10 +75,10 @@ decl_module! {
|
||||
fn propose_spend(
|
||||
origin,
|
||||
value: <T::Balance as HasCompact>::Type,
|
||||
beneficiary: Address<T::AccountId, T::AccountIndex>
|
||||
beneficiary: <T::Lookup as StaticLookup>::Source
|
||||
) {
|
||||
let proposer = ensure_signed(origin)?;
|
||||
let beneficiary = <balances::Module<T>>::lookup(beneficiary)?;
|
||||
let beneficiary = T::Lookup::lookup(beneficiary)?;
|
||||
let value = value.into();
|
||||
|
||||
let bond = Self::calculate_bond(value);
|
||||
@@ -273,7 +273,7 @@ mod tests {
|
||||
use runtime_io::with_externalities;
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use runtime_primitives::BuildStorage;
|
||||
use runtime_primitives::traits::{BlakeTwo256, OnFinalise};
|
||||
use runtime_primitives::traits::{BlakeTwo256, OnFinalise, IdentityLookup};
|
||||
use runtime_primitives::testing::{Digest, DigestItem, Header};
|
||||
|
||||
impl_outer_origin! {
|
||||
@@ -290,13 +290,14 @@ mod tests {
|
||||
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 AccountIndex = u64;
|
||||
type OnNewAccount = ();
|
||||
type OnFreeBalanceZero = ();
|
||||
type EnsureAccountLiquid = ();
|
||||
type Event = ();
|
||||
@@ -318,7 +319,6 @@ mod tests {
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
existential_deposit: 0,
|
||||
reclaim_rebate: 0,
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
proposal_bond: Permill::from_percent(5),
|
||||
@@ -353,7 +353,7 @@ mod tests {
|
||||
#[test]
|
||||
fn spend_proposal_takes_min_deposit() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 1.into(), Address::Id(3)));
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 1.into(), 3));
|
||||
assert_eq!(Balances::free_balance(&0), 99);
|
||||
assert_eq!(Balances::reserved_balance(&0), 1);
|
||||
});
|
||||
@@ -362,7 +362,7 @@ mod tests {
|
||||
#[test]
|
||||
fn spend_proposal_takes_proportional_deposit() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3)));
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), 3));
|
||||
assert_eq!(Balances::free_balance(&0), 95);
|
||||
assert_eq!(Balances::reserved_balance(&0), 5);
|
||||
});
|
||||
@@ -371,7 +371,7 @@ mod tests {
|
||||
#[test]
|
||||
fn spend_proposal_fails_when_proposer_poor() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
assert_noop!(Treasury::propose_spend(Origin::signed(2), 100.into(), Address::Id(3)), "Proposer's balance too low");
|
||||
assert_noop!(Treasury::propose_spend(Origin::signed(2), 100.into(), 3), "Proposer's balance too low");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -380,7 +380,7 @@ mod tests {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
Treasury::on_dilution(100, 100);
|
||||
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3)));
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), 3));
|
||||
assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0.into()));
|
||||
|
||||
<Treasury as OnFinalise<u64>>::on_finalise(1);
|
||||
@@ -404,7 +404,7 @@ mod tests {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
Treasury::on_dilution(100, 100);
|
||||
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3)));
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), 3));
|
||||
assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0.into()));
|
||||
|
||||
<Treasury as OnFinalise<u64>>::on_finalise(2);
|
||||
@@ -418,7 +418,7 @@ mod tests {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
Treasury::on_dilution(100, 100);
|
||||
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3)));
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), 3));
|
||||
assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0.into()));
|
||||
assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0.into()), "No proposal at that index");
|
||||
});
|
||||
@@ -443,7 +443,7 @@ mod tests {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
Treasury::on_dilution(100, 100);
|
||||
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3)));
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), 3));
|
||||
assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0.into()));
|
||||
assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0.into()), "No proposal at that index");
|
||||
});
|
||||
@@ -454,7 +454,7 @@ mod tests {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
Treasury::on_dilution(100, 100);
|
||||
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3)));
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), 3));
|
||||
assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0.into()));
|
||||
|
||||
<Treasury as OnFinalise<u64>>::on_finalise(2);
|
||||
@@ -468,7 +468,7 @@ mod tests {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
Treasury::on_dilution(100, 100);
|
||||
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 150.into(), Address::Id(3)));
|
||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 150.into(), 3));
|
||||
assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0.into()));
|
||||
|
||||
<Treasury as OnFinalise<u64>>::on_finalise(2);
|
||||
|
||||
@@ -35,6 +35,7 @@ extern crate srml_system as system;
|
||||
extern crate srml_consensus as consensus;
|
||||
|
||||
use sr_std::prelude::*;
|
||||
use sr_primitives::traits::StaticLookup;
|
||||
use support::StorageValue;
|
||||
use system::ensure_signed;
|
||||
|
||||
@@ -56,10 +57,11 @@ decl_module! {
|
||||
Self::deposit_event(RawEvent::Upgraded);
|
||||
}
|
||||
|
||||
fn set_key(origin, new: T::AccountId) {
|
||||
fn set_key(origin, new: <T::Lookup as StaticLookup>::Source) {
|
||||
// This is a public call, so we ensure that the origin is some signed account.
|
||||
let _sender = ensure_signed(origin)?;
|
||||
ensure!(_sender == Self::key(), "only the current upgrade key can use the upgrade_key module");
|
||||
let new = T::Lookup::lookup(new)?;
|
||||
|
||||
Self::deposit_event(RawEvent::KeyChanged(Self::key()));
|
||||
<Key<T>>::put(new);
|
||||
|
||||
Reference in New Issue
Block a user