|
|
|
@ -20,7 +20,6 @@ package catalyst |
|
|
|
|
import ( |
|
|
|
|
"errors" |
|
|
|
|
"fmt" |
|
|
|
|
"math/big" |
|
|
|
|
"sync" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
@ -64,11 +63,6 @@ const ( |
|
|
|
|
// attached before starting to issue warnings.
|
|
|
|
|
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
|
|
|
|
|
// to send a consensus update before it's considered offline and the user is
|
|
|
|
|
// warned.
|
|
|
|
@ -667,14 +661,13 @@ func (api *ConsensusAPI) heartbeat() { |
|
|
|
|
// attached, so no need to print scary warnings to the user.
|
|
|
|
|
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 ttd == nil { |
|
|
|
|
if api.eth.BlockChain().Config().TerminalTotalDifficulty == nil { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var offlineLogged time.Time |
|
|
|
|
|
|
|
|
|
for { |
|
|
|
|
// Sleep a bit and retrieve the last known consensus updates
|
|
|
|
|
time.Sleep(5 * time.Second) |
|
|
|
@ -698,20 +691,14 @@ func (api *ConsensusAPI) heartbeat() { |
|
|
|
|
offlineLogged = time.Time{} |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
if time.Since(lastTransitionUpdate) > beaconUpdateExchangeTimeout { |
|
|
|
|
|
|
|
|
|
if time.Since(offlineLogged) > beaconUpdateWarnFrequency { |
|
|
|
|
if lastForkchoiceUpdate.IsZero() && lastNewPayloadUpdate.IsZero() { |
|
|
|
|
if lastTransitionUpdate.IsZero() { |
|
|
|
|
log.Warn("Post-merge network, but no beacon client seen. Please launch one to follow the chain!") |
|
|
|
|
} 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!") |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
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 |
|
|
|
|
} |
|
|
|
|
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() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|