eth/catalyst: improve consensus heartbeat (#26896)

improve the heartbeat function that is no longer suitable in the current situation

Co-authored-by: “openex27” <“openexkevin@gmail.com”>
This commit is contained in:
openex 2023-03-31 03:09:35 +08:00 committed by GitHub
parent 9ce047452e
commit d0fbb10658
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -20,7 +20,6 @@ package catalyst
import ( import (
"errors" "errors"
"fmt" "fmt"
"math/big"
"sync" "sync"
"time" "time"
@ -64,11 +63,6 @@ const (
// attached before starting to issue warnings. // attached before starting to issue warnings.
beaconUpdateStartupTimeout = 30 * time.Second beaconUpdateStartupTimeout = 30 * time.Second
// beaconUpdateExchangeTimeout is the max time allowed for a beacon client to
// do a transition config exchange before it's considered offline and the user
// is warned.
beaconUpdateExchangeTimeout = 2 * time.Minute
// beaconUpdateConsensusTimeout is the max time allowed for a beacon client // beaconUpdateConsensusTimeout is the max time allowed for a beacon client
// to send a consensus update before it's considered offline and the user is // to send a consensus update before it's considered offline and the user is
// warned. // warned.
@ -667,14 +661,13 @@ func (api *ConsensusAPI) heartbeat() {
// attached, so no need to print scary warnings to the user. // attached, so no need to print scary warnings to the user.
time.Sleep(beaconUpdateStartupTimeout) time.Sleep(beaconUpdateStartupTimeout)
var (
offlineLogged time.Time
ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty
)
// If the network is not yet merged/merging, don't bother continuing. // If the network is not yet merged/merging, don't bother continuing.
if ttd == nil { if api.eth.BlockChain().Config().TerminalTotalDifficulty == nil {
return return
} }
var offlineLogged time.Time
for { for {
// Sleep a bit and retrieve the last known consensus updates // Sleep a bit and retrieve the last known consensus updates
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
@ -698,20 +691,14 @@ func (api *ConsensusAPI) heartbeat() {
offlineLogged = time.Time{} offlineLogged = time.Time{}
continue continue
} }
if time.Since(lastTransitionUpdate) > beaconUpdateExchangeTimeout {
if time.Since(offlineLogged) > beaconUpdateWarnFrequency { if time.Since(offlineLogged) > beaconUpdateWarnFrequency {
if lastForkchoiceUpdate.IsZero() && lastNewPayloadUpdate.IsZero() {
if lastTransitionUpdate.IsZero() { if lastTransitionUpdate.IsZero() {
log.Warn("Post-merge network, but no beacon client seen. Please launch one to follow the chain!") log.Warn("Post-merge network, but no beacon client seen. Please launch one to follow the chain!")
} else { } else {
log.Warn("Previously seen beacon client is offline. Please ensure it is operational to follow the chain!")
}
offlineLogged = time.Now()
}
continue
}
if time.Since(offlineLogged) > beaconUpdateWarnFrequency {
if lastForkchoiceUpdate.IsZero() && lastNewPayloadUpdate.IsZero() {
log.Warn("Beacon client online, but never received consensus updates. Please ensure your beacon client is operational to follow the chain!") log.Warn("Beacon client online, but never received consensus updates. Please ensure your beacon client is operational to follow the chain!")
}
} else { } else {
log.Warn("Beacon client online, but no consensus updates received in a while. Please fix your beacon client to follow the chain!") log.Warn("Beacon client online, but no consensus updates received in a while. Please fix your beacon client to follow the chain!")
} }
@ -719,62 +706,6 @@ func (api *ConsensusAPI) heartbeat() {
} }
continue continue
} }
if time.Since(lastTransitionUpdate) <= beaconUpdateExchangeTimeout {
offlineLogged = time.Time{}
continue
}
if time.Since(offlineLogged) > beaconUpdateWarnFrequency {
// Retrieve the last few blocks and make a rough estimate as
// to when the merge transition should happen
var (
chain = api.eth.BlockChain()
head = chain.CurrentHeader()
htd = chain.GetTd(head.Hash(), head.Number.Uint64())
)
if htd.Cmp(ttd) >= 0 {
if lastTransitionUpdate.IsZero() {
log.Warn("Merge already reached, but no beacon client seen. Please launch one to follow the chain!")
} else {
log.Warn("Merge already reached, but previously seen beacon client is offline. Please ensure it is operational to follow the chain!")
}
offlineLogged = time.Now()
continue
}
var eta time.Duration
if head.Number.Uint64() > 0 {
// Accumulate the last 64 difficulties to estimate the growth
var (
deltaDiff uint64
deltaTime uint64
current = head
)
for i := 0; i < 64; i++ {
parent := chain.GetHeader(current.ParentHash, current.Number.Uint64()-1)
if parent == nil {
break
}
deltaDiff += current.Difficulty.Uint64()
deltaTime += current.Time - parent.Time
current = parent
}
// Estimate an ETA based on the block times and the difficulty growth
if deltaTime > 0 {
growth := deltaDiff / deltaTime
left := new(big.Int).Sub(ttd, htd)
eta = time.Duration(new(big.Int).Div(left, new(big.Int).SetUint64(growth+1)).Uint64()) * time.Second
}
}
message := "Merge is configured, but previously seen beacon client is offline. Please ensure it is operational before the transition arrives!"
if lastTransitionUpdate.IsZero() {
message = "Merge is configured, but no beacon client seen. Please ensure you have one available before the transition arrives!"
}
if eta < time.Second {
log.Warn(message)
} else {
log.Warn(message, "eta", common.PrettyAge(time.Now().Add(-eta))) // weird hack, but duration formatted doesn't handle days
}
offlineLogged = time.Now()
}
} }
} }