github.com/decred/dcrd/blockchain@v1.2.1/validate.go (about)

     1  // Copyright (c) 2013-2016 The btcsuite developers
     2  // Copyright (c) 2015-2019 The Decred developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package blockchain
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/binary"
    11  	"fmt"
    12  	"math"
    13  	"math/big"
    14  	"time"
    15  
    16  	"github.com/decred/dcrd/blockchain/stake"
    17  	"github.com/decred/dcrd/blockchain/standalone"
    18  	"github.com/decred/dcrd/chaincfg"
    19  	"github.com/decred/dcrd/chaincfg/chainhash"
    20  	"github.com/decred/dcrd/database"
    21  	"github.com/decred/dcrd/dcrutil"
    22  	"github.com/decred/dcrd/txscript"
    23  	"github.com/decred/dcrd/wire"
    24  )
    25  
    26  const (
    27  	// MaxSigOpsPerBlock is the maximum number of signature operations
    28  	// allowed for a block.  This really should be based upon the max
    29  	// allowed block size for a network and any votes that might change it,
    30  	// however, since it was not updated to be based upon it before
    31  	// release, it will require a hard fork and associated vote agenda to
    32  	// change it.  The original max block size for the protocol was 1MiB,
    33  	// so that is what this is based on.
    34  	MaxSigOpsPerBlock = 1000000 / 200
    35  
    36  	// MaxTimeOffsetSeconds is the maximum number of seconds a block time
    37  	// is allowed to be ahead of the current time.  This is currently 2
    38  	// hours.
    39  	MaxTimeOffsetSeconds = 2 * 60 * 60
    40  
    41  	// MinCoinbaseScriptLen is the minimum length a coinbase script can be.
    42  	MinCoinbaseScriptLen = 2
    43  
    44  	// MaxCoinbaseScriptLen is the maximum length a coinbase script can be.
    45  	MaxCoinbaseScriptLen = 100
    46  
    47  	// maxUniqueCoinbaseNullDataSize is the maximum number of bytes allowed
    48  	// in the pushed data output of the coinbase output that is used to
    49  	// ensure the coinbase has a unique hash.
    50  	maxUniqueCoinbaseNullDataSize = 256
    51  
    52  	// medianTimeBlocks is the number of previous blocks which should be
    53  	// used to calculate the median time used to validate block timestamps.
    54  	medianTimeBlocks = 11
    55  
    56  	// earlyVoteBitsValue is the only value of VoteBits allowed in a block
    57  	// header before stake validation height.
    58  	earlyVoteBitsValue = 0x0001
    59  
    60  	// maxRevocationsPerBlock is the maximum number of revocations that are
    61  	// allowed per block.
    62  	maxRevocationsPerBlock = 255
    63  
    64  	// A ticket commitment output is an OP_RETURN script with a 30-byte data
    65  	// push that consists of a 20-byte hash for the payment hash, 8 bytes
    66  	// for the amount to commit to (with the upper bit flag set to indicate
    67  	// the hash is for a pay-to-script-hash address, otherwise the hash is a
    68  	// pay-to-pubkey-hash), and 2 bytes for the fee limits.  Thus, 1 byte
    69  	// for the OP_RETURN + 1 byte for the data push + 20 bytes for the
    70  	// payment hash means the encoded amount is at offset 22.  Then, 8 bytes
    71  	// for the amount means the encoded fee limits are at offset 30.
    72  	commitHashStartIdx     = 2
    73  	commitHashEndIdx       = commitHashStartIdx + 20
    74  	commitAmountStartIdx   = commitHashEndIdx
    75  	commitAmountEndIdx     = commitAmountStartIdx + 8
    76  	commitFeeLimitStartIdx = commitAmountEndIdx
    77  	commitFeeLimitEndIdx   = commitFeeLimitStartIdx + 2
    78  
    79  	// commitP2SHFlag specifies the bitmask to apply to an amount decoded from
    80  	// a ticket commitment in order to determine if it is a pay-to-script-hash
    81  	// commitment.  The value is derived from the fact it is encoded as the most
    82  	// significant bit in the amount.
    83  	commitP2SHFlag = uint64(1 << 63)
    84  
    85  	// submissionOutputIdx is the index of the stake submission output of a
    86  	// ticket transaction.
    87  	submissionOutputIdx = 0
    88  )
    89  
    90  var (
    91  	// zeroHash is the zero value for a chainhash.Hash and is defined as a
    92  	// package level variable to avoid the need to create a new instance
    93  	// every time a check is needed.
    94  	zeroHash = &chainhash.Hash{}
    95  
    96  	// earlyFinalState is the only value of the final state allowed in a
    97  	// block header before stake validation height.
    98  	earlyFinalState = [6]byte{0x00}
    99  )
   100  
   101  // voteBitsApproveParent returns whether or not the passed vote bits indicate
   102  // the regular transaction tree of the parent block should be considered valid.
   103  func voteBitsApproveParent(voteBits uint16) bool {
   104  	return dcrutil.IsFlagSet16(voteBits, dcrutil.BlockValid)
   105  }
   106  
   107  // headerApprovesParent returns whether or not the vote bits in the passed
   108  // header indicate the regular transaction tree of the parent block should be
   109  // considered valid.
   110  func headerApprovesParent(header *wire.BlockHeader) bool {
   111  	return voteBitsApproveParent(header.VoteBits)
   112  }
   113  
   114  // isNullOutpoint determines whether or not a previous transaction output point
   115  // is set.
   116  func isNullOutpoint(outpoint *wire.OutPoint) bool {
   117  	if outpoint.Index == math.MaxUint32 &&
   118  		outpoint.Hash.IsEqual(zeroHash) &&
   119  		outpoint.Tree == wire.TxTreeRegular {
   120  		return true
   121  	}
   122  	return false
   123  }
   124  
   125  // isNullFraudProof determines whether or not a previous transaction fraud
   126  // proof is set.
   127  func isNullFraudProof(txIn *wire.TxIn) bool {
   128  	switch {
   129  	case txIn.BlockHeight != wire.NullBlockHeight:
   130  		return false
   131  	case txIn.BlockIndex != wire.NullBlockIndex:
   132  		return false
   133  	}
   134  
   135  	return true
   136  }
   137  
   138  // IsCoinBaseTx determines whether or not a transaction is a coinbase.  A
   139  // coinbase is a special transaction created by miners that has no inputs.
   140  // This is represented in the block chain by a transaction with a single input
   141  // that has a previous output transaction index set to the maximum value along
   142  // with a zero hash.
   143  //
   144  // This function only differs from IsCoinBase in that it works with a raw wire
   145  // transaction as opposed to a higher level util transaction.
   146  //
   147  // Deprecated: Use standalone.IsCoinBaseTx instead.
   148  func IsCoinBaseTx(msgTx *wire.MsgTx) bool {
   149  	return standalone.IsCoinBaseTx(msgTx)
   150  }
   151  
   152  // IsCoinBase determines whether or not a transaction is a coinbase.  A
   153  // coinbase is a special transaction created by miners that has no inputs.
   154  // This is represented in the block chain by a transaction with a single input
   155  // that has a previous output transaction index set to the maximum value along
   156  // with a zero hash.
   157  //
   158  // This function only differs from IsCoinBaseTx in that it works with a higher
   159  // level util transaction as opposed to a raw wire transaction.
   160  //
   161  // Deprecated: Use standalone.IsCoinBaseTx instead.
   162  func IsCoinBase(tx *dcrutil.Tx) bool {
   163  	return standalone.IsCoinBaseTx(tx.MsgTx())
   164  }
   165  
   166  // IsExpiredTx returns where or not the passed transaction is expired according
   167  // to the given block height.
   168  //
   169  // This function only differs from IsExpired in that it works with a raw wire
   170  // transaction as opposed to a higher level util transaction.
   171  func IsExpiredTx(tx *wire.MsgTx, blockHeight int64) bool {
   172  	expiry := tx.Expiry
   173  	return expiry != wire.NoExpiryValue && blockHeight >= int64(expiry)
   174  }
   175  
   176  // IsExpired returns where or not the passed transaction is expired according to
   177  // the given block height.
   178  //
   179  // This function only differs from IsExpiredTx in that it works with a higher
   180  // level util transaction as opposed to a raw wire transaction.
   181  func IsExpired(tx *dcrutil.Tx, blockHeight int64) bool {
   182  	return IsExpiredTx(tx.MsgTx(), blockHeight)
   183  }
   184  
   185  // SequenceLockActive determines if all of the inputs to a given transaction
   186  // have achieved a relative age that surpasses the requirements specified by
   187  // their respective sequence locks as calculated by CalcSequenceLock.  A single
   188  // sequence lock is sufficient because the calculated lock selects the minimum
   189  // required time and block height from all of the non-disabled inputs after
   190  // which the transaction can be included.
   191  func SequenceLockActive(lock *SequenceLock, blockHeight int64, medianTime time.Time) bool {
   192  	// The transaction is not yet mature if it has not yet reached the
   193  	// required minimum time and block height according to its sequence
   194  	// locks.
   195  	if blockHeight <= lock.MinHeight || medianTime.Unix() <= lock.MinTime {
   196  		return false
   197  	}
   198  
   199  	return true
   200  }
   201  
   202  // IsFinalizedTransaction determines whether or not a transaction is finalized.
   203  func IsFinalizedTransaction(tx *dcrutil.Tx, blockHeight int64, blockTime time.Time) bool {
   204  	// Lock time of zero means the transaction is finalized.
   205  	msgTx := tx.MsgTx()
   206  	lockTime := msgTx.LockTime
   207  	if lockTime == 0 {
   208  		return true
   209  	}
   210  
   211  	// The lock time field of a transaction is either a block height at
   212  	// which the transaction is finalized or a timestamp depending on if the
   213  	// value is before the txscript.LockTimeThreshold.  When it is under the
   214  	// threshold it is a block height.
   215  	var blockTimeOrHeight int64
   216  	if lockTime < txscript.LockTimeThreshold {
   217  		blockTimeOrHeight = blockHeight
   218  	} else {
   219  		blockTimeOrHeight = blockTime.Unix()
   220  	}
   221  	if int64(lockTime) < blockTimeOrHeight {
   222  		return true
   223  	}
   224  
   225  	// At this point, the transaction's lock time hasn't occurred yet, but
   226  	// the transaction might still be finalized if the sequence number
   227  	// for all transaction inputs is maxed out.
   228  	for _, txIn := range msgTx.TxIn {
   229  		if txIn.Sequence != math.MaxUint32 {
   230  			return false
   231  		}
   232  	}
   233  	return true
   234  }
   235  
   236  // CheckTransactionSanity performs some preliminary checks on a transaction to
   237  // ensure it is sane.  These checks are context free.
   238  func CheckTransactionSanity(tx *wire.MsgTx, params *chaincfg.Params) error {
   239  	// A transaction must have at least one input.
   240  	if len(tx.TxIn) == 0 {
   241  		return ruleError(ErrNoTxInputs, "transaction has no inputs")
   242  	}
   243  
   244  	// A transaction must have at least one output.
   245  	if len(tx.TxOut) == 0 {
   246  		return ruleError(ErrNoTxOutputs, "transaction has no outputs")
   247  	}
   248  
   249  	// A transaction must not exceed the maximum allowed size when
   250  	// serialized.
   251  	serializedTxSize := tx.SerializeSize()
   252  	if serializedTxSize > params.MaxTxSize {
   253  		str := fmt.Sprintf("serialized transaction is too big - got "+
   254  			"%d, max %d", serializedTxSize, params.MaxTxSize)
   255  		return ruleError(ErrTxTooBig, str)
   256  	}
   257  
   258  	// Coinbase script length must be between min and max length.
   259  	isVote := stake.IsSSGen(tx)
   260  	if standalone.IsCoinBaseTx(tx) {
   261  		// The referenced outpoint must be null.
   262  		if !isNullOutpoint(&tx.TxIn[0].PreviousOutPoint) {
   263  			str := fmt.Sprintf("coinbase transaction did not use " +
   264  				"a null outpoint")
   265  			return ruleError(ErrBadCoinbaseOutpoint, str)
   266  		}
   267  
   268  		// The fraud proof must also be null.
   269  		if !isNullFraudProof(tx.TxIn[0]) {
   270  			str := fmt.Sprintf("coinbase transaction fraud proof " +
   271  				"was non-null")
   272  			return ruleError(ErrBadCoinbaseFraudProof, str)
   273  		}
   274  
   275  		slen := len(tx.TxIn[0].SignatureScript)
   276  		if slen < MinCoinbaseScriptLen || slen > MaxCoinbaseScriptLen {
   277  			str := fmt.Sprintf("coinbase transaction script "+
   278  				"length of %d is out of range (min: %d, max: "+
   279  				"%d)", slen, MinCoinbaseScriptLen,
   280  				MaxCoinbaseScriptLen)
   281  			return ruleError(ErrBadCoinbaseScriptLen, str)
   282  		}
   283  	} else if isVote {
   284  		// Check script length of stake base signature.
   285  		slen := len(tx.TxIn[0].SignatureScript)
   286  		if slen < MinCoinbaseScriptLen || slen > MaxCoinbaseScriptLen {
   287  			str := fmt.Sprintf("stakebase transaction script "+
   288  				"length of %d is out of range (min: %d, max: "+
   289  				"%d)", slen, MinCoinbaseScriptLen,
   290  				MaxCoinbaseScriptLen)
   291  			return ruleError(ErrBadStakebaseScriptLen, str)
   292  		}
   293  
   294  		// The script must be set to the one specified by the network.
   295  		// Check script length of stake base signature.
   296  		if !bytes.Equal(tx.TxIn[0].SignatureScript,
   297  			params.StakeBaseSigScript) {
   298  			str := fmt.Sprintf("stakebase transaction signature "+
   299  				"script was set to disallowed value (got %x, "+
   300  				"want %x)", tx.TxIn[0].SignatureScript,
   301  				params.StakeBaseSigScript)
   302  			return ruleError(ErrBadStakebaseScrVal, str)
   303  		}
   304  
   305  		// The ticket reference hash in an SSGen tx must not be null.
   306  		ticketHash := &tx.TxIn[1].PreviousOutPoint
   307  		if isNullOutpoint(ticketHash) {
   308  			return ruleError(ErrBadTxInput, "ssgen tx ticket input"+
   309  				" refers to previous output that is null")
   310  		}
   311  	} else {
   312  		// Previous transaction outputs referenced by the inputs to
   313  		// this transaction must not be null except in the case of
   314  		// stakebases for votes.
   315  		for _, txIn := range tx.TxIn {
   316  			prevOut := &txIn.PreviousOutPoint
   317  			if isNullOutpoint(prevOut) {
   318  				return ruleError(ErrBadTxInput, "transaction "+
   319  					"input refers to previous output that "+
   320  					"is null")
   321  			}
   322  		}
   323  	}
   324  
   325  	// Ensure the transaction amounts are in range.  Each transaction output
   326  	// must not be negative or more than the max allowed per transaction.  Also,
   327  	// the total of all outputs must abide by the same restrictions.  All
   328  	// amounts in a transaction are in a unit value known as an atom.  One
   329  	// Decred is a quantity of atoms as defined by the AtomsPerCoin constant.
   330  	//
   331  	// Also ensure that non-stake transaction output scripts do not contain any
   332  	// stake opcodes.
   333  	isTicket := !isVote && stake.IsSStx(tx)
   334  	isRevocation := !isVote && !isTicket && stake.IsSSRtx(tx)
   335  	isStakeTx := isVote || isTicket || isRevocation
   336  	var totalAtom int64
   337  	for txOutIdx, txOut := range tx.TxOut {
   338  		atom := txOut.Value
   339  		if atom < 0 {
   340  			str := fmt.Sprintf("transaction output has negative value of %v",
   341  				atom)
   342  			return ruleError(ErrBadTxOutValue, str)
   343  		}
   344  		if atom > dcrutil.MaxAmount {
   345  			str := fmt.Sprintf("transaction output value of %v is higher than "+
   346  				"max allowed value of %v", atom, dcrutil.MaxAmount)
   347  			return ruleError(ErrBadTxOutValue, str)
   348  		}
   349  
   350  		// Two's complement int64 overflow guarantees that any overflow is
   351  		// detected and reported.  This is impossible for Decred, but perhaps
   352  		// possible if an alt increases the total money supply.
   353  		totalAtom += atom
   354  		if totalAtom < 0 {
   355  			str := fmt.Sprintf("total value of all transaction outputs "+
   356  				"exceeds max allowed value of %v", dcrutil.MaxAmount)
   357  			return ruleError(ErrBadTxOutValue, str)
   358  		}
   359  		if totalAtom > dcrutil.MaxAmount {
   360  			str := fmt.Sprintf("total value of all transaction outputs is %v "+
   361  				"which is higher than max allowed value of %v", totalAtom,
   362  				dcrutil.MaxAmount)
   363  			return ruleError(ErrBadTxOutValue, str)
   364  		}
   365  
   366  		// Ensure that non-stake transactions have no outputs with opcodes
   367  		// OP_SSTX, OP_SSRTX, OP_SSGEN, or OP_SSTX_CHANGE.
   368  		if !isStakeTx {
   369  			hasOp, err := txscript.ContainsStakeOpCodes(txOut.PkScript)
   370  			if err != nil {
   371  				return ruleError(ErrScriptMalformed, err.Error())
   372  			}
   373  			if hasOp {
   374  				str := fmt.Sprintf("non-stake transaction output %d contains "+
   375  					"stake opcode", txOutIdx)
   376  				return ruleError(ErrRegTxCreateStakeOut, str)
   377  			}
   378  		}
   379  	}
   380  
   381  	// Check for duplicate transaction inputs.
   382  	existingTxOut := make(map[wire.OutPoint]struct{})
   383  	for _, txIn := range tx.TxIn {
   384  		if _, exists := existingTxOut[txIn.PreviousOutPoint]; exists {
   385  			return ruleError(ErrDuplicateTxInputs, "transaction "+
   386  				"contains duplicate inputs")
   387  		}
   388  		existingTxOut[txIn.PreviousOutPoint] = struct{}{}
   389  	}
   390  
   391  	return nil
   392  }
   393  
   394  // checkProofOfStake ensures that all ticket purchases in the block pay at least
   395  // the amount required by the block header stake bits which indicate the target
   396  // stake difficulty (aka ticket price) as claimed.
   397  func checkProofOfStake(block *dcrutil.Block, posLimit int64) error {
   398  	msgBlock := block.MsgBlock()
   399  	for _, staketx := range block.STransactions() {
   400  		msgTx := staketx.MsgTx()
   401  		if stake.IsSStx(msgTx) {
   402  			commitValue := msgTx.TxOut[0].Value
   403  
   404  			// Check for underflow block sbits.
   405  			if commitValue < msgBlock.Header.SBits {
   406  				errStr := fmt.Sprintf("Stake tx %v has a "+
   407  					"commitment value less than the "+
   408  					"minimum stake difficulty specified in"+
   409  					" the block (%v)", staketx.Hash(),
   410  					msgBlock.Header.SBits)
   411  				return ruleError(ErrNotEnoughStake, errStr)
   412  			}
   413  
   414  			// Check if it's above the PoS limit.
   415  			if commitValue < posLimit {
   416  				errStr := fmt.Sprintf("Stake tx %v has a "+
   417  					"commitment value less than the "+
   418  					"minimum stake difficulty for the "+
   419  					"network (%v)", staketx.Hash(),
   420  					posLimit)
   421  				return ruleError(ErrStakeBelowMinimum, errStr)
   422  			}
   423  		}
   424  	}
   425  
   426  	return nil
   427  }
   428  
   429  // CheckProofOfStake ensures that all ticket purchases in the block pay at least
   430  // the amount required by the block header stake bits which indicate the target
   431  // stake difficulty (aka ticket price) as claimed.
   432  func CheckProofOfStake(block *dcrutil.Block, posLimit int64) error {
   433  	return checkProofOfStake(block, posLimit)
   434  }
   435  
   436  // standaloneToChainRuleError attempts to convert the passed error from a
   437  // standalone.RuleError to a blockchain.RuleError with the equivalent code.  The
   438  // error is simply passed through without modification if it is not a
   439  // standalone.RuleError, not one of the specifically recognized error codes, or
   440  // nil.
   441  func standaloneToChainRuleError(err error) error {
   442  	// Convert standalone package rule errors to blockchain rule errors.
   443  	if rErr, ok := err.(standalone.RuleError); ok {
   444  		switch rErr.ErrorCode {
   445  		case standalone.ErrUnexpectedDifficulty:
   446  			return ruleError(ErrUnexpectedDifficulty, rErr.Description)
   447  		case standalone.ErrHighHash:
   448  			return ruleError(ErrHighHash, rErr.Description)
   449  		}
   450  	}
   451  
   452  	return err
   453  }
   454  
   455  // checkProofOfWork ensures the block header bits which indicate the target
   456  // difficulty is in min/max range and that the block hash is less than the
   457  // target difficulty as claimed.
   458  //
   459  // The flags modify the behavior of this function as follows:
   460  //  - BFNoPoWCheck: The check to ensure the block hash is less than the target
   461  //    difficulty is not performed.
   462  func checkProofOfWork(header *wire.BlockHeader, powLimit *big.Int, flags BehaviorFlags) error {
   463  	// Only ensure the target difficulty bits are in the valid range when the
   464  	// the flag to avoid proof of work checks is set.
   465  	if flags&BFNoPoWCheck == BFNoPoWCheck {
   466  		err := standalone.CheckProofOfWorkRange(header.Bits, powLimit)
   467  		return standaloneToChainRuleError(err)
   468  	}
   469  
   470  	// Perform all proof of work checks when the flag is not set:
   471  	//
   472  	// - The target difficulty must be larger than zero.
   473  	// - The target difficulty must be less than the maximum allowed.
   474  	// - The block hash must be less than the claimed target.
   475  	blockHash := header.BlockHash()
   476  	err := standalone.CheckProofOfWork(&blockHash, header.Bits, powLimit)
   477  	return standaloneToChainRuleError(err)
   478  }
   479  
   480  // CheckProofOfWork ensures the block header bits which indicate the target
   481  // difficulty is in min/max range and that the block hash is less than the
   482  // target difficulty as claimed.  This is equivalent to the function in the
   483  // standalone package with the exception that that any error is converted to a
   484  // RuleError.
   485  //
   486  // Deprecated: Use standalone.CheckProofOfWork instead.
   487  func CheckProofOfWork(header *wire.BlockHeader, powLimit *big.Int) error {
   488  	return checkProofOfWork(header, powLimit, BFNone)
   489  }
   490  
   491  // checkBlockHeaderSanity performs some preliminary checks on a block header to
   492  // ensure it is sane before continuing with processing.  These checks are
   493  // context free.
   494  //
   495  // The flags do not modify the behavior of this function directly, however they
   496  // are needed to pass along to checkProofOfWork.
   497  func checkBlockHeaderSanity(header *wire.BlockHeader, timeSource MedianTimeSource, flags BehaviorFlags, chainParams *chaincfg.Params) error {
   498  	// The stake validation height should always be at least stake enabled
   499  	// height, so assert it because the code below relies on that assumption.
   500  	stakeValidationHeight := uint32(chainParams.StakeValidationHeight)
   501  	stakeEnabledHeight := uint32(chainParams.StakeEnabledHeight)
   502  	if stakeEnabledHeight > stakeValidationHeight {
   503  		return AssertError(fmt.Sprintf("checkBlockHeaderSanity called "+
   504  			"with stake enabled height %d after stake validation "+
   505  			"height %d", stakeEnabledHeight, stakeValidationHeight))
   506  	}
   507  
   508  	// Ensure the proof of work bits in the block header is in min/max
   509  	// range and the block hash is less than the target value described by
   510  	// the bits.
   511  	err := checkProofOfWork(header, chainParams.PowLimit, flags)
   512  	if err != nil {
   513  		return err
   514  	}
   515  
   516  	// A block timestamp must not have a greater precision than one second.
   517  	// This check is necessary because Go time.Time values support
   518  	// nanosecond precision whereas the consensus rules only apply to
   519  	// seconds and it's much nicer to deal with standard Go time values
   520  	// instead of converting to seconds everywhere.
   521  	if !header.Timestamp.Equal(time.Unix(header.Timestamp.Unix(), 0)) {
   522  		str := fmt.Sprintf("block timestamp of %v has a higher "+
   523  			"precision than one second", header.Timestamp)
   524  		return ruleError(ErrInvalidTime, str)
   525  	}
   526  
   527  	// Ensure the block time is not too far in the future.
   528  	maxTimestamp := timeSource.AdjustedTime().Add(time.Second *
   529  		MaxTimeOffsetSeconds)
   530  	if header.Timestamp.After(maxTimestamp) {
   531  		str := fmt.Sprintf("block timestamp of %v is too far in the "+
   532  			"future", header.Timestamp)
   533  		return ruleError(ErrTimeTooNew, str)
   534  	}
   535  
   536  	// A block must not contain any votes or revocations, its vote bits
   537  	// must be 0x0001, and its final state must be all zeroes before
   538  	// stake validation begins.
   539  	if header.Height < stakeValidationHeight {
   540  		if header.Voters > 0 {
   541  			errStr := fmt.Sprintf("block at height %d commits to "+
   542  				"%d votes before stake validation height %d",
   543  				header.Height, header.Voters,
   544  				stakeValidationHeight)
   545  			return ruleError(ErrInvalidEarlyStakeTx, errStr)
   546  		}
   547  
   548  		if header.Revocations > 0 {
   549  			errStr := fmt.Sprintf("block at height %d commits to "+
   550  				"%d revocations before stake validation height %d",
   551  				header.Height, header.Revocations,
   552  				stakeValidationHeight)
   553  			return ruleError(ErrInvalidEarlyStakeTx, errStr)
   554  		}
   555  
   556  		if header.VoteBits != earlyVoteBitsValue {
   557  			errStr := fmt.Sprintf("block at height %d commits to "+
   558  				"invalid vote bits before stake validation "+
   559  				"height %d (expected %x, got %x)",
   560  				header.Height, stakeValidationHeight,
   561  				earlyVoteBitsValue, header.VoteBits)
   562  			return ruleError(ErrInvalidEarlyVoteBits, errStr)
   563  		}
   564  
   565  		if header.FinalState != earlyFinalState {
   566  			errStr := fmt.Sprintf("block at height %d commits to "+
   567  				"invalid final state before stake validation "+
   568  				"height %d (expected %x, got %x)",
   569  				header.Height, stakeValidationHeight,
   570  				earlyFinalState, header.FinalState)
   571  			return ruleError(ErrInvalidEarlyFinalState, errStr)
   572  		}
   573  	}
   574  
   575  	// A block must not contain fewer votes than the minimum required to
   576  	// reach majority once stake validation height has been reached.
   577  	if header.Height >= stakeValidationHeight {
   578  		majority := (chainParams.TicketsPerBlock / 2) + 1
   579  		if header.Voters < majority {
   580  			errStr := fmt.Sprintf("block does not commit to enough "+
   581  				"votes (min: %d, got %d)", majority,
   582  				header.Voters)
   583  			return ruleError(ErrNotEnoughVotes, errStr)
   584  		}
   585  	}
   586  
   587  	// The block header must not claim to contain more votes than the
   588  	// maximum allowed.
   589  	if header.Voters > chainParams.TicketsPerBlock {
   590  		errStr := fmt.Sprintf("block commits to too many votes (max: "+
   591  			"%d, got %d)", chainParams.TicketsPerBlock, header.Voters)
   592  		return ruleError(ErrTooManyVotes, errStr)
   593  	}
   594  
   595  	// The block must not contain more ticket purchases than the maximum
   596  	// allowed.
   597  	if header.FreshStake > chainParams.MaxFreshStakePerBlock {
   598  		errStr := fmt.Sprintf("block commits to too many ticket "+
   599  			"purchases (max: %d, got %d)",
   600  			chainParams.MaxFreshStakePerBlock, header.FreshStake)
   601  		return ruleError(ErrTooManySStxs, errStr)
   602  	}
   603  
   604  	return nil
   605  }
   606  
   607  // checkBlockSanity performs some preliminary checks on a block to ensure it is
   608  // sane before continuing with block processing.  These checks are context
   609  // free.
   610  //
   611  // The flags do not modify the behavior of this function directly, however they
   612  // are needed to pass along to checkBlockHeaderSanity.
   613  func checkBlockSanity(block *dcrutil.Block, timeSource MedianTimeSource, flags BehaviorFlags, chainParams *chaincfg.Params) error {
   614  	msgBlock := block.MsgBlock()
   615  	header := &msgBlock.Header
   616  	err := checkBlockHeaderSanity(header, timeSource, flags, chainParams)
   617  	if err != nil {
   618  		return err
   619  	}
   620  
   621  	// All ticket purchases must meet the difficulty specified by the block
   622  	// header.
   623  	err = checkProofOfStake(block, chainParams.MinimumStakeDiff)
   624  	if err != nil {
   625  		return err
   626  	}
   627  
   628  	// A block must have at least one regular transaction.
   629  	numTx := len(msgBlock.Transactions)
   630  	if numTx == 0 {
   631  		return ruleError(ErrNoTransactions, "block does not contain "+
   632  			"any transactions")
   633  	}
   634  
   635  	// A block must not exceed the maximum allowed block payload when
   636  	// serialized.
   637  	//
   638  	// This is a quick and context-free sanity check of the maximum block
   639  	// size according to the wire protocol.  Even though the wire protocol
   640  	// already prevents blocks bigger than this limit, there are other
   641  	// methods of receiving a block that might not have been checked
   642  	// already.  A separate block size is enforced later that takes into
   643  	// account the network-specific block size and the results of block
   644  	// size votes.  Typically that block size is more restrictive than this
   645  	// one.
   646  	serializedSize := msgBlock.SerializeSize()
   647  	if serializedSize > wire.MaxBlockPayload {
   648  		str := fmt.Sprintf("serialized block is too big - got %d, "+
   649  			"max %d", serializedSize, wire.MaxBlockPayload)
   650  		return ruleError(ErrBlockTooBig, str)
   651  	}
   652  	if header.Size != uint32(serializedSize) {
   653  		str := fmt.Sprintf("serialized block is not size indicated in "+
   654  			"header - got %d, expected %d", header.Size,
   655  			serializedSize)
   656  		return ruleError(ErrWrongBlockSize, str)
   657  	}
   658  
   659  	// The first transaction in a block's regular tree must be a coinbase.
   660  	transactions := block.Transactions()
   661  	if !standalone.IsCoinBaseTx(transactions[0].MsgTx()) {
   662  		return ruleError(ErrFirstTxNotCoinbase, "first transaction in "+
   663  			"block is not a coinbase")
   664  	}
   665  
   666  	// A block must not have more than one coinbase.
   667  	for i, tx := range transactions[1:] {
   668  		if standalone.IsCoinBaseTx(tx.MsgTx()) {
   669  			str := fmt.Sprintf("block contains second coinbase at "+
   670  				"index %d", i+1)
   671  			return ruleError(ErrMultipleCoinbases, str)
   672  		}
   673  	}
   674  
   675  	// Do some preliminary checks on each regular transaction to ensure they
   676  	// are sane before continuing.
   677  	for i, tx := range transactions {
   678  		// A block must not have stake transactions in the regular
   679  		// transaction tree.
   680  		msgTx := tx.MsgTx()
   681  		txType := stake.DetermineTxType(msgTx)
   682  		if txType != stake.TxTypeRegular {
   683  			errStr := fmt.Sprintf("block contains a stake "+
   684  				"transaction in the regular transaction tree at "+
   685  				"index %d", i)
   686  			return ruleError(ErrStakeTxInRegularTree, errStr)
   687  		}
   688  
   689  		err := CheckTransactionSanity(msgTx, chainParams)
   690  		if err != nil {
   691  			return err
   692  		}
   693  	}
   694  
   695  	// Do some preliminary checks on each stake transaction to ensure they
   696  	// are sane while tallying each type before continuing.
   697  	stakeValidationHeight := uint32(chainParams.StakeValidationHeight)
   698  	var totalTickets, totalVotes, totalRevocations int64
   699  	var totalYesVotes int64
   700  	for txIdx, stx := range msgBlock.STransactions {
   701  		err := CheckTransactionSanity(stx, chainParams)
   702  		if err != nil {
   703  			return err
   704  		}
   705  
   706  		// A block must not have regular transactions in the stake
   707  		// transaction tree.
   708  		txType := stake.DetermineTxType(stx)
   709  		if txType == stake.TxTypeRegular {
   710  			errStr := fmt.Sprintf("block contains regular "+
   711  				"transaction in stake transaction tree at "+
   712  				"index %d", txIdx)
   713  			return ruleError(ErrRegTxInStakeTree, errStr)
   714  		}
   715  
   716  		switch txType {
   717  		case stake.TxTypeSStx:
   718  			totalTickets++
   719  
   720  		case stake.TxTypeSSGen:
   721  			totalVotes++
   722  
   723  			// All votes in a block must commit to the parent of the
   724  			// block once stake validation height has been reached.
   725  			if header.Height >= stakeValidationHeight {
   726  				votedHash, votedHeight := stake.SSGenBlockVotedOn(stx)
   727  				if (votedHash != header.PrevBlock) || (votedHeight !=
   728  					header.Height-1) {
   729  
   730  					errStr := fmt.Sprintf("vote %s at index %d is "+
   731  						"for parent block %s (height %d) versus "+
   732  						"expected parent block %s (height %d)",
   733  						stx.TxHash(), txIdx, votedHash,
   734  						votedHeight, header.PrevBlock,
   735  						header.Height-1)
   736  					return ruleError(ErrVotesOnWrongBlock, errStr)
   737  				}
   738  
   739  				// Tally how many votes approve the previous block for use
   740  				// when validating the header commitment.
   741  				if voteBitsApproveParent(stake.SSGenVoteBits(stx)) {
   742  					totalYesVotes++
   743  				}
   744  			}
   745  
   746  		case stake.TxTypeSSRtx:
   747  			totalRevocations++
   748  		}
   749  	}
   750  
   751  	// A block must not contain more than the maximum allowed number of
   752  	// revocations.
   753  	if totalRevocations > maxRevocationsPerBlock {
   754  		errStr := fmt.Sprintf("block contains %d revocations which "+
   755  			"exceeds the maximum allowed amount of %d",
   756  			totalRevocations, maxRevocationsPerBlock)
   757  		return ruleError(ErrTooManyRevocations, errStr)
   758  	}
   759  
   760  	// A block must only contain stake transactions of the the allowed
   761  	// types.
   762  	//
   763  	// NOTE: This is not possible to hit at the time this comment was
   764  	// written because all transactions which are not specifically one of
   765  	// the recognized stake transaction forms are considered regular
   766  	// transactions and those are rejected above.  However, if a new stake
   767  	// transaction type is added, that implicit condition would no longer
   768  	// hold and therefore an explicit check is performed here.
   769  	numStakeTx := int64(len(msgBlock.STransactions))
   770  	calcStakeTx := totalTickets + totalVotes + totalRevocations
   771  	if numStakeTx != calcStakeTx {
   772  		errStr := fmt.Sprintf("block contains an unexpected number "+
   773  			"of stake transactions (contains %d, expected %d)",
   774  			numStakeTx, calcStakeTx)
   775  		return ruleError(ErrNonstandardStakeTx, errStr)
   776  	}
   777  
   778  	// A block header must commit to the actual number of tickets purchases that
   779  	// are in the block.
   780  	if int64(header.FreshStake) != totalTickets {
   781  		errStr := fmt.Sprintf("block header commitment to %d ticket "+
   782  			"purchases does not match %d contained in the block",
   783  			header.FreshStake, totalTickets)
   784  		return ruleError(ErrFreshStakeMismatch, errStr)
   785  	}
   786  
   787  	// A block header must commit to the the actual number of votes that are
   788  	// in the block.
   789  	if int64(header.Voters) != totalVotes {
   790  		errStr := fmt.Sprintf("block header commitment to %d votes "+
   791  			"does not match %d contained in the block",
   792  			header.Voters, totalVotes)
   793  		return ruleError(ErrVotesMismatch, errStr)
   794  	}
   795  
   796  	// A block header must commit to the actual number of revocations that
   797  	// are in the block.
   798  	if int64(header.Revocations) != totalRevocations {
   799  		errStr := fmt.Sprintf("block header commitment to %d revocations "+
   800  			"does not match %d contained in the block",
   801  			header.Revocations, totalRevocations)
   802  		return ruleError(ErrRevocationsMismatch, errStr)
   803  	}
   804  
   805  	// A block header must commit to the same previous block acceptance
   806  	// semantics expressed by the votes once stake validation height has
   807  	// been reached.
   808  	if header.Height >= stakeValidationHeight {
   809  		totalNoVotes := totalVotes - totalYesVotes
   810  		headerApproves := headerApprovesParent(header)
   811  		votesApprove := totalYesVotes > totalNoVotes
   812  		if headerApproves != votesApprove {
   813  			errStr := fmt.Sprintf("block header commitment to previous "+
   814  				"block approval does not match votes (header claims: %v, "+
   815  				"votes: %v)", headerApproves, votesApprove)
   816  			return ruleError(ErrIncongruentVotebit, errStr)
   817  		}
   818  	}
   819  
   820  	// A block must not contain anything other than ticket purchases prior to
   821  	// stake validation height.
   822  	//
   823  	// NOTE: This case is impossible to hit at this point at the time this
   824  	// comment was written since the votes and revocations have already been
   825  	// proven to be zero before stake validation height and the only other
   826  	// type at the current time is ticket purchases, however, if another
   827  	// stake type is ever added, consensus would break without this check.
   828  	// It's better to be safe and it's a cheap check.
   829  	if header.Height < stakeValidationHeight {
   830  		if int64(len(msgBlock.STransactions)) != totalTickets {
   831  			errStr := fmt.Sprintf("block contains stake "+
   832  				"transactions other than ticket purchases before "+
   833  				"stake validation height %d (total: %d, expected %d)",
   834  				uint32(chainParams.StakeValidationHeight),
   835  				len(msgBlock.STransactions), header.FreshStake)
   836  			return ruleError(ErrInvalidEarlyStakeTx, errStr)
   837  		}
   838  	}
   839  
   840  	// Build merkle tree and ensure the calculated merkle root matches the
   841  	// entry in the block header.  This also has the effect of caching all
   842  	// of the transaction hashes in the block to speed up future hash
   843  	// checks.  Bitcoind builds the tree here and checks the merkle root
   844  	// after the following checks, but there is no reason not to check the
   845  	// merkle root matches here.
   846  	wantMerkleRoot := standalone.CalcTxTreeMerkleRoot(msgBlock.Transactions)
   847  	if header.MerkleRoot != wantMerkleRoot {
   848  		str := fmt.Sprintf("block merkle root is invalid - block "+
   849  			"header indicates %v, but calculated value is %v",
   850  			header.MerkleRoot, wantMerkleRoot)
   851  		return ruleError(ErrBadMerkleRoot, str)
   852  	}
   853  
   854  	// Build the stake tx tree merkle root too and check it.
   855  	wantStakeRoot := standalone.CalcTxTreeMerkleRoot(msgBlock.STransactions)
   856  	if header.StakeRoot != wantStakeRoot {
   857  		str := fmt.Sprintf("block stake merkle root is invalid - block"+
   858  			" header indicates %v, but calculated value is %v",
   859  			header.StakeRoot, wantStakeRoot)
   860  		return ruleError(ErrBadMerkleRoot, str)
   861  	}
   862  
   863  	// Check for duplicate transactions.  This check will be fairly quick
   864  	// since the transaction hashes are already cached due to building the
   865  	// merkle trees above.
   866  	existingTxHashes := make(map[chainhash.Hash]struct{})
   867  	stakeTransactions := block.STransactions()
   868  	allTransactions := append(transactions, stakeTransactions...)
   869  
   870  	for _, tx := range allTransactions {
   871  		hash := tx.Hash()
   872  		if _, exists := existingTxHashes[*hash]; exists {
   873  			str := fmt.Sprintf("block contains duplicate "+
   874  				"transaction %v", hash)
   875  			return ruleError(ErrDuplicateTx, str)
   876  		}
   877  		existingTxHashes[*hash] = struct{}{}
   878  	}
   879  
   880  	// The number of signature operations must be less than the maximum
   881  	// allowed per block.
   882  	totalSigOps := 0
   883  	for _, tx := range allTransactions {
   884  		// We could potentially overflow the accumulator so check for
   885  		// overflow.
   886  		lastSigOps := totalSigOps
   887  
   888  		msgTx := tx.MsgTx()
   889  		isCoinBase := standalone.IsCoinBaseTx(msgTx)
   890  		isSSGen := stake.IsSSGen(msgTx)
   891  		totalSigOps += CountSigOps(tx, isCoinBase, isSSGen)
   892  		if totalSigOps < lastSigOps || totalSigOps > MaxSigOpsPerBlock {
   893  			str := fmt.Sprintf("block contains too many signature "+
   894  				"operations - got %v, max %v", totalSigOps,
   895  				MaxSigOpsPerBlock)
   896  			return ruleError(ErrTooManySigOps, str)
   897  		}
   898  	}
   899  
   900  	return nil
   901  }
   902  
   903  // CheckBlockSanity performs some preliminary checks on a block to ensure it is
   904  // sane before continuing with block processing.  These checks are context
   905  // free.
   906  func CheckBlockSanity(block *dcrutil.Block, timeSource MedianTimeSource, chainParams *chaincfg.Params) error {
   907  	return checkBlockSanity(block, timeSource, BFNone, chainParams)
   908  }
   909  
   910  // checkBlockHeaderPositional performs several validation checks on the block
   911  // header which depend on its position within the block chain and having the
   912  // headers of all ancestors available.  These checks do not, and must not, rely
   913  // on having the full block data of all ancestors available.
   914  //
   915  // The flags modify the behavior of this function as follows:
   916  //  - BFFastAdd: All checks except those involving comparing the header against
   917  //    the checkpoints and expected height are not performed.
   918  //
   919  // This function MUST be called with the chain state lock held (for reads).
   920  func (b *BlockChain) checkBlockHeaderPositional(header *wire.BlockHeader, prevNode *blockNode, flags BehaviorFlags) error {
   921  	// The genesis block is valid by definition.
   922  	if prevNode == nil {
   923  		return nil
   924  	}
   925  
   926  	fastAdd := flags&BFFastAdd == BFFastAdd
   927  	if !fastAdd {
   928  		// Ensure the difficulty specified in the block header matches
   929  		// the calculated difficulty based on the previous block and
   930  		// difficulty retarget rules.
   931  		expDiff, err := b.calcNextRequiredDifficulty(prevNode,
   932  			header.Timestamp)
   933  		if err != nil {
   934  			return err
   935  		}
   936  		blockDifficulty := header.Bits
   937  		if blockDifficulty != expDiff {
   938  			str := fmt.Sprintf("block difficulty of %d is not the"+
   939  				" expected value of %d", blockDifficulty,
   940  				expDiff)
   941  			return ruleError(ErrUnexpectedDifficulty, str)
   942  		}
   943  
   944  		// Ensure the timestamp for the block header is after the
   945  		// median time of the last several blocks (medianTimeBlocks).
   946  		medianTime := prevNode.CalcPastMedianTime()
   947  		if !header.Timestamp.After(medianTime) {
   948  			str := "block timestamp of %v is not after expected %v"
   949  			str = fmt.Sprintf(str, header.Timestamp, medianTime)
   950  			return ruleError(ErrTimeTooOld, str)
   951  		}
   952  	}
   953  
   954  	// The height of this block is one more than the referenced previous
   955  	// block.
   956  	blockHeight := prevNode.height + 1
   957  
   958  	// Ensure the header commits to the correct height based on the height it
   959  	// actually connects in the blockchain.
   960  	if int64(header.Height) != blockHeight {
   961  		errStr := fmt.Sprintf("block header commitment to height %d "+
   962  			"does not match chain height %d", header.Height,
   963  			blockHeight)
   964  		return ruleError(ErrBadBlockHeight, errStr)
   965  	}
   966  
   967  	// Ensure chain matches up to predetermined checkpoints.
   968  	blockHash := header.BlockHash()
   969  	if !b.verifyCheckpoint(blockHeight, &blockHash) {
   970  		str := fmt.Sprintf("block at height %d does not match "+
   971  			"checkpoint hash", blockHeight)
   972  		return ruleError(ErrBadCheckpoint, str)
   973  	}
   974  
   975  	// Find the previous checkpoint and prevent blocks which fork the main
   976  	// chain before it.  This prevents storage of new, otherwise valid,
   977  	// blocks which build off of old blocks that are likely at a much easier
   978  	// difficulty and therefore could be used to waste cache and disk space.
   979  	checkpointNode, err := b.findPreviousCheckpoint()
   980  	if err != nil {
   981  		return err
   982  	}
   983  	if checkpointNode != nil && blockHeight < checkpointNode.height {
   984  		str := fmt.Sprintf("block at height %d forks the main chain "+
   985  			"before the previous checkpoint at height %d",
   986  			blockHeight, checkpointNode.height)
   987  		return ruleError(ErrForkTooOld, str)
   988  	}
   989  
   990  	if !fastAdd {
   991  		// Reject version 6 blocks for networks other than the main
   992  		// network once a majority of the network has upgraded.
   993  		if b.chainParams.Net != wire.MainNet && header.Version < 7 &&
   994  			b.isMajorityVersion(7, prevNode, b.chainParams.BlockRejectNumRequired) {
   995  
   996  			str := "new blocks with version %d are no longer valid"
   997  			str = fmt.Sprintf(str, header.Version)
   998  			return ruleError(ErrBlockVersionTooOld, str)
   999  		}
  1000  
  1001  		// Reject version 5 blocks once a majority of the network has
  1002  		// upgraded.
  1003  		if header.Version < 6 && b.isMajorityVersion(6, prevNode,
  1004  			b.chainParams.BlockRejectNumRequired) {
  1005  
  1006  			str := "new blocks with version %d are no longer valid"
  1007  			str = fmt.Sprintf(str, header.Version)
  1008  			return ruleError(ErrBlockVersionTooOld, str)
  1009  		}
  1010  
  1011  		// Reject version 4 blocks once a majority of the network has
  1012  		// upgraded.
  1013  		if header.Version < 5 && b.isMajorityVersion(5, prevNode,
  1014  			b.chainParams.BlockRejectNumRequired) {
  1015  
  1016  			str := "new blocks with version %d are no longer valid"
  1017  			str = fmt.Sprintf(str, header.Version)
  1018  			return ruleError(ErrBlockVersionTooOld, str)
  1019  		}
  1020  
  1021  		// Reject version 3 blocks once a majority of the network has
  1022  		// upgraded.
  1023  		if header.Version < 4 && b.isMajorityVersion(4, prevNode,
  1024  			b.chainParams.BlockRejectNumRequired) {
  1025  
  1026  			str := "new blocks with version %d are no longer valid"
  1027  			str = fmt.Sprintf(str, header.Version)
  1028  			return ruleError(ErrBlockVersionTooOld, str)
  1029  		}
  1030  
  1031  		// Reject version 2 blocks once a majority of the network has
  1032  		// upgraded.
  1033  		if header.Version < 3 && b.isMajorityVersion(3, prevNode,
  1034  			b.chainParams.BlockRejectNumRequired) {
  1035  
  1036  			str := "new blocks with version %d are no longer valid"
  1037  			str = fmt.Sprintf(str, header.Version)
  1038  			return ruleError(ErrBlockVersionTooOld, str)
  1039  		}
  1040  
  1041  		// Reject version 1 blocks once a majority of the network has
  1042  		// upgraded.
  1043  		if header.Version < 2 && b.isMajorityVersion(2, prevNode,
  1044  			b.chainParams.BlockRejectNumRequired) {
  1045  
  1046  			str := "new blocks with version %d are no longer valid"
  1047  			str = fmt.Sprintf(str, header.Version)
  1048  			return ruleError(ErrBlockVersionTooOld, str)
  1049  		}
  1050  	}
  1051  
  1052  	return nil
  1053  }
  1054  
  1055  // checkBlockPositional performs several validation checks on the block which
  1056  // depend on its position within the block chain and having the headers of all
  1057  // ancestors available.  These checks do not, and must not, rely on having the
  1058  // full block data of all ancestors available.
  1059  //
  1060  // The flags modify the behavior of this function as follows:
  1061  //  - BFFastAdd: The transactions are not checked to see if they are expired and
  1062  //    the coinbae height check is not performed.
  1063  //
  1064  // The flags are also passed to checkBlockHeaderPositional.  See its
  1065  // documentation for how the flags modify its behavior.
  1066  func (b *BlockChain) checkBlockPositional(block *dcrutil.Block, prevNode *blockNode, flags BehaviorFlags) error {
  1067  	// The genesis block is valid by definition.
  1068  	if prevNode == nil {
  1069  		return nil
  1070  	}
  1071  
  1072  	// Perform all block header related validation checks that depend on its
  1073  	// position within the block chain and having the headers of all
  1074  	// ancestors available, but do not rely on having the full block data of
  1075  	// all ancestors available.
  1076  	header := &block.MsgBlock().Header
  1077  	err := b.checkBlockHeaderPositional(header, prevNode, flags)
  1078  	if err != nil {
  1079  		return err
  1080  	}
  1081  
  1082  	fastAdd := flags&BFFastAdd == BFFastAdd
  1083  	if !fastAdd {
  1084  		// The height of this block is one more than the referenced
  1085  		// previous block.
  1086  		blockHeight := prevNode.height + 1
  1087  
  1088  		// Ensure all transactions in the block are not expired.
  1089  		for _, tx := range block.Transactions() {
  1090  			if IsExpired(tx, blockHeight) {
  1091  				errStr := fmt.Sprintf("block contains expired regular "+
  1092  					"transaction %v (expiration height %d)", tx.Hash(),
  1093  					tx.MsgTx().Expiry)
  1094  				return ruleError(ErrExpiredTx, errStr)
  1095  			}
  1096  		}
  1097  		for _, stx := range block.STransactions() {
  1098  			if IsExpired(stx, blockHeight) {
  1099  				errStr := fmt.Sprintf("block contains expired stake "+
  1100  					"transaction %v (expiration height %d)", stx.Hash(),
  1101  					stx.MsgTx().Expiry)
  1102  				return ruleError(ErrExpiredTx, errStr)
  1103  			}
  1104  		}
  1105  
  1106  		// Check that the coinbase contains at minimum the block
  1107  		// height in output 1.
  1108  		if blockHeight > 1 {
  1109  			err := checkCoinbaseUniqueHeight(blockHeight, block)
  1110  			if err != nil {
  1111  				return err
  1112  			}
  1113  		}
  1114  	}
  1115  
  1116  	return nil
  1117  }
  1118  
  1119  // checkBlockHeaderContext performs several validation checks on the block
  1120  // header which depend on having the full block data for all of its ancestors
  1121  // available.  This includes checks which depend on tallying the results of
  1122  // votes, because votes are part of the block data.
  1123  //
  1124  // It should be noted that rule changes that have become buried deep enough
  1125  // typically will eventually be transitioned to using well-known activation
  1126  // points for efficiency purposes at which point the associated checks no longer
  1127  // require having direct access to the historical votes, and therefore may be
  1128  // transitioned to checkBlockHeaderPositional at that time.  Conversely, any
  1129  // checks in that function which become conditional based on the results of a
  1130  // vote will necessarily need to be transitioned to this function.
  1131  //
  1132  // The flags modify the behavior of this function as follows:
  1133  //  - BFFastAdd: No check are performed.
  1134  //
  1135  // This function MUST be called with the chain state lock held (for writes).
  1136  func (b *BlockChain) checkBlockHeaderContext(header *wire.BlockHeader, prevNode *blockNode, flags BehaviorFlags) error {
  1137  	// The genesis block is valid by definition.
  1138  	if prevNode == nil {
  1139  		return nil
  1140  	}
  1141  
  1142  	fastAdd := flags&BFFastAdd == BFFastAdd
  1143  	if !fastAdd {
  1144  		// Ensure the stake difficulty specified in the block header
  1145  		// matches the calculated difficulty based on the previous block
  1146  		// and difficulty retarget rules.
  1147  		expSDiff, err := b.calcNextRequiredStakeDifficulty(prevNode)
  1148  		if err != nil {
  1149  			return err
  1150  		}
  1151  		if header.SBits != expSDiff {
  1152  			errStr := fmt.Sprintf("block stake difficulty of %d "+
  1153  				"is not the expected value of %d", header.SBits,
  1154  				expSDiff)
  1155  			return ruleError(ErrUnexpectedDifficulty, errStr)
  1156  		}
  1157  
  1158  		// Enforce the stake version in the header once a majority of
  1159  		// the network has upgraded to version 3 blocks.
  1160  		if header.Version >= 3 && b.isMajorityVersion(3, prevNode,
  1161  			b.chainParams.BlockEnforceNumRequired) {
  1162  
  1163  			expectedStakeVer := b.calcStakeVersion(prevNode)
  1164  			if header.StakeVersion != expectedStakeVer {
  1165  				str := fmt.Sprintf("block stake version of %d "+
  1166  					"is not the expected version of %d",
  1167  					header.StakeVersion, expectedStakeVer)
  1168  				return ruleError(ErrBadStakeVersion, str)
  1169  			}
  1170  		}
  1171  
  1172  		// Ensure the header commits to the correct pool size based on
  1173  		// its position within the chain.
  1174  		parentStakeNode, err := b.fetchStakeNode(prevNode)
  1175  		if err != nil {
  1176  			return err
  1177  		}
  1178  		calcPoolSize := uint32(parentStakeNode.PoolSize())
  1179  		if header.PoolSize != calcPoolSize {
  1180  			errStr := fmt.Sprintf("block header commitment to "+
  1181  				"pool size %d does not match expected size %d",
  1182  				header.PoolSize, calcPoolSize)
  1183  			return ruleError(ErrPoolSize, errStr)
  1184  		}
  1185  
  1186  		// Ensure the header commits to the correct final state of the
  1187  		// ticket lottery.
  1188  		calcFinalState := parentStakeNode.FinalState()
  1189  		if header.FinalState != calcFinalState {
  1190  			errStr := fmt.Sprintf("block header commitment to "+
  1191  				"final state of the ticket lottery %x does not "+
  1192  				"match expected value %x", header.FinalState,
  1193  				calcFinalState)
  1194  			return ruleError(ErrInvalidFinalState, errStr)
  1195  		}
  1196  	}
  1197  
  1198  	return nil
  1199  }
  1200  
  1201  // checkCoinbaseUniqueHeight checks to ensure that for all blocks height > 1 the
  1202  // coinbase contains the height encoding to make coinbase hash collisions
  1203  // impossible.
  1204  func checkCoinbaseUniqueHeight(blockHeight int64, block *dcrutil.Block) error {
  1205  	// Coinbase output 0 is the project subsidy, and output 1 is height +
  1206  	// extranonce, so at least two outputs must exist.
  1207  	const minReqOutputs = 2
  1208  	coinbaseTx := block.MsgBlock().Transactions[0]
  1209  	if len(coinbaseTx.TxOut) < minReqOutputs {
  1210  		str := fmt.Sprintf("block %s is missing required coinbase outputs ("+
  1211  			"num outputs: %d, min required: %d)", block.Hash(),
  1212  			len(coinbaseTx.TxOut), minReqOutputs)
  1213  		return ruleError(ErrFirstTxNotCoinbase, str)
  1214  	}
  1215  
  1216  	// Only version 0 scripts are currently valid.
  1217  	const scriptVersion = 0
  1218  	nullDataOut := coinbaseTx.TxOut[1]
  1219  	if nullDataOut.Version != scriptVersion {
  1220  		str := fmt.Sprintf("block %s coinbase output 1 script version %d is "+
  1221  			"not the required version %d", block.Hash(), nullDataOut.Version,
  1222  			scriptVersion)
  1223  		return ruleError(ErrFirstTxNotCoinbase, str)
  1224  	}
  1225  
  1226  	// The nulldata in the coinbase must be a single OP_RETURN followed by a
  1227  	// data push up to maxUniqueCoinbaseNullDataSize bytes and the first 4 bytes
  1228  	// of that data must be the encoded height of the block so that every
  1229  	// coinbase created has a unique transaction hash.
  1230  	//
  1231  	// NOTE: This is intentionally not using GetScriptClass and the related
  1232  	// functions because those are specifically for standardness checks which
  1233  	// can change over time and this function is enforces consensus rules.
  1234  	//
  1235  	// Also of note is that technically normal nulldata scripts support encoding
  1236  	// numbers via small opcodes, however, for legacy reasons, the consensus
  1237  	// rules require the block height to be encoded as a 4-byte little-endian
  1238  	// uint32 pushed via a normal data push, as opposed to using the normal
  1239  	// number handling semantics of scripts, so this is specialized to
  1240  	// accommodate that.
  1241  	var nullData []byte
  1242  	pkScript := nullDataOut.PkScript
  1243  	if len(pkScript) > 1 && pkScript[0] == txscript.OP_RETURN {
  1244  		tokenizer := txscript.MakeScriptTokenizer(scriptVersion, pkScript[1:])
  1245  		if tokenizer.Next() && tokenizer.Done() && tokenizer.Opcode() <=
  1246  			txscript.OP_PUSHDATA4 {
  1247  
  1248  			nullData = tokenizer.Data()
  1249  		}
  1250  	}
  1251  	if len(nullData) > maxUniqueCoinbaseNullDataSize {
  1252  		str := fmt.Sprintf("block %s coinbase output 1 pushes %d bytes which "+
  1253  			"is more than allowed value of %d", block.Hash(), len(nullData),
  1254  			maxUniqueCoinbaseNullDataSize)
  1255  		return ruleError(ErrFirstTxNotCoinbase, str)
  1256  	}
  1257  	if len(nullData) < 4 {
  1258  		str := fmt.Sprintf("block %s coinbase output 1 pushes %d bytes which "+
  1259  			"is too short to encode height", block.Hash(), len(nullData))
  1260  		return ruleError(ErrFirstTxNotCoinbase, str)
  1261  	}
  1262  
  1263  	// Check the height and ensure it is correct.
  1264  	cbHeight := binary.LittleEndian.Uint32(nullData[0:4])
  1265  	if cbHeight != uint32(blockHeight) {
  1266  		header := &block.MsgBlock().Header
  1267  		str := fmt.Sprintf("block %s coinbase output 1 encodes height %d "+
  1268  			"instead of expected height %d (prev block: %s, header height %d)",
  1269  			block.Hash(), cbHeight, uint32(blockHeight), header.PrevBlock,
  1270  			header.Height)
  1271  		return ruleError(ErrCoinbaseHeight, str)
  1272  	}
  1273  
  1274  	return nil
  1275  }
  1276  
  1277  // checkAllowedVotes performs validation of all votes in the block to ensure
  1278  // they spend tickets that are actually allowed to vote per the lottery.
  1279  //
  1280  // This function is safe for concurrent access.
  1281  func (b *BlockChain) checkAllowedVotes(parentStakeNode *stake.Node, block *wire.MsgBlock) error {
  1282  	// Determine the winning ticket hashes and create a map for faster lookup.
  1283  	ticketsPerBlock := int(b.chainParams.TicketsPerBlock)
  1284  	winningHashes := make(map[chainhash.Hash]struct{}, ticketsPerBlock)
  1285  	for _, ticketHash := range parentStakeNode.Winners() {
  1286  		winningHashes[ticketHash] = struct{}{}
  1287  	}
  1288  
  1289  	for _, stx := range block.STransactions {
  1290  		// Ignore non-vote stake transactions.
  1291  		if !stake.IsSSGen(stx) {
  1292  			continue
  1293  		}
  1294  
  1295  		// Ensure the ticket being spent is actually eligible to vote in
  1296  		// this block.
  1297  		ticketHash := stx.TxIn[1].PreviousOutPoint.Hash
  1298  		if _, ok := winningHashes[ticketHash]; !ok {
  1299  			errStr := fmt.Sprintf("block contains vote for "+
  1300  				"ineligible ticket %s (eligible tickets: %s)",
  1301  				ticketHash, winningHashes)
  1302  			return ruleError(ErrTicketUnavailable, errStr)
  1303  		}
  1304  	}
  1305  
  1306  	return nil
  1307  }
  1308  
  1309  // checkAllowedRevocations performs validation of all revocations in the block
  1310  // to ensure they spend tickets that are actually allowed to be revoked per the
  1311  // lottery.  Tickets are only eligible to be revoked if they were missed or have
  1312  // expired.
  1313  //
  1314  // This function is safe for concurrent access.
  1315  func (b *BlockChain) checkAllowedRevocations(parentStakeNode *stake.Node, block *wire.MsgBlock) error {
  1316  	for _, stx := range block.STransactions {
  1317  		// Ignore non-revocation stake transactions.
  1318  		if !stake.IsSSRtx(stx) {
  1319  			continue
  1320  		}
  1321  
  1322  		// Ensure the ticket being spent is actually eligible to be
  1323  		// revoked in this block.
  1324  		ticketHash := stx.TxIn[0].PreviousOutPoint.Hash
  1325  		if !parentStakeNode.ExistsMissedTicket(ticketHash) {
  1326  			errStr := fmt.Sprintf("block contains revocation of "+
  1327  				"ineligible ticket %s", ticketHash)
  1328  			return ruleError(ErrInvalidSSRtx, errStr)
  1329  		}
  1330  	}
  1331  
  1332  	return nil
  1333  }
  1334  
  1335  // checkBlockContext performs several validation checks on the block which depend
  1336  // on having the full block data for all of its ancestors available.  This
  1337  // includes checks which depend on tallying the results of votes, because votes
  1338  // are part of the block data.
  1339  //
  1340  // It should be noted that rule changes that have become buried deep enough
  1341  // typically will eventually be transitioned to using well-known activation
  1342  // points for efficiency purposes at which point the associated checks no longer
  1343  // require having direct access to the historical votes, and therefore may be
  1344  // transitioned to checkBlockPositional at that time.  Conversely, any checks
  1345  // in that function which become conditional based on the results of a vote will
  1346  // necessarily need to be transitioned to this function.
  1347  //
  1348  // The flags modify the behavior of this function as follows:
  1349  //  - BFFastAdd: The max block size is not checked, transactions are not checked
  1350  //    to see if they are finalized, and the included votes and revocations are
  1351  //    not verified to be allowed.
  1352  //
  1353  // The flags are also passed to checkBlockHeaderContext.  See its documentation
  1354  // for how the flags modify its behavior.
  1355  func (b *BlockChain) checkBlockContext(block *dcrutil.Block, prevNode *blockNode, flags BehaviorFlags) error {
  1356  	// The genesis block is valid by definition.
  1357  	if prevNode == nil {
  1358  		return nil
  1359  	}
  1360  
  1361  	// Perform all block header related validation checks which depend on
  1362  	// having the full block data for all of its ancestors available.
  1363  	header := &block.MsgBlock().Header
  1364  	err := b.checkBlockHeaderContext(header, prevNode, flags)
  1365  	if err != nil {
  1366  		return err
  1367  	}
  1368  
  1369  	fastAdd := flags&BFFastAdd == BFFastAdd
  1370  	if !fastAdd {
  1371  		// A block must not exceed the maximum allowed size as defined
  1372  		// by the network parameters and the current status of any hard
  1373  		// fork votes to change it when serialized.
  1374  		maxBlockSize, err := b.maxBlockSize(prevNode)
  1375  		if err != nil {
  1376  			return err
  1377  		}
  1378  		serializedSize := int64(block.MsgBlock().Header.Size)
  1379  		if serializedSize > maxBlockSize {
  1380  			str := fmt.Sprintf("serialized block is too big - "+
  1381  				"got %d, max %d", serializedSize,
  1382  				maxBlockSize)
  1383  			return ruleError(ErrBlockTooBig, str)
  1384  		}
  1385  
  1386  		// Switch to using the past median time of the block prior to
  1387  		// the block being checked for all checks related to lock times
  1388  		// once the stake vote for the agenda is active.
  1389  		blockTime := header.Timestamp
  1390  		lnFeaturesActive, err := b.isLNFeaturesAgendaActive(prevNode)
  1391  		if err != nil {
  1392  			return err
  1393  		}
  1394  		if lnFeaturesActive {
  1395  			blockTime = prevNode.CalcPastMedianTime()
  1396  		}
  1397  
  1398  		// The height of this block is one more than the referenced
  1399  		// previous block.
  1400  		blockHeight := prevNode.height + 1
  1401  
  1402  		// Ensure all transactions in the block are finalized.
  1403  		for _, tx := range block.Transactions() {
  1404  			if !IsFinalizedTransaction(tx, blockHeight, blockTime) {
  1405  				str := fmt.Sprintf("block contains unfinalized regular "+
  1406  					"transaction %v", tx.Hash())
  1407  				return ruleError(ErrUnfinalizedTx, str)
  1408  			}
  1409  		}
  1410  		for _, stx := range block.STransactions() {
  1411  			if !IsFinalizedTransaction(stx, blockHeight, blockTime) {
  1412  				str := fmt.Sprintf("block contains unfinalized stake "+
  1413  					"transaction %v", stx.Hash())
  1414  				return ruleError(ErrUnfinalizedTx, str)
  1415  			}
  1416  		}
  1417  
  1418  		// Ensure that all votes are only for winning tickets and all
  1419  		// revocations are actually eligible to be revoked once stake
  1420  		// validation height has been reached.
  1421  		if blockHeight >= b.chainParams.StakeValidationHeight {
  1422  			parentStakeNode, err := b.fetchStakeNode(prevNode)
  1423  			if err != nil {
  1424  				return err
  1425  			}
  1426  			err = b.checkAllowedVotes(parentStakeNode, block.MsgBlock())
  1427  			if err != nil {
  1428  				return err
  1429  			}
  1430  
  1431  			err = b.checkAllowedRevocations(parentStakeNode,
  1432  				block.MsgBlock())
  1433  			if err != nil {
  1434  				return err
  1435  			}
  1436  		}
  1437  	}
  1438  
  1439  	return nil
  1440  }
  1441  
  1442  // checkDupTxs ensures blocks do not contain duplicate transactions which
  1443  // 'overwrite' older transactions that are not fully spent.  This prevents an
  1444  // attack where a coinbase and all of its dependent transactions could be
  1445  // duplicated to effectively revert the overwritten transactions to a single
  1446  // confirmation thereby making them vulnerable to a double spend.
  1447  //
  1448  // For more details, see https://en.bitcoin.it/wiki/BIP_0030 and
  1449  // http://r6.ca/blog/20120206T005236Z.html.
  1450  //
  1451  // Decred: Check the stake transactions to make sure they don't have this txid
  1452  // too.
  1453  func (b *BlockChain) checkDupTxs(txSet []*dcrutil.Tx, view *UtxoViewpoint) error {
  1454  	if !chaincfg.CheckForDuplicateHashes {
  1455  		return nil
  1456  	}
  1457  
  1458  	// Fetch utxo details for all of the transactions in this block.
  1459  	// Typically, there will not be any utxos for any of the transactions.
  1460  	filteredSet := make(viewFilteredSet)
  1461  	for _, tx := range txSet {
  1462  		filteredSet.add(view, tx.Hash())
  1463  	}
  1464  	err := view.fetchUtxosMain(b.db, filteredSet)
  1465  	if err != nil {
  1466  		return err
  1467  	}
  1468  
  1469  	// Duplicate transactions are only allowed if the previous transaction
  1470  	// is fully spent.
  1471  	for _, tx := range txSet {
  1472  		txEntry := view.LookupEntry(tx.Hash())
  1473  		if txEntry != nil && !txEntry.IsFullySpent() {
  1474  			str := fmt.Sprintf("tried to overwrite transaction %v "+
  1475  				"at block height %d that is not fully spent",
  1476  				tx.Hash(), txEntry.BlockHeight())
  1477  			return ruleError(ErrOverwriteTx, str)
  1478  		}
  1479  	}
  1480  
  1481  	return nil
  1482  }
  1483  
  1484  // extractStakePubKeyHash extracts a pubkey hash from the passed public key
  1485  // script if it is a standard pay-to-pubkey-hash script tagged with the provided
  1486  // stake opcode.  It will return nil otherwise.
  1487  func extractStakePubKeyHash(script []byte, stakeOpcode byte) []byte {
  1488  	if len(script) == 26 &&
  1489  		script[0] == stakeOpcode &&
  1490  		script[1] == txscript.OP_DUP &&
  1491  		script[2] == txscript.OP_HASH160 &&
  1492  		script[3] == txscript.OP_DATA_20 &&
  1493  		script[24] == txscript.OP_EQUALVERIFY &&
  1494  		script[25] == txscript.OP_CHECKSIG {
  1495  
  1496  		return script[4:24]
  1497  	}
  1498  
  1499  	return nil
  1500  }
  1501  
  1502  // isStakePubKeyHash returns whether or not the passed public key script is a
  1503  // standard pay-to-pubkey-hash script tagged with the provided stake opcode.
  1504  func isStakePubKeyHash(script []byte, stakeOpcode byte) bool {
  1505  	return extractStakePubKeyHash(script, stakeOpcode) != nil
  1506  }
  1507  
  1508  // extractStakeScriptHash extracts a script hash from the passed public key
  1509  // script if it is a standard pay-to-script-hash script tagged with the provided
  1510  // stake opcode.  It will return nil otherwise.
  1511  func extractStakeScriptHash(script []byte, stakeOpcode byte) []byte {
  1512  	if len(script) == 24 &&
  1513  		script[0] == stakeOpcode &&
  1514  		script[1] == txscript.OP_HASH160 &&
  1515  		script[2] == txscript.OP_DATA_20 &&
  1516  		script[23] == txscript.OP_EQUAL {
  1517  
  1518  		return script[3:23]
  1519  	}
  1520  
  1521  	return nil
  1522  }
  1523  
  1524  // isStakeScriptHash returns whether or not the passed public key script is a
  1525  // standard pay-to-script-hash script tagged with the provided stake opcode.
  1526  func isStakeScriptHash(script []byte, stakeOpcode byte) bool {
  1527  	return extractStakeScriptHash(script, stakeOpcode) != nil
  1528  }
  1529  
  1530  // isAllowedTicketInputScriptForm returns whether or not the passed public key
  1531  // script is a one of the allowed forms for a ticket input.
  1532  func isAllowedTicketInputScriptForm(script []byte) bool {
  1533  	return isPubKeyHash(script) || isScriptHash(script) ||
  1534  		isStakePubKeyHash(script, txscript.OP_SSGEN) ||
  1535  		isStakeScriptHash(script, txscript.OP_SSGEN) ||
  1536  		isStakePubKeyHash(script, txscript.OP_SSRTX) ||
  1537  		isStakeScriptHash(script, txscript.OP_SSRTX) ||
  1538  		isStakePubKeyHash(script, txscript.OP_SSTXCHANGE) ||
  1539  		isStakeScriptHash(script, txscript.OP_SSTXCHANGE)
  1540  }
  1541  
  1542  // extractTicketCommitAmount extracts and decodes the amount from a ticket
  1543  // output commitment script.
  1544  //
  1545  // NOTE: The caller MUST have already determined that the provided script is
  1546  // a commitment output script or the function may panic.
  1547  func extractTicketCommitAmount(script []byte) int64 {
  1548  	// Extract the encoded amount from the commitment output associated with
  1549  	// the input.  The MSB of the encoded amount specifies if the output is
  1550  	// P2SH, so it must be cleared to get the decoded amount.
  1551  	amtBytes := script[commitAmountStartIdx:commitAmountEndIdx]
  1552  	amtEncoded := binary.LittleEndian.Uint64(amtBytes)
  1553  	return int64(amtEncoded & ^commitP2SHFlag)
  1554  }
  1555  
  1556  // checkTicketPurchaseInputs performs a series of checks on the inputs to a
  1557  // ticket purchase transaction.  An example of some of the checks include
  1558  // verifying all inputs exist, ensuring the input type requirements are met,
  1559  // and validating the output commitments coincide with the inputs.
  1560  //
  1561  // NOTE: The caller MUST have already determined that the provided transaction
  1562  // is a ticket purchase.
  1563  func checkTicketPurchaseInputs(msgTx *wire.MsgTx, view *UtxoViewpoint) error {
  1564  	// Assert there are two outputs for each input to the ticket as well as the
  1565  	// additional voting rights output.
  1566  	if (len(msgTx.TxIn)*2 + 1) != len(msgTx.TxOut) {
  1567  		panicf("attempt to check ticket purchase inputs on tx %s which does "+
  1568  			"not appear to be a ticket purchase (%d inputs, %d outputs)",
  1569  			msgTx.TxHash(), len(msgTx.TxIn), len(msgTx.TxOut))
  1570  	}
  1571  
  1572  	for txInIdx := 0; txInIdx < len(msgTx.TxIn); txInIdx++ {
  1573  		txIn := msgTx.TxIn[txInIdx]
  1574  		originTxHash := &txIn.PreviousOutPoint.Hash
  1575  		originTxIndex := txIn.PreviousOutPoint.Index
  1576  		entry := view.LookupEntry(originTxHash)
  1577  		if entry == nil || entry.IsOutputSpent(originTxIndex) {
  1578  			str := fmt.Sprintf("output %v referenced from transaction %s:%d "+
  1579  				"either does not exist or has already been spent",
  1580  				txIn.PreviousOutPoint, msgTx.TxHash(), txInIdx)
  1581  			return ruleError(ErrMissingTxOut, str)
  1582  		}
  1583  
  1584  		// Ensure the output being spent is one of the allowed script forms.  In
  1585  		// particular, the allowed forms are pay-to-pubkey-hash and
  1586  		// pay-to-script-hash either in the standard form (without a stake
  1587  		// opcode) or their stake-tagged variant (with a stake opcode).
  1588  		pkScriptVer := entry.ScriptVersionByIndex(originTxIndex)
  1589  		if pkScriptVer != 0 {
  1590  			str := fmt.Sprintf("output %v script version %d referenced by "+
  1591  				"ticket %s:%d is not supported", txIn.PreviousOutPoint,
  1592  				pkScriptVer, msgTx.TxHash(), txInIdx)
  1593  			return ruleError(ErrTicketInputScript, str)
  1594  		}
  1595  		pkScript := entry.PkScriptByIndex(originTxIndex)
  1596  		if !isAllowedTicketInputScriptForm(pkScript) {
  1597  			str := fmt.Sprintf("output %v referenced from ticket %s:%d "+
  1598  				"is not pay-to-pubkey-hash or pay-to-script-hash (script: %x)",
  1599  				txIn.PreviousOutPoint, msgTx.TxHash(), txInIdx, pkScript)
  1600  			return ruleError(ErrTicketInputScript, str)
  1601  		}
  1602  
  1603  		// Extract the amount from the commitment output associated with the
  1604  		// input and ensure it matches the expected amount calculated from the
  1605  		// actual input amount and change.
  1606  		commitmentOutIdx := txInIdx*2 + 1
  1607  		commitmentScript := msgTx.TxOut[commitmentOutIdx].PkScript
  1608  		commitmentAmount := extractTicketCommitAmount(commitmentScript)
  1609  		inputAmount := entry.AmountByIndex(originTxIndex)
  1610  		change := msgTx.TxOut[commitmentOutIdx+1].Value
  1611  		adjustedAmount := commitmentAmount + change
  1612  		if adjustedAmount != inputAmount {
  1613  			str := fmt.Sprintf("ticket output %d pays a different amount than "+
  1614  				"the associated input %d (input: %v, commitment: %v, change: "+
  1615  				"%v)", commitmentOutIdx, txInIdx, inputAmount, commitmentAmount,
  1616  				change)
  1617  			return ruleError(ErrTicketCommitment, str)
  1618  		}
  1619  	}
  1620  
  1621  	return nil
  1622  }
  1623  
  1624  // isStakeSubmission returns whether or not the passed public key script is a
  1625  // standard pay-to-script-hash or pay-to-script-hash script tagged with the
  1626  // stake submission opcode.
  1627  func isStakeSubmission(script []byte) bool {
  1628  	return isStakePubKeyHash(script, txscript.OP_SSTX) ||
  1629  		isStakeScriptHash(script, txscript.OP_SSTX)
  1630  }
  1631  
  1632  // extractTicketCommitHash extracts the commitment hash from a ticket output
  1633  // commitment script.
  1634  //
  1635  // NOTE: The caller MUST have already determined that the provided script is
  1636  // a commitment output script or the function may panic.
  1637  func extractTicketCommitHash(script []byte) []byte {
  1638  	return script[commitHashStartIdx:commitHashEndIdx]
  1639  }
  1640  
  1641  // isTicketCommitP2SH returns whether or not the passed ticket output commitment
  1642  // script commits to a hash which represents a pay-to-script-hash output.  When
  1643  // false, it commits to a hash which represents a pay-to-pubkey-hash output.
  1644  //
  1645  // NOTE: The caller MUST have already determined that the provided script is
  1646  // a commitment output script or the function may panic.
  1647  func isTicketCommitP2SH(script []byte) bool {
  1648  	// The MSB of the encoded amount specifies if the output is P2SH.  Since
  1649  	// it is encoded with little endian, the MSB is in final byte in the encoded
  1650  	// amount.
  1651  	//
  1652  	// This is a faster equivalent of:
  1653  	//
  1654  	//	amtBytes := script[commitAmountStartIdx:commitAmountEndIdx]
  1655  	//	amtEncoded := binary.LittleEndian.Uint64(amtBytes)
  1656  	//	return (amtEncoded & commitP2SHFlag) != 0
  1657  	//
  1658  	return script[commitAmountEndIdx-1]&0x80 != 0
  1659  }
  1660  
  1661  // calcTicketReturnAmount calculates the required amount to return from a ticket
  1662  // for a given original contribution amount, the price the ticket was purchased
  1663  // for, the vote subsidy (if any) to include, and the sum of all contributions
  1664  // used to purchase the ticket.
  1665  //
  1666  // Since multiple inputs can be used to purchase a ticket, each one contributes
  1667  // a portion of the overall ticket purchase, including the transaction fee.
  1668  // Thus, when claiming the ticket, either due to it being selected to vote, or
  1669  // being revoked, each output must receive the same proportion of the total
  1670  // amount returned.
  1671  //
  1672  // The vote subsidy must be 0 for revocations since, unlike votes, they do not
  1673  // produce any additional subsidy.
  1674  func calcTicketReturnAmount(contribAmount, ticketPurchaseAmount, voteSubsidy int64, contributionSumBig *big.Int) int64 {
  1675  	// This is effectively equivalent to:
  1676  	//
  1677  	//                  total output amount
  1678  	// return amount =  ------------------- * contribution amount
  1679  	//                  total contributions
  1680  	//
  1681  	// However, in order to avoid floating point math, it uses 64.32 fixed point
  1682  	// integer division to perform:
  1683  	//
  1684  	//                   --                                              --
  1685  	//                  | total output amount * contribution amount * 2^32 |
  1686  	//                  | ------------------------------------------------ |
  1687  	// return amount =  |                total contributions               |
  1688  	//                   --                                              --
  1689  	//                  ----------------------------------------------------
  1690  	//                                        2^32
  1691  	//
  1692  	totalOutputAmtBig := big.NewInt(ticketPurchaseAmount + voteSubsidy)
  1693  	returnAmtBig := big.NewInt(contribAmount)
  1694  	returnAmtBig.Mul(returnAmtBig, totalOutputAmtBig)
  1695  	returnAmtBig.Lsh(returnAmtBig, 32)
  1696  	returnAmtBig.Div(returnAmtBig, contributionSumBig)
  1697  	returnAmtBig.Rsh(returnAmtBig, 32)
  1698  	return returnAmtBig.Int64()
  1699  }
  1700  
  1701  // extractTicketCommitFeeLimits extracts the encoded fee limits from a ticket
  1702  // output commitment script.
  1703  //
  1704  // NOTE: The caller MUST have already determined that the provided script is
  1705  // a commitment output script or the function may panic.
  1706  func extractTicketCommitFeeLimits(script []byte) uint16 {
  1707  	encodedLimits := script[commitFeeLimitStartIdx:commitFeeLimitEndIdx]
  1708  	return binary.LittleEndian.Uint16(encodedLimits)
  1709  }
  1710  
  1711  // checkTicketSubmissionInput ensures the provided unspent transaction output is
  1712  // a supported ticket submission output in terms of the script version and type
  1713  // as well as ensuring the transaction that houses the output is a ticket.
  1714  //
  1715  // Note that the returned error is not a RuleError, so the it is up to the
  1716  // caller convert it accordingly.
  1717  func checkTicketSubmissionInput(ticketUtxo *UtxoEntry) error {
  1718  	submissionScriptVer := ticketUtxo.ScriptVersionByIndex(submissionOutputIdx)
  1719  	if submissionScriptVer != 0 {
  1720  		return fmt.Errorf("script version %d is not supported",
  1721  			submissionScriptVer)
  1722  	}
  1723  	submissionScript := ticketUtxo.PkScriptByIndex(submissionOutputIdx)
  1724  	if !isStakeSubmission(submissionScript) {
  1725  		return fmt.Errorf("not a supported stake submission script (script: "+
  1726  			"%x)", submissionScript)
  1727  	}
  1728  
  1729  	// Ensure the referenced output is from a ticket.  This also proves the form
  1730  	// of the transaction and its outputs are as expected so subsequent code is
  1731  	// able to avoid a lot of additional overhead rechecking things.
  1732  	if ticketUtxo.TransactionType() != stake.TxTypeSStx {
  1733  		return fmt.Errorf("not a submission script")
  1734  	}
  1735  
  1736  	return nil
  1737  }
  1738  
  1739  // checkTicketRedeemerCommitments ensures the outputs of the provided
  1740  // transaction, which MUST be either a vote or revocation, adhere to the
  1741  // commitments in the provided ticket outputs.  The vote subsidy MUST be zero
  1742  // for revocations since they do not produce any additional subsidy.
  1743  //
  1744  // NOTE: This is only intended to be a helper to refactor out common code from
  1745  // checkVoteInputs and checkRevocationInputs.
  1746  func checkTicketRedeemerCommitments(ticketHash *chainhash.Hash, ticketOuts []*stake.MinimalOutput, msgTx *wire.MsgTx, isVote bool, voteSubsidy int64) error {
  1747  	// Make an initial pass over the ticket commitments to calculate the overall
  1748  	// contribution sum.  This is necessary because the output amounts are
  1749  	// required to be scaled to maintain the same proportions as the original
  1750  	// contributions to the ticket, and the overall contribution sum is needed
  1751  	// to calculate those proportions.
  1752  	//
  1753  	// The calculations also require more than 64-bits, so convert it to a big
  1754  	// integer here to avoid multiple conversions later.
  1755  	var contributionSum int64
  1756  	for i := 1; i < len(ticketOuts); i += 2 {
  1757  		contributionSum += extractTicketCommitAmount(ticketOuts[i].PkScript)
  1758  	}
  1759  	contributionSumBig := big.NewInt(contributionSum)
  1760  
  1761  	// The outputs that satisify the commitments of the ticket start at offset
  1762  	// 2 for votes while they start at 0 for revocations.  Also, the payments
  1763  	// must be tagged with the appropriate stake opcode depending on whether it
  1764  	// is a vote or a revocation.  Finally, the fee limits in the original
  1765  	// ticket commitment differ for votes and revocations, so choose the correct
  1766  	// bit flag and mask accordingly.
  1767  	startIdx := 2
  1768  	reqStakeOpcode := byte(txscript.OP_SSGEN)
  1769  	hasFeeLimitFlag := uint16(stake.SStxVoteFractionFlag)
  1770  	feeLimitMask := uint16(stake.SStxVoteReturnFractionMask)
  1771  	if !isVote {
  1772  		startIdx = 0
  1773  		reqStakeOpcode = txscript.OP_SSRTX
  1774  		hasFeeLimitFlag = stake.SStxRevFractionFlag
  1775  		feeLimitMask = stake.SStxRevReturnFractionMask
  1776  	}
  1777  	ticketPaidAmt := ticketOuts[submissionOutputIdx].Value
  1778  	for txOutIdx := startIdx; txOutIdx < len(msgTx.TxOut); txOutIdx++ {
  1779  		// Ensure the output is paying to the address and type specified by the
  1780  		// original commitment in the ticket and is a version 0 script.
  1781  		//
  1782  		// Note that this specifically limits the types of allowed outputs to
  1783  		// P2PKH and P2SH, since the original commitment has the same
  1784  		// limitation.
  1785  		txOut := msgTx.TxOut[txOutIdx]
  1786  		if txOut.Version != 0 {
  1787  			str := fmt.Sprintf("output %s:%d script version %d is not "+
  1788  				"supported", msgTx.TxHash(), txOutIdx, txOut.Version)
  1789  			return ruleError(ErrBadPayeeScriptVersion, str)
  1790  		}
  1791  
  1792  		commitmentOutIdx := (txOutIdx-startIdx)*2 + 1
  1793  		commitmentScript := ticketOuts[commitmentOutIdx].PkScript
  1794  		var paymentHash []byte
  1795  		if isTicketCommitP2SH(commitmentScript) {
  1796  			paymentHash = extractStakeScriptHash(txOut.PkScript, reqStakeOpcode)
  1797  			if paymentHash == nil {
  1798  				str := fmt.Sprintf("output %s:%d payment script type is not "+
  1799  					"pay-to-script-hash as required by ticket output "+
  1800  					"commitment %s:%d", msgTx.TxHash(), txOutIdx, ticketHash,
  1801  					commitmentOutIdx)
  1802  				return ruleError(ErrBadPayeeScriptType, str)
  1803  			}
  1804  		} else {
  1805  			paymentHash = extractStakePubKeyHash(txOut.PkScript, reqStakeOpcode)
  1806  			if paymentHash == nil {
  1807  				str := fmt.Sprintf("output %s:%d payment script type is not "+
  1808  					"pay-to-pubkey-hash as required by ticket output "+
  1809  					"commitment %s:%d", msgTx.TxHash(), txOutIdx, ticketHash,
  1810  					commitmentOutIdx)
  1811  				return ruleError(ErrBadPayeeScriptType, str)
  1812  			}
  1813  		}
  1814  		commitmentHash := extractTicketCommitHash(commitmentScript)
  1815  		if !bytes.Equal(paymentHash, commitmentHash) {
  1816  			str := fmt.Sprintf("output %s:%d does not pay to the hash "+
  1817  				"specified by ticket output commitment %s:%d (ticket commits "+
  1818  				"to %x, output pays %x)", msgTx.TxHash(), txOutIdx, ticketHash,
  1819  				commitmentOutIdx, commitmentHash, paymentHash)
  1820  			return ruleError(ErrMismatchedPayeeHash, str)
  1821  		}
  1822  
  1823  		// Calculate the required payment amount for the output based on the
  1824  		// relative percentage of the associated contribution to the original
  1825  		// ticket and any additional subsidy produced by the vote (must be 0 for
  1826  		// revocations).
  1827  		//
  1828  		// It should be noted that, due to the scaling, the sum of the generated
  1829  		// amounts for mult-participant votes might be a few atoms less than
  1830  		// the full amount and the difference is treated as a standard
  1831  		// transaction fee.
  1832  		commitmentAmt := extractTicketCommitAmount(commitmentScript)
  1833  		expectedOutAmt := calcTicketReturnAmount(commitmentAmt, ticketPaidAmt,
  1834  			voteSubsidy, contributionSumBig)
  1835  
  1836  		// Ensure the amount paid adheres to the commitment while taking into
  1837  		// account any fee limits that might be imposed.  The output amount must
  1838  		// exactly match the calculated amount when when not encumbered with a
  1839  		// fee limit.  On the other hand, when it is encumbered, it must be
  1840  		// between the minimum amount imposed by the fee limit and the
  1841  		// calculated amount.
  1842  		feeLimitsEncoded := extractTicketCommitFeeLimits(commitmentScript)
  1843  		hasFeeLimit := feeLimitsEncoded&hasFeeLimitFlag != 0
  1844  		if !hasFeeLimit {
  1845  			// The output amount must exactly match the calculated amount when
  1846  			// not encumbered with a fee limit.
  1847  			if txOut.Value != expectedOutAmt {
  1848  				str := fmt.Sprintf("output %s:%d does not pay the expected "+
  1849  					"amount per ticket output commitment %s:%d (expected %d, "+
  1850  					"output pays %d)", msgTx.TxHash(), txOutIdx, ticketHash, // PROBLEM:  ticketHash...
  1851  					commitmentOutIdx, expectedOutAmt, txOut.Value)
  1852  				return ruleError(ErrBadPayeeValue, str)
  1853  			}
  1854  		} else {
  1855  			// Calculate the minimum allowed amount based on the fee limit.
  1856  			//
  1857  			// Notice that, since the fee limit is in terms of a log2 value, and
  1858  			// amounts are int64, anything greater than or equal to 63 is
  1859  			// interpreted to mean allow spending the entire amount as a fee.
  1860  			// This allows fast left shifts to be used to calculate the fee
  1861  			// limit while preventing degenerate cases such as negative numbers
  1862  			// for 63.
  1863  			var amtLimitLow int64
  1864  			feeLimitLog2 := feeLimitsEncoded & feeLimitMask
  1865  			if feeLimitLog2 < 63 {
  1866  				feeLimit := int64(1 << uint64(feeLimitLog2))
  1867  				if feeLimit < expectedOutAmt {
  1868  					amtLimitLow = expectedOutAmt - feeLimit
  1869  				}
  1870  			}
  1871  
  1872  			// The output must not be less than the minimum amount.
  1873  			if txOut.Value < amtLimitLow {
  1874  				str := fmt.Sprintf("output %s:%d pays less than the expected "+
  1875  					"expected amount per ticket output commitment %s:%d "+
  1876  					"(lowest allowed %d, output pays %d)", msgTx.TxHash(),
  1877  					txOutIdx, ticketHash, commitmentOutIdx, amtLimitLow, // PROBLEM:  ticketHash...
  1878  					txOut.Value)
  1879  				return ruleError(ErrBadPayeeValue, str)
  1880  			}
  1881  
  1882  			// The output must not be more than the expected amount.
  1883  			if txOut.Value > expectedOutAmt {
  1884  				str := fmt.Sprintf("output %s:%d pays more than the expected "+
  1885  					"amount per ticket output commitment %s:%d (expected %d, "+
  1886  					"output pays %d)", msgTx.TxHash(), txOutIdx, ticketHash,
  1887  					commitmentOutIdx, expectedOutAmt, txOut.Value)
  1888  				return ruleError(ErrBadPayeeValue, str)
  1889  			}
  1890  		}
  1891  	}
  1892  
  1893  	return nil
  1894  }
  1895  
  1896  // checkVoteInputs performs a series of checks on the inputs to a vote
  1897  // transaction.  An example of some of the checks include verifying the
  1898  // referenced ticket exists, the stakebase input commits to correct subsidy,
  1899  // the output amounts adhere to the commitments of the referenced ticket, and
  1900  // the ticket maturity requirements are met.
  1901  //
  1902  // NOTE: The caller MUST have already determined that the provided transaction
  1903  // is a vote.
  1904  func checkVoteInputs(subsidyCache *standalone.SubsidyCache, tx *dcrutil.Tx, txHeight int64, view *UtxoViewpoint, params *chaincfg.Params) error {
  1905  	ticketMaturity := int64(params.TicketMaturity)
  1906  	voteHash := tx.Hash()
  1907  	msgTx := tx.MsgTx()
  1908  
  1909  	// Calculate the theoretical stake vote subsidy by extracting the vote
  1910  	// height.
  1911  	//
  1912  	// WARNING: This really should be calculating the subsidy based on the
  1913  	// height of the block the vote is contained in as opposed to the block it
  1914  	// is voting on.  Unfortunately, this is now part of consensus, so changing
  1915  	// it requires a hard fork vote.
  1916  	_, heightVotingOn := stake.SSGenBlockVotedOn(msgTx)
  1917  	voteSubsidy := subsidyCache.CalcStakeVoteSubsidy(int64(heightVotingOn))
  1918  
  1919  	// The input amount specified by the stakebase must commit to the subsidy
  1920  	// generated by the vote.
  1921  	stakebase := msgTx.TxIn[0]
  1922  	if stakebase.ValueIn != voteSubsidy {
  1923  		str := fmt.Sprintf("vote subsidy input value of %v is not %v",
  1924  			stakebase.ValueIn, voteSubsidy)
  1925  		return ruleError(ErrBadStakebaseAmountIn, str)
  1926  	}
  1927  
  1928  	// The second input to a vote must be the first output of the ticket the
  1929  	// vote is associated with.
  1930  	const ticketInIdx = 1
  1931  	ticketIn := msgTx.TxIn[ticketInIdx]
  1932  	if ticketIn.PreviousOutPoint.Index != submissionOutputIdx {
  1933  		str := fmt.Sprintf("vote %s:%d references output %d instead of the "+
  1934  			"first output", voteHash, ticketInIdx,
  1935  			ticketIn.PreviousOutPoint.Index)
  1936  		return ruleError(ErrInvalidVoteInput, str)
  1937  	}
  1938  
  1939  	// Ensure the referenced ticket is available.
  1940  	ticketHash := &ticketIn.PreviousOutPoint.Hash
  1941  	ticketUtxo := view.LookupEntry(ticketHash)
  1942  	if ticketUtxo == nil || ticketUtxo.IsFullySpent() {
  1943  		str := fmt.Sprintf("ticket output %v referenced by vote %s:%d  either "+
  1944  			"does not exist or has already been spent",
  1945  			ticketIn.PreviousOutPoint, voteHash, ticketInIdx)
  1946  		return ruleError(ErrMissingTxOut, str)
  1947  	}
  1948  
  1949  	// Ensure the referenced transaction output is a supported ticket submission
  1950  	// output in terms of the script version and type as well as ensuring the
  1951  	// transaction that houses the output is a ticket.  This also proves the
  1952  	// form of the transaction and its outputs are as expected so subsequent
  1953  	// code is able to avoid a lot of additional overhead rechecking things.
  1954  	if err := checkTicketSubmissionInput(ticketUtxo); err != nil {
  1955  		str := fmt.Sprintf("output %v referenced by vote %s:%d consensus "+
  1956  			"violation: %s", ticketIn.PreviousOutPoint, voteHash, ticketInIdx,
  1957  			err.Error())
  1958  		return ruleError(ErrInvalidVoteInput, str)
  1959  	}
  1960  
  1961  	// Ensure the vote is not spending a ticket which has not yet reached the
  1962  	// required ticket maturity.
  1963  	//
  1964  	// NOTE: A ticket stake submission (OP_SSTX tagged output) can only be spent
  1965  	// in the block AFTER the entire ticket maturity has passed, hence the +1.
  1966  	originHeight := ticketUtxo.BlockHeight()
  1967  	blocksSincePrev := txHeight - originHeight
  1968  	if blocksSincePrev < ticketMaturity+1 {
  1969  		str := fmt.Sprintf("tried to spend ticket output from transaction "+
  1970  			"%v from height %d at height %d before required ticket maturity "+
  1971  			"of %d+1 blocks", ticketHash, originHeight, txHeight,
  1972  			ticketMaturity)
  1973  		return ruleError(ErrImmatureTicketSpend, str)
  1974  	}
  1975  
  1976  	ticketOuts := ConvertUtxosToMinimalOutputs(ticketUtxo)
  1977  	if len(ticketOuts) == 0 {
  1978  		panicf("missing extra stake data for ticket %v -- probable database "+
  1979  			"corruption", ticketHash)
  1980  	}
  1981  
  1982  	// Ensure the number of payment outputs matches the number of commitments
  1983  	// made by the associated ticket.
  1984  	//
  1985  	// The vote transaction outputs must consist of an OP_RETURN output that
  1986  	// indicates the block being voted on, an OP_RETURN with the user-provided
  1987  	// vote bits, and an output that corresponds to every commitment output in
  1988  	// the ticket associated with the vote.  The associated ticket outputs
  1989  	// consist of a stake submission output, and two outputs for each payment
  1990  	// commitment such that the first one of the pair is a commitment amount and
  1991  	// the second one is the amount of change sent back to the contributor to
  1992  	// the ticket based on their original funding amount.
  1993  	numVotePayments := len(msgTx.TxOut) - 2
  1994  	if numVotePayments*2 != len(ticketOuts)-1 {
  1995  		str := fmt.Sprintf("vote %s makes %d payments when input ticket %s "+
  1996  			"has %d commitments", voteHash, numVotePayments, ticketHash,
  1997  			len(ticketOuts)-1)
  1998  		return ruleError(ErrBadNumPayees, str)
  1999  	}
  2000  
  2001  	// Ensure the outputs adhere to the ticket commitments.
  2002  	return checkTicketRedeemerCommitments(ticketHash, ticketOuts, msgTx, true,
  2003  		voteSubsidy)
  2004  }
  2005  
  2006  // checkRevocationInputs performs a series of checks on the inputs to a
  2007  // revocation transaction.  An example of some of the checks include verifying
  2008  // the referenced ticket exists, the output amounts adhere to the commitments of
  2009  // the ticket, and the ticket maturity requirements are met.
  2010  //
  2011  // NOTE: The caller MUST have already determined that the provided transaction
  2012  // is a revocation.
  2013  func checkRevocationInputs(tx *dcrutil.Tx, txHeight int64, view *UtxoViewpoint, params *chaincfg.Params) error {
  2014  	ticketMaturity := int64(params.TicketMaturity)
  2015  	revokeHash := tx.Hash()
  2016  	msgTx := tx.MsgTx()
  2017  
  2018  	// The first input to a revocation must be the first output of the ticket
  2019  	// the revocation is associated with.
  2020  	const ticketInIdx = 0
  2021  	ticketIn := msgTx.TxIn[ticketInIdx]
  2022  	if ticketIn.PreviousOutPoint.Index != submissionOutputIdx {
  2023  		str := fmt.Sprintf("revocation %s:%d references output %d instead of "+
  2024  			"the first output", revokeHash, ticketInIdx,
  2025  			ticketIn.PreviousOutPoint.Index)
  2026  		return ruleError(ErrInvalidRevokeInput, str)
  2027  	}
  2028  
  2029  	// Ensure the referenced ticket is available.
  2030  	ticketHash := &ticketIn.PreviousOutPoint.Hash
  2031  	ticketUtxo := view.LookupEntry(ticketHash)
  2032  	if ticketUtxo == nil || ticketUtxo.IsFullySpent() {
  2033  		str := fmt.Sprintf("ticket output %v referenced from revocation %s:%d "+
  2034  			"either does not exist or has already been spent",
  2035  			ticketIn.PreviousOutPoint, revokeHash, ticketInIdx)
  2036  		return ruleError(ErrMissingTxOut, str)
  2037  	}
  2038  
  2039  	// Ensure the referenced transaction output is a supported ticket submission
  2040  	// output in terms of the script version and type as well as ensuring the
  2041  	// transaction that houses the output is a ticket.  This also proves the
  2042  	// form of the transaction and its outputs are as expected so subsequent
  2043  	// code is able to avoid a lot of additional overhead rechecking things.
  2044  	if err := checkTicketSubmissionInput(ticketUtxo); err != nil {
  2045  		str := fmt.Sprintf("output %v referenced by revocation %s:%d consensus "+
  2046  			"violation: %s", ticketIn.PreviousOutPoint, revokeHash, ticketInIdx,
  2047  			err.Error())
  2048  		return ruleError(ErrInvalidRevokeInput, str)
  2049  	}
  2050  
  2051  	// Ensure the revocation is not spending a ticket which has not yet reached
  2052  	// the required ticket maturity.
  2053  	//
  2054  	// NOTE: A ticket stake submission (OP_SSTX tagged output) can only be spent
  2055  	// in the block AFTER the entire ticket maturity has passed, and, in order
  2056  	// to be revoked, the ticket must have been missed which can't possibly
  2057  	// happen for another block after that, hence the +2.
  2058  	originHeight := ticketUtxo.BlockHeight()
  2059  	blocksSincePrev := txHeight - originHeight
  2060  	if blocksSincePrev < ticketMaturity+2 {
  2061  		str := fmt.Sprintf("tried to spend ticket output from transaction "+
  2062  			"%v from height %d at height %d before required ticket maturity "+
  2063  			"of %d+2 blocks", ticketHash, originHeight, txHeight,
  2064  			ticketMaturity)
  2065  		return ruleError(ErrImmatureTicketSpend, str)
  2066  	}
  2067  
  2068  	ticketOuts := ConvertUtxosToMinimalOutputs(ticketUtxo)
  2069  	if len(ticketOuts) == 0 {
  2070  		panicf("missing extra stake data for ticket %v -- probable database "+
  2071  			"corruption", ticketHash)
  2072  	}
  2073  
  2074  	// Ensure the number of payment outputs matches the number of commitments
  2075  	// made by the associated ticket.
  2076  	//
  2077  	// The revocation transaction outputs must consist of an output that
  2078  	// corresponds to every commitment output in the ticket associated with the
  2079  	// revocation.  The associated ticket outputs consist of a stake submission
  2080  	// output, and two outputs for each payment commitment such that the first
  2081  	// one of the pair is a commitment amount and the second one is the amount
  2082  	// of change sent back to the contributor to the ticket based on their
  2083  	// original funding amount.
  2084  	numRevocationPayments := len(msgTx.TxOut)
  2085  	if numRevocationPayments*2 != len(ticketOuts)-1 {
  2086  		str := fmt.Sprintf("revocation %s makes %d payments when input ticket "+
  2087  			"%s has %d commitments", revokeHash, numRevocationPayments,
  2088  			ticketHash, len(ticketOuts)-1)
  2089  		return ruleError(ErrBadNumPayees, str)
  2090  	}
  2091  
  2092  	// Ensure the outputs adhere to the ticket commitments.  Zero is passed for
  2093  	// the vote subsidy since revocations do not produce any subsidy.
  2094  	return checkTicketRedeemerCommitments(ticketHash, ticketOuts, msgTx, false,
  2095  		0)
  2096  }
  2097  
  2098  // CheckTransactionInputs performs a series of checks on the inputs to a
  2099  // transaction to ensure they are valid.  An example of some of the checks
  2100  // include verifying all inputs exist, ensuring the coinbase seasoning
  2101  // requirements are met, detecting double spends, validating all values and
  2102  // fees are in the legal range and the total output amount doesn't exceed the
  2103  // input amount, and verifying the signatures to prove the spender was the
  2104  // owner of the Decred and therefore allowed to spend them.  As it checks the
  2105  // inputs, it also calculates the total fees for the transaction and returns
  2106  // that value.
  2107  //
  2108  // NOTE: The transaction MUST have already been sanity checked with the
  2109  // CheckTransactionSanity function prior to calling this function.
  2110  func CheckTransactionInputs(subsidyCache *standalone.SubsidyCache, tx *dcrutil.Tx, txHeight int64, view *UtxoViewpoint, checkFraudProof bool, chainParams *chaincfg.Params) (int64, error) {
  2111  	// Coinbase transactions have no inputs.
  2112  	msgTx := tx.MsgTx()
  2113  	if standalone.IsCoinBaseTx(msgTx) {
  2114  		return 0, nil
  2115  	}
  2116  
  2117  	// -------------------------------------------------------------------
  2118  	// Decred stake transaction testing.
  2119  	// -------------------------------------------------------------------
  2120  
  2121  	// Perform additional checks on ticket purchase transactions such as
  2122  	// ensuring the input type requirements are met and the output commitments
  2123  	// coincide with the inputs.
  2124  	isTicket := stake.IsSStx(msgTx)
  2125  	if isTicket {
  2126  		if err := checkTicketPurchaseInputs(msgTx, view); err != nil {
  2127  			return 0, err
  2128  		}
  2129  	}
  2130  
  2131  	// Perform additional checks on vote transactions such as verying that the
  2132  	// referenced ticket exists, the stakebase input commits to correct subsidy,
  2133  	// the output amounts adhere to the commitments of the referenced ticket,
  2134  	// and the ticket maturity requirements are met.
  2135  	//
  2136  	// Also keep track of whether or not it is a vote since some inputs need
  2137  	// to be skipped later.
  2138  	isVote := stake.IsSSGen(msgTx)
  2139  	if isVote {
  2140  		err := checkVoteInputs(subsidyCache, tx, txHeight, view, chainParams)
  2141  		if err != nil {
  2142  			return 0, err
  2143  		}
  2144  	}
  2145  
  2146  	// Perform additional checks on revocation transactions such as verifying
  2147  	// the referenced ticket exists, the output amounts adhere to the
  2148  	// commitments of the ticket, and the ticket maturity requirements are met.
  2149  	//
  2150  	// Also keep track of whether or not it is a revocation since some inputs
  2151  	// need to be skipped later.
  2152  	isRevocation := stake.IsSSRtx(msgTx)
  2153  	if isRevocation {
  2154  		err := checkRevocationInputs(tx, txHeight, view, chainParams)
  2155  		if err != nil {
  2156  			return 0, err
  2157  		}
  2158  	}
  2159  
  2160  	// -------------------------------------------------------------------
  2161  	// Decred general transaction testing (and a few stake exceptions).
  2162  	// -------------------------------------------------------------------
  2163  
  2164  	txHash := tx.Hash()
  2165  	var totalAtomIn int64
  2166  	for idx, txIn := range msgTx.TxIn {
  2167  		// Inputs won't exist for stakebase tx, so ignore them.
  2168  		if isVote && idx == 0 {
  2169  			// However, do add the reward amount.
  2170  			_, heightVotingOn := stake.SSGenBlockVotedOn(msgTx)
  2171  			stakeVoteSubsidy := subsidyCache.CalcStakeVoteSubsidy(
  2172  				int64(heightVotingOn))
  2173  			totalAtomIn += stakeVoteSubsidy
  2174  			continue
  2175  		}
  2176  
  2177  		txInHash := &txIn.PreviousOutPoint.Hash
  2178  		originTxIndex := txIn.PreviousOutPoint.Index
  2179  		utxoEntry := view.LookupEntry(txInHash)
  2180  		if utxoEntry == nil || utxoEntry.IsOutputSpent(originTxIndex) {
  2181  			str := fmt.Sprintf("output %v referenced from "+
  2182  				"transaction %s:%d either does not exist or "+
  2183  				"has already been spent", txIn.PreviousOutPoint,
  2184  				txHash, idx)
  2185  			return 0, ruleError(ErrMissingTxOut, str)
  2186  		}
  2187  
  2188  		// Check fraud proof witness data.
  2189  
  2190  		// Using zero value outputs as inputs is banned.
  2191  		if utxoEntry.AmountByIndex(originTxIndex) == 0 {
  2192  			str := fmt.Sprintf("tried to spend zero value output "+
  2193  				"from input %v, idx %v", txInHash,
  2194  				originTxIndex)
  2195  			return 0, ruleError(ErrZeroValueOutputSpend, str)
  2196  		}
  2197  
  2198  		if checkFraudProof {
  2199  			if txIn.ValueIn !=
  2200  				utxoEntry.AmountByIndex(originTxIndex) {
  2201  				str := fmt.Sprintf("bad fraud check value in "+
  2202  					"(expected %v, given %v) for txIn %v",
  2203  					utxoEntry.AmountByIndex(originTxIndex),
  2204  					txIn.ValueIn, idx)
  2205  				return 0, ruleError(ErrFraudAmountIn, str)
  2206  			}
  2207  
  2208  			if int64(txIn.BlockHeight) != utxoEntry.BlockHeight() {
  2209  				str := fmt.Sprintf("bad fraud check block "+
  2210  					"height (expected %v, given %v) for "+
  2211  					"txIn %v", utxoEntry.BlockHeight(),
  2212  					txIn.BlockHeight, idx)
  2213  				return 0, ruleError(ErrFraudBlockHeight, str)
  2214  			}
  2215  
  2216  			if txIn.BlockIndex != utxoEntry.BlockIndex() {
  2217  				str := fmt.Sprintf("bad fraud check block "+
  2218  					"index (expected %v, given %v) for "+
  2219  					"txIn %v", utxoEntry.BlockIndex(),
  2220  					txIn.BlockIndex, idx)
  2221  				return 0, ruleError(ErrFraudBlockIndex, str)
  2222  			}
  2223  		}
  2224  
  2225  		// Ensure the transaction is not spending coins which have not
  2226  		// yet reached the required coinbase maturity.
  2227  		coinbaseMaturity := int64(chainParams.CoinbaseMaturity)
  2228  		if utxoEntry.IsCoinBase() {
  2229  			originHeight := utxoEntry.BlockHeight()
  2230  			blocksSincePrev := txHeight - originHeight
  2231  			if blocksSincePrev < coinbaseMaturity {
  2232  				str := fmt.Sprintf("tx %v tried to spend "+
  2233  					"coinbase transaction %v from height "+
  2234  					"%v at height %v before required "+
  2235  					"maturity of %v blocks", txHash,
  2236  					txInHash, originHeight, txHeight,
  2237  					coinbaseMaturity)
  2238  				return 0, ruleError(ErrImmatureSpend, str)
  2239  			}
  2240  		}
  2241  
  2242  		// Ensure that the transaction is not spending coins from a
  2243  		// transaction that included an expiry but which has not yet
  2244  		// reached coinbase maturity many blocks.
  2245  		if utxoEntry.HasExpiry() {
  2246  			originHeight := utxoEntry.BlockHeight()
  2247  			blocksSincePrev := txHeight - originHeight
  2248  			if blocksSincePrev < coinbaseMaturity {
  2249  				str := fmt.Sprintf("tx %v tried to spend "+
  2250  					"transaction %v including an expiry "+
  2251  					"from height %v at height %v before "+
  2252  					"required maturity of %v blocks",
  2253  					txHash, txInHash, originHeight,
  2254  					txHeight, coinbaseMaturity)
  2255  				return 0, ruleError(ErrExpiryTxSpentEarly, str)
  2256  			}
  2257  		}
  2258  
  2259  		// Ensure that the outpoint's tx tree makes sense.
  2260  		originTxOPTree := txIn.PreviousOutPoint.Tree
  2261  		originTxType := utxoEntry.TransactionType()
  2262  		indicatedTree := wire.TxTreeRegular
  2263  		if originTxType != stake.TxTypeRegular {
  2264  			indicatedTree = wire.TxTreeStake
  2265  		}
  2266  		if indicatedTree != originTxOPTree {
  2267  			errStr := fmt.Sprintf("tx %v attempted to spend from "+
  2268  				"a %v tx tree (hash %v), yet the outpoint "+
  2269  				"specified a %v tx tree instead", txHash,
  2270  				indicatedTree, txIn.PreviousOutPoint.Hash,
  2271  				originTxOPTree)
  2272  			return 0, ruleError(ErrDiscordantTxTree, errStr)
  2273  		}
  2274  
  2275  		// The only transaction types that are allowed to spend from OP_SSTX
  2276  		// tagged outputs are votes and revocations.  So, check all the inputs
  2277  		// from non votes and revocations and make sure that they spend no
  2278  		// OP_SSTX tagged outputs.
  2279  		if !(isVote || isRevocation) {
  2280  			if txscript.GetScriptClass(
  2281  				utxoEntry.ScriptVersionByIndex(originTxIndex),
  2282  				utxoEntry.PkScriptByIndex(originTxIndex)) ==
  2283  				txscript.StakeSubmissionTy {
  2284  
  2285  				errSSGen := stake.CheckSSGen(msgTx)
  2286  				errSSRtx := stake.CheckSSRtx(msgTx)
  2287  				errStr := fmt.Sprintf("Tx %v attempted to "+
  2288  					"spend an OP_SSTX tagged output, "+
  2289  					"however it was not an SSGen or SSRtx"+
  2290  					" tx; SSGen err: %v, SSRtx err: %v",
  2291  					txHash, errSSGen.Error(),
  2292  					errSSRtx.Error())
  2293  				return 0, ruleError(ErrTxSStxOutSpend, errStr)
  2294  			}
  2295  		}
  2296  
  2297  		// OP_SSGEN and OP_SSRTX tagged outputs can only be spent after
  2298  		// coinbase maturity many blocks.
  2299  		scriptClass := txscript.GetScriptClass(
  2300  			utxoEntry.ScriptVersionByIndex(originTxIndex),
  2301  			utxoEntry.PkScriptByIndex(originTxIndex))
  2302  		if scriptClass == txscript.StakeGenTy ||
  2303  			scriptClass == txscript.StakeRevocationTy {
  2304  			originHeight := utxoEntry.BlockHeight()
  2305  			blocksSincePrev := txHeight - originHeight
  2306  			if blocksSincePrev <
  2307  				int64(chainParams.SStxChangeMaturity) {
  2308  				str := fmt.Sprintf("tried to spend OP_SSGEN or"+
  2309  					" OP_SSRTX output from tx %v from "+
  2310  					"height %v at height %v before "+
  2311  					"required maturity of %v blocks",
  2312  					txInHash, originHeight, txHeight,
  2313  					coinbaseMaturity)
  2314  				return 0, ruleError(ErrImmatureSpend, str)
  2315  			}
  2316  		}
  2317  
  2318  		// Ticket change outputs may only be spent after ticket change
  2319  		// maturity many blocks.
  2320  		if scriptClass == txscript.StakeSubChangeTy {
  2321  			originHeight := utxoEntry.BlockHeight()
  2322  			blocksSincePrev := txHeight - originHeight
  2323  			if blocksSincePrev <
  2324  				int64(chainParams.SStxChangeMaturity) {
  2325  				str := fmt.Sprintf("tried to spend ticket change"+
  2326  					" output from tx %v from height %v at "+
  2327  					"height %v before required maturity "+
  2328  					"of %v blocks", txInHash, originHeight,
  2329  					txHeight, chainParams.SStxChangeMaturity)
  2330  				return 0, ruleError(ErrImmatureSpend, str)
  2331  			}
  2332  		}
  2333  
  2334  		// Ensure the transaction amounts are in range.  Each of the
  2335  		// output values of the input transactions must not be negative
  2336  		// or more than the max allowed per transaction.  All amounts
  2337  		// in a transaction are in a unit value known as an atom.  One
  2338  		// Decred is a quantity of atoms as defined by the AtomPerCoin
  2339  		// constant.
  2340  		originTxAtom := utxoEntry.AmountByIndex(originTxIndex)
  2341  		if originTxAtom < 0 {
  2342  			str := fmt.Sprintf("transaction output has negative "+
  2343  				"value of %v", originTxAtom)
  2344  			return 0, ruleError(ErrBadTxOutValue, str)
  2345  		}
  2346  		if originTxAtom > dcrutil.MaxAmount {
  2347  			str := fmt.Sprintf("transaction output value of %v is "+
  2348  				"higher than max allowed value of %v",
  2349  				originTxAtom, dcrutil.MaxAmount)
  2350  			return 0, ruleError(ErrBadTxOutValue, str)
  2351  		}
  2352  
  2353  		// The total of all outputs must not be more than the max
  2354  		// allowed per transaction.  Also, we could potentially
  2355  		// overflow the accumulator so check for overflow.
  2356  		lastAtomIn := totalAtomIn
  2357  		totalAtomIn += originTxAtom
  2358  		if totalAtomIn < lastAtomIn ||
  2359  			totalAtomIn > dcrutil.MaxAmount {
  2360  			str := fmt.Sprintf("total value of all transaction "+
  2361  				"inputs is %v which is higher than max "+
  2362  				"allowed value of %v", totalAtomIn,
  2363  				dcrutil.MaxAmount)
  2364  			return 0, ruleError(ErrBadTxOutValue, str)
  2365  		}
  2366  	}
  2367  
  2368  	// Calculate the total output amount for this transaction.  It is safe
  2369  	// to ignore overflow and out of range errors here because those error
  2370  	// conditions would have already been caught by checkTransactionSanity.
  2371  	var totalAtomOut int64
  2372  	for _, txOut := range tx.MsgTx().TxOut {
  2373  		totalAtomOut += txOut.Value
  2374  	}
  2375  
  2376  	// Ensure the transaction does not spend more than its inputs.
  2377  	if totalAtomIn < totalAtomOut {
  2378  		str := fmt.Sprintf("total value of all transaction inputs for "+
  2379  			"transaction %v is %v which is less than the amount "+
  2380  			"spent of %v", txHash, totalAtomIn, totalAtomOut)
  2381  		return 0, ruleError(ErrSpendTooHigh, str)
  2382  	}
  2383  
  2384  	txFeeInAtom := totalAtomIn - totalAtomOut
  2385  	return txFeeInAtom, nil
  2386  }
  2387  
  2388  // CountSigOps returns the number of signature operations for all transaction
  2389  // input and output scripts in the provided transaction.  This uses the
  2390  // quicker, but imprecise, signature operation counting mechanism from
  2391  // txscript.
  2392  func CountSigOps(tx *dcrutil.Tx, isCoinBaseTx bool, isSSGen bool) int {
  2393  	msgTx := tx.MsgTx()
  2394  
  2395  	// Accumulate the number of signature operations in all transaction
  2396  	// inputs.
  2397  	totalSigOps := 0
  2398  	for i, txIn := range msgTx.TxIn {
  2399  		// Skip coinbase inputs.
  2400  		if isCoinBaseTx {
  2401  			continue
  2402  		}
  2403  		// Skip stakebase inputs.
  2404  		if isSSGen && i == 0 {
  2405  			continue
  2406  		}
  2407  
  2408  		numSigOps := txscript.GetSigOpCount(txIn.SignatureScript)
  2409  		totalSigOps += numSigOps
  2410  	}
  2411  
  2412  	// Accumulate the number of signature operations in all transaction
  2413  	// outputs.
  2414  	for _, txOut := range msgTx.TxOut {
  2415  		numSigOps := txscript.GetSigOpCount(txOut.PkScript)
  2416  		totalSigOps += numSigOps
  2417  	}
  2418  
  2419  	return totalSigOps
  2420  }
  2421  
  2422  // CountP2SHSigOps returns the number of signature operations for all input
  2423  // transactions which are of the pay-to-script-hash type.  This uses the
  2424  // precise, signature operation counting mechanism from the script engine which
  2425  // requires access to the input transaction scripts.
  2426  func CountP2SHSigOps(tx *dcrutil.Tx, isCoinBaseTx bool, isStakeBaseTx bool, view *UtxoViewpoint) (int, error) {
  2427  	// Coinbase transactions have no interesting inputs.
  2428  	if isCoinBaseTx {
  2429  		return 0, nil
  2430  	}
  2431  
  2432  	// Stakebase (SSGen) transactions have no P2SH inputs.  Same with SSRtx,
  2433  	// but they will still pass the checks below.
  2434  	if isStakeBaseTx {
  2435  		return 0, nil
  2436  	}
  2437  
  2438  	// Accumulate the number of signature operations in all transaction
  2439  	// inputs.
  2440  	msgTx := tx.MsgTx()
  2441  	totalSigOps := 0
  2442  	for txInIndex, txIn := range msgTx.TxIn {
  2443  		// Ensure the referenced input transaction is available.
  2444  		originTxHash := &txIn.PreviousOutPoint.Hash
  2445  		originTxIndex := txIn.PreviousOutPoint.Index
  2446  		utxoEntry := view.LookupEntry(originTxHash)
  2447  		if utxoEntry == nil || utxoEntry.IsOutputSpent(originTxIndex) {
  2448  			str := fmt.Sprintf("output %v referenced from "+
  2449  				"transaction %s:%d either does not exist or "+
  2450  				"has already been spent", txIn.PreviousOutPoint,
  2451  				tx.Hash(), txInIndex)
  2452  			return 0, ruleError(ErrMissingTxOut, str)
  2453  		}
  2454  
  2455  		// We're only interested in pay-to-script-hash types, so skip
  2456  		// this input if it's not one.
  2457  		pkScript := utxoEntry.PkScriptByIndex(originTxIndex)
  2458  		if !txscript.IsPayToScriptHash(pkScript) {
  2459  			continue
  2460  		}
  2461  
  2462  		// Count the precise number of signature operations in the
  2463  		// referenced public key script.
  2464  		sigScript := txIn.SignatureScript
  2465  		numSigOps := txscript.GetPreciseSigOpCount(sigScript, pkScript,
  2466  			true)
  2467  
  2468  		// We could potentially overflow the accumulator so check for
  2469  		// overflow.
  2470  		lastSigOps := totalSigOps
  2471  		totalSigOps += numSigOps
  2472  		if totalSigOps < lastSigOps {
  2473  			str := fmt.Sprintf("the public key script from output "+
  2474  				"%v contains too many signature operations - "+
  2475  				"overflow", txIn.PreviousOutPoint)
  2476  			return 0, ruleError(ErrTooManySigOps, str)
  2477  		}
  2478  	}
  2479  
  2480  	return totalSigOps, nil
  2481  }
  2482  
  2483  // createLegacySeqLockView returns a view to use when calculating sequence locks
  2484  // for the transactions in the regular tree that preserves the same incorrect
  2485  // semantics that were present in previous versions of the software.
  2486  func (b *BlockChain) createLegacySeqLockView(block, parent *dcrutil.Block, view *UtxoViewpoint) (*UtxoViewpoint, error) {
  2487  	// Clone the real view to avoid mutating it.
  2488  	seqLockView := view.clone()
  2489  
  2490  	// Ensure all of the inputs referenced by the transactions in the regular
  2491  	// tree of the parent block and the parent block outputs are available in
  2492  	// the legacy view so long as it has not been disapproved.
  2493  	if headerApprovesParent(&block.MsgBlock().Header) {
  2494  		err := seqLockView.fetchRegularInputUtxos(b.db, parent)
  2495  		if err != nil {
  2496  			return nil, err
  2497  		}
  2498  
  2499  		for txInIdx, tx := range parent.Transactions() {
  2500  			seqLockView.AddTxOuts(tx, parent.Height(), uint32(txInIdx))
  2501  		}
  2502  	}
  2503  
  2504  	// Ensure all of the inputs referenced by the transactions in the stake tree
  2505  	// of the current block are available in the legacy view.
  2506  	filteredSet := make(viewFilteredSet)
  2507  	for _, stx := range block.STransactions() {
  2508  		isVote := stake.IsSSGen(stx.MsgTx())
  2509  		for txInIdx, txIn := range stx.MsgTx().TxIn {
  2510  			// Ignore stakebase since it has no input.
  2511  			if txInIdx == 0 && isVote {
  2512  				continue
  2513  			}
  2514  
  2515  			// Only request entries that are not already in the view from the
  2516  			// database.
  2517  			originHash := &txIn.PreviousOutPoint.Hash
  2518  			filteredSet.add(seqLockView, originHash)
  2519  		}
  2520  	}
  2521  	err := seqLockView.fetchUtxosMain(b.db, filteredSet)
  2522  	if err != nil {
  2523  		return nil, err
  2524  	}
  2525  
  2526  	// Connect all of the transactions in the stake tree of the current block.
  2527  	for txIdx, stx := range block.STransactions() {
  2528  		err := seqLockView.connectTransaction(stx, block.Height(),
  2529  			uint32(txIdx), nil)
  2530  		if err != nil {
  2531  			return nil, err
  2532  		}
  2533  	}
  2534  
  2535  	return seqLockView, nil
  2536  }
  2537  
  2538  // checkNumSigOps Checks the number of P2SH signature operations to make
  2539  // sure they don't overflow the limits.  It takes a cumulative number of sig
  2540  // ops as an argument and increments will each call.
  2541  // TxTree true == Regular, false == Stake
  2542  func checkNumSigOps(tx *dcrutil.Tx, view *UtxoViewpoint, index int, txTree bool, cumulativeSigOps int) (int, error) {
  2543  	msgTx := tx.MsgTx()
  2544  	isSSGen := stake.IsSSGen(msgTx)
  2545  	numsigOps := CountSigOps(tx, (index == 0) && txTree, isSSGen)
  2546  
  2547  	// Since the first (and only the first) transaction has already been
  2548  	// verified to be a coinbase transaction, use (i == 0) && TxTree as an
  2549  	// optimization for the flag to countP2SHSigOps for whether or not the
  2550  	// transaction is a coinbase transaction rather than having to do a
  2551  	// full coinbase check again.
  2552  	numP2SHSigOps, err := CountP2SHSigOps(tx, (index == 0) && txTree,
  2553  		isSSGen, view)
  2554  	if err != nil {
  2555  		log.Tracef("CountP2SHSigOps failed; error returned %v", err)
  2556  		return 0, err
  2557  	}
  2558  
  2559  	startCumSigOps := cumulativeSigOps
  2560  	cumulativeSigOps += numsigOps
  2561  	cumulativeSigOps += numP2SHSigOps
  2562  
  2563  	// Check for overflow or going over the limits.  We have to do
  2564  	// this on every loop iteration to avoid overflow.
  2565  	if cumulativeSigOps < startCumSigOps ||
  2566  		cumulativeSigOps > MaxSigOpsPerBlock {
  2567  		str := fmt.Sprintf("block contains too many signature "+
  2568  			"operations - got %v, max %v", cumulativeSigOps,
  2569  			MaxSigOpsPerBlock)
  2570  		return 0, ruleError(ErrTooManySigOps, str)
  2571  	}
  2572  
  2573  	return cumulativeSigOps, nil
  2574  }
  2575  
  2576  // checkStakeBaseAmounts calculates the total amount given as subsidy from
  2577  // single stakebase transactions (votes) within a block.  This function skips a
  2578  // ton of checks already performed by CheckTransactionInputs.
  2579  func checkStakeBaseAmounts(subsidyCache *standalone.SubsidyCache, height int64, params *chaincfg.Params, txs []*dcrutil.Tx, view *UtxoViewpoint) error {
  2580  	for _, tx := range txs {
  2581  		msgTx := tx.MsgTx()
  2582  		if stake.IsSSGen(msgTx) {
  2583  			// Ensure the input is available.
  2584  			txInHash := &msgTx.TxIn[1].PreviousOutPoint.Hash
  2585  			utxoEntry, exists := view.entries[*txInHash]
  2586  			if !exists || utxoEntry == nil {
  2587  				str := fmt.Sprintf("couldn't find input tx %v "+
  2588  					"for stakebase amounts check", txInHash)
  2589  				return ruleError(ErrTicketUnavailable, str)
  2590  			}
  2591  
  2592  			originTxIndex := msgTx.TxIn[1].PreviousOutPoint.Index
  2593  			originTxAtom := utxoEntry.AmountByIndex(originTxIndex)
  2594  
  2595  			totalOutputs := int64(0)
  2596  			// Sum up the outputs.
  2597  			for _, out := range msgTx.TxOut {
  2598  				totalOutputs += out.Value
  2599  			}
  2600  
  2601  			difference := totalOutputs - originTxAtom
  2602  
  2603  			// Subsidy aligns with the height we're voting on, not
  2604  			// with the height of the current block.
  2605  			calcSubsidy := subsidyCache.CalcStakeVoteSubsidy(height - 1)
  2606  
  2607  			if difference > calcSubsidy {
  2608  				str := fmt.Sprintf("ssgen tx %v spent more "+
  2609  					"than allowed (spent %v, allowed %v)",
  2610  					tx.Hash(), difference, calcSubsidy)
  2611  				return ruleError(ErrSSGenSubsidy, str)
  2612  			}
  2613  		}
  2614  	}
  2615  
  2616  	return nil
  2617  }
  2618  
  2619  // getStakeBaseAmounts calculates the total amount given as subsidy from the
  2620  // collective stakebase transactions (votes) within a block.  This function
  2621  // skips a ton of checks already performed by CheckTransactionInputs.
  2622  func getStakeBaseAmounts(txs []*dcrutil.Tx, view *UtxoViewpoint) (int64, error) {
  2623  	totalInputs := int64(0)
  2624  	totalOutputs := int64(0)
  2625  	for _, tx := range txs {
  2626  		msgTx := tx.MsgTx()
  2627  		if stake.IsSSGen(msgTx) {
  2628  			// Ensure the input is available.
  2629  			txInHash := &msgTx.TxIn[1].PreviousOutPoint.Hash
  2630  			utxoEntry, exists := view.entries[*txInHash]
  2631  			if !exists || utxoEntry == nil {
  2632  				str := fmt.Sprintf("couldn't find input tx %v "+
  2633  					"for stakebase amounts get", txInHash)
  2634  				return 0, ruleError(ErrTicketUnavailable, str)
  2635  			}
  2636  
  2637  			originTxIndex := msgTx.TxIn[1].PreviousOutPoint.Index
  2638  			originTxAtom := utxoEntry.AmountByIndex(originTxIndex)
  2639  
  2640  			totalInputs += originTxAtom
  2641  
  2642  			// Sum up the outputs.
  2643  			for _, out := range msgTx.TxOut {
  2644  				totalOutputs += out.Value
  2645  			}
  2646  		}
  2647  	}
  2648  
  2649  	return totalOutputs - totalInputs, nil
  2650  }
  2651  
  2652  // getStakeTreeFees determines the amount of fees for in the stake tx tree of
  2653  // some node given a transaction store.
  2654  func getStakeTreeFees(subsidyCache *standalone.SubsidyCache, height int64, params *chaincfg.Params, txs []*dcrutil.Tx, view *UtxoViewpoint) (dcrutil.Amount, error) {
  2655  	totalInputs := int64(0)
  2656  	totalOutputs := int64(0)
  2657  	for _, tx := range txs {
  2658  		msgTx := tx.MsgTx()
  2659  		isSSGen := stake.IsSSGen(msgTx)
  2660  
  2661  		for i, in := range msgTx.TxIn {
  2662  			// Ignore stakebases.
  2663  			if isSSGen && i == 0 {
  2664  				continue
  2665  			}
  2666  
  2667  			txInHash := &in.PreviousOutPoint.Hash
  2668  			utxoEntry, exists := view.entries[*txInHash]
  2669  			if !exists || utxoEntry == nil {
  2670  				str := fmt.Sprintf("couldn't find input tx "+
  2671  					"%v for stake tree fee calculation",
  2672  					txInHash)
  2673  				return 0, ruleError(ErrTicketUnavailable, str)
  2674  			}
  2675  
  2676  			originTxIndex := in.PreviousOutPoint.Index
  2677  			originTxAtom := utxoEntry.AmountByIndex(originTxIndex)
  2678  
  2679  			totalInputs += originTxAtom
  2680  		}
  2681  
  2682  		for _, out := range msgTx.TxOut {
  2683  			totalOutputs += out.Value
  2684  		}
  2685  
  2686  		// For votes, subtract the subsidy to determine actual fees.
  2687  		if isSSGen {
  2688  			// Subsidy aligns with the height we're voting on, not
  2689  			// with the height of the current block.
  2690  			totalOutputs -= subsidyCache.CalcStakeVoteSubsidy(height - 1)
  2691  		}
  2692  	}
  2693  
  2694  	if totalInputs < totalOutputs {
  2695  		str := fmt.Sprintf("negative cumulative fees found in stake " +
  2696  			"tx tree")
  2697  		return 0, ruleError(ErrStakeFees, str)
  2698  	}
  2699  
  2700  	return dcrutil.Amount(totalInputs - totalOutputs), nil
  2701  }
  2702  
  2703  // checkTransactionsAndConnect is the local function used to check the
  2704  // transaction inputs for a transaction list given a predetermined TxStore.
  2705  // After ensuring the transaction is valid, the transaction is connected to the
  2706  // UTXO viewpoint.  TxTree true == Regular, false == Stake
  2707  func (b *BlockChain) checkTransactionsAndConnect(inputFees dcrutil.Amount, node *blockNode, txs []*dcrutil.Tx, view *UtxoViewpoint, stxos *[]spentTxOut, txTree bool) error {
  2708  	// Perform several checks on the inputs for each transaction.  Also
  2709  	// accumulate the total fees.  This could technically be combined with
  2710  	// the loop above instead of running another loop over the
  2711  	// transactions, but by separating it we can avoid running the more
  2712  	// expensive (though still relatively cheap as compared to running the
  2713  	// scripts) checks against all the inputs when the signature operations
  2714  	// are out of bounds.
  2715  	totalFees := int64(inputFees) // Stake tx tree carry forward
  2716  	var cumulativeSigOps int
  2717  	for idx, tx := range txs {
  2718  		// Ensure that the number of signature operations is not beyond
  2719  		// the consensus limit.
  2720  		var err error
  2721  		cumulativeSigOps, err = checkNumSigOps(tx, view, idx, txTree,
  2722  			cumulativeSigOps)
  2723  		if err != nil {
  2724  			return err
  2725  		}
  2726  
  2727  		// This step modifies the txStore and marks the tx outs used
  2728  		// spent, so be aware of this.
  2729  		txFee, err := CheckTransactionInputs(b.subsidyCache, tx,
  2730  			node.height, view, true, /* check fraud proofs */
  2731  			b.chainParams)
  2732  		if err != nil {
  2733  			log.Tracef("CheckTransactionInputs failed; error "+
  2734  				"returned: %v", err)
  2735  			return err
  2736  		}
  2737  
  2738  		// Sum the total fees and ensure we don't overflow the
  2739  		// accumulator.
  2740  		lastTotalFees := totalFees
  2741  		totalFees += txFee
  2742  		if totalFees < lastTotalFees {
  2743  			return ruleError(ErrBadFees, "total fees for block "+
  2744  				"overflows accumulator")
  2745  		}
  2746  
  2747  		// Connect the transaction to the UTXO viewpoint, so that in
  2748  		// flight transactions may correctly validate.
  2749  		err = view.connectTransaction(tx, node.height, uint32(idx),
  2750  			stxos)
  2751  		if err != nil {
  2752  			return err
  2753  		}
  2754  	}
  2755  
  2756  	// The total output values of the coinbase transaction must not exceed
  2757  	// the expected subsidy value plus total transaction fees gained from
  2758  	// mining the block.  It is safe to ignore overflow and out of range
  2759  	// errors here because those error conditions would have already been
  2760  	// caught by checkTransactionSanity.
  2761  	if txTree { //TxTreeRegular
  2762  		// Apply penalty to fees if we're at stake validation height.
  2763  		if node.height >= b.chainParams.StakeValidationHeight {
  2764  			totalFees *= int64(node.voters)
  2765  			totalFees /= int64(b.chainParams.TicketsPerBlock)
  2766  		}
  2767  
  2768  		var totalAtomOutRegular int64
  2769  
  2770  		for _, txOut := range txs[0].MsgTx().TxOut {
  2771  			totalAtomOutRegular += txOut.Value
  2772  		}
  2773  
  2774  		var expAtomOut int64
  2775  		if node.height == 1 {
  2776  			expAtomOut = b.subsidyCache.CalcBlockSubsidy(node.height)
  2777  		} else {
  2778  			subsidyWork := b.subsidyCache.CalcWorkSubsidy(node.height,
  2779  				node.voters)
  2780  			subsidyTax := b.subsidyCache.CalcTreasurySubsidy(node.height,
  2781  				node.voters)
  2782  			expAtomOut = subsidyWork + subsidyTax + totalFees
  2783  		}
  2784  
  2785  		// AmountIn for the input should be equal to the subsidy.
  2786  		coinbaseIn := txs[0].MsgTx().TxIn[0]
  2787  		subsidyWithoutFees := expAtomOut - totalFees
  2788  		if (coinbaseIn.ValueIn != subsidyWithoutFees) &&
  2789  			(node.height > 0) {
  2790  			errStr := fmt.Sprintf("bad coinbase subsidy in input;"+
  2791  				" got %v, expected %v", coinbaseIn.ValueIn,
  2792  				subsidyWithoutFees)
  2793  			return ruleError(ErrBadCoinbaseAmountIn, errStr)
  2794  		}
  2795  
  2796  		if totalAtomOutRegular > expAtomOut {
  2797  			str := fmt.Sprintf("coinbase transaction for block %v"+
  2798  				" pays %v which is more than expected value "+
  2799  				"of %v", node.hash, totalAtomOutRegular,
  2800  				expAtomOut)
  2801  			return ruleError(ErrBadCoinbaseValue, str)
  2802  		}
  2803  	} else { // TxTreeStake
  2804  		if len(txs) == 0 &&
  2805  			node.height < b.chainParams.StakeValidationHeight {
  2806  			return nil
  2807  		}
  2808  		if len(txs) == 0 &&
  2809  			node.height >= b.chainParams.StakeValidationHeight {
  2810  			str := fmt.Sprintf("empty tx tree stake in block " +
  2811  				"after stake validation height")
  2812  			return ruleError(ErrNoStakeTx, str)
  2813  		}
  2814  
  2815  		err := checkStakeBaseAmounts(b.subsidyCache, node.height,
  2816  			b.chainParams, txs, view)
  2817  		if err != nil {
  2818  			return err
  2819  		}
  2820  
  2821  		totalAtomOutStake, err := getStakeBaseAmounts(txs, view)
  2822  		if err != nil {
  2823  			return err
  2824  		}
  2825  
  2826  		var expAtomOut int64
  2827  		if node.height >= b.chainParams.StakeValidationHeight {
  2828  			// Subsidy aligns with the height we're voting on, not
  2829  			// with the height of the current block.
  2830  			expAtomOut = b.subsidyCache.CalcStakeVoteSubsidy(node.height-1) *
  2831  				int64(node.voters)
  2832  		} else {
  2833  			expAtomOut = totalFees
  2834  		}
  2835  
  2836  		if totalAtomOutStake > expAtomOut {
  2837  			str := fmt.Sprintf("stakebase transactions for block "+
  2838  				"pays %v which is more than expected value "+
  2839  				"of %v", totalAtomOutStake, expAtomOut)
  2840  			return ruleError(ErrBadStakebaseValue, str)
  2841  		}
  2842  	}
  2843  
  2844  	return nil
  2845  }
  2846  
  2847  // consensusScriptVerifyFlags returns the script flags that must be used when
  2848  // executing transaction scripts to enforce the consensus rules. This includes
  2849  // any flags required as the result of any agendas that have passed and become
  2850  // active.
  2851  func (b *BlockChain) consensusScriptVerifyFlags(node *blockNode) (txscript.ScriptFlags, error) {
  2852  	scriptFlags := txscript.ScriptVerifyCleanStack |
  2853  		txscript.ScriptVerifyCheckLockTimeVerify
  2854  
  2855  	// Enable enforcement of OP_CSV and OP_SHA256 if the stake vote
  2856  	// for the agenda is active.
  2857  	lnFeaturesActive, err := b.isLNFeaturesAgendaActive(node.parent)
  2858  	if err != nil {
  2859  		return 0, err
  2860  	}
  2861  	if lnFeaturesActive {
  2862  		scriptFlags |= txscript.ScriptVerifyCheckSequenceVerify
  2863  		scriptFlags |= txscript.ScriptVerifySHA256
  2864  	}
  2865  	return scriptFlags, err
  2866  }
  2867  
  2868  // checkConnectBlock performs several checks to confirm connecting the passed
  2869  // block to the chain represented by the passed view does not violate any
  2870  // rules.  In addition, the passed view is updated to spend all of the
  2871  // referenced outputs and add all of the new utxos created by block.  Thus, the
  2872  // view will represent the state of the chain as if the block were actually
  2873  // connected and consequently the best hash for the view is also updated to
  2874  // passed block.
  2875  //
  2876  // An example of some of the checks performed are ensuring connecting the block
  2877  // would not cause any duplicate transaction hashes for old transactions that
  2878  // aren't already fully spent, double spends, exceeding the maximum allowed
  2879  // signature operations per block, invalid values in relation to the expected
  2880  // block subsidy, or fail transaction script validation.
  2881  //
  2882  // The CheckConnectBlockTemplate function makes use of this function to perform
  2883  // the bulk of its work.
  2884  //
  2885  // This function MUST be called with the chain state lock held (for writes).
  2886  func (b *BlockChain) checkConnectBlock(node *blockNode, block, parent *dcrutil.Block, view *UtxoViewpoint, stxos *[]spentTxOut) error {
  2887  	// If the side chain blocks end up in the database, a call to
  2888  	// CheckBlockSanity should be done here in case a previous version
  2889  	// allowed a block that is no longer valid.  However, since the
  2890  	// implementation only currently uses memory for the side chain blocks,
  2891  	// it isn't currently necessary.
  2892  
  2893  	// Ensure the view is for the node being checked.
  2894  	parentHash := &block.MsgBlock().Header.PrevBlock
  2895  	if !view.BestHash().IsEqual(parentHash) {
  2896  		return AssertError(fmt.Sprintf("inconsistent view when "+
  2897  			"checking block connection: best hash is %v instead "+
  2898  			"of expected %v", view.BestHash(), parentHash))
  2899  	}
  2900  
  2901  	// Check that the coinbase pays the treasury, if applicable.
  2902  	err := coinbasePaysTreasury(b.subsidyCache, block.Transactions()[0],
  2903  		node.height, node.voters, b.chainParams)
  2904  	if err != nil {
  2905  		return err
  2906  	}
  2907  
  2908  	// Don't run scripts if this node is before the latest known good
  2909  	// checkpoint since the validity is verified via the checkpoints (all
  2910  	// transactions are included in the merkle root hash and any changes
  2911  	// will therefore be detected by the next checkpoint).  This is a huge
  2912  	// optimization because running the scripts is the most time consuming
  2913  	// portion of block handling.
  2914  	checkpoint := b.latestCheckpoint()
  2915  	runScripts := !b.noVerify
  2916  	if checkpoint != nil && node.height <= checkpoint.Height {
  2917  		runScripts = false
  2918  	}
  2919  	var scriptFlags txscript.ScriptFlags
  2920  	if runScripts {
  2921  		var err error
  2922  		scriptFlags, err = b.consensusScriptVerifyFlags(node)
  2923  		if err != nil {
  2924  			return err
  2925  		}
  2926  	}
  2927  
  2928  	// Create a view which preserves the expected consensus semantics for
  2929  	// relative lock times via sequence numbers once the stake vote for the
  2930  	// agenda is active.
  2931  	legacySeqLockView := view
  2932  	lnFeaturesActive, err := b.isLNFeaturesAgendaActive(node.parent)
  2933  	if err != nil {
  2934  		return err
  2935  	}
  2936  	fixSeqLocksActive, err := b.isFixSeqLocksAgendaActive(node.parent)
  2937  	if err != nil {
  2938  		return err
  2939  	}
  2940  	if lnFeaturesActive && !fixSeqLocksActive {
  2941  		var err error
  2942  		legacySeqLockView, err = b.createLegacySeqLockView(block, parent,
  2943  			view)
  2944  		if err != nil {
  2945  			return err
  2946  		}
  2947  	}
  2948  
  2949  	// Disconnect all of the transactions in the regular transaction tree of
  2950  	// the parent if the block being checked votes against it.
  2951  	if node.height > 1 && !voteBitsApproveParent(node.voteBits) {
  2952  		err := view.disconnectDisapprovedBlock(b.db, parent)
  2953  		if err != nil {
  2954  			return err
  2955  		}
  2956  	}
  2957  
  2958  	// Ensure the stake transaction tree does not contain any transactions
  2959  	// that 'overwrite' older transactions which are not fully spent.
  2960  	err = b.checkDupTxs(block.STransactions(), view)
  2961  	if err != nil {
  2962  		log.Tracef("checkDupTxs failed for cur TxTreeStake: %v", err)
  2963  		return err
  2964  	}
  2965  
  2966  	// Load all of the utxos referenced by the inputs for all transactions
  2967  	// in the block don't already exist in the utxo view from the database.
  2968  	//
  2969  	// These utxo entries are needed for verification of things such as
  2970  	// transaction inputs, counting pay-to-script-hashes, and scripts.
  2971  	err = view.fetchInputUtxos(b.db, block)
  2972  	if err != nil {
  2973  		return err
  2974  	}
  2975  
  2976  	err = b.checkTransactionsAndConnect(0, node, block.STransactions(),
  2977  		view, stxos, false)
  2978  	if err != nil {
  2979  		log.Tracef("checkTransactionsAndConnect failed for "+
  2980  			"TxTreeStake: %v", err)
  2981  		return err
  2982  	}
  2983  
  2984  	stakeTreeFees, err := getStakeTreeFees(b.subsidyCache, node.height,
  2985  		b.chainParams, block.STransactions(), view)
  2986  	if err != nil {
  2987  		log.Tracef("getStakeTreeFees failed for TxTreeStake: %v", err)
  2988  		return err
  2989  	}
  2990  
  2991  	// Enforce all relative lock times via sequence numbers for the stake
  2992  	// transaction tree once the stake vote for the agenda is active.
  2993  	var prevMedianTime time.Time
  2994  	if lnFeaturesActive {
  2995  		// Use the past median time of the *previous* block in order
  2996  		// to determine if the transactions in the current block are
  2997  		// final.
  2998  		prevMedianTime = node.parent.CalcPastMedianTime()
  2999  
  3000  		for _, stx := range block.STransactions() {
  3001  			sequenceLock, err := b.calcSequenceLock(node, stx,
  3002  				view, true)
  3003  			if err != nil {
  3004  				return err
  3005  			}
  3006  			if !SequenceLockActive(sequenceLock, node.height,
  3007  				prevMedianTime) {
  3008  
  3009  				str := fmt.Sprintf("block contains " +
  3010  					"stake transaction whose input " +
  3011  					"sequence locks are not met")
  3012  				return ruleError(ErrUnfinalizedTx, str)
  3013  			}
  3014  		}
  3015  	}
  3016  
  3017  	if runScripts {
  3018  		err = checkBlockScripts(block, view, false, scriptFlags,
  3019  			b.sigCache)
  3020  		if err != nil {
  3021  			log.Tracef("checkBlockScripts failed; error returned "+
  3022  				"on txtreestake of cur block: %v", err)
  3023  			return err
  3024  		}
  3025  	}
  3026  
  3027  	// Ensure the regular transaction tree does not contain any transactions
  3028  	// that 'overwrite' older transactions which are not fully spent.
  3029  	err = b.checkDupTxs(block.Transactions(), view)
  3030  	if err != nil {
  3031  		log.Tracef("checkDupTxs failed for cur TxTreeRegular: %v", err)
  3032  		return err
  3033  	}
  3034  
  3035  	err = b.checkTransactionsAndConnect(stakeTreeFees, node,
  3036  		block.Transactions(), view, stxos, true)
  3037  	if err != nil {
  3038  		log.Tracef("checkTransactionsAndConnect failed for cur "+
  3039  			"TxTreeRegular: %v", err)
  3040  		return err
  3041  	}
  3042  
  3043  	// Enforce all relative lock times via sequence numbers for the regular
  3044  	// transaction tree once the stake vote for the agenda is active.
  3045  	if lnFeaturesActive {
  3046  		// Skip the coinbase since it does not have any inputs and thus
  3047  		// lock times do not apply.
  3048  		for _, tx := range block.Transactions()[1:] {
  3049  			sequenceLock, err := b.calcSequenceLock(node, tx,
  3050  				legacySeqLockView, true)
  3051  			if err != nil {
  3052  				return err
  3053  			}
  3054  			if !SequenceLockActive(sequenceLock, node.height,
  3055  				prevMedianTime) {
  3056  
  3057  				str := fmt.Sprintf("block contains " +
  3058  					"transaction whose input sequence " +
  3059  					"locks are not met")
  3060  				return ruleError(ErrUnfinalizedTx, str)
  3061  			}
  3062  		}
  3063  	}
  3064  
  3065  	if runScripts {
  3066  		err = checkBlockScripts(block, view, true, scriptFlags,
  3067  			b.sigCache)
  3068  		if err != nil {
  3069  			log.Tracef("checkBlockScripts failed; error returned "+
  3070  				"on txtreeregular of cur block: %v", err)
  3071  			return err
  3072  		}
  3073  	}
  3074  
  3075  	// First block has special rules concerning the ledger.
  3076  	if node.height == 1 {
  3077  		err := blockOneCoinbasePaysTokens(block.Transactions()[0],
  3078  			b.chainParams)
  3079  		if err != nil {
  3080  			return err
  3081  		}
  3082  	}
  3083  
  3084  	// Update the best hash for view to include this block since all of its
  3085  	// transactions have been connected.
  3086  	view.SetBestHash(&node.hash)
  3087  
  3088  	return nil
  3089  }
  3090  
  3091  // CheckConnectBlockTemplate fully validates that connecting the passed block to
  3092  // either the tip of the main chain or its parent does not violate any consensus
  3093  // rules, aside from the proof of work requirement.  The block must connect to
  3094  // the current tip of the main chain or its parent.
  3095  //
  3096  // This function is safe for concurrent access.
  3097  func (b *BlockChain) CheckConnectBlockTemplate(block *dcrutil.Block) error {
  3098  	b.chainLock.Lock()
  3099  	defer b.chainLock.Unlock()
  3100  
  3101  	// Skip the proof of work check as this is just a block template.
  3102  	flags := BFNoPoWCheck
  3103  
  3104  	// The block template must build off the current tip of the main chain
  3105  	// or its parent.
  3106  	tip := b.bestChain.Tip()
  3107  	var prevNode *blockNode
  3108  	parentHash := block.MsgBlock().Header.PrevBlock
  3109  	if parentHash == tip.hash {
  3110  		prevNode = tip
  3111  	} else if tip.parent != nil && parentHash == tip.parent.hash {
  3112  		prevNode = tip.parent
  3113  	}
  3114  	if prevNode == nil {
  3115  		var str string
  3116  		if tip.parent != nil {
  3117  			str = fmt.Sprintf("previous block must be the current chain tip "+
  3118  				"%s or its parent %s, but got %s", tip.hash, tip.parent.hash,
  3119  				parentHash)
  3120  		} else {
  3121  			str = fmt.Sprintf("previous block must be the current chain tip "+
  3122  				"%s, but got %s", tip.hash, parentHash)
  3123  		}
  3124  		return ruleError(ErrInvalidTemplateParent, str)
  3125  	}
  3126  
  3127  	// Perform context-free sanity checks on the block and its transactions.
  3128  	err := checkBlockSanity(block, b.timeSource, flags, b.chainParams)
  3129  	if err != nil {
  3130  		return err
  3131  	}
  3132  
  3133  	// The block must pass all of the validation rules which depend on having
  3134  	// the headers of all ancestors available, but do not rely on having the
  3135  	// full block data of all ancestors available.
  3136  	err = b.checkBlockPositional(block, prevNode, flags)
  3137  	if err != nil {
  3138  		return err
  3139  	}
  3140  
  3141  	// The block must pass all of the validation rules which depend on having
  3142  	// the full block data for all of its ancestors available.
  3143  	err = b.checkBlockContext(block, prevNode, flags)
  3144  	if err != nil {
  3145  		return err
  3146  	}
  3147  
  3148  	newNode := newBlockNode(&block.MsgBlock().Header, prevNode)
  3149  	newNode.populateTicketInfo(stake.FindSpentTicketsInBlock(block.MsgBlock()))
  3150  
  3151  	// Use the chain state as is when extending the main (best) chain.
  3152  	if prevNode.hash == tip.hash {
  3153  		// Grab the parent block since it is required throughout the block
  3154  		// connection process.
  3155  		parent, err := b.fetchMainChainBlockByNode(prevNode)
  3156  		if err != nil {
  3157  			return ruleError(ErrMissingParent, err.Error())
  3158  		}
  3159  
  3160  		view := NewUtxoViewpoint()
  3161  		view.SetBestHash(&tip.hash)
  3162  
  3163  		return b.checkConnectBlock(newNode, block, parent, view, nil)
  3164  	}
  3165  
  3166  	// At this point, the block template must be building on the parent of the
  3167  	// current tip due to the previous checks, so undo the transactions and
  3168  	// spend information for the tip block to reach the point of view of the
  3169  	// block template.
  3170  	view := NewUtxoViewpoint()
  3171  	view.SetBestHash(&tip.hash)
  3172  	tipBlock, err := b.fetchMainChainBlockByNode(tip)
  3173  	if err != nil {
  3174  		return err
  3175  	}
  3176  	parent, err := b.fetchMainChainBlockByNode(tip.parent)
  3177  	if err != nil {
  3178  		return err
  3179  	}
  3180  
  3181  	// Load all of the spent txos for the tip block from the spend journal.
  3182  	var stxos []spentTxOut
  3183  	err = b.db.View(func(dbTx database.Tx) error {
  3184  		stxos, err = dbFetchSpendJournalEntry(dbTx, tipBlock)
  3185  		return err
  3186  	})
  3187  	if err != nil {
  3188  		return err
  3189  	}
  3190  
  3191  	// Update the view to unspend all of the spent txos and remove the utxos
  3192  	// created by the tip block.  Also, if the block votes against its parent,
  3193  	// reconnect all of the regular transactions.
  3194  	err = view.disconnectBlock(b.db, tipBlock, parent, stxos)
  3195  	if err != nil {
  3196  		return err
  3197  	}
  3198  
  3199  	// The view is now from the point of view of the parent of the current tip
  3200  	// block.  Ensure the block template can be connected without violating any
  3201  	// rules.
  3202  	return b.checkConnectBlock(newNode, block, parent, view, nil)
  3203  }