diff --git a/Cargo.lock b/Cargo.lock index d19aaa5763..cf2ee625ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1589,6 +1589,33 @@ dependencies = [ "thousands", ] +[[package]] +name = "frame-election-provider-solution-type" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.20#563f4820d8f36d256ada7ea3fef46b2e94c4cd5a" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-election-provider-support" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.20#563f4820d8f36d256ada7ea3fef46b2e94c4cd5a" +dependencies = [ + "frame-election-provider-solution-type", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-npos-elections", + "sp-runtime", + "sp-std", +] + [[package]] name = "frame-executive" version = "4.0.0-dev" @@ -2018,6 +2045,7 @@ dependencies = [ "jsonrpc-core", "pallet-transaction-payment", "pallet-transaction-payment-rpc", + "rand 0.8.5", "sc-basic-authorship", "sc-cli", "sc-client-api", @@ -2056,6 +2084,7 @@ name = "gssmr-test-runtime" version = "4.0.0-dev" dependencies = [ "frame-benchmarking", + "frame-election-provider-support", "frame-executive", "frame-support", "frame-system", @@ -2065,9 +2094,13 @@ dependencies = [ "hex-literal", "pallet-authorship", "pallet-babe", + "pallet-bags-list", "pallet-balances", + "pallet-election-provider-multi-phase", "pallet-grandpa", - "pallet-randomness-collective-flip", + "pallet-session", + "pallet-staking", + "pallet-staking-reward-curve", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", @@ -2079,9 +2112,11 @@ dependencies = [ "sp-consensus-babe", "sp-core", "sp-inherents", + "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", + "sp-staking", "sp-std", "sp-transaction-pool", "sp-version", @@ -4063,6 +4098,21 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-bags-list" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.20#563f4820d8f36d256ada7ea3fef46b2e94c4cd5a" +dependencies = [ + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-balances" version = "4.0.0-dev" @@ -4078,6 +4128,29 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-election-provider-multi-phase" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.20#563f4820d8f36d256ada7ea3fef46b2e94c4cd5a" +dependencies = [ + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "rand 0.7.3", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-npos-elections", + "sp-runtime", + "sp-std", + "static_assertions", + "strum", +] + [[package]] name = "pallet-grandpa" version = "4.0.0-dev" @@ -4102,38 +4175,56 @@ dependencies = [ ] [[package]] -name = "pallet-randomness-collective-flip" +name = "pallet-session" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.20#563f4820d8f36d256ada7ea3fef46b2e94c4cd5a" dependencies = [ "frame-support", "frame-system", + "impl-trait-for-tuples", + "log", + "pallet-timestamp", "parity-scale-codec", - "safe-mix", "scale-info", + "sp-core", + "sp-io", "sp-runtime", + "sp-session", + "sp-staking", "sp-std", + "sp-trie", ] [[package]] -name = "pallet-session" +name = "pallet-staking" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.20#563f4820d8f36d256ada7ea3fef46b2e94c4cd5a" dependencies = [ + "frame-election-provider-support", "frame-support", "frame-system", - "impl-trait-for-tuples", "log", - "pallet-timestamp", + "pallet-authorship", + "pallet-session", "parity-scale-codec", "scale-info", - "sp-core", + "serde", + "sp-application-crypto", "sp-io", "sp-runtime", - "sp-session", "sp-staking", "sp-std", - "sp-trie", +] + +[[package]] +name = "pallet-staking-reward-curve" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.20#563f4820d8f36d256ada7ea3fef46b2e94c4cd5a" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -5135,15 +5226,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.3.3" @@ -5257,15 +5339,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" -[[package]] -name = "safe-mix" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d3d055a2582e6b00ed7a31c1524040aa391092bf636328350813f3a0605215c" -dependencies = [ - "rustc_version 0.2.3", -] - [[package]] name = "salsa20" version = "0.9.0" @@ -6265,15 +6338,6 @@ dependencies = [ "semver-parser 0.7.0", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser 0.7.0", -] - [[package]] name = "semver" version = "0.11.0" @@ -6907,6 +6971,20 @@ dependencies = [ "zstd", ] +[[package]] +name = "sp-npos-elections" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.20#563f4820d8f36d256ada7ea3fef46b2e94c4cd5a" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-arithmetic", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "sp-offchain" version = "4.0.0-dev" diff --git a/node/Cargo.toml b/node/Cargo.toml index cdb8ce7917..8625b5d840 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -17,6 +17,7 @@ name = "gssmr-test-node" [dependencies] clap = { version = "3.1.6", features = ["derive"] } +rand = "0.8" sc-cli = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20", features = ["wasmtime"] } sp-core = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index f30cb998a2..99d363a427 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -1,6 +1,6 @@ use gssmr_test_runtime::{ - AccountId, BabeConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig, - SystemConfig, WASM_BINARY, + AccountId, BabeConfig, Balance, BalancesConfig, DOLLARS, GenesisConfig, GrandpaConfig, MaxNominations, SessionConfig, + SessionKeys, Signature, StakingConfig, StakerStatus, SudoConfig, SystemConfig, WASM_BINARY, }; use sc_service::ChainType; use sp_consensus_babe::AuthorityId as BabeId; @@ -32,8 +32,8 @@ where } /// Generate an Aura authority key. -pub fn authority_keys_from_seed(s: &str) -> (BabeId, GrandpaId) { - (get_from_seed::(s), get_from_seed::(s)) +pub fn authority_keys_from_seed(s: &str) -> (AccountId, BabeId, GrandpaId) { + (get_account_id_from_seed::(s), get_from_seed::(s), get_from_seed::(s)) } pub fn development_config() -> Result { @@ -129,11 +129,30 @@ pub fn local_testnet_config() -> Result { /// Configure initial storage state for FRAME modules. fn testnet_genesis( wasm_binary: &[u8], - initial_authorities: Vec<(BabeId, GrandpaId)>, + initial_authorities: Vec<(AccountId, BabeId, GrandpaId)>, root_key: AccountId, endowed_accounts: Vec, _enable_println: bool, ) -> GenesisConfig { + let mut rng = rand::thread_rng(); + const ENDOWMENT: Balance = 10_000_000 * DOLLARS; + const STASH: Balance = ENDOWMENT / 1000; + let stakers = initial_authorities + .iter() + .map(|x| (x.0.clone(), x.0.clone(), STASH, StakerStatus::Validator)) + .chain(vec![].iter().map(|x: &AccountId| { + use rand::{seq::SliceRandom, Rng}; + let limit = (MaxNominations::get() as usize).min(initial_authorities.len()); + let count = rng.gen::() % limit; + let nominations = initial_authorities + .as_slice() + .choose_multiple(&mut rng, count) + .into_iter() + .map(|choice| choice.0.clone()) + .collect::>(); + (x.clone(), x.clone(), STASH, StakerStatus::Nominator(nominations)) + })) + .collect::>(); GenesisConfig { system: SystemConfig { // Add Wasm runtime to storage. @@ -144,11 +163,31 @@ fn testnet_genesis( balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), }, babe: BabeConfig { - authorities: initial_authorities.iter().map(|x| (x.0.clone(), 1)).collect(), + authorities: vec![], epoch_config: Some(gssmr_test_runtime::BABE_GENESIS_EPOCH_CONFIG), }, grandpa: GrandpaConfig { - authorities: initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect(), + authorities: vec![], + }, + session: SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + SessionKeys { babe: x.1.clone(), grandpa: x.2.clone() }, + ) + }) + .collect::>(), + }, + staking: StakingConfig { + validator_count: initial_authorities.len() as u32, + minimum_validator_count: initial_authorities.len() as u32, + invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + slash_reward_fraction: sp_runtime::Perbill::from_percent(10), + stakers, + ..Default::default() }, sudo: SudoConfig { // Assign network admin rights. diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 8993e37d72..673ae79104 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -20,6 +20,8 @@ pallet-babe = { version = "4.0.0-dev", default-features = false, git = "https:// pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } pallet-grandpa = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } +pallet-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } +pallet-staking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } frame-try-runtime = { version = "0.10.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20", optional = true } @@ -37,6 +39,13 @@ sp-session = { version = "4.0.0-dev", default-features = false, git = "https://g sp-std = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } sp-version = { version = "5.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } +sp-staking = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } +sp-npos-elections = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } +frame-election-provider-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } +pallet-bags-list = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } +pallet-election-provider-multi-phase = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } +pallet-staking-reward-curve = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } + # Used for the node template's RPCs frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.20" } @@ -55,14 +64,19 @@ default = ["std"] std = [ "codec/std", "scale-info/std", + "frame-election-provider-support/std", "frame-executive/std", "frame-support/std", "frame-system-rpc-runtime-api/std", "frame-system/std", "pallet-authorship/std", "pallet-babe/std", + "pallet-bags-list/std", "pallet-balances/std", + "pallet-election-provider-multi-phase/std", "pallet-grandpa/std", + "pallet-session/std", + "pallet-staking/std", "pallet-sudo/std", "pallet-timestamp/std", "pallet-transaction-payment-rpc-runtime-api/std", @@ -72,9 +86,11 @@ std = [ "sp-consensus-babe/std", "sp-core/std", "sp-inherents/std", + "sp-npos-elections/std", "sp-offchain/std", "sp-runtime/std", "sp-session/std", + "sp-staking/std", "sp-std/std", "sp-transaction-pool/std", "sp-version/std", diff --git a/runtime/src/bag_thresholds.rs b/runtime/src/bag_thresholds.rs new file mode 100644 index 0000000000..d88f469f6b --- /dev/null +++ b/runtime/src/bag_thresholds.rs @@ -0,0 +1,234 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated voter bag thresholds. +//! +//! Generated on 2021-07-05T14:35:50.538338181+00:00 +//! for the westend runtime. + +/// Existential weight for this runtime. +#[cfg(any(test, feature = "std"))] +#[allow(unused)] +pub const EXISTENTIAL_WEIGHT: u64 = 10_000_000_000; + +/// Constant ratio between bags for this runtime. +#[cfg(any(test, feature = "std"))] +#[allow(unused)] +pub const CONSTANT_RATIO: f64 = 1.1131723507077667; + +/// Upper thresholds delimiting the bag list. +pub const THRESHOLDS: [u64; 200] = [ + 10_000_000_000, + 11_131_723_507, + 12_391_526_824, + 13_793_905_044, + 15_354_993_703, + 17_092_754_435, + 19_027_181_634, + 21_180_532_507, + 23_577_583_160, + 26_245_913_670, + 29_216_225_417, + 32_522_694_326, + 36_203_364_094, + 40_300_583_912, + 44_861_495_728, + 49_938_576_656, + 55_590_242_767, + 61_881_521_217, + 68_884_798_439, + 76_680_653_006, + 85_358_782_760, + 95_019_036_859, + 105_772_564_622, + 117_743_094_401, + 131_068_357_174, + 145_901_671_259, + 162_413_706_368, + 180_794_447_305, + 201_255_379_901, + 224_031_924_337, + 249_386_143_848, + 277_609_759_981, + 309_027_509_097, + 344_000_878_735, + 382_932_266_827, + 426_269_611_626, + 474_511_545_609, + 528_213_132_664, + 587_992_254_562, + 654_536_720_209, + 728_612_179_460, + 811_070_932_564, + 902_861_736_593, + 1_005_040_721_687, + 1_118_783_542_717, + 1_245_398_906_179, + 1_386_343_627_960, + 1_543_239_395_225, + 1_717_891_425_287, + 1_912_309_236_147, + 2_128_729_767_682, + 2_369_643_119_512, + 2_637_821_201_686, + 2_936_349_627_828, + 3_268_663_217_709, + 3_638_585_517_729, + 4_050_372_794_022, + 4_508_763_004_364, + 5_019_030_312_352, + 5_587_045_771_074, + 6_219_344_874_498, + 6_923_202_753_807, + 7_706_717_883_882, + 8_578_905_263_043, + 9_549_800_138_161, + 10_630_573_468_586, + 11_833_660_457_397, + 13_172_903_628_838, + 14_663_712_098_160, + 16_323_238_866_411, + 18_170_578_180_087, + 20_226_985_226_447, + 22_516_120_692_255, + 25_064_322_999_817, + 27_900_911_352_605, + 31_058_523_077_268, + 34_573_489_143_434, + 38_486_252_181_966, + 42_841_831_811_331, + 47_690_342_626_046, + 53_087_570_807_094, + 59_095_615_988_698, + 65_783_605_766_662, + 73_228_491_069_308, + 81_515_931_542_404, + 90_741_281_135_191, + 101_010_685_227_495, + 112_442_301_921_293, + 125_167_661_548_718, + 139_333_180_038_781, + 155_101_843_555_358, + 172_655_083_789_626, + 192_194_865_483_744, + 213_946_010_204_502, + 238_158_783_103_893, + 265_111_772_429_462, + 295_115_094_915_607, + 328_513_963_936_552, + 365_692_661_475_578, + 407_078_959_611_349, + 453_149_042_394_237, + 504_432_984_742_966, + 561_520_851_400_862, + 625_069_486_125_324, + 695_810_069_225_823, + 774_556_530_406_243, + 862_214_913_708_369, + 959_793_802_308_039, + 1_068_415_923_109_985, + 1_189_331_064_661_951, + 1_323_930_457_019_515, + 1_473_762_779_014_021, + 1_640_551_977_100_649, + 1_826_217_100_807_404, + 2_032_894_383_008_501, + 2_262_961_819_074_188, + 2_519_066_527_700_738, + 2_804_155_208_229_882, + 3_121_508_044_894_685, + 3_474_776_448_088_622, + 3_868_025_066_902_796, + 4_305_778_556_320_752, + 4_793_073_637_166_665, + 5_335_517_047_800_242, + 5_939_350_054_341_159, + 6_611_520_261_667_250, + 7_359_761_551_432_161, + 8_192_683_066_856_378, + 9_119_868_268_136_230, + 10_151_985_198_186_376, + 11_300_909_227_415_580, + 12_579_859_689_817_292, + 14_003_551_982_487_792, + 15_588_366_878_604_342, + 17_352_539_001_951_086, + 19_316_366_631_550_092, + 21_502_445_250_375_680, + 23_935_927_525_325_748, + 26_644_812_709_737_600, + 29_660_268_798_266_784, + 33_016_991_140_790_860, + 36_753_601_641_491_664, + 40_913_093_136_236_104, + 45_543_324_061_189_736, + 50_697_569_104_240_168, + 56_435_132_174_936_472, + 62_822_028_745_677_552, + 69_931_745_415_056_768, + 77_846_085_432_775_824, + 86_656_109_914_600_688, + 96_463_185_576_826_656, + 107_380_151_045_315_664, + 119_532_615_158_469_088, + 133_060_402_202_199_856, + 148_119_160_705_543_712, + 164_882_154_307_451_552, + 183_542_255_300_186_560, + 204_314_163_786_713_728, + 227_436_877_985_347_776, + 253_176_444_104_585_088, + 281_829_017_427_734_464, + 313_724_269_827_691_328, + 349_229_182_918_168_832, + 388_752_270_484_770_624, + 432_748_278_778_513_664, + 481_723_418_752_617_984, + 536_241_190_443_833_600, + 596_928_866_512_693_376, + 664_484_709_541_257_600, + 739_686_006_129_409_280, + 823_398_010_228_713_984, + 916_583_898_614_395_264, + 1_020_315_853_041_475_584, + 1_135_787_396_594_579_584, + 1_264_327_126_171_442_688, + 1_407_413_999_103_859_968, + 1_566_694_349_801_462_272, + 1_744_000_832_209_069_824, + 1_941_373_506_026_471_680, + 2_161_083_309_305_266_176, + 2_405_658_187_494_662_656, + 2_677_912_179_572_818_944, + 2_980_977_795_924_034_048, + 3_318_342_060_496_414_208, + 3_693_886_631_935_247_360, + 4_111_932_465_319_354_368, + 4_577_289_528_371_127_808, + 5_095_312_144_166_932_480, + 5_671_960_597_112_134_656, + 6_313_869_711_009_142_784, + 7_028_425_188_266_614_784, + 7_823_848_588_596_424_704, + 8_709_291_924_949_524_480, + 9_694_942_965_096_232_960, + 10_792_142_450_433_898_496, + 12_013_514_580_722_579_456, + 13_373_112_266_084_982_784, + 14_886_578_817_516_689_408, + 16_571_327_936_291_497_984, + 18_446_744_073_709_551_615, +]; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 12ad808539..1aaae980e3 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -6,21 +6,29 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +use frame_system::EnsureRoot; +use frame_election_provider_support::{onchain, SequentialPhragmen}; use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, }; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, NumberFor, Verify}, - transaction_validity::{TransactionSource, TransactionValidity}, + create_runtime_str, curve::PiecewiseLinear, generic, impl_opaque_keys, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, NumberFor, OpaqueKeys, Verify}, + transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, ApplyExtrinsicResult, MultiSignature, }; use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; +use pallet_session::historical as session_historical; + +#[cfg(any(feature = "std", test))] +pub use pallet_staking::StakerStatus; + +mod bag_thresholds; // A few exports that help ease life for downstream crates. pub use frame_support::{ @@ -120,11 +128,7 @@ pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); // NOTE: Currently it is not possible to change the epoch duration after the chain has started. // Attempting to do so will brick block production. pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 3 * MINUTES; -pub const EPOCH_DURATION_IN_SLOTS: u64 = { - const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64; - - (EPOCH_DURATION_IN_BLOCKS as f64 * SLOT_FILL_RATE) as u64 -}; +pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = 3 * MINUTES; /// The BABE epoch configuration at genesis. pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration = @@ -138,6 +142,11 @@ pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; +pub const UNITS: Balance = 1_000_000_000_000; +pub const CENTS: Balance = UNITS / 100; +pub const MILLICENTS: Balance = CENTS / 1_000; +pub const DOLLARS: Balance = 100 * CENTS; + /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { @@ -146,6 +155,14 @@ pub fn native_version() -> NativeVersion { const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +impl frame_system::offchain::SendTransactionTypes for Runtime +where + Call: From, +{ + type OverarchingCall = Call; + type Extrinsic = UncheckedExtrinsic; +} + parameter_types! { pub const Version: RuntimeVersion = VERSION; pub const BlockHashCount: BlockNumber = 2400; @@ -214,12 +231,12 @@ impl frame_system::Config for Runtime { parameter_types! { // NOTE: Currently it is not possible to change the epoch duration after the chain has started. // Attempting to do so will brick block production. - pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; + pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64; pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK; - pub const BondingDuration: u64 = 24 * 28; - pub const SessionsPerEra: u64 = 6; + pub const BondingDuration: sp_staking::EraIndex = 2; + pub const SessionsPerEra: sp_staking::SessionIndex = 1; pub const ReportLongevity: u64 = - BondingDuration::get() * SessionsPerEra::get() * EpochDuration::get(); + BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); pub const MaxAuthorities: u32 = 100; } @@ -306,12 +323,197 @@ parameter_types! { } impl pallet_authorship::Config for Runtime { - type FindAuthor = (); + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; type UncleGenerations = UncleGenerations; type FilterUncle = (); type EventHandler = (); } +impl_opaque_keys! { + pub struct SessionKeys { + pub grandpa: Grandpa, + pub babe: Babe, + } +} + +impl pallet_session::Config for Runtime { + type Event = Event; + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type ShouldEndSession = Babe; + type NextSessionRotation = Babe; + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type WeightInfo = (); +} + +impl pallet_session::historical::Config for Runtime { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; +} + +const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 100 * CENTS + (bytes as Balance) * 5 * MILLICENTS +} + + +parameter_types! { + // phase durations. 1/4 of the last session for each. + pub const SignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4; + pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4; + + // signed config + pub const SignedMaxSubmissions: u32 = 128; + pub const SignedDepositBase: Balance = deposit(2, 0); + pub const SignedDepositByte: Balance = deposit(0, 10) / 1024; + // Each good submission will get 1 WND as reward + pub SignedRewardBase: Balance = 1 * UNITS; + pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(5u32, 10_000); + + // 1 hour session, 15 minutes unsigned phase, 4 offchain executions. + pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 4; + + /// We take the top 22500 nominators as electing voters.. + pub const MaxElectingVoters: u32 = 22_500; + /// ... and all of the validators as electable targets. Whilst this is the case, we cannot and + /// shall not increase the size of the validator intentions. + pub const MaxElectableTargets: u16 = u16::MAX; + pub const NposSolutionPriority: TransactionPriority = TransactionPriority::max_value() / 2; +} + +frame_election_provider_support::generate_solution_type!( + #[compact] + pub struct NposCompactSolution16::< + VoterIndex = u32, + TargetIndex = u16, + Accuracy = sp_runtime::PerU16, + MaxVoters = MaxElectingVoters, + >(16) +); + +pub struct OnChainSeqPhragmen; +impl onchain::Config for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen; + type DataProvider = Staking; + type WeightInfo = (); +} + +pub struct ElectionBenchmarkConfig; +impl pallet_election_provider_multi_phase::BenchmarkingConfig for ElectionBenchmarkConfig { + const VOTERS: [u32; 2] = [1000, 2000]; + const TARGETS: [u32; 2] = [500, 1000]; + const ACTIVE_VOTERS: [u32; 2] = [500, 800]; + const DESIRED_TARGETS: [u32; 2] = [200, 400]; + const SNAPSHOT_MAXIMUM_VOTERS: u32 = 1000; + const MINER_MAXIMUM_VOTERS: u32 = 1000; + const MAXIMUM_TARGETS: u32 = 300; +} + +impl pallet_election_provider_multi_phase::Config for Runtime { + type Event = Event; + type Currency = Balances; + type EstimateCallFee = TransactionPayment; + type SignedPhase = SignedPhase; + type UnsignedPhase = UnsignedPhase; + type SignedMaxSubmissions = SignedMaxSubmissions; + type SignedRewardBase = SignedRewardBase; + type SignedDepositBase = SignedDepositBase; + type SignedDepositByte = SignedDepositByte; + type SignedDepositWeight = (); + type SignedMaxWeight = Self::MinerMaxWeight; + type SlashHandler = (); // burn slashes + type RewardHandler = (); // nothing to do upon rewards + type SolutionImprovementThreshold = SolutionImprovementThreshold; + type MinerMaxWeight = (); // For now use the one from staking. + type MinerMaxLength = (); + type OffchainRepeat = OffchainRepeat; + type MinerTxPriority = NposSolutionPriority; + type DataProvider = Staking; + type Solution = NposCompactSolution16; + type Fallback = pallet_election_provider_multi_phase::NoFallback; + type GovernanceFallback = onchain::UnboundedExecution; + type Solver = SequentialPhragmen< + AccountId, + pallet_election_provider_multi_phase::SolutionAccuracyOf, + (), + >; + type BenchmarkingConfig = ElectionBenchmarkConfig; + type ForceOrigin = EnsureRoot; + type WeightInfo = (); + type MaxElectingVoters = MaxElectingVoters; + type MaxElectableTargets = MaxElectableTargets; +} + + +parameter_types! { + pub const BagThresholds: &'static [u64] = &bag_thresholds::THRESHOLDS; +} + +impl pallet_bags_list::Config for Runtime { + type Event = Event; + type ScoreProvider = Staking; + type WeightInfo = (); + type BagThresholds = BagThresholds; + type Score = sp_npos_elections::VoteWeight; +} + +pallet_staking_reward_curve::build! { + const REWARD_CURVE: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} + +parameter_types! { + // 27 eras in which slashes can be cancelled (slightly less than 7 days). + pub const SlashDeferDuration: sp_staking::EraIndex = 2; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub const MaxNominatorRewardedPerValidator: u32 = 64; + pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17); + pub const MaxNominations: u32 = 64; +} + +pub struct StakingBenchmarkingConfig; +impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig { + type MaxValidators = ConstU32<1000>; + type MaxNominators = ConstU32<1000>; +} + +impl pallet_staking::Config for Runtime { + type MaxNominations = MaxNominations; + type Currency = Balances; + type CurrencyBalance = Balance; + type UnixTime = Timestamp; + type CurrencyToVote = frame_support::traits::U128CurrencyToVote; + type RewardRemainder = (); + type Event = Event; + type Slash = (); + type Reward = (); + type SessionsPerEra = SessionsPerEra; + type BondingDuration = BondingDuration; + type SlashDeferDuration = SlashDeferDuration; + // A majority of the council can cancel the slash. + type SlashCancelOrigin = EnsureRoot; + type SessionInterface = Self; + type EraPayout = pallet_staking::ConvertCurve; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type OffendingValidatorsThreshold = OffendingValidatorsThreshold; + type NextNewSession = Session; + type ElectionProvider = ElectionProviderMultiPhase; + type GenesisElectionProvider = onchain::UnboundedExecution; + type VoterList = BagsList; + type MaxUnlockingChunks = frame_support::traits::ConstU32<32>; + type BenchmarkingConfig = StakingBenchmarkingConfig; + type OnStakerSlash = (); + type WeightInfo = (); +} + impl pallet_sudo::Config for Runtime { type Event = Event; type Call = Call; @@ -331,6 +533,11 @@ construct_runtime!( Grandpa: pallet_grandpa, Balances: pallet_balances, TransactionPayment: pallet_transaction_payment, + Historical: session_historical, + Session: pallet_session, + ElectionProviderMultiPhase: pallet_election_provider_multi_phase, + BagsList: pallet_bags_list, + Staking: pallet_staking, Sudo: pallet_sudo, } );