Skip to content

rate_limiter - [mainnet]

use 0x1::timestamp;

Enum Resource RateLimiter

enum RateLimiter has copy, drop, store, key
Variants
TokenBucket
Fields
capacity: u64
current_amount: u64
refill_interval: u64
last_refill_timestamp: u64
fractional_accumulated: u64

Functions

initialize

public fun initialize(capacity: u64, refill_interval: u64): rate_limiter::RateLimiter
Implementation
public fun initialize(capacity: u64, refill_interval: u64): RateLimiter {
RateLimiter::TokenBucket {
capacity,
current_amount: capacity, // Start with a full bucket (full capacity of transactions allowed)
refill_interval,
last_refill_timestamp: timestamp::now_seconds(),
fractional_accumulated: 0, // Start with no fractional accumulated
}
}

request

public fun request(limiter: &mut rate_limiter::RateLimiter, num_token_requested: u64): bool
Implementation
public fun request(limiter: &mut RateLimiter, num_token_requested: u64): bool {
refill(limiter);
if (limiter.current_amount >= num_token_requested) {
limiter.current_amount = limiter.current_amount - num_token_requested;
true
} else {
false
}
}

refill

fun refill(limiter: &mut rate_limiter::RateLimiter)
Implementation
fun refill(limiter: &mut RateLimiter) {
let current_time = timestamp::now_seconds();
let time_passed = current_time - limiter.last_refill_timestamp;
// Calculate the full tokens that can be added
let accumulated_amount = time_passed * limiter.capacity + limiter.fractional_accumulated;
let new_tokens = accumulated_amount / limiter.refill_interval;
if (limiter.current_amount + new_tokens >= limiter.capacity) {
limiter.current_amount = limiter.capacity;
limiter.fractional_accumulated = 0;
} else {
limiter.current_amount = limiter.current_amount + new_tokens;
// Update the fractional amount accumulated for the next refill cycle
limiter.fractional_accumulated = accumulated_amount % limiter.refill_interval;
};
limiter.last_refill_timestamp = current_time;
}