difftreelog
Pallet Democracy
in: master
3 files changed
node/src/chain_spec.rsdiffbeforeafterboth1// use nft_runtime::{2// AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig,3// SystemConfig, WASM_BINARY,4// };5// use nft_runtime::{ContractsConfig, ContractsSchedule, NftConfig, CollectionType};6use nft_runtime::*;7use sc_service::ChainType;8use sp_consensus_aura::sr25519::AuthorityId as AuraId;9use sp_core::{sr25519, Pair, Public};10use sp_finality_grandpa::AuthorityId as GrandpaId;11use sp_runtime::traits::{IdentifyAccount, Verify};1213// Note this is the URL for the telemetry server14//const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";1516/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.17pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>;1819/// Helper function to generate a crypto pair from seed20pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {21 TPublic::Pair::from_string(&format!("//{}", seed), None)22 .expect("static values are valid; qed")23 .public()24}2526type AccountPublic = <Signature as Verify>::Signer;2728/// Helper function to generate an account ID from seed29pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId30where31 AccountPublic: From<<TPublic::Pair as Pair>::Public>,32{33 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()34}3536/// Helper function to generate an authority key for Aura37pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) {38 (get_from_seed::<AuraId>(s), get_from_seed::<GrandpaId>(s))39}4041pub fn development_config() -> Result<ChainSpec, String> {42 let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?;4344 Ok(ChainSpec::from_genesis(45 // Name46 "Development",47 // ID48 "dev",49 ChainType::Development,50 move || testnet_genesis(51 wasm_binary,52 // Initial PoA authorities53 vec![54 authority_keys_from_seed("Alice"),55 ],56 // Sudo account57 get_account_id_from_seed::<sr25519::Public>("Alice"),58 // Pre-funded accounts59 vec![60 get_account_id_from_seed::<sr25519::Public>("Alice"),61 get_account_id_from_seed::<sr25519::Public>("Bob"),62 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),63 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),64 ],65 true,66 ),67 // Bootnodes68 vec![],69 // Telemetry70 None,71 // Protocol ID72 None,73 // Properties74 None,75 // Extensions76 None,77 ))78}7980pub fn local_testnet_config() -> Result<ChainSpec, String> {81 let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?;8283 Ok(ChainSpec::from_genesis(84 // Name85 "Local Testnet",86 // ID87 "local_testnet",88 ChainType::Local,89 move || testnet_genesis(90 wasm_binary,91 // Initial PoA authorities92 vec![93 authority_keys_from_seed("Alice"),94 authority_keys_from_seed("Bob"),95 ],96 // Sudo account97 get_account_id_from_seed::<sr25519::Public>("Alice"),98 // Pre-funded accounts99 vec![100 get_account_id_from_seed::<sr25519::Public>("Alice"),101 get_account_id_from_seed::<sr25519::Public>("Bob"),102 get_account_id_from_seed::<sr25519::Public>("Charlie"),103 get_account_id_from_seed::<sr25519::Public>("Dave"),104 get_account_id_from_seed::<sr25519::Public>("Eve"),105 get_account_id_from_seed::<sr25519::Public>("Ferdie"),106 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),107 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),108 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),109 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),110 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),111 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),112 ],113 true,114 ),115 // Bootnodes116 vec![],117 // Telemetry118 None,119 // Protocol ID120 None,121 // Properties122 None,123 // Extensions124 None,125 ))126}127128fn testnet_genesis(129 wasm_binary: &[u8],130 initial_authorities: Vec<(AuraId, GrandpaId)>,131 root_key: AccountId,132 endowed_accounts: Vec<AccountId>,133 enable_println: bool,134) -> GenesisConfig {135 GenesisConfig {136 system: Some(SystemConfig {137 code: wasm_binary.to_vec(),138 changes_trie_config: Default::default(),139 }),140 pallet_balances: Some(BalancesConfig {141 balances: endowed_accounts142 .iter()143 .cloned()144 .map(|k| (k, 1 << 100))145 .collect(),146 }),147 pallet_aura: Some(AuraConfig {148 authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(),149 }),150 pallet_grandpa: Some(GrandpaConfig {151 authorities: initial_authorities152 .iter()153 .map(|x| (x.1.clone(), 1))154 .collect(),155 }),156 pallet_sudo: Some(SudoConfig { key: root_key }),157 pallet_nft: Some(NftConfig {158 collection: vec![(159 1,160 CollectionType {161 owner: get_account_id_from_seed::<sr25519::Public>("Alice"),162 mode: CollectionMode::NFT,163 access: AccessMode::Normal,164 decimal_points: 0,165 name: vec![],166 description: vec![],167 token_prefix: vec![],168 mint_mode: false,169 offchain_schema: vec![],170 sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),171 unconfirmed_sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),172 const_on_chain_schema: vec![],173 variable_on_chain_schema: vec![]174 },175 )],176 nft_item_id: vec![],177 fungible_item_id: vec![],178 refungible_item_id: vec![],179 chain_limit: ChainLimits {180 collection_numbers_limit: 10,181 account_token_ownership_limit: 10,182 collections_admins_limit: 5,183 custom_data_limit: 2048,184 nft_sponsor_transfer_timeout: 15,185 fungible_sponsor_transfer_timeout: 15,186 refungible_sponsor_transfer_timeout: 15,187 },188 }),189 pallet_contracts: Some(ContractsConfig {190 current_schedule: ContractsSchedule {191 enable_println,192 ..Default::default()193 },194 }),195 }196}runtime/Cargo.tomldiffbeforeafterboth--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -57,6 +57,13 @@
sp-transaction-pool = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'v2.0.0_release' }
sp-version = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'v2.0.0_release' }
+pallet-membership = { version = "2.0.0", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'v2.0.0_release' }
+pallet-collective = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'v2.0.0_release' }
+pallet-democracy = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'v2.0.0_release' }
+pallet-elections-phragmen = { version = "2.0.0", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'v2.0.0_release' }
+pallet-treasury = { version = "2.0.0", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'v2.0.0_release' }
+pallet-scheduler = { version = "2.0.0", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'v2.0.0_release' }
+
[features]
default = ['std']
runtime-benchmarks = [
@@ -100,4 +107,11 @@
'sp-std/std',
'sp-transaction-pool/std',
'sp-version/std',
+
+ 'pallet-collective/std',
+ 'pallet-democracy/std',
+ 'pallet-elections-phragmen/std',
+ 'pallet-membership/std',
+ 'pallet-treasury/std',
+ 'pallet-scheduler/std',
]
runtime/src/lib.rsdiffbeforeafterboth--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -13,12 +13,16 @@
use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
use sp_api::impl_runtime_apis;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
-use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
+use sp_core::{
+ crypto::KeyTypeId,
+ OpaqueMetadata,
+ u32_trait::{_1, _2, _3, _4},
+};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{
- BlakeTwo256, Block as BlockT, IdentifyAccount, IdentityLookup, NumberFor, Saturating,
- Verify,
+ Convert, BlakeTwo256, Block as BlockT, IdentifyAccount,
+ IdentityLookup, NumberFor, Saturating, Verify,
},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult, MultiSignature,
@@ -37,7 +41,7 @@
parameter_types,
traits::{
Currency, ExistenceRequirement, Get, KeyOwnerProofSystem, OnUnbalanced, Randomness,
- WithdrawReason,
+ WithdrawReason, LockIdentifier,
},
weights::{
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
@@ -48,11 +52,33 @@
};
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
-use sp_runtime::Perbill;
-use frame_system::{self as system};
+use sp_runtime:: { Perbill, Permill, Percent, ModuleId };
+use frame_system::{self as system, EnsureRoot, EnsureOneOf };
pub use pallet_timestamp::Call as TimestampCall;
+/// Struct that handles the conversion of Balance -> `u64`. This is used for
+/// staking's election calculation.
+pub struct CurrencyToVoteHandler;
+
+impl CurrencyToVoteHandler {
+ fn factor() -> Balance {
+ (Balances::total_issuance() / u64::max_value() as Balance).max(1)
+ }
+}
+
+impl Convert<Balance, u64> for CurrencyToVoteHandler {
+ fn convert(x: Balance) -> u64 {
+ (x / Self::factor()) as u64
+ }
+}
+
+impl Convert<u128, Balance> for CurrencyToVoteHandler {
+ fn convert(x: u128) -> Balance {
+ x * Self::factor()
+ }
+}
+
/// Re-export a nft pallet
/// TODO: Check this re-export. Is this safe and good style?
extern crate pallet_nft;
@@ -303,6 +329,213 @@
type FeeMultiplierUpdate = ();
}
+parameter_types! {
+ pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get();
+ pub const MaxScheduledPerBlock: u32 = 50;
+}
+
+impl pallet_scheduler::Trait for Runtime {
+ type Event = Event;
+ type Origin = Origin;
+ type PalletsOrigin = OriginCaller;
+ type Call = Call;
+ type MaximumWeight = MaximumSchedulerWeight;
+ type ScheduleOrigin = EnsureRoot<AccountId>;
+ type MaxScheduledPerBlock = MaxScheduledPerBlock;
+ type WeightInfo = ();
+}
+
+parameter_types! {
+ pub const ProposalBond: Permill = Permill::from_percent(5);
+ pub const ProposalBondMinimum: Balance = 1 * DOLLARS;
+ pub const SpendPeriod: BlockNumber = 1 * DAYS;
+ pub const Burn: Permill = Permill::from_percent(50);
+ pub const TipCountdown: BlockNumber = 1 * DAYS;
+ pub const TipFindersFee: Percent = Percent::from_percent(20);
+ pub const TipReportDepositBase: Balance = 1 * DOLLARS;
+ pub const DataDepositPerByte: Balance = 1 * CENTS;
+ pub const BountyDepositBase: Balance = 1 * DOLLARS;
+ pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;
+ pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
+ pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;
+ pub const MaximumReasonLength: u32 = 16384;
+ pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);
+ pub const BountyValueMinimum: Balance = 5 * DOLLARS;
+}
+
+impl pallet_treasury::Trait for Runtime {
+ type ModuleId = TreasuryModuleId;
+ type Currency = Balances;
+ type ApproveOrigin =
+ EnsureOneOf<
+ AccountId,
+ EnsureRoot<AccountId>,
+ pallet_collective::EnsureMembers<_4, AccountId, CouncilCollective>
+ >;
+ type RejectOrigin =
+ EnsureOneOf<
+ AccountId,
+ EnsureRoot<AccountId>,
+ pallet_collective::EnsureMembers<_2, AccountId, CouncilCollective>
+ >;
+ type Tippers = Elections;
+ type TipCountdown = TipCountdown;
+ type TipFindersFee = TipFindersFee;
+ type TipReportDepositBase = TipReportDepositBase;
+ type DataDepositPerByte = DataDepositPerByte;
+ type Event = Event;
+ type OnSlash = ();
+ type ProposalBond = ProposalBond;
+ type ProposalBondMinimum = ProposalBondMinimum;
+ type SpendPeriod = SpendPeriod;
+ type Burn = Burn;
+ type BountyDepositBase = BountyDepositBase;
+ type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
+ type BountyUpdatePeriod = BountyUpdatePeriod;
+ type BountyCuratorDeposit = BountyCuratorDeposit;
+ type BountyValueMinimum = BountyValueMinimum;
+ type MaximumReasonLength = MaximumReasonLength;
+ type BurnDestination = ();
+ type WeightInfo = ();
+}
+
+parameter_types! {
+ pub const TechnicalMotionDuration: BlockNumber = 5 * DAYS;
+ pub const TechnicalMaxProposals: u32 = 100;
+ pub const TechnicalMaxMembers: u32 = 100;
+}
+
+type TechnicalCollective = pallet_collective::Instance2;
+impl pallet_collective::Trait<TechnicalCollective> for Runtime {
+ type Origin = Origin;
+ type Proposal = Call;
+ type Event = Event;
+ type MotionDuration = TechnicalMotionDuration;
+ type MaxProposals = TechnicalMaxProposals;
+ type MaxMembers = TechnicalMaxMembers;
+ type DefaultVote = pallet_collective::PrimeDefaultVote;
+ type WeightInfo = ();
+}
+
+parameter_types! {
+ pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
+ pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
+ pub const FastTrackVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES;
+ pub const InstantAllowed: bool = true;
+ pub const MinimumDeposit: Balance = 100 * DOLLARS;
+ pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
+ pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
+ // One cent: $10,000 / MB
+ pub const PreimageByteDeposit: Balance = 1 * CENTS;
+ pub const MaxVotes: u32 = 100;
+}
+
+impl pallet_democracy::Trait for Runtime {
+ type Proposal = Call;
+ type Event = Event;
+ type Currency = Balances;
+ type EnactmentPeriod = EnactmentPeriod;
+ type LaunchPeriod = LaunchPeriod;
+ type VotingPeriod = VotingPeriod;
+ type MinimumDeposit = MinimumDeposit;
+ /// A straight majority of the council can decide what their next motion is.
+ type ExternalOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>;
+ /// A super-majority can have the next scheduled referendum be a straight majority-carries vote.
+ type ExternalMajorityOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
+ /// A unanimous council can have the next scheduled referendum be a straight default-carries
+ /// (NTB) vote.
+ type ExternalDefaultOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>;
+ /// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote
+ /// be tabled immediately and with a shorter voting/enactment period.
+ type FastTrackOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>;
+ type InstantOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>;
+ type InstantAllowed = InstantAllowed;
+ type FastTrackVotingPeriod = FastTrackVotingPeriod;
+ // To cancel a proposal which has been passed, 2/3 of the council must agree to it.
+ type CancellationOrigin = EnsureOneOf<
+ AccountId,
+ EnsureRoot<AccountId>,
+ pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>,
+ >;
+ // Any single technical committee member may veto a coming council proposal, however they can
+ // only do it once and it lasts only for the cooloff period.
+ type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
+ type CooloffPeriod = CooloffPeriod;
+ type PreimageByteDeposit = PreimageByteDeposit;
+ type OperationalPreimageOrigin = pallet_collective::EnsureMember<AccountId, CouncilCollective>;
+ type Slash = Treasury;
+ type Scheduler = Scheduler;
+ type PalletsOrigin = OriginCaller;
+ type MaxVotes = MaxVotes;
+ type WeightInfo = (); //weights::pallet_democracy::WeightInfo;
+}
+
+parameter_types! {
+ pub const CouncilMotionDuration: BlockNumber = 5 * DAYS;
+ pub const CouncilMaxProposals: u32 = 100;
+ pub const CouncilMaxMembers: u32 = 100;
+}
+
+type CouncilCollective = pallet_collective::Instance1;
+impl pallet_collective::Trait<CouncilCollective> for Runtime {
+ type Origin = Origin;
+ type Proposal = Call;
+ type Event = Event;
+ type MotionDuration = CouncilMotionDuration;
+ type MaxProposals = CouncilMaxProposals;
+ type MaxMembers = CouncilMaxMembers;
+ type DefaultVote = pallet_collective::PrimeDefaultVote;
+ type WeightInfo = (); //weights::pallet_collective::WeightInfo;
+}
+
+parameter_types! {
+ pub const CandidacyBond: Balance = 10 * DOLLARS;
+ pub const VotingBond: Balance = 1 * DOLLARS;
+ pub const TermDuration: BlockNumber = 7 * DAYS;
+ pub const DesiredMembers: u32 = 13;
+ pub const DesiredRunnersUp: u32 = 7;
+ pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
+}
+
+// Make sure that there are no more than `MaxMembers` members elected via elections-phragmen.
+// const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get());
+
+impl pallet_elections_phragmen::Trait for Runtime {
+ type Event = Event;
+ type ModuleId = ElectionsPhragmenModuleId;
+ type Currency = Balances;
+ type ChangeMembers = Council;
+ // NOTE: this implies that council's genesis members cannot be set directly and must come from
+ // this module.
+ type InitializeMembers = Council;
+ type CurrencyToVote = CurrencyToVoteHandler;
+ type CandidacyBond = CandidacyBond;
+ type VotingBond = VotingBond;
+ type LoserCandidate = ();
+ type BadReport = ();
+ type KickedMember = ();
+ type DesiredMembers = DesiredMembers;
+ type DesiredRunnersUp = DesiredRunnersUp;
+ type TermDuration = TermDuration;
+ type WeightInfo = (); //weights::pallet_elections_phragmen::WeightInfo;
+}
+
+type EnsureRootOrHalfCouncil = EnsureOneOf<
+ AccountId,
+ EnsureRoot<AccountId>,
+ pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
+>;
+impl pallet_membership::Trait for Runtime {
+ type Event = Event;
+ type AddOrigin = EnsureRootOrHalfCouncil;
+ type RemoveOrigin = EnsureRootOrHalfCouncil;
+ type SwapOrigin = EnsureRootOrHalfCouncil;
+ type ResetOrigin = EnsureRootOrHalfCouncil;
+ type PrimeOrigin = EnsureRootOrHalfCouncil;
+ type MembershipInitialized = TechnicalCommittee;
+ type MembershipChanged = TechnicalCommittee;
+}
+
impl pallet_sudo::Trait for Runtime {
type Event = Event;
type Call = Call;
@@ -330,6 +563,14 @@
TransactionPayment: pallet_transaction_payment::{Module, Storage},
Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},
Nft: pallet_nft::{Module, Call, Config<T>, Storage, Event<T>},
+
+ Democracy: pallet_democracy::{Module, Call, Storage, Config, Event<T>},
+ Council: pallet_collective::<Instance1>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
+ TechnicalCommittee: pallet_collective::<Instance2>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
+ Elections: pallet_elections_phragmen::{Module, Call, Storage, Event<T>, Config<T>},
+ TechnicalMembership: pallet_membership::{Module, Call, Storage, Event<T>, Config<T>},
+ Treasury: pallet_treasury::{Module, Call, Storage, Config, Event<T>},
+ Scheduler: pallet_scheduler::{Module, Call, Storage, Event<T>},
}
);