本文整理汇总了Golang中github.com/decred/dcrutil.Block.STransactions方法的典型用法代码示例。如果您正苦于以下问题:Golang Block.STransactions方法的具体用法?Golang Block.STransactions怎么用?Golang Block.STransactions使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/decred/dcrutil.Block
的用法示例。
在下文中一共展示了Block.STransactions方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: 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
}
示例2: ticketsSpentInBlock
// ticketsSpentInBlock finds all the tickets spent in the block.
func ticketsSpentInBlock(bl *dcrutil.Block) []chainhash.Hash {
tickets := make([]chainhash.Hash, 0)
for _, stx := range bl.STransactions() {
if DetermineTxType(stx.MsgTx()) == TxTypeSSGen {
tickets = append(tickets, stx.MsgTx().TxIn[1].PreviousOutPoint.Hash)
}
}
return tickets
}
示例3: ticketsInBlock
// ticketsInBlock finds all the new tickets in the block.
func ticketsInBlock(bl *dcrutil.Block) []chainhash.Hash {
tickets := make([]chainhash.Hash, 0)
for _, stx := range bl.STransactions() {
if DetermineTxType(stx.MsgTx()) == TxTypeSStx {
h := stx.Sha()
tickets = append(tickets, *h)
}
}
return tickets
}
示例4: votesInBlock
// votesInBlock finds all the votes in the block.
func votesInBlock(bl *dcrutil.Block) []chainhash.Hash {
votes := make([]chainhash.Hash, 0)
for _, stx := range bl.STransactions() {
if DetermineTxType(stx.MsgTx()) == TxTypeSSGen {
h := stx.Sha()
votes = append(votes, *h)
}
}
return votes
}
示例5: 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
}
示例6: unspendStakeTxTree
// unspendStakeTxTree returns all outpoints spent before this one
// in the block's tx tree stake. used for unspending the stake tx
// tree to evaluate tx tree regular of prev block.
func unspendStakeTxTree(block *dcrutil.Block) map[wire.OutPoint]struct{} {
unspentOps := make(map[wire.OutPoint]struct{})
for _, tx := range block.STransactions() {
for _, txIn := range tx.MsgTx().TxIn {
unspentOps[txIn.PreviousOutPoint] = struct{}{}
}
}
return unspentOps
}
示例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
}
示例8: checkBlockScripts
// checkBlockScripts executes and validates the scripts for all transactions in
// the passed block using multiple goroutines.
// txTree = true is TxTreeRegular, txTree = false is TxTreeStake.
func checkBlockScripts(block *dcrutil.Block, utxoView *UtxoViewpoint, txTree bool,
scriptFlags txscript.ScriptFlags, sigCache *txscript.SigCache) error {
// Collect all of the transaction inputs and required information for
// validation for all transactions in the block into a single slice.
numInputs := 0
var txs []*dcrutil.Tx
// TxTreeRegular handling.
if txTree {
txs = block.Transactions()
} else { // TxTreeStake
txs = block.STransactions()
}
for _, tx := range txs {
numInputs += len(tx.MsgTx().TxIn)
}
txValItems := make([]*txValidateItem, 0, numInputs)
for _, tx := range txs {
for txInIdx, txIn := range tx.MsgTx().TxIn {
// Skip coinbases.
if txIn.PreviousOutPoint.Index == math.MaxUint32 {
continue
}
txVI := &txValidateItem{
txInIndex: txInIdx,
txIn: txIn,
tx: tx,
}
txValItems = append(txValItems, txVI)
}
}
// Validate all of the inputs.
validator := newTxValidator(utxoView, scriptFlags, sigCache)
if err := validator.Validate(txValItems); err != nil {
return err
}
return nil
}
示例9: connectTxTree
// connectTxTree lets you connect an arbitrary TxTree to a txStore to push it
// forward in history.
// TxTree true == TxTreeRegular
// TxTree false == TxTreeStake
func connectTxTree(txStore TxStore,
block *dcrutil.Block,
txTree bool) {
var transactions []*dcrutil.Tx
if txTree {
transactions = block.Transactions()
} else {
transactions = block.STransactions()
}
// Loop through all of the 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 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()
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
}
示例10: 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
}
示例11: 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()
}
示例12: 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
}
示例13: 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
}
示例14: findWhereDoubleSpent
// findWhereDoubleSpent determines where a tx was previously doublespent.
// VERY INTENSIVE BLOCKCHAIN SCANNING, USE TO DEBUG SIMULATED BLOCKCHAINS
// ONLY.
func (b *BlockChain) findWhereDoubleSpent(block *dcrutil.Block) error {
height := int64(1)
heightEnd := block.Height()
hashes, err := b.db.FetchHeightRange(height, heightEnd)
if err != nil {
return err
}
var allTxs []*dcrutil.Tx
txs := block.Transactions()[1:]
stxs := block.STransactions()
allTxs = append(txs, stxs...)
for _, hash := range hashes {
curBlock, err := b.getBlockFromHash(&hash)
if err != nil {
return err
}
log.Errorf("Cur block %v", curBlock.Height())
for _, localTx := range allTxs {
for _, localTxIn := range localTx.MsgTx().TxIn {
for _, tx := range curBlock.Transactions()[1:] {
for _, txIn := range tx.MsgTx().TxIn {
if txIn.PreviousOutPoint == localTxIn.PreviousOutPoint {
log.Errorf("Double spend of {hash: %v, idx: %v,"+
" tree: %b}, previously found in tx %v "+
"of block %v txtree regular",
txIn.PreviousOutPoint.Hash,
txIn.PreviousOutPoint.Index,
txIn.PreviousOutPoint.Tree,
tx.Sha(),
hash)
}
}
}
for _, tx := range curBlock.STransactions() {
for _, txIn := range tx.MsgTx().TxIn {
if txIn.PreviousOutPoint == localTxIn.PreviousOutPoint {
log.Errorf("Double spend of {hash: %v, idx: %v,"+
" tree: %b}, previously found in tx %v "+
"of block %v txtree stake\n",
txIn.PreviousOutPoint.Hash,
txIn.PreviousOutPoint.Index,
txIn.PreviousOutPoint.Tree,
tx.Sha(),
hash)
}
}
}
}
}
}
for _, localTx := range stxs {
for _, localTxIn := range localTx.MsgTx().TxIn {
for _, tx := range txs {
for _, txIn := range tx.MsgTx().TxIn {
if txIn.PreviousOutPoint == localTxIn.PreviousOutPoint {
log.Errorf("Double spend of {hash: %v, idx: %v,"+
" tree: %b}, previously found in tx %v "+
"of cur block stake txtree\n",
txIn.PreviousOutPoint.Hash,
txIn.PreviousOutPoint.Index,
txIn.PreviousOutPoint.Tree,
tx.Sha())
}
}
}
}
}
return nil
}
示例15: disconnectTransactions
// disconnectTransactions updates the view by removing all of the transactions
// created by the passed block, restoring all utxos the transactions spent by
// using the provided spent txo information, and setting the best hash for the
// view to the block before the passed block.
//
// This function will ONLY work correctly for a single transaction tree at a
// time because of index tracking.
func (b *BlockChain) disconnectTransactions(view *UtxoViewpoint,
block *dcrutil.Block, parent *dcrutil.Block, stxos []spentTxOut) error {
// Sanity check the correct number of stxos are provided.
if len(stxos) != countSpentOutputs(block, parent) {
return AssertError(fmt.Sprintf("disconnectTransactions "+
"called with bad spent transaction out information "+
"(len stxos %v, count is %v)", len(stxos),
countSpentOutputs(block, parent)))
}
// Loop backwards through all transactions so everything is unspent in
// reverse order. This is necessary since transactions later in a block
// can spend from previous ones.
regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
dcrutil.BlockValid)
thisNodeStakeViewpoint := ViewpointPrevInvalidStake
if regularTxTreeValid {
thisNodeStakeViewpoint = ViewpointPrevValidStake
}
view.SetStakeViewpoint(thisNodeStakeViewpoint)
err := view.fetchInputUtxos(b.db, block, parent)
if err != nil {
return err
}
stxoIdx := len(stxos) - 1
transactions := block.STransactions()
for txIdx := len(transactions) - 1; txIdx > -1; txIdx-- {
tx := transactions[txIdx]
msgTx := tx.MsgTx()
tt := stake.DetermineTxType(msgTx)
// Clear this transaction from the view if it already exists or
// create a new empty entry for when it does not. This is done
// because the code relies on its existence in the view in order
// to signal modifications have happened.
entry := view.entries[*tx.Sha()]
if entry == nil {
entry = newUtxoEntry(msgTx.Version, uint32(block.Height()),
uint32(txIdx), IsCoinBaseTx(msgTx), msgTx.Expiry != 0, tt)
if tt == stake.TxTypeSStx {
stakeExtra := make([]byte, serializeSizeForMinimalOutputs(tx))
putTxToMinimalOutputs(stakeExtra, tx)
entry.stakeExtra = stakeExtra
}
view.entries[*tx.Sha()] = entry
}
entry.modified = true
entry.sparseOutputs = make(map[uint32]*utxoOutput)
// Loop backwards through all of the transaction inputs (except
// for the coinbase which has no inputs) and unspend the
// referenced txos. This is necessary to match the order of the
// spent txout entries.
for txInIdx := len(tx.MsgTx().TxIn) - 1; txInIdx > -1; txInIdx-- {
// Skip empty vote stakebases.
if txInIdx == 0 && (tt == stake.TxTypeSSGen) {
continue
}
// Ensure the spent txout index is decremented to stay
// in sync with the transaction input.
stxo := &stxos[stxoIdx]
stxoIdx--
// When there is not already an entry for the referenced
// transaction in the view, it means it was fully spent,
// so create a new utxo entry in order to resurrect it.
txIn := tx.MsgTx().TxIn[txInIdx]
originHash := &txIn.PreviousOutPoint.Hash
originIndex := txIn.PreviousOutPoint.Index
entry := view.LookupEntry(originHash)
if entry == nil {
if !stxo.txFullySpent {
return AssertError(fmt.Sprintf("tried to revive utx %v from "+
"non-fully spent stx entry", originHash))
}
entry = newUtxoEntry(tx.MsgTx().Version, stxo.height,
stxo.index, stxo.isCoinBase, stxo.hasExpiry,
stxo.txType)
if stxo.txType == stake.TxTypeSStx {
entry.stakeExtra = stxo.stakeExtra
}
view.entries[*originHash] = entry
}
// Mark the entry as modified since it is either new
// or will be changed below.
entry.modified = true
// Restore the specific utxo using the stxo data from
// the spend journal if it doesn't already exist in the
// view.
//.........这里部分代码省略.........