PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/moul/x/daily/ratelimitdemo/v0

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v0
Namespace
moul / x / daily / ratelimitdemo
Files
3 (README)(gnomod.toml)
Exported functions
4
Module
gno.land/r/moul/x/daily/ratelimitdemo/v0
gno
0.9

Files (3)

  • README.mdmarkdown
  • gnomod.tomltoml
  • ratelimitdemo.gnogno
ratelimitdemo.gnogno
1// Package ratelimitdemo is a small on-chain demo of the token-bucket rate2// limiter provided by the [p/moul/x/daily/ratelimit](/p/moul/x/daily/ratelimit/v0)3// library.4//5// It holds a single package-level [ratelimit.Limiter] and wires it to the6// chain: the tick is runtime.ChainHeight() and each caller is keyed by its7// address (unsafe.PreviousRealm().Address()). It contains no limiter logic of8// its own — refill/consume math all lives in the library.9package ratelimitdemo1011import (12	"strconv"1314	"chain/runtime"15	"chain/runtime/unsafe"1617	"gno.land/p/moul/x/daily/ratelimit/v0"18)1920// limiter starts at 0.5 tokens/block (one every two blocks), capacity 5.21var limiter = ratelimit.New(0.5, 5.0)2223// Allow consumes one token for the calling realm/user at the current block24// height and reports whether the request is permitted. Returns false (and25// consumes nothing) when the caller's bucket is empty.26func Allow(cur realm) bool {27	addr := unsafe.PreviousRealm().Address()28	return limiter.Allow(string(addr), runtime.ChainHeight())29}3031// SetConfig updates the shared rate (tokens per block) and burst (capacity).32// rate is clamped to >= 0, burst to >= 1.33func SetConfig(cur realm, rate, burst float64) {34	limiter.SetConfig(rate, burst)35}3637// Tokens reports how many whole tokens `addr` has available at the current38// block height, without mutating any state.39func Tokens(addr address) int {40	return limiter.Tokens(string(addr), runtime.ChainHeight())41}4243// --- rendering --------------------------------------------------------------4445func ftoa(f float64) string { return strconv.FormatFloat(f, 'g', -1, 64) }4647// Render shows the limiter config and a table of known callers with their48// current tokens and last-seen height. Path "/addr/<address>" focuses one49// caller.50func Render(path string) string {51	now := runtime.ChainHeight()52	rate, burst := limiter.Config()5354	if len(path) > 6 && path[:6] == "/addr/" {55		key := path[6:]56		out := "# Rate Limiter — caller\n\n"57		out += "Address: `" + key + "`\n\n"58		out += "- Current tokens: **" + strconv.Itoa(limiter.Tokens(key, now)) + "** / " + ftoa(burst) + "\n"59		out += "- Now (height): " + strconv.FormatInt(now, 10) + "\n"60		return out61	}6263	out := "# Rate Limiter\n\n"64	out += "Demo of the [`p/moul/x/daily/ratelimit`](/p/moul/x/daily/ratelimit/v0) library — "65	out += "an on-chain token-bucket limiter (port of `golang.org/x/time/rate`).\n\n"66	out += "## Config\n\n"67	out += "| Parameter | Value |\n|---|---|\n"68	out += "| Rate (tokens/block) | " + ftoa(rate) + " |\n"69	out += "| Burst (capacity) | " + ftoa(burst) + " |\n"70	out += "| Clock height | " + strconv.FormatInt(now, 10) + " |\n\n"7172	out += "## Callers\n\n"73	if limiter.Len() == 0 {74		out += "_No caller has hit the limiter yet._\n\n"75	} else {76		out += "| Address | Tokens | Last height |\n|---|---|---|\n"77		limiter.Iterate(now, func(key string, tokens int, last int64) bool {78			out += "| `" + key + "` | " + strconv.Itoa(tokens) +79				" | " + strconv.FormatInt(last, 10) + " |\n"80			return false81		})82		out += "\n"83	}8485	out += "---\n"86	out += "Call `Allow(cur)` to consume a token; read `Tokens(addr)` for a caller's balance.\n"87	return out88}89

Functions

  • Allow(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}) bool

  • Render(path string) string

  • SetConfig(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, rate float64, burst float64)

  • Tokens(addr string) int

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.