forked from cerc-io/plugeth
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:
@@ -23,7 +23,6 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@@ -31,6 +30,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -69,20 +69,9 @@ type processedFees struct {
|
||||
}
|
||||
|
||||
// txGasAndReward is sorted in ascending order based on reward
|
||||
type (
|
||||
txGasAndReward struct {
|
||||
gasUsed uint64
|
||||
reward *big.Int
|
||||
}
|
||||
sortGasAndReward []txGasAndReward
|
||||
)
|
||||
|
||||
func (s sortGasAndReward) Len() int { return len(s) }
|
||||
func (s sortGasAndReward) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
func (s sortGasAndReward) Less(i, j int) bool {
|
||||
return s[i].reward.Cmp(s[j].reward) < 0
|
||||
type txGasAndReward struct {
|
||||
gasUsed uint64
|
||||
reward *big.Int
|
||||
}
|
||||
|
||||
// processBlock takes a blockFees structure with the blockNumber, the header and optionally
|
||||
@@ -117,12 +106,14 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
|
||||
return
|
||||
}
|
||||
|
||||
sorter := make(sortGasAndReward, len(bf.block.Transactions()))
|
||||
sorter := make([]txGasAndReward, len(bf.block.Transactions()))
|
||||
for i, tx := range bf.block.Transactions() {
|
||||
reward, _ := tx.EffectiveGasTip(bf.block.BaseFee())
|
||||
sorter[i] = txGasAndReward{gasUsed: bf.receipts[i].GasUsed, reward: reward}
|
||||
}
|
||||
sort.Stable(sorter)
|
||||
slices.SortStableFunc(sorter, func(a, b txGasAndReward) bool {
|
||||
return a.reward.Cmp(b.reward) < 0
|
||||
})
|
||||
|
||||
var txIndex int
|
||||
sumGasUsed := sorter[0].gasUsed
|
||||
|
||||
+15
-38
@@ -19,7 +19,6 @@ package gasprice
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@@ -30,6 +29,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
const sampleNumber = 3 // Number of transactions sampled in a block
|
||||
@@ -208,7 +208,7 @@ func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) {
|
||||
}
|
||||
price := lastPrice
|
||||
if len(results) > 0 {
|
||||
sort.Sort(bigIntArray(results))
|
||||
slices.SortFunc(results, func(a, b *big.Int) bool { return a.Cmp(b) < 0 })
|
||||
price = results[(len(results)-1)*oracle.percentile/100]
|
||||
}
|
||||
if price.Cmp(oracle.maxPrice) > 0 {
|
||||
@@ -227,30 +227,6 @@ type results struct {
|
||||
err error
|
||||
}
|
||||
|
||||
type txSorter struct {
|
||||
txs []*types.Transaction
|
||||
baseFee *big.Int
|
||||
}
|
||||
|
||||
func newSorter(txs []*types.Transaction, baseFee *big.Int) *txSorter {
|
||||
return &txSorter{
|
||||
txs: txs,
|
||||
baseFee: baseFee,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *txSorter) Len() int { return len(s.txs) }
|
||||
func (s *txSorter) Swap(i, j int) {
|
||||
s.txs[i], s.txs[j] = s.txs[j], s.txs[i]
|
||||
}
|
||||
func (s *txSorter) Less(i, j int) bool {
|
||||
// It's okay to discard the error because a tx would never be
|
||||
// accepted into a block with an invalid effective tip.
|
||||
tip1, _ := s.txs[i].EffectiveGasTip(s.baseFee)
|
||||
tip2, _ := s.txs[j].EffectiveGasTip(s.baseFee)
|
||||
return tip1.Cmp(tip2) < 0
|
||||
}
|
||||
|
||||
// getBlockValues calculates the lowest transaction gas price in a given block
|
||||
// and sends it to the result channel. If the block is empty or all transactions
|
||||
// are sent by the miner itself(it doesn't make any sense to include this kind of
|
||||
@@ -267,14 +243,21 @@ func (oracle *Oracle) getBlockValues(ctx context.Context, blockNum uint64, limit
|
||||
signer := types.MakeSigner(oracle.backend.ChainConfig(), block.Number(), block.Time())
|
||||
|
||||
// Sort the transaction by effective tip in ascending sort.
|
||||
txs := make([]*types.Transaction, len(block.Transactions()))
|
||||
copy(txs, block.Transactions())
|
||||
sorter := newSorter(txs, block.BaseFee())
|
||||
sort.Sort(sorter)
|
||||
txs := block.Transactions()
|
||||
sortedTxs := make([]*types.Transaction, len(txs))
|
||||
copy(sortedTxs, txs)
|
||||
baseFee := block.BaseFee()
|
||||
slices.SortFunc(sortedTxs, func(a, b *types.Transaction) bool {
|
||||
// It's okay to discard the error because a tx would never be
|
||||
// accepted into a block with an invalid effective tip.
|
||||
tip1, _ := a.EffectiveGasTip(baseFee)
|
||||
tip2, _ := b.EffectiveGasTip(baseFee)
|
||||
return tip1.Cmp(tip2) < 0
|
||||
})
|
||||
|
||||
var prices []*big.Int
|
||||
for _, tx := range sorter.txs {
|
||||
tip, _ := tx.EffectiveGasTip(block.BaseFee())
|
||||
for _, tx := range sortedTxs {
|
||||
tip, _ := tx.EffectiveGasTip(baseFee)
|
||||
if ignoreUnder != nil && tip.Cmp(ignoreUnder) == -1 {
|
||||
continue
|
||||
}
|
||||
@@ -291,9 +274,3 @@ func (oracle *Oracle) getBlockValues(ctx context.Context, blockNum uint64, limit
|
||||
case <-quit:
|
||||
}
|
||||
}
|
||||
|
||||
type bigIntArray []*big.Int
|
||||
|
||||
func (s bigIntArray) Len() int { return len(s) }
|
||||
func (s bigIntArray) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 }
|
||||
func (s bigIntArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
Reference in New Issue
Block a user