Skip to content

Commit 840362b

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

File tree

6 files changed

+262
-115
lines changed

6 files changed

+262
-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: 0 additions & 1 deletion
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 {

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: 104 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,80 @@ 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::{
2198+
RateLimit, RateLimitKind, RateLimitTarget, TransactionIdentifier,
2199+
};
2200+
use pallet_rate_limiting_runtime_api::RateLimitRpcResponse;
2201+
2202+
let pallet_name = sp_std::str::from_utf8(&pallet).ok()?;
2203+
let extrinsic_name = sp_std::str::from_utf8(&extrinsic).ok()?;
2204+
2205+
let pallet_index = u8::try_from(
2206+
RuntimeCall::get_module_names()
2207+
.iter()
2208+
.position(|name| *name == pallet_name)?,
2209+
)
2210+
.ok()?;
2211+
let extrinsic_index = u8::try_from(
2212+
RuntimeCall::get_call_names(pallet_name)
2213+
.iter()
2214+
.position(|name| *name == extrinsic_name)?,
2215+
)
2216+
.ok()?;
2217+
2218+
let identifier = TransactionIdentifier::new(pallet_index, extrinsic_index);
2219+
let target = if let Some(group_id) =
2220+
pallet_rate_limiting::CallGroups::<Runtime>::get(identifier)
2221+
{
2222+
let uses_group = pallet_rate_limiting::Groups::<Runtime>::get(
2223+
group_id,
2224+
)
2225+
.map(|details| details.sharing.config_uses_group())
2226+
.unwrap_or(false);
2227+
2228+
if uses_group {
2229+
RateLimitTarget::Group(group_id)
2230+
} else {
2231+
RateLimitTarget::Transaction(identifier)
2232+
}
2233+
} else {
2234+
RateLimitTarget::Transaction(identifier)
2235+
};
2236+
2237+
let limits =
2238+
pallet_rate_limiting::Limits::<Runtime>::get(target)?;
2239+
let default_limit =
2240+
pallet_rate_limiting::DefaultLimit::<Runtime>::get();
2241+
let resolved = limits.kind_for(None).map(|kind| match *kind {
2242+
RateLimitKind::Default => default_limit,
2243+
RateLimitKind::Exact(span) => span,
2244+
});
2245+
2246+
let (global, contextual) = match limits {
2247+
RateLimit::Global(kind) => (Some(kind), sp_std::vec::Vec::new()),
2248+
RateLimit::Scoped(entries) => (
2249+
None,
2250+
entries
2251+
.into_iter()
2252+
.map(|(scope, kind)| (scope.encode(), kind))
2253+
.collect(),
2254+
),
2255+
};
2256+
2257+
Some(RateLimitRpcResponse {
2258+
global,
2259+
contextual,
2260+
default_limit,
2261+
resolved,
2262+
})
2263+
}
2264+
}
2265+
21652266
impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord>
21662267
for Runtime
21672268
{

0 commit comments

Comments
 (0)