From 7f8a3aacdeef01c3fd760082837ea1236b74adec Mon Sep 17 00:00:00 2001 From: muharem Date: Thu, 30 Mar 2023 18:01:39 +0200 Subject: [PATCH 1/2] collective: max proposal weight --- bin/node/runtime/src/lib.rs | 4 ++++ frame/alliance/src/mock.rs | 6 ++++- frame/collective/src/lib.rs | 14 ++++++++++++ frame/collective/src/tests.rs | 42 ++++++++++++++++++++++++++++++++++- frame/utility/src/tests.rs | 2 ++ 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 48bea5ddc101f..a60f631ab4fb7 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -210,6 +210,7 @@ parameter_types! { }) .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) .build_or_panic(); + pub MaxCollectivesProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block; } const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct()); @@ -1009,6 +1010,7 @@ impl pallet_collective::Config for Runtime { type DefaultVote = pallet_collective::PrimeDefaultVote; type WeightInfo = pallet_collective::weights::SubstrateWeight; type SetMembersOrigin = EnsureRoot; + type MaxProposalWeight = MaxCollectivesProposalWeight; } parameter_types! { @@ -1069,6 +1071,7 @@ impl pallet_collective::Config for Runtime { type DefaultVote = pallet_collective::PrimeDefaultVote; type WeightInfo = pallet_collective::weights::SubstrateWeight; type SetMembersOrigin = EnsureRoot; + type MaxProposalWeight = MaxCollectivesProposalWeight; } type EnsureRootOrHalfCouncil = EitherOfDiverse< @@ -1695,6 +1698,7 @@ impl pallet_collective::Config for Runtime { type DefaultVote = pallet_collective::PrimeDefaultVote; type WeightInfo = pallet_collective::weights::SubstrateWeight; type SetMembersOrigin = EnsureRoot; + type MaxProposalWeight = MaxCollectivesProposalWeight; } parameter_types! { diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 848f6b2a00557..c334a3943b025 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -43,10 +43,12 @@ type AccountId = u64; parameter_types! { pub const BlockHashCount: BlockNumber = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::MAX); } impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); + type BlockWeights = BlockWeights; type BlockLength = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; @@ -97,6 +99,7 @@ parameter_types! { pub const MotionDuration: BlockNumber = MOTION_DURATION_IN_BLOCKS; pub const MaxProposals: u32 = 100; pub const MaxMembers: u32 = 100; + pub MaxProposalWeight: Weight = sp_runtime::Perbill::from_percent(50) * BlockWeights::get().max_block; } type AllianceCollective = pallet_collective::Instance1; impl pallet_collective::Config for Test { @@ -109,6 +112,7 @@ impl pallet_collective::Config for Test { type DefaultVote = pallet_collective::PrimeDefaultVote; type WeightInfo = (); type SetMembersOrigin = EnsureRoot; + type MaxProposalWeight = MaxProposalWeight; } parameter_types! { diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index c58965d2c9199..5d688ccc0c271 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -217,6 +217,10 @@ pub mod pallet { /// Origin allowed to set collective members type SetMembersOrigin: EnsureOrigin<::RuntimeOrigin>; + + /// The maximum weight of a dispatch call that can be proposed and executed. + #[pallet::constant] + type MaxProposalWeight: Get; } #[pallet::genesis_config] @@ -710,6 +714,11 @@ impl, I: 'static> Pallet { ) -> Result<(u32, DispatchResultWithPostInfo), DispatchError> { let proposal_len = proposal.encoded_size(); ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); + let proposal_weight = proposal.get_dispatch_info().weight; + ensure!( + proposal_weight.all_lte(T::MaxProposalWeight::get()), + Error::::WrongProposalWeight + ); let proposal_hash = T::Hashing::hash_of(&proposal); ensure!(!>::contains_key(proposal_hash), Error::::DuplicateProposal); @@ -732,6 +741,11 @@ impl, I: 'static> Pallet { ) -> Result<(u32, u32), DispatchError> { let proposal_len = proposal.encoded_size(); ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); + let proposal_weight = proposal.get_dispatch_info().weight; + ensure!( + proposal_weight.all_lte(T::MaxProposalWeight::get()), + Error::::WrongProposalWeight + ); let proposal_hash = T::Hashing::hash_of(&proposal); ensure!(!>::contains_key(proposal_hash), Error::::DuplicateProposal); diff --git a/frame/collective/src/tests.rs b/frame/collective/src/tests.rs index 79f6cc27fadbd..0ce936ad48576 100644 --- a/frame/collective/src/tests.rs +++ b/frame/collective/src/tests.rs @@ -90,10 +90,13 @@ pub type MaxMembers = ConstU32<100>; parameter_types! { pub const MotionDuration: u64 = 3; pub const MaxProposals: u32 = 257; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::MAX); + pub static MaxProposalWeight: Weight = default_max_proposal_weight(); } impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); + type BlockWeights = BlockWeights; type BlockLength = (); type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; @@ -127,6 +130,7 @@ impl Config for Test { type DefaultVote = PrimeDefaultVote; type WeightInfo = (); type SetMembersOrigin = EnsureRoot; + type MaxProposalWeight = MaxProposalWeight; } impl Config for Test { type RuntimeOrigin = RuntimeOrigin; @@ -138,6 +142,7 @@ impl Config for Test { type DefaultVote = MoreThanMajorityThenPrimeDefaultVote; type WeightInfo = (); type SetMembersOrigin = EnsureRoot; + type MaxProposalWeight = MaxProposalWeight; } impl mock_democracy::Config for Test { type RuntimeEvent = RuntimeEvent; @@ -153,6 +158,7 @@ impl Config for Test { type DefaultVote = PrimeDefaultVote; type WeightInfo = (); type SetMembersOrigin = EnsureRoot; + type MaxProposalWeight = MaxProposalWeight; } pub fn new_test_ext() -> sp_io::TestExternalities { @@ -184,6 +190,10 @@ fn record(event: RuntimeEvent) -> EventRecord { EventRecord { phase: Phase::Initialization, event, topics: vec![] } } +fn default_max_proposal_weight() -> Weight { + sp_runtime::Perbill::from_percent(80) * BlockWeights::get().max_block +} + #[test] fn motions_basic_environment_works() { new_test_ext().execute_with(|| { @@ -192,6 +202,36 @@ fn motions_basic_environment_works() { }); } +#[test] +fn proposal_weight_limit_works() { + new_test_ext().execute_with(|| { + let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + + assert_ok!(Collective::propose( + RuntimeOrigin::signed(1), + 2, + Box::new(proposal.clone()), + proposal_len + )); + + // set a small limit for max proposal weight. + MaxProposalWeight::set(Weight::from_parts(1, 1)); + assert_noop!( + Collective::propose( + RuntimeOrigin::signed(1), + 2, + Box::new(proposal.clone()), + proposal_len + ), + Error::::WrongProposalWeight + ); + + // reset the max weight to default. + MaxProposalWeight::set(default_max_proposal_weight()); + }); +} + #[test] fn close_works() { new_test_ext().execute_with(|| { diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 04f2728242874..3786b9889f7fe 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -209,6 +209,7 @@ parameter_types! { pub const MotionDuration: BlockNumber = MOTION_DURATION_IN_BLOCKS; pub const MaxProposals: u32 = 100; pub const MaxMembers: u32 = 100; + pub MaxProposalWeight: Weight = sp_runtime::Perbill::from_percent(50) * BlockWeights::get().max_block; } type CouncilCollective = pallet_collective::Instance1; @@ -222,6 +223,7 @@ impl pallet_collective::Config for Test { type DefaultVote = pallet_collective::PrimeDefaultVote; type WeightInfo = (); type SetMembersOrigin = frame_system::EnsureRoot; + type MaxProposalWeight = MaxProposalWeight; } impl example::Config for Test {} From 6968c5f708b8648b178c0b7067731591388f07ea Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 19 Apr 2023 10:07:15 +0200 Subject: [PATCH 2/2] fix test --- frame/collective/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/collective/src/tests.rs b/frame/collective/src/tests.rs index 91983ea942e3b..4775133ffa2f6 100644 --- a/frame/collective/src/tests.rs +++ b/frame/collective/src/tests.rs @@ -221,7 +221,7 @@ fn motions_basic_environment_works() { #[test] fn proposal_weight_limit_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let proposal = make_proposal(42); let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);