From 7b07231e85abf910532c4d57b50936d274f35967 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 18 Jun 2018 03:58:46 -0700 Subject: [PATCH] cmd/geth/main, cmd/utils, eth/downloader: add an option to stop geth once in sync --- cmd/geth/main.go | 21 +++++++++++++++++++++ cmd/geth/usage.go | 1 + cmd/utils/flags.go | 6 ++++++ eth/config.go | 2 ++ eth/downloader/downloader.go | 6 ++++++ 5 files changed, 36 insertions(+) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index edf2a557a7..e9d655b8f9 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -72,6 +72,7 @@ var ( utils.EthashDatasetDirFlag, utils.EthashDatasetsInMemoryFlag, utils.EthashDatasetsOnDiskFlag, + utils.ExitInSyncFlag, utils.TxPoolNoLocalsFlag, utils.TxPoolJournalFlag, utils.TxPoolRejournalFlag, @@ -299,6 +300,26 @@ func startNode(ctx *cli.Context, stack *node.Node) { } } }() + + // Schedule exit when synchronised if enabled + if exitInSync := ctx.GlobalDuration(utils.ExitInSyncFlag.Name); exitInSync >= 0 { + go func() { + // todo: support light mode + if ctx.GlobalBool(utils.LightModeFlag.Name) || ctx.GlobalString(utils.SyncModeFlag.Name) == "light" { + log.Warn("Exit after block synchronisation disabled for light mode") + } else { + var ethereum *eth.Ethereum + if err := stack.Service(ðereum); err != nil { + utils.Fatalf("Ethereum service not running: %v", err) + } + <-ethereum.Downloader().SyncedCh + log.Info("Synchronisation completed, exitting", "countdown", exitInSync) + time.Sleep(exitInSync) + stack.Stop() + } + }() + } + // Start auxiliary services if enabled if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { // Mining only makes sense if a full Ethereum node is running diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index d934c6b021..6344a65db6 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -75,6 +75,7 @@ var AppHelpFlagGroups = []flagGroup{ utils.TestnetFlag, utils.RinkebyFlag, utils.SyncModeFlag, + utils.ExitInSyncFlag, utils.GCModeFlag, utils.EthStatsURLFlag, utils.IdentityFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 41a1ac35fe..73366a097d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -170,6 +170,11 @@ var ( Usage: `Blockchain sync mode ("fast", "full", or "light")`, Value: &defaultSyncMode, } + ExitInSyncFlag = cli.DurationFlag{ + Name: "exitinsync", + Usage: "Exit after block synchronisation", + Value: -1, + } GCModeFlag = cli.StringFlag{ Name: "gcmode", Usage: `Blockchain garbage collection mode ("full", "archive")`, @@ -1040,6 +1045,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { if ctx.GlobalIsSet(NetworkIdFlag.Name) { cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name) } + cfg.ExitInSync = ctx.GlobalDuration(ExitInSyncFlag.Name) if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) { cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 diff --git a/eth/config.go b/eth/config.go index 426d2bf1ef..3b33ea4beb 100644 --- a/eth/config.go +++ b/eth/config.go @@ -114,6 +114,8 @@ type Config struct { // Miscellaneous options DocRoot string `toml:"-"` + + ExitInSync time.Duration } type configMarshaling struct { diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index fbde9c6caa..403a4cc3e0 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -128,6 +128,7 @@ type Downloader struct { bodyWakeCh chan bool // [eth/62] Channel to signal the block body fetcher of new tasks receiptWakeCh chan bool // [eth/63] Channel to signal the receipt fetcher of new tasks headerProcCh chan []*types.Header // [eth/62] Channel to feed the header processor new tasks + SyncedCh chan bool // for stateFetcher stateSyncStart chan *stateSync @@ -220,6 +221,7 @@ func New(mode SyncMode, stateDb ethdb.Database, mux *event.TypeMux, chain BlockC bodyWakeCh: make(chan bool, 1), receiptWakeCh: make(chan bool, 1), headerProcCh: make(chan []*types.Header, 1), + SyncedCh: make(chan bool, 1), quitCh: make(chan struct{}), stateCh: make(chan dataPack), stateSyncStart: make(chan *stateSync), @@ -317,6 +319,10 @@ func (d *Downloader) Synchronise(id string, head common.Hash, td *big.Int, mode err := d.synchronise(id, head, td, mode) switch err { case nil: + select { + case d.SyncedCh <- true: + default: + } case errBusy: case errTimeout, errBadPeer, errStallingPeer,