Skip to content
59 changes: 56 additions & 3 deletions eco-tests/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use frame_system::{EnsureRoot, limits, offchain::CreateTransactionBase};
use pallet_subtensor::*;
use pallet_subtensor_proxy as pallet_proxy;
use pallet_subtensor_utility as pallet_utility;
use sp_core::{ConstU64, H256, U256, offchain::KeyTypeId};
use sp_core::{ConstU64, H256, U256, offchain::KeyTypeId, Get};
use sp_runtime::Perbill;
use sp_runtime::{
Percent,
Expand All @@ -45,6 +45,7 @@ frame_support::construct_runtime!(
Swap: pallet_subtensor_swap = 9,
Crowdloan: pallet_crowdloan = 10,
Proxy: pallet_subtensor_proxy = 11,
Commitments: pallet_commitments = 12,
}
);

Expand Down Expand Up @@ -300,7 +301,7 @@ impl pallet_subtensor::Config for Test {
type HotkeySwapOnSubnetInterval = HotkeySwapOnSubnetInterval;
type ProxyInterface = FakeProxier;
type LeaseDividendsDistributionInterval = LeaseDividendsDistributionInterval;
type GetCommitments = ();
type GetCommitments = MockGetCommitments;
type MaxImmuneUidsPercentage = MaxImmuneUidsPercentage;
type CommitmentsInterface = CommitmentsI;
type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit;
Expand Down Expand Up @@ -339,7 +340,59 @@ impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {

pub struct CommitmentsI;
impl CommitmentsInterface for CommitmentsI {
fn purge_netuid(_netuid: NetUid) {}
fn purge_netuid(netuid: NetUid) {
pallet_commitments::Pallet::<Test>::purge_netuid(netuid);
}
}

pub struct MockGetCommitments;
impl pallet_commitments::GetCommitments<AccountId> for MockGetCommitments {
fn get_commitments(netuid: NetUid) -> Vec<(AccountId, Vec<u8>)> {
pallet_commitments::Pallet::<Test>::get_commitments(netuid)
}
}

parameter_types! {
pub const MockCommitmentInitialDeposit: Balance = TaoBalance::new(0);
pub const MockCommitmentFieldDeposit: Balance = TaoBalance::new(0);
}

#[derive(scale_info::TypeInfo)]
pub struct MockMaxCommitFields;
impl Get<u32> for MockMaxCommitFields {
fn get() -> u32 {
3
}
}

pub struct MockCanCommit;
impl pallet_commitments::CanCommit<AccountId> for MockCanCommit {
fn can_commit(netuid: NetUid, address: &AccountId) -> bool {
SubtensorModule::is_hotkey_registered_on_network(netuid, address)
}
}

pub struct MockOnMetadataCommitment;
impl pallet_commitments::OnMetadataCommitment<AccountId> for MockOnMetadataCommitment {
fn on_metadata_commitment(_: NetUid, _: &AccountId) {}
}

pub struct MockTempoInterface;
impl pallet_commitments::GetTempoInterface for MockTempoInterface {
fn get_epoch_index(netuid: NetUid, cur_block: u64) -> u64 {
SubtensorModule::get_epoch_index(netuid, cur_block)
}
}

impl pallet_commitments::Config for Test {
type Currency = Balances;
type WeightInfo = ();
type CanCommit = MockCanCommit;
type OnMetadataCommitment = MockOnMetadataCommitment;
type MaxFields = MockMaxCommitFields;
type InitialDeposit = MockCommitmentInitialDeposit;
type FieldDeposit = MockCommitmentFieldDeposit;
type TempoInterface = MockTempoInterface;
}

parameter_types! {
Expand Down
3 changes: 2 additions & 1 deletion node/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ pub fn create_benchmark_extrinsic(
pallet_shield::CheckShieldedTxValidity::<runtime::Runtime>::new(),
pallet_subtensor::SubtensorTransactionExtension::<runtime::Runtime>::new(),
pallet_drand::drand_priority::DrandPriority::<runtime::Runtime>::new(),
pallet_commitments::CommitmentsTransactionExtension::<runtime::Runtime>::new(),
),
frame_metadata_hash_extension::CheckMetadataHash::<runtime::Runtime>::new(true),
);
Expand All @@ -158,7 +159,7 @@ pub fn create_benchmark_extrinsic(
(),
(),
),
((), (), (), (), ()),
((), (), (), (), (), ()),
None,
),
);
Expand Down
2 changes: 1 addition & 1 deletion pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ pub mod pallet {
/// It is only callable by the root account or subnet owner.
/// The extrinsic will call the Subtensor pallet to set the difficulty.
#[pallet::call_index(24)]
#[pallet::weight(Weight::from_parts(38_500_000, 0)
#[pallet::weight(Weight::from_parts(22_220_000, 0)
.saturating_add(<T as frame_system::Config>::DbWeight::get().reads(3_u64))
.saturating_add(<T as frame_system::Config>::DbWeight::get().writes(1_u64)))]
pub fn sudo_set_difficulty(
Expand Down
130 changes: 125 additions & 5 deletions pallets/commitments/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,27 @@ pub mod weights;

use ark_serialize::CanonicalDeserialize;
use codec::Encode;
use frame_support::IterableStorageDoubleMap;
use frame_support::{
BoundedVec,
traits::{Currency, Get},
BoundedVec, IterableStorageDoubleMap,
dispatch::{DispatchErrorWithPostInfo, DispatchExtension, DispatchInfo, PostDispatchInfo},
pallet_prelude::{
Decode, DecodeWithMemTracking, PhantomData, ValidTransaction, ValidateResult,
},
traits::{Currency, Get, IsSubType, OriginTrait},
};
use frame_system::pallet_prelude::BlockNumberFor;
pub use pallet::*;
use scale_info::prelude::collections::BTreeSet;
use sp_runtime::SaturatedConversion;
use sp_runtime::{Saturating, Weight, traits::Zero};
use sp_runtime::{
SaturatedConversion, Saturating, Weight,
traits::Zero,
traits::{
AsSystemOriginSigner, DispatchInfoOf, Dispatchable, Implication, TransactionExtension,
},
transaction_validity::{InvalidTransaction, TransactionSource, TransactionValidityError},
};
use sp_std::{boxed::Box, vec::Vec};
use subtensor_macros::freeze_struct;
use subtensor_runtime_common::NetUid;
use tle::{
curves::drand::TinyBLS381,
Expand Down Expand Up @@ -576,6 +586,116 @@ impl<T: Config> Pallet<T> {
}
}

type CallOf<T> = <T as frame_system::Config>::RuntimeCall;
type OriginOf<T> = <CallOf<T> as Dispatchable>::RuntimeOrigin;

#[derive(Default, Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)]
#[scale_info(skip_type_params(T))]
#[freeze_struct("7f03f99666ee2c4f")]
pub struct CommitmentsTransactionExtension<T>(PhantomData<T>);

impl<T> sp_std::fmt::Debug for CommitmentsTransactionExtension<T> {
fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
write!(f, "CommitmentsTransactionExtension")
}
}

impl<T> CommitmentsTransactionExtension<T>
where
T: Config + Send + Sync + TypeInfo,
CallOf<T>: Dispatchable + IsSubType<pallet::Call<T>>,
{
pub fn new() -> Self {
Self(Default::default())
}
}

impl<T> TransactionExtension<CallOf<T>> for CommitmentsTransactionExtension<T>
where
T: Config + Send + Sync + TypeInfo,
CallOf<T>: Dispatchable + IsSubType<pallet::Call<T>>,
OriginOf<T>: AsSystemOriginSigner<T::AccountId> + Clone,
{
const IDENTIFIER: &'static str = "CommitmentsTransactionExtension";

type Implicit = ();
type Val = ();
type Pre = ();

fn weight(&self, _call: &CallOf<T>) -> Weight {
Weight::from_parts(0, 0)
}

fn validate(
&self,
origin: OriginOf<T>,
call: &CallOf<T>,
_info: &DispatchInfoOf<CallOf<T>>,
_len: usize,
_self_implicit: Self::Implicit,
_inherited_implication: &impl Implication,
_source: TransactionSource,
) -> ValidateResult<Self::Val, CallOf<T>> {
let Some(who) = origin.as_system_origin_signer() else {
return Ok((ValidTransaction::default(), (), origin));
};

match call.is_sub_type() {
Some(pallet::Call::set_commitment { netuid, .. }) => {
if !T::CanCommit::can_commit(*netuid, who) {
return Err(InvalidTransaction::BadSigner.into());
}

Ok((ValidTransaction::default(), (), origin))
}
_ => Ok((ValidTransaction::default(), (), origin)),
}
}

fn prepare(
self,
_val: Self::Val,
_origin: &OriginOf<T>,
_call: &CallOf<T>,
_info: &DispatchInfoOf<CallOf<T>>,
_len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
Ok(())
}
}
pub struct CommitmentsDispatchExtension<T: Config>(PhantomData<T>);

impl<T> DispatchExtension<CallOf<T>> for CommitmentsDispatchExtension<T>
where
T: Config,
CallOf<T>:
Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<pallet::Call<T>>,
OriginOf<T>: OriginTrait<AccountId = T::AccountId>,
{
type Pre = ();

fn weight(_call: &CallOf<T>) -> Weight {
T::DbWeight::get().reads(1)
}

fn pre_dispatch(
origin: &OriginOf<T>,
call: &CallOf<T>,
) -> Result<Self::Pre, DispatchErrorWithPostInfo> {
let Some(who) = origin.as_signer() else {
return Ok(());
};

if let Some(pallet::Call::set_commitment { netuid, .. }) = call.is_sub_type()
&& !T::CanCommit::can_commit(*netuid, who)
{
return Err(Error::<T>::AccountNotAllowedCommit.into());
}

Ok(())
}
}

pub trait GetCommitments<AccountId> {
fn get_commitments(netuid: NetUid) -> Vec<(AccountId, Vec<u8>)>;
}
Expand Down
29 changes: 22 additions & 7 deletions pallets/subtensor/src/guards/check_coldkey_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use frame_support::{
pallet_prelude::*,
traits::{IsSubType, OriginTrait},
};
use pallet_commitments::CanCommit;
use sp_runtime::traits::Dispatchable;
use sp_std::marker::PhantomData;

Expand All @@ -28,24 +29,32 @@ pub struct CheckColdkeySwap<T: Config>(PhantomData<T>);

impl<T> DispatchExtension<<T as frame_system::Config>::RuntimeCall> for CheckColdkeySwap<T>
where
T: Config + pallet_shield::Config,
T: Config + pallet_shield::Config + pallet_commitments::Config,
<T as frame_system::Config>::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>
+ IsSubType<Call<T>>
+ IsSubType<pallet_shield::Call<T>>,
+ IsSubType<pallet_shield::Call<T>>
+ IsSubType<pallet_commitments::Call<T>>,
DispatchableOriginOf<T>: OriginTrait<AccountId = T::AccountId>,
{
type Pre = ();

fn weight(_call: &CallOf<T>) -> Weight {
T::DbWeight::get().reads(2)
fn weight(call: &CallOf<T>) -> Weight {
let mut weight = T::DbWeight::get().reads(2);

if matches!(
IsSubType::<pallet_commitments::Call<T>>::is_sub_type(call),
Some(pallet_commitments::Call::set_commitment { .. })
) {
weight = weight.saturating_add(T::DbWeight::get().reads(1));
}

weight
}

fn pre_dispatch(
origin: &DispatchableOriginOf<T>,
call: &CallOf<T>,
) -> Result<Self::Pre, DispatchErrorWithPostInfo> {
// Only care about signed origins.
// Root is already bypassed by the extension before we get here.
let Some(who) = origin.as_signer() else {
return Ok(());
};
Expand Down Expand Up @@ -75,10 +84,16 @@ where
}
}

if let Some(pallet_commitments::Call::set_commitment { netuid, .. }) =
IsSubType::<pallet_commitments::Call<T>>::is_sub_type(call)
&& !<T as pallet_commitments::Config>::CanCommit::can_commit(*netuid, who)
{
return Err(pallet_commitments::Error::<T>::AccountNotAllowedCommit.into());
}

Ok(())
}
}

#[cfg(test)]
#[allow(clippy::expect_used, clippy::unwrap_used)]
mod tests {
Expand Down
4 changes: 2 additions & 2 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1190,7 +1190,7 @@ mod dispatches {
/// * `BadOrigin` - If the origin is not root.
///
#[pallet::call_index(69)]
#[pallet::weight(Weight::from_parts(10_190_000, 0)
#[pallet::weight(Weight::from_parts(5_064_000, 0)
.saturating_add(T::DbWeight::get().reads(0))
.saturating_add(T::DbWeight::get().writes(1)))]
pub fn sudo_set_tx_childkey_take_rate_limit(
Expand Down Expand Up @@ -1455,7 +1455,7 @@ mod dispatches {

/// User register a new subnetwork
#[pallet::call_index(79)]
#[pallet::weight((Weight::from_parts(396_000_000, 0)
#[pallet::weight((Weight::from_parts(232_300_000, 0)
.saturating_add(T::DbWeight::get().reads(35_u64))
.saturating_add(T::DbWeight::get().writes(52_u64)), DispatchClass::Normal, Pays::Yes))]
pub fn register_network_with_identity(
Expand Down
Loading
Loading