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.

stakeindex.gno

2.47 Kb · 109 lines
  1package kourtv3
  2const stakeIdxPage = 64
  3const stakeIdxEntry = 9
  4const stakePageMax = 200
  5type stakeRow struct {
  6	packed string
  7}
  8func stakeIdxKey(who address, claimID uint64) string {
  9	return string(who) + beClaimKey(claimID/stakeIdxPage)
 10}
 11func sideByte(side int) string {
 12	if side == sideYES {
 13		return "y"
 14	}
 15	return "n"
 16}
 17func stakeIdxMine(pre, k string) bool { return len(k) == len(pre)+8 }
 18func indexPosition(c *Court, claimID uint64, who address, side int) {
 19	k := stakeIdxKey(who, claimID)
 20	entry := beClaimKey(claimID) + sideByte(side)
 21	if v := c.stakeIdx.Get(k); v != nil {
 22		r := v.(*stakeRow)
 23		r.packed += entry
 24		return
 25	}
 26	c.stakeIdx.Set(k, &stakeRow{packed: entry})
 27}
 28func stakeIdxWalk(c *Court, who address, fn func(claimID uint64, side int) bool) {
 29	if c.stakeIdx == nil {
 30		return
 31	}
 32	pre := string(who)
 33	c.stakeIdx.Iterate(pre, pre+"\xff", func(k string, v any) bool {
 34		if !stakeIdxMine(pre, k) {
 35			return false
 36		}
 37		r, ok := v.(*stakeRow)
 38		if !ok {
 39			return false
 40		}
 41		for i := 0; i+stakeIdxEntry <= len(r.packed); i += stakeIdxEntry {
 42			side := sideNO
 43			if r.packed[i+8] == 'y' {
 44				side = sideYES
 45			}
 46			if fn(beClaimID(r.packed[i:i+8]), side) {
 47				return true
 48			}
 49		}
 50		return false
 51	})
 52}
 53func stakeIdxCount(c *Court, who address) int {
 54	if c.stakeIdx == nil {
 55		return 0
 56	}
 57	n, pre := 0, string(who)
 58	c.stakeIdx.Iterate(pre, pre+"\xff", func(k string, v any) bool {
 59		if !stakeIdxMine(pre, k) {
 60			return false
 61		}
 62		if r, ok := v.(*stakeRow); ok {
 63			n += len(r.packed) / stakeIdxEntry
 64		}
 65		return false
 66	})
 67	return n
 68}
 69func StakedSize(courtSlug string, who address) int {
 70	if !who.IsValid() {
 71		return 0
 72	}
 73	return stakeIdxCount(mustCourt(courtSlug), who)
 74}
 75func StakedPage(courtSlug string, who address, offset, limit int) string {
 76	if !who.IsValid() {
 77		return ""
 78	}
 79	if limit <= 0 || limit > stakePageMax {
 80		limit = stakePageMax
 81	}
 82	c := mustCourt(courtSlug)
 83	acc := ratePreview(c)
 84	out, seen, sent := "", 0, 0
 85	stakeIdxWalk(c, who, func(claimID uint64, side int) bool {
 86		if seen < offset {
 87			seen++
 88			return false
 89		}
 90		seen++
 91		var live, conv int64
 92		if cv := c.claims.Get(beClaimKey(claimID)); cv != nil {
 93			cs := cv.(*claimState)
 94			if pv := cs.stakers.Get(posKey(who, side)); pv != nil {
 95				pos := pv.(*stakePos)
 96				live = pos.stake
 97				conv = convPreviewCC(cs, pos, acc)
 98			}
 99		}
100		out += ";c:" + itoa(int64(claimID)) + ":" + itoa(int64(side)) +
101			":" + itoa(live) + ":" + itoa(conv)
102		sent++
103		return sent >= limit
104	})
105	if out == "" {
106		return ""
107	}
108	return out[1:]
109}