Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package ratelimit is a deterministic token-bucket rate limiter — a port of golang.org/x/time/rate with the wall clock...

Readme View source

gno.land/p/moul/x/daily/ratelimit/v0

Deterministic token-bucket rate limiter — a port of golang.org/x/time/rate with the wall clock replaced by a caller-supplied monotonic tick (on-chain, the block height).

A Limiter owns a set of per-key token buckets sharing one rate/burst config. Each bucket refills at rate tokens per tick up to burst; the caller picks what a key is (typically an address) and passes the current tick on every call. Pure integer/float math over persistent avl state — no chain imports, no ambient state, fully replayable.

1import "gno.land/p/moul/x/daily/ratelimit/v0"
2
3l := ratelimit.New(0.5, 5.0)     // 0.5 tokens/tick, capacity 5
4l.Allow("g1caller", height)      // consume one token; false if empty
5l.AllowN("g1caller", height, 3)  // consume 3 atomically; false if <3
6l.Tokens("g1caller", height)     // read-only balance (whole tokens)

Live demo: r/moul/x/daily/ratelimitdemo · render it at /r/moul/x/daily/ratelimitdemo/v0.


Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

Dependency graph:

gno.land/p/moul/x/daily/ratelimit/v0 dependency graph

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.

Overview

Package ratelimit is a deterministic token-bucket rate limiter — a port of golang.org/x/time/rate with the wall clock replaced by a caller-supplied monotonic tick (on-chain, that tick is the block height).

It is a pure library: it imports no chain APIs and reads no ambient state. A Limiter owns a set of per-key token buckets sharing one rate/burst config; the caller decides what a key is (typically an address string) and supplies the current tick on every call. Between two observations at ticks `last` and `now`, a bucket gains (now-last)*rate tokens, capped at `burst`. Everything is integer/float arithmetic over persistent avl state, hence deterministic and replayable.

A realm wires it up by holding a *Limiter in a package-level var and feeding it runtime.ChainHeight() as the tick. For a complete, live example see the demo realm r/moul/x/daily/ratelimitdemo(/r/moul/x/daily/ratelimitdemo/v0).

Functions 1

func New

1func New(rate, burst float64) *Limiter
source

New returns a Limiter replenishing `rate` tokens per tick, each bucket capped at `burst`. rate is clamped to >= 0, burst to >= 1.

Types 1

type Limiter

struct
1type Limiter struct {
2	rate    float64   // tokens replenished per tick
3	burst   float64   // bucket capacity (max tokens, largest single burst)
4	buckets *avl.Tree // key string -> *bucket, ordered by key (deterministic)
5}
source

Limiter is a set of per-key token buckets sharing one rate/burst config. The zero value is not usable; construct one with New.

Methods on Limiter

func Allow

method on Limiter
1func (l *Limiter) Allow(key string, now int64) bool
source

Allow consumes one token for `key` at tick `now` and reports whether the request is permitted. When the bucket is empty it returns false and consumes nothing. Equivalent to AllowN(key, now, 1).

func AllowN

method on Limiter
1func (l *Limiter) AllowN(key string, now int64, n float64) bool
source

AllowN consumes `n` tokens for `key` at tick `now` and reports whether the request is permitted. When fewer than `n` tokens are available it returns false and consumes nothing. A key is seen for the first time with a full bucket of `burst` tokens.

func Config

method on Limiter
1func (l *Limiter) Config() (rate, burst float64)
source

Config returns the current rate (tokens/tick) and burst (capacity).

func Iterate

method on Limiter
1func (l *Limiter) Iterate(now int64, fn func(key string, tokens int, last int64) bool) bool
source

Iterate calls fn for every known key in ascending order, passing the whole tokens available at tick `now` and the last tick the key was observed. Returning true from fn stops the iteration early; Iterate reports whether it was stopped that way.

func Len

method on Limiter
1func (l *Limiter) Len() int
source

Len returns the number of keys the limiter has seen.

func SetConfig

method on Limiter
1func (l *Limiter) SetConfig(rate, burst float64)
source

SetConfig updates the shared rate and burst. rate is clamped to >= 0, burst to >= 1. Existing buckets keep their stored tokens; the new config applies from the next refill.

func Tokens

method on Limiter
1func (l *Limiter) Tokens(key string, now int64) int
source

Tokens is a read-only view of how many whole tokens `key` has available at tick `now`, without mutating any state.

Imports 1

Source Files 3