all: drop x/exp direct dependency (#30558)

This is a not-particularly-important "cleanliness" PR. It removes the
last remnants of the `x/exp` package, where we used the `maps.Keys`
function.

The original returned the keys in a slice, but when it became 'native'
the signature changed to return an iterator, so the new idiom is
`slices.Collect(maps.Keys(theMap))`, unless of course the raw iterator
can be used instead.

In some cases, where we previously collect into slice and then sort, we
can now instead do `slices.SortXX` on the iterator instead, making the
code a bit more concise.

This PR might be _slighly_ less optimal, because the original `x/exp`
implementation allocated the slice at the correct size off the bat,
which I suppose the new code won't.

Putting it up for discussion.

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
Martin HS 2025-02-27 15:53:52 +01:00 committed by GitHub
parent f005d95b55
commit 767c202e47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 24 additions and 36 deletions

View File

@ -24,6 +24,7 @@ import (
"errors"
"fmt"
"io"
"maps"
"math/big"
"os"
"path/filepath"
@ -40,7 +41,6 @@ import (
"github.com/ethereum/go-ethereum/eth/protocols/eth"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"golang.org/x/exp/maps"
)
// Chain is a lightweight blockchain-like store which can read a hivechain
@ -162,8 +162,8 @@ func (c *Chain) RootAt(height int) common.Hash {
// GetSender returns the address associated with account at the index in the
// pre-funded accounts list.
func (c *Chain) GetSender(idx int) (common.Address, uint64) {
accounts := maps.Keys(c.senders)
slices.SortFunc(accounts, common.Address.Cmp)
accounts := slices.SortedFunc(maps.Keys(c.senders), common.Address.Cmp)
addr := accounts[idx]
return addr, c.senders[addr].Nonce
}

View File

@ -20,6 +20,7 @@ import (
"encoding/json"
"errors"
"fmt"
"maps"
"os"
"regexp"
"slices"
@ -28,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/tests"
"github.com/urfave/cli/v2"
"golang.org/x/exp/maps"
)
var blockTestCommand = &cli.Command{
@ -80,8 +80,7 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) {
tracer := tracerFromFlags(ctx)
// Pull out keys to sort and ensure tests are run in order.
keys := maps.Keys(tests)
slices.Sort(keys)
keys := slices.Sorted(maps.Keys(tests))
// Run all the tests.
var results []testResult

View File

@ -19,6 +19,7 @@ package snapshot
import (
"encoding/binary"
"fmt"
"maps"
"math"
"math/rand"
"slices"
@ -30,7 +31,6 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
bloomfilter "github.com/holiman/bloomfilter/v2"
"golang.org/x/exp/maps"
)
var (
@ -431,8 +431,7 @@ func (dl *diffLayer) AccountList() []common.Hash {
dl.lock.Lock()
defer dl.lock.Unlock()
dl.accountList = maps.Keys(dl.accountData)
slices.SortFunc(dl.accountList, common.Hash.Cmp)
dl.accountList = slices.SortedFunc(maps.Keys(dl.accountData), common.Hash.Cmp)
dl.memory += uint64(len(dl.accountList) * common.HashLength)
return dl.accountList
}
@ -464,8 +463,7 @@ func (dl *diffLayer) StorageList(accountHash common.Hash) []common.Hash {
dl.lock.Lock()
defer dl.lock.Unlock()
storageList := maps.Keys(dl.storageData[accountHash])
slices.SortFunc(storageList, common.Hash.Cmp)
storageList := slices.SortedFunc(maps.Keys(dl.storageData[accountHash]), common.Hash.Cmp)
dl.storageList[accountHash] = storageList
dl.memory += uint64(len(dl.storageList)*common.HashLength + common.HashLength)
return storageList

View File

@ -18,12 +18,12 @@ package blobpool
import (
"container/heap"
"maps"
"math"
"slices"
"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
"golang.org/x/exp/maps"
)
// evictHeap is a helper data structure to keep track of the cheapest bottleneck
@ -54,8 +54,7 @@ func newPriceHeap(basefee *uint256.Int, blobfee *uint256.Int, index map[common.A
// Populate the heap in account sort order. Not really needed in practice,
// but it makes the heap initialization deterministic and less annoying to
// test in unit tests.
heap.addrs = maps.Keys(index)
slices.SortFunc(heap.addrs, common.Address.Cmp)
heap.addrs = slices.SortedFunc(maps.Keys(index), common.Address.Cmp)
for i, addr := range heap.addrs {
heap.index[addr] = i
}

View File

@ -19,6 +19,7 @@ package legacypool
import (
"errors"
"maps"
"math"
"math/big"
"slices"
@ -40,7 +41,6 @@ import (
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
"github.com/holiman/uint256"
"golang.org/x/exp/maps"
)
const (
@ -1674,7 +1674,7 @@ func (as *accountSet) addTx(tx *types.Transaction) {
// reuse. The returned slice should not be changed!
func (as *accountSet) flatten() []common.Address {
if as.cache == nil {
as.cache = maps.Keys(as.accounts)
as.cache = slices.Collect(maps.Keys(as.accounts))
}
return as.cache
}

View File

@ -18,6 +18,7 @@
package locals
import (
"slices"
"sync"
"time"
@ -28,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
"golang.org/x/exp/slices"
)
var (

2
go.mod
View File

@ -65,7 +65,6 @@ require (
go.uber.org/automaxprocs v1.5.2
go.uber.org/goleak v1.3.0
golang.org/x/crypto v0.32.0
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
golang.org/x/sync v0.10.0
golang.org/x/sys v0.29.0
golang.org/x/text v0.21.0
@ -142,6 +141,7 @@ require (
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.34.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

4
go.sum
View File

@ -553,8 +553,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=

View File

@ -21,12 +21,11 @@ import (
"bytes"
"errors"
"fmt"
"maps"
"net"
"net/netip"
"slices"
"strings"
"golang.org/x/exp/maps"
)
var special4, special6 Netlist
@ -324,8 +323,7 @@ func (s *DistinctNetSet) key(ip netip.Addr) netip.Prefix {
// String implements fmt.Stringer
func (s DistinctNetSet) String() string {
keys := maps.Keys(s.members)
slices.SortFunc(keys, func(a, b netip.Prefix) int {
keys := slices.SortedFunc(maps.Keys(s.members), func(a, b netip.Prefix) int {
return strings.Compare(a.String(), b.String())
})

View File

@ -21,6 +21,7 @@ import (
"encoding/binary"
"errors"
"fmt"
"maps"
"slices"
"time"
@ -29,7 +30,6 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"golang.org/x/exp/maps"
)
// State history records the state changes involved in executing a block. The
@ -250,15 +250,11 @@ type history struct {
// newHistory constructs the state history object with provided state change set.
func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, rawStorageKey bool) *history {
var (
accountList = maps.Keys(accounts)
accountList = slices.SortedFunc(maps.Keys(accounts), common.Address.Cmp)
storageList = make(map[common.Address][]common.Hash)
)
slices.SortFunc(accountList, common.Address.Cmp)
for addr, slots := range storages {
slist := maps.Keys(slots)
slices.SortFunc(slist, common.Hash.Cmp)
storageList[addr] = slist
storageList[addr] = slices.SortedFunc(maps.Keys(slots), common.Hash.Cmp)
}
version := historyVersion
if !rawStorageKey {

View File

@ -19,6 +19,7 @@ package pathdb
import (
"fmt"
"io"
"maps"
"slices"
"sync"
@ -27,7 +28,6 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rlp"
"golang.org/x/exp/maps"
)
// counter helps in tracking items and their corresponding sizes.
@ -174,8 +174,7 @@ func (s *stateSet) accountList() []common.Hash {
s.listLock.Lock()
defer s.listLock.Unlock()
list = maps.Keys(s.accountData)
slices.SortFunc(list, common.Hash.Cmp)
list = slices.SortedFunc(maps.Keys(s.accountData), common.Hash.Cmp)
s.accountListSorted = list
return list
}
@ -205,8 +204,7 @@ func (s *stateSet) storageList(accountHash common.Hash) []common.Hash {
s.listLock.Lock()
defer s.listLock.Unlock()
list := maps.Keys(s.storageData[accountHash])
slices.SortFunc(list, common.Hash.Cmp)
list := slices.SortedFunc(maps.Keys(s.storageData[accountHash]), common.Hash.Cmp)
s.storageListSorted[accountHash] = list
return list
}