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

v3 source realm

Package validators implements on-chain validator set management through Proof of Authority. The realm exposes a publi...

Overview

Package validators implements on-chain validator set management through Proof of Authority. The realm exposes a public proposal constructor for GovDAO; on approval, the proposal callback applies the captured deltas to the chain's effective valset and publishes the new full set via gno.land/r/sys/params. The chain's EndBlocker reads the result on the next block and propagates to consensus.

No in-realm validator state. All reads go through sysparams.GetValsetEffective (proposed-if-dirty, else current).

Functions 9

func AssertGenesisValopersConsistent

crossing Action
1func AssertGenesisValopersConsistent(cur realm)
source

AssertGenesisValopersConsistent panics if any entry in valset:current (the seeded genesis valset) lacks a corresponding valoperCache profile whose SigningAddress matches.

**Genesis-mode only.** The function refuses to run unless runtime.ChainHeight() == 0. This is the documented intended usage (last migration .jsonl tx, before any block has been produced) and also closes a post-genesis MsgCall DoS surface — without the guard, an attacker could pay gas to repeatedly invoke an O(N) iteration over valoperCache + valset:current after the chain is live.

gnoland's InitChainer auto-runs this assertion at end of genesis-mode replay when GnoGenesisState.PastChainIDs is non-empty; failure aborts the boot unconditionally. valoper-seed and hand-crafted migration .jsonls do NOT need to emit the call themselves.

Crossing function: callable via MsgCall (only at genesis-mode). Doesn't mutate state — pure invariant check. Inverse direction (every valoperCache entry must have a corresponding valset:current entry) is intentionally NOT checked: extra valoper profiles registered without immediate valset inclusion are a normal post-genesis state.

func GetValidator

Action
1func GetValidator(addr address) validators.Validator
source

GetValidator returns the validator with the given address from the effective set; panics if absent.

func IsValidator

Action
1func IsValidator(addr address) bool
source

IsValidator returns true if addr is part of the effective validator set (proposed if a v3 proposal is awaiting EndBlocker, else current).

func NewValidatorProposalRequest

crossing Action
1func NewValidatorProposalRequest(cur realm, changes []ValoperChange, title, description string) dao.ProposalRequest
source

NewValidatorProposalRequest builds a GovDAO proposal that, when executed, applies the deltas to the chain's effective valset and publishes the new full set via SetValsetProposal.

NON-CROSSING (no `cur realm`). Direct MsgCall is unsupported; proposers route through r/gnops/valopers/proposal's facade (which IS crossing and accepts user txs).

Validation at creation time:

  • Each operator may appear AT MOST ONCE in changes; duplicates panic. Power changes for an op already in the active set use a single {op, newPower} entry (upsert), not the legacy remove/re-add pair.
  • Every ValoperChange's OperatorAddress must exist in valoperCache. Unknown operators panic.
  • Adds (Power > 0) require KeepRunning=true. An op that has called UpdateKeepRunning(false) signals opt-out; no proposal can keep them in the active set, period.

Pubkey resolution at execution time: the executor callback re-reads valoperCache for each entry to capture the CURRENT signing pubkey/address — not the creation-time one. Defends against a stale (now-retired) key publication if the operator rotated while the proposal sat in GovDAO. Also re-checks KeepRunning so an operator flipping to KeepRunning=false between propose-create and propose-execute is honored. Removes are unaffected (operator address is the lookup key, not signing address).

Emits ValidatorAdded / ValidatorRemoved events per entry on successful execution. (Power-upsert on an existing op also emits ValidatorAdded with the new power.)

func NotifyValoperChanged

crossing Action
1func NotifyValoperChanged(cur realm, op address, signingPubKey string, signingAddress address, keepRunning bool)
source

NotifyValoperChanged refreshes the cached entry for op. Auth: caller realm must be r/gnops/valopers.

READ-ONLY against valopers: by design this function does not call back into valopers (no pull). Valopers pushes the current values in as args. This eliminates the confused-deputy class where v3 → valopers callbacks would make valopers see v3 as PreviousRealm.

func Render

1func Render(string) string
source

Render displays the effective validator set.

func RotateValoperSigningKey

crossing Action
1func RotateValoperSigningKey(cur realm, op address, oldPubKey, newPubKey string)
source

RotateValoperSigningKey applies a signing-key rotation to the effective valset and publishes the new full set via sysparams. Auth: caller realm must be r/gnops/valopers.

Body is read-modify-write against sysparams.GetValsetEffective so concurrent same-block writers (other rotations or GovDAO executors) accumulate instead of clobbering. Mirrors the executor pattern in validators.gno.

Idempotent: if the rotating operator's old signing address is not currently in the effective valset (e.g., they were removed), the rotation is a no-op at the sysparams level — valopers' profile and signingRegistry already record the new key. Either replays cleanly.

Emits ValoperRotated event with op + old/new addresses + height.

Types 1

type ValoperChange

struct
1type ValoperChange struct {
2	OperatorAddress address
3	Power           uint64
4}
source

ValoperChange is the operator-keyed input shape for the v3 valset proposal builder. Power=0 removes; Power>0 adds (or upserts the power on an op already in the active set — Tendermint's natural ValidatorUpdate semantics).

Each operator may appear AT MOST ONCE per proposal; duplicates are rejected at create-time.

Imports 10

Source Files 7