In trying to learning how governance works, I have implemented a bare-minimum governance configuration. I run it on a local relay chain and passed referenda always fail enactment with BadOrigin
no matter what extrinsic is proposed. Even a simple balance transfer initiated by the origin account for the transfer fails. All proposals are proposed by a Council member, using the Polkadot UI -> Democracy tab. Everything else works as expected. Any ideas why this could be happening?
Here is my governance-related config:
parameter_types! {
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(10) * RuntimeBlockWeights::get().max_block;
pub const MaxScheduledPerBlock: u32 = 50;
pub const NoPreimagePostponement: Option<u32> = Some(5 * MINUTES);
}
impl pallet_scheduler::Config 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 = pallet_scheduler::weights::SubstrateWeight<Runtime>;
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type PreimageProvider = Preimage;
type NoPreimagePostponement = NoPreimagePostponement;
}
parameter_types! {
pub const PreimageMaxSize: u32 = 4096 * 1024;
pub const PreimageBaseDeposit: Balance = 1 * MILLIUNIT;
pub const PreimageByteDeposit: Balance = 1 * MICROUNIT;
}
impl pallet_preimage::Config for Runtime {
type WeightInfo = pallet_preimage::weights::SubstrateWeight<Runtime>;
type Event = Event;
type Currency = Balances;
type ManagerOrigin = EnsureRoot<AccountId>;
type MaxSize = PreimageMaxSize;
type BaseDeposit = PreimageBaseDeposit;
type ByteDeposit = PreimageByteDeposit;
}
parameter_types! {
pub const CouncilMotionDuration: BlockNumber = 5 * DAYS;
pub const CouncilMaxProposals: u32 = 25;
pub const CouncilMaxMembers: u32 = 1;
}
type CouncilCollective = pallet_collective::Instance1;
impl pallet_collective::Config<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 = pallet_collective::weights::SubstrateWeight<Runtime>;
}
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 MinimumDeposit: Balance = 100 * UNIT;
pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
pub const MaxProposals: u32 = 100;
}
impl pallet_democracy::Config for Runtime {
type CooloffPeriod = CooloffPeriod;
type Currency = Balances;
type EnactmentPeriod = EnactmentPeriod;
type Event = Event;
type FastTrackVotingPeriod = FastTrackVotingPeriod;
type InstantAllowed = frame_support::traits::ConstBool<true>;
type LaunchPeriod = LaunchPeriod;
type MaxProposals = MaxProposals;
type MaxVotes = ConstU32<100>;
type MinimumDeposit = MinimumDeposit;
type PreimageByteDeposit = PreimageByteDeposit;
type Proposal = Call;
type Scheduler = Scheduler;
type Slash = ();
type WeightInfo = pallet_democracy::weights::SubstrateWeight<Runtime>;
type VoteLockingPeriod = EnactmentPeriod; // Same as EnactmentPeriod
type VotingPeriod = VotingPeriod;
type ExternalDefaultOrigin = pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 1>;
type ExternalMajorityOrigin = pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 4>;
type ExternalOrigin = pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>;
type FastTrackOrigin = EnsureRoot<AccountId>;
type InstantOrigin = EnsureRoot<AccountId>;
type PalletsOrigin = OriginCaller;
type CancellationOrigin = pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>;
type CancelProposalOrigin = EitherOfDiverse<EnsureRoot<AccountId>, pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 1>>;
type BlacklistOrigin = EnsureRoot<AccountId>;
type VetoOrigin = pallet_collective::EnsureMember<AccountId, CouncilCollective>;
}