diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index ecea328f3c..d61a4f1235 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -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" diff --git a/substrate/Cargo.toml b/substrate/Cargo.toml index 2cff897a07..d67f32ed3c 100644 --- a/substrate/Cargo.toml +++ b/substrate/Cargo.toml @@ -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", diff --git a/substrate/core/executor/src/native_executor.rs b/substrate/core/executor/src/native_executor.rs index 09606bc904..b9a7187d4c 100644 --- a/substrate/core/executor/src/native_executor.rs +++ b/substrate/core/executor/src/native_executor.rs @@ -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 diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs index ac15df0881..05f4e8122b 100644 --- a/substrate/core/sr-primitives/src/traits.rs +++ b/substrate/core/sr-primitives/src/traits.rs @@ -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 { type Success; - fn ensure_origin(o: OuterOrigin) -> Result; + fn ensure_origin(o: OuterOrigin) -> result::Result; } /// 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; } +/// 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; +} + +#[derive(Default)] +pub struct IdentityLookup(PhantomData); +impl StaticLookup for IdentityLookup { + type Source = T; + type Target = T; + fn lookup(x: T) -> result::Result { Ok(x) } +} +impl Lookup for IdentityLookup { + type Source = T; + type Target = T; + fn lookup(&self, x: T) -> result::Result { Ok(x) } +} + /// Get the "current" block number. pub trait CurrentHeight { /// The type of the block number. diff --git a/substrate/core/test-runtime/wasm/Cargo.lock b/substrate/core/test-runtime/wasm/Cargo.lock index cb033b3aae..f5d3724241 100644 --- a/substrate/core/test-runtime/wasm/Cargo.lock +++ b/substrate/core/test-runtime/wasm/Cargo.lock @@ -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" diff --git a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index 5e5f1f72c9..6fc6c1fbd0 100644 Binary files a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ diff --git a/substrate/node/cli/src/chain_spec.rs b/substrate/node/cli/src/chain_spec.rs index ebf35a7491..78e6d92341 100644 --- a/substrate/node/cli/src/chain_spec.rs +++ b/substrate/node/cli/src/chain_spec.rs @@ -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 { diff --git a/substrate/node/executor/Cargo.toml b/substrate/node/executor/Cargo.toml index 35e1d87200..0f53831e73 100644 --- a/substrate/node/executor/Cargo.toml +++ b/substrate/node/executor/Cargo.toml @@ -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] diff --git a/substrate/node/executor/src/lib.rs b/substrate/node/executor/src/lib.rs index b8d459689b..15499ba31f 100644 --- a/substrate/node/executor/src/lib.rs +++ b/substrate/node/executor/src/lib.rs @@ -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(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); @@ -151,7 +152,7 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); @@ -172,7 +173,7 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); @@ -197,7 +198,7 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::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::(addr, 10.into(), 10_000.into(), vec![0x00, 0x01, 0x02, 0x03]) + contract::Call::call::(indices::address::Address::Id(addr), 10.into(), 10_000.into(), vec![0x00, 0x01, 0x02, 0x03]) ), }, ] @@ -741,7 +751,7 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); @@ -763,7 +773,7 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); diff --git a/substrate/node/runtime/Cargo.toml b/substrate/node/runtime/Cargo.toml index a400609f83..2385a8e0ec 100644 --- a/substrate/node/runtime/Cargo.toml +++ b/substrate/node/runtime/Cargo.toml @@ -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", diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index 3567edbbf6..ad6595cbd5 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -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; type AccountId = AccountId; + type Lookup = Indices; type Header = generic::Header; type Event = Event; type Log = Log; @@ -127,10 +130,17 @@ impl aura::Trait for Runtime { type HandleReport = aura::StakingSlasher; } +impl indices::Trait for Runtime { + type AccountIndex = AccountIndex; + type IsDeadAccount = Balances; + type ResolveHint = indices::SimpleResolveHint; + 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, Inherent}, Consensus: consensus::{Module, Call, Storage, Config, 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; +pub type Address = ::Source; /// Block header type as expected by this runtime. pub type Header = generic::Header; /// Block type as expected by this runtime. @@ -255,7 +263,7 @@ pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic; /// Executive: handles dispatch to the various modules. -pub type Executive = executive::Executive, Balances, AllModules>; +pub type Executive = executive::Executive, Balances, AllModules>; impl_runtime_apis! { impl client_api::Core for Runtime { diff --git a/substrate/node/runtime/wasm/Cargo.lock b/substrate/node/runtime/wasm/Cargo.lock index dcadee72d8..d7f72b4eda 100644 --- a/substrate/node/runtime/wasm/Cargo.lock +++ b/substrate/node/runtime/wasm/Cargo.lock @@ -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" diff --git a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm index 1caae1e872..3b424afdf5 100644 Binary files a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm and b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm differ diff --git a/substrate/srml/assets/src/lib.rs b/substrate/srml/assets/src/lib.rs index dd6446c958..4e234c846c 100644 --- a/substrate/srml/assets/src/lib.rs +++ b/substrate/srml/assets/src/lib.rs @@ -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: ::Type) { let origin = ensure_signed(origin)?; + let total = total.into(); let id = Self::next_asset_id(); >::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, + target: ::Source, + amount: ::Type + ) { let origin = ensure_signed(origin)?; + let id = id.into(); let origin_account = (id, origin.clone()); let origin_balance = >::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) { let origin = ensure_signed(origin)?; + let id = id.into(); let balance = >::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; 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"); }); } } diff --git a/substrate/srml/aura/src/mock.rs b/substrate/srml/aura/src/mock.rs index eb1fc9756b..6ff33e6c51 100644 --- a/substrate/srml/aura/src/mock.rs +++ b/substrate/srml/aura/src/mock.rs @@ -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; type Header = Header; type Event = (); type Log = DigestItem; diff --git a/substrate/srml/balances/src/lib.rs b/substrate/srml/balances/src/lib.rs index c6e5d7729a..7dda538a61 100644 --- a/substrate/srml/balances/src/lib.rs +++ b/substrate/srml/balances/src/lib.rs @@ -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 = RawAddress<::AccountId, ::AccountIndex>; - /// The account with the given id was killed. pub trait OnFreeBalanceZero { /// The account was the given id was killed. @@ -117,16 +106,17 @@ impl EnsureAccountLiquid for () { pub trait Trait: system::Trait { /// The balance of an account. - type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + As + As + As; - /// 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 + As + As + As + As + Copy; + type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + As + As; + /// 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; + /// Handler for when a new account is created. + type OnNewAccount: OnNewAccount; + /// A function that returns true iff a given account can transfer its funds to another account. type EnsureAccountLiquid: EnsureAccountLiquid; @@ -141,12 +131,12 @@ decl_module! { /// Transfer some liquid free balance to another staker. pub fn transfer( origin, - dest: RawAddress, + dest: ::Source, value: ::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, + who: ::Source, free: ::Type, reserved: ::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 where ::AccountId, - ::AccountIndex, ::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::AccountIndex::sa(config.balances.len() / ENUM_SET_SIZE) - }): T::AccountIndex; - /// The enumeration sets. - pub EnumSet get(enum_set): map T::AccountIndex => Vec; - /// 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| { - 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::::hash(&>::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 Module { } } - /// Lookup an T::AccountIndex to get an Id, if there's one there. - pub fn lookup_index(index: T::AccountIndex) -> Option { - 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) -> Option { - 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 Module { // 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 !>::exists(who) { - let outcome = Self::new_account(&who, balance); - let credit = match outcome { - NewAccountOutcome::GoodHint => balance + >::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 Module { } } - 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 % >::sa(quantized_account_count * reclaim_index_modulus); - let maybe_try_index = As::::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(); - >::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 { - >::put(set_index + One::one()); - } - - // write set. - >::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 Module { >::put(v); } } - - pub fn lookup(a: address::Address) -> result::Result { - match a { - address::Address::Id(i) => Ok(i), - address::Address::Index(i) => >::lookup_index(i).ok_or("invalid account index"), - } - } -} - -pub struct ChainContext(::rstd::marker::PhantomData); -impl Default for ChainContext { - fn default() -> Self { - ChainContext(::rstd::marker::PhantomData) - } -} - -impl Lookup for ChainContext { - type Source = address::Address; - type Target = T::AccountId; - fn lookup(&self, a: Self::Source) -> result::Result { - >::lookup(a) - } -} - -impl CurrentHeight for ChainContext { - type BlockNumber = T::BlockNumber; - fn current_height(&self) -> Self::BlockNumber { - >::block_number() - } -} - -impl BlockNumberToHash for ChainContext { - type BlockNumber = T::BlockNumber; - type Hash = T::Hash; - fn block_number_to_hash(&self, n: Self::BlockNumber) -> Option { - Some(>::block_hash(n)) - } } impl MakePayment for Module { @@ -718,3 +541,9 @@ impl MakePayment for Module { Ok(()) } } + +impl IsDeadAccount for Module { + fn is_dead_account(who: &T::AccountId) -> bool { + Self::total_balance(who).is_zero() + } +} diff --git a/substrate/srml/balances/src/mock.rs b/substrate/srml/balances/src/mock.rs index 8b9dbce3d4..1ff7a03073 100644 --- a/substrate/srml/balances/src/mock.rs +++ b/substrate/srml/balances/src/mock.rs @@ -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; 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() } diff --git a/substrate/srml/balances/src/tests.rs b/substrate/srml/balances/src/tests.rs index 9ad100fe61..1d0b64e447 100644 --- a/substrate/srml/balances/src/tests.rs +++ b/substrate/srml/balances/src/tests.rs @@ -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!(>::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!(>::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() { >::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" ); } diff --git a/substrate/srml/consensus/src/mock.rs b/substrate/srml/consensus/src/mock.rs index 78351309ac..9bf81cd327 100644 --- a/substrate/srml/consensus/src/mock.rs +++ b/substrate/srml/consensus/src/mock.rs @@ -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; type Header = Header; type Event = (); type Log = DigestItem; diff --git a/substrate/srml/contract/src/lib.rs b/substrate/srml/contract/src/lib.rs index 199f005881..4bef3b1d8c 100644 --- a/substrate/srml/contract/src/lib.rs +++ b/substrate/srml/contract/src/lib.rs @@ -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: ::Source, value: ::Type, gas_limit: ::Type, data: Vec @@ -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. // diff --git a/substrate/srml/contract/src/tests.rs b/substrate/srml/contract/src/tests.rs index b28bfcb82d..399004c6a4 100644 --- a/substrate/srml/contract/src/tests.rs +++ b/substrate/srml/contract/src/tests.rs @@ -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; 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. diff --git a/substrate/srml/council/src/lib.rs b/substrate/srml/council/src/lib.rs index 9d50445891..60320c0738 100644 --- a/substrate/srml/council/src/lib.rs +++ b/substrate/srml/council/src/lib.rs @@ -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; 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::{ launch_period: 1, diff --git a/substrate/srml/council/src/motions.rs b/substrate/srml/council/src/motions.rs index ad0f5032cf..8e6f94fbd5 100644 --- a/substrate/srml/council/src/motions.rs +++ b/substrate/srml/council/src/motions.rs @@ -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)) } ]); }); diff --git a/substrate/srml/council/src/seats.rs b/substrate/srml/council/src/seats.rs index 54579e356e..25c37b9b8e 100644 --- a/substrate/srml/council/src/seats.rs +++ b/substrate/srml/council/src/seats.rs @@ -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, - who: Address, + who: ::Source, who_index: Compact, assumed_vote_index: Compact ) { let reporter = ensure_signed(origin)?; let assumed_vote_index: VoteIndex = assumed_vote_index.into(); - let who = >::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, + candidate: ::Source, total: ::Type, index: Compact ) -> 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 = >::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) { - let who = >::lookup(who)?; + fn remove_member(who: ::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()); diff --git a/substrate/srml/council/src/voting.rs b/substrate/srml/council/src/voting.rs index ffc340e4f9..4a69e4f560 100644 --- a/substrate/srml/council/src/voting.rs +++ b/substrate/srml/council/src/voting.rs @@ -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 { diff --git a/substrate/srml/democracy/src/lib.rs b/substrate/srml/democracy/src/lib.rs index 599e15b0c0..2c0a1bd888 100644 --- a/substrate/srml/democracy/src/lib.rs +++ b/substrate/srml/democracy/src/lib.rs @@ -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; - >::mutate(when, |items| if items.len() > which { items[which] = None }); + pub fn cancel_queued(when: ::Type, which: Compact) -> Result { + let which = u32::from(which) as usize; + >::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; 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::{ 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 { diff --git a/substrate/srml/example/src/lib.rs b/substrate/srml/example/src/lib.rs index 8b14aae6ee..13ea7f9cdb 100644 --- a/substrate/srml/example/src/lib.rs +++ b/substrate/srml/example/src/lib.rs @@ -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: ::Type) { // Put the new value into storage. - >::put(new_value); + >::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; 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 = (); } diff --git a/substrate/srml/executive/Cargo.toml b/substrate/srml/executive/Cargo.toml index ee956e9399..c51ab85c5c 100644 --- a/substrate/srml/executive/Cargo.toml +++ b/substrate/srml/executive/Cargo.toml @@ -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] diff --git a/substrate/srml/executive/src/lib.rs b/substrate/srml/executive/src/lib.rs index 005b8508db..35ea7c4a91 100644 --- a/substrate/srml/executive/src/lib.rs +++ b/substrate/srml/executive/src/lib.rs @@ -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; 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>; - type Executive = super::Executive, balances::ChainContext, balances::Module, ()>; + type Executive = super::Executive, system::ChainContext, balances::Module, ()>; #[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::::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()); diff --git a/substrate/srml/grandpa/src/mock.rs b/substrate/srml/grandpa/src/mock.rs index c263083892..380133ae80 100644 --- a/substrate/srml/grandpa/src/mock.rs +++ b/substrate/srml/grandpa/src/mock.rs @@ -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; type Header = Header; type Event = TestEvent; type Log = DigestItem; diff --git a/substrate/srml/indices/Cargo.toml b/substrate/srml/indices/Cargo.toml new file mode 100644 index 0000000000..6e51f6999f --- /dev/null +++ b/substrate/srml/indices/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "srml-indices" +version = "0.1.0" +authors = ["Parity Technologies "] + +[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", +] diff --git a/substrate/srml/balances/src/address.rs b/substrate/srml/indices/src/address.rs similarity index 100% rename from substrate/srml/balances/src/address.rs rename to substrate/srml/indices/src/address.rs diff --git a/substrate/srml/indices/src/lib.rs b/substrate/srml/indices/src/lib.rs new file mode 100644 index 0000000000..3aff9a555f --- /dev/null +++ b/substrate/srml/indices/src/lib.rs @@ -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 . + +//! 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 = RawAddress<::AccountId, ::AccountIndex>; + +/// Turn an Id into an Index, or None for the purpose of getting +/// a hint at a possibly desired index. +pub trait ResolveHint> { + /// 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; +} + +/// Simple encode-based resolve hint implemenntation. +pub struct SimpleResolveHint(PhantomData<(AccountId, AccountIndex)>); +impl> ResolveHint for SimpleResolveHint { + fn resolve_hint(who: &AccountId) -> Option { + 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 + As + As + As + As + Copy; + + /// Whether an account is dead or not. + type IsDeadAccount: IsDeadAccount; + + /// How to turn an id into an index. + type ResolveHint: ResolveHint; + + /// The overarching event type. + type Event: From> + Into<::Event>; +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn deposit_event() = default; + } +} + +decl_event!( + pub enum Event where + ::AccountId, + ::AccountIndex + { + /// A new account was created. + NewAccountIndex(AccountId, AccountIndex), + } +); + +decl_storage! { + trait Store for Module as Indices { + /// The next free enumeration set. + pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig| { + T::AccountIndex::sa(config.ids.len() / ENUM_SET_SIZE) + }): T::AccountIndex; + + /// The enumeration sets. + pub EnumSet get(enum_set): map T::AccountIndex => Vec; + } + add_extra_genesis { + config(ids): Vec; + build(|storage: &mut primitives::StorageMap, _: &mut primitives::ChildrenStorageMap, config: &GenesisConfig| { + for i in 0..(config.ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE { + storage.insert(GenesisConfig::::hash(&>::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 Module { + // PUBLIC IMMUTABLES + + /// Lookup an T::AccountIndex to get an Id, if there's one there. + pub fn lookup_index(index: T::AccountIndex) -> Option { + 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) -> Option { + 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 OnNewAccount for Module { + 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(); + >::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 { + >::put(set_index + One::one()); + } + + // write set. + >::insert(set_index, set); + + Self::deposit_event(RawEvent::NewAccountIndex(who.clone(), index)); + } +} + +impl StaticLookup for Module { + type Source = address::Address; + type Target = T::AccountId; + fn lookup(a: Self::Source) -> result::Result { + Self::lookup_address(a).ok_or("invalid account index") + } +} diff --git a/substrate/srml/indices/src/mock.rs b/substrate/srml/indices/src/mock.rs new file mode 100644 index 0000000000..8c8305fef8 --- /dev/null +++ b/substrate/srml/indices/src/mock.rs @@ -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 . + +//! 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 = 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 for TestIsDeadAccount { + fn is_dead_account(who: &u64) -> bool { + !ALIVE.borrow_mut().contains(who) + } +} + +pub struct TestResolveHint; +impl ResolveHint for TestResolveHint { + fn resolve_hint(who: &u64) -> Option { + 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 { + { + let mut h = ALIVE.borrow_mut(); + h.clear(); + for i in 1..5 { h.insert(i); } + } + + let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + t.extend(GenesisConfig:: { + ids: vec![1, 2, 3, 4] + }.build_storage().unwrap().0); + t.into() +} + +pub type Indices = Module; diff --git a/substrate/srml/indices/src/tests.rs b/substrate/srml/indices/src/tests.rs new file mode 100644 index 0000000000..f16a93470d --- /dev/null +++ b/substrate/srml/indices/src/tests.rs @@ -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 . + +//! 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)); + }, + ); +} diff --git a/substrate/srml/session/src/lib.rs b/substrate/srml/session/src/lib.rs index ea33395021..4e0c668f63 100644 --- a/substrate/srml/session/src/lib.rs +++ b/substrate/srml/session/src/lib.rs @@ -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; type Header = Header; type Event = (); type Log = DigestItem; diff --git a/substrate/srml/staking/src/lib.rs b/substrate/srml/staking/src/lib.rs index 70f71de152..031083b8c6 100644 --- a/substrate/srml/staking/src/lib.rs +++ b/substrate/srml/staking/src/lib.rs @@ -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) { + fn nominate(origin, target: ::Source) { let who = ensure_signed(origin)?; - let target = >::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."); diff --git a/substrate/srml/staking/src/mock.rs b/substrate/srml/staking/src/mock.rs index b6efce154d..752922da03 100644 --- a/substrate/srml/staking/src/mock.rs +++ b/substrate/srml/staking/src/mock.rs @@ -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; 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::{ sessions_per_era, diff --git a/substrate/srml/staking/src/tests.rs b/substrate/srml/staking/src/tests.rs index fc3209bae3..5601cff5f6 100644 --- a/substrate/srml/staking/src/tests.rs +++ b/substrate/srml/staking/src/tests.rs @@ -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"); }); } diff --git a/substrate/srml/sudo/src/lib.rs b/substrate/srml/sudo/src/lib.rs index ca4859a4d3..0ce66f3df6 100644 --- a/substrate/srml/sudo/src/lib.rs +++ b/substrate/srml/sudo/src/lib.rs @@ -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: ::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())); >::put(new); diff --git a/substrate/srml/system/src/lib.rs b/substrate/srml/system/src/lib.rs index 67b10e2639..93ccd85c67 100644 --- a/substrate/srml/system/src/lib.rs +++ b/substrate/srml/system/src/lib.rs @@ -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 { + /// A new account `who` has been registered. + fn on_new_account(who: &AccountId); +} + +impl OnNewAccount for () { + fn on_new_account(_who: &AccountId) {} +} + +/// Determinator to say whether a given account is unused. +pub trait IsDeadAccount { + /// Is the given account dead? + fn is_dead_account(who: &AccountId) -> bool; +} + +impl IsDeadAccount for () { + fn is_dead_account(_who: &AccountId) -> bool { + true + } +} + /// Compute the extrinsics root of a list of extrinsics. pub fn extrinsics_root(extrinsics: &[E]) -> H::Output { extrinsics_data_root::(extrinsics.iter().map(codec::Encode::encode).collect()) @@ -71,6 +93,7 @@ pub trait Trait: 'static + Eq + Clone { type Hashing: Hash; type Digest: Parameter + Member + MaybeSerializeDebugButNotDeserialize + Default + traits::Digest; type AccountId: Parameter + Member + MaybeSerializeDebug + MaybeDisplay + Ord + Default; + type Lookup: StaticLookup; type Header: Parameter + traits::Header< Number = Self::BlockNumber, Hash = Self::Hash, @@ -400,10 +423,10 @@ impl Default for ChainContext { } impl Lookup for ChainContext { - type Source = T::AccountId; - type Target = T::AccountId; + type Source = ::Source; + type Target = ::Target; fn lookup(&self, s: Self::Source) -> rstd::result::Result { - Ok(s) + ::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; type Header = Header; type Event = u16; type Log = DigestItem; diff --git a/substrate/srml/timestamp/src/lib.rs b/substrate/srml/timestamp/src/lib.rs index 27dcc81bab..71bf6ebded 100644 --- a/substrate/srml/timestamp/src/lib.rs +++ b/substrate/srml/timestamp/src/lib.rs @@ -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; type Header = Header; type Event = (); type Log = DigestItem; diff --git a/substrate/srml/treasury/src/lib.rs b/substrate/srml/treasury/src/lib.rs index c919c5e959..3cc1a3c491 100644 --- a/substrate/srml/treasury/src/lib.rs +++ b/substrate/srml/treasury/src/lib.rs @@ -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: ::Type, - beneficiary: Address + beneficiary: ::Source ) { let proposer = ensure_signed(origin)?; - let beneficiary = >::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; 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::{ 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())); >::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())); >::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())); >::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())); >::on_finalise(2); diff --git a/substrate/srml/upgrade-key/src/lib.rs b/substrate/srml/upgrade-key/src/lib.rs index 2b4470a9f3..1b10d3a3d3 100644 --- a/substrate/srml/upgrade-key/src/lib.rs +++ b/substrate/srml/upgrade-key/src/lib.rs @@ -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: ::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())); >::put(new);