From 3b9808f23ca4eb1621a92aad80de5c89269f17fe Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 27 May 2015 13:29:34 +0200 Subject: [PATCH] cmd/geth, cmd/utils: don't use Ethereum for import, export and upgradedb The blockchain commands don't need the full stack. With this change, p2p, miner, downloader, etc are no longer started for blockchain operations. --- cmd/geth/main.go | 113 +++++++++++++-------------------------------- cmd/utils/cmd.go | 51 +++++++++----------- cmd/utils/flags.go | 44 ++++++++---------- 3 files changed, 73 insertions(+), 135 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 0cbf8e41a..f849063fa 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -41,6 +41,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" ) @@ -282,17 +283,12 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso utils.SolcPathFlag, } app.Before = func(ctx *cli.Context) error { + utils.SetupLogger(ctx) if ctx.GlobalBool(utils.PProfEanbledFlag.Name) { utils.StartPProf(ctx) } return nil } - - // missing: - // flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") - // flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0") - // flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false") - } func main() { @@ -516,53 +512,25 @@ func importchain(ctx *cli.Context) { if len(ctx.Args()) != 1 { utils.Fatalf("This command requires an argument.") } - - cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) - cfg.SkipBcVersionCheck = true - - ethereum, err := eth.New(cfg) - if err != nil { - utils.Fatalf("%v\n", err) - } - - chainmgr := ethereum.ChainManager() + chain, blockDB, stateDB, extraDB := utils.GetChain(ctx) start := time.Now() - err = utils.ImportChain(chainmgr, ctx.Args().First()) - if err != nil { + if err := utils.ImportChain(chain, ctx.Args().First()); err != nil { utils.Fatalf("Import error: %v\n", err) } - - // force database flush - ethereum.BlockDb().Flush() - ethereum.StateDb().Flush() - ethereum.ExtraDb().Flush() - + flushAll(blockDB, stateDB, extraDB) fmt.Printf("Import done in %v", time.Since(start)) - - return } func exportchain(ctx *cli.Context) { if len(ctx.Args()) != 1 { utils.Fatalf("This command requires an argument.") } - - cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx) - cfg.SkipBcVersionCheck = true - - ethereum, err := eth.New(cfg) - if err != nil { - utils.Fatalf("%v\n", err) - } - - chainmgr := ethereum.ChainManager() + chain, _, _, _ := utils.GetChain(ctx) start := time.Now() - err = utils.ExportChain(chainmgr, ctx.Args().First()) - if err != nil { + if err := utils.ExportChain(chain, ctx.Args().First()); err != nil { utils.Fatalf("Export error: %v\n", err) } fmt.Printf("Export done in %v", time.Since(start)) - return } func removeDb(ctx *cli.Context) { @@ -585,76 +553,54 @@ func removeDb(ctx *cli.Context) { } func upgradeDb(ctx *cli.Context) { - fmt.Println("Upgrade blockchain DB") + glog.Infoln("Upgrading blockchain database") - cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) - cfg.SkipBcVersionCheck = true - - ethereum, err := eth.New(cfg) - if err != nil { - utils.Fatalf("%v\n", err) - } - - v, _ := ethereum.BlockDb().Get([]byte("BlockchainVersion")) + chain, blockDB, stateDB, extraDB := utils.GetChain(ctx) + v, _ := blockDB.Get([]byte("BlockchainVersion")) bcVersion := int(common.NewValue(v).Uint()) - if bcVersion == 0 { bcVersion = core.BlockChainVersion } + // Export the current chain. filename := fmt.Sprintf("blockchain_%d_%s.chain", bcVersion, time.Now().Format("20060102_150405")) exportFile := filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), filename) - - err = utils.ExportChain(ethereum.ChainManager(), exportFile) - if err != nil { + if err := utils.ExportChain(chain, exportFile); err != nil { utils.Fatalf("Unable to export chain for reimport %s\n", err) } - - ethereum.BlockDb().Close() - ethereum.StateDb().Close() - ethereum.ExtraDb().Close() - + flushAll(blockDB, stateDB, extraDB) os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain")) os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state")) - ethereum, err = eth.New(cfg) - if err != nil { - utils.Fatalf("%v\n", err) - } - - ethereum.BlockDb().Put([]byte("BlockchainVersion"), common.NewValue(core.BlockChainVersion).Bytes()) - - err = utils.ImportChain(ethereum.ChainManager(), exportFile) + // Import the chain file. + chain, blockDB, stateDB, extraDB = utils.GetChain(ctx) + blockDB.Put([]byte("BlockchainVersion"), common.NewValue(core.BlockChainVersion).Bytes()) + err := utils.ImportChain(chain, exportFile) + flushAll(blockDB, stateDB, extraDB) if err != nil { utils.Fatalf("Import error %v (a backup is made in %s, use the import command to import it)\n", err, exportFile) + } else { + os.Remove(exportFile) + glog.Infoln("Import finished") } - - // force database flush - ethereum.BlockDb().Flush() - ethereum.StateDb().Flush() - ethereum.ExtraDb().Flush() - - os.Remove(exportFile) - - fmt.Println("Import finished") } func dump(ctx *cli.Context) { - chainmgr, _, stateDb := utils.GetChain(ctx) + chain, _, stateDB, _ := utils.GetChain(ctx) for _, arg := range ctx.Args() { var block *types.Block if hashish(arg) { - block = chainmgr.GetBlock(common.HexToHash(arg)) + block = chain.GetBlock(common.HexToHash(arg)) } else { num, _ := strconv.Atoi(arg) - block = chainmgr.GetBlockByNumber(uint64(num)) + block = chain.GetBlockByNumber(uint64(num)) } if block == nil { fmt.Println("{}") utils.Fatalf("block not found") } else { - statedb := state.New(block.Root(), stateDb) - fmt.Printf("%s\n", statedb.Dump()) + state := state.New(block.Root(), stateDB) + fmt.Printf("%s\n", state.Dump()) } } } @@ -707,3 +653,10 @@ func hashish(x string) bool { _, err := strconv.Atoi(x) return err != nil } + +func flushAll(dbs ...common.Database) { + for _, db := range dbs { + db.Flush() + db.Close() + } +} diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 39b4e46da..550ac1c51 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -167,7 +167,7 @@ func FormatTransactionData(data string) []byte { } func ImportChain(chainmgr *core.ChainManager, fn string) error { - fmt.Printf("importing blockchain '%s'\n", fn) + glog.Infoln("Importing blockchain", fn) fh, err := os.OpenFile(fn, os.O_RDONLY, os.ModePerm) if err != nil { return err @@ -176,43 +176,36 @@ func ImportChain(chainmgr *core.ChainManager, fn string) error { chainmgr.Reset() stream := rlp.NewStream(fh, 0) - var i, n int batchSize := 2500 blocks := make(types.Blocks, batchSize) - - for ; ; i++ { - var b types.Block - if err := stream.Decode(&b); err == io.EOF { - break - } else if err != nil { - return fmt.Errorf("at block %d: %v", i, err) - } - - blocks[n] = &b - n++ - - if n == batchSize { - if _, err := chainmgr.InsertChain(blocks); err != nil { - return fmt.Errorf("invalid block %v", err) + n := 0 + for { + // Load a batch of RLP blocks. + i := 0 + for ; i < batchSize; i++ { + var b types.Block + if err := stream.Decode(&b); err == io.EOF { + break + } else if err != nil { + return fmt.Errorf("at block %d: %v", n, err) } - n = 0 - blocks = make(types.Blocks, batchSize) + blocks[i] = &b + n++ + } + if i == 0 { + break + } + // Import the batch. + if _, err := chainmgr.InsertChain(blocks[:i]); err != nil { + return fmt.Errorf("invalid block %d: %v", n, err) } } - - if n > 0 { - if _, err := chainmgr.InsertChain(blocks[:n]); err != nil { - return fmt.Errorf("invalid block %v", err) - } - } - - fmt.Printf("imported %d blocks\n", i) return nil } func ExportChain(chainmgr *core.ChainManager, fn string) error { - fmt.Printf("exporting blockchain '%s'\n", fn) + glog.Infoln("Exporting blockchain to", fn) fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) if err != nil { return err @@ -221,6 +214,6 @@ func ExportChain(chainmgr *core.ChainManager, fn string) error { if err := chainmgr.Export(fh); err != nil { return err } - fmt.Printf("exported blockchain\n") + glog.Infoln("Exported blockchain to", fn) return nil } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 155110ddc..176a546f1 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -283,20 +283,10 @@ func GetNodeKey(ctx *cli.Context) (key *ecdsa.PrivateKey) { } func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config { - // Set verbosity on glog - glog.SetV(ctx.GlobalInt(VerbosityFlag.Name)) - glog.CopyStandardLogTo("INFO") - // Set the log type - //glog.SetToStderr(ctx.GlobalBool(LogToStdErrFlag.Name)) - glog.SetToStderr(true) - // Set the log dir - glog.SetLogDir(ctx.GlobalString(LogFileFlag.Name)) - customName := ctx.GlobalString(IdentityFlag.Name) if len(customName) > 0 { clientID += "/" + customName } - return ð.Config{ Name: common.MakeName(clientID, version), DataDir: ctx.GlobalString(DataDirFlag.Name), @@ -327,32 +317,34 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config { } } -func GetChain(ctx *cli.Context) (*core.ChainManager, common.Database, common.Database) { - dataDir := ctx.GlobalString(DataDirFlag.Name) +// SetupLogger configures glog from the logging-related command line flags. +func SetupLogger(ctx *cli.Context) { + glog.SetV(ctx.GlobalInt(VerbosityFlag.Name)) + glog.CopyStandardLogTo("INFO") + glog.SetToStderr(true) + glog.SetLogDir(ctx.GlobalString(LogFileFlag.Name)) +} - blockDb, err := ethdb.NewLDBDatabase(filepath.Join(dataDir, "blockchain")) - if err != nil { +func GetChain(ctx *cli.Context) (chain *core.ChainManager, blockDB, stateDB, extraDB common.Database) { + dd := ctx.GlobalString(DataDirFlag.Name) + var err error + if blockDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "blockchain")); err != nil { Fatalf("Could not open database: %v", err) } - - stateDb, err := ethdb.NewLDBDatabase(filepath.Join(dataDir, "state")) - if err != nil { + if stateDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "state")); err != nil { Fatalf("Could not open database: %v", err) } - - extraDb, err := ethdb.NewLDBDatabase(filepath.Join(dataDir, "extra")) - if err != nil { + if extraDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "extra")); err != nil { Fatalf("Could not open database: %v", err) } eventMux := new(event.TypeMux) pow := ethash.New() - chainManager := core.NewChainManager(blockDb, stateDb, pow, eventMux) - txPool := core.NewTxPool(eventMux, chainManager.State, chainManager.GasLimit) - blockProcessor := core.NewBlockProcessor(stateDb, extraDb, pow, txPool, chainManager, eventMux) - chainManager.SetProcessor(blockProcessor) - - return chainManager, blockDb, stateDb + chain = core.NewChainManager(blockDB, stateDB, pow, eventMux) + txpool := core.NewTxPool(eventMux, chain.State, chain.GasLimit) + proc := core.NewBlockProcessor(stateDB, extraDB, pow, txpool, chain, eventMux) + chain.SetProcessor(proc) + return chain, blockDB, stateDB, extraDB } func GetAccountManager(ctx *cli.Context) *accounts.Manager {