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

govern.gno

4.34 Kb · 114 lines
  1package bubble
  2
  3import (
  4	governor "gno.land/p/g1leu8d2vsplhehcfkjg50mwgdpxdkt8tztu95wr/governor/v0"
  5)
  6
  7// The governor: kourt's engine on this ledger, with this realm's own powers installed under the reserved prefix.
  8// Everything about proposals — kinds, tally, rules, sweep, pages — is the engine's; what is here is what only a
  9// realm can do: hold a live cur, check it, read who is calling, dispatch a decided kind with a sub-realm.
 10//
 11// "Usable for governance flexibly as we build it out": a new power is a Kind any realm can Offer (published,
 12// immutable code plus the bar it would pass at) and the holders adopt by govern:adopt. The token is never
 13// redeployed to gain a power.
 14
 15type (
 16	Kind  = governor.Kind
 17	Rules = governor.Rules
 18)
 19
 20func NewRules(quorumBps, thresholdBps, votingBlocks, delayBlocks, graceBlocks, proposeBps int64) Rules {
 21	return governor.NewRules(quorumBps, thresholdBps, votingBlocks, delayBlocks, graceBlocks, proposeBps)
 22}
 23
 24func TextOnly(s string) error { return governor.TextOnly(s) }
 25
 26// engine is this realm's governor. Unexported: whoever holds it can adopt a kind without a vote.
 27var engine = governor.New(ledger, ledger)
 28
 29func init() {
 30	installKinds()
 31}
 32
 33// dispatch runs a decided kind with a SUB-realm, never this realm's own capability (the engine's note on
 34// dispatch: a kind holding the live cur could cross into anything that trusts this realm).
 35func dispatch(cur realm) governor.Dispatch {
 36	return func(k Kind, subpath, payload string) error {
 37		return k.Do(0, cur.Sub(subpath), payload)
 38	}
 39}
 40
 41// Offer publishes a kind. It grants nothing: the holders adopt it by vote.
 42func Offer(cur realm, k Kind, r Rules) { engine.Offer(caller(cur), k, r) }
 43
 44// Propose asks a question under an adopted kind. A money kind carries its absolute turnout floor (kinds.gno).
 45func Propose(cur realm, kind, payload, title string) int64 {
 46	who := caller(cur)
 47	var id int64
 48	if floor := quorumFloor(kind); floor > 0 {
 49		id = engine.ProposeWithQuorum(who, kind, payload, title, floor)
 50	} else {
 51		id = engine.Propose(who, kind, payload, title)
 52	}
 53	if len(askedKinds) > 512 { // a guard, not a record: only decided-but-unnoted money votes need it, and those are few
 54		askedKinds = map[int64]string{}
 55	}
 56	askedKinds[id] = kind
 57	return id
 58}
 59
 60// Vote casts the caller's weight as of the proposal's sealed epoch: "yes", "no" or "abstain".
 61func Vote(cur realm, id int64, choice string) { engine.Vote(caller(cur), id, choice) }
 62
 63func VoteWithReason(cur realm, id int64, choice, reason string) {
 64	engine.VoteWithReason(caller(cur), id, choice, reason)
 65}
 66
 67// Cancel withdraws the proposer's own open proposal.
 68func Cancel(cur realm, id int64) { engine.Cancel(caller(cur), id) }
 69
 70// Settle writes down a conclusion the rules already reached. Permissionless. A decided money vote's turnout goes
 71// into the bar's memory (kinds.gno).
 72func Settle(cur realm, id int64) {
 73	engine.Settle(caller(cur), id)
 74	if isMoneyKind(kindOf(id)) {
 75		noteTurnout(id)
 76	}
 77}
 78
 79// Execute runs a decided proposal after its delay. Permissionless.
 80func Execute(cur realm, id int64) {
 81	engine.Execute(caller(cur), id, dispatch(cur))
 82	if isMoneyKind(kindOf(id)) {
 83		noteTurnout(id)
 84	}
 85}
 86
 87// kindOf is the kind a proposal was asked under, as this realm noted it at Propose (the engine describes a
 88// proposal by its payload alone); an id it never saw is "".
 89func kindOf(id int64) string { return askedKinds[id] }
 90
 91// askedKinds is id -> kind for the proposals asked here, the last few hundred.
 92var askedKinds = map[int64]string{}
 93
 94func ReleaseRoll(cur realm, id int64) { engine.ReleaseRoll(caller(cur), id) }
 95
 96func Sweep(cur realm) {
 97	caller(cur)
 98	engine.Sweep()
 99}
100
101// ------------------------------------------------------------------ reads --
102
103func State(id int64) string                         { return engine.State(id) }
104func Describe(id int64) string                      { return engine.Describe(id) }
105func Preview(kind, payload string) string           { return engine.Preview(kind, payload) }
106func HasVoted(id int64, who address) bool           { return engine.HasVoted(id, who) }
107func Tally(id int64) (yes, no, abstain, total int64) { return engine.Tally(id) }
108func KindRules(name string) (Rules, bool)           { return engine.KindRules(name) }
109
110func Timings(id int64) (opened, closes, ready, expires int64) { return engine.Timings(id) }
111
112func VoteOf(id int64, who address) (choice string, weight int64, ok bool) {
113	return engine.VoteOf(id, who)
114}