Skip to content

Commit

Permalink
feat(pallet-communities): dispatch_as_account
Browse files Browse the repository at this point in the history
  • Loading branch information
pandres95 committed Apr 8, 2024
1 parent c83e1fb commit a3fb24a
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 13 deletions.
29 changes: 25 additions & 4 deletions pallets/communities/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use self::{
origin::DecisionMethod,
types::{
AccountIdOf, CommunityIdOf, DecisionMethodFor, MembershipIdOf, NativeBalanceOf, PalletsOriginOf, PollIndexOf,
Vote,
RuntimeCallFor, Vote,
},
Event, HoldReason, Pallet as Communities,
};
Expand All @@ -20,10 +20,10 @@ use frame_support::{
BoundedVec,
};
use frame_system::{
pallet_prelude::{BlockNumberFor, OriginFor, RuntimeCallFor},
pallet_prelude::{BlockNumberFor, OriginFor},
RawOrigin,
};
use sp_runtime::traits::StaticLookup;
use sp_runtime::traits::{Hash, StaticLookup};
use sp_std::{vec, vec::Vec};

fn assert_has_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
Expand Down Expand Up @@ -136,7 +136,7 @@ where
#[benchmarks(
where
T: frame_system::Config + crate::Config,
RuntimeCallFor<T>: From<crate::Call<T>>,
<T as Config>::RuntimeEvent: From<frame_system::Event<T>>,
MembershipIdOf<T>: From<u32>,
BlockNumberFor<T>: From<u32>
)]
Expand Down Expand Up @@ -407,6 +407,27 @@ mod benchmarks {
Ok(())
}

#[benchmark]
fn dispatch_as_account() -> Result<(), BenchmarkError> {
// setup code
let (id, origin) = create_community::<T>(RawOrigin::Root.into(), Some(DecisionMethod::NativeToken))?;
let remark = b"Hello, world".to_vec();

#[extrinsic_call]
_(
origin.into_caller(),
Box::new(frame_system::Call::<T>::remark_with_event { remark: remark.clone() }.into()),
);

// verification code
let sender = Communities::<T>::community_account(&id);
let hash = <T as frame_system::Config>::Hashing::hash(&remark);

assert_has_event::<T>(frame_system::Event::<T>::Remarked { sender, hash }.into());

Ok(())
}

impl_benchmark_test_suite!(
Communities,
sp_io::TestExternalities::new(Default::default()),
Expand Down
19 changes: 17 additions & 2 deletions pallets/communities/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@ use crate::{
origin::DecisionMethod,
types::{
AccountIdOf, CommunityIdOf, CommunityInfo, CommunityState, ConstSizedField, MembershipIdOf, PalletsOriginOf,
PollIndexOf, Tally, Vote, VoteOf, VoteWeight,
PollIndexOf, RuntimeCallFor, Tally, Vote, VoteOf, VoteWeight,
},
CommunityDecisionMethod, CommunityIdFor, CommunityVotes, Config, Error, HoldReason, Info, Metadata, Pallet,
};
use fc_traits_memberships::{GenericRank, Inspect, Rank};
use frame_support::{
dispatch::PostDispatchInfo,
fail,
pallet_prelude::*,
traits::{
fungible::MutateFreeze as FunMutateFreeze, fungibles::MutateHold as FunsMutateHold, tokens::Precision, Polling,
},
};
use sp_runtime::{traits::AccountIdConversion, TokenError};
use sp_runtime::{
traits::{AccountIdConversion, Dispatchable},
DispatchResultWithInfo, TokenError,
};
use sp_std::vec::Vec;

impl<T: Config> Pallet<T> {
Expand Down Expand Up @@ -189,6 +193,17 @@ impl<T: Config> Pallet<T> {
_ => Err(Error::<T>::NoLocksInPlace.into()),
}
}

pub(crate) fn do_dispatch_as_community_account(
community_id: &CommunityIdOf<T>,
call: RuntimeCallFor<T>,
) -> DispatchResultWithInfo<PostDispatchInfo> {
let community_account = Self::community_account(community_id);
let signer = frame_system::RawOrigin::Signed(community_account);

let post = call.dispatch(signer.into()).map_err(|e| e.error)?;
Ok(post)
}
}

impl<T: Config> Tally<T> {
Expand Down
30 changes: 27 additions & 3 deletions pallets/communities/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,14 @@ pub mod pallet {
use core::num::NonZeroU8;
use fc_traits_memberships::{self as membership, Inspect, Manager, Rank};
use frame_support::{
dispatch::{DispatchResultWithPostInfo, GetDispatchInfo, PostDispatchInfo},
pallet_prelude::*,
traits::{fungible, fungibles, EnsureOrigin, Polling},
traits::{fungible, fungibles, EnsureOrigin, IsSubType, Polling},
Blake2_128Concat, Parameter,
};
use frame_system::pallet_prelude::{OriginFor, *};
use sp_runtime::traits::StaticLookup;
use types::{PollIndexOf, *};
use sp_runtime::traits::{Dispatchable, StaticLookup};
use types::{PollIndexOf, RuntimeCallFor, *};
const ONE: NonZeroU8 = NonZeroU8::MIN;

#[pallet::pallet]
Expand Down Expand Up @@ -192,6 +193,15 @@ pub mod pallet {
+ fungible::freeze::Inspect<Self::AccountId, Id = Self::RuntimeHoldReason>
+ fungible::freeze::Mutate<Self::AccountId, Id = Self::RuntimeHoldReason>;

/// The overarching call type.
type RuntimeCall: Parameter
+ Dispatchable<RuntimeOrigin = Self::RuntimeOrigin, PostInfo = PostDispatchInfo>
+ GetDispatchInfo
+ From<Call<Self>>
+ From<frame_system::Call<Self>>
+ IsSubType<Call<Self>>
+ IsType<<Self as frame_system::Config>::RuntimeCall>;

/// The overarching hold reason.
type RuntimeHoldReason: From<HoldReason>;

Expand Down Expand Up @@ -499,5 +509,19 @@ pub mod pallet {

Self::do_unlock_for_vote(&who, &poll_index, &vote)
}

/// Dispatch a callable as the community account
#[pallet::call_index(11)]
#[pallet::weight({
let di = call.get_dispatch_info();
let weight = T::WeightInfo::dispatch_as_account()
.saturating_add(T::DbWeight::get().reads_writes(1, 1))
.saturating_add(di.weight);
(weight, di.class)
})]
pub fn dispatch_as_account(origin: OriginFor<T>, call: Box<RuntimeCallFor<T>>) -> DispatchResultWithPostInfo {
let community_id = T::MemberMgmtOrigin::ensure_origin(origin)?;
Self::do_dispatch_as_community_account(&community_id, *call)
}
}
}
1 change: 1 addition & 0 deletions pallets/communities/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ impl pallet_communities::Config for Test {
type CommunityMgmtOrigin = EnsureRoot<AccountId>;
type MemberMgmtOrigin = EnsureCommunity<Self>;

type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type RuntimeHoldReason = RuntimeHoldReason;
type WeightInfo = WeightInfo;
Expand Down
6 changes: 2 additions & 4 deletions pallets/communities/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLo
pub type PalletsOriginOf<T> =
<<T as frame_system::Config>::RuntimeOrigin as frame_support::traits::OriginTrait>::PalletsOrigin;
pub type MembershipIdOf<T> = <T as Config>::MembershipId;
pub type RuntimeCallFor<T> = <T as Config>::RuntimeCall;

pub type SizedField<S> = BoundedVec<u8, S>;
pub type ConstSizedField<const S: u32> = SizedField<ConstU32<S>>;
Expand Down Expand Up @@ -148,10 +149,7 @@ impl<T: Config> Tally<T> {
}

#[cfg(feature = "runtime-benchmarks")]
use {
frame_benchmarking::BenchmarkError,
frame_system::pallet_prelude::{OriginFor, RuntimeCallFor},
};
use {frame_benchmarking::BenchmarkError, frame_system::pallet_prelude::OriginFor};

#[cfg(feature = "runtime-benchmarks")]
pub trait BenchmarkHelper<T: Config> {
Expand Down
27 changes: 27 additions & 0 deletions pallets/communities/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub trait WeightInfo {
fn vote() -> Weight;
fn remove_vote() -> Weight;
fn unlock() -> Weight;
fn dispatch_as_account() -> Weight;
}

/// Weights for pallet_communities using the Substrate node and recommended hardware.
Expand Down Expand Up @@ -265,6 +266,14 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
.saturating_add(T::DbWeight::get().reads(5))
.saturating_add(T::DbWeight::get().writes(3))
}
fn dispatch_as_account() -> Weight {
// Proof Size summary in bytes:
// Measured: `1079`
// Estimated: `9147`
// Minimum execution time: 128_764_000 picoseconds.
Weight::from_parts(37_944_303, 0)
.saturating_add(Weight::from_parts(0, 4065))
}
}

// For backwards compatibility and tests
Expand Down Expand Up @@ -485,4 +494,22 @@ impl WeightInfo for () {
.saturating_add(RocksDbWeight::get().reads(5))
.saturating_add(RocksDbWeight::get().writes(3))
}
/// Storage: `CommunityReferenda::ReferendumInfoFor` (r:1 w:0)
/// Proof: `CommunityReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
/// Storage: `Communities::CommunityVotes` (r:1 w:1)
/// Proof: `Communities::CommunityVotes` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `Balances::Freezes` (r:1 w:1)
/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(5682), added: 8157, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Balances::Locks` (r:1 w:0)
/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
fn dispatch_as_account() -> Weight {
// Proof Size summary in bytes:
// Measured: `1079`
// Estimated: `9147`
// Minimum execution time: 128_764_000 picoseconds.
Weight::from_parts(37_944_303, 0)
.saturating_add(Weight::from_parts(0, 4065))
}
}
2 changes: 2 additions & 0 deletions runtime/kreivo/src/communities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ impl pallet_communities::Config for Runtime {

type Assets = Assets;
type Balances = Balances;

type RuntimeCall = RuntimeCall;
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeEvent = RuntimeEvent;
type WeightInfo = crate::weights::pallet_communities::WeightInfo<Runtime>;
Expand Down

0 comments on commit a3fb24a

Please sign in to comment.