From 11e7c5bf2cfc20bb2ce9b800bd4e28d204773412 Mon Sep 17 00:00:00 2001 From: Roshan Date: Sun, 18 Feb 2024 20:22:29 +0800 Subject: [PATCH] fix review comments --- core/txpool/bundlepool/bundlepool.go | 6 +++ miner/bidder.go | 57 ++++++++++++++++++---------- miner/worker.go | 1 - miner/worker_builder.go | 1 - 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/core/txpool/bundlepool/bundlepool.go b/core/txpool/bundlepool/bundlepool.go index fa26d977dd..9adcb86972 100644 --- a/core/txpool/bundlepool/bundlepool.go +++ b/core/txpool/bundlepool/bundlepool.go @@ -358,6 +358,7 @@ func (bgp *BundleGasPricer) Push(gasPrice *big.Int) { func (bgp *BundleGasPricer) retire() { now := time.Now() + // make sure the first element is not expired for !bgp.queue.Empty() { v, _ := bgp.queue.Peek() info := v @@ -366,6 +367,11 @@ func (bgp *BundleGasPricer) retire() { } bgp.queue.Pop() } + // only keep one element + length := bgp.queue.Size() + for i := 1; i < length; i++ { + bgp.queue.Remove(i) + } } // LatestBundleGasPrice is a method to get the latest-cached bundle gas price. diff --git a/miner/bidder.go b/miner/bidder.go index 85a8cd460e..b86dd4aa77 100644 --- a/miner/bidder.go +++ b/miner/bidder.go @@ -9,8 +9,6 @@ import ( "sync" "time" - "golang.org/x/exp/slices" - "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -23,6 +21,8 @@ import ( "github.com/ethereum/go-ethereum/rpc" ) +const maxBid int64 = 3 + var ( dialer = &net.Dialer{ Timeout: time.Second, @@ -52,7 +52,7 @@ type BidderConfig struct { Enable bool Validators []ValidatorConfig Account common.Address - DelayLeftOver time.Duration + DelayLeftOver uint64 } type Bidder struct { @@ -62,7 +62,7 @@ type Bidder struct { validators map[common.Address]*ethclient.Client // validator address -> ethclient.Client - works map[int64][]*environment + bestWorks map[int64]*environment newBidCh chan *environment exitCh chan struct{} @@ -78,7 +78,7 @@ func NewBidder(config *BidderConfig, engine consensus.Engine, chain *core.BlockC engine: engine, chain: chain, validators: make(map[common.Address]*ethclient.Client), - works: make(map[int64][]*environment), + bestWorks: make(map[int64]*environment), newBidCh: make(chan *environment, 10), exitCh: make(chan struct{}), } @@ -111,28 +111,36 @@ func (b *Bidder) mainLoop() { defer timer.Stop() <-timer.C // discard the initial tick - currentHeight := b.chain.CurrentBlock().Number.Int64() + var ( + bidNum int64 = 0 + bidUntil time.Time + currentHeight = b.chain.CurrentBlock().Number.Int64() + ) for { select { case work := <-b.newBidCh: if work.header.Number.Int64() > currentHeight { + bidNum = 0 + bidUntil = time.Unix(int64(work.header.Time+b.chain.Config().Parlia.Period-b.config.DelayLeftOver), 0) currentHeight = work.header.Number.Int64() - nextHeaderTimestamp := work.header.Time + b.chain.Config().Parlia.Period - timer.Reset(time.Until(time.Unix(int64(nextHeaderTimestamp), 0).Add(-b.config.DelayLeftOver))) + + if time.Now().After(bidUntil) { + timer.Reset(0) + } else { + timer.Reset(bidUntil.Sub(time.Now()) / time.Duration(maxBid)) + } + } + if bidNum < maxBid && b.isBestWork(work) { + b.bestWorks[work.header.Number.Int64()] = work } - b.works[work.header.Number.Int64()] = append(b.works[work.header.Number.Int64()], work) case <-timer.C: - works := b.works[currentHeight] - slices.SortStableFunc(works, func(i, j *environment) int { - return j.profit.Cmp(i.profit) - }) - - for i, work := range works { - // only bid for the top 3 most profitable works - if i >= 3 { - break + if b.bestWorks[currentHeight] != nil { + b.bid(b.bestWorks[currentHeight]) + b.bestWorks[currentHeight] = nil + bidNum++ + if bidNum < maxBid && time.Now().Before(bidUntil) { + timer.Reset(bidUntil.Sub(time.Now()) / time.Duration(maxBid-bidNum)) } - b.bid(work) } case <-b.exitCh: return @@ -203,7 +211,7 @@ func (b *Bidder) bid(work *environment) { BlockNumber: parent.Number.Uint64() + 1, ParentHash: parent.Hash(), GasUsed: work.header.GasUsed, - GasFee: work.blockReward.Uint64(), + GasFee: work.profit.Uint64(), Txs: txs, // TODO: decide builderFee according to realtime traffic and validator commission } @@ -231,6 +239,15 @@ func (b *Bidder) bid(work *environment) { return } +// isBestWork returns the work is better than the current best work +func (b *Bidder) isBestWork(work *environment) bool { + if work.profit == nil { + return false + } + + return b.bestWorks[work.header.Number.Int64()].profit.Cmp(work.profit) < 0 +} + // signBid signs the bid with builder's account func (b *Bidder) signBid(bid *types.Bid) ([]byte, error) { bz, err := rlp.EncodeToBytes(bid) diff --git a/miner/worker.go b/miner/worker.go index 3d1a720b24..7c75801992 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -719,7 +719,6 @@ func (w *worker) commitTransaction(env *environment, tx *txpool.Transaction, rec gasUsed := new(big.Int).SetUint64(receipt.GasUsed) env.profit.Add(env.profit, gasUsed.Mul(gasUsed, tx.Tx.GasPrice())) - env.blockReward.Add(env.blockReward, gasUsed.Mul(gasUsed, tx.Tx.GasPrice())) return receipt.Logs, nil } diff --git a/miner/worker_builder.go b/miner/worker_builder.go index 3d92206f56..3123094936 100644 --- a/miner/worker_builder.go +++ b/miner/worker_builder.go @@ -30,7 +30,6 @@ func (w *worker) commitWorkV2(interruptCh chan int32, timestamp int64) { // fillTransactions retrieves the pending bundles and transactions from the txpool and fills them // into the given sealing block. The selection and ordering strategy can be extended in the future. func (w *worker) fillTransactionsAndBundles(interruptCh chan int32, env *environment, stopTimer *time.Timer) error { - env.blockReward = new(big.Int) env.profit = new(big.Int) var (