// TicketPoolBlockMaturity returns the block at which all tickets with height
// greater than it are immature.
517823
func (pgb *ChainDB) TicketPoolBlockMaturity() int64 {
	bestBlock := int64(pgb.stakeDB.Height())
	return bestBlock - int64(pgb.chainParams.TicketMaturity)
}
581529
func (db *DB) RetrievePoolInfo(ind int64) (*apitypes.TicketPoolInfo, error) {
	tpi := &apitypes.TicketPoolInfo{
		Height: uint32(ind),
	}
	var hash, winners string
	err := db.QueryRow(db.getPoolSQL, ind).Scan(&hash, &tpi.Size,
		&tpi.Value, &tpi.ValAvg, &winners)
	tpi.Winners = splitToArray(winners)
	return tpi, err
}
367653
func SSTXInBlock(block *dcrutil.Block) []*dcrutil.Tx {
	_, txns := TicketTxnsInBlock(block)
	return txns
}
318635
func (tp *TicketPool) fetchDiff(height int64) (*PoolDiffDBItem, error) {
	var heightBytes [8]byte
	binary.BigEndian.PutUint64(heightBytes[:], uint64(height))

	var diff *PoolDiffDBItem
	err := tp.diffDB.View(func(txn *badger.Txn) error {
		item, errTx := txn.Get(heightBytes[:])
		if errTx != nil {
			return fmt.Errorf("failed to find height %d in TicketPool: %v",
				height, errTx)
		}

		// Don't waste time with a copy since we are going to read the data in
		// this transaction.
		var hashReader bytes.Reader
		//nolint:unparam
		errTx = item.Value(func(v []byte) error {
			hashReader.Reset(v)
			return nil
		})
		if errTx != nil {
			return fmt.Errorf("key [%x]. Error while fetching value [%v]",
				item.Key(), errTx)
		}

		var poolDiff PoolDiff
		if errTx = gob.NewDecoder(&hashReader).Decode(&poolDiff); errTx != nil {
			return fmt.Errorf("failed to decode PoolDiff: %v", errTx)
		}

		diff = &PoolDiffDBItem{
			Height:   height,
			PoolDiff: poolDiff,
		}
		return nil
	})

	return diff, err
}
137914
func (pq *BlockPriorityQueue) RescanMinMaxForUpdate(heightAdd, heightRemove uint32) {
	// If removing a block at either min or max height AND the added block does
	// not expand the range on the on relevant end, a rescan is necessary.
	if (int64(heightRemove) == pq.minHeight && heightAdd >= heightRemove) ||
		(int64(heightRemove) == pq.maxHeight && heightAdd <= heightRemove) {
		pq.RescanMinMax()
	}
	// only the added block height needs to be checked now, no rescan needed
	pq.updateMinMax(heightAdd)
}
272016
func SetSpendingForTickets(db *sql.DB, ticketDbIDs, spendDbIDs []uint64,
	blockHeights []int64, spendTypes []dbtypes.TicketSpendType,
	poolStatuses []dbtypes.TicketPoolStatus) (int64, error) {
	dbtx, err := db.Begin()
	if err != nil {
		return 0, fmt.Errorf(`unable to begin database transaction: %v`, err)
	}

	var stmt *sql.Stmt
	stmt, err = dbtx.Prepare(internal.SetTicketSpendingInfoForTicketDbID)
	if err != nil {
		// Already up a creek. Just return error from Prepare.
		_ = dbtx.Rollback()
		return 0, fmt.Errorf("tickets SELECT prepare failed: %v", err)
	}

	var totalTicketsUpdated int64
	rowsAffected := make([]int64, len(ticketDbIDs))
	for i, ticketDbID := range ticketDbIDs {
		rowsAffected[i], err = sqlExecStmt(stmt, "failed to set ticket spending info: ",
			ticketDbID, blockHeights[i], spendDbIDs[i], spendTypes[i], poolStatuses[i])
		if err != nil {
			_ = stmt.Close()
			return 0, dbtx.Rollback()
		}
		totalTicketsUpdated += rowsAffected[i]
		if rowsAffected[i] != 1 {
			log.Warnf("Updated spending info for %d tickets, expecting just 1!",
				rowsAffected[i])
		}
	}

	_ = stmt.Close()

	return totalTicketsUpdated, dbtx.Commit()
}
308821
func (p *MockPeer) BlockHeight() uint64 {
	p.lock.RLock()
	defer p.lock.RUnlock()
	return p.blockHeight
}
930086
func (p *MempoolMonitor) LastBlockHash() chainhash.Hash {
	p.mtx.RLock()
	defer p.mtx.RUnlock()
	return p.lastBlock.Hash
}
569103
func (q *queue) PendingBlocks() int {
	q.lock.Lock()
	defer q.lock.Unlock()

	return q.blockTaskQueue.Size()
}
379806
func (pq *BlockPriorityQueue) UpdateBlock(b *CachedBlock, summary *BlockDataBasic, stakeInfo *StakeInfoExtended) {
	if b != nil {
		heightAdded, hash, mismatch := checkBlockHeightHash(&cachedBlockData{
			blockSummary: summary,
			stakeInfo:    stakeInfo,
		})
		if mismatch {
			fmt.Println("Cannot UpdateBlock!")
			return
		}
		heightRemoved := b.height

		b.height = heightAdded
		b.hash = hash
		b.summary = summary
		b.stakeInfo = stakeInfo
		b.accesses = 0
		b.Access()
		heap.Fix(pq, b.heapIdx)
		pq.RescanMinMaxForUpdate(heightAdded, heightRemoved)
		pq.lastAccess = time.Unix(0, b.accessTime)
	}
}
305422
func (db *StakeDatabase) PoolInfo(hash chainhash.Hash) (*apitypes.TicketPoolInfo, bool) {
	return db.poolInfo.Get(hash)
}
301913
func (d *AddressCacheItem) BlockHeight() int64 {
	d.mtx.RLock()
	defer d.mtx.RUnlock()
	return d.height
}
88747
func (pgb *ChainDB) TicketPoolByDateAndInterval(maturityBlock int64,
	interval dbtypes.TimeBasedGrouping) (*dbtypes.PoolTicketsData, error) {
	ctx, cancel := context.WithTimeout(pgb.ctx, pgb.queryTimeout)
	defer cancel()
	tpd, err := retrieveTicketsByDate(ctx, pgb.db, maturityBlock, interval.String())
	return tpd, pgb.replaceCancelError(err)
}
284289
func (c *MempoolDataCache) GetNumTickets() (uint32, uint32) {
	c.mtx.RLock()
	defer c.mtx.RUnlock()
	return c.height, c.numTickets
}
405914
func (tp *TicketPool) Pool(height int64) ([]chainhash.Hash, error) {
	tp.mtx.Lock()
	defer tp.mtx.Unlock()

	if height > tp.tip {
		return nil, fmt.Errorf("block height %d is not connected yet, tip is %d", height, tp.tip)
	}

	for height > tp.cursor {
		if err := tp.advance(); err != nil {
			return nil, err
		}
	}
	for tp.cursor > height {
		if err := tp.retreat(); err != nil {
			return nil, err
		}
	}
	p, _ := tp.currentPool()
	return p, nil
}
1358695
func (pq *BlockPriorityQueue) updateMinMax(h uint32) (updated bool) {
	if int64(h) > pq.maxHeight {
		pq.maxHeight = int64(h)
		updated = true
	}
	if int64(h) < pq.minHeight {
		pq.minHeight = int64(h)
		updated = true
	}
	return
}
989854
func (c *BitcoindConn) blockEventHandler(conn *gozmq.Conn) {
	defer c.wg.Done()
	defer conn.Close()

	log.Info("Started listening for bitcoind block notifications via ZMQ "+
		"on", c.zmqBlockHost)

	for {
		// Before attempting to read from the ZMQ socket, we'll make
		// sure to check if we've been requested to shut down.
		select {
		case <-c.quit:
			return
		default:
		}

		// Poll an event from the ZMQ socket.
		msgBytes, err := conn.Receive()
		if err != nil {
			// It's possible that the connection to the socket
			// continuously times out, so we'll prevent logging this
			// error to prevent spamming the logs.
			netErr, ok := err.(net.Error)
			if ok && netErr.Timeout() {
				continue
			}

			log.Errorf("Unable to receive ZMQ rawblock message: %v",
				err)
			continue
		}

		// We have an event! We'll now ensure it is a block event,
		// deserialize it, and report it to the different rescan
		// clients.
		eventType := string(msgBytes[0])
		switch eventType {
		case "rawblock":
			block := &wire.MsgBlock{}
			r := bytes.NewReader(msgBytes[1])
			if err := block.Deserialize(r); err != nil {
				log.Errorf("Unable to deserialize block: %v",
					err)
				continue
			}

			c.rescanClientsMtx.Lock()
			for _, client := range c.rescanClients {
				select {
				case client.zmqBlockNtfns <- block:
				case <-client.quit:
				case <-c.quit:
					c.rescanClientsMtx.Unlock()
					return
				}
			}
			c.rescanClientsMtx.Unlock()
		default:
			// It's possible that the message wasn't fully read if
			// bitcoind shuts down, which will produce an unreadable
			// event type. To prevent from logging it, we'll make
			// sure it conforms to the ASCII standard.
			if eventType == "" || !isASCII(eventType) {
				continue
			}

			log.Warnf("Received unexpected event type from "+
				"rawblock subscription: %v", eventType)
		}
	}
}