瀏覽代碼

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.
Felix Lange 10 年之前
父節點
當前提交
3b9808f23c
共有 3 個文件被更改,包括 72 次插入134 次删除
  1. 33 80
      cmd/geth/main.go
  2. 21 28
      cmd/utils/cmd.go
  3. 18 26
      cmd/utils/flags.go

+ 33 - 80
cmd/geth/main.go

@@ -41,6 +41,7 @@ import (
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/eth"
 	"github.com/ethereum/go-ethereum/eth"
 	"github.com/ethereum/go-ethereum/logger"
 	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/logger/glog"
 	"github.com/mattn/go-colorable"
 	"github.com/mattn/go-colorable"
 	"github.com/mattn/go-isatty"
 	"github.com/mattn/go-isatty"
 )
 )
@@ -282,17 +283,12 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
 		utils.SolcPathFlag,
 		utils.SolcPathFlag,
 	}
 	}
 	app.Before = func(ctx *cli.Context) error {
 	app.Before = func(ctx *cli.Context) error {
+		utils.SetupLogger(ctx)
 		if ctx.GlobalBool(utils.PProfEanbledFlag.Name) {
 		if ctx.GlobalBool(utils.PProfEanbledFlag.Name) {
 			utils.StartPProf(ctx)
 			utils.StartPProf(ctx)
 		}
 		}
 		return nil
 		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() {
 func main() {
@@ -516,53 +512,25 @@ func importchain(ctx *cli.Context) {
 	if len(ctx.Args()) != 1 {
 	if len(ctx.Args()) != 1 {
 		utils.Fatalf("This command requires an argument.")
 		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()
 	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)
 		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))
 	fmt.Printf("Import done in %v", time.Since(start))
-
-	return
 }
 }
 
 
 func exportchain(ctx *cli.Context) {
 func exportchain(ctx *cli.Context) {
 	if len(ctx.Args()) != 1 {
 	if len(ctx.Args()) != 1 {
 		utils.Fatalf("This command requires an argument.")
 		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()
 	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)
 		utils.Fatalf("Export error: %v\n", err)
 	}
 	}
 	fmt.Printf("Export done in %v", time.Since(start))
 	fmt.Printf("Export done in %v", time.Since(start))
-	return
 }
 }
 
 
 func removeDb(ctx *cli.Context) {
 func removeDb(ctx *cli.Context) {
@@ -585,76 +553,54 @@ func removeDb(ctx *cli.Context) {
 }
 }
 
 
 func upgradeDb(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())
 	bcVersion := int(common.NewValue(v).Uint())
-
 	if bcVersion == 0 {
 	if bcVersion == 0 {
 		bcVersion = core.BlockChainVersion
 		bcVersion = core.BlockChainVersion
 	}
 	}
 
 
+	// Export the current chain.
 	filename := fmt.Sprintf("blockchain_%d_%s.chain", bcVersion, time.Now().Format("20060102_150405"))
 	filename := fmt.Sprintf("blockchain_%d_%s.chain", bcVersion, time.Now().Format("20060102_150405"))
 	exportFile := filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), filename)
 	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)
 		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), "blockchain"))
 	os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state"))
 	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 {
 	if err != nil {
 		utils.Fatalf("Import error %v (a backup is made in %s, use the import command to import it)\n", err, exportFile)
 		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) {
 func dump(ctx *cli.Context) {
-	chainmgr, _, stateDb := utils.GetChain(ctx)
+	chain, _, stateDB, _ := utils.GetChain(ctx)
 	for _, arg := range ctx.Args() {
 	for _, arg := range ctx.Args() {
 		var block *types.Block
 		var block *types.Block
 		if hashish(arg) {
 		if hashish(arg) {
-			block = chainmgr.GetBlock(common.HexToHash(arg))
+			block = chain.GetBlock(common.HexToHash(arg))
 		} else {
 		} else {
 			num, _ := strconv.Atoi(arg)
 			num, _ := strconv.Atoi(arg)
-			block = chainmgr.GetBlockByNumber(uint64(num))
+			block = chain.GetBlockByNumber(uint64(num))
 		}
 		}
 		if block == nil {
 		if block == nil {
 			fmt.Println("{}")
 			fmt.Println("{}")
 			utils.Fatalf("block not found")
 			utils.Fatalf("block not found")
 		} else {
 		} 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)
 	_, err := strconv.Atoi(x)
 	return err != nil
 	return err != nil
 }
 }
+
+func flushAll(dbs ...common.Database) {
+	for _, db := range dbs {
+		db.Flush()
+		db.Close()
+	}
+}

+ 21 - 28
cmd/utils/cmd.go

@@ -167,7 +167,7 @@ func FormatTransactionData(data string) []byte {
 }
 }
 
 
 func ImportChain(chainmgr *core.ChainManager, fn string) error {
 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)
 	fh, err := os.OpenFile(fn, os.O_RDONLY, os.ModePerm)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -176,43 +176,36 @@ func ImportChain(chainmgr *core.ChainManager, fn string) error {
 
 
 	chainmgr.Reset()
 	chainmgr.Reset()
 	stream := rlp.NewStream(fh, 0)
 	stream := rlp.NewStream(fh, 0)
-	var i, n int
 
 
 	batchSize := 2500
 	batchSize := 2500
 	blocks := make(types.Blocks, batchSize)
 	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 n > 0 {
-		if _, err := chainmgr.InsertChain(blocks[:n]); err != nil {
-			return fmt.Errorf("invalid block %v", err)
+		if i == 0 {
+			break
+		}
+		// Import the batch.
+		if _, err := chainmgr.InsertChain(blocks[:i]); err != nil {
+			return fmt.Errorf("invalid block %d: %v", n, err)
 		}
 		}
 	}
 	}
-
-	fmt.Printf("imported %d blocks\n", i)
 	return nil
 	return nil
 }
 }
 
 
 func ExportChain(chainmgr *core.ChainManager, fn string) error {
 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)
 	fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -221,6 +214,6 @@ func ExportChain(chainmgr *core.ChainManager, fn string) error {
 	if err := chainmgr.Export(fh); err != nil {
 	if err := chainmgr.Export(fh); err != nil {
 		return err
 		return err
 	}
 	}
-	fmt.Printf("exported blockchain\n")
+	glog.Infoln("Exported blockchain to", fn)
 	return nil
 	return nil
 }
 }

+ 18 - 26
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 {
 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)
 	customName := ctx.GlobalString(IdentityFlag.Name)
 	if len(customName) > 0 {
 	if len(customName) > 0 {
 		clientID += "/" + customName
 		clientID += "/" + customName
 	}
 	}
-
 	return &eth.Config{
 	return &eth.Config{
 		Name:               common.MakeName(clientID, version),
 		Name:               common.MakeName(clientID, version),
 		DataDir:            ctx.GlobalString(DataDirFlag.Name),
 		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)
 		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)
 		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)
 		Fatalf("Could not open database: %v", err)
 	}
 	}
 
 
 	eventMux := new(event.TypeMux)
 	eventMux := new(event.TypeMux)
 	pow := ethash.New()
 	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 {
 func GetAccountManager(ctx *cli.Context) *accounts.Manager {