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

proposal.gno

3.88 Kb · 103 lines
  1package proposal
  2
  3import (
  4	"errors"
  5
  6	"gno.land/p/nt/ufmt/v0"
  7	valopers "gno.land/r/gnops/valopers"
  8	"gno.land/r/gov/dao"
  9	sysparams "gno.land/r/sys/params"
 10	validators "gno.land/r/sys/validators/v0"
 11)
 12
 13var (
 14	ErrValidatorMissing = errors.New("the validator is missing")
 15	ErrSameValues       = errors.New("the valoper has the same voting power and pubkey")
 16)
 17
 18// NewValidatorProposalRequest creates a proposal request to the GovDAO
 19// for adding (or removing) the given valoper to/from the validator set.
 20//
 21// Signature is preserved for historical-replay compatibility (gnoland-1
 22// callers call this with a single address). Body is rewired to call
 23// v0's operator-keyed NewValidatorProposalRequest with a single-element
 24// slice; v0's executor re-resolves the signing pubkey from valoperCache
 25// at execution time, so a mid-flight rotation publishes the current key.
 26func NewValidatorProposalRequest(cur realm, addr address) dao.ProposalRequest {
 27	var (
 28		valoper     = valopers.GetByAddr(addr)
 29		votingPower = uint64(1)
 30	)
 31
 32	exist := validators.IsValidator(valoper.SigningAddress)
 33
 34	// Determine the voting power
 35	if !valoper.KeepRunning {
 36		if !exist {
 37			panic(ErrValidatorMissing)
 38		}
 39		votingPower = uint64(0)
 40	}
 41
 42	if exist {
 43		validator := validators.GetValidator(valoper.SigningAddress)
 44		if validator.VotingPower == votingPower && validator.PubKey == valoper.SigningPubKey {
 45			panic(ErrSameValues)
 46		}
 47	}
 48
 49	// Craft the proposal title and description, framed around the
 50	// valoper profile. Voters see the operator identity (moniker +
 51	// operator address); the signing key is an implementation detail
 52	// resolved at execution time by v0's executor.
 53	title := ufmt.Sprintf(
 54		"Add valoper %s to the valset",
 55		valoper.Moniker,
 56	)
 57
 58	description := ufmt.Sprintf("Valoper profile: [%s](/r/gnops/valopers:%s)\n\n%s",
 59		valoper.Moniker,
 60		valoper.OperatorAddress,
 61		valoper.Render(),
 62	)
 63
 64	return validators.NewValidatorProposalRequest(cross(cur),
 65		[]validators.ValoperChange{validators.NewValoperChange(valoper.OperatorAddress, votingPower)},
 66		title,
 67		description,
 68	)
 69}
 70
 71// ProposeNewInstructionsProposalRequest creates a proposal to the GovDAO
 72// for updating the realm instructions.
 73//
 74// Signature is preserved; the body now delegates. Building the request
 75// here required valopers to export the privileged closure, which handed
 76// this realm's frame identity to any caller. The
 77// closure and the request are now built inside valopers, which returns
 78// the request with its executor sealed — see valopers.NewInstructionsProposalRequest.
 79func ProposeNewInstructionsProposalRequest(cur realm, newInstructions string) dao.ProposalRequest {
 80	return valopers.NewInstructionsProposalRequest(cross(cur), newInstructions)
 81}
 82
 83// ProposeAuthorityRotationProposalRequest creates a proposal to the GovDAO
 84// for re-pointing the valopers realm's governance authority.
 85//
 86// Delegates, for the same reason as above: the rotation closure reaches
 87// auth.Transfer, so it must never leave the valopers package. Exposed here
 88// because this package is where proposal factories for the realm live —
 89// see valopers.NewAuthorityRotationProposalRequest for why it takes a path
 90// rather than an authz.Authority, and why it exists at all.
 91func ProposeAuthorityRotationProposalRequest(cur realm, newContractPath string) dao.ProposalRequest {
 92	return valopers.NewAuthorityRotationProposalRequest(cross(cur), newContractPath)
 93}
 94
 95// ProposeNewMinFeeProposalRequest creates a proposal to the GovDAO
 96// for updating the minimum fee to register a new valoper. Signature
 97// preserved for historical-replay compatibility (gnoland-1's
 98// set_minfee.gno MsgRun calls this); body now delegates to the
 99// generic sys/params factory so the fee lives in
100// node:valoper:register_fee.
101func ProposeNewMinFeeProposalRequest(cur realm, newMinFee int64) dao.ProposalRequest {
102	return sysparams.NewSysParamUint64PropRequest(cross(cur), "node", "valoper", "register_fee", uint64(newMinFee))
103}