• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Golang dcrutil.IsFlagSet16函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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



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

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


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


示例3: DropAfterBlockBySha

// DropAfterBlockBySha removes any blocks from the database after the given
// block.  This is different than a simple truncate since the spend information
// for each block must also be unwound.  This is part of the database.Db interface
// implementation.
func (db *MemDb) DropAfterBlockBySha(sha *chainhash.Hash) error {
	db.Lock()
	defer db.Unlock()

	if db.closed {
		return ErrDbClosed
	}

	// Begin by attempting to find the height associated with the passed
	// hash.
	height, exists := db.blocksBySha[*sha]
	if !exists {
		return fmt.Errorf("block %v does not exist in the database",
			sha)
	}

	// The spend information has to be undone in reverse order, so loop
	// backwards from the last block through the block just after the passed
	// block.  While doing this unspend all transactions in each block and
	// remove the block.
	endHeight := int64(len(db.blocks) - 1)
	for i := endHeight; i > height; i-- {

		blk := db.blocks[i]
		blkprev := db.blocks[i-1]
		// Unspend the stake tx in the current block
		for _, tx := range blk.STransactions {
			txSha := tx.TxSha()
			db.removeTx(tx, &txSha)
		}

		// Check to see if the regular txs of the parent were even included; if
		// they are, unspend all of these regular tx too
		votebits := blk.Header.VoteBits
		if dcrutil.IsFlagSet16(votebits, dcrutil.BlockValid) && height != 0 {
			// Unspend the regular tx in the previous block
			for _, tx := range blkprev.Transactions {
				txSha := tx.TxSha()
				db.removeTx(tx, &txSha)
			}
		}

		db.blocks[i] = nil
		db.blocks = db.blocks[:i]
	}
	return nil
}
开发者ID:ironbits,项目名称:dcrd,代码行数:51,代码来源:memdb.go


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


示例5: testExistsTxSha

// testExistsTxSha ensures ExistsTxSha conforms to the interface contract.
func testExistsTxSha(tc *testContext) bool {
	var blockPrev *dcrutil.Block = nil
	// Decred: WARNING. This function assumes that all block insertion calls have
	// dcrutil.blocks passed to them with block.blockHeight set correctly. However,
	// loading the genesis block in dcrd didn't do this (via block manager); pre-
	// production it should be established that all calls to this function pass
	// blocks with block.blockHeight set correctly.
	if tc.block.Height() != 0 {
		var errBlockPrev error
		blockPrev, errBlockPrev = tc.db.FetchBlockBySha(&tc.block.MsgBlock().Header.PrevBlock)
		if errBlockPrev != nil {
			blockSha := tc.block.Sha()
			tc.t.Errorf("Failed to fetch parent block of block %v", blockSha)
		}
	}

	votebits := tc.block.MsgBlock().Header.VoteBits
	if dcrutil.IsFlagSet16(votebits, dcrutil.BlockValid) && blockPrev != nil {
		for i, tx := range blockPrev.Transactions() {
			// The transaction must exist in the database.
			txHash := tx.Sha()
			exists, err := tc.db.ExistsTxSha(txHash)
			if err != nil {
				tc.t.Errorf("ExistsTxSha (%s): block #%d (%s) tx #%d "+
					"(%s) unexpected error: %v", tc.dbType,
					tc.blockHeight, tc.blockHash, i, txHash, err)
				return false
			}
			if !exists {
				_, err := tc.db.FetchTxBySha(txHash)
				if err != nil {
					tc.t.Errorf("ExistsTxSha (%s): block #%d (%s) "+
						"tx #%d (%s) does not exist", tc.dbType,
						tc.blockHeight, tc.blockHash, i, txHash)
				}
				return false
			}
		}
	}
	return true
}
开发者ID:ironbits,项目名称:dcrd,代码行数:42,代码来源:interface_test.go


示例6: 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, parent *dcrutil.Block) {
	b.Lock()
	defer b.Unlock()
	b.receivedLogBlocks++
	regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
		dcrutil.BlockValid)
	if regularTxTreeValid {
		b.receivedLogTx += int64(len(parent.MsgBlock().Transactions))
	}
	b.receivedLogTx += int64(len(block.MsgBlock().STransactions))

	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:decred,项目名称:dcrd,代码行数:42,代码来源:blocklogger.go


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


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


示例9: InsertBlock

// InsertBlock inserts raw block and transaction data from a block into the
// database.  The first block inserted into the database will be treated as the
// genesis block.  Every subsequent block insert requires the referenced parent
// block to already exist.
func (db *LevelDb) InsertBlock(block *dcrutil.Block) (height int64, rerr error) {
	// Be careful with this function on syncs.  It contains decred changes.

	// Obtain the previous block first so long as it's not the genesis block
	var blockPrev *dcrutil.Block

	// Decred: WARNING. This function assumes that all block insertion calls have
	// dcrutil.blocks passed to them with block.blockHeight set correctly. However,
	// loading the genesis block in btcd didn't do this (via block manager); pre-
	// production it should be established that all calls to this function pass
	// blocks with block.blockHeight set correctly.
	if block.Height() != 0 {
		var errBlockPrev error
		blockPrev, errBlockPrev = db.FetchBlockBySha(&block.MsgBlock().Header.PrevBlock)
		if errBlockPrev != nil {
			blockSha := block.Sha()
			log.Warnf("Failed to fetch parent block of block %v", blockSha)
			return 0, errBlockPrev
		}
	}

	db.dbLock.Lock()
	defer db.dbLock.Unlock()
	defer func() {
		if rerr == nil {
			rerr = db.processBatches()
		} else {
			db.lBatch().Reset()
		}
	}()

	blocksha := block.Sha()
	mblock := block.MsgBlock()
	rawMsg, err := block.Bytes()
	if err != nil {
		log.Warnf("Failed to obtain raw block sha %v", blocksha)
		return 0, err
	}
	_, sTxLoc, err := block.TxLoc()
	if err != nil {
		log.Warnf("Failed to obtain raw block sha %v, stxloc %v", blocksha, sTxLoc)
		return 0, err
	}

	// Insert block into database
	newheight, err := db.insertBlockData(blocksha, &mblock.Header.PrevBlock,
		rawMsg)
	if err != nil {
		log.Warnf("Failed to insert block %v %v %v", blocksha,
			&mblock.Header.PrevBlock, err)
		return 0, err
	}

	// Get data necessary to process regular tx tree of parent block if it's not
	// the genesis block.
	var mBlockPrev *wire.MsgBlock
	var txLoc []wire.TxLoc

	if blockPrev != nil {
		blockShaPrev := blockPrev.Sha()

		mBlockPrev = blockPrev.MsgBlock()

		txLoc, _, err = blockPrev.TxLoc()
		if err != nil {
			log.Warnf("Failed to obtain raw block sha %v, txloc %v", blockShaPrev, txLoc)
			return 0, err
		}
	}

	// Insert the regular tx of the parent block into the tx database if the vote
	// bits enable it, and if it's not the genesis block.
	votebits := mblock.Header.VoteBits
	if dcrutil.IsFlagSet16(votebits, dcrutil.BlockValid) && blockPrev != nil {
		for txidx, tx := range mBlockPrev.Transactions {
			txsha, err := blockPrev.TxSha(txidx)

			if err != nil {
				log.Warnf("failed to compute tx name block %v idx %v err %v", blocksha, txidx, err)
				return 0, err
			}
			spentbuflen := (len(tx.TxOut) + 7) / 8
			spentbuf := make([]byte, spentbuflen, spentbuflen)
			if len(tx.TxOut)%8 != 0 {
				for i := uint(len(tx.TxOut) % 8); i < 8; i++ {
					spentbuf[spentbuflen-1] |= (byte(1) << i)
				}
			}

			// newheight-1 instead of newheight below, as the tx is actually found
			// in the parent.
			//fmt.Printf("insert tx %v into db at height %v\n", txsha, newheight)
			err = db.insertTx(txsha, newheight-1, uint32(txidx), txLoc[txidx].TxStart, txLoc[txidx].TxLen, spentbuf)
			if err != nil {
				log.Warnf("block %v idx %v failed to insert tx %v %v err %v", blocksha, newheight-1, &txsha, txidx, err)
				return 0, err
//.........这里部分代码省略.........
开发者ID:alexlyp,项目名称:dcrd,代码行数:101,代码来源:leveldb.go


示例10: DropAfterBlockBySha

// DropAfterBlockBySha will remove any blocks from the database after
// the given block.
func (db *LevelDb) DropAfterBlockBySha(sha *chainhash.Hash) (rerr error) {
	db.dbLock.Lock()
	defer db.dbLock.Unlock()
	defer func() {
		if rerr == nil {
			rerr = db.processBatches()
		} else {
			db.lBatch().Reset()
		}
	}()

	startheight := db.nextBlock - 1

	keepidx, err := db.getBlkLoc(sha)
	if err != nil {
		// should the error here be normalized ?
		log.Tracef("block loc failed %v ", sha)
		return err
	}

	for height := startheight; height > keepidx; height = height - 1 {
		var blk *dcrutil.Block
		blksha, buf, err := db.getBlkByHeight(height)
		if err != nil {
			return err
		}

		blk, err = dcrutil.NewBlockFromBytes(buf)
		if err != nil {
			return err
		}

		// Obtain previous block sha and buffer
		var blkprev *dcrutil.Block
		_, bufprev, errprev := db.getBlkByHeight(height - 1) // discard blkshaprev
		if errprev != nil {
			return errprev
		}

		// Do the same thing for the parent block
		blkprev, errprev = dcrutil.NewBlockFromBytes(bufprev)
		if errprev != nil {
			return errprev
		}

		// Unspend the stake tx in the current block
		for _, tx := range blk.MsgBlock().STransactions {
			err = db.unSpend(tx)
			if err != nil {
				return err
			}
		}
		// rather than iterate the list of tx backward, do it twice.
		for _, tx := range blk.STransactions() {
			var txUo txUpdateObj
			txUo.delete = true
			db.txUpdateMap[*tx.Sha()] = &txUo
		}

		// Check to see if the regular txs of the parent were even included; if
		// they are, unspend all of these regular tx too
		votebits := blk.MsgBlock().Header.VoteBits
		if dcrutil.IsFlagSet16(votebits, dcrutil.BlockValid) && height != 0 {
			// Unspend the regular tx in the current block
			for _, tx := range blkprev.MsgBlock().Transactions {
				err = db.unSpend(tx)
				if err != nil {
					return err
				}
			}
			// rather than iterate the list of tx backward, do it twice.
			for _, tx := range blkprev.Transactions() {
				var txUo txUpdateObj
				txUo.delete = true
				db.txUpdateMap[*tx.Sha()] = &txUo
			}
		}

		db.lBatch().Delete(shaBlkToKey(blksha))
		db.lBatch().Delete(int64ToKey(height))
	}

	// update the last block cache
	db.lastBlkShaCached = true
	db.lastBlkSha = *sha
	db.lastBlkIdx = keepidx
	db.nextBlock = keepidx + 1

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


示例11: makeUtxoView

// makeUtxoView creates a mock unspent transaction output view by using the
// transaction index in order to look up all inputs referenced by the
// transactions in the block.  This is sometimes needed when catching indexes up
// because many of the txouts could actually already be spent however the
// associated scripts are still required to index them.
func makeUtxoView(dbTx database.Tx, block, parent *dcrutil.Block) (*blockchain.UtxoViewpoint, error) {
	view := blockchain.NewUtxoViewpoint()
	regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
		dcrutil.BlockValid)
	if regularTxTreeValid {
		for txIdx, tx := range parent.Transactions() {
			// Coinbases do not reference any inputs.  Since the block is
			// required to have already gone through full validation, it has
			// already been proven on the first transaction in the block is
			// a coinbase.
			if txIdx == 0 {
				continue
			}

			// Use the transaction index to load all of the referenced
			// inputs and add their outputs to the view.
			for _, txIn := range tx.MsgTx().TxIn {
				// Skip already fetched outputs.
				originOut := &txIn.PreviousOutPoint
				if view.LookupEntry(&originOut.Hash) != nil {
					continue
				}

				originTx, err := dbFetchTx(dbTx, originOut.Hash)
				if err != nil {
					return nil, err
				}

				view.AddTxOuts(dcrutil.NewTx(originTx),
					int64(wire.NullBlockHeight), wire.NullBlockIndex)
			}
		}
	}

	for _, tx := range block.STransactions() {
		msgTx := tx.MsgTx()
		isSSGen, _ := stake.IsSSGen(msgTx)

		// Use the transaction index to load all of the referenced
		// inputs and add their outputs to the view.
		for i, txIn := range msgTx.TxIn {
			// Skip stakebases.
			if isSSGen && i == 0 {
				continue
			}

			originOut := &txIn.PreviousOutPoint
			if view.LookupEntry(&originOut.Hash) != nil {
				continue
			}

			originTx, err := dbFetchTx(dbTx, originOut.Hash)
			if err != nil {
				return nil, err
			}

			view.AddTxOuts(dcrutil.NewTx(originTx), int64(wire.NullBlockHeight),
				wire.NullBlockIndex)
		}
	}

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


示例12: disconnectTransactions

// disconnectTransactions updates the passed map by undoing transaction and
// spend information for all transactions in the passed block.  Only
// transactions in the passed map are updated.
func disconnectTransactions(txStore TxStore, block *dcrutil.Block, parent *dcrutil.Block) error {
	// Loop through all of the stake transactions in the block to see if any of
	// them are ones that need to be undone based on the transaction store.
	for _, tx := range block.STransactions() {
		// Clear this transaction from the transaction store if needed.
		// Only clear it rather than deleting it because the transaction
		// connect code relies on its presence to decide whether or not
		// to update the store and any transactions which exist on both
		// sides of a fork would otherwise not be updated.
		if txD, exists := txStore[*tx.Sha()]; exists {
			txD.Tx = nil
			txD.BlockHeight = int64(wire.NullBlockHeight)
			txD.BlockIndex = wire.NullBlockIndex
			txD.Spent = nil
			txD.Err = database.ErrTxShaMissing
		}

		// Unspend the origin transaction output.
		for _, txIn := range tx.MsgTx().TxIn {
			originHash := &txIn.PreviousOutPoint.Hash
			originIndex := txIn.PreviousOutPoint.Index
			originTx, exists := txStore[*originHash]
			if exists && originTx.Tx != nil && originTx.Err == nil {
				if originTx.Spent == nil {
					continue
				}
				if originIndex >= uint32(len(originTx.Spent)) {
					continue
				}
				originTx.Spent[originIndex] = false
			}
		}
	}

	// There is no regular tx from before the genesis block, so ignore the genesis
	// block for the next step.
	if parent != nil && block.Height() != 0 {
		mBlock := block.MsgBlock()
		votebits := mBlock.Header.VoteBits
		regularTxTreeValid := dcrutil.IsFlagSet16(votebits, dcrutil.BlockValid)

		// Only bother to unspend transactions if the parent's tx tree was
		// validated. Otherwise, these transactions were never in the blockchain's
		// history in the first place.
		if regularTxTreeValid {
			// Loop through all of the regular transactions in the block to see if
			// any of them are ones that need to be undone based on the
			// transaction store.
			for _, tx := range parent.Transactions() {
				// Clear this transaction from the transaction store if needed.
				// Only clear it rather than deleting it because the transaction
				// connect code relies on its presence to decide whether or not
				// to update the store and any transactions which exist on both
				// sides of a fork would otherwise not be updated.
				if txD, exists := txStore[*tx.Sha()]; exists {
					txD.Tx = nil
					txD.BlockHeight = int64(wire.NullBlockHeight)
					txD.BlockIndex = wire.NullBlockIndex
					txD.Spent = nil
					txD.Err = database.ErrTxShaMissing
				}

				// Unspend the origin transaction output.
				for _, txIn := range tx.MsgTx().TxIn {
					originHash := &txIn.PreviousOutPoint.Hash
					originIndex := txIn.PreviousOutPoint.Index
					originTx, exists := txStore[*originHash]
					if exists && originTx.Tx != nil && originTx.Err == nil {
						if originTx.Spent == nil {
							continue
						}
						if originIndex >= uint32(len(originTx.Spent)) {
							continue
						}
						originTx.Spent[originIndex] = false
					}
				}
			}
		}
	}

	return nil
}
开发者ID:ironbits,项目名称:dcrd,代码行数:86,代码来源:txlookup.go


示例13: connectTransactions

func connectTransactions(txStore TxStore, block *dcrutil.Block, parent *dcrutil.Block) error {
	// There is no regular tx from before the genesis block, so ignore the genesis
	// block for the next step.
	if parent != nil && block.Height() != 0 {
		mBlock := block.MsgBlock()
		votebits := mBlock.Header.VoteBits
		regularTxTreeValid := dcrutil.IsFlagSet16(votebits, dcrutil.BlockValid)

		// Only add the transactions in the event that the parent block's regular
		// tx were validated.
		if regularTxTreeValid {
			// Loop through all of the regular transactions in the block to see if
			// any of them are ones we need to update and spend based on the
			// results map.
			for i, tx := range parent.Transactions() {
				// Update the transaction store with the transaction information
				// if it's one of the requested transactions.
				msgTx := tx.MsgTx()
				if txD, exists := txStore[*tx.Sha()]; exists {
					txD.Tx = tx
					txD.BlockHeight = block.Height() - 1
					txD.BlockIndex = uint32(i)
					txD.Spent = make([]bool, len(msgTx.TxOut))
					txD.Err = nil
				}

				// Spend the origin transaction output.
				for _, txIn := range msgTx.TxIn {
					originHash := &txIn.PreviousOutPoint.Hash
					originIndex := txIn.PreviousOutPoint.Index
					if originTx, exists := txStore[*originHash]; exists {
						if originTx.Spent == nil {
							continue
						}
						if originIndex >= uint32(len(originTx.Spent)) {
							continue
						}
						originTx.Spent[originIndex] = true
					}
				}
			}
		}
	}

	// Loop through all of the stake transactions in the block to see if any of
	// them are ones we need to update and spend based on the results map.
	for i, tx := range block.STransactions() {
		// Update the transaction store with the transaction information
		// if it's one of the requested transactions.
		msgTx := tx.MsgTx()
		if txD, exists := txStore[*tx.Sha()]; exists {
			txD.Tx = tx
			txD.BlockHeight = block.Height()
			txD.BlockIndex = uint32(i)
			txD.Spent = make([]bool, len(msgTx.TxOut))
			txD.Err = nil
		}

		// Spend the origin transaction output.
		for _, txIn := range msgTx.TxIn {
			originHash := &txIn.PreviousOutPoint.Hash
			originIndex := txIn.PreviousOutPoint.Index
			if originTx, exists := txStore[*originHash]; exists {
				if originTx.Spent == nil {
					continue
				}
				if originIndex >= uint32(len(originTx.Spent)) {
					continue
				}
				originTx.Spent[originIndex] = true
			}
		}
	}

	return nil
}
开发者ID:ironbits,项目名称:dcrd,代码行数:76,代码来源:txlookup.go


示例14: testUnspentInsertStakeTree

// insert every block in the test chain
// after each insert, fetch all the tx affected by the latest
// block and verify that the the tx is spent/unspent
// new tx should be fully unspent, referenced tx should have
// the associated txout set to spent.
// checks tx tree stake only
func testUnspentInsertStakeTree(t *testing.T) {
	// Ignore db remove errors since it means we didn't have an old one.
	dbname := fmt.Sprintf("tstdbuspnt1")
	dbnamever := dbname + ".ver"
	_ = os.RemoveAll(dbname)
	_ = os.RemoveAll(dbnamever)
	db, err := database.CreateDB("leveldb", dbname)
	if err != nil {
		t.Errorf("Failed to open test database %v", err)
		return
	}
	defer os.RemoveAll(dbname)
	defer os.RemoveAll(dbnamever)
	defer func() {
		if err := db.Close(); err != nil {
			t.Errorf("Close: unexpected error: %v", err)
		}
	}()
	blocks := loadblocks(t)
endtest:
	for height := int64(0); height < int64(len(blocks))-1; height++ {
		block := blocks[height]

		var txneededList []*chainhash.Hash
		var txlookupList []*chainhash.Hash
		var txOutList []*chainhash.Hash
		var txInList []*wire.OutPoint
		spentFromParent := make(map[wire.OutPoint]struct{})
		for _, tx := range block.MsgBlock().STransactions {
			for _, txin := range tx.TxIn {
				if txin.PreviousOutPoint.Index == uint32(4294967295) {
					continue
				}
				origintxsha := &txin.PreviousOutPoint.Hash

				exists, err := db.ExistsTxSha(origintxsha)
				if err != nil {
					t.Errorf("ExistsTxSha: unexpected error %v ", err)
				}
				if !exists {
					// Check and see if the outpoint references txtreeregular of
					// the previous block. If it does, make sure nothing in tx
					// treeregular spends it in flight. Then check make sure it's
					// not currently spent for this block. If it isn't, mark it
					// spent and skip lookup in the db below, since the db won't
					// yet be able to add it as it's still to be inserted.
					spentFromParentReg := false
					parent := blocks[height-1]
					parentValid := dcrutil.IsFlagSet16(dcrutil.BlockValid, block.MsgBlock().Header.VoteBits)
					if parentValid {
						for _, prtx := range parent.Transactions() {
							// Check and make sure it's not being spent in this tx
							// tree first by an in flight tx. Mark it spent if it
							// is so it fails the check below.
							for _, prtxCheck := range parent.Transactions() {
								for _, prTxIn := range prtxCheck.MsgTx().TxIn {
									if prTxIn.PreviousOutPoint == txin.PreviousOutPoint {
										spentFromParent[txin.PreviousOutPoint] = struct{}{}
									}
								}
							}

							// If it is in the tree, make sure it's not already spent
							// somewhere else and mark it spent. Set the flag below
							// so we skip lookup.
							if prtx.Sha().IsEqual(origintxsha) {
								if _, spent := spentFromParent[txin.PreviousOutPoint]; !spent {
									spentFromParent[txin.PreviousOutPoint] = struct{}{}
									spentFromParentReg = true
								}
							}
						}
					}

					if !spentFromParentReg {
						t.Errorf("referenced tx not found %v %v", origintxsha, height)
					} else {
						continue
					}
				}

				txInList = append(txInList, &txin.PreviousOutPoint)
				txneededList = append(txneededList, origintxsha)
				txlookupList = append(txlookupList, origintxsha)
			}
			txshaname := tx.TxSha()
			txlookupList = append(txlookupList, &txshaname)
			txOutList = append(txOutList, &txshaname)
		}

		txneededmap := map[chainhash.Hash]*database.TxListReply{}
		txlist := db.FetchUnSpentTxByShaList(txneededList)
		for _, txe := range txlist {
			if txe.Err != nil {
//.........这里部分代码省略.........
开发者ID:ironbits,项目名称:dcrd,代码行数:101,代码来源:insertremove_test.go


示例15: indexBlock

// indexBlock extract all of the standard addresses from all of the transactions
// in the passed block and maps each of them to the assocaited transaction using
// the passed map.
func (idx *AddrIndex) indexBlock(data writeIndexData, block, parent *dcrutil.Block, view *blockchain.UtxoViewpoint) {
	regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
		dcrutil.BlockValid)
	var stakeStartIdx int
	if regularTxTreeValid {
		for txIdx, tx := range parent.Transactions() {
			// Coinbases do not reference any inputs.  Since the block is
			// required to have already gone through full validation, it has
			// already been proven on the first transaction in the block is
			// a coinbase.
			if txIdx != 0 {
				for _, txIn := range tx.MsgTx().TxIn {
					// The view should always have the input since
					// the index contract requires it, however, be
					// safe and simply ignore any missing entries.
					origin := &txIn.PreviousOutPoint
					entry := view.LookupEntry(&origin.Hash)
					if entry == nil {
						log.Warnf("Missing input %v for tx %v while "+
							"indexing block %v (height %v)\n", origin.Hash,
							tx.Sha(), block.Sha(), block.Height())
						continue
					}

					version := entry.ScriptVersionByIndex(origin.Index)
					pkScript := entry.PkScriptByIndex(origin.Index)
					txType := entry.TransactionType()
					idx.indexPkScript(data, version, pkScript, txIdx,
						txType == stake.TxTypeSStx)
				}
			}

			for _, txOut := range tx.MsgTx().TxOut {
				idx.indexPkScript(data, txOut.Version, txOut.PkScript, txIdx,
					false)
			}
		}

		stakeStartIdx = len(parent.Transactions())
	}

	for txIdx, tx := range block.STransactions() {
		msgTx := tx.MsgTx()
		thisTxOffset := txIdx + stakeStartIdx

		isSSGen, _ := stake.IsSSGen(msgTx)
		for i, txIn := range msgTx.TxIn {
			// Skip stakebases.
			if isSSGen && i == 0 {
				continue
			}

			// The view should always have the input since
			// the index contract requires it, however, be
			// safe and simply ignore any missing entries.
			origin := &txIn.PreviousOutPoint
			entry := view.LookupEntry(&origin.Hash)
			if entry == nil {
				log.Warnf("Missing input %v for tx %v while "+
					"indexing block %v (height %v)\n", origin.Hash,
					tx.Sha(), block.Sha(), block.Height())
				continue
			}

			version := entry.ScriptVersionByIndex(origin.Index)
			pkScript := entry.PkScriptByIndex(origin.Index)
			txType := entry.TransactionType()
			idx.indexPkScript(data, version, pkScript, thisTxOffset,
				txType == stake.TxTypeSStx)
		}

		isSStx, _ := stake.IsSStx(msgTx)
		for _, txOut := range msgTx.TxOut {
			idx.indexPkScript(data, txOut.Version, txOut.PkScript,
				thisTxOffset, isSStx)
		}
	}
}
开发者ID:decred,项目名称:dcrd,代码行数:81,代码来源:addrindex.go


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


示例17: testFetchTxBySha

// testFetchTxBySha ensures FetchTxBySha conforms to the interface contract.
func testFetchTxBySha(tc *testContext) bool {
	var blockPrev *dcrutil.Block = nil
	if tc.block.Height() != 0 {
		var errBlockPrev error
		blockPrev, errBlockPrev = tc.db.FetchBlockBySha(&tc.block.MsgBlock().Header.PrevBlock)
		if errBlockPrev != nil {
			blockSha := tc.block.Sha()
			tc.t.Errorf("Failed to fetch parent block of block %v", blockSha)
		}
	}

	votebits := tc.block.MsgBlock().Header.VoteBits
	if dcrutil.IsFlagSet16(votebits, dcrutil.BlockValid) && blockPrev != nil {
		for i, tx := range blockPrev.Transactions() {
			txHash := tx.Sha()
			txReplyList, err := tc.db.FetchTxBySha(txHash)
			if err != nil {
				tc.t.Errorf("FetchTxBySha (%s): block #%d (%s) "+
					"tx #%d (%s) err: %v", tc.dbType, tc.blockHeight,
					tc.blockHash, i, txHash, err)
				return false
			}
			if len(txReplyList) == 0 {
				tc.t.Errorf("FetchTxBySha (%s): block #%d (%s) "+
					"tx #%d (%s) did not return reply data",
					tc.dbType, tc.blockHeight, tc.blockHash, i,
					txHash)
				return false
			}
			txFromDb := txReplyList[len(txReplyList)-1].Tx
			if !reflect.DeepEqual(tx.MsgTx(), txFromDb) {
				tc.t.Errorf("FetchTxBySha (%s): block #%d (%s) "+
					"tx #%d (%s, %s) does not match stored tx\n"+
					"got: %v\nwant: %v", tc.dbType, tc.blockHeight,
					tc.blockHash, i, txHash, txFromDb.TxSha(), spew.Sdump(txFromDb),
					spew.Sdump(tx.MsgTx()))
				return false
			}
		}
	}
	for i, tx := range tc.block.MsgBlock().STransactions {
		txHash := tx.TxSha()
		txReplyList, err := tc.db.FetchTxBySha(&txHash)
		if err != nil {
			tc.t.Errorf("FetchTxBySha (%s): block #%d (%s) "+
				"sstx #%d (%s) err: %v", tc.dbType, tc.blockHeight,
				tc.blockHash, i, txHash, err)
			return false
		}
		if len(txReplyList) == 0 {
			tc.t.Errorf("FetchTxBySha (%s): block #%d (%s) "+
				"sstx #%d (%s) did not return reply data",
				tc.dbType, tc.blockHeight, tc.blockHash, i,
				txHash)
			return false
		}
		txFromDb := txReplyList[len(txReplyList)-1].Tx
		if !reflect.DeepEqual(tx, txFromDb) {
			tc.t.Errorf("FetchTxBySha (%s): block #%d (%s) "+
				"sstx #%d (%s) does not match stored sstx\n"+
				"got: %v\nwant: %v", tc.dbType, tc.blockHeight,
				tc.blockHash, i, txHash, spew.Sdump(txFromDb),
				spew.Sdump(tx))
			return false
		}
	}

	return true
}
开发者ID:ironbits,项目名称:dcrd,代码行数:70,代码来源:interface_test.go


示例18: connectTickets

// connectTickets updates the passed map by removing removing any tickets
// from the ticket pool that have been considered spent or missed in this block
// according to the block header. Then, it connects all the newly mature tickets
// to the passed map.
func (b *BlockChain) connectTickets(tixStore TicketStore,
	node *blockNode,
	block *dcrutil.Block) error {
	if tixStore == nil {
		return fmt.Errorf("nil ticket store!")
	}

	// Nothing to do if tickets haven't yet possibly matured.
	height := node.height
	if height < b.chainParams.StakeEnabledHeight {
		return nil
	}

	parentBlock, err := b.GetBlockFromHash(node.parentHash)
	if err != nil {
		return err
	}

	revocations := node.header.Revocations

	tM := int64(b.chainParams.TicketMaturity)

	// Skip a number of validation steps before we requiring chain
	// voting.
	if node.height >= b.chainParams.StakeValidationHeight {
		regularTxTreeValid := dcrutil.IsFlagSet16(node.header.VoteBits,
			dcrutil.BlockValid)
		thisNodeStakeViewpoint := ViewpointPrevInvalidStake
		if regularTxTreeValid {
			thisNodeStakeViewpoint = ViewpointPrevValidStake
		}

		// We need the missed tickets bucket from the original perspective of
		// the node.
		missedTickets, err := b.GenerateMissedTickets(tixStore)
		if err != nil {
			return err
		}

		// TxStore at blockchain HEAD + TxTreeRegular of prevBlock (if
		// validated) for this node.
		txInputStoreStake, err := b.fetchInputTransactions(node, block,
			thisNodeStakeViewpoint)
		if err != nil {
			errStr := fmt.Sprintf("fetchInputTransactions failed for incoming "+
				"node %v; error given: %v", node.hash, err)
			return errors.New(errStr)
		}

		// PART 1: Spend/miss winner tickets

		// Iterate through all the SSGen (vote) tx in the block and add them to
		// a map of tickets that were actually used.
		spentTicketsFromBlock := make(map[chainhash.Hash]bool)
		numberOfSSgen := 0
		for _, staketx := range block.STransactions() {
			if is, _ := stake.IsSSGen(staketx); is {
				msgTx := staketx.MsgTx()
				sstxIn := msgTx.TxIn[1] // sstx input
				sstxHash := sstxIn.PreviousOutPoint.Hash

				originTx, exists := txInputStoreStake[sstxHash]
				if !exists {
					str := fmt.Sprintf("unable to find input transaction "+
						"%v for transaction %v", sstxHash, staketx.Sha())
					return ruleError(ErrMissingTx, str)
				}

				sstxHeight := originTx.BlockHeight

				// Check maturity of ticket; we can only spend the ticket after it
				// hits maturity at height + tM + 1.
				if (height - sstxHeight) < (tM + 1) {
					blockSha := block.Sha()
					errStr := fmt.Sprintf("Error:  

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Golang dcrutil.NewBlock函数代码示例发布时间:2022-05-23
下一篇:
Golang dcrutil.DecodeAddress函数代码示例发布时间:2022-05-23
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap