Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ var (
utils.LogDebugFlag,
utils.LogBacktraceAtFlag,
utils.ZeroFeeAddressesFlag,
utils.UpgradeTimestampFlag,
}, utils.NetworkFlags, utils.DatabaseFlags)

rpcFlags = []cli.Flag{
Expand Down Expand Up @@ -366,6 +367,8 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend, isCon
rpcClient := stack.Attach()
ethClient := ethclient.NewClient(rpcClient)

utils.ShutdownAtUpgradeTimestamp(ctx, stack, ethClient)

go func() {
// Open any wallets already attached
for _, wallet := range stack.AccountManager().Wallets() {
Expand Down
38 changes: 38 additions & 0 deletions cmd/utils/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"bufio"
"bytes"
"compress/gzip"
"context"
"crypto/sha256"
"errors"
"fmt"
Expand All @@ -40,6 +41,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/internal/debug"
"github.com/ethereum/go-ethereum/internal/era"
Expand Down Expand Up @@ -123,6 +125,42 @@ func StartNode(ctx *cli.Context, stack *node.Node, isConsole bool) {
}()
}

func ShutdownAtUpgradeTimestamp(ctx *cli.Context, n *node.Node, ethClient *ethclient.Client) {
upgradeTimestamp := n.Config().UpgradeTimestamp
if upgradeTimestamp == 0 {
log.Info("Upgrade timestamp is not set, skipping shutdown at upgrade timestamp")
return
}
log.Info("Starting goroutine to shutdown at upgrade timestamp", "upgradeTimestamp", upgradeTimestamp)
go func() {
headers := make(chan *types.Header)
sub, err := ethClient.SubscribeNewHead(context.Background(), headers)
if err != nil {
log.Error("ShutdownAtUpgradeTimestamp: failed to subscribe to new head", "err", err)
return
}
defer sub.Unsubscribe()
for {
select {
case <-ctx.Done():
log.Info("ShutdownAtUpgradeTimestamp: context cancelled, exiting goroutine")
return
case header, ok := <-headers:
if !ok {
log.Error("ShutdownAtUpgradeTimestamp: subscription closed, exiting goroutine")
return
}
shutdownTimestamp := upgradeTimestamp - 200 // Timestamps are in ms, block time is 200ms
if header.Time >= shutdownTimestamp {
log.Info("Final block before upgrade has been sealed, initiating shutdown", "header_timestamp", header.Time)
n.Close()
return
}
}
}
}()
}

func monitorFreeDiskSpace(sigc chan os.Signal, path string, freeDiskSpaceCritical uint64) {
if path == "" {
return
Expand Down
9 changes: 9 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,12 @@ var (
Category: flags.MiscCategory,
}

UpgradeTimestampFlag = &cli.Uint64Flag{
Name: "upgrade-timestamp-ms",
Usage: "Timestamp (in unix milliseconds) at which the node will shut down for upgrade",
Category: flags.MiscCategory,
}

// RPC settings
IPCDisabledFlag = &cli.BoolFlag{
Name: "ipcdisable",
Expand Down Expand Up @@ -1405,6 +1411,9 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
if ctx.IsSet(LogDebugFlag.Name) {
log.Warn("log.debug flag is deprecated")
}
if ctx.IsSet(UpgradeTimestampFlag.Name) {
cfg.UpgradeTimestamp = ctx.Uint64(UpgradeTimestampFlag.Name)
}
}

func setSmartCard(ctx *cli.Context, cfg *node.Config) {
Expand Down
3 changes: 3 additions & 0 deletions node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ type Config struct {
EnablePersonal bool `toml:"-"`

DBEngine string `toml:",omitempty"`

// UpgradeTimestamp is approximately the timestamp where the node will shut down for upgrade.
UpgradeTimestamp uint64 `toml:",omitempty"`
}

// IPCEndpoint resolves an IPC endpoint based on a configured value, taking into
Expand Down
Loading