当前位置: 首页>>代码示例>>Golang>>正文


Golang Block.MsgBlock方法代码示例

本文整理汇总了Golang中github.com/decred/dcrutil.Block.MsgBlock方法的典型用法代码示例。如果您正苦于以下问题:Golang Block.MsgBlock方法的具体用法?Golang Block.MsgBlock怎么用?Golang Block.MsgBlock使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在github.com/decred/dcrutil.Block的用法示例。


在下文中一共展示了Block.MsgBlock方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。

示例1: LogBlockHeight

// LogBlockHeight logs a new block height as an information message to show
// progress to the user. In order to prevent spam, it limits logging to one
// message every 10 seconds with duration and totals included.
func (b *blockProgressLogger) LogBlockHeight(block *dcrutil.Block) {
	b.Lock()
	defer b.Unlock()

	b.receivedLogBlocks++
	b.receivedLogTx += int64(len(block.MsgBlock().Transactions))

	now := time.Now()
	duration := now.Sub(b.lastBlockLogTime)
	if duration < time.Second*10 {
		return
	}

	// Truncate the duration to 10s of milliseconds.
	durationMillis := int64(duration / time.Millisecond)
	tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10)

	// Log information about new block height.
	blockStr := "blocks"
	if b.receivedLogBlocks == 1 {
		blockStr = "block"
	}
	txStr := "transactions"
	if b.receivedLogTx == 1 {
		txStr = "transaction"
	}
	b.subsystemLogger.Infof("%s %d %s in the last %s (%d %s, height %d, %s)",
		b.progressAction, b.receivedLogBlocks, blockStr, tDuration, b.receivedLogTx,
		txStr, block.Height(), block.MsgBlock().Header.Timestamp)

	b.receivedLogBlocks = 0
	b.receivedLogTx = 0
	b.lastBlockLogTime = now
}
开发者ID:ironbits,项目名称:dcrd,代码行数:37,代码来源:blocklogger.go

示例2: checkBlockContext

// checkBlockContext peforms several validation checks on the block which depend
// on its position within the block chain.
//
// The flags modify the behavior of this function as follows:
//  - BFFastAdd: The transaction are not checked to see if they are finalized
//    and the somewhat expensive duplication transaction check is not performed.
//
// The flags are also passed to checkBlockHeaderContext.  See its documentation
// for how the flags modify its behavior.
func (b *BlockChain) checkBlockContext(block *dcrutil.Block, prevNode *blockNode,
	flags BehaviorFlags) error {
	// The genesis block is valid by definition.
	if prevNode == nil {
		return nil
	}

	// Perform all block header related validation checks.
	header := &block.MsgBlock().Header
	err := b.checkBlockHeaderContext(header, prevNode, flags)
	if err != nil {
		return err
	}

	fastAdd := flags&BFFastAdd == BFFastAdd
	if !fastAdd {
		// The height of this block is one more than the referenced
		// previous block.
		blockHeight := prevNode.height + 1

		// Ensure all transactions in the block are finalized.
		for _, tx := range block.Transactions() {
			if !IsFinalizedTransaction(tx, blockHeight,
				header.Timestamp) {

				str := fmt.Sprintf("block contains unfinalized regular "+
					"transaction %v", tx.Sha())
				return ruleError(ErrUnfinalizedTx, str)
			}
		}
		for _, stx := range block.STransactions() {
			if !IsFinalizedTransaction(stx, blockHeight,
				header.Timestamp) {

				str := fmt.Sprintf("block contains unfinalized stake "+
					"transaction %v", stx.Sha())
				return ruleError(ErrUnfinalizedTx, str)
			}
		}

		// Check that the node is at the correct height in the blockchain,
		// as specified in the block header.
		if blockHeight != int64(block.MsgBlock().Header.Height) {
			errStr := fmt.Sprintf("Block header height invalid; expected %v"+
				" but %v was found", blockHeight, header.Height)
			return ruleError(ErrBadBlockHeight, errStr)
		}

		// Check that the coinbase contains at minimum the block
		// height in output 1.
		if blockHeight > 1 {
			err := checkCoinbaseUniqueHeight(blockHeight, block)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
开发者ID:decred,项目名称:dcrd,代码行数:69,代码来源:accept.go

示例3: dbIndexDisconnectBlock

// dbIndexDisconnectBlock removes all of the index entries associated with the
// given block using the provided indexer and updates the tip of the indexer
// accordingly.  An error will be returned if the current tip for the indexer is
// not the passed block.
func dbIndexDisconnectBlock(dbTx database.Tx, indexer Indexer, block, parent *dcrutil.Block, view *blockchain.UtxoViewpoint) error {
	// Assert that the block being disconnected is the current tip of the
	// index.
	idxKey := indexer.Key()
	curTipHash, _, err := dbFetchIndexerTip(dbTx, idxKey)
	if err != nil {
		return err
	}
	if !curTipHash.IsEqual(block.Sha()) {
		return AssertError(fmt.Sprintf("dbIndexDisconnectBlock must "+
			"be called with the block at the current index tip "+
			"(%s, tip %s, block %s)", indexer.Name(),
			curTipHash, block.Sha()))
	}

	// Notify the indexer with the disconnected block so it can remove all
	// of the appropriate entries.
	if err := indexer.DisconnectBlock(dbTx, block, parent, view); err != nil {
		return err
	}

	// Update the current index tip.
	prevHash := &block.MsgBlock().Header.PrevBlock
	return dbPutIndexerTip(dbTx, idxKey, prevHash, uint32(block.Height())-1)
}
开发者ID:decred,项目名称:dcrd,代码行数:29,代码来源:manager.go

示例4: submitBlock

// submitBlock submits the passed block to network after ensuring it passes all
// of the consensus validation rules.
func (m *CPUMiner) submitBlock(block *dcrutil.Block) bool {
	m.submitBlockLock.Lock()
	defer m.submitBlockLock.Unlock()

	_, latestHeight := m.server.blockManager.chainState.Best()

	// Be sure to set this so ProcessBlock doesn't fail! - Decred
	block.SetHeight(latestHeight + 1)

	// Process this block using the same rules as blocks coming from other
	// nodes. This will in turn relay it to the network like normal.
	isOrphan, err := m.server.blockManager.ProcessBlock(block, blockchain.BFNone)
	if err != nil {
		// Anything other than a rule violation is an unexpected error,
		// so log that error as an internal error.
		if rErr, ok := err.(blockchain.RuleError); !ok {
			minrLog.Errorf("Unexpected error while processing "+
				"block submitted via CPU miner: %v", err)
			return false
		} else {
			// Occasionally errors are given out for timing errors with
			// ResetMinDifficulty and high block works that is above
			// the target. Feed these to debug.
			if m.server.chainParams.ResetMinDifficulty &&
				rErr.ErrorCode == blockchain.ErrHighHash {
				minrLog.Debugf("Block submitted via CPU miner rejected "+
					"because of ResetMinDifficulty time sync failure: %v",
					err)
				return false
			} else {
				// Other rule errors should be reported.
				minrLog.Errorf("Block submitted via CPU miner rejected: %v", err)
				return false
			}
		}

	}
	if isOrphan {
		minrLog.Errorf("Block submitted via CPU miner is an orphan building "+
			"on parent %v", block.MsgBlock().Header.PrevBlock)
		return false
	}

	// The block was accepted.
	coinbaseTxOuts := block.MsgBlock().Transactions[0].TxOut
	coinbaseTxGenerated := int64(0)
	for _, out := range coinbaseTxOuts {
		coinbaseTxGenerated += out.Value
	}
	minrLog.Infof("Block submitted via CPU miner accepted (hash %s, "+
		"height %v, amount %v)",
		block.Sha(),
		block.Height(),
		dcrutil.Amount(coinbaseTxGenerated))
	return true
}
开发者ID:ironbits,项目名称:dcrd,代码行数:58,代码来源:cpuminer.go

示例5: ticketsRevokedInBlock

// ticketsRevokedInBlock fetches a list of tickets that were revoked in the
// block.
func ticketsRevokedInBlock(bl *dcrutil.Block) []chainhash.Hash {
	var tickets []chainhash.Hash
	for _, stx := range bl.MsgBlock().STransactions {
		if stake.DetermineTxType(stx) == stake.TxTypeSSRtx {
			tickets = append(tickets, stx.TxIn[0].PreviousOutPoint.Hash)
		}
	}

	return tickets
}
开发者ID:decred,项目名称:dcrd,代码行数:12,代码来源:accept.go

示例6: voteVersionsInBlock

// voteVersionsInBlock returns all versions in a block.
func voteVersionsInBlock(bl *dcrutil.Block, params *chaincfg.Params) []uint32 {
	versions := make([]uint32, 0, params.TicketsPerBlock)
	for _, stx := range bl.MsgBlock().STransactions {
		if is, _ := stake.IsSSGen(stx); !is {
			continue
		}
		versions = append(versions, stake.SSGenVersion(stx))
	}

	return versions
}
开发者ID:decred,项目名称:dcrd,代码行数:12,代码来源:accept.go

示例7: lookupTransaction

// lookupTransaction is a special transaction lookup function that searches
// the database, the block, and its parent for a transaction. This is needed
// because indexBlockAddrs is called AFTER a block is added/removed in the
// blockchain in blockManager, necessitating that the blocks internally be
// searched for inputs for any given transaction too. Additionally, it's faster
// to get the tx from the blocks here since they're already
func (a *addrIndexer) lookupTransaction(txHash chainhash.Hash, blk *dcrutil.Block,
	parent *dcrutil.Block) (*wire.MsgTx, error) {
	// Search the previous block and parent first.
	txTreeRegularValid := dcrutil.IsFlagSet16(blk.MsgBlock().Header.VoteBits,
		dcrutil.BlockValid)

	// Search the regular tx tree of this and the last block if the
	// tx tree regular was validated.
	if txTreeRegularValid {
		for _, stx := range parent.STransactions() {
			if stx.Sha().IsEqual(&txHash) {
				return stx.MsgTx(), nil
			}
		}
		for _, tx := range parent.Transactions() {
			if tx.Sha().IsEqual(&txHash) {
				return tx.MsgTx(), nil
			}
		}
		for _, tx := range blk.Transactions() {
			if tx.Sha().IsEqual(&txHash) {
				return tx.MsgTx(), nil
			}
		}
	} else {
		// Just search this block's regular tx tree and the previous
		// block's stake tx tree.
		for _, stx := range parent.STransactions() {
			if stx.Sha().IsEqual(&txHash) {
				return stx.MsgTx(), nil
			}
		}
		for _, tx := range blk.Transactions() {
			if tx.Sha().IsEqual(&txHash) {
				return tx.MsgTx(), nil
			}
		}
	}

	// Lookup and fetch the referenced output's tx in the database.
	txList, err := a.server.db.FetchTxBySha(&txHash)
	if err != nil {
		adxrLog.Errorf("Error fetching tx %v: %v",
			txHash, err)
		return nil, err
	}

	if len(txList) == 0 {
		return nil, fmt.Errorf("transaction %v not found",
			txHash)
	}

	return txList[len(txList)-1].Tx, nil
}
开发者ID:frankbraun,项目名称:dcrd,代码行数:60,代码来源:chainindexer.go

示例8: checkCoinbaseUniqueHeight

// checkCoinbaseUniqueHeight checks to ensure that for all blocks height > 1
// that the coinbase contains the height encoding to make coinbase hash collisions
// impossible.
func checkCoinbaseUniqueHeight(blockHeight int64, block *dcrutil.Block) error {
	if !(len(block.MsgBlock().Transactions) > 0) {
		str := fmt.Sprintf("block %v has no coinbase", block.Sha())
		return ruleError(ErrNoTransactions, str)
	}

	// Coinbase TxOut[0] is always tax, TxOut[1] is always
	// height + extranonce, so at least two outputs must
	// exist.
	if !(len(block.MsgBlock().Transactions[0].TxOut) > 1) {
		str := fmt.Sprintf("block %v is missing necessary coinbase "+
			"outputs", block.Sha())
		return ruleError(ErrFirstTxNotCoinbase, str)
	}

	// The first 4 bytes of the NullData output must be the
	// encoded height of the block, so that every coinbase
	// created has a unique transaction hash.
	nullData, err := txscript.GetNullDataContent(
		block.MsgBlock().Transactions[0].TxOut[1].Version,
		block.MsgBlock().Transactions[0].TxOut[1].PkScript)
	if err != nil {
		str := fmt.Sprintf("block %v txOut 1 has wrong pkScript "+
			"type", block.Sha())
		return ruleError(ErrFirstTxNotCoinbase, str)
	}

	if len(nullData) < 4 {
		str := fmt.Sprintf("block %v txOut 1 has too short nullData "+
			"push to contain height", block.Sha())
		return ruleError(ErrFirstTxNotCoinbase, str)
	}

	// Check the height and ensure it is correct.
	cbHeight := binary.LittleEndian.Uint32(nullData[0:4])
	if cbHeight != uint32(blockHeight) {
		prevBlock := block.MsgBlock().Header.PrevBlock
		str := fmt.Sprintf("block %v txOut 1 has wrong height in "+
			"coinbase; want %v, got %v; prevBlock %v, header height %v",
			block.Sha(), blockHeight, cbHeight, prevBlock,
			block.MsgBlock().Header.Height)
		return ruleError(ErrCoinbaseHeight, str)
	}

	return nil
}
开发者ID:alexlyp,项目名称:dcrd,代码行数:49,代码来源:accept.go

示例9: connectTransactions

// connectTransactions updates the view by adding all new utxos created by all
// of the transactions in the passed block, marking all utxos the transactions
// spend as spent, and setting the best hash for the view to the passed block.
// In addition, when the 'stxos' argument is not nil, it will be updated to
// append an entry for each spent txout.
func (b *BlockChain) connectTransactions(view *UtxoViewpoint, block *dcrutil.Block,
	parent *dcrutil.Block, stxos *[]spentTxOut) error {
	regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
		dcrutil.BlockValid)
	thisNodeStakeViewpoint := ViewpointPrevInvalidStake
	if regularTxTreeValid {
		thisNodeStakeViewpoint = ViewpointPrevValidStake
	}

	if parent != nil && block.Height() != 0 {
		view.SetStakeViewpoint(ViewpointPrevValidInitial)
		err := view.fetchInputUtxos(b.db, block, parent)
		if err != nil {
			return err
		}
		mBlock := block.MsgBlock()
		votebits := mBlock.Header.VoteBits
		regularTxTreeValid := dcrutil.IsFlagSet16(votebits, dcrutil.BlockValid)
		if regularTxTreeValid {
			for i, tx := range parent.Transactions() {
				err := view.connectTransaction(tx, parent.Height(), uint32(i),
					stxos)
				if err != nil {
					return err
				}
			}
		}
	}

	for i, stx := range block.STransactions() {
		view.SetStakeViewpoint(thisNodeStakeViewpoint)
		err := view.fetchInputUtxos(b.db, block, parent)
		if err != nil {
			return err
		}
		err = view.connectTransaction(stx, block.Height(), uint32(i), stxos)
		if err != nil {
			return err
		}
	}

	// Update the best hash for view to include this block since all of its
	// transactions have been connected.
	view.SetBestHash(block.Sha())
	return nil
}
开发者ID:decred,项目名称:dcrd,代码行数:51,代码来源:utxoviewpoint.go

示例10: NewMerkleBlock

// NewMerkleBlock returns a new *wire.MsgMerkleBlock and an array of the matched
// transaction hashes based on the passed block and filter.
func NewMerkleBlock(block *dcrutil.Block, filter *Filter) (*wire.MsgMerkleBlock, []*chainhash.Hash) {
	numTx := uint32(len(block.Transactions()))
	mBlock := merkleBlock{
		numTx:       numTx,
		allHashes:   make([]*chainhash.Hash, 0, numTx),
		matchedBits: make([]byte, 0, numTx),
	}

	// Find and keep track of any transactions that match the filter.
	var matchedHashes []*chainhash.Hash
	for _, tx := range block.Transactions() {
		if filter.MatchTxAndUpdate(tx) {
			mBlock.matchedBits = append(mBlock.matchedBits, 0x01)
			matchedHashes = append(matchedHashes, tx.Sha())
		} else {
			mBlock.matchedBits = append(mBlock.matchedBits, 0x00)
		}
		mBlock.allHashes = append(mBlock.allHashes, tx.Sha())
	}

	// Calculate the number of merkle branches (height) in the tree.
	height := uint32(0)
	for mBlock.calcTreeWidth(height) > 1 {
		height++
	}

	// Build the depth-first partial merkle tree.
	mBlock.traverseAndBuild(height, 0)

	// Create and return the merkle block.
	msgMerkleBlock := wire.MsgMerkleBlock{
		Header:       block.MsgBlock().Header,
		Transactions: uint32(mBlock.numTx),
		Hashes:       make([]*chainhash.Hash, 0, len(mBlock.finalHashes)),
		Flags:        make([]byte, (len(mBlock.bits)+7)/8),
	}
	for _, sha := range mBlock.finalHashes {
		msgMerkleBlock.AddTxHash(sha)
	}
	for i := uint32(0); i < uint32(len(mBlock.bits)); i++ {
		msgMerkleBlock.Flags[i/8] |= mBlock.bits[i] << (i % 8)
	}
	return &msgMerkleBlock, matchedHashes
}
开发者ID:alexlyp,项目名称:dcrutil,代码行数:46,代码来源:merkleblock.go

示例11: dbRemoveTxIndexEntries

// dbRemoveTxIndexEntries uses an existing database transaction to remove the
// latest transaction entry for every transaction in the passed block.
func dbRemoveTxIndexEntries(dbTx database.Tx, block, parent *dcrutil.Block) error {
	regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
		dcrutil.BlockValid)
	if regularTxTreeValid {
		for _, tx := range parent.Transactions() {
			txSha := tx.Sha()
			err := dbRemoveTxIndexEntry(dbTx, *txSha)
			if err != nil {
				return err
			}
		}
	}
	for _, tx := range block.STransactions() {
		txSha := tx.Sha()
		err := dbRemoveTxIndexEntry(dbTx, *txSha)
		if err != nil {
			return err
		}
	}

	return nil
}
开发者ID:decred,项目名称:dcrd,代码行数:24,代码来源:txindex.go

示例12: dbIndexConnectBlock

// dbIndexConnectBlock adds all of the index entries associated with the
// given block using the provided indexer and updates the tip of the indexer
// accordingly.  An error will be returned if the current tip for the indexer is
// not the previous block for the passed block.
func dbIndexConnectBlock(dbTx database.Tx, indexer Indexer, block, parent *dcrutil.Block, view *blockchain.UtxoViewpoint) error {
	// Assert that the block being connected properly connects to the
	// current tip of the index.
	idxKey := indexer.Key()
	curTipHash, _, err := dbFetchIndexerTip(dbTx, idxKey)
	if err != nil {
		return err
	}
	if !curTipHash.IsEqual(&block.MsgBlock().Header.PrevBlock) {
		return AssertError(fmt.Sprintf("dbIndexConnectBlock must be "+
			"called with a block that extends the current index "+
			"tip (%s, tip %s, block %s)", indexer.Name(),
			curTipHash, block.Sha()))
	}

	// Notify the indexer with the connected block so it can index it.
	if err := indexer.ConnectBlock(dbTx, block, parent, view); err != nil {
		return err
	}

	// Update the current index tip.
	return dbPutIndexerTip(dbTx, idxKey, block.Sha(), uint32(block.Height()))
}
开发者ID:decred,项目名称:dcrd,代码行数:27,代码来源:manager.go

示例13: CalculateAddedSubsidy

// CalculateAddedSubsidy calculates the amount of subsidy added by a block
// and its parent. The blocks passed to this function MUST be valid blocks
// that have already been confirmed to abide by the consensus rules of the
// network, or the function might panic.
func CalculateAddedSubsidy(block, parent *dcrutil.Block) int64 {
	var subsidy int64

	regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
		dcrutil.BlockValid)
	if regularTxTreeValid {
		subsidy += parent.MsgBlock().Transactions[0].TxIn[0].ValueIn
	}

	for _, stx := range block.MsgBlock().STransactions {
		if isSSGen, _ := stake.IsSSGen(stx); isSSGen {
			subsidy += stx.TxIn[0].ValueIn
		}
	}

	return subsidy
}
开发者ID:decred,项目名称:dcrd,代码行数:21,代码来源:subsidy.go

示例14: maybeAcceptBlock

// maybeAcceptBlock potentially accepts a block into the memory block chain.
// It performs several validation checks which depend on its position within
// the block chain before adding it.  The block is expected to have already gone
// through ProcessBlock before calling this function with it.
//
// The flags modify the behavior of this function as follows:
//  - BFDryRun: The memory chain index will not be pruned and no accept
//    notification will be sent since the block is not being accepted.
func (b *BlockChain) maybeAcceptBlock(block *dcrutil.Block,
	flags BehaviorFlags) (bool, error) {
	dryRun := flags&BFDryRun == BFDryRun

	// Get a block node for the block previous to this one.  Will be nil
	// if this is the genesis block.
	prevNode, err := b.getPrevNodeFromBlock(block)
	if err != nil {
		log.Debugf("getPrevNodeFromBlock: %v", err)
		return false, err
	}

	// The height of this block is one more than the referenced previous
	// block.
	blockHeight := int64(0)
	if prevNode != nil {
		blockHeight = prevNode.height + 1
	}
	block.SetHeight(blockHeight)

	// The block must pass all of the validation rules which depend on the
	// position of the block within the block chain.
	err = b.checkBlockContext(block, prevNode, flags)
	if err != nil {
		return false, err
	}

	// Prune block nodes which are no longer needed before creating
	// a new node.
	if !dryRun {
		err = b.pruneBlockNodes()
		if err != nil {
			return false, err
		}
	}

	// Create a new block node for the block and add it to the in-memory
	// block chain (could be either a side chain or the main chain).
	blockHeader := &block.MsgBlock().Header
	var voteBitsStake []uint16
	for _, stx := range block.STransactions() {
		if is, _ := stake.IsSSGen(stx); is {
			vb := stake.GetSSGenVoteBits(stx)
			voteBitsStake = append(voteBitsStake, vb)
		}
	}

	newNode := newBlockNode(blockHeader, block.Sha(), blockHeight, voteBitsStake)
	if prevNode != nil {
		newNode.parent = prevNode
		newNode.height = blockHeight
		newNode.workSum.Add(prevNode.workSum, newNode.workSum)
	}

	// Connect the passed block to the chain while respecting proper chain
	// selection according to the chain with the most proof of work.  This
	// also handles validation of the transaction scripts.
	var onMainChain bool
	onMainChain, err = b.connectBestChain(newNode, block, flags)
	if err != nil {
		return false, err
	}

	// Notify the caller that the new block was accepted into the block
	// chain.  The caller would typically want to react by relaying the
	// inventory to other peers.
	if !dryRun {
		b.sendNotification(NTBlockAccepted,
			&BlockAcceptedNtfnsData{onMainChain, block})
	}

	return onMainChain, nil
}
开发者ID:alexlyp,项目名称:dcrd,代码行数:81,代码来源:accept.go

示例15: insertBlock

// insertBlock is the internal function which implements the public
// InsertBlock.  See the comment for InsertBlock for more details.
//
// This function MUST be called with the tmdb lock held (for writes).
func (tmdb *TicketDB) insertBlock(block *dcrutil.Block) (SStxMemMap,
	SStxMemMap, SStxMemMap, error) {

	height := block.Height()
	if height < tmdb.StakeEnabledHeight {
		return nil, nil, nil, nil
	}

	// Sanity check: Does the number of tickets in ticketMap equal the number
	// of tickets indicated in the header?
	poolSizeBlock := int(block.MsgBlock().Header.PoolSize)
	poolSize := 0
	for i := 0; i < BucketsSize; i++ {
		poolSize += len(tmdb.maps.ticketMap[i])
	}
	if poolSize != poolSizeBlock {
		return nil, nil, nil, fmt.Errorf("ticketpoolsize in block %v not "+
			"equal to the calculated ticketpoolsize, indicating database "+
			"corruption (got %v, want %v)",
			block.Sha(),
			poolSizeBlock,
			poolSize)
	}

	// Create the block in the spentTicketMap.
	tmdb.maybeInsertBlock(block.Height())

	// Iterate through all the SSGen (vote) tx in the block and add them to
	// a map of tickets that were actually used. The rest of the tickets in
	// the buckets were then considered missed --> missedTicketMap.
	// Note that it doesn't really matter what value you set usedTickets to,
	// it's just a map of tickets that were actually used in the block. It
	// would probably be more efficient to use an array.
	usedTickets := make(map[chainhash.Hash]struct{})
	spendingHashes := make(map[chainhash.Hash]chainhash.Hash)
	revocations := make(map[chainhash.Hash]struct{})

	for _, staketx := range block.STransactions() {
		if is, _ := IsSSGen(staketx); is {
			msgTx := staketx.MsgTx()
			sstxIn := msgTx.TxIn[1] // sstx input
			sstxHash := sstxIn.PreviousOutPoint.Hash

			usedTickets[sstxHash] = struct{}{}
			spendingHashes[sstxHash] = *staketx.Sha()
		}

		if is, _ := IsSSRtx(staketx); is {
			msgTx := staketx.MsgTx()
			sstxIn := msgTx.TxIn[0] // sstx input
			sstxHash := sstxIn.PreviousOutPoint.Hash

			revocations[sstxHash] = struct{}{}
		}
	}

	// Spend or miss all the necessary tickets and do some sanity checks.
	parentBlock, err := tmdb.database.FetchBlockBySha(
		&block.MsgBlock().Header.PrevBlock)
	if err != nil {
		return nil, nil, nil, err
	}
	spentAndMissedTickets, err := tmdb.spendTickets(parentBlock,
		usedTickets,
		spendingHashes)
	if err != nil {
		return nil, nil, nil, err
	}

	// Expire all old tickets, and stick them into the spent and missed ticket
	// map too.
	expiredTickets, err := tmdb.expireTickets(height)
	if err != nil {
		return nil, nil, nil, err
	}
	if len(expiredTickets) > 0 && len(spentAndMissedTickets) == 0 {
		return nil, nil, nil, fmt.Errorf("tried to expire tickets before " +
			"stake validation height! TicketExpiry may be too small")
	}
	if len(expiredTickets) > 0 {
		for hash, ticket := range expiredTickets {
			spentAndMissedTickets[hash] = ticket
		}
	}

	revokedTickets, err := tmdb.revokeTickets(revocations)
	if err != nil {
		return nil, nil, nil, err
	}

	newTickets, err := tmdb.pushMatureTicketsAtHeight(block.Height())
	if err != nil {
		return nil, nil, nil, err
	}

	log.Debugf("Connected block %v (height %v) to the ticket database",
//.........这里部分代码省略.........
开发者ID:zebbra2014,项目名称:dcrd,代码行数:101,代码来源:ticketdb.go


注:本文中的github.com/decred/dcrutil.Block.MsgBlock方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。