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

stakeindex.gno

2.46 Kb · 109 lines
  1package kourt
  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}