Skip to content

Commit 50ecb16

Browse files
Dan Lainefjl
andauthored
tests, trie: use slices package for sorting (#27496)
Co-authored-by: Felix Lange <[email protected]>
1 parent 87e510d commit 50ecb16

File tree

5 files changed

+52
-67
lines changed

5 files changed

+52
-67
lines changed

tests/fuzzers/rangeproof/rangeproof-fuzzer.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,19 @@ import (
2121
"encoding/binary"
2222
"fmt"
2323
"io"
24-
"sort"
2524

2625
"github.com/ethereum/go-ethereum/common"
2726
"github.com/ethereum/go-ethereum/core/rawdb"
2827
"github.com/ethereum/go-ethereum/ethdb/memorydb"
2928
"github.com/ethereum/go-ethereum/trie"
29+
"golang.org/x/exp/slices"
3030
)
3131

3232
type kv struct {
3333
k, v []byte
3434
t bool
3535
}
3636

37-
type entrySlice []*kv
38-
39-
func (p entrySlice) Len() int { return len(p) }
40-
func (p entrySlice) Less(i, j int) bool { return bytes.Compare(p[i].k, p[j].k) < 0 }
41-
func (p entrySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
42-
4337
type fuzzer struct {
4438
input io.Reader
4539
exhausted bool
@@ -97,14 +91,16 @@ func (f *fuzzer) fuzz() int {
9791
if f.exhausted {
9892
return 0 // input too short
9993
}
100-
var entries entrySlice
94+
var entries []*kv
10195
for _, kv := range vals {
10296
entries = append(entries, kv)
10397
}
10498
if len(entries) <= 1 {
10599
return 0
106100
}
107-
sort.Sort(entries)
101+
slices.SortFunc(entries, func(a, b *kv) bool {
102+
return bytes.Compare(a.k, b.k) < 0
103+
})
108104

109105
var ok = 0
110106
for {

tests/fuzzers/stacktrie/trie_fuzzer.go

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"fmt"
2424
"hash"
2525
"io"
26-
"sort"
2726

2827
"github.com/ethereum/go-ethereum/common"
2928
"github.com/ethereum/go-ethereum/core/rawdb"
@@ -33,6 +32,7 @@ import (
3332
"github.com/ethereum/go-ethereum/trie"
3433
"github.com/ethereum/go-ethereum/trie/trienode"
3534
"golang.org/x/crypto/sha3"
35+
"golang.org/x/exp/slices"
3636
)
3737

3838
type fuzzer struct {
@@ -104,19 +104,6 @@ func (b *spongeBatch) Replay(w ethdb.KeyValueWriter) error { return nil }
104104
type kv struct {
105105
k, v []byte
106106
}
107-
type kvs []kv
108-
109-
func (k kvs) Len() int {
110-
return len(k)
111-
}
112-
113-
func (k kvs) Less(i, j int) bool {
114-
return bytes.Compare(k[i].k, k[j].k) < 0
115-
}
116-
117-
func (k kvs) Swap(i, j int) {
118-
k[j], k[i] = k[i], k[j]
119-
}
120107

121108
// Fuzz is the fuzzing entry-point.
122109
// The function must return
@@ -156,7 +143,7 @@ func (f *fuzzer) fuzz() int {
156143
trieB = trie.NewStackTrie(func(owner common.Hash, path []byte, hash common.Hash, blob []byte) {
157144
rawdb.WriteTrieNode(spongeB, owner, path, hash, blob, dbB.Scheme())
158145
})
159-
vals kvs
146+
vals []kv
160147
useful bool
161148
maxElements = 10000
162149
// operate on unique keys only
@@ -192,7 +179,9 @@ func (f *fuzzer) fuzz() int {
192179
dbA.Commit(rootA, false)
193180

194181
// Stacktrie requires sorted insertion
195-
sort.Sort(vals)
182+
slices.SortFunc(vals, func(a, b kv) bool {
183+
return bytes.Compare(a.k, b.k) < 0
184+
})
196185
for _, kv := range vals {
197186
if f.debugging {
198187
fmt.Printf("{\"%#x\" , \"%#x\"} // stacktrie.Update\n", kv.k, kv.v)

trie/iterator_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ type kv struct {
8484
t bool
8585
}
8686

87+
func (k *kv) less(other *kv) bool {
88+
return bytes.Compare(k.k, other.k) < 0
89+
}
90+
8791
func TestIteratorLargeData(t *testing.T) {
8892
trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
8993
vals := make(map[string]*kv)

trie/proof_test.go

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ import (
2222
"encoding/binary"
2323
"fmt"
2424
mrand "math/rand"
25-
"sort"
2625
"testing"
2726

2827
"github.com/ethereum/go-ethereum/common"
2928
"github.com/ethereum/go-ethereum/core/rawdb"
3029
"github.com/ethereum/go-ethereum/crypto"
3130
"github.com/ethereum/go-ethereum/ethdb/memorydb"
31+
"golang.org/x/exp/slices"
3232
)
3333

3434
// Prng is a pseudo random number generator seeded by strong randomness.
@@ -165,21 +165,15 @@ func TestMissingKeyProof(t *testing.T) {
165165
}
166166
}
167167

168-
type entrySlice []*kv
169-
170-
func (p entrySlice) Len() int { return len(p) }
171-
func (p entrySlice) Less(i, j int) bool { return bytes.Compare(p[i].k, p[j].k) < 0 }
172-
func (p entrySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
173-
174168
// TestRangeProof tests normal range proof with both edge proofs
175169
// as the existent proof. The test cases are generated randomly.
176170
func TestRangeProof(t *testing.T) {
177171
trie, vals := randomTrie(4096)
178-
var entries entrySlice
172+
var entries []*kv
179173
for _, kv := range vals {
180174
entries = append(entries, kv)
181175
}
182-
sort.Sort(entries)
176+
slices.SortFunc(entries, (*kv).less)
183177
for i := 0; i < 500; i++ {
184178
start := mrand.Intn(len(entries))
185179
end := mrand.Intn(len(entries)-start) + start + 1
@@ -208,11 +202,11 @@ func TestRangeProof(t *testing.T) {
208202
// The test cases are generated randomly.
209203
func TestRangeProofWithNonExistentProof(t *testing.T) {
210204
trie, vals := randomTrie(4096)
211-
var entries entrySlice
205+
var entries []*kv
212206
for _, kv := range vals {
213207
entries = append(entries, kv)
214208
}
215-
sort.Sort(entries)
209+
slices.SortFunc(entries, (*kv).less)
216210
for i := 0; i < 500; i++ {
217211
start := mrand.Intn(len(entries))
218212
end := mrand.Intn(len(entries)-start) + start + 1
@@ -280,11 +274,11 @@ func TestRangeProofWithNonExistentProof(t *testing.T) {
280274
// - There exists a gap between the last element and the right edge proof
281275
func TestRangeProofWithInvalidNonExistentProof(t *testing.T) {
282276
trie, vals := randomTrie(4096)
283-
var entries entrySlice
277+
var entries []*kv
284278
for _, kv := range vals {
285279
entries = append(entries, kv)
286280
}
287-
sort.Sort(entries)
281+
slices.SortFunc(entries, (*kv).less)
288282

289283
// Case 1
290284
start, end := 100, 200
@@ -337,11 +331,11 @@ func TestRangeProofWithInvalidNonExistentProof(t *testing.T) {
337331
// non-existent one.
338332
func TestOneElementRangeProof(t *testing.T) {
339333
trie, vals := randomTrie(4096)
340-
var entries entrySlice
334+
var entries []*kv
341335
for _, kv := range vals {
342336
entries = append(entries, kv)
343337
}
344-
sort.Sort(entries)
338+
slices.SortFunc(entries, (*kv).less)
345339

346340
// One element with existent edge proof, both edge proofs
347341
// point to the SAME key.
@@ -424,11 +418,11 @@ func TestOneElementRangeProof(t *testing.T) {
424418
// The edge proofs can be nil.
425419
func TestAllElementsProof(t *testing.T) {
426420
trie, vals := randomTrie(4096)
427-
var entries entrySlice
421+
var entries []*kv
428422
for _, kv := range vals {
429423
entries = append(entries, kv)
430424
}
431-
sort.Sort(entries)
425+
slices.SortFunc(entries, (*kv).less)
432426

433427
var k [][]byte
434428
var v [][]byte
@@ -474,13 +468,13 @@ func TestAllElementsProof(t *testing.T) {
474468
func TestSingleSideRangeProof(t *testing.T) {
475469
for i := 0; i < 64; i++ {
476470
trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
477-
var entries entrySlice
471+
var entries []*kv
478472
for i := 0; i < 4096; i++ {
479473
value := &kv{randBytes(32), randBytes(20), false}
480474
trie.MustUpdate(value.k, value.v)
481475
entries = append(entries, value)
482476
}
483-
sort.Sort(entries)
477+
slices.SortFunc(entries, (*kv).less)
484478

485479
var cases = []int{0, 1, 50, 100, 1000, 2000, len(entries) - 1}
486480
for _, pos := range cases {
@@ -509,13 +503,13 @@ func TestSingleSideRangeProof(t *testing.T) {
509503
func TestReverseSingleSideRangeProof(t *testing.T) {
510504
for i := 0; i < 64; i++ {
511505
trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
512-
var entries entrySlice
506+
var entries []*kv
513507
for i := 0; i < 4096; i++ {
514508
value := &kv{randBytes(32), randBytes(20), false}
515509
trie.MustUpdate(value.k, value.v)
516510
entries = append(entries, value)
517511
}
518-
sort.Sort(entries)
512+
slices.SortFunc(entries, (*kv).less)
519513

520514
var cases = []int{0, 1, 50, 100, 1000, 2000, len(entries) - 1}
521515
for _, pos := range cases {
@@ -545,11 +539,11 @@ func TestReverseSingleSideRangeProof(t *testing.T) {
545539
// The prover is expected to detect the error.
546540
func TestBadRangeProof(t *testing.T) {
547541
trie, vals := randomTrie(4096)
548-
var entries entrySlice
542+
var entries []*kv
549543
for _, kv := range vals {
550544
entries = append(entries, kv)
551545
}
552-
sort.Sort(entries)
546+
slices.SortFunc(entries, (*kv).less)
553547

554548
for i := 0; i < 500; i++ {
555549
start := mrand.Intn(len(entries))
@@ -648,11 +642,11 @@ func TestGappedRangeProof(t *testing.T) {
648642
// TestSameSideProofs tests the element is not in the range covered by proofs
649643
func TestSameSideProofs(t *testing.T) {
650644
trie, vals := randomTrie(4096)
651-
var entries entrySlice
645+
var entries []*kv
652646
for _, kv := range vals {
653647
entries = append(entries, kv)
654648
}
655-
sort.Sort(entries)
649+
slices.SortFunc(entries, (*kv).less)
656650

657651
pos := 1000
658652
first := decreaseKey(common.CopyBytes(entries[pos].k))
@@ -690,13 +684,13 @@ func TestSameSideProofs(t *testing.T) {
690684

691685
func TestHasRightElement(t *testing.T) {
692686
trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
693-
var entries entrySlice
687+
var entries []*kv
694688
for i := 0; i < 4096; i++ {
695689
value := &kv{randBytes(32), randBytes(20), false}
696690
trie.MustUpdate(value.k, value.v)
697691
entries = append(entries, value)
698692
}
699-
sort.Sort(entries)
693+
slices.SortFunc(entries, (*kv).less)
700694

701695
var cases = []struct {
702696
start int
@@ -764,11 +758,11 @@ func TestHasRightElement(t *testing.T) {
764758
// The first edge proof must be a non-existent proof.
765759
func TestEmptyRangeProof(t *testing.T) {
766760
trie, vals := randomTrie(4096)
767-
var entries entrySlice
761+
var entries []*kv
768762
for _, kv := range vals {
769763
entries = append(entries, kv)
770764
}
771-
sort.Sort(entries)
765+
slices.SortFunc(entries, (*kv).less)
772766

773767
var cases = []struct {
774768
pos int
@@ -799,11 +793,11 @@ func TestEmptyRangeProof(t *testing.T) {
799793
func TestBloatedProof(t *testing.T) {
800794
// Use a small trie
801795
trie, kvs := nonRandomTrie(100)
802-
var entries entrySlice
796+
var entries []*kv
803797
for _, kv := range kvs {
804798
entries = append(entries, kv)
805799
}
806-
sort.Sort(entries)
800+
slices.SortFunc(entries, (*kv).less)
807801
var keys [][]byte
808802
var vals [][]byte
809803

@@ -833,11 +827,11 @@ func TestBloatedProof(t *testing.T) {
833827
// noop technically, but practically should be rejected.
834828
func TestEmptyValueRangeProof(t *testing.T) {
835829
trie, values := randomTrie(512)
836-
var entries entrySlice
830+
var entries []*kv
837831
for _, kv := range values {
838832
entries = append(entries, kv)
839833
}
840-
sort.Sort(entries)
834+
slices.SortFunc(entries, (*kv).less)
841835

842836
// Create a new entry with a slightly modified key
843837
mid := len(entries) / 2
@@ -877,11 +871,11 @@ func TestEmptyValueRangeProof(t *testing.T) {
877871
// practically should be rejected.
878872
func TestAllElementsEmptyValueRangeProof(t *testing.T) {
879873
trie, values := randomTrie(512)
880-
var entries entrySlice
874+
var entries []*kv
881875
for _, kv := range values {
882876
entries = append(entries, kv)
883877
}
884-
sort.Sort(entries)
878+
slices.SortFunc(entries, (*kv).less)
885879

886880
// Create a new entry with a slightly modified key
887881
mid := len(entries) / 2
@@ -983,11 +977,11 @@ func BenchmarkVerifyRangeProof5000(b *testing.B) { benchmarkVerifyRangeProof(b,
983977

984978
func benchmarkVerifyRangeProof(b *testing.B, size int) {
985979
trie, vals := randomTrie(8192)
986-
var entries entrySlice
980+
var entries []*kv
987981
for _, kv := range vals {
988982
entries = append(entries, kv)
989983
}
990-
sort.Sort(entries)
984+
slices.SortFunc(entries, (*kv).less)
991985

992986
start := 2
993987
end := start + size
@@ -1020,11 +1014,11 @@ func BenchmarkVerifyRangeNoProof1000(b *testing.B) { benchmarkVerifyRangeNoProof
10201014

10211015
func benchmarkVerifyRangeNoProof(b *testing.B, size int) {
10221016
trie, vals := randomTrie(size)
1023-
var entries entrySlice
1017+
var entries []*kv
10241018
for _, kv := range vals {
10251019
entries = append(entries, kv)
10261020
}
1027-
sort.Sort(entries)
1021+
slices.SortFunc(entries, (*kv).less)
10281022

10291023
var keys [][]byte
10301024
var values [][]byte

trie/trienode/node.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ package trienode
1818

1919
import (
2020
"fmt"
21-
"sort"
2221
"strings"
2322

2423
"github.com/ethereum/go-ethereum/common"
24+
"golang.org/x/exp/slices"
2525
)
2626

2727
// Node is a wrapper which contains the encoded blob of the trie node and its
@@ -100,12 +100,14 @@ func NewNodeSet(owner common.Hash) *NodeSet {
100100
// ForEachWithOrder iterates the nodes with the order from bottom to top,
101101
// right to left, nodes with the longest path will be iterated first.
102102
func (set *NodeSet) ForEachWithOrder(callback func(path string, n *Node)) {
103-
var paths sort.StringSlice
103+
var paths []string
104104
for path := range set.Nodes {
105105
paths = append(paths, path)
106106
}
107107
// Bottom-up, longest path first
108-
sort.Sort(sort.Reverse(paths))
108+
slices.SortFunc(paths, func(a, b string) bool {
109+
return a > b // Sort in reverse order
110+
})
109111
for _, path := range paths {
110112
callback(path, set.Nodes[path].Unwrap())
111113
}

0 commit comments

Comments
 (0)