Skip to content

Commit

Permalink
feat: add Technical committee origin to preimage ManagerOrigin (#967)
Browse files Browse the repository at this point in the history
* TechnicalCommiteeMajority is now ManagerOrigin for preimage pallet

* Technical committee can create preimage unit test

* Council can create preimage test

* Root can note preimage test created; Swap alice for charlie in preimage tests to avoid having alice in the tech committee and don't crash with democracy veto test
  • Loading branch information
tsenovilla authored Jan 27, 2025
1 parent 9d49185 commit 898f408
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 6 deletions.
2 changes: 1 addition & 1 deletion runtime/laos/src/configs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod balances;
mod base_fee;
mod benchmark;
mod bounties;
mod collective;
pub(crate) mod collective;
pub mod cumulus_parachain_system;
mod cumulus_xcmp_queue;
mod democracy;
Expand Down
223 changes: 220 additions & 3 deletions runtime/laos/src/configs/preimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
// along with LAOS. If not, see <http://www.gnu.org/licenses/>.

use crate::{
configs::collective::CouncilMajority, currency::calculate_deposit, weights, AccountId, Balance,
Balances, Runtime, RuntimeEvent, RuntimeHoldReason,
configs::collective::{CouncilMajority, TechnicalCommitteeMajority},
currency::calculate_deposit,
weights, AccountId, Balance, Balances, Runtime, RuntimeEvent, RuntimeHoldReason,
};
use frame_support::{
parameter_types,
Expand All @@ -33,7 +34,10 @@ parameter_types! {

impl pallet_preimage::Config for Runtime {
type Currency = Balances;
type ManagerOrigin = EitherOfDiverse<EnsureRoot<AccountId>, CouncilMajority>;
type ManagerOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
EitherOfDiverse<CouncilMajority, TechnicalCommitteeMajority>,
>;
type RuntimeEvent = RuntimeEvent;
type Consideration = HoldConsideration<
AccountId,
Expand All @@ -43,3 +47,216 @@ impl pallet_preimage::Config for Runtime {
>;
type WeightInfo = weights::pallet_preimage::WeightInfo<Runtime>;
}

#[cfg(test)]
mod tests {

use super::*;
use crate::{
tests::{ExtBuilder, BOB, CHARLIE},
Council, Preimage, RuntimeCall, RuntimeOrigin, TechnicalCommittee,
};
use core::str::FromStr;
use frame_support::{assert_ok, dispatch::GetDispatchInfo, traits::PreimageProvider};
use parity_scale_codec::Encode;
use sp_runtime::traits::Hash;

#[test]
fn root_can_note_preimage() {
ExtBuilder::default().build().execute_with(|| {
let system_remark_calldata = RuntimeCall::System(frame_system::Call::remark {
remark: "Hello world!".as_bytes().to_vec(),
})
.encode();

let hashed_calldata =
<Runtime as frame_system::Config>::Hashing::hash(&system_remark_calldata);

// The preimage doesn't exist
assert!(<pallet_preimage::Pallet<Runtime> as PreimageProvider<
<Runtime as frame_system::Config>::Hash,
>>::get_preimage(&hashed_calldata)
.is_none());

assert_ok!(Preimage::note_preimage(
RuntimeOrigin::root(),
system_remark_calldata.clone(),
));

// The preimage exists due to root has created it. Its value is
// exactly the system remark calldata
assert!(<pallet_preimage::Pallet<Runtime> as PreimageProvider<
<Runtime as frame_system::Config>::Hash,
>>::get_preimage(&hashed_calldata)
.is_some());

assert_eq!(
<pallet_preimage::Pallet<Runtime> as PreimageProvider<
<Runtime as frame_system::Config>::Hash,
>>::get_preimage(&hashed_calldata)
.expect("The previous assert ensures that this is Some; qed"),
system_remark_calldata
);
});
}

#[test]
fn council_can_note_preimage() {
let charlie = AccountId::from_str(CHARLIE).expect("CHARLIE is a valid H160 address; qed");
let bob = AccountId::from_str(BOB).expect("BOB is a valid H160 address;qed");

ExtBuilder::default().build().execute_with(|| {
let system_remark_calldata = RuntimeCall::System(frame_system::Call::remark {
remark: "Hello world!".as_bytes().to_vec(),
})
.encode();

let hashed_calldata =
<Runtime as frame_system::Config>::Hashing::hash(&system_remark_calldata);

// The preimage doesn't exist
assert!(<pallet_preimage::Pallet<Runtime> as PreimageProvider<
<Runtime as frame_system::Config>::Hash,
>>::get_preimage(&hashed_calldata)
.is_none());

let threshold = 2u32;
// This lenghtBound is enough for a system remark
let lenght_bound = 19u32;

let proposal = RuntimeCall::Preimage(pallet_preimage::Call::note_preimage {
bytes: system_remark_calldata.clone(),
});

assert_ok!(Council::propose(
RuntimeOrigin::signed(charlie),
threshold,
Box::new(proposal.clone()),
lenght_bound
));

let proposal_index = 0u32;
let proposal_hash =
pallet_collective::pallet::Proposals::<Runtime, pallet_collective::Instance1>::get(
)[proposal_index as usize];
let proposal_weight_bound = proposal.get_dispatch_info().weight;

assert_ok!(Council::vote(
RuntimeOrigin::signed(charlie),
proposal_hash,
proposal_index,
true
));

assert_ok!(Council::vote(
RuntimeOrigin::signed(bob),
proposal_hash,
proposal_index,
true
));

assert_ok!(Council::close(
RuntimeOrigin::signed(charlie),
proposal_hash,
proposal_index,
proposal_weight_bound,
lenght_bound
));

// The preimage exists due to the council has created it. Its value is
// exactly the system remark calldata
assert!(<pallet_preimage::Pallet<Runtime> as PreimageProvider<
<Runtime as frame_system::Config>::Hash,
>>::get_preimage(&hashed_calldata)
.is_some());

assert_eq!(
<pallet_preimage::Pallet<Runtime> as PreimageProvider<
<Runtime as frame_system::Config>::Hash,
>>::get_preimage(&hashed_calldata)
.expect("The previous assert ensures that this is Some; qed"),
system_remark_calldata
);
});
}

#[test]
fn technical_committee_can_note_preimage() {
let charlie = AccountId::from_str(CHARLIE).expect("CHARLIE is a valid H160 address; qed");
let bob = AccountId::from_str(BOB).expect("BOB is a valid H160 address;qed");

ExtBuilder::default().build().execute_with(|| {
let system_remark_calldata = RuntimeCall::System(frame_system::Call::remark {
remark: "Hello world!".as_bytes().to_vec(),
})
.encode();

let hashed_calldata =
<Runtime as frame_system::Config>::Hashing::hash(&system_remark_calldata);

// The preimage doesn't exist
assert!(<pallet_preimage::Pallet<Runtime> as PreimageProvider<
<Runtime as frame_system::Config>::Hash,
>>::get_preimage(&hashed_calldata)
.is_none());

let threshold = 2u32;
// This lenghtBound is enough for a system remark
let lenght_bound = 19u32;

let proposal = RuntimeCall::Preimage(pallet_preimage::Call::note_preimage {
bytes: system_remark_calldata.clone(),
});

assert_ok!(TechnicalCommittee::propose(
RuntimeOrigin::signed(charlie),
threshold,
Box::new(proposal.clone()),
lenght_bound
));

let proposal_index = 0u32;
let proposal_hash =
pallet_collective::pallet::Proposals::<Runtime, pallet_collective::Instance2>::get(
)[proposal_index as usize];
let proposal_weight_bound = proposal.get_dispatch_info().weight;

assert_ok!(TechnicalCommittee::vote(
RuntimeOrigin::signed(charlie),
proposal_hash,
proposal_index,
true
));

assert_ok!(TechnicalCommittee::vote(
RuntimeOrigin::signed(bob),
proposal_hash,
proposal_index,
true
));

assert_ok!(TechnicalCommittee::close(
RuntimeOrigin::signed(charlie),
proposal_hash,
proposal_index,
proposal_weight_bound,
lenght_bound
));

// The preimage exists due to the technical committee has created it. Its value is
// exactly the system remark calldata
assert!(<pallet_preimage::Pallet<Runtime> as PreimageProvider<
<Runtime as frame_system::Config>::Hash,
>>::get_preimage(&hashed_calldata)
.is_some());

assert_eq!(
<pallet_preimage::Pallet<Runtime> as PreimageProvider<
<Runtime as frame_system::Config>::Hash,
>>::get_preimage(&hashed_calldata)
.expect("The previous assert ensures that this is Some; qed"),
system_remark_calldata
);
});
}
}
36 changes: 34 additions & 2 deletions runtime/laos/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ mod metadata;
mod precompile_tests;
mod version_tests;

use core::str::FromStr;
use core::{marker::PhantomData, str::FromStr};
use sp_runtime::BuildStorage;

use super::*;
use crate::{currency::UNIT, AccountId, Balances, Runtime};
use crate::{
configs::collective::MaxMembersTechnicalCommittee, currency::UNIT, AccountId, Balances, Runtime,
};
use fp_rpc::runtime_decl_for_ethereum_runtime_rpc_api::EthereumRuntimeRPCApiV5;
use frame_support::{
assert_ok,
storage::bounded_vec::BoundedVec,
traits::{
tokens::{fungible::Balanced, Precision},
Currency, WithdrawReasons,
Expand Down Expand Up @@ -58,6 +61,20 @@ impl ExtBuilder {
.build_storage()
.unwrap();

let bob = AccountId::from_str(BOB).expect("This shouldn't fail");
let charlie = AccountId::from_str(CHARLIE).expect("This shouldn't fail");

let mut technical_committee_and_council_members =
BoundedVec::with_bounded_capacity(MaxMembersTechnicalCommittee::get() as usize);

technical_committee_and_council_members
.try_push(bob)
.expect("The technical committee bound is greater than 2 members;qed");

technical_committee_and_council_members
.try_push(charlie)
.expect("The technical committee bound is greater than 2 members;qed");

// get deduplicated list of all accounts and balances
let all_accounts = self
.balances
Expand All @@ -83,6 +100,20 @@ impl ExtBuilder {
.assimilate_storage(&mut t)
.unwrap();

pallet_membership::GenesisConfig::<crate::Runtime, pallet_membership::Instance2> {
members: technical_committee_and_council_members.clone(),
phantom: PhantomData,
}
.assimilate_storage(&mut t)
.unwrap();

pallet_collective::GenesisConfig::<crate::Runtime, pallet_membership::Instance1> {
phantom: PhantomData,
members: technical_committee_and_council_members.into_inner(),
}
.assimilate_storage(&mut t)
.unwrap();

t.into()
}
}
Expand All @@ -93,6 +124,7 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities {

pub(crate) const ALICE: &str = "0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac";
pub(crate) const BOB: &str = "0x6c2b9c9b5007740e52d80dddb8e197b0c844f239";
pub(crate) const CHARLIE: &str = "0x798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc";

#[test]
fn minimum_balance_should_be_0() {
Expand Down

0 comments on commit 898f408

Please sign in to comment.