// GetBlockSummaryHeight returns the largest block height for which the database
// can provide a block summary. A cached best block summary height will be
// returned when available to avoid unnecessary DB queries.
431813
func (db *DB) GetBlockSummaryHeight() (int64, error) {
	db.mtx.RLock()
	defer db.mtx.RUnlock()
	if db.dbSummaryHeight < 0 {
		h, err := db.getBlockSummaryHeight()
		if err == nil {
			db.dbSummaryHeight = h
		}
		return h, err
	}
	return db.dbSummaryHeight, nil
}
465074
func (db *WiredDB) GetBestBlockHeightHash() (chainhash.Hash, int64, error) {
	bestBlockSummary := db.GetBestBlockSummary()
	if bestBlockSummary == nil {
		return chainhash.Hash{}, -1, fmt.Errorf("unable to retrieve best block summary")
	}
	height := int64(bestBlockSummary.Height)
	hash, err := chainhash.NewHashFromStr(bestBlockSummary.Hash)
	return *hash, height, err
}
547433
func (db *SQLDB) GetBlock(height uint64) (types.EventData, error) {
	var data types.EventData
	data.BlockHeight = height
	data.Tables = make(map[string]types.EventDataTable)

	// get all table structures involved in the block
	tables, err := db.getBlockTables(height)
	if err != nil {
		return data, err
	}

	query := ""

	// for each table
	for _, table := range tables {
		// get query for table
		query, err = db.getSelectQuery(table, height)
		if err != nil {
			db.Log.Info("msg", "Error building table query", "err", err)
			return data, err
		}
		db.Log.Info("msg", "Query table data", "query", query)
		rows, err := db.DB.Query(query)
		if err != nil {
			db.Log.Info("msg", "Error querying table data", "err", err)
			return data, err
		}
		defer rows.Close()

		cols, err := rows.Columns()
		if err != nil {
			db.Log.Info("msg", "Error getting row columns", "err", err)
			return data, err
		}

		// builds pointers
		length := len(cols)
		pointers := make([]interface{}, length)
		containers := make([]sql.NullString, length)

		for i := range pointers {
			pointers[i] = &containers[i]
		}

		// for each row in table
		var dataRows []types.EventDataRow

		for rows.Next() {

			row := make(map[string]interface{})

			if err = rows.Scan(pointers...); err != nil {
				db.Log.Info("msg", "Error scanning data", "err", err)
				return data, err
			}
			db.Log.Info("msg", "Query resultset", "value", fmt.Sprintf("%+v", containers))

			// for each column in row
			for i, col := range cols {
				// add value if not null
				if containers[i].Valid {
					row[col] = containers[i].String
				}
			}
			dataRows = append(dataRows, types.EventDataRow{Action: types.ActionRead, RowData: row})
		}

		if err = rows.Err(); err != nil {
			db.Log.Info("msg", "Error during rows iteration", "err", err)
			return data, err
		}
		data.Tables[table.Name] = dataRows
	}
	return data, nil
}
960928
func (b *BlockChain) BlockByHeight(blockHeight int32) (*btcutil.Block, error) {
	// Lookup the block height in the best chain.
	node := b.bestChain.NodeByHeight(blockHeight)
	if node == nil {
		str := fmt.Sprintf("no block at height %d exists", blockHeight)
		return nil, errNotInMainChain(str)
	}

	// Load the block from the database and return it.
	var block *btcutil.Block
	err := b.db.View(func(dbTx database.Tx) error {
		var err error
		block, err = dbFetchBlockByNode(dbTx, node)
		return err
	})
	return block, err
}
1080350
func (h *blockHeaderStore) FetchHeaderByHeight(height uint32) (*wire.BlockHeader, error) {
	// Lock store for read.
	h.mtx.RLock()
	defer h.mtx.RUnlock()

	// For this query, we don't need to consult the index, and can instead
	// just seek into the flat file based on the target height and return
	// the full header.
	header, err := h.readHeader(height)
	if err != nil {
		return nil, err
	}

	return &header, nil
}
334601
func (apic *APICache) GetBlockHash(height int64) string {
	if !apic.IsEnabled() {
		return ""
	}
	hash, ok := apic.blockHash(height)
	if !ok {
		return ""
	}
	return hash.String()
}
1271258
func getMissedBlocks(chainConn ChainConn, startingHeight,
	endingHeight int32) ([]BlockEpoch, error) {

	numMissedBlocks := endingHeight - startingHeight
	if numMissedBlocks < 0 {
		return nil, fmt.Errorf("starting height %d is greater than "+
			"ending height %d", startingHeight, endingHeight)
	}

	missedBlocks := make([]BlockEpoch, 0, numMissedBlocks)
	for height := startingHeight; height < endingHeight; height++ {
		hash, err := chainConn.GetBlockHash(int64(height))
		if err != nil {
			return nil, fmt.Errorf("unable to find blockhash for "+
				"height=%d: %v", height, err)
		}
		missedBlocks = append(missedBlocks,
			BlockEpoch{Hash: hash, Height: height})
	}

	return missedBlocks, nil
}
834158
func NewHeightFromBytes(b []byte) (*Height, int) {
	blockNum, n1 := util.DecodeOrderPreservingVarUint64(b)
	txNum, n2 := util.DecodeOrderPreservingVarUint64(b[n1:])
	return NewHeight(blockNum, txNum), n1 + n2
}
1199977
func (_m *Store) PurgeByHeight(maxBlockNumToRetain uint64) error {
	ret := _m.Called(maxBlockNumToRetain)

	var r0 error
	if rf, ok := ret.Get(0).(func(uint64) error); ok {
		r0 = rf(maxBlockNumToRetain)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}
385816
func (s *ChainService) rollBackToHeight(height uint32) (*waddrmgr.BlockStamp, error) {
	header, headerHeight, err := s.BlockHeaders.ChainTip()
	if err != nil {
		return nil, err
	}
	bs := &waddrmgr.BlockStamp{
		Height: int32(headerHeight),
		Hash:   header.BlockHash(),
	}

	_, regHeight, err := s.RegFilterHeaders.ChainTip()
	if err != nil {
		return nil, err
	}

	for uint32(bs.Height) > height {
		header, _, err := s.BlockHeaders.FetchHeader(&bs.Hash)
		if err != nil {
			return nil, err
		}

		newTip := &header.PrevBlock

		// Only roll back filter headers if they've caught up this far.
		if uint32(bs.Height) <= regHeight {
			newFilterTip, err := s.RegFilterHeaders.RollbackLastBlock(newTip)
			if err != nil {
				return nil, err
			}
			regHeight = uint32(newFilterTip.Height)
		}

		bs, err = s.BlockHeaders.RollbackLastBlock()
		if err != nil {
			return nil, err
		}

		// Notifications are asynchronous, so we include the previous
		// header in the disconnected notification in case we're rolling
		// back farther and the notification subscriber needs it but
		// can't read it before it's deleted from the store.
		prevHeader, _, err := s.BlockHeaders.FetchHeader(newTip)
		if err != nil {
			return nil, err
		}

		// Now we send the block disconnected notifications.
		s.blockManager.onBlockDisconnected(
			*header, headerHeight, *prevHeader,
		)
	}
	return bs, nil
}
736498
func (apic *APICache) GetBlockSize(height int64) int32 {
	if !apic.IsEnabled() {
		return -1
	}
	cachedBlock := apic.GetCachedBlockByHeight(height)
	if cachedBlock != nil && cachedBlock.summary != nil {
		return int32(cachedBlock.summary.Size)
	}
	return -1
}
643855
func (db *WiredDB) GetBestBlockSummary() *apitypes.BlockDataBasic {
	// Attempt to retrieve height of best block in DB.
	dbBlkHeight, err := db.GetBlockSummaryHeight()
	if err != nil {
		log.Errorf("GetBlockSummaryHeight failed: %v", err)
		return nil
	}

	// Empty table is not an error.
	if dbBlkHeight == -1 {
		return nil
	}

	// Retrieve the block data.
	blockSummary, err := db.RetrieveBlockSummary(dbBlkHeight)
	if err != nil {
		log.Errorf("Unable to retrieve block %d summary: %v", dbBlkHeight, err)
		return nil
	}

	return blockSummary
}
586896
func (c *chainView) NodeByHeight(height int32) *blockNode {
	c.mtx.Lock()
	node := c.nodeByHeight(height)
	c.mtx.Unlock()
	return node
}
1164579
func (pgb *ChainDB) GetBlockHeight(hash string) (int64, error) {
	ctx, cancel := context.WithTimeout(pgb.ctx, pgb.queryTimeout)
	defer cancel()
	height, err := RetrieveBlockHeight(ctx, pgb.db, hash)
	if err != nil {
		log.Errorf("Unable to get block height for hash %s: %v", hash, err)
		return -1, pgb.replaceCancelError(err)
	}
	return height, nil
}
105200
func fetchBlockHash(ns walletdb.ReadBucket, height int32) (*chainhash.Hash, error) {
	bucket := ns.NestedReadBucket(syncBucketName)
	errStr := fmt.Sprintf("failed to fetch block hash for height %d", height)

	heightBytes := make([]byte, 4)
	binary.BigEndian.PutUint32(heightBytes, uint32(height))
	hashBytes := bucket.Get(heightBytes)
	if hashBytes == nil {
		err := errors.New("block not found")
		return nil, managerError(ErrBlockNotFound, errStr, err)
	}
	if len(hashBytes) != 32 {
		err := fmt.Errorf("couldn't get hash from database")
		return nil, managerError(ErrDatabase, errStr, err)
	}
	var hash chainhash.Hash
	if err := hash.SetBytes(hashBytes); err != nil {
		return nil, managerError(ErrDatabase, errStr, err)
	}
	return &hash, nil
}
308821
func (p *MockPeer) BlockHeight() uint64 {
	p.lock.RLock()
	defer p.lock.RUnlock()
	return p.blockHeight
}
1203459
func (b *BlockData) ToBlockExplorerSummary() apitypes.BlockExplorerBasic {
	extra := b.ExtraInfo
	t := dbtypes.NewTimeDefFromUNIX(b.Header.Time)
	return apitypes.BlockExplorerBasic{
		Height:                 b.Header.Height,
		Size:                   b.Header.Size,
		Voters:                 b.Header.Voters,
		Revocations:            b.Header.Revocations,
		FreshStake:             b.Header.FreshStake,
		StakeDiff:              b.Header.SBits,
		BlockExplorerExtraInfo: extra,
		Time:                   t,
	}
}