Skip to content

Commit eaca7aa

Browse files
committed
Configure pallet-rate-limiting for the runtime
1 parent 434f7e3 commit eaca7aa

File tree

6 files changed

+341
-115
lines changed

6 files changed

+341
-115
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pallets/rate-limiting/src/lib.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,6 @@ pub mod pallet {
440440
pub groups: Vec<(<T as Config<I>>::GroupId, Vec<u8>, GroupSharing)>,
441441
}
442442

443-
#[cfg(feature = "std")]
444443
impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
445444
fn default() -> Self {
446445
Self {
@@ -541,7 +540,9 @@ pub mod pallet {
541540
Ok(Self::within_span(&usage_target, usage_key, block_span))
542541
}
543542

544-
pub(crate) fn resolved_limit(
543+
/// Resolves the configured span for the provided target/scope, applying the pallet default
544+
/// when the stored value uses [`RateLimitKind::Default`].
545+
pub fn resolved_limit(
545546
target: &RateLimitTarget<<T as Config<I>>::GroupId>,
546547
scope: &Option<<T as Config<I>>::LimitScope>,
547548
) -> Option<BlockNumberFor<T>> {
@@ -689,7 +690,8 @@ pub mod pallet {
689690
Self::resolved_limit(&target, &scope)
690691
}
691692

692-
fn identifier_for_call_names(
693+
/// Looks up the transaction identifier for a pallet/extrinsic name pair.
694+
pub fn identifier_for_call_names(
693695
pallet_name: &str,
694696
extrinsic_name: &str,
695697
) -> Option<TransactionIdentifier> {
@@ -730,7 +732,9 @@ pub mod pallet {
730732
))
731733
}
732734

733-
pub(crate) fn config_target(
735+
/// Returns the storage target used to store configuration for the provided identifier,
736+
/// respecting any configured group assignment.
737+
pub fn config_target(
734738
identifier: &TransactionIdentifier,
735739
) -> Result<RateLimitTarget<<T as Config<I>>::GroupId>, DispatchError> {
736740
Self::target_for(identifier, GroupSharing::config_uses_group)

pallets/rate-limiting/src/tx_extension.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ where
3535
T: Config<I> + Send + Sync + TypeInfo,
3636
I: 'static + TypeInfo;
3737

38+
impl<T, I> RateLimitTransactionExtension<T, I>
39+
where
40+
T: Config<I> + Send + Sync + TypeInfo,
41+
I: 'static + TypeInfo,
42+
{
43+
pub fn new() -> Self {
44+
Self(PhantomData)
45+
}
46+
}
47+
3848
impl<T, I> Clone for RateLimitTransactionExtension<T, I>
3949
where
4050
T: Config<I> + Send + Sync + TypeInfo,

runtime/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ frame-try-runtime = { workspace = true, optional = true }
3939
pallet-timestamp.workspace = true
4040
pallet-transaction-payment.workspace = true
4141
pallet-rate-limiting.workspace = true
42+
pallet-rate-limiting-runtime-api.workspace = true
4243
pallet-subtensor-utility.workspace = true
4344
frame-executive.workspace = true
4445
frame-metadata-hash-extension.workspace = true
@@ -189,6 +190,7 @@ std = [
189190
"pallet-transaction-payment-rpc-runtime-api/std",
190191
"pallet-transaction-payment/std",
191192
"pallet-rate-limiting/std",
193+
"pallet-rate-limiting-runtime-api/std",
192194
"pallet-subtensor-utility/std",
193195
"pallet-sudo/std",
194196
"pallet-multisig/std",

runtime/src/lib.rs

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ use frame_support::{
2424
dispatch::DispatchResult,
2525
genesis_builder_helper::{build_state, get_preset},
2626
pallet_prelude::Get,
27-
traits::{Contains, InsideBoth, LinearStoragePrice, fungible::HoldConsideration},
27+
traits::{
28+
Contains, GetCallMetadata, InsideBoth, LinearStoragePrice, fungible::HoldConsideration,
29+
},
2830
};
2931
use frame_system::{EnsureRoot, EnsureRootWithSuccess, EnsureSigned};
3032
use pallet_commitments::{CanCommit, OnMetadataCommitment};
@@ -74,6 +76,8 @@ use subtensor_swap_interface::{Order, SwapHandler};
7476
pub use rate_limiting::{
7577
ScopeResolver as RuntimeScopeResolver, UsageResolver as RuntimeUsageResolver,
7678
};
79+
pub type RateLimitingInstance = ();
80+
pub type RateLimitGroupId = u32;
7781

7882
// A few exports that help ease life for downstream crates.
7983
pub use frame_support::{
@@ -158,6 +162,7 @@ impl frame_system::offchain::CreateSignedTransaction<pallet_drand::Call<Runtime>
158162
frame_system::CheckEra::<Runtime>::from(Era::Immortal),
159163
check_nonce::CheckNonce::<Runtime>::from(nonce).into(),
160164
frame_system::CheckWeight::<Runtime>::new(),
165+
pallet_rate_limiting::RateLimitTransactionExtension::<Runtime>::new(),
161166
ChargeTransactionPaymentWrapper::new(
162167
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
163168
),
@@ -225,10 +230,10 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
225230
// `spec_version`, and `authoring_version` are the same between Wasm and native.
226231
// This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use
227232
// the compatible custom types.
228-
spec_version: 347,
233+
spec_version: 348,
229234
impl_version: 1,
230235
apis: RUNTIME_API_VERSIONS,
231-
transaction_version: 1,
236+
transaction_version: 2,
232237
system_version: 1,
233238
};
234239

@@ -1121,6 +1126,25 @@ impl pallet_subtensor::Config for Runtime {
11211126
type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit;
11221127
}
11231128

1129+
parameter_types! {
1130+
pub const RateLimitingMaxGroupMembers: u32 = 64;
1131+
pub const RateLimitingMaxGroupNameLength: u32 = 64;
1132+
}
1133+
1134+
impl pallet_rate_limiting::Config for Runtime {
1135+
type RuntimeCall = RuntimeCall;
1136+
type AdminOrigin = EnsureRoot<AccountId>;
1137+
type LimitScope = RateLimitScope;
1138+
type LimitScopeResolver = RuntimeScopeResolver;
1139+
type UsageKey = RateLimitUsageKey<AccountId>;
1140+
type UsageResolver = RuntimeUsageResolver;
1141+
type GroupId = u32;
1142+
type MaxGroupMembers = RateLimitingMaxGroupMembers;
1143+
type MaxGroupNameLength = RateLimitingMaxGroupNameLength;
1144+
#[cfg(feature = "runtime-benchmarks")]
1145+
type BenchmarkHelper = ();
1146+
}
1147+
11241148
parameter_types! {
11251149
pub const SwapProtocolId: PalletId = PalletId(*b"ten/swap");
11261150
pub const SwapMaxFeeRate: u16 = 10000; // 15.26%
@@ -1574,6 +1598,7 @@ construct_runtime!(
15741598
Crowdloan: pallet_crowdloan = 27,
15751599
Swap: pallet_subtensor_swap = 28,
15761600
Contracts: pallet_contracts = 29,
1601+
RateLimiting: pallet_rate_limiting = 30,
15771602
}
15781603
);
15791604

@@ -1592,6 +1617,7 @@ pub type TransactionExtensions = (
15921617
frame_system::CheckEra<Runtime>,
15931618
check_nonce::CheckNonce<Runtime>,
15941619
frame_system::CheckWeight<Runtime>,
1620+
pallet_rate_limiting::RateLimitTransactionExtension<Runtime>,
15951621
ChargeTransactionPaymentWrapper<Runtime>,
15961622
pallet_subtensor::transaction_extension::SubtensorTransactionExtension<Runtime>,
15971623
pallet_drand::drand_priority::DrandPriority<Runtime>,
@@ -1610,6 +1636,7 @@ type Migrations = (
16101636
pallet_subtensor::migrations::migrate_init_total_issuance::initialise_total_issuance::Migration<
16111637
Runtime,
16121638
>,
1639+
rate_limiting::migration::Migration<Runtime>,
16131640
// Remove storage from removed governance pallets
16141641
frame_support::migrations::RemovePallet<TriumviratePalletStr, RocksDbWeight>,
16151642
frame_support::migrations::RemovePallet<TriumvirateMembersPalletStr, RocksDbWeight>,
@@ -2162,6 +2189,50 @@ impl_runtime_apis! {
21622189
}
21632190
}
21642191

2192+
impl pallet_rate_limiting_runtime_api::RateLimitingRuntimeApi<Block> for Runtime {
2193+
fn get_rate_limit(
2194+
pallet: Vec<u8>,
2195+
extrinsic: Vec<u8>,
2196+
) -> Option<pallet_rate_limiting_runtime_api::RateLimitRpcResponse> {
2197+
use pallet_rate_limiting::{Pallet as RateLimiting, RateLimit};
2198+
use pallet_rate_limiting_runtime_api::RateLimitRpcResponse;
2199+
2200+
let pallet_name = sp_std::str::from_utf8(&pallet).ok()?;
2201+
let extrinsic_name = sp_std::str::from_utf8(&extrinsic).ok()?;
2202+
2203+
let identifier = RateLimiting::<Runtime, RateLimitingInstance>::identifier_for_call_names(
2204+
pallet_name,
2205+
extrinsic_name,
2206+
)?;
2207+
let target =
2208+
RateLimiting::<Runtime, RateLimitingInstance>::config_target(&identifier).ok()?;
2209+
let limits =
2210+
pallet_rate_limiting::Limits::<Runtime, RateLimitingInstance>::get(target)?;
2211+
let default_limit =
2212+
pallet_rate_limiting::DefaultLimit::<Runtime, RateLimitingInstance>::get();
2213+
let resolved =
2214+
RateLimiting::<Runtime, RateLimitingInstance>::resolved_limit(&target, &None);
2215+
2216+
let (global, contextual) = match limits {
2217+
RateLimit::Global(kind) => (Some(kind), sp_std::vec::Vec::new()),
2218+
RateLimit::Scoped(entries) => (
2219+
None,
2220+
entries
2221+
.into_iter()
2222+
.map(|(scope, kind)| (scope.encode(), kind))
2223+
.collect(),
2224+
),
2225+
};
2226+
2227+
Some(RateLimitRpcResponse {
2228+
global,
2229+
contextual,
2230+
default_limit,
2231+
resolved,
2232+
})
2233+
}
2234+
}
2235+
21652236
impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord>
21662237
for Runtime
21672238
{

0 commit comments

Comments
 (0)