mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Revert "core: use slices package for sorting (#27489)"
This reverts commit d7a94d9832.
This commit is contained in:
parent
2ea2fce6b8
commit
e4463061aa
8 changed files with 94 additions and 39 deletions
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
@ -47,7 +48,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -1015,8 +1015,8 @@ func (bc *BlockChain) procFutureBlocks() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(blocks) > 0 {
|
if len(blocks) > 0 {
|
||||||
slices.SortFunc(blocks, func(a, b *types.Block) bool {
|
sort.Slice(blocks, func(i, j int) bool {
|
||||||
return a.NumberU64() < b.NumberU64()
|
return blocks[i].NumberU64() < blocks[j].NumberU64()
|
||||||
})
|
})
|
||||||
// Insert one by one as chain insertion needs contiguous ancestry between blocks
|
// Insert one by one as chain insertion needs contiguous ancestry between blocks
|
||||||
for i := range blocks {
|
for i := range blocks {
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,13 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -270,8 +270,8 @@ func gatherForks(config *params.ChainConfig) ([]uint64, []uint64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slices.Sort(forksByBlock)
|
sort.Slice(forksByBlock, func(i, j int) bool { return forksByBlock[i] < forksByBlock[j] })
|
||||||
slices.Sort(forksByTime)
|
sort.Slice(forksByTime, func(i, j int) bool { return forksByTime[i] < forksByTime[j] })
|
||||||
|
|
||||||
// Deduplicate fork identifiers applying multiple forks
|
// Deduplicate fork identifiers applying multiple forks
|
||||||
for i := 1; i < len(forksByBlock); i++ {
|
for i := 1; i < len(forksByBlock); i++ {
|
||||||
|
|
|
||||||
|
|
@ -30,28 +30,32 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type allocItem struct{ Addr, Balance *big.Int }
|
type allocItem struct{ Addr, Balance *big.Int }
|
||||||
|
|
||||||
func makelist(g *core.Genesis) []allocItem {
|
type allocList []allocItem
|
||||||
items := make([]allocItem, 0, len(g.Alloc))
|
|
||||||
|
func (a allocList) Len() int { return len(a) }
|
||||||
|
func (a allocList) Less(i, j int) bool { return a[i].Addr.Cmp(a[j].Addr) < 0 }
|
||||||
|
func (a allocList) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
|
|
||||||
|
func makelist(g *core.Genesis) allocList {
|
||||||
|
a := make(allocList, 0, len(g.Alloc))
|
||||||
for addr, account := range g.Alloc {
|
for addr, account := range g.Alloc {
|
||||||
if len(account.Storage) > 0 || len(account.Code) > 0 || account.Nonce != 0 {
|
if len(account.Storage) > 0 || len(account.Code) > 0 || account.Nonce != 0 {
|
||||||
panic(fmt.Sprintf("can't encode account %x", addr))
|
panic(fmt.Sprintf("can't encode account %x", addr))
|
||||||
}
|
}
|
||||||
bigAddr := new(big.Int).SetBytes(addr.Bytes())
|
bigAddr := new(big.Int).SetBytes(addr.Bytes())
|
||||||
items = append(items, allocItem{bigAddr, account.Balance})
|
a = append(a, allocItem{bigAddr, account.Balance})
|
||||||
}
|
}
|
||||||
slices.SortFunc(items, func(a, b allocItem) bool {
|
sort.Sort(a)
|
||||||
return a.Addr.Cmp(b.Addr) < 0
|
return a
|
||||||
})
|
|
||||||
return items
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makealloc(g *core.Genesis) string {
|
func makealloc(g *core.Genesis) string {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
@ -30,7 +31,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
|
// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
|
||||||
|
|
@ -836,13 +836,23 @@ type badBlock struct {
|
||||||
Body *types.Body
|
Body *types.Body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// badBlockList implements the sort interface to allow sorting a list of
|
||||||
|
// bad blocks by their number in the reverse order.
|
||||||
|
type badBlockList []*badBlock
|
||||||
|
|
||||||
|
func (s badBlockList) Len() int { return len(s) }
|
||||||
|
func (s badBlockList) Less(i, j int) bool {
|
||||||
|
return s[i].Header.Number.Uint64() < s[j].Header.Number.Uint64()
|
||||||
|
}
|
||||||
|
func (s badBlockList) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
|
||||||
// ReadBadBlock retrieves the bad block with the corresponding block hash.
|
// ReadBadBlock retrieves the bad block with the corresponding block hash.
|
||||||
func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block {
|
func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block {
|
||||||
blob, err := db.Get(badBlockKey)
|
blob, err := db.Get(badBlockKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var badBlocks []*badBlock
|
var badBlocks badBlockList
|
||||||
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -861,7 +871,7 @@ func ReadAllBadBlocks(db ethdb.Reader) []*types.Block {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var badBlocks []*badBlock
|
var badBlocks badBlockList
|
||||||
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -879,7 +889,7 @@ func WriteBadBlock(db ethdb.KeyValueStore, block *types.Block) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Failed to load old bad blocks", "error", err)
|
log.Warn("Failed to load old bad blocks", "error", err)
|
||||||
}
|
}
|
||||||
var badBlocks []*badBlock
|
var badBlocks badBlockList
|
||||||
if len(blob) > 0 {
|
if len(blob) > 0 {
|
||||||
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
||||||
log.Crit("Failed to decode old bad blocks", "error", err)
|
log.Crit("Failed to decode old bad blocks", "error", err)
|
||||||
|
|
@ -895,10 +905,7 @@ func WriteBadBlock(db ethdb.KeyValueStore, block *types.Block) {
|
||||||
Header: block.Header(),
|
Header: block.Header(),
|
||||||
Body: block.Body(),
|
Body: block.Body(),
|
||||||
})
|
})
|
||||||
slices.SortFunc(badBlocks, func(a, b *badBlock) bool {
|
sort.Sort(sort.Reverse(badBlocks))
|
||||||
// Note: sorting in descending number order.
|
|
||||||
return a.Header.Number.Uint64() >= b.Header.Number.Uint64()
|
|
||||||
})
|
|
||||||
if len(badBlocks) > badBlockToKeep {
|
if len(badBlocks) > badBlockToKeep {
|
||||||
badBlocks = badBlocks[:badBlockToKeep]
|
badBlocks = badBlocks[:badBlockToKeep]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,12 @@ package rawdb
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChainIterator(t *testing.T) {
|
func TestChainIterator(t *testing.T) {
|
||||||
|
|
@ -92,11 +92,9 @@ func TestChainIterator(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !c.reverse {
|
if !c.reverse {
|
||||||
slices.Sort(numbers)
|
sort.Ints(numbers)
|
||||||
} else {
|
} else {
|
||||||
slices.SortFunc(numbers, func(a, b int) bool {
|
sort.Sort(sort.Reverse(sort.IntSlice(numbers)))
|
||||||
return a > b // Sort descending
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(numbers, c.expect) {
|
if !reflect.DeepEqual(numbers, c.expect) {
|
||||||
t.Fatalf("Case %d failed, visit element mismatch, want %v, got %v", i, c.expect, numbers)
|
t.Fatalf("Case %d failed, visit element mismatch, want %v, got %v", i, c.expect, numbers)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -29,7 +30,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
bloomfilter "github.com/holiman/bloomfilter/v2"
|
bloomfilter "github.com/holiman/bloomfilter/v2"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -525,7 +525,7 @@ func (dl *diffLayer) AccountList() []common.Hash {
|
||||||
dl.accountList = append(dl.accountList, hash)
|
dl.accountList = append(dl.accountList, hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slices.SortFunc(dl.accountList, common.Hash.Less)
|
sort.Sort(hashes(dl.accountList))
|
||||||
dl.memory += uint64(len(dl.accountList) * common.HashLength)
|
dl.memory += uint64(len(dl.accountList) * common.HashLength)
|
||||||
return dl.accountList
|
return dl.accountList
|
||||||
}
|
}
|
||||||
|
|
@ -563,7 +563,7 @@ func (dl *diffLayer) StorageList(accountHash common.Hash) ([]common.Hash, bool)
|
||||||
for k := range storageMap {
|
for k := range storageMap {
|
||||||
storageList = append(storageList, k)
|
storageList = append(storageList, k)
|
||||||
}
|
}
|
||||||
slices.SortFunc(storageList, common.Hash.Less)
|
sort.Sort(hashes(storageList))
|
||||||
dl.storageList[accountHash] = storageList
|
dl.storageList[accountHash] = storageList
|
||||||
dl.memory += uint64(len(dl.storageList)*common.HashLength + common.HashLength)
|
dl.memory += uint64(len(dl.storageList)*common.HashLength + common.HashLength)
|
||||||
return storageList, destructed
|
return storageList, destructed
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// weightedIterator is a iterator with an assigned weight. It is used to prioritise
|
// weightedIterator is a iterator with an assigned weight. It is used to prioritise
|
||||||
|
|
@ -33,10 +32,18 @@ type weightedIterator struct {
|
||||||
priority int
|
priority int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *weightedIterator) Less(other *weightedIterator) bool {
|
// weightedIterators is a set of iterators implementing the sort.Interface.
|
||||||
|
type weightedIterators []*weightedIterator
|
||||||
|
|
||||||
|
// Len implements sort.Interface, returning the number of active iterators.
|
||||||
|
func (its weightedIterators) Len() int { return len(its) }
|
||||||
|
|
||||||
|
// Less implements sort.Interface, returning which of two iterators in the stack
|
||||||
|
// is before the other.
|
||||||
|
func (its weightedIterators) Less(i, j int) bool {
|
||||||
// Order the iterators primarily by the account hashes
|
// Order the iterators primarily by the account hashes
|
||||||
hashI := it.it.Hash()
|
hashI := its[i].it.Hash()
|
||||||
hashJ := other.it.Hash()
|
hashJ := its[j].it.Hash()
|
||||||
|
|
||||||
switch bytes.Compare(hashI[:], hashJ[:]) {
|
switch bytes.Compare(hashI[:], hashJ[:]) {
|
||||||
case -1:
|
case -1:
|
||||||
|
|
@ -45,7 +52,12 @@ func (it *weightedIterator) Less(other *weightedIterator) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Same account/storage-slot in multiple layers, split by priority
|
// Same account/storage-slot in multiple layers, split by priority
|
||||||
return it.priority < other.priority
|
return its[i].priority < its[j].priority
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap implements sort.Interface, swapping two entries in the iterator stack.
|
||||||
|
func (its weightedIterators) Swap(i, j int) {
|
||||||
|
its[i], its[j] = its[j], its[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
// fastIterator is a more optimized multi-layer iterator which maintains a
|
// fastIterator is a more optimized multi-layer iterator which maintains a
|
||||||
|
|
@ -57,7 +69,7 @@ type fastIterator struct {
|
||||||
curAccount []byte
|
curAccount []byte
|
||||||
curSlot []byte
|
curSlot []byte
|
||||||
|
|
||||||
iterators []*weightedIterator
|
iterators weightedIterators
|
||||||
initiated bool
|
initiated bool
|
||||||
account bool
|
account bool
|
||||||
fail error
|
fail error
|
||||||
|
|
@ -155,9 +167,7 @@ func (fi *fastIterator) init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Re-sort the entire list
|
// Re-sort the entire list
|
||||||
slices.SortFunc(fi.iterators, func(a, b *weightedIterator) bool {
|
sort.Sort(fi.iterators)
|
||||||
return a.Less(b)
|
|
||||||
})
|
|
||||||
fi.initiated = false
|
fi.initiated = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
36
core/state/snapshot/sort.go
Normal file
36
core/state/snapshot/sort.go
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2019 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package snapshot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hashes is a helper to implement sort.Interface.
|
||||||
|
type hashes []common.Hash
|
||||||
|
|
||||||
|
// Len is the number of elements in the collection.
|
||||||
|
func (hs hashes) Len() int { return len(hs) }
|
||||||
|
|
||||||
|
// Less reports whether the element with index i should sort before the element
|
||||||
|
// with index j.
|
||||||
|
func (hs hashes) Less(i, j int) bool { return bytes.Compare(hs[i][:], hs[j][:]) < 0 }
|
||||||
|
|
||||||
|
// Swap swaps the elements with indexes i and j.
|
||||||
|
func (hs hashes) Swap(i, j int) { hs[i], hs[j] = hs[j], hs[i] }
|
||||||
Loading…
Reference in a new issue