Skip to content

Commit 3375be4

Browse files
authored
Merge branch 'master' into feat/remove-is-origin-call
2 parents 2c1fc58 + ddfff60 commit 3375be4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1404
-353
lines changed

contribs/gnogenesis/internal/txs/txs_add_packages.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818

1919
const (
2020
defaultAccount_Name = "test1"
21-
defaultAccount_Address = "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
2221
defaultAccount_Seed = "source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast"
2322
defaultAccount_publicKey = "gpub1pgfj7ard9eg82cjtv4u4xetrwqer2dntxyfzxz3pq0skzdkmzu0r9h6gny6eg8c9dc303xrrudee6z4he4y7cs5rnjwmyf40yaj"
2423
)

contribs/gnomigrate/internal/txs/txs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ func processFile(ctx context.Context, io commands.IO, source, destination string
184184
continue
185185
}
186186

187-
if _, err = outputFile.WriteString(fmt.Sprintf("%s\n", string(marshaledData))); err != nil {
187+
if _, err = fmt.Fprintf(outputFile, "%s\n", marshaledData); err != nil {
188188
io.ErrPrintfln("unable to save to output file, %s", err)
189189
}
190190
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Package addrset provides a specialized set data structure for managing unique Gno addresses.
2+
//
3+
// It is built on top of an AVL tree for efficient operations and maintains addresses in sorted order.
4+
// This package is particularly useful when you need to:
5+
// - Track a collection of unique addresses (e.g., for whitelists, participants, etc.)
6+
// - Efficiently check address membership
7+
// - Support pagination when displaying addresses
8+
//
9+
// Example usage:
10+
//
11+
// import (
12+
// "std"
13+
// "gno.land/p/moul/addrset"
14+
// )
15+
//
16+
// func MyHandler() {
17+
// // Create a new address set
18+
// var set addrset.Set
19+
//
20+
// // Add some addresses
21+
// addr1 := std.Address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
22+
// addr2 := std.Address("g1sss5g0rkqr88k4u648yd5d3l9t4d8vvqwszqth")
23+
//
24+
// set.Add(addr1) // returns true (newly added)
25+
// set.Add(addr2) // returns true (newly added)
26+
// set.Add(addr1) // returns false (already exists)
27+
//
28+
// // Check membership
29+
// if set.Has(addr1) {
30+
// // addr1 is in the set
31+
// }
32+
//
33+
// // Get size
34+
// size := set.Size() // returns 2
35+
//
36+
// // Iterate with pagination (10 items per page, starting at offset 0)
37+
// set.IterateByOffset(0, 10, func(addr std.Address) bool {
38+
// // Process addr
39+
// return false // continue iteration
40+
// })
41+
//
42+
// // Remove an address
43+
// set.Remove(addr1) // returns true (was present)
44+
// set.Remove(addr1) // returns false (not present)
45+
// }
46+
package addrset
47+
48+
import (
49+
"std"
50+
51+
"gno.land/p/demo/avl"
52+
)
53+
54+
type Set struct {
55+
tree avl.Tree
56+
}
57+
58+
// Add inserts an address into the set.
59+
// Returns true if the address was newly added, false if it already existed.
60+
func (s *Set) Add(addr std.Address) bool {
61+
return !s.tree.Set(string(addr), nil)
62+
}
63+
64+
// Remove deletes an address from the set.
65+
// Returns true if the address was found and removed, false if it didn't exist.
66+
func (s *Set) Remove(addr std.Address) bool {
67+
_, removed := s.tree.Remove(string(addr))
68+
return removed
69+
}
70+
71+
// Has checks if an address exists in the set.
72+
func (s *Set) Has(addr std.Address) bool {
73+
return s.tree.Has(string(addr))
74+
}
75+
76+
// Size returns the number of addresses in the set.
77+
func (s *Set) Size() int {
78+
return s.tree.Size()
79+
}
80+
81+
// IterateByOffset walks through addresses starting at the given offset.
82+
// The callback should return true to stop iteration.
83+
func (s *Set) IterateByOffset(offset int, count int, cb func(addr std.Address) bool) {
84+
s.tree.IterateByOffset(offset, count, func(key string, _ interface{}) bool {
85+
return cb(std.Address(key))
86+
})
87+
}
88+
89+
// ReverseIterateByOffset walks through addresses in reverse order starting at the given offset.
90+
// The callback should return true to stop iteration.
91+
func (s *Set) ReverseIterateByOffset(offset int, count int, cb func(addr std.Address) bool) {
92+
s.tree.ReverseIterateByOffset(offset, count, func(key string, _ interface{}) bool {
93+
return cb(std.Address(key))
94+
})
95+
}
96+
97+
// Tree returns the underlying AVL tree for advanced usage.
98+
func (s *Set) Tree() avl.ITree {
99+
return &s.tree
100+
}
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
package addrset
2+
3+
import (
4+
"std"
5+
"testing"
6+
7+
"gno.land/p/demo/uassert"
8+
)
9+
10+
func TestSet(t *testing.T) {
11+
addr1 := std.Address("addr1")
12+
addr2 := std.Address("addr2")
13+
addr3 := std.Address("addr3")
14+
15+
tests := []struct {
16+
name string
17+
actions func(s *Set)
18+
size int
19+
has map[std.Address]bool
20+
addrs []std.Address // for iteration checks
21+
}{
22+
{
23+
name: "empty set",
24+
actions: func(s *Set) {},
25+
size: 0,
26+
has: map[std.Address]bool{addr1: false},
27+
},
28+
{
29+
name: "single address",
30+
actions: func(s *Set) {
31+
s.Add(addr1)
32+
},
33+
size: 1,
34+
has: map[std.Address]bool{
35+
addr1: true,
36+
addr2: false,
37+
},
38+
addrs: []std.Address{addr1},
39+
},
40+
{
41+
name: "multiple addresses",
42+
actions: func(s *Set) {
43+
s.Add(addr1)
44+
s.Add(addr2)
45+
s.Add(addr3)
46+
},
47+
size: 3,
48+
has: map[std.Address]bool{
49+
addr1: true,
50+
addr2: true,
51+
addr3: true,
52+
},
53+
addrs: []std.Address{addr1, addr2, addr3},
54+
},
55+
{
56+
name: "remove address",
57+
actions: func(s *Set) {
58+
s.Add(addr1)
59+
s.Add(addr2)
60+
s.Remove(addr1)
61+
},
62+
size: 1,
63+
has: map[std.Address]bool{
64+
addr1: false,
65+
addr2: true,
66+
},
67+
addrs: []std.Address{addr2},
68+
},
69+
{
70+
name: "duplicate adds",
71+
actions: func(s *Set) {
72+
uassert.True(t, s.Add(addr1)) // first add returns true
73+
uassert.False(t, s.Add(addr1)) // second add returns false
74+
uassert.True(t, s.Remove(addr1)) // remove existing returns true
75+
uassert.False(t, s.Remove(addr1)) // remove non-existing returns false
76+
},
77+
size: 0,
78+
has: map[std.Address]bool{
79+
addr1: false,
80+
},
81+
},
82+
}
83+
84+
for _, tt := range tests {
85+
t.Run(tt.name, func(t *testing.T) {
86+
var set Set
87+
88+
// Execute test actions
89+
tt.actions(&set)
90+
91+
// Check size
92+
uassert.Equal(t, tt.size, set.Size())
93+
94+
// Check existence
95+
for addr, expected := range tt.has {
96+
uassert.Equal(t, expected, set.Has(addr))
97+
}
98+
99+
// Check iteration if addresses are specified
100+
if tt.addrs != nil {
101+
collected := []std.Address{}
102+
set.IterateByOffset(0, 10, func(addr std.Address) bool {
103+
collected = append(collected, addr)
104+
return false
105+
})
106+
107+
// Check length
108+
uassert.Equal(t, len(tt.addrs), len(collected))
109+
110+
// Check each address
111+
for i, addr := range tt.addrs {
112+
uassert.Equal(t, addr, collected[i])
113+
}
114+
}
115+
})
116+
}
117+
}
118+
119+
func TestSetIterationLimits(t *testing.T) {
120+
tests := []struct {
121+
name string
122+
addrs []std.Address
123+
offset int
124+
limit int
125+
expected int
126+
}{
127+
{
128+
name: "zero offset full list",
129+
addrs: []std.Address{"a1", "a2", "a3"},
130+
offset: 0,
131+
limit: 10,
132+
expected: 3,
133+
},
134+
{
135+
name: "offset with limit",
136+
addrs: []std.Address{"a1", "a2", "a3", "a4"},
137+
offset: 1,
138+
limit: 2,
139+
expected: 2,
140+
},
141+
{
142+
name: "offset beyond size",
143+
addrs: []std.Address{"a1", "a2"},
144+
offset: 3,
145+
limit: 1,
146+
expected: 0,
147+
},
148+
}
149+
150+
for _, tt := range tests {
151+
t.Run(tt.name, func(t *testing.T) {
152+
var set Set
153+
for _, addr := range tt.addrs {
154+
set.Add(addr)
155+
}
156+
157+
// Test forward iteration
158+
count := 0
159+
set.IterateByOffset(tt.offset, tt.limit, func(addr std.Address) bool {
160+
count++
161+
return false
162+
})
163+
uassert.Equal(t, tt.expected, count)
164+
165+
// Test reverse iteration
166+
count = 0
167+
set.ReverseIterateByOffset(tt.offset, tt.limit, func(addr std.Address) bool {
168+
count++
169+
return false
170+
})
171+
uassert.Equal(t, tt.expected, count)
172+
})
173+
}
174+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module gno.land/p/moul/addrset

0 commit comments

Comments
 (0)