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


Golang Block.Sha方法代码示例

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


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

示例1: 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

示例2: 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

示例3: DebugBlockString

// DebugBlockString dumps a verbose message containing information about
// the transactions of a block.
func DebugBlockString(block *dcrutil.Block) string {
	if block == nil {
		return "block pointer nil"
	}

	var buffer bytes.Buffer

	hash := block.Sha()

	str := fmt.Sprintf("Block Header: %v Height: %v \n",
		hash, block.Height())
	buffer.WriteString(str)

	str = fmt.Sprintf("Block contains %v regular transactions "+
		"and %v stake transactions \n",
		len(block.Transactions()),
		len(block.STransactions()))
	buffer.WriteString(str)

	str = fmt.Sprintf("List of regular transactions \n")
	buffer.WriteString(str)

	for i, tx := range block.Transactions() {
		str = fmt.Sprintf("Index: %v, Hash: %v \n", i, tx.Sha())
		buffer.WriteString(str)
	}

	if len(block.STransactions()) == 0 {
		return buffer.String()
	}

	str = fmt.Sprintf("List of stake transactions \n")
	buffer.WriteString(str)

	for i, stx := range block.STransactions() {
		txTypeStr := ""
		txType := stake.DetermineTxType(stx)
		switch txType {
		case stake.TxTypeSStx:
			txTypeStr = "SStx"
		case stake.TxTypeSSGen:
			txTypeStr = "SSGen"
		case stake.TxTypeSSRtx:
			txTypeStr = "SSRtx"
		default:
			txTypeStr = "Error"
		}

		str = fmt.Sprintf("Index: %v, Type: %v, Hash: %v \n",
			i, txTypeStr, stx.Sha())
		buffer.WriteString(str)
	}

	return buffer.String()
}
开发者ID:ironbits,项目名称:dcrd,代码行数:57,代码来源:common.go

示例4: DisconnectBlock

// DisconnectBlock is invoked by the index manager when a block has been
// disconnected from the main chain.  This indexer removes the
// hash-to-transaction mapping for every transaction in the block.
//
// This is part of the Indexer interface.
func (idx *TxIndex) DisconnectBlock(dbTx database.Tx, block, parent *dcrutil.Block, view *blockchain.UtxoViewpoint) error {
	// Remove all of the transactions in the block from the index.
	if err := dbRemoveTxIndexEntries(dbTx, block, parent); err != nil {
		return err
	}

	// Remove the block ID index entry for the block being disconnected and
	// decrement the current internal block ID to account for it.
	blockSha := block.Sha()
	if err := dbRemoveBlockIDIndexEntry(dbTx, *blockSha); err != nil {
		return err
	}
	idx.curBlockID--
	return nil
}
开发者ID:decred,项目名称:dcrd,代码行数:20,代码来源:txindex.go

示例5: InsertBlock

// InsertBlock synchronously queues a newly solved block to have its
// transactions indexed by address.
func (a *addrIndexer) InsertBlock(block *dcrutil.Block, parent *dcrutil.Block) error {
	addrIndex, err := a.indexBlockAddrs(block, parent)
	if err != nil {
		return fmt.Errorf("Unable to index transactions of"+
			" block: %v", err)
	}
	err = a.server.db.UpdateAddrIndexForBlock(block.Sha(),
		block.Height(),
		addrIndex)
	if err != nil {
		return fmt.Errorf("Unable to insert block: %v", err.Error())
	}

	return nil
}
开发者ID:frankbraun,项目名称:dcrd,代码行数:17,代码来源:chainindexer.go

示例6: 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

示例7: 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

示例8: ConnectBlock

// ConnectBlock is invoked by the index manager when a new block has been
// connected to the main chain.  This indexer adds a hash-to-transaction mapping
// for every transaction in the passed block.
//
// This is part of the Indexer interface.
func (idx *TxIndex) ConnectBlock(dbTx database.Tx, block, parent *dcrutil.Block, view *blockchain.UtxoViewpoint) error {
	// Increment the internal block ID to use for the block being connected
	// and add all of the transactions in the block to the index.
	newBlockID := idx.curBlockID + 1
	if err := dbAddTxIndexEntries(dbTx, block, parent, newBlockID); err != nil {
		return err
	}

	// Add the new block ID index entry for the block being connected and
	// update the current internal block ID accordingly.
	blockSha := block.Sha()
	err := dbPutBlockIDIndexEntry(dbTx, *blockSha, newBlockID)
	if err != nil {
		return err
	}
	idx.curBlockID = newBlockID
	return nil
}
开发者ID:decred,项目名称:dcrd,代码行数:23,代码来源:txindex.go

示例9: 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

示例10: dbAddTxIndexEntries

// dbAddTxIndexEntries uses an existing database transaction to add a
// transaction index entry for every transaction in the passed block.
func dbAddTxIndexEntries(dbTx database.Tx, block, parent *dcrutil.Block, blockID uint32) error {
	// The offset and length of the transactions within the serialized
	// block, for the regular transactions of the parent (if added)
	// and the stake transactions of the current block.
	regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
		dcrutil.BlockValid)
	var parentRegularTxs []*dcrutil.Tx
	var parentTxLocs []wire.TxLoc
	var parentBlockID uint32
	if regularTxTreeValid && block.Height() > 1 {
		var err error
		parentRegularTxs = parent.Transactions()

		parentTxLocs, _, err = parent.TxLoc()
		if err != nil {
			return err
		}

		parentSha := parent.Sha()
		parentBlockID, err = dbFetchBlockIDByHash(dbTx, *parentSha)
		if err != nil {
			return err
		}
	}
	_, blockStxLocs, err := block.TxLoc()
	if err != nil {
		return err
	}

	allTxs := append(parentRegularTxs, block.STransactions()...)
	allTxsLocs := append(parentTxLocs, blockStxLocs...)
	stakeTxStartIdx := len(parentRegularTxs)

	// As an optimization, allocate a single slice big enough to hold all
	// of the serialized transaction index entries for the block and
	// serialize them directly into the slice.  Then, pass the appropriate
	// subslice to the database to be written.  This approach significantly
	// cuts down on the number of required allocations.
	offset := 0
	serializedValues := make([]byte, len(allTxs)*txEntrySize)
	blockIDToUse := parentBlockID
	for i, tx := range allTxs {
		// Switch to using the newest block ID for the stake transactions,
		// since these are not from the parent.
		if i == stakeTxStartIdx {
			blockIDToUse = blockID
		}

		putTxIndexEntry(serializedValues[offset:], blockIDToUse, allTxsLocs[i])
		endOffset := offset + txEntrySize
		txSha := tx.Sha()
		err := dbPutTxIndexEntry(dbTx, *txSha,
			serializedValues[offset:endOffset:endOffset])
		if err != nil {
			return err
		}
		offset += txEntrySize
	}

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

示例11: fetchInputTransactions

// fetchInputTransactions fetches the input transactions referenced by the
// transactions in the given block from its point of view.  See fetchTxList
// for more details on what the point of view entails.
// Decred: This function is for verifying the validity of the regular tx tree in
// 		this block for the case that it does get accepted in the next block.
func (b *BlockChain) fetchInputTransactions(node *blockNode, block *dcrutil.Block, viewpoint int8) (TxStore, error) {
	// Verify we have the same node as we do block.
	blockHash := block.Sha()
	if !node.hash.IsEqual(blockHash) {
		return nil, fmt.Errorf("node and block hash are different!")
	}

	// If we need the previous block, grab it.
	var parentBlock *dcrutil.Block
	if viewpoint == ViewpointPrevValidInitial ||
		viewpoint == ViewpointPrevValidStake ||
		viewpoint == ViewpointPrevValidRegular {
		var errFetchBlock error
		parentBlock, errFetchBlock = b.getBlockFromHash(node.parentHash)
		if errFetchBlock != nil {
			return nil, errFetchBlock
		}
	}

	txInFlight := map[chainhash.Hash]int{}
	txNeededSet := make(map[chainhash.Hash]struct{})
	txStore := make(TxStore)

	// Case 1: ViewpointPrevValidInitial. We need the viewpoint of the
	// current chain without the TxTreeRegular of the previous block
	// added so we can validate that.
	if viewpoint == ViewpointPrevValidInitial {
		// Build a map of in-flight transactions because some of the inputs in
		// this block could be referencing other transactions earlier in this
		// block which are not yet in the chain.
		transactions := parentBlock.Transactions()
		for i, tx := range transactions {
			txInFlight[*tx.Sha()] = i
		}

		// Loop through all of the transaction inputs (except for the coinbase
		// which has no inputs) collecting them into sets of what is needed and
		// what is already known (in-flight).
		for i, tx := range transactions[1:] {
			for _, txIn := range tx.MsgTx().TxIn {
				// Add an entry to the transaction store for the needed
				// transaction with it set to missing by default.
				originHash := &txIn.PreviousOutPoint.Hash
				txD := &TxData{Hash: originHash, Err: database.ErrTxShaMissing}
				txStore[*originHash] = txD

				// It is acceptable for a transaction input to reference
				// the output of another transaction in this block only
				// if the referenced transaction comes before the
				// current one in this block.  Update the transaction
				// store acccordingly when this is the case.  Otherwise,
				// we still need the transaction.
				//
				// NOTE: The >= is correct here because i is one less
				// than the actual position of the transaction within
				// the block due to skipping the coinbase.
				if inFlightIndex, ok := txInFlight[*originHash]; ok &&
					i >= inFlightIndex {

					originTx := transactions[inFlightIndex]
					txD.Tx = originTx
					txD.BlockHeight = node.height - 1
					txD.BlockIndex = uint32(inFlightIndex)
					txD.Spent = make([]bool, len(originTx.MsgTx().TxOut))
					txD.Err = nil
				} else {
					txNeededSet[*originHash] = struct{}{}
				}
			}
		}

		// Request the input transactions from the point of view of the node.
		txNeededStore, err := b.fetchTxStore(node, block, txNeededSet, viewpoint)
		if err != nil {
			return nil, err
		}

		// Merge the results of the requested transactions and the in-flight
		// transactions.
		for _, txD := range txNeededStore {
			txStore[*txD.Hash] = txD
		}

		return txStore, nil
	}

	// Case 2+3: ViewpointPrevValidStake and ViewpointPrevValidStake.
	// For ViewpointPrevValidStake, we need the viewpoint of the
	// current chain with the TxTreeRegular of the previous block
	// added so we can validate the TxTreeStake of the current block.
	// For ViewpointPrevInvalidStake, we need the viewpoint of the
	// current chain with the TxTreeRegular of the previous block
	// missing so we can validate the TxTreeStake of the current block.
	if viewpoint == ViewpointPrevValidStake ||
		viewpoint == ViewpointPrevInvalidStake {
//.........这里部分代码省略.........
开发者ID:ironbits,项目名称:dcrd,代码行数:101,代码来源:txlookup.go

示例12: IsCheckpointCandidate

// IsCheckpointCandidate returns whether or not the passed block is a good
// checkpoint candidate.
//
// The factors used to determine a good checkpoint are:
//  - The block must be in the main chain
//  - The block must be at least 'CheckpointConfirmations' blocks prior to the
//    current end of the main chain
//  - The timestamps for the blocks before and after the checkpoint must have
//    timestamps which are also before and after the checkpoint, respectively
//    (due to the median time allowance this is not always the case)
//  - The block must not contain any strange transaction such as those with
//    nonstandard scripts
//
// The intent is that candidates are reviewed by a developer to make the final
// decision and then manually added to the list of checkpoints for a network.
//
// This function is safe for concurrent access.
func (b *BlockChain) IsCheckpointCandidate(block *dcrutil.Block) (bool, error) {
	b.chainLock.RLock()
	defer b.chainLock.RUnlock()

	// Checkpoints must be enabled.
	if b.noCheckpoints {
		return false, fmt.Errorf("checkpoints are disabled")
	}

	var isCandidate bool
	err := b.db.View(func(dbTx database.Tx) error {
		// A checkpoint must be in the main chain.
		blockHeight, err := dbFetchHeightByHash(dbTx, block.Sha())
		if err != nil {
			// Only return an error if it's not due to the block not
			// being in the main chain.
			if !isNotInMainChainErr(err) {
				return err
			}
			return nil
		}

		// Ensure the height of the passed block and the entry for the
		// block in the main chain match.  This should always be the
		// case unless the caller provided an invalid block.
		if blockHeight != block.Height() {
			return fmt.Errorf("passed block height of %d does not "+
				"match the main chain height of %d",
				block.Height(), blockHeight)
		}

		// A checkpoint must be at least CheckpointConfirmations blocks
		// before the end of the main chain.
		mainChainHeight := b.bestNode.height
		if blockHeight > (mainChainHeight - CheckpointConfirmations) {
			return nil
		}

		// Get the previous block header.
		prevHash := &block.MsgBlock().Header.PrevBlock
		prevHeader, err := dbFetchHeaderByHash(dbTx, prevHash)
		if err != nil {
			return err
		}

		// Get the next block header.
		nextHeader, err := dbFetchHeaderByHeight(dbTx, blockHeight+1)
		if err != nil {
			return err
		}

		// A checkpoint must have timestamps for the block and the
		// blocks on either side of it in order (due to the median time
		// allowance this is not always the case).
		prevTime := prevHeader.Timestamp
		curTime := block.MsgBlock().Header.Timestamp
		nextTime := nextHeader.Timestamp
		if prevTime.After(curTime) || nextTime.Before(curTime) {
			return nil
		}

		// A checkpoint must have transactions that only contain
		// standard scripts.
		for _, tx := range block.Transactions() {
			if isNonstandardTransaction(tx) {
				return nil
			}
		}

		// All of the checks passed, so the block is a candidate.
		isCandidate = true
		return nil
	})
	return isCandidate, err
}
开发者ID:decred,项目名称:dcrd,代码行数:92,代码来源:checkpoints.go

示例13: ConnectBlock

// ConnectBlock is invoked by the index manager when a new block has been
// connected to the main chain.  This indexer adds a mapping for each address
// the transactions in the block involve.
//
// This is part of the Indexer interface.
func (idx *AddrIndex) ConnectBlock(dbTx database.Tx, block, parent *dcrutil.Block,
	view *blockchain.UtxoViewpoint) error {
	// The offset and length of the transactions within the serialized
	// block for the regular transactions of the previous block, if
	// applicable.
	regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
		dcrutil.BlockValid)
	var parentTxLocs []wire.TxLoc
	var parentBlockID uint32
	if regularTxTreeValid && block.Height() > 1 {
		var err error
		parentTxLocs, _, err = parent.TxLoc()
		if err != nil {
			return err
		}

		parentSha := parent.Sha()
		parentBlockID, err = dbFetchBlockIDByHash(dbTx, *parentSha)
		if err != nil {
			return err
		}
	}

	// The offset and length of the transactions within the serialized
	// block for the added stake transactions.
	_, blockStxLocs, err := block.TxLoc()
	if err != nil {
		return err
	}

	// Nothing to index, just return.
	if len(parentTxLocs)+len(blockStxLocs) == 0 {
		return nil
	}

	// Get the internal block ID associated with the block.
	blockSha := block.Sha()
	blockID, err := dbFetchBlockIDByHash(dbTx, *blockSha)
	if err != nil {
		return err
	}

	// Build all of the address to transaction mappings in a local map.
	addrsToTxns := make(writeIndexData)
	idx.indexBlock(addrsToTxns, block, parent, view)

	// Add all of the index entries for each address.
	stakeIdxsStart := len(parentTxLocs)
	allTxLocs := append(parentTxLocs, blockStxLocs...)
	addrIdxBucket := dbTx.Metadata().Bucket(addrIndexKey)
	for addrKey, txIdxs := range addrsToTxns {
		for _, txIdx := range txIdxs {
			// Switch to using the newest block ID for the stake transactions,
			// since these are not from the parent. Offset the index to be
			// correct for the location in this given block.
			blockIDToUse := parentBlockID
			if txIdx >= stakeIdxsStart {
				blockIDToUse = blockID
			}

			err := dbPutAddrIndexEntry(addrIdxBucket, addrKey,
				blockIDToUse, allTxLocs[txIdx])
			if err != nil {
				return err
			}
		}
	}

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

示例14: 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

示例15: 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.
//
// This function MUST be called with the chain state lock held (for writes).
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 stake nodes and block nodes which are no longer needed before
	// creating a new node.
	if !dryRun {
		err := b.pruner.pruneChainIfNeeded()
		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
	newNode := newBlockNode(blockHeader, block.Sha(), blockHeight,
		ticketsSpentInBlock(block), ticketsRevokedInBlock(block),
		voteVersionsInBlock(block, b.chainParams))
	if prevNode != nil {
		newNode.parent = prevNode
		newNode.height = blockHeight
		newNode.workSum.Add(prevNode.workSum, newNode.workSum)
	}

	// Fetching a stake node could enable a new DoS vector, so restrict
	// this only to blocks that are recent in history.
	if newNode.height < b.bestNode.height-minMemoryNodes {
		newNode.stakeNode, err = b.fetchStakeNode(newNode)
		if err != nil {
			return false, err
		}
		newNode.stakeUndoData = newNode.stakeNode.UndoData()
	}

	// 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.chainLock.Unlock()
		b.sendNotification(NTBlockAccepted,
			&BlockAcceptedNtfnsData{onMainChain, block})
		b.chainLock.Lock()
	}

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


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