PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

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/timelock/v0

Realm
Open in gnoweb ↗

Overview

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

Files (3)

  • README.mdmarkdown
  • gnomod.tomltoml
  • timelock.gnogno
timelock.gnogno
1// Package timelock is a simplified port of OpenZeppelin's TimelockController.2//3// Operations are scheduled with a delay (measured in blocks). A scheduled4// operation becomes executable only once the chain height reaches the5// operation's ready height. Until then it can be cancelled by anyone (this6// simplified port omits role-based access control). Once executed or7// cancelled, an operation is terminal.8//9// Solidity mapping:10//   - block.number      -> runtime.ChainHeight()11//   - msg.sender        -> unsafe.PreviousRealm().Address()12//   - require(...)       -> panic(...)13//   - events            -> chain.Emit(...)14//   - mapping(id => op) -> avl.Tree keyed by zero-padded id15package timelock1617import (18	"strconv"1920	"chain"21	"chain/runtime"22	"chain/runtime/unsafe"2324	"gno.land/p/nt/avl/v0"25	"gno.land/p/nt/ufmt/v0"26)2728// State labels for an operation.29const (30	StatePending   = "Pending"   // scheduled, not yet ready31	StateReady     = "Ready"     // ready height reached, awaiting execution32	StateExecuted  = "Executed"  // terminal33	StateCancelled = "Cancelled" // terminal34)3536// Operation is a single scheduled action.37type Operation struct {38	ID          int39	Action      string40	Proposer    address41	Scheduled   int64 // chain height at scheduling42	ReadyHeight int64 // executable once ChainHeight() >= ReadyHeight43	Done        bool  // executed44	Cancelled   bool45}4647var (48	ops    = avl.NewTree() // key: paddedKey(id) -> *Operation49	nextID = 150)5152// Schedule registers a new operation to run after delayBlocks blocks and53// returns its id. delayBlocks must be >= 0.54func Schedule(cur realm, action string, delayBlocks int) int {55	if action == "" {56		panic("timelock: empty action")57	}58	if delayBlocks < 0 {59		panic("timelock: negative delay")60	}6162	h := runtime.ChainHeight()63	id := nextID64	nextID++6566	op := &Operation{67		ID:          id,68		Action:      action,69		Proposer:    unsafe.PreviousRealm().Address(),70		Scheduled:   h,71		ReadyHeight: h + int64(delayBlocks),72	}73	ops.Set(paddedKey(id), op)7475	chain.Emit("Scheduled",76		"id", strconv.Itoa(id),77		"action", action,78		"readyHeight", strconv.FormatInt(op.ReadyHeight, 10),79	)80	return id81}8283// Execute runs a ready operation. It panics if the operation is unknown,84// already terminal, or not yet ready.85func Execute(cur realm, id int) {86	op := mustGet(id)87	if op.Done {88		panic("timelock: already executed")89	}90	if op.Cancelled {91		panic("timelock: operation cancelled")92	}93	if runtime.ChainHeight() < op.ReadyHeight {94		panic("timelock: operation not ready")95	}96	op.Done = true9798	chain.Emit("Executed", "id", strconv.Itoa(id), "action", op.Action)99}100101// Cancel drops a pending or ready operation before it executes. It panics if102// the operation is unknown or already terminal.103func Cancel(cur realm, id int) {104	op := mustGet(id)105	if op.Done {106		panic("timelock: already executed")107	}108	if op.Cancelled {109		panic("timelock: already cancelled")110	}111	op.Cancelled = true112113	chain.Emit("Cancelled", "id", strconv.Itoa(id), "action", op.Action)114}115116// mustGet returns the operation or panics if absent.117func mustGet(id int) *Operation {118	v := ops.Get(paddedKey(id))119	if v == nil {120		panic("timelock: unknown operation")121	}122	return v.(*Operation)123}124125// --- pure/read-only helpers (safe to unit-test) ---126127// paddedKey returns a fixed-width, lexicographically sortable key for an id so128// avl iteration yields operations in id order.129func paddedKey(id int) string {130	s := strconv.Itoa(id)131	for len(s) < 12 {132		s = "0" + s133	}134	return s135}136137// StateOf returns the display state of op at the given chain height.138func StateOf(op *Operation, height int64) string {139	switch {140	case op.Cancelled:141		return StateCancelled142	case op.Done:143		return StateExecuted144	case height >= op.ReadyHeight:145		return StateReady146	default:147		return StatePending148	}149}150151// BlocksRemaining returns how many blocks remain before op is ready (0 if152// already ready or past).153func BlocksRemaining(op *Operation, height int64) int64 {154	if height >= op.ReadyHeight {155		return 0156	}157	return op.ReadyHeight - height158}159160// Render implements the standard realm markdown view.161func Render(path string) string {162	h := runtime.ChainHeight()163	out := "# Timelock Controller\n\n"164	out += ufmt.Sprintf("Current chain height: **%d**\n\n", h)165166	if ops.Size() == 0 {167		out += "_No operations scheduled yet._\n\n"168		out += "Call `Schedule(action, delayBlocks)` to queue one.\n"169		return out170	}171172	out += ufmt.Sprintf("Total operations: **%d**\n\n", ops.Size())173	out += "| ID | Action | State | Ready @ | Blocks left | Proposer |\n"174	out += "|---:|--------|-------|--------:|------------:|----------|\n"175176	ops.Iterate("", "", func(_ string, v any) bool {177		op := v.(*Operation)178		state := StateOf(op, h)179		left := BlocksRemaining(op, h)180		out += ufmt.Sprintf("| %d | %s | %s | %d | %d | %s |\n",181			op.ID, op.Action, state, op.ReadyHeight, left, op.Proposer.String())182		return false183	})184	return out185}186

Functions

  • BlocksRemaining(op *gno.land/r/moul/x/daily/timelock/v0.Operation, height int64) int64

  • Cancel(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}, id int)

  • Execute(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}, id int)

  • Render(path string) string

  • Schedule(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}, action string, delayBlocks int) int

  • StateOf(op *gno.land/r/moul/x/daily/timelock/v0.Operation, height int64) string

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.