Skip to content

Commit

Permalink
feat: leaner dao interfaces (#1465)
Browse files Browse the repository at this point in the history
Signed-off-by: Norman Meier <[email protected]>
Co-authored-by: MikaelVallenet <[email protected]>
  • Loading branch information
n0izn0iz and MikaelVallenet authored Dec 23, 2024
1 parent a475671 commit 7f31f69
Show file tree
Hide file tree
Showing 18 changed files with 211 additions and 246 deletions.
47 changes: 2 additions & 45 deletions gno/p/dao_core/dao_core.gno
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import (
"strconv"
"strings"

"gno.land/p/demo/json"
dao_interfaces "gno.land/p/teritori/dao_interfaces"
"gno.land/p/teritori/jsonutil"
)

// TODO: add wrapper message handler to handle multiple proposal modules messages
Expand All @@ -16,7 +14,6 @@ type daoCore struct {
dao_interfaces.IDAOCore

votingModule dao_interfaces.IVotingModule
rolesModule dao_interfaces.IRolesModule
proposalModules []dao_interfaces.ActivableProposalModule
activeProposalModuleCount int
realm std.Realm
Expand All @@ -25,18 +22,13 @@ type daoCore struct {

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

if rolesModuleFactory == nil {
panic("Missing roles module factory")
}

if len(proposalModulesFactories) == 0 {
panic("No proposal modules factories")
}
Expand All @@ -48,12 +40,6 @@ func NewDAOCore(
proposalModules: make([]dao_interfaces.ActivableProposalModule, len(proposalModulesFactories)),
}

// important to keep this order since voting module might depend on roles module
core.rolesModule = rolesModuleFactory(core)
if core.rolesModule == nil {
panic("roles module factory returned nil")
}

core.votingModule = votingModuleFactory(core)
if core.votingModule == nil {
panic("voting module factory returned nil")
Expand Down Expand Up @@ -131,32 +117,6 @@ func (d *daoCore) VotingModule() dao_interfaces.IVotingModule {
return d.votingModule
}

func (d *daoCore) RolesModule() dao_interfaces.IRolesModule {
return d.rolesModule
}

func (d *daoCore) GetMembersJSON(start, end string, limit uint64, height int64) string {
vMembers := d.votingModule.GetMembersJSON(start, end, limit, height)
nodes, err := json.Unmarshal([]byte(vMembers))
if err != nil {
panic("failed to unmarshal voting module members")
}
vals := nodes.MustArray()
for i, val := range vals {
obj := val.MustObject()
addr := jsonutil.MustAddress(obj["address"])
roles := d.rolesModule.GetMemberRoles(addr)
rolesJSON := make([]*json.Node, len(roles))
for j, role := range roles {
rolesJSON[j] = json.StringNode("", role)
}
obj["roles"] = json.ArrayNode("", rolesJSON)
vals[i] = json.ObjectNode("", obj)

}
return json.ArrayNode("", vals).String()
}

func (d *daoCore) VotingPowerAtHeight(address std.Address, height int64) uint64 {
return d.VotingModule().VotingPowerAtHeight(address, height, []string{})
}
Expand All @@ -169,15 +129,12 @@ func (d *daoCore) Render(path string) string {
sb := strings.Builder{}
sb.WriteString("# DAO Core\n")
votingInfo := d.votingModule.Info()

sb.WriteString("## Voting Module: ")
sb.WriteString(votingInfo.String())
sb.WriteRune('\n')
sb.WriteString(d.votingModule.Render(""))
rolesInfo := d.rolesModule.Info()
sb.WriteString("# Roles Module: ")
sb.WriteString(rolesInfo.String())
sb.WriteRune('\n')
sb.WriteString(d.rolesModule.Render(""))

sb.WriteString("## Supported Messages:\n")
sb.WriteString(d.registry.Render())

Expand Down
62 changes: 1 addition & 61 deletions gno/p/dao_core/dao_core_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -46,57 +46,6 @@ func (vm *votingModule) TotalPowerAtHeight(height int64) uint64 {
return 0
}

type rolesModule struct {
core dao_interfaces.IDAOCore
}

func rolesModuleFactory(core dao_interfaces.IDAOCore) dao_interfaces.IRolesModule {
return &rolesModule{core: core}
}

func (rm *rolesModule) Info() dao_interfaces.ModuleInfo {
return dao_interfaces.ModuleInfo{
Kind: "TestRoles",
Version: "42.21",
}
}

func (rm *rolesModule) ConfigJSON() string {
return "{}"
}

func (rm *rolesModule) Render(path string) string {
return "# Test Roles Module"
}

func (rm *rolesModule) HasRole(address std.Address, role string) bool {
return false
}

func (rm *rolesModule) NewRoleJSON(roleName, resourcesJSON string) {
panic("not implemented")
}

func (rm *rolesModule) DeleteRole(roleName string) {
panic("not implemented")
}

func (rm *rolesModule) GrantRole(address std.Address, role string) {
panic("not implemented")
}

func (rm *rolesModule) RevokeRole(address std.Address, role string) {
panic("not implemented")
}

func (rm *rolesModule) GetMemberRoles(address std.Address) []string {
return []string{}
}

func (rm *rolesModule) GetMemberResourceVPower(address std.Address, resource string) uint64 {
return 0
}

type proposalModule struct {
core dao_interfaces.IDAOCore
}
Expand Down Expand Up @@ -151,7 +100,7 @@ func TestDAOCore(t *testing.T) {
return handler
}

core := NewDAOCore(votingModuleFactory, rolesModuleFactory, []dao_interfaces.ProposalModuleFactory{proposalModuleFactory}, []dao_interfaces.MessageHandlerFactory{handlerFactory})
core := NewDAOCore(votingModuleFactory, []dao_interfaces.ProposalModuleFactory{proposalModuleFactory}, []dao_interfaces.MessageHandlerFactory{handlerFactory})
if core == nil {
t.Fatal("core is nil")
}
Expand All @@ -169,15 +118,6 @@ func TestDAOCore(t *testing.T) {
t.Fatal("voting module has wrong kind")
}

rolesMod := core.RolesModule()
if rolesMod == nil {
t.Fatal("roles module is nil")
}

if rolesMod.Info().Kind != "TestRoles" {
t.Fatal("roles module has wrong kind")
}

propMods := core.ProposalModules()
if len(propMods) != 1 {
t.Fatal("expected 1 proposal module")
Expand Down
3 changes: 0 additions & 3 deletions gno/p/dao_interfaces/core.gno
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,10 @@ type IDAOCore interface {
Render(path string) string

VotingModule() IVotingModule
RolesModule() IRolesModule
ProposalModules() []ActivableProposalModule
ActiveProposalModuleCount() int
Registry() *MessagesRegistry

UpdateVotingModule(newVotingModule IVotingModule)
UpdateProposalModules(toAdd []IProposalModule, toDisable []int)

GetMembersJSON(start, end string, limit uint64, height int64) string
}
10 changes: 2 additions & 8 deletions gno/p/dao_interfaces/core_testing.gno
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package dao_interfaces

type dummyCore struct{}

var _ IDAOCore = (*dummyCore)(nil)

func NewDummyCore() IDAOCore {
return &dummyCore{}
}
Expand All @@ -14,10 +16,6 @@ func (d *dummyCore) VotingModule() IVotingModule {
panic("not implemented")
}

func (d *dummyCore) RolesModule() IRolesModule {
panic("not implemented")
}

func (d *dummyCore) ProposalModules() []ActivableProposalModule {
panic("not implemented")
}
Expand All @@ -37,7 +35,3 @@ func (d *dummyCore) UpdateVotingModule(newVotingModule IVotingModule) {
func (d *dummyCore) UpdateProposalModules(toAdd []IProposalModule, toDisable []int) {
panic("not implemented")
}

func (d *dummyCore) GetMembersJSON(start, end string, limit uint64, height int64) string {
panic("not implemented")
}
16 changes: 0 additions & 16 deletions gno/p/dao_interfaces/modules.gno
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ type IVotingModule interface {
type VotingModuleFactory func(core IDAOCore) IVotingModule

type IProposalModule interface {
Core() IDAOCore
Info() ModuleInfo
ConfigJSON() string
Render(path string) string
Expand All @@ -37,18 +36,3 @@ type IProposalModule interface {
}

type ProposalModuleFactory func(core IDAOCore) IProposalModule

type IRolesModule interface {
Info() ModuleInfo
ConfigJSON() string
Render(path string) string
GetMemberRoles(address std.Address) []string
GetMemberResourceVPower(address std.Address, resource string) uint64
HasRole(address std.Address, role string) bool
NewRoleJSON(roleName, resourcesJSON string)
DeleteRole(roleName string)
GrantRole(address std.Address, role string)
RevokeRole(address std.Address, role string)
}

type RolesModuleFactory func(core IDAOCore) IRolesModule
8 changes: 2 additions & 6 deletions gno/p/dao_proposal_single/dao_proposal_single.gno
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ func (opts DAOProposalSingleOpts) ToJSON() *json.Node {
}

type DAOProposalSingle struct {
dao_interfaces.IProposalModule

core dao_interfaces.IDAOCore
opts *DAOProposalSingleOpts
proposals []*Proposal
}

var _ dao_interfaces.IProposalModule = (*DAOProposalSingle)(nil)

func NewDAOProposalSingle(core dao_interfaces.IDAOCore, opts *DAOProposalSingleOpts) *DAOProposalSingle {
if core == nil {
panic("core cannot be nil")
Expand Down Expand Up @@ -238,10 +238,6 @@ func (d *DAOProposalSingle) Render(path string) string {
return sb.String()
}

func (d *DAOProposalSingle) Core() dao_interfaces.IDAOCore {
return d.core
}

func (d *DAOProposalSingle) Info() dao_interfaces.ModuleInfo {
return dao_interfaces.ModuleInfo{
Kind: "gno.land/p/teritori/dao_proposal_single",
Expand Down
2 changes: 0 additions & 2 deletions gno/p/dao_roles_group/roles_group.gno
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
)

type RolesGroup struct {
dao_interfaces.IRolesModule

rm *role_manager.RoleManager
resourcesVPower *avl.Tree // roles -> ResourceVPower[]
}
Expand Down
9 changes: 5 additions & 4 deletions gno/p/dao_roles_voting_group/roles_voting_group.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"gno.land/p/demo/json"
dao_interfaces "gno.land/p/teritori/dao_interfaces"
"gno.land/p/teritori/dao_roles_group"
"gno.land/p/teritori/havl"
"gno.land/p/teritori/jsonutil"
)
Expand All @@ -30,15 +31,15 @@ func (m *Member) FromJSON(ast *json.Node) {
}

type RolesVotingGroup struct {
dao_interfaces.IVotingModule

powerByAddr *havl.Tree // std.Address -> uint64
totalPower *havl.Tree // "" -> uint64
memberCount *havl.Tree // "" -> uint32
rolesModule dao_interfaces.IRolesModule
rolesModule *dao_roles_group.RolesGroup
}

func NewRolesVotingGroup(rm dao_interfaces.IRolesModule) *RolesVotingGroup {
var _ dao_interfaces.IVotingModule = (*RolesVotingGroup)(nil)

func NewRolesVotingGroup(rm *dao_roles_group.RolesGroup) *RolesVotingGroup {
return &RolesVotingGroup{
powerByAddr: havl.NewTree(),
totalPower: havl.NewTree(),
Expand Down
2 changes: 1 addition & 1 deletion gno/p/dao_roles_voting_group/roles_voting_group_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var (

func TestRolesVotingGroup(t *testing.T) {
rm := dao_roles_group.NewRolesGroup()
var j dao_interfaces.IRolesModule
var j *dao_roles_group.RolesGroup
j = rm
rv := NewRolesVotingGroup(j)
var i dao_interfaces.IVotingModule
Expand Down
2 changes: 1 addition & 1 deletion gno/p/havl/havl.gno
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Tree struct {
initialHeight int64
}

var Latest = int64(0)
const Latest = int64(0)

// FIXME: this is not optimized at all, we make a full copy on write

Expand Down
11 changes: 5 additions & 6 deletions gno/r/dao_realm/dao_realm.gno
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ func init() {
return group
}

rolesModuleFactory := func(core dao_interfaces.IDAOCore) dao_interfaces.IRolesModule {
roles = dao_roles_group.NewRolesGroup()
return roles
}

// TODO: consider using factories that return multiple modules and handlers

proposalModulesFactories := []dao_interfaces.ProposalModuleFactory{
Expand Down Expand Up @@ -82,7 +77,7 @@ func init() {
},
}

daoCore = dao_core.NewDAOCore(votingModuleFactory, rolesModuleFactory, proposalModulesFactories, messageHandlersFactories)
daoCore = dao_core.NewDAOCore(votingModuleFactory, proposalModulesFactories, messageHandlersFactories)

// Register the DAO profile
profile.SetStringField(profile.DisplayName, "DAO Realm")
Expand Down Expand Up @@ -148,3 +143,7 @@ func getProposalJSON(moduleIndex int, proposalIndex int) string {
module := dao_core.GetProposalModule(daoCore, moduleIndex)
return module.Module.ProposalJSON(proposalIndex)
}

func getMembersJSON(start, end string, limit uint64) string {
return daoCore.VotingModule().GetMembersJSON(start, end, limit, std.GetHeight())
}
Loading

0 comments on commit 7f31f69

Please sign in to comment.