From 56f92b547ac9e8f06a77cb53e3f41f1133187349 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Tue, 27 Feb 2024 20:31:34 +0900 Subject: [PATCH 01/18] gov wip' --- runtime/bajun/src/gov.rs | 155 +++++++++++++++++++++++++++++++++++++++ runtime/bajun/src/lib.rs | 49 +++---------- 2 files changed, 166 insertions(+), 38 deletions(-) create mode 100644 runtime/bajun/src/gov.rs diff --git a/runtime/bajun/src/gov.rs b/runtime/bajun/src/gov.rs new file mode 100644 index 0000000..683cc50 --- /dev/null +++ b/runtime/bajun/src/gov.rs @@ -0,0 +1,155 @@ +use crate::{ + BlockWeights, OriginCaller, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, AJUNS, DAYS, +}; +use ajuna_primitives::{AccountId, Balance, BlockNumber}; +use frame_support::{ + dispatch::RawOrigin, + parameter_types, + traits::{ConstBool, ConstU32, EitherOfDiverse, EnsureOrigin}, + weights::Weight, +}; +use frame_system::EnsureRoot; +use pallet_collective::{EnsureMember, EnsureProportionAtLeast, EnsureProportionMoreThan}; +use sp_runtime::Perbill; +use sp_std::marker::PhantomData; + +pub type EnsureRootOrMoreThanHalfCouncil = EitherOfDiverse< + EnsureRoot, + EnsureProportionMoreThan, +>; + +pub type EnsureRootOrMoreThanHalfTechnicalCommittee = EitherOfDiverse< + EnsureRoot, + EnsureProportionAtLeast, +>; + +pub type EnsureRootOrAllTechnicalCommittee = EitherOfDiverse< + EnsureRoot, + EnsureProportionAtLeast, +>; + +type AccountIdFor = ::AccountId; + +/// Ensures that the signer of a transaction is a member of said collective instance. +/// +/// This is fundamentally different from the `pallet_collective::EnsureMember`, +/// which checks if the referendum to be executed has been ayed by any member. +/// It is a different kind of origin. +pub struct EnsureSignerIsCollectiveMember(PhantomData<(T, I)>); +impl< + O: Into>, O>> + From>>, + T: pallet_collective::Config, + I, + > EnsureOrigin for EnsureSignerIsCollectiveMember +{ + type Success = AccountIdFor; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + RawOrigin::Signed(a) if pallet_collective::Pallet::::is_member(&a) => Ok(a), + r => Err(O::from(r)), + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + use parity_scale_codec::Decode; + use sp_runtime::traits::TrailingZeroInput; + let zero_account_id = + >::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?; + Ok(O::from(RawOrigin::Signed(zero_account_id))) + } +} + +/// Council collective instance declaration. +/// +/// The council primarily serves to optimize and balance the inclusive referendum system, +/// by being allowed to propose external democracy proposals, which can be fast tracked and +/// bypass the one active referendum at a time rule. +/// +/// It also controls the treasury. +type CouncilCollective = pallet_collective::Instance2; + +parameter_types! { + pub CouncilMotionDuration: BlockNumber = 3 * DAYS; + pub MaxProposalWeight: Weight = Perbill::from_percent(50) * BlockWeights::get().max_block; +} + +impl pallet_collective::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type Proposal = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type MotionDuration = CouncilMotionDuration; + type MaxProposals = ConstU32<100>; + type MaxMembers = ConstU32<100>; + type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; + type WeightInfo = pallet_collective::weights::SubstrateWeight; + type SetMembersOrigin = EnsureRootOrMoreThanHalfCouncil; + type MaxProposalWeight = MaxProposalWeight; +} + +/// The technical committee primarily serves to safeguard against malicious referenda, +/// and fast track critical referenda. +pub type TechnicalCommitteeInstance = pallet_collective::Instance1; + +parameter_types! { + pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS; +} + +impl pallet_collective::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type Proposal = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type MotionDuration = TechnicalMotionDuration; + type MaxProposals = ConstU32<100>; + type MaxMembers = ConstU32<100>; + type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; + type WeightInfo = pallet_collective::weights::SubstrateWeight; + type SetMembersOrigin = EnsureRootOrMoreThanHalfCouncil; + type MaxProposalWeight = MaxProposalWeight; +} + +parameter_types! { + pub const ThreeDays: BlockNumber = 3 * DAYS; + pub const TwentyEightDays: BlockNumber = 28 * DAYS; + pub const ThirtyDays: BlockNumber = 30 * DAYS; + pub EnactmentPeriod: BlockNumber = 7 * DAYS; + pub const MinimumDeposit: Balance = AJUNS; +} + +impl pallet_democracy::Config for Runtime { + type WeightInfo = pallet_democracy::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; + type Scheduler = pallet_scheduler::Pallet; + type Preimages = pallet_preimage::Pallet; + type Currency = pallet_balances::Pallet; + type EnactmentPeriod = EnactmentPeriod; + type LaunchPeriod = TwentyEightDays; + type VotingPeriod = TwentyEightDays; + type VoteLockingPeriod = EnactmentPeriod; + type MinimumDeposit = MinimumDeposit; + type InstantAllowed = ConstBool; + type FastTrackVotingPeriod = ThreeDays; + type CooloffPeriod = TwentyEightDays; + type MaxVotes = ConstU32<100>; + type MaxProposals = ConstU32<100>; + type MaxDeposits = ConstU32<100>; + type MaxBlacklisted = ConstU32<100>; + type ExternalOrigin = EnsureRootOrMoreThanHalfCouncil; + type ExternalMajorityOrigin = EnsureRootOrMoreThanHalfCouncil; + type ExternalDefaultOrigin = EnsureRootOrMoreThanHalfCouncil; + // Initially, we want that only the council can submit proposals to + // prevent malicious proposals. + type SubmitOrigin = EnsureSignerIsCollectiveMember; + type FastTrackOrigin = EnsureRootOrMoreThanHalfTechnicalCommittee; + type InstantOrigin = EnsureRootOrMoreThanHalfTechnicalCommittee; + // To cancel a proposal that has passed. + type CancellationOrigin = EnsureRoot; + type BlacklistOrigin = EnsureRootOrMoreThanHalfCouncil; + // To cancel a proposal before it has passed, and slash its backers. + type CancelProposalOrigin = EnsureRootOrAllTechnicalCommittee; + // 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 = EnsureMember; + type PalletsOrigin = OriginCaller; + type Slash = pallet_treasury::Pallet; +} diff --git a/runtime/bajun/src/lib.rs b/runtime/bajun/src/lib.rs index f867083..0b6cff9 100644 --- a/runtime/bajun/src/lib.rs +++ b/runtime/bajun/src/lib.rs @@ -22,10 +22,12 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +mod gov; mod proxy_type; mod weights; pub mod xcm_config; +use crate::gov::EnsureRootOrMoreThanHalfCouncil; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use smallvec::smallvec; @@ -87,6 +89,12 @@ use parachains_common::{BlockNumber, Hash, Header}; use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; use sp_runtime::traits::{Convert, IdentifyAccount, IdentityLookup, Verify}; +parameter_types! { + pub const OneDay: BlockNumber = DAYS; + pub const OneWeek: BlockNumber = 7 * DAYS; + pub const TwoWeeks: BlockNumber = 14 * DAYS; +} + /// The address format for describing accounts. pub type Address = MultiAddress; @@ -461,42 +469,6 @@ parameter_types! { pub MaxProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block; } -type CouncilCollective = pallet_collective::Instance2; -impl pallet_collective::Config for Runtime { - type RuntimeOrigin = RuntimeOrigin; - type Proposal = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type MotionDuration = Weekly; - type MaxProposals = frame_support::traits::ConstU32<100>; - type MaxMembers = CouncilMaxMembers; - type DefaultVote = pallet_collective::PrimeDefaultVote; - type WeightInfo = weights::pallet_collective::WeightInfo; - type SetMembersOrigin = EnsureRoot; - type MaxProposalWeight = MaxProposalWeight; -} - -type EnsureRootOrMoreThanHalfCouncil = EitherOfDiverse< - EnsureRoot, - EnsureProportionMoreThan, ->; -type EnsureRootOrAtLeastTwoThirdsCouncil = EitherOfDiverse< - EnsureRoot, - EnsureProportionAtLeast, ->; - -impl pallet_membership::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type AddOrigin = EnsureRootOrMoreThanHalfCouncil; - type RemoveOrigin = EnsureRootOrMoreThanHalfCouncil; - type SwapOrigin = EnsureRootOrMoreThanHalfCouncil; - type ResetOrigin = EnsureRootOrAtLeastTwoThirdsCouncil; - type PrimeOrigin = EnsureRootOrAtLeastTwoThirdsCouncil; - type MembershipInitialized = Council; - type MembershipChanged = Council; - type MaxMembers = CouncilMaxMembers; - type WeightInfo = weights::pallet_membership::WeightInfo; -} - parameter_types! { pub TreasuryAccount: AccountId = Treasury::account_id(); pub const SpendPayoutPeriod: u32 = 5; @@ -511,7 +483,7 @@ impl pallet_treasury::Config for Runtime { type ProposalBond = FivePercent; type ProposalBondMinimum = MinimumProposalBond; type ProposalBondMaximum = (); - type SpendPeriod = Weekly; + type SpendPeriod = OneWeek; type Burn = ZeroPercent; type PalletId = TreasuryPalletId; type BurnDestination = (); @@ -920,8 +892,9 @@ construct_runtime!( // Governance Sudo: pallet_sudo = 40, Treasury: pallet_treasury = 41, + // type CouncilCollective = pallet_collective::Instance2 Council: pallet_collective:: = 42, - CouncilMembership: pallet_membership:: = 43, + // CouncilMembership: pallet_membership:: = 43, // Indexes 50-59 should be reserved for our games. Randomness: pallet_insecure_randomness_collective_flip = 50, From 46eaddfd871f33156b8e0c793bafd3420aae63c2 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Tue, 27 Feb 2024 21:15:04 +0900 Subject: [PATCH 02/18] [runtime] fix compilation with governance stuff --- Cargo.lock | 1 + runtime/bajun/Cargo.toml | 3 +++ runtime/bajun/src/gov.rs | 12 ++++++------ runtime/bajun/src/lib.rs | 9 ++++++--- runtime/bajun/src/proxy_type.rs | 1 - 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab8f223..6f70afd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -893,6 +893,7 @@ dependencies = [ "pallet-balances", "pallet-collator-selection", "pallet-collective", + "pallet-democracy", "pallet-identity", "pallet-insecure-randomness-collective-flip", "pallet-membership", diff --git a/runtime/bajun/Cargo.toml b/runtime/bajun/Cargo.toml index 1c53c36..f405af6 100644 --- a/runtime/bajun/Cargo.toml +++ b/runtime/bajun/Cargo.toml @@ -33,6 +33,7 @@ pallet-aura = { workspace = true } pallet-authorship = { workspace = true } pallet-balances = { workspace = true } pallet-collective = { workspace = true } +pallet-democracy = { workspace = true } pallet-identity = { workspace = true } pallet-insecure-randomness-collective-flip = { workspace = true } pallet-membership = { workspace = true } @@ -121,6 +122,7 @@ std = [ "pallet-balances/std", "pallet-collective/std", "pallet-collator-selection/std", + "pallet-democracy/std", "pallet-identity/std", "pallet-membership/std", "pallet-message-queue/std", @@ -170,6 +172,7 @@ runtime-benchmarks = [ "pallet-balances/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", "pallet-collective/runtime-benchmarks", + "pallet-democracy/runtime-benchmarks", "pallet-identity/runtime-benchmarks", "pallet-membership/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", diff --git a/runtime/bajun/src/gov.rs b/runtime/bajun/src/gov.rs index 683cc50..beef8a8 100644 --- a/runtime/bajun/src/gov.rs +++ b/runtime/bajun/src/gov.rs @@ -1,7 +1,8 @@ +use crate::{AccountId, Balance, BlockNumber}; use crate::{ - BlockWeights, OriginCaller, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, AJUNS, DAYS, + OriginCaller, Runtime, RuntimeBlockWeights, RuntimeCall, RuntimeEvent, RuntimeOrigin, BAJUN, + DAYS, }; -use ajuna_primitives::{AccountId, Balance, BlockNumber}; use frame_support::{ dispatch::RawOrigin, parameter_types, @@ -70,9 +71,8 @@ impl< type CouncilCollective = pallet_collective::Instance2; parameter_types! { - pub CouncilMotionDuration: BlockNumber = 3 * DAYS; - pub MaxProposalWeight: Weight = Perbill::from_percent(50) * BlockWeights::get().max_block; -} +pub CouncilMotionDuration: BlockNumber = 3 * DAYS; +pub MaxProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block;} impl pallet_collective::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; @@ -113,7 +113,7 @@ parameter_types! { pub const TwentyEightDays: BlockNumber = 28 * DAYS; pub const ThirtyDays: BlockNumber = 30 * DAYS; pub EnactmentPeriod: BlockNumber = 7 * DAYS; - pub const MinimumDeposit: Balance = AJUNS; + pub const MinimumDeposit: Balance = BAJUN; } impl pallet_democracy::Config for Runtime { diff --git a/runtime/bajun/src/lib.rs b/runtime/bajun/src/lib.rs index 0b6cff9..20e54d8 100644 --- a/runtime/bajun/src/lib.rs +++ b/runtime/bajun/src/lib.rs @@ -53,7 +53,7 @@ use frame_support::{ dispatch::DispatchClass, genesis_builder_helper::{build_config, create_default_config}, parameter_types, - traits::{AsEnsureOriginWithArg, ConstBool, Contains, EitherOfDiverse}, + traits::{AsEnsureOriginWithArg, ConstBool, Contains}, weights::{ constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, @@ -64,7 +64,6 @@ use frame_system::{ limits::{BlockLength, BlockWeights}, EnsureRoot, EnsureSigned, }; -use pallet_collective::{EnsureProportionAtLeast, EnsureProportionMoreThan}; use pallet_identity::legacy::IdentityInfo; use pallet_transaction_payment::CurrencyAdapter; use scale_info::TypeInfo; @@ -894,7 +893,11 @@ construct_runtime!( Treasury: pallet_treasury = 41, // type CouncilCollective = pallet_collective::Instance2 Council: pallet_collective:: = 42, - // CouncilMembership: pallet_membership:: = 43, + // Removed: CouncilMembership: pallet_membership:: = 43, + // pub type TechnicalCommitteeInstance = pallet_collective::Instance1; + TechnicalCommittee: pallet_collective:: = 44, + // In case we want membership after all, reserve index 45. + Democracy: pallet_democracy = 46, // Indexes 50-59 should be reserved for our games. Randomness: pallet_insecure_randomness_collective_flip = 50, diff --git a/runtime/bajun/src/proxy_type.rs b/runtime/bajun/src/proxy_type.rs index 4d64cf2..5bd3ef6 100644 --- a/runtime/bajun/src/proxy_type.rs +++ b/runtime/bajun/src/proxy_type.rs @@ -61,7 +61,6 @@ impl InstanceFilter for ProxyType { // Specifically omitting the entire Balances pallet RuntimeCall::Session(..) | RuntimeCall::Council(..) | - RuntimeCall::CouncilMembership(..) | RuntimeCall::Treasury(..) | RuntimeCall::Vesting(orml_vesting::Call::claim{..}) | RuntimeCall::Vesting(orml_vesting::Call::claim_for{..}) | From 3249f83fb1778b07b6410ba6e727415e7c41ba42 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Tue, 27 Feb 2024 22:03:53 +0900 Subject: [PATCH 03/18] compiles with the governance config --- node/src/chain_spec.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index a0be7bd..f9e7205 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -182,6 +182,12 @@ fn testnet_genesis( "invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::>(), "candidacyBond": EXISTENTIAL_DEPOSIT * 16, }, + "council": { + "members": vec![get_account_id_from_seed::("Alice")] + }, + "technicalCommittee": { + "members": vec![get_account_id_from_seed::("Alice")] + }, "session": { "keys": invulnerables .into_iter() From 3827b87c80a7d911c11edfda8fe5bc002260a9ee Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Tue, 27 Feb 2024 22:24:10 +0900 Subject: [PATCH 04/18] fix benchmark compilation --- runtime/bajun/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/bajun/src/lib.rs b/runtime/bajun/src/lib.rs index 20e54d8..ff4b2f7 100644 --- a/runtime/bajun/src/lib.rs +++ b/runtime/bajun/src/lib.rs @@ -926,7 +926,7 @@ mod benches { [cumulus_pallet_xcmp_queue, XcmpQueue] [pallet_treasury, Treasury] [pallet_collective, Council] - [pallet_membership, CouncilMembership] + [pallet_collective, TechnicalCommittee] [pallet_identity, Identity] [pallet_preimage, Preimage] [pallet_proxy, Proxy] From 04c989013a095164146fc55ddae5743adc59ec3e Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 11:56:37 +0900 Subject: [PATCH 05/18] fix try-runtime build --- runtime/bajun/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/bajun/Cargo.toml b/runtime/bajun/Cargo.toml index f405af6..9c5aebf 100644 --- a/runtime/bajun/Cargo.toml +++ b/runtime/bajun/Cargo.toml @@ -208,6 +208,7 @@ try-runtime = [ "pallet-balances/try-runtime", "pallet-collator-selection/try-runtime", "pallet-collective/try-runtime", + "pallet-democracy/try-runtime", "pallet-identity/try-runtime", "pallet-membership/try-runtime", "pallet-message-queue/try-runtime", From 8e27d143501317a2d5a0d71ac4712335a3e0539b Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 12:01:44 +0900 Subject: [PATCH 06/18] add chopsticks config --- .gitignore | 3 +++ README.md | 46 +++++++++++++++++++++++++++++++++++++++++++- chopsticks/bajun.yml | 22 +++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 chopsticks/bajun.yml diff --git a/.gitignore b/.gitignore index c6f7615..db655d8 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,7 @@ build/ /dist/ /target +# Chopsticks +/chopsticks/*.db.sqlite* + # Before adding new lines, see the comment at the top. diff --git a/README.md b/README.md index 99b2efc..33674de 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,48 @@ [![codecov](https://codecov.io/gh/ajuna-network/ajuna-runtimes-bajun/branch/main/graph/badge.svg?token=V2Y88ZUD6C)](https://codecov.io/gh/ajuna-network/Ajuna) [![Docker Image Version (latest semver)](https://img.shields.io/docker/v/ajuna/parachain-bajun?label=bajun%20network&logo=docker&sort=semver&style=plastic)](https://hub.docker.com/repository/docker/ajuna/parachain-bajun/tags?page=1&ordering=last_updated) -A game platform [parachain](https://wiki.polkadot.network/docs/learn-parachains) built with [Substrate](https://docs.substrate.io/). +A game platform [parachain](https://wiki.polkadot.network/docs/learn-parachains) built +with [Substrate](https://docs.substrate.io/). + +## Chopsticks + +Chopsticks can be used to create a local fork of a life network, copying all its storage values and override specific +storage values with a config file. The fork will create a block whenever an extrinsic is added to the tx-pool but +it will be stale otherwise, but exposes a fast-forward rpc to produce 'n' blocks, which is useful for scheduler testing. + +Chopsticks can be used to: + +* Test runtime upgrades and functionality thereafter +* Setup XCM with multiple networks and allow for XCM testing +* Test execution of scheduled task, which is mostly execution of governance proposals. + +**Preliminary Note** +Chopsticks will by default listen on the IPV6 localhost port 8000, which means we can either access it with: + +* ws://localhost:8000 +* ws://[::1]:8000 + +but ws://127.0.0.1:8000 doesn't work. + +### Test Runtime Upgrades + +Note: Currently, try-runtime seems to be a better solution to test the runtime upgrade itself, but chopsticks will be +good to test functionality after the runtime upgrade happened. + +The following command overrides the runtime with the local build of the upgraded runtime and will run the migration +upon the next block, which means as soon as we send an arbitrary extrinsic. + +```bash +nvm use 20 +npx @acala-network/chopsticks@latest --config ./chopsticks/bajun.yml --wasm-override ./target/release/wbuild/bajun-runtime/bajun_runtime.compact.compressed.wasm +``` + +Then we can send an arbitrary extrinsic to trigger the next block and observe the logs of the runtime upgrade. + +### Test XCM stuff + +TBD when we actually start setting up XCM. + +### Test Governance execution + +TBD when we have governance \ No newline at end of file diff --git a/chopsticks/bajun.yml b/chopsticks/bajun.yml new file mode 100644 index 0000000..70552a4 --- /dev/null +++ b/chopsticks/bajun.yml @@ -0,0 +1,22 @@ +# In the future we want to add this config to https://github.com/AcalaNetwork/chopsticks/tree/master/configs. +# But we should wait until we have the governance pallets included because this will change this config. +endpoint: + - wss://rpc-parachain.bajun.network + - wss://bajun.api.onfinality.io/public-ws + - wss://bajun.public.curie.radiumblock.co/ws +mock-signature-host: true +block: ${env.BAJUN_PARACHAIN_BLOCK_NUMBER} +db: ./chopsticks/bajun-parachain.db.sqlite +runtime-log-level: 5 +# wasm-override: bajun_runtime.wasm + +# Once we have governance we want to make Alice single councillor and technical committee member. +import-storage: + Sudo: + Key: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY # Alice + System: + Account: # Give our dev accounts some funds + - - - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + - providers: 1 + data: + free: 1000000000000000 \ No newline at end of file From ffae567ebe7ee7e4c5547b6f0f20ce0d8d09af31 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 12:04:32 +0900 Subject: [PATCH 07/18] add licence header to gov --- runtime/bajun/src/gov.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/runtime/bajun/src/gov.rs b/runtime/bajun/src/gov.rs index beef8a8..985a276 100644 --- a/runtime/bajun/src/gov.rs +++ b/runtime/bajun/src/gov.rs @@ -1,3 +1,19 @@ +// Ajuna Node +// Copyright (C) 2022 BlogaTech AG + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + use crate::{AccountId, Balance, BlockNumber}; use crate::{ OriginCaller, Runtime, RuntimeBlockWeights, RuntimeCall, RuntimeEvent, RuntimeOrigin, BAJUN, From 0e0fbaa32d18c8bf17941065d5b30710669007f5 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 12:41:37 +0900 Subject: [PATCH 08/18] [runtime] remove homegrown ensure signed by and add membership instances for both collective instances --- runtime/bajun/src/gov.rs | 89 ++++++++++++++++++++-------------------- runtime/bajun/src/lib.rs | 8 ++-- 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/runtime/bajun/src/gov.rs b/runtime/bajun/src/gov.rs index 985a276..9589c8c 100644 --- a/runtime/bajun/src/gov.rs +++ b/runtime/bajun/src/gov.rs @@ -14,25 +14,23 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use crate::{AccountId, Balance, BlockNumber}; +use crate::{AccountId, Balance, BlockNumber, Council, CouncilMembership, TechnicalCommittee}; use crate::{ OriginCaller, Runtime, RuntimeBlockWeights, RuntimeCall, RuntimeEvent, RuntimeOrigin, BAJUN, DAYS, }; use frame_support::{ - dispatch::RawOrigin, parameter_types, - traits::{ConstBool, ConstU32, EitherOfDiverse, EnsureOrigin}, + traits::{ConstBool, ConstU32, EitherOfDiverse}, weights::Weight, }; -use frame_system::EnsureRoot; +use frame_system::{EnsureRoot, EnsureSignedBy}; use pallet_collective::{EnsureMember, EnsureProportionAtLeast, EnsureProportionMoreThan}; use sp_runtime::Perbill; -use sp_std::marker::PhantomData; pub type EnsureRootOrMoreThanHalfCouncil = EitherOfDiverse< EnsureRoot, - EnsureProportionMoreThan, + EnsureProportionMoreThan, >; pub type EnsureRootOrMoreThanHalfTechnicalCommittee = EitherOfDiverse< @@ -45,38 +43,6 @@ pub type EnsureRootOrAllTechnicalCommittee = EitherOfDiverse< EnsureProportionAtLeast, >; -type AccountIdFor = ::AccountId; - -/// Ensures that the signer of a transaction is a member of said collective instance. -/// -/// This is fundamentally different from the `pallet_collective::EnsureMember`, -/// which checks if the referendum to be executed has been ayed by any member. -/// It is a different kind of origin. -pub struct EnsureSignerIsCollectiveMember(PhantomData<(T, I)>); -impl< - O: Into>, O>> + From>>, - T: pallet_collective::Config, - I, - > EnsureOrigin for EnsureSignerIsCollectiveMember -{ - type Success = AccountIdFor; - fn try_origin(o: O) -> Result { - o.into().and_then(|o| match o { - RawOrigin::Signed(a) if pallet_collective::Pallet::::is_member(&a) => Ok(a), - r => Err(O::from(r)), - }) - } - - #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin() -> Result { - use parity_scale_codec::Decode; - use sp_runtime::traits::TrailingZeroInput; - let zero_account_id = - >::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?; - Ok(O::from(RawOrigin::Signed(zero_account_id))) - } -} - /// Council collective instance declaration. /// /// The council primarily serves to optimize and balance the inclusive referendum system, @@ -84,31 +50,49 @@ impl< /// bypass the one active referendum at a time rule. /// /// It also controls the treasury. -type CouncilCollective = pallet_collective::Instance2; +type CouncilCollectiveInstance = pallet_collective::Instance2; parameter_types! { -pub CouncilMotionDuration: BlockNumber = 3 * DAYS; -pub MaxProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block;} + pub CouncilMotionDuration: BlockNumber = 3 * DAYS; + pub MaxProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block; + pub CouncilMaxMembers: u32 = 100; +} -impl pallet_collective::Config for Runtime { +impl pallet_collective::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; type Proposal = RuntimeCall; type RuntimeEvent = RuntimeEvent; type MotionDuration = CouncilMotionDuration; type MaxProposals = ConstU32<100>; - type MaxMembers = ConstU32<100>; + type MaxMembers = CouncilMaxMembers; type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; type WeightInfo = pallet_collective::weights::SubstrateWeight; type SetMembersOrigin = EnsureRootOrMoreThanHalfCouncil; type MaxProposalWeight = MaxProposalWeight; } +/// Helper pallet to manage Council members. +type CouncilMembershipInstance = pallet_membership::Instance2; +impl pallet_membership::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AddOrigin = EnsureRootOrMoreThanHalfCouncil; + type RemoveOrigin = EnsureRootOrMoreThanHalfCouncil; + type SwapOrigin = EnsureRootOrMoreThanHalfCouncil; + type ResetOrigin = EnsureRootOrMoreThanHalfCouncil; + type PrimeOrigin = EnsureRootOrMoreThanHalfCouncil; + type MembershipInitialized = Council; + type MembershipChanged = Council; + type MaxMembers = CouncilMaxMembers; + type WeightInfo = pallet_membership::weights::SubstrateWeight; +} + /// The technical committee primarily serves to safeguard against malicious referenda, /// and fast track critical referenda. pub type TechnicalCommitteeInstance = pallet_collective::Instance1; parameter_types! { pub const TechnicalMotionDuration: BlockNumber = 3 * DAYS; + pub const TechnicalCommitteeMaxMembers: u32 = 100; } impl pallet_collective::Config for Runtime { @@ -117,13 +101,28 @@ impl pallet_collective::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MotionDuration = TechnicalMotionDuration; type MaxProposals = ConstU32<100>; - type MaxMembers = ConstU32<100>; + type MaxMembers = TechnicalCommitteeMaxMembers; type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; type WeightInfo = pallet_collective::weights::SubstrateWeight; type SetMembersOrigin = EnsureRootOrMoreThanHalfCouncil; type MaxProposalWeight = MaxProposalWeight; } +/// Helper pallet to manage Council members. +type TechnicalCommitteeMembershipInstance = pallet_membership::Instance1; +impl pallet_membership::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AddOrigin = EnsureRootOrMoreThanHalfCouncil; + type RemoveOrigin = EnsureRootOrMoreThanHalfCouncil; + type SwapOrigin = EnsureRootOrMoreThanHalfCouncil; + type ResetOrigin = EnsureRootOrMoreThanHalfCouncil; + type PrimeOrigin = EnsureRootOrMoreThanHalfCouncil; + type MembershipInitialized = TechnicalCommittee; + type MembershipChanged = TechnicalCommittee; + type MaxMembers = TechnicalCommitteeMaxMembers; + type WeightInfo = pallet_membership::weights::SubstrateWeight; +} + parameter_types! { pub const ThreeDays: BlockNumber = 3 * DAYS; pub const TwentyEightDays: BlockNumber = 28 * DAYS; @@ -155,7 +154,7 @@ impl pallet_democracy::Config for Runtime { type ExternalDefaultOrigin = EnsureRootOrMoreThanHalfCouncil; // Initially, we want that only the council can submit proposals to // prevent malicious proposals. - type SubmitOrigin = EnsureSignerIsCollectiveMember; + type SubmitOrigin = EnsureSignedBy; type FastTrackOrigin = EnsureRootOrMoreThanHalfTechnicalCommittee; type InstantOrigin = EnsureRootOrMoreThanHalfTechnicalCommittee; // To cancel a proposal that has passed. diff --git a/runtime/bajun/src/lib.rs b/runtime/bajun/src/lib.rs index ff4b2f7..58e50db 100644 --- a/runtime/bajun/src/lib.rs +++ b/runtime/bajun/src/lib.rs @@ -891,12 +891,14 @@ construct_runtime!( // Governance Sudo: pallet_sudo = 40, Treasury: pallet_treasury = 41, - // type CouncilCollective = pallet_collective::Instance2 + // type CouncilCollectiveInstance = pallet_collective::Instance2 Council: pallet_collective:: = 42, - // Removed: CouncilMembership: pallet_membership:: = 43, + // type CouncilMembershipInstance = pallet_membership::Instance2; + CouncilMembership: pallet_membership:: = 43, // pub type TechnicalCommitteeInstance = pallet_collective::Instance1; TechnicalCommittee: pallet_collective:: = 44, - // In case we want membership after all, reserve index 45. + // type TechnicalCommitteeMembershipInstance = pallet_membership::Instance1; + TechnicalCommitteeMembership: pallet_membership:: = 45, Democracy: pallet_democracy = 46, // Indexes 50-59 should be reserved for our games. From 322695901665194ffa52fe3b5faf6728a7a8e84a Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 12:43:26 +0900 Subject: [PATCH 09/18] [runtime] fix doc comment --- runtime/bajun/src/gov.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/bajun/src/gov.rs b/runtime/bajun/src/gov.rs index 9589c8c..9bc61e2 100644 --- a/runtime/bajun/src/gov.rs +++ b/runtime/bajun/src/gov.rs @@ -108,7 +108,7 @@ impl pallet_collective::Config for Runtime { type MaxProposalWeight = MaxProposalWeight; } -/// Helper pallet to manage Council members. +/// Helper pallet to manage TechnicalCommittee members. type TechnicalCommitteeMembershipInstance = pallet_membership::Instance1; impl pallet_membership::Config for Runtime { type RuntimeEvent = RuntimeEvent; From 25f3fc9a7c844b07e8f4ed354317c7e063fe2cb8 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 12:47:20 +0900 Subject: [PATCH 10/18] [runtime] sort benchmark entries and add membership pallets --- runtime/bajun/src/lib.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/runtime/bajun/src/lib.rs b/runtime/bajun/src/lib.rs index 58e50db..b5974b2 100644 --- a/runtime/bajun/src/lib.rs +++ b/runtime/bajun/src/lib.rs @@ -918,21 +918,23 @@ extern crate frame_benchmarking; #[cfg(feature = "runtime-benchmarks")] mod benches { define_benchmarks!( + [cumulus_pallet_xcmp_queue, XcmpQueue] [frame_system, SystemBench::] [pallet_balances, Balances] - [pallet_session, SessionBench::] - [pallet_timestamp, Timestamp] - [pallet_multisig, Multisig] - [pallet_utility, Utility] [pallet_collator_selection, CollatorSelection] - [cumulus_pallet_xcmp_queue, XcmpQueue] - [pallet_treasury, Treasury] [pallet_collective, Council] [pallet_collective, TechnicalCommittee] [pallet_identity, Identity] + [pallet_membership, CouncilMembership] + [pallet_membership, TechnicalCommitteeMembership] + [pallet_multisig, Multisig] [pallet_preimage, Preimage] [pallet_proxy, Proxy] [pallet_scheduler, Scheduler] + [pallet_session, SessionBench::] + [pallet_timestamp, Timestamp] + [pallet_treasury, Treasury] + [pallet_utility, Utility] [pallet_ajuna_awesome_avatars, AwesomeAvatarsBench::] [pallet_nfts, Nft] ); From 072aa8738a6e6deb99fbb4fd5dcf059229ee90ff Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 12:56:38 +0900 Subject: [PATCH 11/18] [runtime/gov] order imports --- runtime/bajun/src/gov.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/runtime/bajun/src/gov.rs b/runtime/bajun/src/gov.rs index 9bc61e2..b052ec9 100644 --- a/runtime/bajun/src/gov.rs +++ b/runtime/bajun/src/gov.rs @@ -14,10 +14,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use crate::{AccountId, Balance, BlockNumber, Council, CouncilMembership, TechnicalCommittee}; use crate::{ - OriginCaller, Runtime, RuntimeBlockWeights, RuntimeCall, RuntimeEvent, RuntimeOrigin, BAJUN, - DAYS, + AccountId, Balance, BlockNumber, Council, CouncilMembership, OriginCaller, Runtime, + RuntimeBlockWeights, RuntimeCall, RuntimeEvent, RuntimeOrigin, TechnicalCommittee, BAJUN, DAYS, }; use frame_support::{ parameter_types, From 9be7a0949c36df7c2a29c48d0174f93d9bd97b1a Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 12:57:14 +0900 Subject: [PATCH 12/18] [runtime/proxy_type] add technical committee, members, and democracy to non-transfer proxy type --- runtime/bajun/src/proxy_type.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runtime/bajun/src/proxy_type.rs b/runtime/bajun/src/proxy_type.rs index 5bd3ef6..fd20587 100644 --- a/runtime/bajun/src/proxy_type.rs +++ b/runtime/bajun/src/proxy_type.rs @@ -61,6 +61,10 @@ impl InstanceFilter for ProxyType { // Specifically omitting the entire Balances pallet RuntimeCall::Session(..) | RuntimeCall::Council(..) | + RuntimeCall::CouncilMembership(..) | + RuntimeCall::TechnicalCommittee(..) | + RuntimeCall::TechnicalCommitteeMembership(..) | + RuntimeCall::Democracy(..) | RuntimeCall::Treasury(..) | RuntimeCall::Vesting(orml_vesting::Call::claim{..}) | RuntimeCall::Vesting(orml_vesting::Call::claim_for{..}) | From 0c0b6f2dfd075e403ec1000f171c6c0b664cf1f6 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 13:28:00 +0900 Subject: [PATCH 13/18] [node/chain_spec] add bob and charlie to council and technical committee members --- node/src/chain_spec.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index f9e7205..28d1995 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -183,10 +183,18 @@ fn testnet_genesis( "candidacyBond": EXISTENTIAL_DEPOSIT * 16, }, "council": { - "members": vec![get_account_id_from_seed::("Alice")] + "members": vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + ] }, "technicalCommittee": { - "members": vec![get_account_id_from_seed::("Alice")] + "members": vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + ] }, "session": { "keys": invulnerables From 1789c95ef248816f0939322d9ebefe4ca8780193 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 13:49:38 +0900 Subject: [PATCH 14/18] [runtime] fix supplying a preimage --- runtime/bajun/src/lib.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/runtime/bajun/src/lib.rs b/runtime/bajun/src/lib.rs index b5974b2..ee88a3d 100644 --- a/runtime/bajun/src/lib.rs +++ b/runtime/bajun/src/lib.rs @@ -47,7 +47,7 @@ use sp_version::RuntimeVersion; use frame_support::pallet_prelude::ConstU32; use frame_support::traits::fungible::HoldConsideration; use frame_support::traits::tokens::{PayFromAccount, UnityAssetBalanceConversion}; -use frame_support::traits::{Footprint, TransformOrigin}; +use frame_support::traits::{LinearStoragePrice, TransformOrigin}; use frame_support::{ construct_runtime, dispatch::DispatchClass, @@ -86,7 +86,7 @@ use pallet_nfts::{AttributeNamespace, Call as NftsCall}; use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; use parachains_common::{BlockNumber, Hash, Header}; use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; -use sp_runtime::traits::{Convert, IdentifyAccount, IdentityLookup, Verify}; +use sp_runtime::traits::{IdentifyAccount, IdentityLookup, Verify}; parameter_types! { pub const OneDay: BlockNumber = DAYS; @@ -436,7 +436,7 @@ impl pallet_balances::Config for Runtime { type ReserveIdentifier = [u8; 8]; type FreezeIdentifier = (); type MaxFreezes = (); - type RuntimeHoldReason = (); + type RuntimeHoldReason = RuntimeHoldReason; type RuntimeFreezeReason = (); } @@ -748,11 +748,11 @@ impl pallet_scheduler::Config for Runtime { type Preimages = Preimage; } -pub struct ConvertDeposit; -impl Convert for ConvertDeposit { - fn convert(a: Footprint) -> u128 { - (a.count as u128) * 2 + (a.size as u128) - } +parameter_types! { + pub const PreimageBaseDeposit: Balance = deposit(2, 64); + pub const PreimageByteDeposit: Balance = deposit(0, 1); + pub const PreimageHoldReason: RuntimeHoldReason = + RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); } impl pallet_preimage::Config for Runtime { @@ -760,7 +760,12 @@ impl pallet_preimage::Config for Runtime { type WeightInfo = weights::pallet_preimage::WeightInfo; type Currency = Balances; type ManagerOrigin = EnsureRoot; - type Consideration = HoldConsideration; + type Consideration = HoldConsideration< + AccountId, + Balances, + PreimageHoldReason, + LinearStoragePrice, + >; } impl pallet_insecure_randomness_collective_flip::Config for Runtime {} From 23eb93677ca3fcfe904a8ff72ac0190a5632ee31 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 14:40:01 +0900 Subject: [PATCH 15/18] [chopsticks] also give some funds to Bob and Charlie --- chopsticks/bajun.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/chopsticks/bajun.yml b/chopsticks/bajun.yml index 70552a4..e1e0681 100644 --- a/chopsticks/bajun.yml +++ b/chopsticks/bajun.yml @@ -16,7 +16,15 @@ import-storage: Key: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY # Alice System: Account: # Give our dev accounts some funds - - - - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + - - - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY # Alice + - providers: 1 + data: + free: 1000000000000000 + - - - 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty # Bob + - providers: 1 + data: + free: 1000000000000000 + - - - 5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y # Charlie - providers: 1 data: free: 1000000000000000 \ No newline at end of file From d206b8ac1da5251fa0df4a67050080ea7550365d Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 14:47:42 +0900 Subject: [PATCH 16/18] [README] add doc about creating new blocks --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 33674de..835e25c 100644 --- a/README.md +++ b/README.md @@ -52,4 +52,7 @@ TBD when we actually start setting up XCM. ### Test Governance execution -TBD when we have governance \ No newline at end of file +Simply create an external proposal and fast-track it with a small voting period and delay, e.g. 10 blocks. Then, in +polkadot-js/apps, go to Developer -> JavaScript and execute the following chopsticks-dev-rpc: +`api.rpc('dev_newBlock', { count: 10 })`. After this you can observe the blocks being created one by one until the +proposal is executed. From 25cd7c5b452ba218a938879dc512d4a6ccbd2cb3 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 14:50:39 +0900 Subject: [PATCH 17/18] [runtime] fix toml format --- runtime/bajun/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/bajun/Cargo.toml b/runtime/bajun/Cargo.toml index 9c5aebf..ab317a3 100644 --- a/runtime/bajun/Cargo.toml +++ b/runtime/bajun/Cargo.toml @@ -33,7 +33,7 @@ pallet-aura = { workspace = true } pallet-authorship = { workspace = true } pallet-balances = { workspace = true } pallet-collective = { workspace = true } -pallet-democracy = { workspace = true } +pallet-democracy = { workspace = true } pallet-identity = { workspace = true } pallet-insecure-randomness-collective-flip = { workspace = true } pallet-membership = { workspace = true } From a64e35cf0b2ac1287a2fc2d02e1fd5cb6b8d2ea5 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 28 Feb 2024 15:18:49 +0900 Subject: [PATCH 18/18] better doc comments --- README.md | 5 +++-- runtime/bajun/src/gov.rs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 835e25c..efef0b7 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,9 @@ with [Substrate](https://docs.substrate.io/). ## Chopsticks Chopsticks can be used to create a local fork of a life network, copying all its storage values and override specific -storage values with a config file. The fork will create a block whenever an extrinsic is added to the tx-pool but -it will be stale otherwise, but exposes a fast-forward rpc to produce 'n' blocks, which is useful for scheduler testing. +storage values with a config file. The fork will create a block whenever an extrinsic is added to the tx-pool. +Otherwise, it will be stale, but exposes a fast-forward rpc to produce 'n' blocks, which is useful for scheduler +testing. Chopsticks can be used to: diff --git a/runtime/bajun/src/gov.rs b/runtime/bajun/src/gov.rs index b052ec9..9a42afd 100644 --- a/runtime/bajun/src/gov.rs +++ b/runtime/bajun/src/gov.rs @@ -44,7 +44,7 @@ pub type EnsureRootOrAllTechnicalCommittee = EitherOfDiverse< /// Council collective instance declaration. /// -/// The council primarily serves to optimize and balance the inclusive referendum system, +/// The council primarily serves to optimize and balance the inclusive referendum system /// by being allowed to propose external democracy proposals, which can be fast tracked and /// bypass the one active referendum at a time rule. /// @@ -85,7 +85,7 @@ impl pallet_membership::Config for Runtime { type WeightInfo = pallet_membership::weights::SubstrateWeight; } -/// The technical committee primarily serves to safeguard against malicious referenda, +/// The technical committee primarily serves to safeguard against malicious referenda /// and fast track critical referenda. pub type TechnicalCommitteeInstance = pallet_collective::Instance1;