Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

votelock.gno

2.95 Kb · 124 lines
  1package kourt
  2import "gno.land/p/nt/bptree/v0"
  3const (
  4	voteLockDispute  = "d"
  5	voteLockElection = "e"
  6)
  7func voteLockKey(who address, kind string, id, sub uint64) string {
  8	return string(who) + kind + beClaimKey(id) + beClaimKey(sub)
  9}
 10func voteLockParts(who address, key string) (kind string, id, sub uint64, ok bool) {
 11	tail := key[len(string(who)):]
 12	if len(tail) != 1+8+8 {
 13		return "", 0, 0, false
 14	}
 15	return tail[0:1], beClaimID(tail[1:9]), beClaimID(tail[9:17]), true
 16}
 17func voteLockOpen(c *Court, who address, key string) bool {
 18	kind, id, sub, ok := voteLockParts(who, key)
 19	if !ok {
 20		return false
 21	}
 22	switch kind {
 23	case voteLockDispute:
 24		v := c.claims.Get(beClaimKey(id))
 25		if v == nil {
 26			return false
 27		}
 28		cs := v.(*claimState)
 29		return cs.disputeOpen && cs.proposalID == int64(sub)
 30	case voteLockElection:
 31		if c.mod == nil || c.mod.election == nil {
 32			return false
 33		}
 34		e := c.mod.election
 35		return e.seq == id && !e.resolved
 36	}
 37	return false
 38}
 39func voteLockedOf(c *Court, who address) int64 {
 40	if c.voteLocks == nil {
 41		return 0
 42	}
 43	var most int64
 44	pre := string(who)
 45	c.voteLocks.Iterate(pre, pre+"\xff", func(k string, v any) bool {
 46		if w := v.(int64); w > most && voteLockOpen(c, who, k) {
 47			most = w
 48		}
 49		return false
 50	})
 51	return most
 52}
 53func lockVote(c *Court, who address, kind string, id, sub, amount int64) {
 54	if amount <= 0 {
 55		return
 56	}
 57	if c.voteLocks == nil {
 58		c.voteLocks = bptree.NewBPTree32()
 59	}
 60	pruneVoteLocks(c, who)
 61	c.voteLocks.Set(voteLockKey(who, kind, uint64(id), uint64(sub)), amount)
 62}
 63func pruneVoteLocks(c *Court, who address) int {
 64	if c.voteLocks == nil {
 65		return 0
 66	}
 67	var stale []string
 68	pre := string(who)
 69	c.voteLocks.Iterate(pre, pre+"\xff", func(k string, _ any) bool {
 70		if _, _, _, ok := voteLockParts(who, k); !ok {
 71			return false
 72		}
 73		if !voteLockOpen(c, who, k) {
 74			stale = append(stale, k)
 75		}
 76		return false
 77	})
 78	for _, k := range stale {
 79		c.voteLocks.Remove(k)
 80	}
 81	return len(stale)
 82}
 83func beClaimID(s string) uint64 {
 84	var v uint64
 85	for i := 0; i < 8; i++ {
 86		v = v<<8 | uint64(s[i])
 87	}
 88	return v
 89}
 90func PruneVoteLocks(cur realm, courtSlug string, who address) int {
 91	if !cur.IsCurrent() {
 92		panic(errStaleRealm)
 93	}
 94	if !who.IsValid() {
 95		panic("kourtv2: that is not a valid address")
 96	}
 97	return pruneVoteLocks(mustCourt(courtSlug), who)
 98}
 99func CommitmentsOf(courtSlug string, who address) string {
100	c := mustCourt(courtSlug)
101	out := "stake:" + itoa(lockedOf(c, who)) +
102		";vote:" + itoa(voteLockedOf(c, who)) +
103		";free:" + itoa(disposable(c, who))
104	if c.voteLocks == nil {
105		return out
106	}
107	pre := string(who)
108	c.voteLocks.Iterate(pre, pre+"\xff", func(k string, v any) bool {
109		if !voteLockOpen(c, who, k) {
110			return false
111		}
112		kind, id, sub, ok := voteLockParts(who, k)
113		if !ok {
114			return false
115		}
116		out += ";q:" + kind + ":" + itoa(int64(id)) + ":" + itoa(int64(sub)) +
117			":" + itoa(v.(int64))
118		return false
119	})
120	return out
121}
122func VoteLockedOf(courtSlug string, who address) int64 {
123	return voteLockedOf(mustCourt(courtSlug), who)
124}