func blockRecovery(ctx *cli.Context) { if len(ctx.Args()) < 1 { glog.Fatal("recover requires block number or hash") } arg := ctx.Args().First() cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx) blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"), cfg.DatabaseCache) if err != nil { glog.Fatalln("could not open db:", err) } var block *types.Block if arg[0] == '#' { block = core.GetBlock(blockDb, core.GetCanonicalHash(blockDb, common.String2Big(arg[1:]).Uint64())) } else { block = core.GetBlock(blockDb, common.HexToHash(arg)) } if block == nil { glog.Fatalln("block not found. Recovery failed") } if err = core.WriteHeadBlockHash(blockDb, block.Hash()); err != nil { glog.Fatalln("block write err", err) } glog.Infof("Recovery succesful. New HEAD %x\n", block.Hash()) }
func (self *Filter) getLogs(start, end uint64) (logs vm.Logs) { var block *types.Block for i := start; i <= end; i++ { hash := core.GetCanonicalHash(self.db, i) if hash != (common.Hash{}) { block = core.GetBlock(self.db, hash) } else { // block not found return logs } // Use bloom filtering to see if this block is interesting given the // current parameters if self.bloomFilter(block) { // Get the logs of the block var ( receipts = core.GetBlockReceipts(self.db, block.Hash()) unfiltered vm.Logs ) for _, receipt := range receipts { unfiltered = append(unfiltered, receipt.Logs...) } logs = append(logs, self.FilterLogs(unfiltered)...) } } return logs }
// MustMakeChainConfigFromDb reads the chain configuration from the given database. func MustMakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainConfig { // If the chain is already initialized, use any existing chain configs config := new(core.ChainConfig) genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0)) if genesis != nil { storedConfig, err := core.GetChainConfig(db, genesis.Hash()) switch err { case nil: config = storedConfig case core.ChainConfigNotFoundErr: // No configs found, use empty, will populate below default: Fatalf("Could not make chain configuration: %v", err) } } // Set any missing fields due to them being unset or system upgrade if config.HomesteadBlock == nil { if ctx.GlobalBool(TestNetFlag.Name) { config.HomesteadBlock = params.TestNetHomesteadBlock } else { config.HomesteadBlock = params.MainNetHomesteadBlock } } if config.DAOForkBlock == nil { if ctx.GlobalBool(TestNetFlag.Name) { config.DAOForkBlock = params.TestNetDAOForkBlock } else { config.DAOForkBlock = params.MainNetDAOForkBlock } config.DAOForkSupport = true } // Force override any existing configs if explicitly requested switch { case ctx.GlobalBool(SupportDAOFork.Name): config.DAOForkSupport = true case ctx.GlobalBool(OpposeDAOFork.Name): config.DAOForkSupport = false } // Temporarilly display a proper message so the user knows which fork its on if !ctx.GlobalBool(TestNetFlag.Name) && (genesis == nil || genesis.Hash() == common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")) { choice := "SUPPORT" if !config.DAOForkSupport { choice = "OPPOSE" } current := fmt.Sprintf("Geth is currently configured to %s the DAO hard-fork!", choice) howtoswap := fmt.Sprintf("You can change your choice prior to block #%v with --support-dao-fork or --oppose-dao-fork.", config.DAOForkBlock) howtosync := fmt.Sprintf("After the hard-fork block #%v passed, changing chains requires a resync from scratch!", config.DAOForkBlock) separator := strings.Repeat("-", len(howtoswap)) glog.V(logger.Warn).Info(separator) glog.V(logger.Warn).Info(current) glog.V(logger.Warn).Info(howtoswap) glog.V(logger.Warn).Info(howtosync) glog.V(logger.Warn).Info(separator) } return config }
// Run filters logs with the current parameters set func (self *Filter) Find() vm.Logs { latestBlock := core.GetBlock(self.db, core.GetHeadBlockHash(self.db)) var beginBlockNo uint64 = uint64(self.begin) if self.begin == -1 { beginBlockNo = latestBlock.NumberU64() } var endBlockNo uint64 = uint64(self.end) if self.end == -1 { endBlockNo = latestBlock.NumberU64() } // if no addresses are present we can't make use of fast search which // uses the mipmap bloom filters to check for fast inclusion and uses // higher range probability in order to ensure at least a false positive if len(self.addresses) == 0 { return self.getLogs(beginBlockNo, endBlockNo) } return self.mipFind(beginBlockNo, endBlockNo, 0) }
// MustMakeChainConfigFromDb reads the chain configuration from the given database. func MustMakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainConfig { genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0)) if genesis != nil { // Existing genesis block, use stored config if available. storedConfig, err := core.GetChainConfig(db, genesis.Hash()) if err == nil { return storedConfig } else if err != core.ChainConfigNotFoundErr { Fatalf("Could not make chain configuration: %v", err) } } var homesteadBlockNo *big.Int if ctx.GlobalBool(TestNetFlag.Name) { homesteadBlockNo = params.TestNetHomesteadBlock } else { homesteadBlockNo = params.MainNetHomesteadBlock } return &core.ChainConfig{HomesteadBlock: homesteadBlockNo} }
func addMipmapBloomBins(db ethdb.Database) (err error) { const mipmapVersion uint = 2 // check if the version is set. We ignore data for now since there's // only one version so we can easily ignore it for now var data []byte data, _ = db.Get([]byte("setting-mipmap-version")) if len(data) > 0 { var version uint if err := rlp.DecodeBytes(data, &version); err == nil && version == mipmapVersion { return nil } } defer func() { if err == nil { var val []byte val, err = rlp.EncodeToBytes(mipmapVersion) if err == nil { err = db.Put([]byte("setting-mipmap-version"), val) } return } }() latestBlock := core.GetBlock(db, core.GetHeadBlockHash(db)) if latestBlock == nil { // clean database return } tstart := time.Now() glog.V(logger.Info).Infoln("upgrading db log bloom bins") for i := uint64(0); i <= latestBlock.NumberU64(); i++ { hash := core.GetCanonicalHash(db, i) if (hash == common.Hash{}) { return fmt.Errorf("chain db corrupted. Could not find block %d.", i) } core.WriteMipmapBloom(db, i, core.GetBlockReceipts(db, hash)) } glog.V(logger.Info).Infoln("upgrade completed in", time.Since(tstart)) return nil }
func New(ctx *node.ServiceContext, config *Config) (*Ethereum, 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("eth/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("eth/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 geth upgradedb.\n", bcVersion, config.BlockChainVersion) } core.WriteBlockChainVersion(chainDb, config.BlockChainVersion) } glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) eth := &Ethereum{ 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") eth.pow, err = ethash.NewForTesting() if err != nil { return nil, err } case config.PowShared: glog.V(logger.Info).Infof("ethash used in shared mode") eth.pow = ethash.NewShared() default: eth.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 ethereum genesis block") } if config.ChainConfig == nil { return nil, errors.New("missing chain config") } eth.chainConfig = config.ChainConfig eth.chainConfig.VmConfig = vm.Config{ EnableJit: config.EnableJit, ForceJit: config.ForceJit, } eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.pow, eth.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 } eth.gpo = NewGasPriceOracle(eth) newPool := core.NewTxPool(eth.chainConfig, eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit) eth.txPool = newPool if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.FastSync, config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.blockchain, chainDb); err != nil { return nil, err } eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.pow) eth.miner.SetGasPrice(config.GasPrice) eth.miner.SetExtra(config.ExtraData) return eth, nil }