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

execution_kind.gno

2.92 Kb · 73 lines
 1package commondao
 2
 3import (
 4	"errors"
 5	"time"
 6)
 7
 8// executionKindName is the name of the arbitrary-execution kind.
 9const executionKindName = "execution"
10
11var ErrExecutionFuncRequired = errors.New("execution proposal requires a non-nil Fn")
12
13// defaultExecutionVotingPeriod is the voting period of execution proposals.
14const defaultExecutionVotingPeriod = 7 * 24 * time.Hour
15
16// ExecutionArgs are the args for the execution kind (ExecutionKind): a
17// title, a body, and the ExecFunc to run on approval. The closure must be
18// authored in a persistent realm so it survives Propose→Execute; a
19// closure created by a `maketx run` script does not persist and cannot be
20// executed later.
21type ExecutionArgs struct {
22	Title string
23	Body  string
24	Fn    ExecFunc
25}
26
27// ExecutionKind is the package's one concrete proposal kind: a stateless,
28// reusable arbitrary-execution kind that runs an ExecFunc supplied by the
29// proposer on approval. It is /p/-typed so any realm can register it with
30// WithProposalKind(ExecutionKind{}) or RegisterKind without defining its
31// own execution kind.
32//
33// The executor moves value only through the DAO-scoped sub the host
34// passes (see ExecFunc): the host mints and passes that sub, so the
35// executor receives whichever DAO's sub the host decides (its own DAO's by
36// default). The closure is frozen at Propose (vote-integrity: the exact
37// code is fixed before the vote).
38//
39// This kind applies NO policy check to the closure beyond a non-nil Fn: it
40// runs the arbitrary code as-is. A realm that has treasury constraints (e.g.
41// a freeze flag) should NOT catalog this kind directly; instead it should
42// author its own execution kind whose definition wraps the closure with a
43// Validable check that enforces those constraints (blocking execution while
44// frozen, etc.), so arbitrary execution cannot bypass them. The reference
45// realm gno.land/r/nt/commondao/v0 does exactly this.
46type ExecutionKind struct{}
47
48// Name returns the execution kind's registry name.
49func (ExecutionKind) Name() string { return executionKindName }
50
51// New validates ExecutionArgs and builds an execution definition. It is a
52// pure factory: it receives only a readonly view and captures no mutable
53// handle.
54func (ExecutionKind) New(_ ReadonlyCommonDAO, args any) (ProposalDefinition, error) {
55	a, ok := args.(ExecutionArgs)
56	if !ok || a.Fn == nil {
57		return nil, ErrExecutionFuncRequired
58	}
59	return executionDef{title: a.Title, body: a.Body, fn: a.Fn}, nil
60}
61
62// executionDef is the definition produced by ExecutionKind.
63type executionDef struct {
64	title string
65	body  string
66	fn    ExecFunc
67}
68
69func (d executionDef) Title() string             { return d.title }
70func (d executionDef) Body() string              { return d.body }
71func (executionDef) VotingPeriod() time.Duration { return defaultExecutionVotingPeriod }
72func (executionDef) Threshold() Threshold        { return ThresholdSupermajority }
73func (d executionDef) Executor() ExecFunc        { return d.fn }