eth: use slices package for sorting (#27490)

Also adds Hash.Less method for sorting purposes.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
Dan Laine
2023-06-19 23:38:57 +02:00
committed by GitHub
co-authored by Felix Lange
parent 9a167c45d1
commit b1ef0bfe03
6 changed files with 61 additions and 104 deletions
+27 -30
View File
@@ -22,7 +22,6 @@ import (
"encoding/binary"
"fmt"
"math/big"
"sort"
"sync"
"testing"
"time"
@@ -38,6 +37,7 @@ import (
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/trie/trienode"
"golang.org/x/crypto/sha3"
"golang.org/x/exp/slices"
)
func TestHashing(t *testing.T) {
@@ -127,9 +127,9 @@ type testPeer struct {
remote *Syncer
logger log.Logger
accountTrie *trie.Trie
accountValues entrySlice
accountValues []*kv
storageTries map[common.Hash]*trie.Trie
storageValues map[common.Hash]entrySlice
storageValues map[common.Hash][]*kv
accountRequestHandler accountHandlerFunc
storageRequestHandler storageHandlerFunc
@@ -1321,12 +1321,9 @@ type kv struct {
k, v []byte
}
// Some helpers for sorting
type entrySlice []*kv
func (p entrySlice) Len() int { return len(p) }
func (p entrySlice) Less(i, j int) bool { return bytes.Compare(p[i].k, p[j].k) < 0 }
func (p entrySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (k *kv) less(other *kv) bool {
return bytes.Compare(k.k, other.k) < 0
}
func key32(i uint64) []byte {
key := make([]byte, 32)
@@ -1367,11 +1364,11 @@ func getCodeByHash(hash common.Hash) []byte {
}
// makeAccountTrieNoStorage spits out a trie, along with the leafs
func makeAccountTrieNoStorage(n int) (string, *trie.Trie, entrySlice) {
func makeAccountTrieNoStorage(n int) (string, *trie.Trie, []*kv) {
var (
db = trie.NewDatabase(rawdb.NewMemoryDatabase())
accTrie = trie.NewEmpty(db)
entries entrySlice
entries []*kv
)
for i := uint64(1); i <= uint64(n); i++ {
value, _ := rlp.EncodeToBytes(&types.StateAccount{
@@ -1385,7 +1382,7 @@ func makeAccountTrieNoStorage(n int) (string, *trie.Trie, entrySlice) {
accTrie.MustUpdate(elem.k, elem.v)
entries = append(entries, elem)
}
sort.Sort(entries)
slices.SortFunc(entries, (*kv).less)
// Commit the state changes into db and re-create the trie
// for accessing later.
@@ -1399,9 +1396,9 @@ func makeAccountTrieNoStorage(n int) (string, *trie.Trie, entrySlice) {
// makeBoundaryAccountTrie constructs an account trie. Instead of filling
// accounts normally, this function will fill a few accounts which have
// boundary hash.
func makeBoundaryAccountTrie(n int) (string, *trie.Trie, entrySlice) {
func makeBoundaryAccountTrie(n int) (string, *trie.Trie, []*kv) {
var (
entries entrySlice
entries []*kv
boundaries []common.Hash
db = trie.NewDatabase(rawdb.NewMemoryDatabase())
@@ -1447,7 +1444,7 @@ func makeBoundaryAccountTrie(n int) (string, *trie.Trie, entrySlice) {
accTrie.MustUpdate(elem.k, elem.v)
entries = append(entries, elem)
}
sort.Sort(entries)
slices.SortFunc(entries, (*kv).less)
// Commit the state changes into db and re-create the trie
// for accessing later.
@@ -1460,14 +1457,14 @@ func makeBoundaryAccountTrie(n int) (string, *trie.Trie, entrySlice) {
// makeAccountTrieWithStorageWithUniqueStorage creates an account trie where each accounts
// has a unique storage set.
func makeAccountTrieWithStorageWithUniqueStorage(accounts, slots int, code bool) (string, *trie.Trie, entrySlice, map[common.Hash]*trie.Trie, map[common.Hash]entrySlice) {
func makeAccountTrieWithStorageWithUniqueStorage(accounts, slots int, code bool) (string, *trie.Trie, []*kv, map[common.Hash]*trie.Trie, map[common.Hash][]*kv) {
var (
db = trie.NewDatabase(rawdb.NewMemoryDatabase())
accTrie = trie.NewEmpty(db)
entries entrySlice
entries []*kv
storageRoots = make(map[common.Hash]common.Hash)
storageTries = make(map[common.Hash]*trie.Trie)
storageEntries = make(map[common.Hash]entrySlice)
storageEntries = make(map[common.Hash][]*kv)
nodes = trienode.NewMergedNodeSet()
)
// Create n accounts in the trie
@@ -1494,7 +1491,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(accounts, slots int, code bool)
storageRoots[common.BytesToHash(key)] = stRoot
storageEntries[common.BytesToHash(key)] = stEntries
}
sort.Sort(entries)
slices.SortFunc(entries, (*kv).less)
// Commit account trie
root, set := accTrie.Commit(true)
@@ -1515,14 +1512,14 @@ func makeAccountTrieWithStorageWithUniqueStorage(accounts, slots int, code bool)
}
// makeAccountTrieWithStorage spits out a trie, along with the leafs
func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (string, *trie.Trie, entrySlice, map[common.Hash]*trie.Trie, map[common.Hash]entrySlice) {
func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (string, *trie.Trie, []*kv, map[common.Hash]*trie.Trie, map[common.Hash][]*kv) {
var (
db = trie.NewDatabase(rawdb.NewMemoryDatabase())
accTrie = trie.NewEmpty(db)
entries entrySlice
entries []*kv
storageRoots = make(map[common.Hash]common.Hash)
storageTries = make(map[common.Hash]*trie.Trie)
storageEntries = make(map[common.Hash]entrySlice)
storageEntries = make(map[common.Hash][]*kv)
nodes = trienode.NewMergedNodeSet()
)
// Create n accounts in the trie
@@ -1536,7 +1533,7 @@ func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (strin
var (
stRoot common.Hash
stNodes *trienode.NodeSet
stEntries entrySlice
stEntries []*kv
)
if boundary {
stRoot, stNodes, stEntries = makeBoundaryStorageTrie(common.BytesToHash(key), slots, db)
@@ -1559,7 +1556,7 @@ func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (strin
storageRoots[common.BytesToHash(key)] = stRoot
storageEntries[common.BytesToHash(key)] = stEntries
}
sort.Sort(entries)
slices.SortFunc(entries, (*kv).less)
// Commit account trie
root, set := accTrie.Commit(true)
@@ -1588,9 +1585,9 @@ func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (strin
// makeStorageTrieWithSeed fills a storage trie with n items, returning the
// not-yet-committed trie and the sorted entries. The seeds can be used to ensure
// that tries are unique.
func makeStorageTrieWithSeed(owner common.Hash, n, seed uint64, db *trie.Database) (common.Hash, *trienode.NodeSet, entrySlice) {
func makeStorageTrieWithSeed(owner common.Hash, n, seed uint64, db *trie.Database) (common.Hash, *trienode.NodeSet, []*kv) {
trie, _ := trie.New(trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash), db)
var entries entrySlice
var entries []*kv
for i := uint64(1); i <= n; i++ {
// store 'x' at slot 'x'
slotValue := key32(i + seed)
@@ -1603,7 +1600,7 @@ func makeStorageTrieWithSeed(owner common.Hash, n, seed uint64, db *trie.Databas
trie.MustUpdate(elem.k, elem.v)
entries = append(entries, elem)
}
sort.Sort(entries)
slices.SortFunc(entries, (*kv).less)
root, nodes := trie.Commit(false)
return root, nodes, entries
}
@@ -1611,9 +1608,9 @@ func makeStorageTrieWithSeed(owner common.Hash, n, seed uint64, db *trie.Databas
// makeBoundaryStorageTrie constructs a storage trie. Instead of filling
// storage slots normally, this function will fill a few slots which have
// boundary hash.
func makeBoundaryStorageTrie(owner common.Hash, n int, db *trie.Database) (common.Hash, *trienode.NodeSet, entrySlice) {
func makeBoundaryStorageTrie(owner common.Hash, n int, db *trie.Database) (common.Hash, *trienode.NodeSet, []*kv) {
var (
entries entrySlice
entries []*kv
boundaries []common.Hash
trie, _ = trie.New(trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash), db)
)
@@ -1654,7 +1651,7 @@ func makeBoundaryStorageTrie(owner common.Hash, n int, db *trie.Database) (commo
trie.MustUpdate(elem.k, elem.v)
entries = append(entries, elem)
}
sort.Sort(entries)
slices.SortFunc(entries, (*kv).less)
root, nodes := trie.Commit(false)
return root, nodes, entries
}