func getHeight(database database.Db, str string) (int64, error) { argtype, idx, sha, err := parsesha(str) if err != nil { log.Warnf("unable to decode [%v] %v", str, err) return 0, err } switch argtype { case ArgSha: // nothing to do blk, err := database.FetchBlockBySha(sha) if err != nil { log.Warnf("unable to locate block sha %v err %v", sha, err) return 0, err } idx = blk.Height() case ArgHeight: } return idx, nil }
func DumpBlock(database database.Db, height int64, fo io.Writer, rflag bool, fflag bool, tflag bool) error { sha, err := database.FetchBlockShaByHeight(height) if err != nil { return err } blk, err := database.FetchBlockBySha(sha) if err != nil { log.Warnf("Failed to fetch block %v, err %v", sha, err) return err } rblk, err := blk.Bytes() blkid := blk.Height() if rflag { log.Infof("Block %v depth %v %v", sha, blkid, spew.Sdump(rblk)) } mblk := blk.MsgBlock() if fflag { log.Infof("Block %v depth %v %v", sha, blkid, spew.Sdump(mblk)) } if tflag { log.Infof("Num transactions %v", len(mblk.Transactions)) for i, tx := range mblk.Transactions { txsha := tx.TxSha() log.Infof("tx %v: %v", i, &txsha) } } if fo != nil { // generate and write header values binary.Write(fo, binary.LittleEndian, uint32(wire.SimNet)) binary.Write(fo, binary.LittleEndian, uint32(len(rblk))) // write block fo.Write(rblk) } return nil }
// findCandidates searches the chain backwards for checkpoint candidates and // returns a slice of found candidates, if any. It also stops searching for // candidates at the last checkpoint that is already hard coded into chain // since there is no point in finding candidates before already existing // checkpoints. func findCandidates(db database.Db, latestHash *chainhash.Hash) ([]*chaincfg.Checkpoint, error) { // Start with the latest block of the main chain. block, err := db.FetchBlockBySha(latestHash) if err != nil { return nil, err } // Setup chain and get the latest checkpoint. Ignore notifications // since they aren't needed for this util. chain := blockchain.New(db, nil, activeNetParams, nil, nil) latestCheckpoint := chain.LatestCheckpoint() if latestCheckpoint == nil { // Set the latest checkpoint to the genesis block if there isn't // already one. latestCheckpoint = &chaincfg.Checkpoint{ Hash: activeNetParams.GenesisHash, Height: 0, } } // The latest known block must be at least the last known checkpoint // plus required checkpoint confirmations. checkpointConfirmations := int64(blockchain.CheckpointConfirmations) requiredHeight := latestCheckpoint.Height + checkpointConfirmations if block.Height() < requiredHeight { return nil, fmt.Errorf("the block database is only at height "+ "%d which is less than the latest checkpoint height "+ "of %d plus required confirmations of %d", block.Height(), latestCheckpoint.Height, checkpointConfirmations) } // For the first checkpoint, the required height is any block after the // genesis block, so long as the chain has at least the required number // of confirmations (which is enforced above). if len(activeNetParams.Checkpoints) == 0 { requiredHeight = 1 } // Indeterminate progress setup. numBlocksToTest := block.Height() - requiredHeight progressInterval := (numBlocksToTest / 100) + 1 // min 1 fmt.Print("Searching for candidates") defer fmt.Println() // Loop backwards through the chain to find checkpoint candidates. candidates := make([]*chaincfg.Checkpoint, 0, cfg.NumCandidates) numTested := int64(0) for len(candidates) < cfg.NumCandidates && block.Height() > requiredHeight { // Display progress. if numTested%progressInterval == 0 { fmt.Print(".") } // Determine if this block is a checkpoint candidate. isCandidate, err := chain.IsCheckpointCandidate(block) if err != nil { return nil, err } // All checks passed, so this node seems like a reasonable // checkpoint candidate. if isCandidate { checkpoint := chaincfg.Checkpoint{ Height: block.Height(), Hash: block.Sha(), } candidates = append(candidates, &checkpoint) } prevHash := &block.MsgBlock().Header.PrevBlock block, err = db.FetchBlockBySha(prevHash) if err != nil { return nil, err } numTested++ } return candidates, nil }