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}