fix: waiting for the last simulation before pick best bid (#2507)
This commit is contained in:
parent
1047f0e59a
commit
af7e9b95bd
@ -29,11 +29,6 @@ import (
|
|||||||
const (
|
const (
|
||||||
// maxBidPerBuilderPerBlock is the max bid number per builder
|
// maxBidPerBuilderPerBlock is the max bid number per builder
|
||||||
maxBidPerBuilderPerBlock = 3
|
maxBidPerBuilderPerBlock = 3
|
||||||
|
|
||||||
// leftOverTimeRate is the rate of left over time to simulate a bid
|
|
||||||
leftOverTimeRate = 11
|
|
||||||
// leftOverTimeScale is the scale of left over time to simulate a bid
|
|
||||||
leftOverTimeScale = 10
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -318,18 +313,6 @@ func (b *bidSimulator) newBidLoop() {
|
|||||||
|
|
||||||
// commit aborts in-flight bid execution with given signal and resubmits a new one.
|
// commit aborts in-flight bid execution with given signal and resubmits a new one.
|
||||||
commit := func(reason int32, bidRuntime *BidRuntime) {
|
commit := func(reason int32, bidRuntime *BidRuntime) {
|
||||||
// if the left time is not enough to do simulation, return
|
|
||||||
var simDuration time.Duration
|
|
||||||
if lastBid := b.GetBestBid(bidRuntime.bid.ParentHash); lastBid != nil && lastBid.duration != 0 {
|
|
||||||
simDuration = lastBid.duration
|
|
||||||
}
|
|
||||||
|
|
||||||
if time.Until(b.bidMustBefore(bidRuntime.bid.ParentHash)) <= simDuration*leftOverTimeRate/leftOverTimeScale {
|
|
||||||
log.Debug("BidSimulator: abort commit, not enough time to simulate",
|
|
||||||
"builder", bidRuntime.bid.Builder, "bidHash", bidRuntime.bid.Hash().Hex())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if interruptCh != nil {
|
if interruptCh != nil {
|
||||||
// each commit work will have its own interruptCh to stop work with a reason
|
// each commit work will have its own interruptCh to stop work with a reason
|
||||||
interruptCh <- reason
|
interruptCh <- reason
|
||||||
@ -370,6 +353,7 @@ func (b *bidSimulator) newBidLoop() {
|
|||||||
expectedValidatorReward: expectedValidatorReward,
|
expectedValidatorReward: expectedValidatorReward,
|
||||||
packedBlockReward: big.NewInt(0),
|
packedBlockReward: big.NewInt(0),
|
||||||
packedValidatorReward: big.NewInt(0),
|
packedValidatorReward: big.NewInt(0),
|
||||||
|
finished: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
simulatingBid := b.GetSimulatingBid(newBid.ParentHash)
|
simulatingBid := b.GetSimulatingBid(newBid.ParentHash)
|
||||||
@ -410,11 +394,6 @@ func (b *bidSimulator) newBidLoop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bidSimulator) bidMustBefore(parentHash common.Hash) time.Time {
|
|
||||||
parentHeader := b.chain.GetHeaderByHash(parentHash)
|
|
||||||
return bidutil.BidMustBefore(parentHeader, b.chainConfig.Parlia.Period, b.delayLeftOver)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bidSimulator) bidBetterBefore(parentHash common.Hash) time.Time {
|
func (b *bidSimulator) bidBetterBefore(parentHash common.Hash) time.Time {
|
||||||
parentHeader := b.chain.GetHeaderByHash(parentHash)
|
parentHeader := b.chain.GetHeaderByHash(parentHash)
|
||||||
return bidutil.BidBetterBefore(parentHeader, b.chainConfig.Parlia.Period, b.delayLeftOver, b.config.BidSimulationLeftOver)
|
return bidutil.BidBetterBefore(parentHeader, b.chainConfig.Parlia.Period, b.delayLeftOver, b.config.BidSimulationLeftOver)
|
||||||
@ -530,7 +509,6 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) {
|
|||||||
|
|
||||||
// ensure simulation exited then start next simulation
|
// ensure simulation exited then start next simulation
|
||||||
b.SetSimulatingBid(parentHash, bidRuntime)
|
b.SetSimulatingBid(parentHash, bidRuntime)
|
||||||
start := time.Now()
|
|
||||||
|
|
||||||
defer func(simStart time.Time) {
|
defer func(simStart time.Time) {
|
||||||
logCtx := []any{
|
logCtx := []any{
|
||||||
@ -556,10 +534,11 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
b.RemoveSimulatingBid(parentHash)
|
b.RemoveSimulatingBid(parentHash)
|
||||||
bidSimTimer.UpdateSince(start)
|
close(bidRuntime.finished)
|
||||||
|
|
||||||
if success {
|
if success {
|
||||||
bidRuntime.duration = time.Since(simStart)
|
bidRuntime.duration = time.Since(simStart)
|
||||||
|
bidSimTimer.UpdateSince(simStart)
|
||||||
|
|
||||||
// only recommit self bid when newBidCh is empty
|
// only recommit self bid when newBidCh is empty
|
||||||
if len(b.newBidCh) > 0 {
|
if len(b.newBidCh) > 0 {
|
||||||
@ -583,6 +562,14 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the left time is not enough to do simulation, return
|
||||||
|
delay := b.engine.Delay(b.chain, bidRuntime.env.header, &b.delayLeftOver)
|
||||||
|
if delay == nil || *delay <= 0 {
|
||||||
|
log.Info("BidSimulator: abort commit, not enough time to simulate",
|
||||||
|
"builder", bidRuntime.bid.Builder, "bidHash", bidRuntime.bid.Hash().Hex())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
gasLimit := bidRuntime.env.header.GasLimit
|
gasLimit := bidRuntime.env.header.GasLimit
|
||||||
if bidRuntime.env.gasPool == nil {
|
if bidRuntime.env.gasPool == nil {
|
||||||
bidRuntime.env.gasPool = new(core.GasPool).AddGas(gasLimit)
|
bidRuntime.env.gasPool = new(core.GasPool).AddGas(gasLimit)
|
||||||
@ -650,14 +637,12 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) {
|
|||||||
if b.config.GreedyMergeTx {
|
if b.config.GreedyMergeTx {
|
||||||
delay := b.engine.Delay(b.chain, bidRuntime.env.header, &b.delayLeftOver)
|
delay := b.engine.Delay(b.chain, bidRuntime.env.header, &b.delayLeftOver)
|
||||||
if delay != nil && *delay > 0 {
|
if delay != nil && *delay > 0 {
|
||||||
stopTimer := time.NewTimer(*delay)
|
|
||||||
|
|
||||||
bidTxsSet := mapset.NewSet[common.Hash]()
|
bidTxsSet := mapset.NewSet[common.Hash]()
|
||||||
for _, tx := range bidRuntime.bid.Txs {
|
for _, tx := range bidRuntime.bid.Txs {
|
||||||
bidTxsSet.Add(tx.Hash())
|
bidTxsSet.Add(tx.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
fillErr := b.bidWorker.fillTransactions(interruptCh, bidRuntime.env, stopTimer, bidTxsSet)
|
fillErr := b.bidWorker.fillTransactions(interruptCh, bidRuntime.env, nil, bidTxsSet)
|
||||||
log.Trace("BidSimulator: greedy merge stopped", "block", bidRuntime.env.header.Number,
|
log.Trace("BidSimulator: greedy merge stopped", "block", bidRuntime.env.header.Number,
|
||||||
"builder", bidRuntime.bid.Builder, "tx count", bidRuntime.env.tcount-bidTxLen+1, "err", fillErr)
|
"builder", bidRuntime.bid.Builder, "tx count", bidRuntime.env.tcount-bidTxLen+1, "err", fillErr)
|
||||||
|
|
||||||
@ -733,6 +718,7 @@ type BidRuntime struct {
|
|||||||
packedBlockReward *big.Int
|
packedBlockReward *big.Int
|
||||||
packedValidatorReward *big.Int
|
packedValidatorReward *big.Int
|
||||||
|
|
||||||
|
finished chan struct{}
|
||||||
duration time.Duration
|
duration time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,9 @@ const (
|
|||||||
// the current 4 mining loops could have asynchronous risk of mining block with
|
// the current 4 mining loops could have asynchronous risk of mining block with
|
||||||
// save height, keep recently mined blocks to avoid double sign for safety,
|
// save height, keep recently mined blocks to avoid double sign for safety,
|
||||||
recentMinedCacheLimit = 20
|
recentMinedCacheLimit = 20
|
||||||
|
|
||||||
|
// the default to wait for the mev miner to finish
|
||||||
|
waitMEVMinerEndTimeLimit = 50 * time.Millisecond
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -171,6 +174,7 @@ type getWorkReq struct {
|
|||||||
|
|
||||||
type bidFetcher interface {
|
type bidFetcher interface {
|
||||||
GetBestBid(parentHash common.Hash) *BidRuntime
|
GetBestBid(parentHash common.Hash) *BidRuntime
|
||||||
|
GetSimulatingBid(prevBlockHash common.Hash) *BidRuntime
|
||||||
}
|
}
|
||||||
|
|
||||||
// worker is the main object which takes care of submitting new work to consensus engine
|
// worker is the main object which takes care of submitting new work to consensus engine
|
||||||
@ -1336,6 +1340,15 @@ LOOP:
|
|||||||
// when in-turn, compare with remote work.
|
// when in-turn, compare with remote work.
|
||||||
from := bestWork.coinbase
|
from := bestWork.coinbase
|
||||||
if w.bidFetcher != nil && bestWork.header.Difficulty.Cmp(diffInTurn) == 0 {
|
if w.bidFetcher != nil && bestWork.header.Difficulty.Cmp(diffInTurn) == 0 {
|
||||||
|
if pendingBid := w.bidFetcher.GetSimulatingBid(bestWork.header.ParentHash); pendingBid != nil {
|
||||||
|
waitBidTimer := time.NewTimer(waitMEVMinerEndTimeLimit)
|
||||||
|
defer waitBidTimer.Stop()
|
||||||
|
select {
|
||||||
|
case <-waitBidTimer.C:
|
||||||
|
case <-pendingBid.finished:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bestBid := w.bidFetcher.GetBestBid(bestWork.header.ParentHash)
|
bestBid := w.bidFetcher.GetBestBid(bestWork.header.ParentHash)
|
||||||
|
|
||||||
if bestBid != nil {
|
if bestBid != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user