Skip to content

Commit

Permalink
fix: make social feed and moderation work with latest dao packages
Browse files Browse the repository at this point in the history
Signed-off-by: Norman Meier <norman@berty.tech>
  • Loading branch information
n0izn0iz committed Sep 19, 2023
1 parent 1eea98f commit aca197f
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 66 deletions.
12 changes: 12 additions & 0 deletions examples/gno.land/r/demo/social_feeds/feed.gno
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ func (fid FeedID) String() string {
return strconv.Itoa(int(fid))
}

func (fid *FeedID) FromJSON(ast *ujson.JSONASTNode) {
val, err := strconv.Atoi(ast.Value)
if err != nil {
panic(err)
}
*fid = FeedID(val)
}

func (fid FeedID) ToJSON() string {
return strconv.Itoa(int(fid))
}

type Feed struct {
id FeedID
url string
Expand Down
10 changes: 9 additions & 1 deletion examples/gno.land/r/demo/social_feeds/messages.gno
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ type ExecutableMessageBanPost struct {
}

func (msg *ExecutableMessageBanPost) Type() string {
return "BanPost"
return "gno.land/r/demo/social_feeds.BanPost"
}

func (msg *ExecutableMessageBanPost) ToJSON() string {
return ujson.FormatObject([]ujson.FormatKV{
{Key: "feedId", Value: msg.FeedID},
{Key: "postId", Value: msg.PostID},
{Key: "reason", Value: msg.Reason},
})
}

func (msg *ExecutableMessageBanPost) String() string {
Expand Down
12 changes: 12 additions & 0 deletions examples/gno.land/r/demo/social_feeds/post.gno
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ func (pid PostID) String() string {
return strconv.Itoa(int(pid))
}

func (pid *PostID) FromJSON(ast *ujson.JSONASTNode) {
val, err := strconv.Atoi(ast.Value)
if err != nil {
panic(err)
}
*pid = PostID(val)
}

func (pid PostID) ToJSON() string {
return strconv.Itoa(int(pid))
}

type Reaction struct {
icon string
count uint64
Expand Down
2 changes: 1 addition & 1 deletion examples/gno.land/r/demo/social_feeds_dao/gno.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ module gno.land/r/demo/social_feeds_dao

require (
"gno.land/r/demo/social_feeds" v0.0.0-latest
"gno.land/r/demo/groups_v9" v0.0.0-latest
"gno.land/r/demo/groups" v0.0.0-latest
)
135 changes: 71 additions & 64 deletions examples/gno.land/r/demo/social_feeds_dao/social_feeds_dao.gno
Original file line number Diff line number Diff line change
Expand Up @@ -6,99 +6,106 @@ import (
"strings"
"time"

dao_core "gno.land/p/demo/daodao/core_v6"
dao_core "gno.land/p/demo/daodao/core"
dao_interfaces "gno.land/p/demo/daodao/interfaces"
"gno.land/p/demo/daodao/proposal_single_v7"
"gno.land/p/demo/daodao/voting_group_v8"
"gno.land/p/demo/daodao/proposal_single"
"gno.land/p/demo/daodao/voting_group"
"gno.land/p/demo/ujson"
"gno.land/r/demo/dao_registry_v5"
"gno.land/r/demo/groups_v9"
"gno.land/r/demo/dao_registry"
"gno.land/r/demo/groups"
social_feeds "gno.land/r/demo/social_feeds"
)

var (
daoCore dao_core.IDAOCore
registry = dao_interfaces.NewMessagesRegistry()
mainFeedName = "teritori9"
daoCore dao_interfaces.IDAOCore
mainFeedName = "teritori"
groupName = "social_feeds_dao_voting_group"
groupID groups.GroupID
feedID social_feeds.FeedID
)

func init() {
// NOTE: why creator is: g16lcthjkpr9emfj2yemnsfmyc563jw98p4wwvgg ??????
groupID = groups.CreateGroup(mainFeedName)
feedID = social_feeds.CreateFeed(mainFeedName)

// Create Feed
currentRealm := std.CurrentRealm()
feedID := social_feeds.CreateFeed(mainFeedName)

// For testing purpose we add 2 users
groups.AddMember(groupID, "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", 1, "")

registry.Register(groups.NewAddMemberHandler())
registry.Register(groups.NewDeleteMemberHandler())
votingModuleFactory := func(core dao_interfaces.IDAOCore) dao_interfaces.IVotingModule {
groupID = groups.CreateGroup(groupName)
groups.AddMember(groupID, "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", 1, "")
groups.AddMember(groupID, "g108cszmcvs4r3k67k7h5zuhm4el3qhlrxzhshtv", 1, "")
return dao_voting_group.NewVotingGroup(groupID)
}

daoCore = dao_core.NewDAOCore(dao_voting_group.NewGRC4Voting(groupID), nil)
proposalModulesFactories := []dao_interfaces.ProposalModuleFactory{
func(core dao_interfaces.IDAOCore) dao_interfaces.IProposalModule {
tt := dao_proposal_single.PercentageThresholdPercent(1500)
tq := dao_proposal_single.PercentageThresholdPercent(5000)
return dao_proposal_single.NewDAOProposalSingle(core, &dao_proposal_single.DAOProposalSingleOpts{
MaxVotingPeriod: time.Second * 86400,
Threshold: &dao_proposal_single.ThresholdThresholdQuorum{
Threshold: &tt, // 15%
Quorum: &tq, // 50%
},
})
},
}

tt := dao_interfaces.Percent(1500) // 15%
tq := dao_interfaces.Percent(5000) // 50%
proposalMod := dao_proposal_single.NewDAOProposalSingle(daoCore, &dao_proposal_single.DAOProposalSingleOpts{
MaxVotingPeriod: time.Second * 86400,
Threshold: dao_interfaces.Threshold{ThresholdQuorum: &dao_interfaces.ThresholdQuorum{
Threshold: dao_interfaces.PercentageThreshold{Percent: &tt},
Quorum: dao_interfaces.PercentageThreshold{Percent: &tq},
}},
Registry: registry,
})
// TODO: add a router to support multiple proposal modules
registry.Register(dao_proposal_single.NewUpdateSettingsHandler(proposalMod))
daoCore.AddProposalModule(proposalMod)
messagesHandlersFactories := []dao_interfaces.MessageHandlerFactory{
func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler {
return social_feeds.NewBanPostHandler()
},
func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler {
return dao_proposal_single.NewUpdateSettingsHandler(core.ProposalModules()[0].Module.(*dao_proposal_single.DAOProposalSingle))
},
func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler {
return groups.NewAddMemberHandler()
},
func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler {
return groups.NewDeleteMemberHandler()
},
}

registry.Register(social_feeds.NewBanPostHandler())
dao_registry.Register("social_feeds_dao", "Teritori Feed DAO", "https://avatars.githubusercontent.com/u/108656591?s=200&v=4")
daoCore = dao_core.NewDAOCore(votingModuleFactory, proposalModulesFactories, messagesHandlersFactories)
dao_registry.Register("Social Feed Moderation", "DAO responsible for Teritori social feed moderation", "ipfs://bafkreieqcwmjcb64r42ygs6a4dswz63djzgayjn3rhzjber3e42cknawlm")
}

func Render(path string) string {
return "[[feed](/r/demo/social_feeds:" + mainFeedName + ")]\n\n" + daoCore.Render(path)
}

func GetCore() dao_core.IDAOCore {
return daoCore
}

func Vote(moduleIndex int, proposalID int, vote dao_interfaces.Vote, rationale string) {
dao_core.GetProposalModule(daoCore, moduleIndex).Vote(proposalID, vote, rationale)
func VoteJSON(moduleIndex int, proposalID int, voteJSON string) {
// move check in dao core
module := dao_core.GetProposalModule(daoCore, moduleIndex)
if !module.Enabled {
panic("proposal module is not enabled")
}
module.Module.VoteJSON(proposalID, voteJSON)
}

func Execute(moduleIndex int, proposalID int) {
dao_core.GetProposalModule(daoCore, moduleIndex).Execute(proposalID)
}

func Propose(moduleIndex int, title string, description string, b64Messages string) {
mod := dao_core.GetProposalModule(daoCore, moduleIndex)
var messages []dao_interfaces.ExecutableMessage
if len(b64Messages) != 0 {
rawMessages := strings.Split(b64Messages, ",")
for _, rawMessage := range rawMessages {
message := registry.FromBase64String(rawMessage)
messages = append(messages, message)
}
// move check in dao core
module := dao_core.GetProposalModule(daoCore, moduleIndex)
if !module.Enabled {
panic("proposal module is not enabled")
}
mod.Propose(title, description, messages)
module.Module.Execute(proposalID)
}

func GetBinaryMembers() string {
members := groups.GetMembers(groupID)
ss := []string{}
for _, member := range members {
ss = append(ss, base64.RawURLEncoding.EncodeToString(member.Bytes()))
func ProposeJSON(moduleIndex int, proposalJSON string) int {
// move check in dao core
module := dao_core.GetProposalModule(daoCore, moduleIndex)
if !module.Enabled {
panic("proposal module is not enabled")
}
return strings.Join(ss, ",")
return module.Module.ProposeJSON(proposalJSON)
}

func GetProposalsJSON(moduleIndex int) string {
return ujson.FormatSlice(dao_core.GetProposalModule(daoCore, moduleIndex).Proposals())
func getProposalsJSON(moduleIndex int, limit int, startAfter string, reverse bool) string {
// move logic in dao core
module := dao_core.GetProposalModule(daoCore, moduleIndex)
return module.Module.ProposalsJSON(limit, startAfter, reverse)
}

func GetGroupID() uint64 {
return uint64(groupID)
func getProposalJSON(moduleIndex int, proposalIndex int) string {
// move logic in dao core
module := dao_core.GetProposalModule(daoCore, moduleIndex)
return module.Module.ProposalJSON(proposalIndex)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package social_feeds_dao

import (
"fmt"
"std"
"testing"

proposal_single "gno.land/p/demo/daodao/proposal_single"
social_feeds "gno.land/r/demo/social_feeds"
)

func TestSocialFeedsDAO(t *testing.T) {
std.TestSetOrigCaller("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")

// create a post
postID := social_feeds.CreatePost(feedID, social_feeds.PostID(0), 0, "Hello, world!")
_ = social_feeds.GetPost(feedID, postID)

// ban the post
proposalID := ProposeJSON(0, fmt.Sprintf(`{"title": "Ban post", "description": "", "messages": [{"type":"gno.land/r/demo/social_feeds.BanPost","payload":{"feedId":%d,"postId":%d,"reason":"spam"}}]}`, feedID, postID))
VoteJSON(0, proposalID, fmt.Sprintf(`{"vote": %d, "rationale": "%s"}`, proposal_single.VoteYes, "testing"))
Execute(0, proposalID)

// check that the post is deleted
func() {
defer func() {
r := recover()
expected := "Unable to get post"
if r == nil {
t.Errorf("Expected panic while getting post after ban")
} else if r != expected {
t.Errorf("Expected panic with message '%s', got '%s'", expected, r)
}
}()
_ = social_feeds.GetPost(feedID, postID)
}()

// check that the proposal has the correct shape
expected := `{"id":0,"title":"Ban post","description":"","proposer":"g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5","startHeight":123,"threshold":{"thresholdQuorum":{"threshold":{"percent":1500},"quorum":{"percent":5000}}},"totalPower":2,"messages":[{"type":"gno.land/r/demo/social_feeds.BanPost","payload":{"feedId":1,"postId":1,"reason":"spam"}}],"status":"Executed","votes":{"yes":1,"no":0,"abstain":0},"allowRevoting":false,"ballots":{"g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5":{"power":1,"vote":"Yes","rationale":"testing"}}}`
if proposal := getProposalJSON(0, proposalID); proposal != expected {
t.Errorf("Expected proposal to be:\n%s\nGot:\n%s", expected, proposal)
}
}

0 comments on commit aca197f

Please sign in to comment.