admin

package
v0.4.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 15, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package admin implements the server directory, validator registration, and health monitoring services. It runs as an optional in-process component inside the svoted binary, backed by a local SQLite database.

This package replaces the Vercel Edge functions that previously managed the server fleet via Vercel Edge Config.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddressToValoper

func AddressToValoper(address string) (string, error)

AddressToValoper converts an account bech32 address to a valoper address.

func RegisterRoutes

func RegisterRoutes(
	router *mux.Router,
	getAdmin func() *Admin,
	logger log.Logger,
)

RegisterRoutes registers admin HTTP routes on the given mux router. Getters are used so routes can be mounted before the admin server is fully initialized (same pattern as the helper server).

func RunHealthProber

func RunHealthProber(ctx context.Context, store *Store, interval time.Duration, logger log.Logger)

RunHealthProber periodically probes each approved server and removes unreachable ones. This replaces the Vercel health-check-servers cron.

func RunStaleEvictor

func RunStaleEvictor(ctx context.Context, store *Store, interval time.Duration, staleThreshold int, logger log.Logger)

RunStaleEvictor periodically removes pulse entries older than the threshold. This replaces the Vercel evict-stale-servers cron.

func VerifyArbitrarySignature

func VerifyArbitrarySignature(signerAddress, payload string, signatureB64, pubKeyB64 string) error

VerifyArbitrarySignature verifies a Keplr-style ADR-036 signArbitrary signature. It checks that:

  1. The secp256k1 signature is valid over the amino sign doc.
  2. The public key derives to the claimed signer address.

Types

type Admin

type Admin struct {
	Store          *Store
	AdminAddress   string
	StaleThreshold int
	PIRServers     []ServiceEntry
	CheckBonding   BondingChecker
	GetVoteManager VoteManagerGetter
	Logger         log.Logger
}

Admin manages the server directory lifecycle.

func New

func New(cfg Config, checkBonding BondingChecker, getVoteManager VoteManagerGetter, homeDir string, logger log.Logger) (*Admin, error)

New creates a new Admin from the given configuration.

func (*Admin) Close

func (a *Admin) Close() error

Close shuts down the admin server and releases resources.

func (*Admin) Start

func (a *Admin) Start(ctx context.Context, cfg Config) error

Start launches the background monitor goroutines. It blocks until the context is cancelled.

type BondingChecker

type BondingChecker func(valoperAddress string) bool

BondingChecker returns true if the given valoper address is a bonded validator.

type Config

type Config struct {
	// Disable turns off the admin server entirely.
	Disable bool `mapstructure:"disable"`

	// DBPath is the path to the SQLite database file.
	DBPath string `mapstructure:"db_path"`

	// AdminAddress is the bech32 address of the bootstrap admin authorized
	// to approve/reject pending validator registrations. When empty, the
	// approve-registration endpoint returns 403 for all callers.
	AdminAddress string `mapstructure:"admin_address"`

	// ProbeInterval is how often to probe vote servers for health (seconds).
	ProbeInterval int `mapstructure:"probe_interval"`

	// EvictInterval is how often to check for stale server pulses (seconds).
	EvictInterval int `mapstructure:"evict_interval"`

	// StaleThreshold is how long a server can go without a pulse before
	// being excluded from the voting-config response (seconds).
	StaleThreshold int `mapstructure:"stale_threshold"`

	// PIRServers is the JSON-encoded list of PIR server entries included
	// in the voting-config response. Read from app.toml; wallets need this
	// alongside the dynamic vote_servers list.
	PIRServers string `mapstructure:"pir_servers"`
}

Config holds the admin server configuration, read from app.toml admin.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default admin configuration.

type PendingRegistration

type PendingRegistration struct {
	OperatorAddress string `json:"operator_address"`
	URL             string `json:"url"`
	Moniker         string `json:"moniker"`
	Timestamp       int64  `json:"timestamp"`
	Signature       string `json:"signature"`
	PubKey          string `json:"pub_key"`
	ExpiresAt       int64  `json:"expires_at"`
}

PendingRegistration is the wire format for a pending validator registration.

type ServiceEntry

type ServiceEntry struct {
	URL             string `json:"url"`
	Label           string `json:"label"`
	OperatorAddress string `json:"operator_address,omitempty"`
}

ServiceEntry is the wire format for a server in the voting-config response.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store is a SQLite-backed store for the admin server's state: approved servers, pending registrations, and heartbeat pulses.

func NewStore

func NewStore(dbPath string) (*Store, error)

NewStore opens (or creates) a SQLite database and runs migrations.

func (*Store) BuildVotingConfig

func (s *Store) BuildVotingConfig(pirServers []ServiceEntry) (*VotingConfig, error)

BuildVotingConfig assembles the voting-config response from approved servers that have a pulse (or were recently approved). Servers without a pulse are still included — the health prober will remove truly dead ones.

func (*Store) CleanPendingByOperator

func (s *Store) CleanPendingByOperator(operatorAddress, url string) error

CleanPendingByOperator removes pending registrations matching the given operator address or URL.

func (*Store) Close

func (s *Store) Close() error

Close closes the underlying database.

func (*Store) EvictStalePulses

func (s *Store) EvictStalePulses(staleThresholdSecs int) ([]string, error)

EvictStalePulses removes pulse entries older than the threshold and returns the URLs that were evicted.

func (*Store) GetPulses

func (s *Store) GetPulses() (map[string]int64, error)

GetPulses returns all pulse entries as a map of url -> timestamp.

func (*Store) IsApproved

func (s *Store) IsApproved(operatorAddress string) (bool, error)

IsApproved returns true if the given operator address is in the approved list.

func (*Store) ListApprovedServers

func (s *Store) ListApprovedServers() ([]ServiceEntry, error)

ListApprovedServers returns all approved server entries.

func (*Store) ListPendingRegistrations

func (s *Store) ListPendingRegistrations() ([]PendingRegistration, error)

ListPendingRegistrations returns non-expired pending registrations.

func (*Store) RemoveApprovedServer

func (s *Store) RemoveApprovedServer(operatorAddress string) (removedURL string, err error)

RemoveApprovedServer removes an approved server by operator address. Returns the removed entry's URL (empty if not found).

func (*Store) RemovePendingRegistration

func (s *Store) RemovePendingRegistration(operatorAddress string) (*PendingRegistration, error)

RemovePendingRegistration removes a pending registration by operator address. Returns the entry if found, or nil if not found.

func (*Store) RemovePulse

func (s *Store) RemovePulse(url string) error

RemovePulse removes a pulse entry by URL.

func (*Store) UpsertApprovedServer

func (s *Store) UpsertApprovedServer(e ServiceEntry) error

UpsertApprovedServer inserts or replaces an approved server entry.

func (*Store) UpsertPendingRegistration

func (s *Store) UpsertPendingRegistration(r PendingRegistration) error

UpsertPendingRegistration inserts or replaces a pending registration.

func (*Store) UpsertPulse

func (s *Store) UpsertPulse(url string, pulseAt int64) error

UpsertPulse records a heartbeat timestamp for a server URL.

type VoteManagerGetter

type VoteManagerGetter func() string

VoteManagerGetter returns the current vote-manager bech32 address, or empty.

type VotingConfig

type VotingConfig struct {
	Version     int            `json:"version"`
	VoteServers []ServiceEntry `json:"vote_servers"`
	PIRServers  []ServiceEntry `json:"pir_servers"`
}

VotingConfig is the wire format returned by GET /api/voting-config.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL