func blockRecovery(ctx *cli.Context) { utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name)) arg := ctx.Args().First() if len(ctx.Args()) < 1 && len(arg) > 0 { glog.Fatal("recover requires block number or hash") } cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx) utils.CheckLegalese(cfg.DataDir) 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.GetBlockByNumber(blockDb, common.String2Big(arg[1:]).Uint64()) } else { block = core.GetBlockByHash(blockDb, common.HexToHash(arg)) } if block == nil { glog.Fatalln("block not found. Recovery failed") } err = core.WriteHead(blockDb, block) if err != nil { glog.Fatalln("block write err", err) } glog.Infof("Recovery succesful. New HEAD %x\n", block.Hash()) }
// insert injects a block into the current chain block chain. Note, this function // assumes that the `mu` mutex is held! func (bc *ChainManager) insert(block *types.Block) { err := WriteHead(bc.chainDb, block) if err != nil { glog.Fatal("db write fail:", err) } bc.checkpoint++ if bc.checkpoint > checkpointLimit { err = bc.chainDb.Put([]byte("checkpoint"), block.Hash().Bytes()) if err != nil { glog.Fatal("db write fail:", err) } bc.checkpoint = 0 } bc.currentBlock = block bc.lastBlockHash = block.Hash() }
// Flush flushes the trie to the backing layer. If this is a leveldb instance // we'll use a batched write, otherwise we'll use regular put. func (self *Cache) Flush() { if db, ok := self.backend.(*ethdb.LDBDatabase); ok { if err := db.LDB().Write(self.batch, nil); err != nil { glog.Fatal("db write err:", err) } } else { for k, v := range self.store { self.backend.Put([]byte(k), v) } } }
func NewChainManager(chainDb common.Database, sqlDB types.SQLDatabase, pow pow.PoW, mux *event.TypeMux) (*ChainManager, error) { cache, _ := lru.New(blockCacheLimit) bc := &ChainManager{ chainDb: chainDb, sqlDB: sqlDB, eventMux: mux, quit: make(chan struct{}), cache: cache, pow: pow, } bc.genesisBlock = bc.GetBlockByNumber(0) if bc.genesisBlock == nil { reader, err := NewDefaultGenesisReader() if err != nil { return nil, err } bc.genesisBlock, err = WriteGenesisBlock(chainDb, reader) if err != nil { return nil, err } glog.V(logger.Info).Infoln("WARNING: Wrote default shift genesis block") } if err := bc.setLastState(); err != nil { return nil, err } // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain for hash, _ := range BadHashes { if block := bc.GetBlock(hash); block != nil { glog.V(logger.Error).Infof("Found bad hash. Reorganising chain to state %x\n", block.ParentHash().Bytes()[:4]) block = bc.GetBlock(block.ParentHash()) if block == nil { glog.Fatal("Unable to complete. Parent block not found. Corrupted DB?") } bc.SetHead(block) glog.V(logger.Error).Infoln("Chain reorg was successfull. Resuming normal operation") } } // Take ownership of this particular state bc.futureBlocks, _ = lru.New(maxFutureBlocks) bc.makeCache() go bc.update() return bc, nil }
// WriteBlock writes a block to the database func WriteBlock(db common.Database, block *types.Block) error { tstart := time.Now() enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block)) key := append(blockHashPre, block.Hash().Bytes()...) err := db.Put(key, enc) if err != nil { glog.Fatal("db write fail:", err) return err } if glog.V(logger.Debug) { glog.Infof("wrote block #%v %s. Took %v\n", block.Number(), common.PP(block.Hash().Bytes()), time.Since(tstart)) } return nil }