core,params: add fork readiness indicator in logs

This commit is contained in:
lightclient 2025-03-08 21:38:42 +01:00
parent 7405dc5c4b
commit 62eda99668
No known key found for this signature in database
GPG key ID: 657913021EF45A6A
3 changed files with 77 additions and 1 deletions

View file

@ -21,6 +21,7 @@ import (
"errors"
"fmt"
"io"
"math"
"math/big"
"runtime"
"slices"
@ -98,6 +99,10 @@ var (
errInvalidNewChain = errors.New("invalid new chain")
)
var (
forkReadyInterval = 3 * time.Minute
)
const (
bodyCacheLimit = 256
blockCacheLimit = 256
@ -268,6 +273,8 @@ type BlockChain struct {
processor Processor // Block transaction processor interface
vmConfig vm.Config
logger *tracing.Hooks
lastForkReadyAlert time.Time // Last time there was a fork readiness print out
}
// NewBlockChain returns a fully initialised block chain using information
@ -1825,6 +1832,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
trieDiffNodes, trieBufNodes, _ := bc.triedb.Size()
stats.report(chain, it.index, snapDiffItems, snapBufItems, trieDiffNodes, trieBufNodes, setHead)
// Print confirmation that a future fork is scheduled, but not yet active.
bc.logForkReadiness(block)
if !setHead {
// After merge we expect few side chains. Simply count
// all blocks the CL gives us for GC processing time
@ -1858,6 +1868,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
"root", block.Root())
}
}
stats.ignored += it.remaining()
return witness, it.index, err
}
@ -2455,6 +2466,22 @@ func (bc *BlockChain) reportBlock(block *types.Block, res *ProcessResult, err er
log.Error(summarizeBadBlock(block, receipts, bc.Config(), err))
}
// logForkReadiness will write a log when a future fork is scheduled, but not
// active. This is useful so operators know their client is ready for the fork.
func (bc *BlockChain) logForkReadiness(block *types.Block) {
c := bc.Config()
current, last := c.LatestFork(block.Time()), c.LatestFork(math.MaxUint64)
var at time.Time
if t := c.Timestamp(last); t != nil {
at = time.Unix(int64(*t), 0)
}
if current < last && time.Now().After(bc.lastForkReadyAlert.Add(forkReadyInterval)) {
log.Info("Ready for fork activation", "fork", last, "date", at.Format(time.RFC822),
"remaining", time.Until(at).Round(time.Second), "timestamp", at.Unix())
bc.lastForkReadyAlert = time.Now()
}
}
// summarizeBadBlock returns a string summarizing the bad block and other
// relevant information.
func summarizeBadBlock(block *types.Block, receipts []*types.Receipt, config *params.ChainConfig, err error) string {

View file

@ -875,6 +875,23 @@ func (c *ChainConfig) LatestFork(time uint64) forks.Fork {
}
}
// Timestamp returns the timestamp associated with the fork or returns nil if
// the fork isn't defined or isn't a time-based fork.
func (c *ChainConfig) Timestamp(fork forks.Fork) *uint64 {
switch {
case fork == forks.Osaka:
return c.OsakaTime
case fork == forks.Prague:
return c.PragueTime
case fork == forks.Cancun:
return c.CancunTime
case fork == forks.Shanghai:
return c.ShanghaiTime
default:
panic("unknown timestamp fork requested")
}
}
// isForkBlockIncompatible returns true if a fork scheduled at block s1 cannot be
// rescheduled to block s2 because head is already past the fork.
func isForkBlockIncompatible(s1, s2, head *big.Int) bool {

View file

@ -20,7 +20,7 @@ package forks
type Fork int
const (
Frontier = iota
Frontier Fork = iota
FrontierThawing
Homestead
DAO
@ -41,3 +41,35 @@ const (
Prague
Osaka
)
// String implements fmt.Stringer.
func (f Fork) String() string {
s, ok := forkToString[f]
if !ok {
return "Unknown fork"
}
return s
}
var forkToString = map[Fork]string{
Frontier: "Frontier",
FrontierThawing: "Frontier Thawing",
Homestead: "Homestead",
DAO: "DAO",
TangerineWhistle: "Tangerine Whistle",
SpuriousDragon: "Spurious Dragon",
Byzantium: "Byzantium",
Constantinople: "Constantinople",
Petersburg: "Petersburg",
Istanbul: "Istanbul",
MuirGlacier: "Muir Glacier",
Berlin: "Berlin",
London: "London",
ArrowGlacier: "Arrow Glacier",
GrayGlacier: "Gray Glacier",
Paris: "Paris",
Shanghai: "Shanghai",
Cancun: "Cancun",
Prague: "Prague",
Osaka: "Osaka",
}