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: da0-da0 port + moderated boards #3

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
400aefb
feat(gnovm): add unicode/utf16 in stdlibs
n0izn0iz Aug 24, 2023
d09c845
feat: ujson
n0izn0iz Aug 24, 2023
613e66d
feat: da0-da0 port + moderated boards
n0izn0iz Jul 5, 2023
6bdb796
TMP
n0izn0iz Jul 6, 2023
1d50f09
TMP
n0izn0iz Jul 9, 2023
14996d3
TMP
n0izn0iz Jul 9, 2023
2ced617
feat: grc20 support
n0izn0iz Jul 11, 2023
bae4c9f
bug examples
n0izn0iz Jul 13, 2023
5fdf7ba
TMP
n0izn0iz Aug 2, 2023
cdb1827
TMP
n0izn0iz Aug 2, 2023
f0430ea
tmp: json
n0izn0iz Aug 9, 2023
8c3192e
chore: remove versioning
n0izn0iz Aug 23, 2023
eb79f91
fix: missing gno mod require
n0izn0iz Aug 23, 2023
7964e32
chore: switch jsonutil -> ujson
n0izn0iz Aug 25, 2023
2169839
chore: refacto
n0izn0iz Aug 25, 2023
f97cd60
chore: remove unused binutils
n0izn0iz Aug 25, 2023
86407af
chore: remove dumb file
n0izn0iz Aug 25, 2023
1d23daf
chore: revert changes in gnovm
n0izn0iz Aug 25, 2023
bfffd57
chore: remove artifact
n0izn0iz Aug 25, 2023
9882490
chore: extract grc20_registry in own branch
n0izn0iz Aug 26, 2023
2463053
fix: fully switch to json encoding in demo dao_realm
n0izn0iz Aug 26, 2023
a94f123
fix: correctly decode json in tests
n0izn0iz Aug 26, 2023
b49ecbc
fix: group test output
n0izn0iz Aug 26, 2023
e775976
chore: revert users change
n0izn0iz Aug 26, 2023
d2221b2
fix: tests
n0izn0iz Aug 26, 2023
2c52356
chore: remove published bug
n0izn0iz Aug 26, 2023
60904d0
chore: make failing mis_ownership test
n0izn0iz Aug 26, 2023
8aefa76
chore: remove upstreamed bug
n0izn0iz Aug 26, 2023
738712a
chore: remove upstreamed bugs
n0izn0iz Aug 26, 2023
5db8ed5
chore: remove contracts makefiles
n0izn0iz Aug 26, 2023
6c4c62a
feat: add dao Pause and ExecuteAdminMsgs
n0izn0iz Aug 28, 2023
7f1a835
chore: add test to demonstrate prev-realm bug
n0izn0iz Aug 29, 2023
5c53fa2
chore: remove upstreamed bug
n0izn0iz Aug 30, 2023
ca72e83
chore: refacto core contracts
n0izn0iz Sep 13, 2023
3b7e84e
chore: clean dao realm example
n0izn0iz Sep 14, 2023
d367ec9
chore: remove unused file
n0izn0iz Sep 14, 2023
8ddfacd
fix: remove unexisting dep
n0izn0iz Sep 14, 2023
4eae8cd
feat: add support for time
n0izn0iz Sep 14, 2023
3044fd2
chore: add missing dep in gno mod
n0izn0iz Sep 14, 2023
622ddaa
chore: remove pause related artifacts
n0izn0iz Sep 14, 2023
bcd12a8
fix: make ujson publishable
n0izn0iz Sep 14, 2023
b626523
fix: tokenizer unquoting
n0izn0iz Sep 14, 2023
7aad056
chore: code dedup
n0izn0iz Sep 14, 2023
56d5001
chore: add comment
n0izn0iz Sep 14, 2023
c4afed0
fix: broken module name
n0izn0iz Sep 15, 2023
57ee9fe
feat: allow to get voting power at any height
n0izn0iz Sep 16, 2023
b3a3ead
feat: jsonify messages
n0izn0iz Sep 18, 2023
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ pbbindings.go
*#
cover.out
coverage.out
/.deploy/
228 changes: 228 additions & 0 deletions examples/gno.land/p/demo/daodao/core/dao_core.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
package core

import (
"std"
"strings"
"time"

dao_interfaces "gno.land/p/demo/daodao/interfaces"
"gno.land/p/demo/markdown_utils"
)

// TODO: clean this file

// TODO: add wrapper message handler to handle multiple proposal modules messages

type daoCore struct {
dao_interfaces.IDAOCore

votingModule dao_interfaces.IVotingModule
proposalModules []dao_interfaces.ActivableProposalModule
activeProposalModuleCount int
realm std.Realm
registry *dao_interfaces.MessagesRegistry
}

func NewDAOCore(
votingModuleFactory dao_interfaces.VotingModuleFactory,
proposalModulesFactories []dao_interfaces.ProposalModuleFactory,
messageHandlersFactories []dao_interfaces.MessageHandlerFactory,
) dao_interfaces.IDAOCore {
if votingModuleFactory == nil {
panic("Missing voting module factory")
}

if len(proposalModulesFactories) == 0 {
panic("No proposal modules factories")
}

core := &daoCore{
realm: std.CurrentRealm(),
activeProposalModuleCount: len(proposalModulesFactories),
registry: dao_interfaces.NewMessagesRegistry(),
proposalModules: make([]dao_interfaces.ActivableProposalModule, len(proposalModulesFactories)),
}

core.votingModule = votingModuleFactory(core)
if core.votingModule == nil {
panic("voting module factory returned nil")
}

for i, modFactory := range proposalModulesFactories {
mod := modFactory(core)
if mod == nil {
panic("proposal module factory returned nil")
}
core.proposalModules[i] = dao_interfaces.ActivableProposalModule{
Enabled: true,
Module: mod,
}
}

// this registry is specific to gno since we can't do dynamic calls
core.registry.Register(NewUpdateVotingModuleMessageHandler(core))
core.registry.Register(NewUpdateProposalModulesMessageHandler(core))
for _, handlerFactory := range messageHandlersFactories {
handler := handlerFactory(core)
if handler == nil {
panic("message handler factory returned nil")
}
core.registry.Register(handler)
}

return core
}

// mutations

func (d *daoCore) ExecuteProposalHook(moduleIndex int, msgs []dao_interfaces.ExecutableMessage) {
module := GetProposalModule(d, moduleIndex)
if !module.Enabled {
panic(ErrModuleDisabledCannotExecute)
}

d.executeMsgs(msgs)
}

func (d *daoCore) UpdateVotingModule(newVotingModule dao_interfaces.IVotingModule) {
if std.CurrentRealm().Addr() != d.realm.Addr() { // not sure this check necessary since the ownership system should protect against mutation from other realms
panic(ErrUnauthorized)
}

// FIXME: check da0-da0 implem
d.votingModule = newVotingModule
}

func (d *daoCore) UpdateProposalModules(toAdd []dao_interfaces.IProposalModule, toDisable []int) {
if std.CurrentRealm().Addr() != d.realm.Addr() { // not sure this check necessary since the ownership system should protect against mutation from other realms
panic(ErrUnauthorized)
}

for _, module := range toAdd {
d.AddProposalModule(module)
}

for _, moduleIndex := range toDisable {
module := GetProposalModule(d, moduleIndex)

if !module.Enabled {
panic(ErrModuleAlreadyDisabled)
}
module.Enabled = false

d.activeProposalModuleCount--
if d.activeProposalModuleCount == 0 {
panic("no active proposal modules") // this -> `panic(ErrNoActiveProposalModules)` triggers `panic: reflect: reflect.Value.SetString using value obtained using unexported field`
}
}
}

// gno-specific mutations

func (d *daoCore) RegisterMessageHandler(msg dao_interfaces.MessageHandler) {
d.registry.Register(msg)
}

func (d *daoCore) RemoveMessageHandler(t string) {
d.registry.Remove(t)
}

// queries

func (d *daoCore) DumpState() {
panic(ErrNotImplemented)
}

func (d *daoCore) Info() {
panic(ErrNotImplemented)
}

func (d *daoCore) ProposalModules() []dao_interfaces.ActivableProposalModule {
return d.proposalModules
}

func (d *daoCore) ProposalModuleCount() int {
return len(d.proposalModules)
}

func (d *daoCore) TotalPowerAtHeight() {
panic(ErrNotImplemented)
}

func (d *daoCore) VotingModule() dao_interfaces.IVotingModule {
return d.votingModule
}

func (d *daoCore) VotingPowerAtHeight(address std.Address, height int64) uint64 {
return d.VotingModule().VotingPowerAtHeight(address, height)
}

func (d *daoCore) ActiveProposalModules() {
panic(ErrNotImplemented)
}

// custom queries

func (d *daoCore) VotingModule() dao_interfaces.IVotingModule {
return d.votingModule
}

func (d *daoCore) AddProposalModule(proposalMod dao_interfaces.IProposalModule) {
for _, mod := range d.proposalModules {
if mod.Module != proposalMod {
continue
}

if mod.Enabled {
panic(ErrModuleAlreadyAdded)
}
mod.Enabled = true
d.activeProposalModuleCount++
return
}

d.proposalModules = append(d.proposalModules, dao_interfaces.ActivableProposalModule{
Enabled: true,
Module: proposalMod,
})

d.activeProposalModuleCount++
}

func (d *daoCore) ActiveProposalModuleCount() int {
return d.activeProposalModuleCount
}

func (d *daoCore) Render(path string) string {
s := "# DAO Core\n"
s += "This is an attempt at porting [DA0-DA0 contracts](https://github.com/DA0-DA0/dao-contracts)\n"
s += markdown_utils.Indent(d.votingModule.Render(path)) + "\n"
for _, propMod := range d.proposalModules {
if !propMod.Enabled {
continue
}
s += markdown_utils.Indent(propMod.Module.Render(path)) + "\n"
}
return s
}

func (d *daoCore) Registry() *dao_interfaces.MessagesRegistry {
return d.registry
}

func GetProposalModule(core dao_interfaces.IDAOCore, moduleIndex int) *dao_interfaces.ActivableProposalModule {
if moduleIndex < 0 {
panic("module index must be >= 0")
}
mods := core.ProposalModules()
if moduleIndex >= len(mods) {
panic("invalid module index")
}
return &mods[moduleIndex]
}

func (d *daoCore) executeMsgs(msgs []dao_interfaces.ExecutableMessage) {
for _, msg := range msgs {
d.registry.Execute(msg)
}
}
Loading
Loading