forked from cerc-io/plugeth
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"
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"unicode"
|
"unicode"
|
||||||
@ -157,12 +156,13 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
|
|||||||
// makeFullNode loads geth configuration and creates the Ethereum backend.
|
// makeFullNode loads geth configuration and creates the Ethereum backend.
|
||||||
func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
|
func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
|
||||||
stack, cfg := makeConfigNode(ctx)
|
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) {
|
if ctx.IsSet(utils.OverrideTerminalTotalDifficulty.Name) {
|
||||||
cfg.Eth.OverrideTerminalTotalDifficulty = flags.GlobalBig(ctx, 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)
|
backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
|
||||||
// Warn users to migrate if they have a legacy freezer format.
|
// Warn users to migrate if they have a legacy freezer format.
|
||||||
if eth != nil && !ctx.IsSet(utils.IgnoreLegacyReceiptsFlag.Name) {
|
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`.")
|
utils.Fatalf("Database has receipts with a legacy format. Please run `geth db freezer-migrate`.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure GraphQL if requested
|
// Configure GraphQL if requested
|
||||||
if ctx.IsSet(utils.GraphQLEnabledFlag.Name) {
|
if ctx.IsSet(utils.GraphQLEnabledFlag.Name) {
|
||||||
utils.RegisterGraphQLService(stack, backend, cfg.Node)
|
utils.RegisterGraphQLService(stack, backend, cfg.Node)
|
||||||
|
@ -69,8 +69,8 @@ var (
|
|||||||
utils.NoUSBFlag,
|
utils.NoUSBFlag,
|
||||||
utils.USBFlag,
|
utils.USBFlag,
|
||||||
utils.SmartCardDaemonPathFlag,
|
utils.SmartCardDaemonPathFlag,
|
||||||
utils.OverrideGrayGlacierFlag,
|
|
||||||
utils.OverrideTerminalTotalDifficulty,
|
utils.OverrideTerminalTotalDifficulty,
|
||||||
|
utils.OverrideTerminalTotalDifficultyPassed,
|
||||||
utils.EthashCacheDirFlag,
|
utils.EthashCacheDirFlag,
|
||||||
utils.EthashCachesInMemoryFlag,
|
utils.EthashCachesInMemoryFlag,
|
||||||
utils.EthashCachesOnDiskFlag,
|
utils.EthashCachesOnDiskFlag,
|
||||||
|
@ -262,17 +262,16 @@ var (
|
|||||||
Value: 2048,
|
Value: 2048,
|
||||||
Category: flags.EthCategory,
|
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{
|
OverrideTerminalTotalDifficulty = &flags.BigFlag{
|
||||||
Name: "override.terminaltotaldifficulty",
|
Name: "override.terminaltotaldifficulty",
|
||||||
Usage: "Manually specify TerminalTotalDifficulty, overriding the bundled setting",
|
Usage: "Manually specify TerminalTotalDifficulty, overriding the bundled setting",
|
||||||
Category: flags.EthCategory,
|
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
|
// Light server and client settings
|
||||||
LightServeFlag = &cli.IntFlag{
|
LightServeFlag = &cli.IntFlag{
|
||||||
Name: "light.serve",
|
Name: "light.serve",
|
||||||
|
@ -233,7 +233,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
|
|||||||
return SetupGenesisBlockWithOverride(db, genesis, nil, nil)
|
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 {
|
if genesis != nil && genesis.Config == nil {
|
||||||
return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
|
return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
|
||||||
}
|
}
|
||||||
@ -243,8 +243,8 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
|
|||||||
if overrideTerminalTotalDifficulty != nil {
|
if overrideTerminalTotalDifficulty != nil {
|
||||||
config.TerminalTotalDifficulty = overrideTerminalTotalDifficulty
|
config.TerminalTotalDifficulty = overrideTerminalTotalDifficulty
|
||||||
}
|
}
|
||||||
if overrideGrayGlacier != nil {
|
if overrideTerminalTotalDifficultyPassed != nil {
|
||||||
config.GrayGlacierBlock = overrideGrayGlacier
|
config.TerminalTotalDifficultyPassed = *overrideTerminalTotalDifficultyPassed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
|
|||||||
if n := len(ancients); n > 0 {
|
if n := len(ancients); n > 0 {
|
||||||
context = append(context, []interface{}{"hash", ancients[n-1]}...)
|
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
|
// Avoid database thrashing with tiny writes
|
||||||
if frozen-first < freezerBatchLimit {
|
if frozen-first < freezerBatchLimit {
|
||||||
|
@ -137,7 +137,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
||||||
return nil, genesisErr
|
return nil, genesisErr
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -59,6 +60,11 @@ const (
|
|||||||
// invalidTipsetsCap is the max number of recent block hashes tracked that
|
// invalidTipsetsCap is the max number of recent block hashes tracked that
|
||||||
// have lead to some bad ancestor block. It's just an OOM protection.
|
// have lead to some bad ancestor block. It's just an OOM protection.
|
||||||
invalidTipsetsCap = 512
|
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 {
|
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
|
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
|
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.
|
// 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),
|
invalidTipsets: make(map[common.Hash]*types.Header),
|
||||||
}
|
}
|
||||||
eth.Downloader().SetBadBlockCallback(api.setInvalidAncestor)
|
eth.Downloader().SetBadBlockCallback(api.setInvalidAncestor)
|
||||||
|
go api.heartbeat()
|
||||||
|
|
||||||
return api
|
return api
|
||||||
}
|
}
|
||||||
@ -122,14 +139,18 @@ func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI {
|
|||||||
// If there are payloadAttributes:
|
// If there are payloadAttributes:
|
||||||
// we try to assemble a block with the payloadAttributes and return its payloadID
|
// 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) {
|
func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, payloadAttributes *beacon.PayloadAttributesV1) (beacon.ForkChoiceResponse, error) {
|
||||||
api.forkChoiceLock.Lock()
|
api.forkchoiceLock.Lock()
|
||||||
defer api.forkChoiceLock.Unlock()
|
defer api.forkchoiceLock.Unlock()
|
||||||
|
|
||||||
log.Trace("Engine API request received", "method", "ForkchoiceUpdated", "head", update.HeadBlockHash, "finalized", update.FinalizedBlockHash, "safe", update.SafeBlockHash)
|
log.Trace("Engine API request received", "method", "ForkchoiceUpdated", "head", update.HeadBlockHash, "finalized", update.FinalizedBlockHash, "safe", update.SafeBlockHash)
|
||||||
if update.HeadBlockHash == (common.Hash{}) {
|
if update.HeadBlockHash == (common.Hash{}) {
|
||||||
log.Warn("Forkchoice requested update to zero hash")
|
log.Warn("Forkchoice requested update to zero hash")
|
||||||
return beacon.STATUS_INVALID, nil // TODO(karalabe): Why does someone send us this?
|
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
|
// 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
|
// 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
|
// ExchangeTransitionConfigurationV1 checks the given configuration against
|
||||||
// the configuration of the node.
|
// the configuration of the node.
|
||||||
func (api *ConsensusAPI) ExchangeTransitionConfigurationV1(config beacon.TransitionConfigurationV1) (*beacon.TransitionConfigurationV1, error) {
|
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 {
|
if config.TerminalTotalDifficulty == nil {
|
||||||
return nil, errors.New("invalid terminal total difficulty")
|
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
|
ttd := api.eth.BlockChain().Config().TerminalTotalDifficulty
|
||||||
if ttd == nil || ttd.Cmp(config.TerminalTotalDifficulty.ToInt()) != 0 {
|
if ttd == nil || ttd.Cmp(config.TerminalTotalDifficulty.ToInt()) != 0 {
|
||||||
log.Warn("Invalid TTD configured", "geth", ttd, "beacon", config.TerminalTotalDifficulty)
|
log.Warn("Invalid TTD configured", "geth", ttd, "beacon", config.TerminalTotalDifficulty)
|
||||||
return nil, fmt.Errorf("invalid ttd: execution %v consensus %v", ttd, config.TerminalTotalDifficulty)
|
return nil, fmt.Errorf("invalid ttd: execution %v consensus %v", ttd, config.TerminalTotalDifficulty)
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.TerminalBlockHash != (common.Hash{}) {
|
if config.TerminalBlockHash != (common.Hash{}) {
|
||||||
if hash := api.eth.BlockChain().GetCanonicalHash(uint64(config.TerminalBlockNumber)); hash == config.TerminalBlockHash {
|
if hash := api.eth.BlockChain().GetCanonicalHash(uint64(config.TerminalBlockNumber)); hash == config.TerminalBlockHash {
|
||||||
return &beacon.TransitionConfigurationV1{
|
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)
|
log.Debug("Invalid NewPayload params", "params", params, "error", err)
|
||||||
return beacon.PayloadStatusV1{Status: beacon.INVALIDBLOCKHASH}, nil
|
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
|
// If we already have the block locally, ignore the entire execution and just
|
||||||
// return a fake success.
|
// return a fake success.
|
||||||
if block := api.eth.BlockChain().GetBlockByHash(params.BlockHash); block != nil {
|
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()
|
errorMsg := err.Error()
|
||||||
return beacon.PayloadStatusV1{Status: beacon.INVALID, LatestValidHash: ¤tHash, ValidationError: &errorMsg}
|
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 is the configuration for checkpoint oracle.
|
||||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
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 (TODO: remove after the fork)
|
||||||
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
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.
|
// CreateConsensusEngine creates a consensus engine for the given chain configuration.
|
||||||
|
@ -18,49 +18,49 @@ import (
|
|||||||
// MarshalTOML marshals as TOML.
|
// MarshalTOML marshals as TOML.
|
||||||
func (c Config) MarshalTOML() (interface{}, error) {
|
func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Genesis *core.Genesis `toml:",omitempty"`
|
Genesis *core.Genesis `toml:",omitempty"`
|
||||||
NetworkId uint64
|
NetworkId uint64
|
||||||
SyncMode downloader.SyncMode
|
SyncMode downloader.SyncMode
|
||||||
EthDiscoveryURLs []string
|
EthDiscoveryURLs []string
|
||||||
SnapDiscoveryURLs []string
|
SnapDiscoveryURLs []string
|
||||||
NoPruning bool
|
NoPruning bool
|
||||||
NoPrefetch bool
|
NoPrefetch bool
|
||||||
TxLookupLimit uint64 `toml:",omitempty"`
|
TxLookupLimit uint64 `toml:",omitempty"`
|
||||||
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
||||||
LightServ int `toml:",omitempty"`
|
LightServ int `toml:",omitempty"`
|
||||||
LightIngress int `toml:",omitempty"`
|
LightIngress int `toml:",omitempty"`
|
||||||
LightEgress int `toml:",omitempty"`
|
LightEgress int `toml:",omitempty"`
|
||||||
LightPeers int `toml:",omitempty"`
|
LightPeers int `toml:",omitempty"`
|
||||||
LightNoPrune bool `toml:",omitempty"`
|
LightNoPrune bool `toml:",omitempty"`
|
||||||
LightNoSyncServe bool `toml:",omitempty"`
|
LightNoSyncServe bool `toml:",omitempty"`
|
||||||
SyncFromCheckpoint bool `toml:",omitempty"`
|
SyncFromCheckpoint bool `toml:",omitempty"`
|
||||||
UltraLightServers []string `toml:",omitempty"`
|
UltraLightServers []string `toml:",omitempty"`
|
||||||
UltraLightFraction int `toml:",omitempty"`
|
UltraLightFraction int `toml:",omitempty"`
|
||||||
UltraLightOnlyAnnounce bool `toml:",omitempty"`
|
UltraLightOnlyAnnounce bool `toml:",omitempty"`
|
||||||
SkipBcVersionCheck bool `toml:"-"`
|
SkipBcVersionCheck bool `toml:"-"`
|
||||||
DatabaseHandles int `toml:"-"`
|
DatabaseHandles int `toml:"-"`
|
||||||
DatabaseCache int
|
DatabaseCache int
|
||||||
DatabaseFreezer string
|
DatabaseFreezer string
|
||||||
TrieCleanCache int
|
TrieCleanCache int
|
||||||
TrieCleanCacheJournal string `toml:",omitempty"`
|
TrieCleanCacheJournal string `toml:",omitempty"`
|
||||||
TrieCleanCacheRejournal time.Duration `toml:",omitempty"`
|
TrieCleanCacheRejournal time.Duration `toml:",omitempty"`
|
||||||
TrieDirtyCache int
|
TrieDirtyCache int
|
||||||
TrieTimeout time.Duration
|
TrieTimeout time.Duration
|
||||||
SnapshotCache int
|
SnapshotCache int
|
||||||
Preimages bool
|
Preimages bool
|
||||||
Miner miner.Config
|
Miner miner.Config
|
||||||
Ethash ethash.Config
|
Ethash ethash.Config
|
||||||
TxPool core.TxPoolConfig
|
TxPool core.TxPoolConfig
|
||||||
GPO gasprice.Config
|
GPO gasprice.Config
|
||||||
EnablePreimageRecording bool
|
EnablePreimageRecording bool
|
||||||
DocRoot string `toml:"-"`
|
DocRoot string `toml:"-"`
|
||||||
RPCGasCap uint64
|
RPCGasCap uint64
|
||||||
RPCEVMTimeout time.Duration
|
RPCEVMTimeout time.Duration
|
||||||
RPCTxFeeCap float64
|
RPCTxFeeCap float64
|
||||||
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
||||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
||||||
OverrideGrayGlacier *big.Int `toml:",omitempty"`
|
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
||||||
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
OverrideTerminalTotalDifficultyPassed *bool `toml:",omitempty"`
|
||||||
}
|
}
|
||||||
var enc Config
|
var enc Config
|
||||||
enc.Genesis = c.Genesis
|
enc.Genesis = c.Genesis
|
||||||
@ -104,57 +104,57 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
|||||||
enc.RPCTxFeeCap = c.RPCTxFeeCap
|
enc.RPCTxFeeCap = c.RPCTxFeeCap
|
||||||
enc.Checkpoint = c.Checkpoint
|
enc.Checkpoint = c.Checkpoint
|
||||||
enc.CheckpointOracle = c.CheckpointOracle
|
enc.CheckpointOracle = c.CheckpointOracle
|
||||||
enc.OverrideGrayGlacier = c.OverrideGrayGlacier
|
|
||||||
enc.OverrideTerminalTotalDifficulty = c.OverrideTerminalTotalDifficulty
|
enc.OverrideTerminalTotalDifficulty = c.OverrideTerminalTotalDifficulty
|
||||||
|
enc.OverrideTerminalTotalDifficultyPassed = c.OverrideTerminalTotalDifficultyPassed
|
||||||
return &enc, nil
|
return &enc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalTOML unmarshals from TOML.
|
// UnmarshalTOML unmarshals from TOML.
|
||||||
func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Genesis *core.Genesis `toml:",omitempty"`
|
Genesis *core.Genesis `toml:",omitempty"`
|
||||||
NetworkId *uint64
|
NetworkId *uint64
|
||||||
SyncMode *downloader.SyncMode
|
SyncMode *downloader.SyncMode
|
||||||
EthDiscoveryURLs []string
|
EthDiscoveryURLs []string
|
||||||
SnapDiscoveryURLs []string
|
SnapDiscoveryURLs []string
|
||||||
NoPruning *bool
|
NoPruning *bool
|
||||||
NoPrefetch *bool
|
NoPrefetch *bool
|
||||||
TxLookupLimit *uint64 `toml:",omitempty"`
|
TxLookupLimit *uint64 `toml:",omitempty"`
|
||||||
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
||||||
LightServ *int `toml:",omitempty"`
|
LightServ *int `toml:",omitempty"`
|
||||||
LightIngress *int `toml:",omitempty"`
|
LightIngress *int `toml:",omitempty"`
|
||||||
LightEgress *int `toml:",omitempty"`
|
LightEgress *int `toml:",omitempty"`
|
||||||
LightPeers *int `toml:",omitempty"`
|
LightPeers *int `toml:",omitempty"`
|
||||||
LightNoPrune *bool `toml:",omitempty"`
|
LightNoPrune *bool `toml:",omitempty"`
|
||||||
LightNoSyncServe *bool `toml:",omitempty"`
|
LightNoSyncServe *bool `toml:",omitempty"`
|
||||||
SyncFromCheckpoint *bool `toml:",omitempty"`
|
SyncFromCheckpoint *bool `toml:",omitempty"`
|
||||||
UltraLightServers []string `toml:",omitempty"`
|
UltraLightServers []string `toml:",omitempty"`
|
||||||
UltraLightFraction *int `toml:",omitempty"`
|
UltraLightFraction *int `toml:",omitempty"`
|
||||||
UltraLightOnlyAnnounce *bool `toml:",omitempty"`
|
UltraLightOnlyAnnounce *bool `toml:",omitempty"`
|
||||||
SkipBcVersionCheck *bool `toml:"-"`
|
SkipBcVersionCheck *bool `toml:"-"`
|
||||||
DatabaseHandles *int `toml:"-"`
|
DatabaseHandles *int `toml:"-"`
|
||||||
DatabaseCache *int
|
DatabaseCache *int
|
||||||
DatabaseFreezer *string
|
DatabaseFreezer *string
|
||||||
TrieCleanCache *int
|
TrieCleanCache *int
|
||||||
TrieCleanCacheJournal *string `toml:",omitempty"`
|
TrieCleanCacheJournal *string `toml:",omitempty"`
|
||||||
TrieCleanCacheRejournal *time.Duration `toml:",omitempty"`
|
TrieCleanCacheRejournal *time.Duration `toml:",omitempty"`
|
||||||
TrieDirtyCache *int
|
TrieDirtyCache *int
|
||||||
TrieTimeout *time.Duration
|
TrieTimeout *time.Duration
|
||||||
SnapshotCache *int
|
SnapshotCache *int
|
||||||
Preimages *bool
|
Preimages *bool
|
||||||
Miner *miner.Config
|
Miner *miner.Config
|
||||||
Ethash *ethash.Config
|
Ethash *ethash.Config
|
||||||
TxPool *core.TxPoolConfig
|
TxPool *core.TxPoolConfig
|
||||||
GPO *gasprice.Config
|
GPO *gasprice.Config
|
||||||
EnablePreimageRecording *bool
|
EnablePreimageRecording *bool
|
||||||
DocRoot *string `toml:"-"`
|
DocRoot *string `toml:"-"`
|
||||||
RPCGasCap *uint64
|
RPCGasCap *uint64
|
||||||
RPCEVMTimeout *time.Duration
|
RPCEVMTimeout *time.Duration
|
||||||
RPCTxFeeCap *float64
|
RPCTxFeeCap *float64
|
||||||
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
||||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
||||||
OverrideGrayGlacier *big.Int `toml:",omitempty"`
|
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
||||||
OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"`
|
OverrideTerminalTotalDifficultyPassed *bool `toml:",omitempty"`
|
||||||
}
|
}
|
||||||
var dec Config
|
var dec Config
|
||||||
if err := unmarshal(&dec); err != nil {
|
if err := unmarshal(&dec); err != nil {
|
||||||
@ -283,11 +283,11 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
|||||||
if dec.CheckpointOracle != nil {
|
if dec.CheckpointOracle != nil {
|
||||||
c.CheckpointOracle = dec.CheckpointOracle
|
c.CheckpointOracle = dec.CheckpointOracle
|
||||||
}
|
}
|
||||||
if dec.OverrideGrayGlacier != nil {
|
|
||||||
c.OverrideGrayGlacier = dec.OverrideGrayGlacier
|
|
||||||
}
|
|
||||||
if dec.OverrideTerminalTotalDifficulty != nil {
|
if dec.OverrideTerminalTotalDifficulty != nil {
|
||||||
c.OverrideTerminalTotalDifficulty = dec.OverrideTerminalTotalDifficulty
|
c.OverrideTerminalTotalDifficulty = dec.OverrideTerminalTotalDifficulty
|
||||||
}
|
}
|
||||||
|
if dec.OverrideTerminalTotalDifficultyPassed != nil {
|
||||||
|
c.OverrideTerminalTotalDifficultyPassed = dec.OverrideTerminalTotalDifficultyPassed
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -191,11 +191,22 @@ func newHandler(config *handlerConfig) (*handler, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Construct the downloader (long sync) and its backing state bloom if snap
|
// Construct the downloader (long sync)
|
||||||
// sync is requested. The downloader is responsible for deallocating the state
|
|
||||||
// bloom when it's done.
|
|
||||||
h.downloader = downloader.New(h.checkpointNumber, config.Database, h.eventMux, h.chain, nil, h.removePeer, success)
|
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)
|
// Construct the fetcher (short sync)
|
||||||
validator := func(header *types.Header) error {
|
validator := func(header *types.Header) error {
|
||||||
// All the block fetcher activities should be disabled
|
// 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
|
// 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
|
// avoid triggering a sync in that case, but that could also miss sibling or
|
||||||
// other family TTD block being accepted.
|
// other family TTD block being accepted.
|
||||||
if cs.handler.merger.TDDReached() {
|
if cs.handler.chain.Config().TerminalTotalDifficultyPassed || cs.handler.merger.TDDReached() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Ensure we're at minimum peer count.
|
// Ensure we're at minimum peer count.
|
||||||
|
@ -93,7 +93,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat {
|
||||||
return nil, genesisErr
|
return nil, genesisErr
|
||||||
}
|
}
|
||||||
|
@ -100,23 +100,24 @@ var (
|
|||||||
|
|
||||||
// RopstenChainConfig contains the chain parameters to run a node on the Ropsten test network.
|
// RopstenChainConfig contains the chain parameters to run a node on the Ropsten test network.
|
||||||
RopstenChainConfig = &ChainConfig{
|
RopstenChainConfig = &ChainConfig{
|
||||||
ChainID: big.NewInt(3),
|
ChainID: big.NewInt(3),
|
||||||
HomesteadBlock: big.NewInt(0),
|
HomesteadBlock: big.NewInt(0),
|
||||||
DAOForkBlock: nil,
|
DAOForkBlock: nil,
|
||||||
DAOForkSupport: true,
|
DAOForkSupport: true,
|
||||||
EIP150Block: big.NewInt(0),
|
EIP150Block: big.NewInt(0),
|
||||||
EIP150Hash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
|
EIP150Hash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
|
||||||
EIP155Block: big.NewInt(10),
|
EIP155Block: big.NewInt(10),
|
||||||
EIP158Block: big.NewInt(10),
|
EIP158Block: big.NewInt(10),
|
||||||
ByzantiumBlock: big.NewInt(1_700_000),
|
ByzantiumBlock: big.NewInt(1_700_000),
|
||||||
ConstantinopleBlock: big.NewInt(4_230_000),
|
ConstantinopleBlock: big.NewInt(4_230_000),
|
||||||
PetersburgBlock: big.NewInt(4_939_394),
|
PetersburgBlock: big.NewInt(4_939_394),
|
||||||
IstanbulBlock: big.NewInt(6_485_846),
|
IstanbulBlock: big.NewInt(6_485_846),
|
||||||
MuirGlacierBlock: big.NewInt(7_117_117),
|
MuirGlacierBlock: big.NewInt(7_117_117),
|
||||||
BerlinBlock: big.NewInt(9_812_189),
|
BerlinBlock: big.NewInt(9_812_189),
|
||||||
LondonBlock: big.NewInt(10_499_401),
|
LondonBlock: big.NewInt(10_499_401),
|
||||||
TerminalTotalDifficulty: new(big.Int).SetUint64(50000000000000000),
|
TerminalTotalDifficulty: new(big.Int).SetUint64(50_000_000_000_000_000),
|
||||||
Ethash: new(EthashConfig),
|
TerminalTotalDifficultyPassed: true,
|
||||||
|
Ethash: new(EthashConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
// RopstenTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
|
// 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 contains the chain parameters to run a node on the Sepolia test network.
|
||||||
SepoliaChainConfig = &ChainConfig{
|
SepoliaChainConfig = &ChainConfig{
|
||||||
ChainID: big.NewInt(11155111),
|
ChainID: big.NewInt(11155111),
|
||||||
HomesteadBlock: big.NewInt(0),
|
HomesteadBlock: big.NewInt(0),
|
||||||
DAOForkBlock: nil,
|
DAOForkBlock: nil,
|
||||||
DAOForkSupport: true,
|
DAOForkSupport: true,
|
||||||
EIP150Block: big.NewInt(0),
|
EIP150Block: big.NewInt(0),
|
||||||
EIP155Block: big.NewInt(0),
|
EIP155Block: big.NewInt(0),
|
||||||
EIP158Block: big.NewInt(0),
|
EIP158Block: big.NewInt(0),
|
||||||
ByzantiumBlock: big.NewInt(0),
|
ByzantiumBlock: big.NewInt(0),
|
||||||
ConstantinopleBlock: big.NewInt(0),
|
ConstantinopleBlock: big.NewInt(0),
|
||||||
PetersburgBlock: big.NewInt(0),
|
PetersburgBlock: big.NewInt(0),
|
||||||
IstanbulBlock: big.NewInt(0),
|
IstanbulBlock: big.NewInt(0),
|
||||||
MuirGlacierBlock: big.NewInt(0),
|
MuirGlacierBlock: big.NewInt(0),
|
||||||
BerlinBlock: big.NewInt(0),
|
BerlinBlock: big.NewInt(0),
|
||||||
LondonBlock: big.NewInt(0),
|
LondonBlock: big.NewInt(0),
|
||||||
TerminalTotalDifficulty: big.NewInt(17_000_000_000_000_000),
|
TerminalTotalDifficulty: big.NewInt(17_000_000_000_000_000),
|
||||||
MergeNetsplitBlock: big.NewInt(1735371),
|
TerminalTotalDifficultyPassed: true,
|
||||||
Ethash: new(EthashConfig),
|
MergeNetsplitBlock: big.NewInt(1735371),
|
||||||
|
Ethash: new(EthashConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
// SepoliaTrustedCheckpoint contains the light client trusted checkpoint for the Sepolia test network.
|
// 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
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
// adding flags to the config to also have to set these fields.
|
// 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
|
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
||||||
// and accepted by the Ethereum core developers into the Clique consensus.
|
// and accepted by the Ethereum core developers into the Clique consensus.
|
||||||
//
|
//
|
||||||
// This configuration is intentionally not using keyed fields to force anyone
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
// adding flags to the config to also have to set these fields.
|
// 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)
|
TestRules = TestChainConfig.Rules(new(big.Int), false)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -370,6 +372,11 @@ type ChainConfig struct {
|
|||||||
// the network that triggers the consensus upgrade.
|
// the network that triggers the consensus upgrade.
|
||||||
TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"`
|
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
|
// Various consensus engines
|
||||||
Ethash *EthashConfig `json:"ethash,omitempty"`
|
Ethash *EthashConfig `json:"ethash,omitempty"`
|
||||||
Clique *CliqueConfig `json:"clique,omitempty"`
|
Clique *CliqueConfig `json:"clique,omitempty"`
|
||||||
@ -408,12 +415,16 @@ func (c *ChainConfig) String() string {
|
|||||||
case c.Ethash != nil:
|
case c.Ethash != nil:
|
||||||
if c.TerminalTotalDifficulty == nil {
|
if c.TerminalTotalDifficulty == nil {
|
||||||
banner += "Consensus: Ethash (proof-of-work)\n"
|
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 {
|
} else {
|
||||||
banner += "Consensus: Beacon (proof-of-stake), merged from Ethash (proof-of-work)\n"
|
banner += "Consensus: Beacon (proof-of-stake), merged from Ethash (proof-of-work)\n"
|
||||||
}
|
}
|
||||||
case c.Clique != nil:
|
case c.Clique != nil:
|
||||||
if c.TerminalTotalDifficulty == nil {
|
if c.TerminalTotalDifficulty == nil {
|
||||||
banner += "Consensus: Clique (proof-of-authority)\n"
|
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 {
|
} else {
|
||||||
banner += "Consensus: Beacon (proof-of-stake), merged from Clique (proof-of-authority)\n"
|
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)"
|
banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md)"
|
||||||
} else {
|
} else {
|
||||||
banner += "Merge configured:\n"
|
banner += "Merge configured:\n"
|
||||||
banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md)\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(" - Network known to be merged: %v\n", c.TerminalTotalDifficultyPassed)
|
||||||
banner += fmt.Sprintf(" - Merge netsplit block: %-8v", c.MergeNetsplitBlock)
|
banner += fmt.Sprintf(" - Total terminal difficulty: %v\n", c.TerminalTotalDifficulty)
|
||||||
|
banner += fmt.Sprintf(" - Merge netsplit block: %-8v", c.MergeNetsplitBlock)
|
||||||
}
|
}
|
||||||
return banner
|
return banner
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user