diff --git a/p2p/discover/ntp.go b/p2p/discover/ntp.go index 3f9157808f..48ceffe95b 100644 --- a/p2p/discover/ntp.go +++ b/p2p/discover/ntp.go @@ -22,10 +22,10 @@ package discover import ( "fmt" "net" + "sort" "time" "github.com/ethereum/go-ethereum/log" - "golang.org/x/exp/slices" ) const ( @@ -33,6 +33,14 @@ const ( ntpChecks = 3 // Number of measurements to do against the NTP server ) +// durationSlice attaches the methods of sort.Interface to []time.Duration, +// sorting in increasing order. +type durationSlice []time.Duration + +func (s durationSlice) Len() int { return len(s) } +func (s durationSlice) Less(i, j int) bool { return s[i] < s[j] } +func (s durationSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + // checkClockDrift queries an NTP server for clock drifts and warns the user if // one large enough is detected. func checkClockDrift() { @@ -101,7 +109,7 @@ func sntpDrift(measurements int) (time.Duration, error) { drifts = append(drifts, sent.Sub(t)+elapsed/2) } // Calculate average drift (drop two extremities to avoid outliers) - slices.Sort(drifts) + sort.Sort(durationSlice(drifts)) drift := time.Duration(0) for i := 1; i < len(drifts)-1; i++ { diff --git a/p2p/discover/table_util_test.go b/p2p/discover/table_util_test.go index 52544a2c93..5b5e9a0431 100644 --- a/p2p/discover/table_util_test.go +++ b/p2p/discover/table_util_test.go @@ -24,12 +24,12 @@ import ( "fmt" "math/rand" "net" + "sort" "sync" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" - "golang.org/x/exp/slices" ) var nullNode *enode.Node @@ -217,14 +217,14 @@ func nodeEqual(n1 *enode.Node, n2 *enode.Node) bool { } func sortByID(nodes []*enode.Node) { - slices.SortFunc(nodes, func(a, b *enode.Node) bool { - return string(a.ID().Bytes()) < string(b.ID().Bytes()) + sort.Slice(nodes, func(i, j int) bool { + return string(nodes[i].ID().Bytes()) < string(nodes[j].ID().Bytes()) }) } func sortedByDistanceTo(distbase enode.ID, slice []*node) bool { - return slices.IsSortedFunc(slice, func(a, b *node) bool { - return enode.DistCmp(distbase, a.ID(), b.ID()) < 0 + return sort.SliceIsSorted(slice, func(i, j int) bool { + return enode.DistCmp(distbase, slice[i].ID(), slice[j].ID()) < 0 }) } diff --git a/p2p/discover/v4_lookup_test.go b/p2p/discover/v4_lookup_test.go index 83c4626288..a00de9ca18 100644 --- a/p2p/discover/v4_lookup_test.go +++ b/p2p/discover/v4_lookup_test.go @@ -20,13 +20,13 @@ import ( "crypto/ecdsa" "fmt" "net" + "sort" "testing" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/discover/v4wire" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" - "golang.org/x/exp/slices" ) func TestUDPv4_Lookup(t *testing.T) { @@ -302,8 +302,8 @@ func (tn *preminedTestnet) closest(n int) (nodes []*enode.Node) { nodes = append(nodes, tn.node(d, i)) } } - slices.SortFunc(nodes, func(a, b *enode.Node) bool { - return enode.DistCmp(tn.target.id(), a.ID(), b.ID()) < 0 + sort.Slice(nodes, func(i, j int) bool { + return enode.DistCmp(tn.target.id(), nodes[i].ID(), nodes[j].ID()) < 0 }) return nodes[:n] } diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 887d46c497..392a95b61e 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -24,6 +24,7 @@ import ( "math/rand" "net" "reflect" + "sort" "testing" "time" @@ -34,7 +35,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/require" - "golang.org/x/exp/slices" ) // Real sockets, real crypto: this test checks end-to-end connectivity for UDPv5. @@ -61,8 +61,8 @@ func TestUDPv5_lookupE2E(t *testing.T) { for i := range nodes { expectedResult[i] = nodes[i].Self() } - slices.SortFunc(expectedResult, func(a, b *enode.Node) bool { - return enode.DistCmp(target.ID(), a.ID(), b.ID()) < 0 + sort.Slice(expectedResult, func(i, j int) bool { + return enode.DistCmp(target.ID(), expectedResult[i].ID(), expectedResult[j].ID()) < 0 }) // Do the lookup. diff --git a/p2p/dnsdisc/tree.go b/p2p/dnsdisc/tree.go index f91aff458f..a3f426e428 100644 --- a/p2p/dnsdisc/tree.go +++ b/p2p/dnsdisc/tree.go @@ -23,6 +23,7 @@ import ( "encoding/base64" "fmt" "io" + "sort" "strings" "github.com/ethereum/go-ethereum/crypto" @@ -30,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" "golang.org/x/crypto/sha3" - "golang.org/x/exp/slices" ) // Tree is a merkle tree of node records. @@ -214,8 +214,8 @@ func (t *Tree) build(entries []entry) entry { } func sortByID(nodes []*enode.Node) []*enode.Node { - slices.SortFunc(nodes, func(a, b *enode.Node) bool { - return bytes.Compare(a.ID().Bytes(), b.ID().Bytes()) < 0 + sort.Slice(nodes, func(i, j int) bool { + return bytes.Compare(nodes[i].ID().Bytes(), nodes[j].ID().Bytes()) < 0 }) return nodes } diff --git a/p2p/peer.go b/p2p/peer.go index 23ac117749..a4b22fb6d4 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "net" + "sort" "sync" "time" @@ -31,7 +32,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/exp/slices" ) var ( @@ -375,7 +375,7 @@ func countMatchingProtocols(protocols []Protocol, caps []Cap) int { // matchProtocols creates structures for matching named subprotocols. func matchProtocols(protocols []Protocol, caps []Cap, rw MsgReadWriter) map[string]*protoRW { - slices.SortFunc(caps, Cap.Less) + sort.Sort(capsByNameAndVersion(caps)) offset := baseProtocolLength result := make(map[string]*protoRW) diff --git a/p2p/protocol.go b/p2p/protocol.go index 4b3cca6d4a..fa23a087c2 100644 --- a/p2p/protocol.go +++ b/p2p/protocol.go @@ -77,10 +77,10 @@ func (cap Cap) String() string { return fmt.Sprintf("%s/%d", cap.Name, cap.Version) } -// Less defines the canonical sorting order of capabilities. -func (cap Cap) Less(other Cap) bool { - if cap.Name == other.Name { - return cap.Version < other.Version - } - return cap.Name < other.Name +type capsByNameAndVersion []Cap + +func (cs capsByNameAndVersion) Len() int { return len(cs) } +func (cs capsByNameAndVersion) Swap(i, j int) { cs[i], cs[j] = cs[j], cs[i] } +func (cs capsByNameAndVersion) Less(i, j int) bool { + return cs[i].Name < cs[j].Name || (cs[i].Name == cs[j].Name && cs[i].Version < cs[j].Version) } diff --git a/p2p/server.go b/p2p/server.go index bdfeb74c67..f7bf948b69 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" "net" + "sort" "sync" "sync/atomic" "time" @@ -38,7 +39,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/p2p/netutil" - "golang.org/x/exp/slices" ) const ( @@ -498,7 +498,7 @@ func (srv *Server) setupLocalNode() error { for _, p := range srv.Protocols { srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap()) } - slices.SortFunc(srv.ourHandshake.Caps, Cap.Less) + sort.Sort(capsByNameAndVersion(srv.ourHandshake.Caps)) // Create the local node. db, err := enode.OpenDB(srv.NodeDatabase)