func upgradeDB(ctx *cli.Context) error { glog.Infoln("Upgrading blockchain database") chain, chainDb := utils.MakeChain(ctx) bcVersion := core.GetBlockChainVersion(chainDb) 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) if err := utils.ExportChain(chain, exportFile); err != nil { utils.Fatalf("Unable to export chain for reimport %s", err) } chainDb.Close() os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "chaindata")) // Import the chain file. chain, chainDb = utils.MakeChain(ctx) core.WriteBlockChainVersion(chainDb, core.BlockChainVersion) err := utils.ImportChain(chain, exportFile) chainDb.Close() if err != nil { utils.Fatalf("Import error %v (a backup is made in %s, use the import command to import it)", err, exportFile) } else { os.Remove(exportFile) glog.Infoln("Import finished") } return nil }
func New(ctx *node.ServiceContext, config *Config) (*Expanse, error) { // Open the chain database and perform any upgrades needed chainDb, err := ctx.OpenDatabase("chaindata", config.DatabaseCache, config.DatabaseHandles) if err != nil { return nil, err } if db, ok := chainDb.(*ethdb.LDBDatabase); ok { db.Meter("exp/db/chaindata/") } if err := upgradeChainDatabase(chainDb); err != nil { return nil, err } if err := addMipmapBloomBins(chainDb); err != nil { return nil, err } dappDb, err := ctx.OpenDatabase("dapp", config.DatabaseCache, config.DatabaseHandles) if err != nil { return nil, err } if db, ok := dappDb.(*ethdb.LDBDatabase); ok { db.Meter("exp/db/dapp/") } glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId) // Load up any custom genesis block if requested if len(config.Genesis) > 0 { block, err := core.WriteGenesisBlock(chainDb, strings.NewReader(config.Genesis)) if err != nil { return nil, err } glog.V(logger.Info).Infof("Successfully wrote custom genesis block: %x", block.Hash()) } // Load up a test setup if directly injected if config.TestGenesisState != nil { chainDb = config.TestGenesisState } if config.TestGenesisBlock != nil { core.WriteTd(chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.Difficulty()) core.WriteBlock(chainDb, config.TestGenesisBlock) core.WriteCanonicalHash(chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64()) core.WriteHeadBlockHash(chainDb, config.TestGenesisBlock.Hash()) } if !config.SkipBcVersionCheck { bcVersion := core.GetBlockChainVersion(chainDb) if bcVersion != config.BlockChainVersion && bcVersion != 0 { return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run gexp upgradedb.\n", bcVersion, config.BlockChainVersion) } core.WriteBlockChainVersion(chainDb, config.BlockChainVersion) } glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) exp := &Expanse{ shutdownChan: make(chan bool), chainDb: chainDb, dappDb: dappDb, eventMux: ctx.EventMux, accountManager: config.AccountManager, etherbase: config.Etherbase, netVersionId: config.NetworkId, NatSpec: config.NatSpec, MinerThreads: config.MinerThreads, SolcPath: config.SolcPath, AutoDAG: config.AutoDAG, PowTest: config.PowTest, GpoMinGasPrice: config.GpoMinGasPrice, GpoMaxGasPrice: config.GpoMaxGasPrice, GpoFullBlockRatio: config.GpoFullBlockRatio, GpobaseStepDown: config.GpobaseStepDown, GpobaseStepUp: config.GpobaseStepUp, GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, httpclient: httpclient.New(config.DocRoot), } switch { case config.PowTest: glog.V(logger.Info).Infof("ethash used in test mode") exp.pow, err = ethash.NewForTesting() if err != nil { return nil, err } case config.PowShared: glog.V(logger.Info).Infof("ethash used in shared mode") exp.pow = ethash.NewShared() default: exp.pow = ethash.New() } // load the genesis block or write a new one if no genesis // block is prenent in the database. genesis := core.GetBlock(chainDb, core.GetCanonicalHash(chainDb, 0)) if genesis == nil { genesis, err = core.WriteDefaultGenesisBlock(chainDb) if err != nil { return nil, err } glog.V(logger.Info).Infoln("WARNING: Wrote default expanse genesis block") } if config.ChainConfig == nil { return nil, errors.New("missing chain config") } core.WriteChainConfig(chainDb, genesis.Hash(), config.ChainConfig) exp.chainConfig = config.ChainConfig exp.chainConfig.VmConfig = vm.Config{ EnableJit: config.EnableJit, ForceJit: config.ForceJit, } exp.blockchain, err = core.NewBlockChain(chainDb, exp.chainConfig, exp.pow, exp.EventMux()) if err != nil { if err == core.ErrNoGenesis { return nil, fmt.Errorf(`No chain found. Please initialise a new chain using the "init" subcommand.`) } return nil, err } exp.gpo = NewGasPriceOracle(exp) newPool := core.NewTxPool(exp.chainConfig, exp.EventMux(), exp.blockchain.State, exp.blockchain.GasLimit) exp.txPool = newPool if exp.protocolManager, err = NewProtocolManager(exp.chainConfig, config.FastSync, config.NetworkId, exp.eventMux, exp.txPool, exp.pow, exp.blockchain, chainDb); err != nil { return nil, err } exp.miner = miner.New(exp, exp.chainConfig, exp.EventMux(), exp.pow) exp.miner.SetGasPrice(config.GasPrice) exp.miner.SetExtra(config.ExtraData) return exp, nil }