cmd, core, eth, les, params: add merge-passed chain config (#24538)
* cmd, core, eth, les, params: add merge-passed chain config * eth/catalyst, params: add various warning on malfunctioning beacons * eth/catalyst: fix warning for beacons without transition exchanges
This commit is contained in:
parent
49aa8a633b
commit
6fd06ab075
@ -20,7 +20,6 @@ import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"reflect"
|
||||
"unicode"
|
||||
@ -157,12 +156,13 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
|
||||
// makeFullNode loads geth configuration and creates the Ethereum backend.
|
||||
func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
|
||||
stack, cfg := makeConfigNode(ctx)
|
||||
if ctx.IsSet(utils.OverrideGrayGlacierFlag.Name) {
|
||||
cfg.Eth.OverrideGrayGlacier = new(big.Int).SetUint64(ctx.Uint64(utils.OverrideGrayGlacierFlag.Name))
|
||||
}
|
||||
if ctx.IsSet(utils.OverrideTerminalTotalDifficulty.Name) {
|
||||
cfg.Eth.OverrideTerminalTotalDifficulty = flags.GlobalBig(ctx, utils.OverrideTerminalTotalDifficulty.Name)
|
||||
}
|
||||
if ctx.IsSet(utils.OverrideTerminalTotalDifficultyPassed.Name) {
|
||||
override := ctx.Bool(utils.OverrideTerminalTotalDifficultyPassed.Name)
|
||||
cfg.Eth.OverrideTerminalTotalDifficultyPassed = &override
|
||||
}
|
||||
backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
|
||||
// Warn users to migrate if they have a legacy freezer format.
|
||||
if eth != nil && !ctx.IsSet(utils.IgnoreLegacyReceiptsFlag.Name) {
|
||||
@ -181,7 +181,6 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
|
||||
utils.Fatalf("Database has receipts with a legacy format. Please run `geth db freezer-migrate`.")
|
||||
}
|
||||
}
|
||||
|
||||
// Configure GraphQL if requested
|
||||
if ctx.IsSet(utils.GraphQLEnabledFlag.Name) {
|
||||
utils.RegisterGraphQLService(stack, backend, cfg.Node)
|
||||
|
@ -69,8 +69,8 @@ var (
|
||||
utils.NoUSBFlag,
|
||||
utils.USBFlag,
|
||||
utils.SmartCardDaemonPathFlag,
|
||||
utils.OverrideGrayGlacierFlag,
|
||||
utils.OverrideTerminalTotalDifficulty,
|
||||
utils.OverrideTerminalTotalDifficultyPassed,
|
||||
utils.EthashCacheDirFlag,
|
||||
utils.EthashCachesInMemoryFlag,
|
||||
utils.EthashCachesOnDiskFlag,
|
||||
|
@ -262,17 +262,16 @@ var (
|
||||
Value: 2048,
|
||||
Category: flags.EthCategory,
|
||||
}
|
||||
OverrideGrayGlacierFlag = &cli.Uint64Flag{
|
||||
Name: "override.grayglacier",
|
||||
Usage: "Manually specify Gray Glacier fork-block, overriding the bundled setting",
|
||||
Category: flags.EthCategory,
|
||||
}
|
||||
OverrideTerminalTotalDifficulty = &flags.BigFlag{
|
||||
Name: "override.terminaltotaldifficulty",
|
||||
Usage: "Manually specify TerminalTotalDifficulty, overriding the bundled setting",
|
||||
Category: flags.EthCategory,
|
||||
}
|
||||
|
||||
OverrideTerminalTotalDifficultyPassed = &cli.BoolFlag{
|
||||
Name: "override.terminaltotaldifficultypassed",
|
||||
Usage: "Manually specify TerminalTotalDifficultyPassed, overriding the bundled setting",
|
||||
Category: flags.EthCategory,
|
||||
}
|
||||
// Light server and client settings
|
||||
LightServeFlag = &cli.IntFlag{
|
||||
Name: "light.serve",
|
||||
|
@ -233,7 +233,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
|
||||
return SetupGenesisBlockWithOverride(db, genesis, nil, nil)
|
||||
}
|
||||
|
||||
func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideGrayGlacier, overrideTerminalTotalDifficulty *big.Int) (*params.ChainConfig, common.Hash, error) {
|
||||
func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideTerminalTotalDifficulty *big.Int, overrideTerminalTotalDifficultyPassed *bool) (*params.ChainConfig, common.Hash, error) {
|
||||
if genesis != nil && genesis.Config == nil {
|
||||
return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
|
||||
}
|
||||
@ -243,8 +243,8 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
|
||||
if overrideTerminalTotalDifficulty != nil {
|
||||
config.TerminalTotalDifficulty = overrideTerminalTotalDifficulty
|
||||
}
|
||||
if overrideGrayGlacier != nil {
|
||||
config.GrayGlacierBlock = overrideGrayGlacier
|
||||
if overrideTerminalTotalDifficultyPassed != nil {
|
||||
config.TerminalTotalDifficultyPassed = *overrideTerminalTotalDifficultyPassed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
|
||||
if n := len(ancients); n > 0 {
|
||||
context = append(context, []interface{}{"hash", ancients[n-1]}...)
|
||||
}
|
||||
log.Info("Deep froze chain segment", context...)
|
||||
log.Debug("Deep froze chain segment", context...)
|
||||
|
||||
// Avoid database thrashing with tiny writes
|
||||
if frozen-first < freezerBatchLimit {
|
||||
|
@ -137,7 +137,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideGrayGlacier, config.OverrideTerminalTotalDifficulty)
|
||||
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideTerminalTotalDifficulty, config.OverrideTerminalTotalDifficultyPassed)
|
||||
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
||||
return nil, genesisErr
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -59,6 +60,11 @@ const (
|
||||
// invalidTipsetsCap is the max number of recent block hashes tracked that
|
||||
// have lead to some bad ancestor block. It's just an OOM protection.
|
||||
invalidTipsetsCap = 512
|
||||
|
||||
// beaconUpdateTimeout is the max time allowed for a beacon client to signal
|
||||
// use (from the last heartbeat) before it's consifered offline and the user
|
||||
// is warned.
|
||||
beaconUpdateTimeout = 30 * time.Second
|
||||
)
|
||||
|
||||
type ConsensusAPI struct {
|
||||
@ -90,7 +96,17 @@ type ConsensusAPI struct {
|
||||
invalidTipsets map[common.Hash]*types.Header // Ephemeral cache to track invalid tipsets and their bad ancestor
|
||||
invalidLock sync.Mutex // Protects the invalid maps from concurrent access
|
||||
|
||||
forkChoiceLock sync.Mutex // Lock for the forkChoiceUpdated method
|
||||
// Geth can appear to be stuck or do strange things if the beacon client is
|
||||
// offline or is sending us strange data. Stash some update stats away so
|
||||
// that we can warn the user and not have them open issues on our tracker.
|
||||
lastTransitionUpdate time.Time
|
||||
lastTransitionLock sync.Mutex
|
||||
lastForkchoiceUpdate time.Time
|
||||
lastForkchoiceLock sync.Mutex
|
||||
lastNewPayloadUpdate time.Time
|
||||
lastNewPayloadLock sync.Mutex
|
||||
|
||||
forkchoiceLock sync.Mutex // Lock for the forkChoiceUpdated method
|
||||
}
|
||||
|
||||
// NewConsensusAPI creates a new consensus api for the given backend.
|
||||
@ -107,6 +123,7 @@ func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI {
|
||||
invalidTipsets: make(map[common.Hash]*types.Header),
|
||||
}
|
||||
eth.Downloader().SetBadBlockCallback(api.setInvalidAncestor)
|
||||
go api.heartbeat()
|
||||
|
||||
return api
|
||||
}
|
||||
@ -122,14 +139,18 @@ func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI {
|
||||
// If there are payloadAttributes:
|
||||
// we try to assemble a block with the payloadAttributes and return its payloadID
|
||||
func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, payloadAttributes *beacon.PayloadAttributesV1) (beacon.ForkChoiceResponse, error) {
|
||||
api.forkChoiceLock.Lock()
|
||||
defer api.forkChoiceLock.Unlock()
|
||||
api.forkchoiceLock.Lock()
|
||||
defer api.forkchoiceLock.Unlock()
|
||||
|
||||
log.Trace("Engine API request received", "method", "ForkchoiceUpdated", "head", update.HeadBlockHash, "finalized", update.FinalizedBlockHash, "safe", update.SafeBlockHash)
|
||||
if update.HeadBlockHash == (common.Hash{}) {
|
||||
log.Warn("Forkchoice requested update to zero hash")
|
||||
return beacon.STATUS_INVALID, nil // TODO(karalabe): Why does someone send us this?
|
||||
}
|
||||
// Stash away the last update to warn the user if the beacon client goes offline
|
||||
api.lastForkchoiceLock.Lock()
|
||||
api.lastForkchoiceUpdate = time.Now()
|
||||
api.lastForkchoiceLock.Unlock()
|
||||
|
||||
// Check whether we have the block yet in our database or not. If not, we'll
|
||||
// need to either trigger a sync, or to reject this forkchoice update for a
|
||||
@ -265,15 +286,20 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
|
||||
// ExchangeTransitionConfigurationV1 checks the given configuration against
|
||||
// the configuration of the node.
|
||||
func (api *ConsensusAPI) ExchangeTransitionConfigurationV1(config beacon.TransitionConfigurationV1) (*beacon.TransitionConfigurationV1, error) {
|
||||
log.Trace("Engine API request received", "method", "ExchangeTransitionConfiguration", "ttd", config.TerminalTotalDifficulty)
|
||||
if config.TerminalTotalDifficulty == nil {
|
||||
return nil, errors.New("invalid terminal total difficulty")
|
||||
}
|
||||
// Stash away the last update to warn the user if the beacon client goes offline
|
||||
api.lastTransitionLock.Lock()
|
||||
api.lastTransitionUpdate = time.Now()
|
||||
api.lastTransitionLock.Unlock()
|
||||
|
||||
ttd := api.eth.BlockChain().Config().TerminalTotalDifficulty
|
||||
if ttd == nil || ttd.Cmp(config.TerminalTotalDifficulty.ToInt()) != 0 {
|
||||
log.Warn("Invalid TTD configured", "geth", ttd, "beacon", config.TerminalTotalDifficulty)
|
||||
return nil, fmt.Errorf("invalid ttd: execution %v consensus %v", ttd, config.TerminalTotalDifficulty)
|
||||
}
|
||||
|
||||
if config.TerminalBlockHash != (common.Hash{}) {
|
||||
if hash := api.eth.BlockChain().GetCanonicalHash(uint64(config.TerminalBlockNumber)); hash == config.TerminalBlockHash {
|
||||
return &beacon.TransitionConfigurationV1{
|
||||
@ -305,6 +331,11 @@ func (api *ConsensusAPI) NewPayloadV1(params beacon.ExecutableDataV1) (beacon.Pa
|
||||
log.Debug("Invalid NewPayload params", "params", params, "error", err)
|
||||
return beacon.PayloadStatusV1{Status: beacon.INVALIDBLOCKHASH}, nil
|
||||
}
|
||||
// Stash away the last update to warn the user if the beacon client goes offline
|
||||
api.lastNewPayloadLock.Lock()
|
||||
api.lastNewPayloadUpdate = time.Now()
|
||||
api.lastNewPayloadLock.Unlock()
|
||||
|
||||
// If we already have the block locally, ignore the entire execution and just
|
||||
// return a fake success.
|
||||
if block := api.eth.BlockChain().GetBlockByHash(params.BlockHash); block != nil {
|
||||
@ -507,3 +538,123 @@ func (api *ConsensusAPI) invalid(err error, latestValid *types.Header) beacon.Pa
|
||||
errorMsg := err.Error()
|
||||
return beacon.PayloadStatusV1{Status: beacon.INVALID, LatestValidHash: ¤tHash, ValidationError: &errorMsg}
|
||||
}
|
||||
|
||||
// heatbeat loops indefinitely, and checks if there have been beacon client updates
|
||||
// received in the last while. If not - or if they but strange ones - it warns the
|
||||
// user that something might be off with their consensus node.
|
||||
//
|
||||
// TODO(karalabe): Spin this goroutine down somehow
|
||||
func (api *ConsensusAPI) heartbeat() {
|
||||
// Sleep a bit more on startup since there's obviously no beacon client yet
|
||||
// attached, so no need to print scary warnings to the user.
|
||||
time.Sleep(beaconUpdateTimeout)
|
||||
|
||||
var (
|
||||
offlineLogged time.Time
|
||||
)
|
||||
for {
|
||||
// Sleep a bit and retrieve the last known consensus updates
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
// If the network is not yet merged/merging, don't bother scaring the user
|
||||
ttd := api.eth.BlockChain().Config().TerminalTotalDifficulty
|
||||
if ttd == nil {
|
||||
continue
|
||||
}
|
||||
api.lastTransitionLock.Lock()
|
||||
lastTransitionUpdate := api.lastTransitionUpdate
|
||||
api.lastTransitionLock.Unlock()
|
||||
|
||||
api.lastForkchoiceLock.Lock()
|
||||
lastForkchoiceUpdate := api.lastForkchoiceUpdate
|
||||
api.lastForkchoiceLock.Unlock()
|
||||
|
||||
api.lastNewPayloadLock.Lock()
|
||||
lastNewPayloadUpdate := api.lastNewPayloadUpdate
|
||||
api.lastNewPayloadLock.Unlock()
|
||||
|
||||
// If there have been no updates for the past while, warn the user
|
||||
// that the beacon client is probably offline
|
||||
if api.eth.BlockChain().Config().TerminalTotalDifficultyPassed || api.eth.Merger().TDDReached() {
|
||||
if time.Since(lastForkchoiceUpdate) > beaconUpdateTimeout && time.Since(lastNewPayloadUpdate) > beaconUpdateTimeout {
|
||||
if time.Since(lastTransitionUpdate) > beaconUpdateTimeout {
|
||||
if time.Since(offlineLogged) > beaconUpdateTimeout {
|
||||
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) > beaconUpdateTimeout {
|
||||
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!")
|
||||
}
|
||||
offlineLogged = time.Now()
|
||||
}
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if time.Since(lastTransitionUpdate) > beaconUpdateTimeout {
|
||||
if time.Since(offlineLogged) > beaconUpdateTimeout {
|
||||
// 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.CurrentBlock()
|
||||
htd = chain.GetTd(head.Hash(), head.NumberU64())
|
||||
eta time.Duration
|
||||
)
|
||||
if head.NumberU64() > 0 && htd.Cmp(ttd) < 0 {
|
||||
// Accumulate the last 64 difficulties to estimate the growth
|
||||
var diff float64
|
||||
|
||||
block := head
|
||||
for i := 0; i < 64; i++ {
|
||||
diff += float64(block.Difficulty().Uint64())
|
||||
if parent := chain.GetBlock(block.ParentHash(), block.NumberU64()-1); parent == nil {
|
||||
break
|
||||
} else {
|
||||
block = parent
|
||||
}
|
||||
}
|
||||
// Estimate an ETA based on the block times and the difficulty growth
|
||||
growth := diff / float64(head.Time()-block.Time()+1) // +1 to avoid div by zero
|
||||
if growth > 0 {
|
||||
if left := new(big.Int).Sub(ttd, htd); left.IsUint64() {
|
||||
eta = time.Duration(float64(left.Uint64())/growth) * time.Second
|
||||
} else {
|
||||
eta = time.Duration(new(big.Int).Div(left, big.NewInt(int64(growth))).Uint64()) * time.Second
|
||||
}
|
||||
}
|
||||
}
|
||||
var message string
|
||||
if htd.Cmp(ttd) > 0 {
|
||||
if lastTransitionUpdate.IsZero() {
|
||||
message = "Merge already reached, but no beacon client seen. Please launch one to follow the chain!"
|
||||
} else {
|
||||
message = "Merge already reached, but previously seen beacon client is offline. Please ensure it is operational to follow the chain!"
|
||||
}
|
||||
} else {
|
||||
if lastTransitionUpdate.IsZero() {
|
||||
message = "Merge is configured, but no beacon client seen. Please ensure you have one available before the transision arrives!"
|
||||
} else {
|
||||
message = "Merge is configured, but previously seen beacon client is offline. Please ensure it is operational before the transision arrives!"
|
||||
}
|
||||
}
|
||||
if eta == 0 {
|
||||
log.Warn(message)
|
||||
} else {
|
||||
log.Warn(message, "eta", common.PrettyAge(time.Now().Add(-eta))) // weird hack, but duration formatted doens't handle days
|
||||
}
|
||||
offlineLogged = time.Now()
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,11 +205,11 @@ type Config struct {
|
||||
// CheckpointOracle is the configuration for checkpoint oracle.
|
||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
||||
|
||||
// Gray Glacier block override (TODO: remove after the fork)
|
||||
OverrideGrayGlacier *big.Int `toml:",omitempty"`
|
||||
|
||||
// OverrideTerminalTotalDifficulty (TODO: remove after the fork)
|
||||
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
||||
|
||||
// OverrideTerminalTotalDifficultyPassed (TODO: remove after the fork)
|
||||
OverrideTerminalTotalDifficultyPassed *bool `toml:",omitempty"`
|
||||
}
|
||||
|
||||
// CreateConsensusEngine creates a consensus engine for the given chain configuration.
|
||||
|
@ -18,49 +18,49 @@ import (
|
||||
// MarshalTOML marshals as TOML.
|
||||
func (c Config) MarshalTOML() (interface{}, error) {
|
||||
type Config struct {
|
||||
Genesis *core.Genesis `toml:",omitempty"`
|
||||
NetworkId uint64
|
||||
SyncMode downloader.SyncMode
|
||||
EthDiscoveryURLs []string
|
||||
SnapDiscoveryURLs []string
|
||||
NoPruning bool
|
||||
NoPrefetch bool
|
||||
TxLookupLimit uint64 `toml:",omitempty"`
|
||||
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
||||
LightServ int `toml:",omitempty"`
|
||||
LightIngress int `toml:",omitempty"`
|
||||
LightEgress int `toml:",omitempty"`
|
||||
LightPeers int `toml:",omitempty"`
|
||||
LightNoPrune bool `toml:",omitempty"`
|
||||
LightNoSyncServe bool `toml:",omitempty"`
|
||||
SyncFromCheckpoint bool `toml:",omitempty"`
|
||||
UltraLightServers []string `toml:",omitempty"`
|
||||
UltraLightFraction int `toml:",omitempty"`
|
||||
UltraLightOnlyAnnounce bool `toml:",omitempty"`
|
||||
SkipBcVersionCheck bool `toml:"-"`
|
||||
DatabaseHandles int `toml:"-"`
|
||||
DatabaseCache int
|
||||
DatabaseFreezer string
|
||||
TrieCleanCache int
|
||||
TrieCleanCacheJournal string `toml:",omitempty"`
|
||||
TrieCleanCacheRejournal time.Duration `toml:",omitempty"`
|
||||
TrieDirtyCache int
|
||||
TrieTimeout time.Duration
|
||||
SnapshotCache int
|
||||
Preimages bool
|
||||
Miner miner.Config
|
||||
Ethash ethash.Config
|
||||
TxPool core.TxPoolConfig
|
||||
GPO gasprice.Config
|
||||
EnablePreimageRecording bool
|
||||
DocRoot string `toml:"-"`
|
||||
RPCGasCap uint64
|
||||
RPCEVMTimeout time.Duration
|
||||
RPCTxFeeCap float64
|
||||
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
||||
OverrideGrayGlacier *big.Int `toml:",omitempty"`
|
||||
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
||||
Genesis *core.Genesis `toml:",omitempty"`
|
||||
NetworkId uint64
|
||||
SyncMode downloader.SyncMode
|
||||
EthDiscoveryURLs []string
|
||||
SnapDiscoveryURLs []string
|
||||
NoPruning bool
|
||||
NoPrefetch bool
|
||||
TxLookupLimit uint64 `toml:",omitempty"`
|
||||
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
||||
LightServ int `toml:",omitempty"`
|
||||
LightIngress int `toml:",omitempty"`
|
||||
LightEgress int `toml:",omitempty"`
|
||||
LightPeers int `toml:",omitempty"`
|
||||
LightNoPrune bool `toml:",omitempty"`
|
||||
LightNoSyncServe bool `toml:",omitempty"`
|
||||
SyncFromCheckpoint bool `toml:",omitempty"`
|
||||
UltraLightServers []string `toml:",omitempty"`
|
||||
UltraLightFraction int `toml:",omitempty"`
|
||||
UltraLightOnlyAnnounce bool `toml:",omitempty"`
|
||||
SkipBcVersionCheck bool `toml:"-"`
|
||||
DatabaseHandles int `toml:"-"`
|
||||
DatabaseCache int
|
||||
DatabaseFreezer string
|
||||
TrieCleanCache int
|
||||
TrieCleanCacheJournal string `toml:",omitempty"`
|
||||
TrieCleanCacheRejournal time.Duration `toml:",omitempty"`
|
||||
TrieDirtyCache int
|
||||
TrieTimeout time.Duration
|
||||
SnapshotCache int
|
||||
Preimages bool
|
||||
Miner miner.Config
|
||||
Ethash ethash.Config
|
||||
TxPool core.TxPoolConfig
|
||||
GPO gasprice.Config
|
||||
EnablePreimageRecording bool
|
||||
DocRoot string `toml:"-"`
|
||||
RPCGasCap uint64
|
||||
RPCEVMTimeout time.Duration
|
||||
RPCTxFeeCap float64
|
||||
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
||||
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
||||
OverrideTerminalTotalDifficultyPassed *bool `toml:",omitempty"`
|
||||
}
|
||||
var enc Config
|
||||
enc.Genesis = c.Genesis
|
||||
@ -104,57 +104,57 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||
enc.RPCTxFeeCap = c.RPCTxFeeCap
|
||||
enc.Checkpoint = c.Checkpoint
|
||||
enc.CheckpointOracle = c.CheckpointOracle
|
||||
enc.OverrideGrayGlacier = c.OverrideGrayGlacier
|
||||
enc.OverrideTerminalTotalDifficulty = c.OverrideTerminalTotalDifficulty
|
||||
enc.OverrideTerminalTotalDifficultyPassed = c.OverrideTerminalTotalDifficultyPassed
|
||||
return &enc, nil
|
||||
}
|
||||
|
||||
// UnmarshalTOML unmarshals from TOML.
|
||||
func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||
type Config struct {
|
||||
Genesis *core.Genesis `toml:",omitempty"`
|
||||
NetworkId *uint64
|
||||
SyncMode *downloader.SyncMode
|
||||
EthDiscoveryURLs []string
|
||||
SnapDiscoveryURLs []string
|
||||
NoPruning *bool
|
||||
NoPrefetch *bool
|
||||
TxLookupLimit *uint64 `toml:",omitempty"`
|
||||
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
||||
LightServ *int `toml:",omitempty"`
|
||||
LightIngress *int `toml:",omitempty"`
|
||||
LightEgress *int `toml:",omitempty"`
|
||||
LightPeers *int `toml:",omitempty"`
|
||||
LightNoPrune *bool `toml:",omitempty"`
|
||||
LightNoSyncServe *bool `toml:",omitempty"`
|
||||
SyncFromCheckpoint *bool `toml:",omitempty"`
|
||||
UltraLightServers []string `toml:",omitempty"`
|
||||
UltraLightFraction *int `toml:",omitempty"`
|
||||
UltraLightOnlyAnnounce *bool `toml:",omitempty"`
|
||||
SkipBcVersionCheck *bool `toml:"-"`
|
||||
DatabaseHandles *int `toml:"-"`
|
||||
DatabaseCache *int
|
||||
DatabaseFreezer *string
|
||||
TrieCleanCache *int
|
||||
TrieCleanCacheJournal *string `toml:",omitempty"`
|
||||
TrieCleanCacheRejournal *time.Duration `toml:",omitempty"`
|
||||
TrieDirtyCache *int
|
||||
TrieTimeout *time.Duration
|
||||
SnapshotCache *int
|
||||
Preimages *bool
|
||||
Miner *miner.Config
|
||||
Ethash *ethash.Config
|
||||
TxPool *core.TxPoolConfig
|
||||
GPO *gasprice.Config
|
||||
EnablePreimageRecording *bool
|
||||
DocRoot *string `toml:"-"`
|
||||
RPCGasCap *uint64
|
||||
RPCEVMTimeout *time.Duration
|
||||
RPCTxFeeCap *float64
|
||||
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
||||
OverrideGrayGlacier *big.Int `toml:",omitempty"`
|
||||
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
||||
Genesis *core.Genesis `toml:",omitempty"`
|
||||
NetworkId *uint64
|
||||
SyncMode *downloader.SyncMode
|
||||
EthDiscoveryURLs []string
|
||||
SnapDiscoveryURLs []string
|
||||
NoPruning *bool
|
||||
NoPrefetch *bool
|
||||
TxLookupLimit *uint64 `toml:",omitempty"`
|
||||
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
||||
LightServ *int `toml:",omitempty"`
|
||||
LightIngress *int `toml:",omitempty"`
|
||||
LightEgress *int `toml:",omitempty"`
|
||||
LightPeers *int `toml:",omitempty"`
|
||||
LightNoPrune *bool `toml:",omitempty"`
|
||||
LightNoSyncServe *bool `toml:",omitempty"`
|
||||
SyncFromCheckpoint *bool `toml:",omitempty"`
|
||||
UltraLightServers []string `toml:",omitempty"`
|
||||
UltraLightFraction *int `toml:",omitempty"`
|
||||
UltraLightOnlyAnnounce *bool `toml:",omitempty"`
|
||||
SkipBcVersionCheck *bool `toml:"-"`
|
||||
DatabaseHandles *int `toml:"-"`
|
||||
DatabaseCache *int
|
||||
DatabaseFreezer *string
|
||||
TrieCleanCache *int
|
||||
TrieCleanCacheJournal *string `toml:",omitempty"`
|
||||
TrieCleanCacheRejournal *time.Duration `toml:",omitempty"`
|
||||
TrieDirtyCache *int
|
||||
TrieTimeout *time.Duration
|
||||
SnapshotCache *int
|
||||
Preimages *bool
|
||||
Miner *miner.Config
|
||||
Ethash *ethash.Config
|
||||
TxPool *core.TxPoolConfig
|
||||
GPO *gasprice.Config
|
||||
EnablePreimageRecording *bool
|
||||
DocRoot *string `toml:"-"`
|
||||
RPCGasCap *uint64
|
||||
RPCEVMTimeout *time.Duration
|
||||
RPCTxFeeCap *float64
|
||||
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
||||
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
||||
OverrideTerminalTotalDifficultyPassed *bool `toml:",omitempty"`
|
||||
}
|
||||
var dec Config
|
||||
if err := unmarshal(&dec); err != nil {
|
||||
@ -283,11 +283,11 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||
if dec.CheckpointOracle != nil {
|
||||
c.CheckpointOracle = dec.CheckpointOracle
|
||||
}
|
||||
if dec.OverrideGrayGlacier != nil {
|
||||
c.OverrideGrayGlacier = dec.OverrideGrayGlacier
|
||||
}
|
||||
if dec.OverrideTerminalTotalDifficulty != nil {
|
||||
c.OverrideTerminalTotalDifficulty = dec.OverrideTerminalTotalDifficulty
|
||||
}
|
||||
if dec.OverrideTerminalTotalDifficultyPassed != nil {
|
||||
c.OverrideTerminalTotalDifficultyPassed = dec.OverrideTerminalTotalDifficultyPassed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -191,11 +191,22 @@ func newHandler(config *handlerConfig) (*handler, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Construct the downloader (long sync) and its backing state bloom if snap
|
||||
// sync is requested. The downloader is responsible for deallocating the state
|
||||
// bloom when it's done.
|
||||
// Construct the downloader (long sync)
|
||||
h.downloader = downloader.New(h.checkpointNumber, config.Database, h.eventMux, h.chain, nil, h.removePeer, success)
|
||||
|
||||
if ttd := h.chain.Config().TerminalTotalDifficulty; ttd != nil {
|
||||
if h.chain.Config().TerminalTotalDifficultyPassed {
|
||||
log.Info("Chain post-merge, sync via beacon client")
|
||||
} else {
|
||||
head := h.chain.CurrentBlock()
|
||||
if td := h.chain.GetTd(head.Hash(), head.NumberU64()); td.Cmp(ttd) >= 0 {
|
||||
log.Info("Chain post-TTD, sync via beacon client")
|
||||
} else {
|
||||
log.Warn("Chain pre-merge, sync via PoW (ensure beacon client is ready)")
|
||||
}
|
||||
}
|
||||
} else if h.chain.Config().TerminalTotalDifficultyPassed {
|
||||
log.Error("Chain configured post-merge, but without TTD. Are you debugging sync?")
|
||||
}
|
||||
// Construct the fetcher (short sync)
|
||||
validator := func(header *types.Header) error {
|
||||
// All the block fetcher activities should be disabled
|
||||
|
@ -163,7 +163,7 @@ func (cs *chainSyncer) nextSyncOp() *chainSyncOp {
|
||||
// An alternative would be to check the local chain for exceeding the TTD and
|
||||
// avoid triggering a sync in that case, but that could also miss sibling or
|
||||
// other family TTD block being accepted.
|
||||
if cs.handler.merger.TDDReached() {
|
||||
if cs.handler.chain.Config().TerminalTotalDifficultyPassed || cs.handler.merger.TDDReached() {
|
||||
return nil
|
||||
}
|
||||
// Ensure we're at minimum peer count.
|
||||
|
@ -93,7 +93,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideGrayGlacier, config.OverrideTerminalTotalDifficulty)
|
||||
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideTerminalTotalDifficulty, config.OverrideTerminalTotalDifficultyPassed)
|
||||
if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat {
|
||||
return nil, genesisErr
|
||||
}
|
||||
|
@ -100,23 +100,24 @@ var (
|
||||
|
||||
// RopstenChainConfig contains the chain parameters to run a node on the Ropsten test network.
|
||||
RopstenChainConfig = &ChainConfig{
|
||||
ChainID: big.NewInt(3),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
DAOForkBlock: nil,
|
||||
DAOForkSupport: true,
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP150Hash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
|
||||
EIP155Block: big.NewInt(10),
|
||||
EIP158Block: big.NewInt(10),
|
||||
ByzantiumBlock: big.NewInt(1_700_000),
|
||||
ConstantinopleBlock: big.NewInt(4_230_000),
|
||||
PetersburgBlock: big.NewInt(4_939_394),
|
||||
IstanbulBlock: big.NewInt(6_485_846),
|
||||
MuirGlacierBlock: big.NewInt(7_117_117),
|
||||
BerlinBlock: big.NewInt(9_812_189),
|
||||
LondonBlock: big.NewInt(10_499_401),
|
||||
TerminalTotalDifficulty: new(big.Int).SetUint64(50000000000000000),
|
||||
Ethash: new(EthashConfig),
|
||||
ChainID: big.NewInt(3),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
DAOForkBlock: nil,
|
||||
DAOForkSupport: true,
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP150Hash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
|
||||
EIP155Block: big.NewInt(10),
|
||||
EIP158Block: big.NewInt(10),
|
||||
ByzantiumBlock: big.NewInt(1_700_000),
|
||||
ConstantinopleBlock: big.NewInt(4_230_000),
|
||||
PetersburgBlock: big.NewInt(4_939_394),
|
||||
IstanbulBlock: big.NewInt(6_485_846),
|
||||
MuirGlacierBlock: big.NewInt(7_117_117),
|
||||
BerlinBlock: big.NewInt(9_812_189),
|
||||
LondonBlock: big.NewInt(10_499_401),
|
||||
TerminalTotalDifficulty: new(big.Int).SetUint64(50_000_000_000_000_000),
|
||||
TerminalTotalDifficultyPassed: true,
|
||||
Ethash: new(EthashConfig),
|
||||
}
|
||||
|
||||
// RopstenTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
|
||||
@ -142,23 +143,24 @@ var (
|
||||
|
||||
// SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network.
|
||||
SepoliaChainConfig = &ChainConfig{
|
||||
ChainID: big.NewInt(11155111),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
DAOForkBlock: nil,
|
||||
DAOForkSupport: true,
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
IstanbulBlock: big.NewInt(0),
|
||||
MuirGlacierBlock: big.NewInt(0),
|
||||
BerlinBlock: big.NewInt(0),
|
||||
LondonBlock: big.NewInt(0),
|
||||
TerminalTotalDifficulty: big.NewInt(17_000_000_000_000_000),
|
||||
MergeNetsplitBlock: big.NewInt(1735371),
|
||||
Ethash: new(EthashConfig),
|
||||
ChainID: big.NewInt(11155111),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
DAOForkBlock: nil,
|
||||
DAOForkSupport: true,
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
IstanbulBlock: big.NewInt(0),
|
||||
MuirGlacierBlock: big.NewInt(0),
|
||||
BerlinBlock: big.NewInt(0),
|
||||
LondonBlock: big.NewInt(0),
|
||||
TerminalTotalDifficulty: big.NewInt(17_000_000_000_000_000),
|
||||
TerminalTotalDifficultyPassed: true,
|
||||
MergeNetsplitBlock: big.NewInt(1735371),
|
||||
Ethash: new(EthashConfig),
|
||||
}
|
||||
|
||||
// SepoliaTrustedCheckpoint contains the light client trusted checkpoint for the Sepolia test network.
|
||||
@ -263,16 +265,16 @@ var (
|
||||
//
|
||||
// This configuration is intentionally not using keyed fields to force anyone
|
||||
// adding flags to the config to also have to set these fields.
|
||||
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, new(EthashConfig), nil}
|
||||
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, new(EthashConfig), nil}
|
||||
|
||||
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
||||
// and accepted by the Ethereum core developers into the Clique consensus.
|
||||
//
|
||||
// This configuration is intentionally not using keyed fields to force anyone
|
||||
// adding flags to the config to also have to set these fields.
|
||||
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
|
||||
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, false, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
|
||||
|
||||
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, new(EthashConfig), nil}
|
||||
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, new(EthashConfig), nil}
|
||||
TestRules = TestChainConfig.Rules(new(big.Int), false)
|
||||
)
|
||||
|
||||
@ -370,6 +372,11 @@ type ChainConfig struct {
|
||||
// the network that triggers the consensus upgrade.
|
||||
TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"`
|
||||
|
||||
// TerminalTotalDifficultyPassed is a flag specifying that the network already
|
||||
// passed the terminal total difficulty. Its purpose is to disable legacy sync
|
||||
// even without having seen the TTD locally (safer long term).
|
||||
TerminalTotalDifficultyPassed bool `json:"terminalTotalDifficultyPassed,omitempty"`
|
||||
|
||||
// Various consensus engines
|
||||
Ethash *EthashConfig `json:"ethash,omitempty"`
|
||||
Clique *CliqueConfig `json:"clique,omitempty"`
|
||||
@ -408,12 +415,16 @@ func (c *ChainConfig) String() string {
|
||||
case c.Ethash != nil:
|
||||
if c.TerminalTotalDifficulty == nil {
|
||||
banner += "Consensus: Ethash (proof-of-work)\n"
|
||||
} else if !c.TerminalTotalDifficultyPassed {
|
||||
banner += "Consensus: Beacon (proof-of-stake), merging from Ethash (proof-of-work)\n"
|
||||
} else {
|
||||
banner += "Consensus: Beacon (proof-of-stake), merged from Ethash (proof-of-work)\n"
|
||||
}
|
||||
case c.Clique != nil:
|
||||
if c.TerminalTotalDifficulty == nil {
|
||||
banner += "Consensus: Clique (proof-of-authority)\n"
|
||||
} else if !c.TerminalTotalDifficultyPassed {
|
||||
banner += "Consensus: Beacon (proof-of-stake), merging from Clique (proof-of-authority)\n"
|
||||
} else {
|
||||
banner += "Consensus: Beacon (proof-of-stake), merged from Clique (proof-of-authority)\n"
|
||||
}
|
||||
@ -462,9 +473,10 @@ func (c *ChainConfig) String() string {
|
||||
banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md)"
|
||||
} else {
|
||||
banner += "Merge configured:\n"
|
||||
banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md)\n"
|
||||
banner += fmt.Sprintf(" - Total terminal difficulty: %v\n", c.TerminalTotalDifficulty)
|
||||
banner += fmt.Sprintf(" - Merge netsplit block: %-8v", c.MergeNetsplitBlock)
|
||||
banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md)\n"
|
||||
banner += fmt.Sprintf(" - Network known to be merged: %v\n", c.TerminalTotalDifficultyPassed)
|
||||
banner += fmt.Sprintf(" - Total terminal difficulty: %v\n", c.TerminalTotalDifficulty)
|
||||
banner += fmt.Sprintf(" - Merge netsplit block: %-8v", c.MergeNetsplitBlock)
|
||||
}
|
||||
return banner
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user