Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(PoC,gov): initial sys/validators and gov/dao contracts #1945

Merged
merged 35 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5e3341b
chore: pseudo code for poc's r/system/validators
moul Apr 17, 2024
72ccb5d
chore: fioxup
moul Apr 17, 2024
d8c3e00
chore: fioxup
moul Apr 17, 2024
a15cb37
chore: fioxup
moul Apr 17, 2024
330fdd3
chore: fioxup
moul Apr 17, 2024
faebb39
chore: rename r/system -> r/sys
moul Apr 18, 2024
954214c
chore: fioxup
moul Apr 18, 2024
6e40742
chore: fioxup
moul Apr 18, 2024
a6c7b64
Merge branch 'master' into dev/moul/poc-poc
moul Apr 18, 2024
99c34b0
chore: fixup
moul Apr 18, 2024
2ab8428
chore: fixup
moul Apr 18, 2024
47e0515
chore: fixup
moul Apr 20, 2024
54a0759
chore: fixup
moul Apr 20, 2024
2cfd8e5
Update app.go
moul May 7, 2024
53b43e7
Update app.go
moul May 7, 2024
f957551
Update app.go
moul May 7, 2024
48f9653
Update app.go
moul May 7, 2024
b9f1f1a
chore: make contribs/ Makefile dynamic
moul Jun 10, 2024
c820f26
chore: fixup
moul Jun 10, 2024
6c096ac
Merge branch 'master' into dev/moul/poc-poc
moul Jun 11, 2024
39ba578
chore: cleanup
moul Jun 11, 2024
b572e5c
chore: fixup
moul Jun 11, 2024
8668980
chore: fixup
moul Jun 11, 2024
69368a6
chore: fixup
moul Jun 11, 2024
691a8a2
chore: fixup
moul Jun 11, 2024
52b8ad1
Merge branch 'dev/moul/contribs-auto-makefile' into dev/moul/poc-poc
moul Jun 11, 2024
276ec31
feat: improve p/ownable API
moul Jun 11, 2024
eabbeb4
chore: fixup
moul Jun 11, 2024
9d299b9
chore: fixup
moul Jun 11, 2024
fdc36d5
chore: fixup
moul Jun 11, 2024
9983a6d
Merge branch 'dev/moul/ownable-update' into dev/moul/poc-poc
moul Jun 12, 2024
c7e82b2
chore: fixup
moul Jun 12, 2024
3db42c8
Remove panic from flow
zivkovicmilos Jun 12, 2024
cafbb79
Tidy gno mod
zivkovicmilos Jun 12, 2024
0a5daf1
fix: contribs/makefile
gfanton Jun 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions examples/gno.land/p/gov/proposal/proposal.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Package proposal provides a structure for executing proposals.
package proposal

// NewExecutor creates a new executor with the provided callback function.
func NewExecutor(callback func() error) Executor {
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
return &executorImpl{
callback: callback,
done: false,
}
}

// executorImpl is an implementation of the Executor interface.
type executorImpl struct {
callback func() error
done bool
success bool
}

// execute runs the executor's callback function.
func (exec *executorImpl) execute() error {
if exec.done {
return ErrAlreadyDone
}
// XXX: assertCalledByGovdao
err := exec.callback()
exec.done = true
exec.success = err == nil
return err
}

// Done returns whether the executor has been executed.
func (exec *executorImpl) Done() bool {
return exec.done
}

// Success returns whether the execution was successful.
func (exec *executorImpl) Success() bool {
return exec.success
}
14 changes: 14 additions & 0 deletions examples/gno.land/p/gov/proposal/types.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Package proposal defines types for proposal execution.
package proposal

// Executor represents a minimal closure-oriented proposal design.
// It is intended to be used by a govdao governance proposal (v1, v2, etc).
type Executor interface {
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
execute() error
Done() bool
Success() bool // Done() && !err
}

// ErrAlreadyDone is the error returned when trying to execute an already
// executed proposal.
var ErrAlreadyDone = errors.New("already executed")
37 changes: 37 additions & 0 deletions examples/gno.land/r/gnoland/valopers/valopers.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Package valopers is designed around the permissionless lifecycle of valoper profiles.
// It also includes parts designed for govdao to propose valset changes based on registered valopers.
package valopers
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved

import (
"gno.land/p/demo/ownable"
"gno.land/r/gov/dao"
)

// Valoper represents a validator operator profile.
type Valoper struct {
ownable.Ownable // Embedding the Ownable type for ownership management.

DisplayName string // The display name of the valoper.
ValidatorAddr std.Address // The address of the validator.
// TODO: Add other valoper metadata as needed.
}

// Register registers a new valoper.
// TODO: Define the parameters and implement the function.
func Register( /* TBD */ ) {
panic("not implemented")
}

// Update updates an existing valoper.
// TODO: Define the parameters and implement the function.
func Update( /* TBD */ ) {
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
panic("not implemented")
}

// GovXXX is a placeholder for a function to interact with the governance DAO.
// TODO: Define a good API and implement it.
func GovXXX() {
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
// Assert that the caller is a member of the governance DAO.
dao.AssertIsMember(std.PrevRealm().Addr())
panic("not implemented")
}
60 changes: 60 additions & 0 deletions examples/gno.land/r/gov/dao/dao.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package govdao
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved

import "std"

var proposals = make([]Proposal, 0)

// XXX var members ...

// Proposal represents a proposal in the governance system.
type Proposal struct {
author std.Address
idx int
Comment string
Callback func()
}

// Propose is designed to be called by another contract or with
// `maketx run`, not by a `maketx call`.
func Propose(proposal Proposal) int {
// XXX: require payment?
// XXX: sanitize proposal
caller := std.PrevRealm().Addr()
AssertIsMember(caller)
proposal.author = caller
proposal.idx = len(proposals)
proposals = append(proposals, proposal)
return proposal.idx
}

func VoteOnProposal(idx int, option string) {
AssertIsMember(caller)
panic("not implemented")
// XXX: implement the voting (woudl be cool to have a generic p/)
}

func ExecuteProposal(idx int) {
assertProposalExists(idx)
// XXX: assert voting is finished
// XXX: assert voting result is YES
// XXX: proposal was not already executed
proposal := proposals[idx]
proposal.Callback()
}

func assertProposalExists(idx int) {
if idx < 0 || idx >= len(proposals) {
panic("invalid proposal id")
}
}

func IsMember(addr std.Address) bool {
// XXX: implement
return true
}

zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
func AssertIsMember(addr std.Address) {
if !IsMember(addr) {
panic("caller is not member of govdao")
}
}
38 changes: 38 additions & 0 deletions examples/gno.land/r/gov/proposals/prop1/prop1.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Package prop1 is an example of proposal creation using a contract.
//
// Please note that this package is intended for demonstration purposes only.
// You could execute this code by running a `maketx run` command or by uploading
// a similar package to a personal namespace.
//
// For the specific case of validators, a `r/gnoland/valopers` will be used to
// organize the lifecycle of validators (register, etc), and this more complex
// contract will be responsible to generate proposals.
package prop1

import (
"std"

govdao "gno.land/r/gov/dao"
"gno.land/r/sys/validators"
)

func init() {
// Create the validators change proposal.
changesFn := func() []validators.Change {
return []validators.Change{
{Address: std.Address("g12345678"), Power: 1}, // add a new validator
{Address: std.Address("g000000000"), Power: 0}, // remove an existing validator
}
}

// Wraps changesFn to emit a certified event only if executed from a
// complete governance proposal process.
executor := validators.NewExecutor(changesFn)
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved

// Create a proposal.
// XXX: payment
govdao.Propose(govdao.Proposal{
Comment: "manual valset changes proposal example",
Executor: executor,
})
}
34 changes: 32 additions & 2 deletions examples/gno.land/r/sys/validators/validators.gno
Original file line number Diff line number Diff line change
@@ -1,4 +1,34 @@
// This package is used to manage the validator set.
// Package validators is used to manage the validator set.
package validators

// write specs.
import (
"std"

"gno.land/p/gov/proposal"
)

// Change represents a change in the validator set.
type Change struct {
Address std.Address
Power int
}

// NewProposalExecutor creates a new executor that wraps a changes closure
// proposal. It emits a typed object (subscribed by tm2) only if it passes
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
// through a complete p/gov/proposal process.
func NewProposalExecutor(changesFn []Change) proposal.Executor {
if changesFn == nil {
panic("changesFn should not be nil")
}

// Certify that the changes are sent from the context of this realm.
callback := func() {
changes := changesFn()

// XXX: Not final API. Depends on the std.Emit implementation.
std.Emit(changes)
}

exec := proposal.NewExecutor(callback)
return exec
}
18 changes: 18 additions & 0 deletions gno.land/pkg/gnoland/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) {
func(ctx sdk.Context, tx std.Tx, simulate bool) (
newCtx sdk.Context, res sdk.Result, abort bool,
) {
// XXX: pseudo code
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
valsetRealm := cfg.GetGnoSDKCfg("valset-trusted-realm")
if evt:= subscribeRealmEvent(valsetRealm) ; evt != nil {
applyValsetChange(evt)
}
varsRealm := cfg.GetGnoSDKCfg("vars-trusted-realm")
if evt:= subscribeRealmEvent(varsRealm) ; evt != nil {
cfg.SetGnoSDKCfg(evt.Name, evt.Value)
}

// Override auth params.
ctx = ctx.WithValue(
auth.AuthParamsContextKey{}, auth.DefaultParams())
Expand All @@ -106,6 +116,8 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) {
},
)



// Set EndBlocker
baseApp.SetEndBlocker(EndBlocker(vmKpr))

Expand Down Expand Up @@ -140,6 +152,12 @@ func NewApp(dataRootDir string, skipFailingGenesisTxs bool, logger *slog.Logger,
return nil, fmt.Errorf("error initializing database %q using path %q: %w", dbm.GoLevelDBBackend, dataRootDir, err)
}

// XXX: default gno sdk config
cfg.SetGnoSDKCfg("valset-trusted-realm", "r/sys/vals")
cfg.SetGnoSDKCfg("cfg-trusted-realm", "r/sys/vars")
cfg.SetGnoSDKCfg("gnot-locked", true)
//

cfg.Logger = logger
return NewAppWithOptions(cfg)
}
Expand Down
Loading