Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions substrate/frame/collective/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ sp-runtime = { workspace = true }

[dev-dependencies]
pallet-balances = { workspace = true, default-features = false }
pallet-preimage = { workspace = true, default-features = false}

[features]
default = ["std"]
Expand Down
21 changes: 13 additions & 8 deletions substrate/frame/collective/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ use frame_support::{
ensure,
traits::{
Backing, ChangeMembers, Consideration, EnsureOrigin, EnsureOriginWithArg, Get, GetBacking,
InitializeMembers, MaybeConsideration, OriginTrait, StorageVersion,
InitializeMembers, MaybeConsideration, OriginTrait, QueryPreimage, StorageVersion,
StorePreimage,
},
weights::Weight,
};
Expand Down Expand Up @@ -398,6 +399,8 @@ pub mod pallet {
/// consider using a constant cost (e.g., [`crate::deposit::Constant`]) equal to the minimum
/// balance under the `runtime-benchmarks` feature.
type Consideration: MaybeConsideration<Self::AccountId, u32>;

type Preimages: QueryPreimage<H = Self::Hashing> + StorePreimage;
}

#[pallet::genesis_config]
Expand Down Expand Up @@ -439,7 +442,7 @@ pub mod pallet {
/// Actual proposal for a given hash, if it's current.
#[pallet::storage]
pub type ProposalOf<T: Config<I>, I: 'static = ()> =
StorageMap<_, Identity, T::Hash, <T as Config<I>>::Proposal, OptionQuery>;
StorageMap<_, Identity, T::Hash, (), OptionQuery>;
Comment on lines 444 to +445
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be removed and migrated with a multi block migration to Preimage


/// Consideration cost created for publishing and storing a proposal.
///
Expand Down Expand Up @@ -976,7 +979,8 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
let index = ProposalCount::<T, I>::get();

<ProposalCount<T, I>>::mutate(|i| *i += 1);
<ProposalOf<T, I>>::insert(proposal_hash, proposal);
T::Preimages::note(proposal.encode().into())?;
<ProposalOf<T, I>>::insert(proposal_hash, ());
let votes = {
let end = frame_system::Pallet::<T>::block_number() + T::MotionDuration::get();
Votes { index, threshold, ayes: vec![], nays: vec![], end }
Expand Down Expand Up @@ -1135,12 +1139,13 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
length_bound: u32,
weight_bound: Weight,
) -> Result<(<T as Config<I>>::Proposal, usize), DispatchError> {
let key = ProposalOf::<T, I>::hashed_key_for(hash);
// read the length of the proposal storage entry directly
let proposal_len =
storage::read(&key, &mut [0; 0], 0).ok_or(Error::<T, I>::ProposalMissing)?;
let proposal_len = T::Preimages::len(hash).ok_or(Error::<T, I>::ProposalMissing)?;
ensure!(proposal_len <= length_bound, Error::<T, I>::WrongProposalLength);
let proposal = ProposalOf::<T, I>::get(hash).ok_or(Error::<T, I>::ProposalMissing)?;

let bytes = T::Preimages::fetch(hash, Some(proposal_len))
.map_err(|_| Error::<T, I>::ProposalMissing)?;
let proposal = <T as Config<I>>::Proposal::decode(&mut &bytes[..])
.map_err(|_| Error::<T, I>::ProposalMissing)?;
let proposal_weight = proposal.get_dispatch_info().call_weight;
ensure!(proposal_weight.all_lte(weight_bound), Error::<T, I>::WrongProposalWeight);
Ok((proposal, proposal_len as usize))
Expand Down
38 changes: 33 additions & 5 deletions substrate/frame/collective/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use frame_support::{
fungible::{HoldConsideration, Inspect, Mutate},
ConstU32, ConstU64, StorageVersion,
},
Hashable,
};
use frame_system::{EnsureRoot, EventRecord, Phase};
use sp_core::{ConstU128, H256};
Expand All @@ -34,6 +33,7 @@ use sp_runtime::{
traits::{BlakeTwo256, Convert, Zero},
BuildStorage, FixedU128,
};
use std::{borrow::Cow, cell::RefCell, collections::HashMap};

pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic<u32, RuntimeCall, u64, ()>;
Expand All @@ -47,6 +47,7 @@ frame_support::construct_runtime!(
CollectiveMajority: pallet_collective::<Instance2>,
DefaultCollective: pallet_collective,
Democracy: mock_democracy,
Preimage: pallet_preimage,
}
);

Expand Down Expand Up @@ -85,6 +86,14 @@ mod mock_democracy {
}
}

impl pallet_preimage::Config for Test {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
type Currency = Balances;
type ManagerOrigin = EnsureRoot<u64>;
type Consideration = ();
}

pub type MaxMembers = ConstU32<100>;
type AccountId = u64;

Expand Down Expand Up @@ -134,6 +143,7 @@ impl Config<Instance1> for Test {
type KillOrigin = EnsureRoot<AccountId>;
type Consideration =
HoldConsideration<AccountId, Balances, ProposalHoldReason, CollectiveDeposit, u32>;
type Preimages = Preimage;
}

type CollectiveMajorityDeposit = deposit::Linear<ConstU32<2>, ProposalDepositBase>;
Expand All @@ -154,6 +164,7 @@ impl Config<Instance2> for Test {
type KillOrigin = EnsureRoot<AccountId>;
type Consideration =
HoldConsideration<AccountId, Balances, ProposalHoldReason, CollectiveMajorityDeposit, u32>;
type Preimages = Preimage;
}
impl mock_democracy::Config for Test {
type RuntimeEvent = RuntimeEvent;
Expand Down Expand Up @@ -182,6 +193,7 @@ impl Config for Test {
type KillOrigin = EnsureRoot<AccountId>;
type Consideration =
HoldConsideration<AccountId, Balances, ProposalHoldReason, DefaultCollectiveDeposit, u32>;
type Preimages = Preimage;
}

pub struct ExtBuilder {
Expand Down Expand Up @@ -227,6 +239,7 @@ impl ExtBuilder {

pub fn build_and_execute(self, test: impl FnOnce() -> ()) {
self.build().execute_with(|| {
PREIMAGES.with(|m| m.borrow_mut().clear());
test();
Collective::do_try_state().unwrap();
})
Expand Down Expand Up @@ -357,6 +370,7 @@ fn close_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0,
Expand Down Expand Up @@ -504,6 +518,7 @@ fn close_with_prime_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0,
Expand Down Expand Up @@ -579,6 +594,7 @@ fn close_with_voting_prime_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0,
Expand Down Expand Up @@ -672,6 +688,7 @@ fn close_with_no_prime_but_majority_works() {
who: 5,
amount: 2,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::CollectiveMajority(CollectiveEvent::Proposed {
account: 5,
proposal_index: 0,
Expand Down Expand Up @@ -847,7 +864,7 @@ fn propose_works() {
proposal_len
));
assert_eq!(*Proposals::<Test, Instance1>::get(), vec![hash]);
assert_eq!(ProposalOf::<Test, Instance1>::get(&hash), Some(proposal));
assert_eq!(ProposalOf::<Test, Instance1>::get(&hash), Some(()));
assert_eq!(
Voting::<Test, Instance1>::get(&hash),
Some(Votes { index: 0, threshold: 3, ayes: vec![], nays: vec![], end })
Expand All @@ -863,6 +880,7 @@ fn propose_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0,
Expand Down Expand Up @@ -1058,6 +1076,7 @@ fn motions_vote_after_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0,
Expand Down Expand Up @@ -1210,6 +1229,7 @@ fn motions_approval_with_enough_votes_and_lower_voting_threshold_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0, // 0 is the proposal that failed to execute?
Expand Down Expand Up @@ -1272,6 +1292,7 @@ fn motions_approval_with_enough_votes_and_lower_voting_threshold_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 1,
Expand Down Expand Up @@ -1350,6 +1371,7 @@ fn motions_disapproval_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0,
Expand Down Expand Up @@ -1416,6 +1438,7 @@ fn motions_approval_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0,
Expand Down Expand Up @@ -1497,23 +1520,27 @@ fn motion_with_no_votes_closes_with_disapproval() {
// Events show that the close ended in a disapproval.
assert_eq!(
System::events()[1],
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
);
assert_eq!(
System::events()[2],
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0,
proposal_hash: hash,
threshold: 3
}))
})),
);
assert_eq!(
System::events()[2],
System::events()[3],
record(RuntimeEvent::Collective(CollectiveEvent::Closed {
proposal_hash: hash,
yes: 0,
no: 3
}))
);
assert_eq!(
System::events()[3],
System::events()[4],
record(RuntimeEvent::Collective(CollectiveEvent::Disapproved { proposal_hash: hash }))
);
})
Expand Down Expand Up @@ -1581,6 +1608,7 @@ fn disapprove_proposal_works() {
who: 1,
amount: 0,
})),
record(RuntimeEvent::Preimage(pallet_preimage::Event::Noted { hash })),
record(RuntimeEvent::Collective(CollectiveEvent::Proposed {
account: 1,
proposal_index: 0,
Expand Down
Loading