-
Notifications
You must be signed in to change notification settings - Fork 301
/
Copy pathrate_limit.rs
63 lines (51 loc) · 1.59 KB
/
rate_limit.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use frame_support::Parameter;
use parity_scale_codec::Encode;
use sp_runtime::{traits::Member, RuntimeDebug};
#[derive(PartialEq, Eq, RuntimeDebug)]
pub enum RateLimiterError {
ExceedLimit,
}
/// Rate Limiter
pub trait RateLimiter {
/// The type for the rate limiter.
type RateLimiterId: Parameter + Member + Copy;
/// Check whether the rate limiter of can be bypassed according to the
/// `key`.
fn is_whitelist(limiter_id: Self::RateLimiterId, key: impl Encode) -> bool;
/// Check whether the `value` can be consumed under the limit of
/// `limit_key`.
fn can_consume(
limiter_id: Self::RateLimiterId,
limit_key: impl Encode,
value: u128,
) -> Result<(), RateLimiterError>;
/// The handler function to consume quota.
fn consume(limiter_id: Self::RateLimiterId, limit_key: impl Encode, value: u128);
/// Try consume quota.
fn try_consume(
limiter_id: Self::RateLimiterId,
limit_key: impl Encode + Clone,
value: u128,
whitelist_check: Option<impl Encode>,
) -> Result<(), RateLimiterError> {
let need_consume = match whitelist_check {
Some(whitelist_key) => !Self::is_whitelist(limiter_id, whitelist_key),
None => true,
};
if need_consume {
Self::can_consume(limiter_id, limit_key.clone(), value)?;
Self::consume(limiter_id, limit_key, value);
}
Ok(())
}
}
impl RateLimiter for () {
type RateLimiterId = ();
fn is_whitelist(_: Self::RateLimiterId, _: impl Encode) -> bool {
true
}
fn can_consume(_: Self::RateLimiterId, _: impl Encode, _: u128) -> Result<(), RateLimiterError> {
Ok(())
}
fn consume(_: Self::RateLimiterId, _: impl Encode, _: u128) {}
}