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

     1  // Copyright (c) 2016-2019 The Decred developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package chaingen
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"math"
    12  	"math/big"
    13  	"runtime"
    14  	"sort"
    15  	"time"
    16  
    17  	"github.com/decred/dcrd/chaincfg"
    18  	"github.com/decred/dcrd/chaincfg/chainhash"
    19  	"github.com/decred/dcrd/dcrutil"
    20  	"github.com/decred/dcrd/txscript"
    21  	"github.com/decred/dcrd/wire"
    22  )
    23  
    24  var (
    25  	// hash256prngSeedConst is a constant derived from the hex
    26  	// representation of pi and is used in conjunction with a caller-provided
    27  	// seed when initializing the deterministic lottery prng.
    28  	hash256prngSeedConst = []byte{0x24, 0x3f, 0x6a, 0x88, 0x85, 0xa3, 0x08,
    29  		0xd3}
    30  
    31  	// opTrueScript is a simple public key script that contains the OP_TRUE
    32  	// opcode.  It is defined here to reduce garbage creation.
    33  	opTrueScript = []byte{txscript.OP_TRUE}
    34  
    35  	// opTrueRedeemScript is the signature script that can be used to redeem
    36  	// a p2sh output to the opTrueScript.  It is defined here to reduce
    37  	// garbage creation.
    38  	opTrueRedeemScript = []byte{txscript.OP_DATA_1, txscript.OP_TRUE}
    39  
    40  	// coinbaseSigScript is the signature script used by the tests when
    41  	// creating standard coinbase transactions.  It is defined here to
    42  	// reduce garbage creation.
    43  	coinbaseSigScript = []byte{txscript.OP_0, txscript.OP_0}
    44  )
    45  
    46  const (
    47  	// voteBitYes is the specific bit that is set in the vote bits to
    48  	// indicate that the previous block is valid.
    49  	voteBitYes = 0x01
    50  )
    51  
    52  // SpendableOut represents a transaction output that is spendable along with
    53  // additional metadata such as the block its in and how much it pays.
    54  type SpendableOut struct {
    55  	prevOut     wire.OutPoint
    56  	blockHeight uint32
    57  	blockIndex  uint32
    58  	amount      dcrutil.Amount
    59  }
    60  
    61  // PrevOut returns the outpoint associated with the spendable output.
    62  func (s *SpendableOut) PrevOut() wire.OutPoint {
    63  	return s.prevOut
    64  }
    65  
    66  // BlockHeight returns the block height of the block the spendable output is in.
    67  func (s *SpendableOut) BlockHeight() uint32 {
    68  	return s.blockHeight
    69  }
    70  
    71  // BlockIndex returns the offset into the block the spendable output is in.
    72  func (s *SpendableOut) BlockIndex() uint32 {
    73  	return s.blockIndex
    74  }
    75  
    76  // Amount returns the amount associated with the spendable output.
    77  func (s *SpendableOut) Amount() dcrutil.Amount {
    78  	return s.amount
    79  }
    80  
    81  // makeSpendableOutForTxInternal returns a spendable output for the given
    82  // transaction block height, transaction index within the block, transaction
    83  // tree and transaction output index within the transaction.
    84  func makeSpendableOutForTxInternal(tx *wire.MsgTx, blockHeight, txIndex, txOutIndex uint32, tree int8) SpendableOut {
    85  	return SpendableOut{
    86  		prevOut: wire.OutPoint{
    87  			Hash:  *tx.CachedTxHash(),
    88  			Index: txOutIndex,
    89  			Tree:  tree,
    90  		},
    91  		blockHeight: blockHeight,
    92  		blockIndex:  txIndex,
    93  		amount:      dcrutil.Amount(tx.TxOut[txOutIndex].Value),
    94  	}
    95  }
    96  
    97  // MakeSpendableOutForTx returns a spendable output for a regular transaction.
    98  func MakeSpendableOutForTx(tx *wire.MsgTx, blockHeight, txIndex, txOutIndex uint32) SpendableOut {
    99  	return makeSpendableOutForTxInternal(tx, blockHeight, txIndex, txOutIndex, wire.TxTreeRegular)
   100  }
   101  
   102  // MakeSpendableOutForSTx returns a spendable output for a stake transaction.
   103  func MakeSpendableOutForSTx(tx *wire.MsgTx, blockHeight, txIndex, txOutIndex uint32) SpendableOut {
   104  	return makeSpendableOutForTxInternal(tx, blockHeight, txIndex, txOutIndex, wire.TxTreeStake)
   105  }
   106  
   107  // MakeSpendableOut returns a spendable output for the given block, transaction
   108  // index within the block, and transaction output index within the transaction.
   109  func MakeSpendableOut(block *wire.MsgBlock, txIndex, txOutIndex uint32) SpendableOut {
   110  	tx := block.Transactions[txIndex]
   111  	return MakeSpendableOutForTx(tx, block.Header.Height, txIndex, txOutIndex)
   112  }
   113  
   114  // MakeSpendableStakeOut returns a spendable stake output for the given block,
   115  // transaction index within the block, and transaction output index within the
   116  // transaction.
   117  func MakeSpendableStakeOut(block *wire.MsgBlock, txIndex, txOutIndex uint32) SpendableOut {
   118  	tx := block.STransactions[txIndex]
   119  	return MakeSpendableOutForSTx(tx, block.Header.Height, txIndex, txOutIndex)
   120  }
   121  
   122  // stakeTicket represents a transaction that is an sstx along with the height of
   123  // the block it was mined in and the its index within that block.
   124  type stakeTicket struct {
   125  	tx          *wire.MsgTx
   126  	blockHeight uint32
   127  	blockIndex  uint32
   128  }
   129  
   130  // stakeTicketSorter implements sort.Interface to allow a slice of stake tickets
   131  // to be sorted.
   132  type stakeTicketSorter []*stakeTicket
   133  
   134  // Len returns the number of stake tickets in the slice.  It is part of the
   135  // sort.Interface implementation.
   136  func (t stakeTicketSorter) Len() int { return len(t) }
   137  
   138  // Swap swaps the stake tickets at the passed indices.  It is part of the
   139  // sort.Interface implementation.
   140  func (t stakeTicketSorter) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
   141  
   142  // Less returns whether the stake ticket with index i should sort before the
   143  // stake ticket with index j.  It is part of the sort.Interface implementation.
   144  func (t stakeTicketSorter) Less(i, j int) bool {
   145  	iHash := t[i].tx.CachedTxHash()[:]
   146  	jHash := t[j].tx.CachedTxHash()[:]
   147  	return bytes.Compare(iHash, jHash) < 0
   148  }
   149  
   150  // Generator houses state used to ease the process of generating test blocks
   151  // that build from one another along with housing other useful things such as
   152  // available spendable outputs and generic payment scripts used throughout the
   153  // tests.
   154  type Generator struct {
   155  	params           *chaincfg.Params
   156  	tip              *wire.MsgBlock
   157  	tipName          string
   158  	blocks           map[chainhash.Hash]*wire.MsgBlock
   159  	blockHeights     map[chainhash.Hash]uint32
   160  	blocksByName     map[string]*wire.MsgBlock
   161  	p2shOpTrueAddr   dcrutil.Address
   162  	p2shOpTrueScript []byte
   163  
   164  	// Used for tracking spendable coinbase outputs.
   165  	spendableOuts     [][]SpendableOut
   166  	prevCollectedHash chainhash.Hash
   167  
   168  	// Used for tracking the live ticket pool and revocations.
   169  	originalParents map[chainhash.Hash]chainhash.Hash
   170  	immatureTickets []*stakeTicket
   171  	liveTickets     []*stakeTicket
   172  	wonTickets      map[chainhash.Hash][]*stakeTicket
   173  	expiredTickets  []*stakeTicket
   174  	revokedTickets  map[chainhash.Hash][]*stakeTicket
   175  	missedVotes     map[chainhash.Hash]*stakeTicket
   176  }
   177  
   178  // MakeGenerator returns a generator instance initialized with the genesis block
   179  // as the tip as well as a cached generic pay-to-script-hash script for OP_TRUE.
   180  func MakeGenerator(params *chaincfg.Params) (Generator, error) {
   181  	// Generate a generic pay-to-script-hash script that is a simple
   182  	// OP_TRUE.  This allows the tests to avoid needing to generate and
   183  	// track actual public keys and signatures.
   184  	p2shOpTrueAddr, err := dcrutil.NewAddressScriptHash(opTrueScript, params)
   185  	if err != nil {
   186  		return Generator{}, err
   187  	}
   188  	p2shOpTrueScript, err := txscript.PayToAddrScript(p2shOpTrueAddr)
   189  	if err != nil {
   190  		return Generator{}, err
   191  	}
   192  
   193  	genesis := params.GenesisBlock
   194  	genesisHash := genesis.BlockHash()
   195  	return Generator{
   196  		params:           params,
   197  		tip:              genesis,
   198  		tipName:          "genesis",
   199  		blocks:           map[chainhash.Hash]*wire.MsgBlock{genesisHash: genesis},
   200  		blockHeights:     map[chainhash.Hash]uint32{genesis.BlockHash(): 0},
   201  		blocksByName:     map[string]*wire.MsgBlock{"genesis": genesis},
   202  		p2shOpTrueAddr:   p2shOpTrueAddr,
   203  		p2shOpTrueScript: p2shOpTrueScript,
   204  		originalParents:  make(map[chainhash.Hash]chainhash.Hash),
   205  		wonTickets:       make(map[chainhash.Hash][]*stakeTicket),
   206  		revokedTickets:   make(map[chainhash.Hash][]*stakeTicket),
   207  		missedVotes:      make(map[chainhash.Hash]*stakeTicket),
   208  	}, nil
   209  }
   210  
   211  // Params returns the chain params associated with the generator instance.
   212  func (g *Generator) Params() *chaincfg.Params {
   213  	return g.params
   214  }
   215  
   216  // Tip returns the current tip block of the generator instance.
   217  func (g *Generator) Tip() *wire.MsgBlock {
   218  	return g.tip
   219  }
   220  
   221  // TipName returns the name of the current tip block of the generator instance.
   222  func (g *Generator) TipName() string {
   223  	return g.tipName
   224  }
   225  
   226  // P2shOpTrueAddr returns the generator p2sh script that is composed with
   227  // a single OP_TRUE.
   228  func (g *Generator) P2shOpTrueAddr() dcrutil.Address {
   229  	return g.p2shOpTrueAddr
   230  }
   231  
   232  // BlockByName returns the block associated with the provided block name.  It
   233  // will panic if the specified block name does not exist.
   234  func (g *Generator) BlockByName(blockName string) *wire.MsgBlock {
   235  	block, ok := g.blocksByName[blockName]
   236  	if !ok {
   237  		panic(fmt.Sprintf("block name %s does not exist", blockName))
   238  	}
   239  	return block
   240  }
   241  
   242  // BlockByHash returns the block associated with the provided block hash.  It
   243  // will panic if the specified block hash does not exist.
   244  func (g *Generator) BlockByHash(hash *chainhash.Hash) *wire.MsgBlock {
   245  	block, ok := g.blocks[*hash]
   246  	if !ok {
   247  		panic(fmt.Sprintf("block with hash %s does not exist", hash))
   248  	}
   249  	return block
   250  }
   251  
   252  // blockHeight returns the block height associated with the provided block hash.
   253  // It will panic if the specified block hash does not exist.
   254  func (g *Generator) blockHeight(hash chainhash.Hash) uint32 {
   255  	height, ok := g.blockHeights[hash]
   256  	if !ok {
   257  		panic(fmt.Sprintf("no block height found for block %s", hash))
   258  	}
   259  	return height
   260  }
   261  
   262  // opReturnScript returns a provably-pruneable OP_RETURN script with the
   263  // provided data.
   264  func opReturnScript(data []byte) []byte {
   265  	builder := txscript.NewScriptBuilder()
   266  	script, err := builder.AddOp(txscript.OP_RETURN).AddData(data).Script()
   267  	if err != nil {
   268  		panic(err)
   269  	}
   270  	return script
   271  }
   272  
   273  // UniqueOpReturnScript returns a standard provably-pruneable OP_RETURN script
   274  // with a random uint64 encoded as the data.
   275  func UniqueOpReturnScript() []byte {
   276  	rand, err := wire.RandomUint64()
   277  	if err != nil {
   278  		panic(err)
   279  	}
   280  
   281  	data := make([]byte, 8)
   282  	binary.LittleEndian.PutUint64(data[0:8], rand)
   283  	return opReturnScript(data)
   284  }
   285  
   286  // calcFullSubsidy returns the full block subsidy for the given block height.
   287  //
   288  // NOTE: This and the other subsidy calculation funcs intentionally are not
   289  // using the blockchain code since the intent is to be able to generate known
   290  // good tests which exercise that code, so it wouldn't make sense to use the
   291  // same code to generate them.
   292  func (g *Generator) calcFullSubsidy(blockHeight uint32) dcrutil.Amount {
   293  	iterations := int64(blockHeight) / g.params.SubsidyReductionInterval
   294  	subsidy := g.params.BaseSubsidy
   295  	for i := int64(0); i < iterations; i++ {
   296  		subsidy *= g.params.MulSubsidy
   297  		subsidy /= g.params.DivSubsidy
   298  	}
   299  	return dcrutil.Amount(subsidy)
   300  }
   301  
   302  // calcPoWSubsidy returns the proof-of-work subsidy portion from a given full
   303  // subsidy, block height, and number of votes that will be included in the
   304  // block.
   305  //
   306  // NOTE: This and the other subsidy calculation funcs intentionally are not
   307  // using the blockchain code since the intent is to be able to generate known
   308  // good tests which exercise that code, so it wouldn't make sense to use the
   309  // same code to generate them.
   310  func (g *Generator) calcPoWSubsidy(fullSubsidy dcrutil.Amount, blockHeight uint32, numVotes uint16) dcrutil.Amount {
   311  	powProportion := dcrutil.Amount(g.params.WorkRewardProportion)
   312  	totalProportions := dcrutil.Amount(g.params.TotalSubsidyProportions())
   313  	powSubsidy := (fullSubsidy * powProportion) / totalProportions
   314  	if int64(blockHeight) < g.params.StakeValidationHeight {
   315  		return powSubsidy
   316  	}
   317  
   318  	// Reduce the subsidy according to the number of votes.
   319  	ticketsPerBlock := dcrutil.Amount(g.params.TicketsPerBlock)
   320  	return (powSubsidy * dcrutil.Amount(numVotes)) / ticketsPerBlock
   321  }
   322  
   323  // calcPoSSubsidy returns the proof-of-stake subsidy portion for a given block
   324  // height being voted on.
   325  //
   326  // NOTE: This and the other subsidy calculation funcs intentionally are not
   327  // using the blockchain code since the intent is to be able to generate known
   328  // good tests which exercise that code, so it wouldn't make sense to use the
   329  // same code to generate them.
   330  func (g *Generator) calcPoSSubsidy(heightVotedOn uint32) dcrutil.Amount {
   331  	if int64(heightVotedOn+1) < g.params.StakeValidationHeight {
   332  		return 0
   333  	}
   334  
   335  	fullSubsidy := g.calcFullSubsidy(heightVotedOn)
   336  	posProportion := dcrutil.Amount(g.params.StakeRewardProportion)
   337  	totalProportions := dcrutil.Amount(g.params.TotalSubsidyProportions())
   338  	return (fullSubsidy * posProportion) / totalProportions
   339  }
   340  
   341  // calcDevSubsidy returns the dev org subsidy portion from a given full subsidy.
   342  //
   343  // NOTE: This and the other subsidy calculation funcs intentionally are not
   344  // using the blockchain code since the intent is to be able to generate known
   345  // good tests which exercise that code, so it wouldn't make sense to use the
   346  // same code to generate them.
   347  func (g *Generator) calcDevSubsidy(fullSubsidy dcrutil.Amount, blockHeight uint32, numVotes uint16) dcrutil.Amount {
   348  	devProportion := dcrutil.Amount(g.params.BlockTaxProportion)
   349  	totalProportions := dcrutil.Amount(g.params.TotalSubsidyProportions())
   350  	devSubsidy := (fullSubsidy * devProportion) / totalProportions
   351  	if int64(blockHeight) < g.params.StakeValidationHeight {
   352  		return devSubsidy
   353  	}
   354  
   355  	// Reduce the subsidy according to the number of votes.
   356  	ticketsPerBlock := dcrutil.Amount(g.params.TicketsPerBlock)
   357  	return (devSubsidy * dcrutil.Amount(numVotes)) / ticketsPerBlock
   358  }
   359  
   360  // standardCoinbaseOpReturnScript returns a standard script suitable for use as
   361  // the second output of a standard coinbase transaction of a new block.  In
   362  // particular, the serialized data used with the OP_RETURN starts with the block
   363  // height and is followed by 32 bytes which are treated as 4 uint64 extra
   364  // nonces.  This implementation puts a cryptographically random value into the
   365  // final extra nonce position.  The actual format of the data after the block
   366  // height is not defined however this effectively mirrors the actual mining code
   367  // at the time it was written.
   368  func standardCoinbaseOpReturnScript(blockHeight uint32) []byte {
   369  	rand, err := wire.RandomUint64()
   370  	if err != nil {
   371  		panic(err)
   372  	}
   373  
   374  	data := make([]byte, 36)
   375  	binary.LittleEndian.PutUint32(data[0:4], blockHeight)
   376  	binary.LittleEndian.PutUint64(data[28:36], rand)
   377  	return opReturnScript(data)
   378  }
   379  
   380  // addCoinbaseTxOutputs adds the following outputs to the provided transaction
   381  // which is assumed to be a coinbase transaction:
   382  // - First output pays the development subsidy portion to the dev org
   383  // - Second output is a standard provably prunable data-only coinbase output
   384  // - Third and subsequent outputs pay the pow subsidy portion to the generic
   385  //   OP_TRUE p2sh script hash
   386  func (g *Generator) addCoinbaseTxOutputs(tx *wire.MsgTx, blockHeight uint32, devSubsidy, powSubsidy dcrutil.Amount) {
   387  	// First output is the developer subsidy.
   388  	tx.AddTxOut(&wire.TxOut{
   389  		Value:    int64(devSubsidy),
   390  		Version:  g.params.OrganizationPkScriptVersion,
   391  		PkScript: g.params.OrganizationPkScript,
   392  	})
   393  
   394  	// Second output is a provably prunable data-only output that is used
   395  	// to ensure the coinbase is unique.
   396  	tx.AddTxOut(wire.NewTxOut(0, standardCoinbaseOpReturnScript(blockHeight)))
   397  
   398  	// Final outputs are the proof-of-work subsidy split into more than one
   399  	// output.  These are in turn used throughout the tests as inputs to
   400  	// other transactions such as ticket purchases and additional spend
   401  	// transactions.
   402  	const numPoWOutputs = 6
   403  	amount := powSubsidy / numPoWOutputs
   404  	for i := 0; i < numPoWOutputs; i++ {
   405  		if i == numPoWOutputs-1 {
   406  			amount = powSubsidy - amount*(numPoWOutputs-1)
   407  		}
   408  		tx.AddTxOut(wire.NewTxOut(int64(amount), g.p2shOpTrueScript))
   409  	}
   410  }
   411  
   412  // CreateCoinbaseTx returns a coinbase transaction paying an appropriate
   413  // subsidy based on the passed block height and number of votes to the dev org
   414  // and proof-of-work miner.
   415  //
   416  // See the addCoinbaseTxOutputs documentation for a breakdown of the outputs
   417  // the transaction contains.
   418  func (g *Generator) CreateCoinbaseTx(blockHeight uint32, numVotes uint16) *wire.MsgTx {
   419  	// Calculate the subsidy proportions based on the block height and the
   420  	// number of votes the block will include.
   421  	fullSubsidy := g.calcFullSubsidy(blockHeight)
   422  	devSubsidy := g.calcDevSubsidy(fullSubsidy, blockHeight, numVotes)
   423  	powSubsidy := g.calcPoWSubsidy(fullSubsidy, blockHeight, numVotes)
   424  
   425  	tx := wire.NewMsgTx()
   426  	tx.AddTxIn(&wire.TxIn{
   427  		// Coinbase transactions have no inputs, so previous outpoint is
   428  		// zero hash and max index.
   429  		PreviousOutPoint: *wire.NewOutPoint(&chainhash.Hash{},
   430  			wire.MaxPrevOutIndex, wire.TxTreeRegular),
   431  		Sequence:        wire.MaxTxInSequenceNum,
   432  		ValueIn:         int64(devSubsidy + powSubsidy),
   433  		BlockHeight:     wire.NullBlockHeight,
   434  		BlockIndex:      wire.NullBlockIndex,
   435  		SignatureScript: coinbaseSigScript,
   436  	})
   437  
   438  	g.addCoinbaseTxOutputs(tx, blockHeight, devSubsidy, powSubsidy)
   439  
   440  	return tx
   441  }
   442  
   443  // PurchaseCommitmentScript returns a standard provably-pruneable OP_RETURN
   444  // commitment script suitable for use in a ticket purchase tx (sstx) using the
   445  // provided target address, amount, and fee limits.
   446  func PurchaseCommitmentScript(addr dcrutil.Address, amount, voteFeeLimit, revocationFeeLimit dcrutil.Amount) []byte {
   447  	// The limits are defined in terms of the closest base 2 exponent and
   448  	// a bit that must be set to specify the limit is to be applied.  The
   449  	// vote fee exponent is in the bottom 8 bits, while the revocation fee
   450  	// exponent is in the upper 8 bits.
   451  	limits := uint16(0)
   452  	if voteFeeLimit != 0 {
   453  		exp := uint16(math.Ceil(math.Log2(float64(voteFeeLimit))))
   454  		limits |= (exp | 0x40)
   455  	}
   456  	if revocationFeeLimit != 0 {
   457  		exp := uint16(math.Ceil(math.Log2(float64(revocationFeeLimit))))
   458  		limits |= ((exp | 0x40) << 8)
   459  	}
   460  
   461  	// The data consists of the 20-byte raw script address for the given
   462  	// address, 8 bytes for the amount to commit to (with the upper bit flag
   463  	// set to indicate a pay-to-script-hash address), and 2 bytes for the
   464  	// fee limits.
   465  	var data [30]byte
   466  	copy(data[:], addr.ScriptAddress())
   467  	binary.LittleEndian.PutUint64(data[20:], uint64(amount))
   468  	data[27] |= 1 << 7
   469  	binary.LittleEndian.PutUint16(data[28:], limits)
   470  	script, err := txscript.NewScriptBuilder().AddOp(txscript.OP_RETURN).
   471  		AddData(data[:]).Script()
   472  	if err != nil {
   473  		panic(err)
   474  	}
   475  	return script
   476  }
   477  
   478  // CreateTicketPurchaseTx creates a new transaction that spends the provided
   479  // output to purchase a stake submission ticket (sstx) at the given ticket
   480  // price.  Both the ticket and the change will go to a p2sh script that is
   481  // composed with a single OP_TRUE.
   482  //
   483  // The transaction consists of the following outputs:
   484  // - First output is an OP_SSTX followed by the OP_TRUE p2sh script hash
   485  // - Second output is an OP_RETURN followed by the commitment script
   486  // - Third output is an OP_SSTXCHANGE followed by the OP_TRUE p2sh script hash
   487  func (g *Generator) CreateTicketPurchaseTx(spend *SpendableOut, ticketPrice, fee dcrutil.Amount) *wire.MsgTx {
   488  	// The first output is the voting rights address.  This impl uses the
   489  	// standard pay-to-script-hash to an OP_TRUE.
   490  	pkScript, err := txscript.PayToSStx(g.p2shOpTrueAddr)
   491  	if err != nil {
   492  		panic(err)
   493  	}
   494  
   495  	// Generate the commitment script.
   496  	commitScript := PurchaseCommitmentScript(g.p2shOpTrueAddr,
   497  		ticketPrice+fee, 0, ticketPrice)
   498  
   499  	// Calculate change and generate script to deliver it.
   500  	change := spend.amount - ticketPrice - fee
   501  	changeScript, err := txscript.PayToSStxChange(g.p2shOpTrueAddr)
   502  	if err != nil {
   503  		panic(err)
   504  	}
   505  
   506  	// Generate and return the transaction spending from the provided
   507  	// spendable output with the previously described outputs.
   508  	tx := wire.NewMsgTx()
   509  	tx.AddTxIn(&wire.TxIn{
   510  		PreviousOutPoint: spend.prevOut,
   511  		Sequence:         wire.MaxTxInSequenceNum,
   512  		ValueIn:          int64(spend.amount),
   513  		BlockHeight:      spend.blockHeight,
   514  		BlockIndex:       spend.blockIndex,
   515  		SignatureScript:  opTrueRedeemScript,
   516  	})
   517  	tx.AddTxOut(wire.NewTxOut(int64(ticketPrice), pkScript))
   518  	tx.AddTxOut(wire.NewTxOut(0, commitScript))
   519  	tx.AddTxOut(wire.NewTxOut(int64(change), changeScript))
   520  	return tx
   521  }
   522  
   523  // isTicketPurchaseTx returns whether or not the passed transaction is a stake
   524  // ticket purchase.
   525  //
   526  // NOTE: Like many other functions in this test code, this function
   527  // intentionally does not use the blockchain/stake package code since the intent
   528  // is to be able to generate known good tests which exercise that code, so it
   529  // wouldn't make sense to use the same code to generate them.  It must also be
   530  // noted that this function is NOT robust.  It is the minimum necessary needed
   531  // by the testing framework.
   532  func isTicketPurchaseTx(tx *wire.MsgTx) bool {
   533  	if len(tx.TxOut) == 0 {
   534  		return false
   535  	}
   536  	txOut := tx.TxOut[0]
   537  	scriptClass := txscript.GetScriptClass(txOut.Version, txOut.PkScript)
   538  	return scriptClass == txscript.StakeSubmissionTy
   539  }
   540  
   541  // isVoteTx returns whether or not the passed tx is a stake vote (ssgen).
   542  //
   543  // NOTE: Like many other functions in this test code, this function
   544  // intentionally does not use the blockchain/stake package code since the intent
   545  // is to be able to generate known good tests which exercise that code, so it
   546  // wouldn't make sense to use the same code to generate them.  It must also be
   547  // noted that this function is NOT robust.  It is the minimum necessary needed
   548  // by the testing framework.
   549  func isVoteTx(tx *wire.MsgTx) bool {
   550  	if len(tx.TxOut) < 3 {
   551  		return false
   552  	}
   553  	txOut := tx.TxOut[2]
   554  	scriptClass := txscript.GetScriptClass(txOut.Version, txOut.PkScript)
   555  	return scriptClass == txscript.StakeGenTy
   556  }
   557  
   558  // isRevocationTx returns whether or not the passed tx is a stake ticket
   559  // revocation (ssrtx).
   560  //
   561  // NOTE: Like many other functions in this test code, this function
   562  // intentionally does not use the blockchain/stake package code since the intent
   563  // is to be able to generate known good tests which exercise that code, so it
   564  // wouldn't make sense to use the same code to generate them.  It must also be
   565  // noted that this function is NOT robust.  It is the minimum necessary needed
   566  // by the testing framework.
   567  func isRevocationTx(tx *wire.MsgTx) bool {
   568  	if len(tx.TxOut) == 0 {
   569  		return false
   570  	}
   571  	txOut := tx.TxOut[0]
   572  	scriptClass := txscript.GetScriptClass(txOut.Version, txOut.PkScript)
   573  	return scriptClass == txscript.StakeRevocationTy
   574  }
   575  
   576  // VoteCommitmentScript returns a standard provably-pruneable OP_RETURN script
   577  // suitable for use in a vote tx (ssgen) given the block hash and height to vote
   578  // on.
   579  func VoteCommitmentScript(hash chainhash.Hash, height uint32) []byte {
   580  	// The vote commitment consists of a 32-byte hash of the block it is
   581  	// voting on along with its expected height as a 4-byte little-endian
   582  	// uint32.  32-byte hash + 4-byte uint32 = 36 bytes.
   583  	var data [36]byte
   584  	copy(data[:], hash[:])
   585  	binary.LittleEndian.PutUint32(data[32:], height)
   586  	script, err := txscript.NewScriptBuilder().AddOp(txscript.OP_RETURN).
   587  		AddData(data[:]).Script()
   588  	if err != nil {
   589  		panic(err)
   590  	}
   591  	return script
   592  }
   593  
   594  // voteBlockScript returns a standard provably-pruneable OP_RETURN script
   595  // suitable for use in a vote tx (ssgen) given the block to vote on.
   596  func voteBlockScript(parentBlock *wire.MsgBlock) []byte {
   597  	return VoteCommitmentScript(parentBlock.BlockHash(),
   598  		parentBlock.Header.Height)
   599  }
   600  
   601  // voteBitsScript returns a standard provably-pruneable OP_RETURN script
   602  // suitable for use in a vote tx (ssgen) with the appropriate vote bits set
   603  // depending on the provided params.
   604  func voteBitsScript(bits uint16, voteVersion uint32) []byte {
   605  	data := make([]byte, 6)
   606  	binary.LittleEndian.PutUint16(data, bits)
   607  	binary.LittleEndian.PutUint32(data[2:], voteVersion)
   608  	if voteVersion == 0 {
   609  		data = data[:2]
   610  	}
   611  	script, err := txscript.NewScriptBuilder().AddOp(txscript.OP_RETURN).
   612  		AddData(data).Script()
   613  	if err != nil {
   614  		panic(err)
   615  	}
   616  	return script
   617  }
   618  
   619  // CreateVoteTx returns a new transaction (ssgen) paying an appropriate subsidy
   620  // for the given block height (and the number of votes per block) as well as the
   621  // original commitments.
   622  //
   623  // The transaction consists of the following outputs:
   624  // - First output is an OP_RETURN followed by the block hash and height
   625  // - Second output is an OP_RETURN followed by the vote bits
   626  // - Third and subsequent outputs are the payouts according to the ticket
   627  //   commitments and the appropriate proportion of the vote subsidy.
   628  func (g *Generator) CreateVoteTx(voteBlock *wire.MsgBlock, ticketTx *wire.MsgTx, ticketBlockHeight, ticketBlockIndex uint32) *wire.MsgTx {
   629  	// Calculate the proof-of-stake subsidy proportion based on the block
   630  	// height.
   631  	posSubsidy := g.calcPoSSubsidy(voteBlock.Header.Height)
   632  	voteSubsidy := posSubsidy / dcrutil.Amount(g.params.TicketsPerBlock)
   633  	ticketPrice := dcrutil.Amount(ticketTx.TxOut[0].Value)
   634  
   635  	// The first output is the block (hash and height) the vote is for.
   636  	blockScript := voteBlockScript(voteBlock)
   637  
   638  	// The second output is the vote bits.
   639  	voteScript := voteBitsScript(voteBitYes, 0)
   640  
   641  	// The third and subsequent outputs pay the original commitment amounts
   642  	// along with the appropriate portion of the vote subsidy.  This impl
   643  	// uses the standard pay-to-script-hash to an OP_TRUE.
   644  	stakeGenScript, err := txscript.PayToSSGen(g.p2shOpTrueAddr)
   645  	if err != nil {
   646  		panic(err)
   647  	}
   648  
   649  	// Generate and return the transaction with the proof-of-stake subsidy
   650  	// coinbase and spending from the provided ticket along with the
   651  	// previously described outputs.
   652  	ticketHash := ticketTx.CachedTxHash()
   653  	tx := wire.NewMsgTx()
   654  	tx.AddTxIn(&wire.TxIn{
   655  		PreviousOutPoint: *wire.NewOutPoint(&chainhash.Hash{},
   656  			wire.MaxPrevOutIndex, wire.TxTreeRegular),
   657  		Sequence:        wire.MaxTxInSequenceNum,
   658  		ValueIn:         int64(voteSubsidy),
   659  		BlockHeight:     wire.NullBlockHeight,
   660  		BlockIndex:      wire.NullBlockIndex,
   661  		SignatureScript: g.params.StakeBaseSigScript,
   662  	})
   663  	tx.AddTxIn(&wire.TxIn{
   664  		PreviousOutPoint: *wire.NewOutPoint(ticketHash, 0,
   665  			wire.TxTreeStake),
   666  		Sequence:        wire.MaxTxInSequenceNum,
   667  		ValueIn:         int64(ticketPrice),
   668  		BlockHeight:     ticketBlockHeight,
   669  		BlockIndex:      ticketBlockIndex,
   670  		SignatureScript: opTrueRedeemScript,
   671  	})
   672  	tx.AddTxOut(wire.NewTxOut(0, blockScript))
   673  	tx.AddTxOut(wire.NewTxOut(0, voteScript))
   674  	tx.AddTxOut(wire.NewTxOut(int64(voteSubsidy+ticketPrice), stakeGenScript))
   675  	return tx
   676  }
   677  
   678  // createVoteTxFromTicket returns a new transaction (ssgen) paying an appropriate subsidy
   679  // for the given block height (and the number of votes per block) as well as the
   680  // original commitments. It requires a stake ticket as a parameter.
   681  func (g *Generator) createVoteTxFromTicket(voteBlock *wire.MsgBlock, ticket *stakeTicket) *wire.MsgTx {
   682  	return g.CreateVoteTx(voteBlock, ticket.tx, ticket.blockHeight, ticket.blockIndex)
   683  }
   684  
   685  // CreateRevocationTx returns a new transaction (ssrtx) refunding the ticket
   686  // price for a ticket which either missed its vote or expired.
   687  //
   688  // The transaction consists of the following inputs:
   689  // - The outpoint of the ticket that was missed or expired.
   690  //
   691  // The transaction consists of the following outputs:
   692  // - The payouts according to the ticket commitments.
   693  func (g *Generator) CreateRevocationTx(ticketTx *wire.MsgTx, ticketBlockHeight, ticketBlockIndex uint32) *wire.MsgTx {
   694  	// The outputs pay the original commitment amounts.  This impl uses the
   695  	// standard pay-to-script-hash to an OP_TRUE.
   696  	revokeScript, err := txscript.PayToSSRtx(g.p2shOpTrueAddr)
   697  	if err != nil {
   698  		panic(err)
   699  	}
   700  
   701  	// Generate and return the transaction spending from the provided ticket
   702  	// along with the previously described outputs.
   703  	ticketPrice := ticketTx.TxOut[0].Value
   704  	ticketHash := ticketTx.CachedTxHash()
   705  	tx := wire.NewMsgTx()
   706  	tx.AddTxIn(&wire.TxIn{
   707  		PreviousOutPoint: *wire.NewOutPoint(ticketHash, 0,
   708  			wire.TxTreeStake),
   709  		Sequence:        wire.MaxTxInSequenceNum,
   710  		ValueIn:         ticketPrice,
   711  		BlockHeight:     ticketBlockHeight,
   712  		BlockIndex:      ticketBlockIndex,
   713  		SignatureScript: opTrueRedeemScript,
   714  	})
   715  	tx.AddTxOut(wire.NewTxOut(ticketPrice, revokeScript))
   716  	return tx
   717  }
   718  
   719  // CreateRevocationTxFromTicket returns a new transaction (ssrtx) refunding
   720  // the ticket price for a ticket which either missed its vote or expired.
   721  // It requires a stake ticket as a parameter.
   722  func (g *Generator) createRevocationTxFromTicket(ticket *stakeTicket) *wire.MsgTx {
   723  	return g.CreateRevocationTx(ticket.tx, ticket.blockHeight, ticket.blockIndex)
   724  }
   725  
   726  // ancestorBlock returns the ancestor block at the provided height by following
   727  // the chain backwards from the given block.  The returned block will be nil
   728  // when a height is requested that is after the height of the passed block.
   729  // Also, a callback can optionally be provided that is invoked with each block
   730  // as it traverses.
   731  func (g *Generator) ancestorBlock(block *wire.MsgBlock, height uint32, f func(*wire.MsgBlock)) *wire.MsgBlock {
   732  	// Nothing to do if the requested height is outside of the valid
   733  	// range.
   734  	if block == nil || height > block.Header.Height {
   735  		return nil
   736  	}
   737  
   738  	// Iterate backwards until the requested height is reached.
   739  	for block != nil && block.Header.Height > height {
   740  		block = g.blocks[block.Header.PrevBlock]
   741  		if f != nil && block != nil {
   742  			f(block)
   743  		}
   744  	}
   745  
   746  	return block
   747  }
   748  
   749  // mergeDifficulty takes an original stake difficulty and two new, scaled
   750  // stake difficulties, merges the new difficulties, and outputs a new
   751  // merged stake difficulty.
   752  func mergeDifficulty(oldDiff int64, newDiff1 int64, newDiff2 int64) int64 {
   753  	newDiff1Big := big.NewInt(newDiff1)
   754  	newDiff2Big := big.NewInt(newDiff2)
   755  	newDiff2Big.Lsh(newDiff2Big, 32)
   756  
   757  	oldDiffBig := big.NewInt(oldDiff)
   758  	oldDiffBigLSH := big.NewInt(oldDiff)
   759  	oldDiffBigLSH.Lsh(oldDiffBig, 32)
   760  
   761  	newDiff1Big.Div(oldDiffBigLSH, newDiff1Big)
   762  	newDiff2Big.Div(newDiff2Big, oldDiffBig)
   763  
   764  	// Combine the two changes in difficulty.
   765  	summedChange := big.NewInt(0)
   766  	summedChange.Set(newDiff2Big)
   767  	summedChange.Lsh(summedChange, 32)
   768  	summedChange.Div(summedChange, newDiff1Big)
   769  	summedChange.Mul(summedChange, oldDiffBig)
   770  	summedChange.Rsh(summedChange, 32)
   771  
   772  	return summedChange.Int64()
   773  }
   774  
   775  // limitRetarget clamps the passed new difficulty to the old one adjusted by the
   776  // factor specified in the chain parameters.  This ensures the difficulty can
   777  // only move up or down by a limited amount.
   778  func (g *Generator) limitRetarget(oldDiff, newDiff int64) int64 {
   779  	maxRetarget := g.params.RetargetAdjustmentFactor
   780  	switch {
   781  	case newDiff == 0:
   782  		fallthrough
   783  	case (oldDiff / newDiff) > (maxRetarget - 1):
   784  		return oldDiff / maxRetarget
   785  	case (newDiff / oldDiff) > (maxRetarget - 1):
   786  		return oldDiff * maxRetarget
   787  	}
   788  
   789  	return newDiff
   790  }
   791  
   792  // CalcNextRequiredDifficulty returns the required proof-of-work difficulty for
   793  // the block after the current tip block the generator is associated with.
   794  //
   795  // An overview of the algorithm is as follows:
   796  // 1) Use the proof-of-work limit for all blocks before the first retarget
   797  //    window
   798  // 2) Use the previous block's difficulty if the next block is not at a retarget
   799  //    interval
   800  // 3) Calculate the ideal retarget difficulty for each window based on the
   801  //    actual timespan of the window versus the target timespan and exponentially
   802  //    weight each difficulty such that the most recent window has the highest
   803  //    weight
   804  // 4) Calculate the final retarget difficulty based on the exponential weighted
   805  //    average and ensure it is limited to the max retarget adjustment factor
   806  func (g *Generator) CalcNextRequiredDifficulty() uint32 {
   807  	// Target difficulty before the first retarget interval is the pow
   808  	// limit.
   809  	nextHeight := g.tip.Header.Height + 1
   810  	windowSize := g.params.WorkDiffWindowSize
   811  	if int64(nextHeight) < windowSize {
   812  		return g.params.PowLimitBits
   813  	}
   814  
   815  	// Return the previous block's difficulty requirements if the next block
   816  	// is not at a difficulty retarget interval.
   817  	curDiff := int64(g.tip.Header.Bits)
   818  	if int64(nextHeight)%windowSize != 0 {
   819  		return uint32(curDiff)
   820  	}
   821  
   822  	// Calculate the ideal retarget difficulty for each window based on the
   823  	// actual time between blocks versus the target time and exponentially
   824  	// weight them.
   825  	adjustedTimespan := big.NewInt(0)
   826  	tempBig := big.NewInt(0)
   827  	weightedTimespanSum, weightSum := big.NewInt(0), big.NewInt(0)
   828  	targetTimespan := int64(g.params.TargetTimespan)
   829  	targetTimespanBig := big.NewInt(targetTimespan)
   830  	numWindows := g.params.WorkDiffWindows
   831  	weightAlpha := g.params.WorkDiffAlpha
   832  	block := g.tip
   833  	finalWindowTime := block.Header.Timestamp.UnixNano()
   834  	for i := int64(0); i < numWindows; i++ {
   835  		// Get the timestamp of the block at the start of the window and
   836  		// calculate the actual timespan accordingly.  Use the target
   837  		// timespan if there are not yet enough blocks left to cover the
   838  		// window.
   839  		actualTimespan := targetTimespan
   840  		if int64(block.Header.Height) > windowSize {
   841  			for j := int64(0); j < windowSize; j++ {
   842  				block = g.blocks[block.Header.PrevBlock]
   843  			}
   844  			startWindowTime := block.Header.Timestamp.UnixNano()
   845  			actualTimespan = finalWindowTime - startWindowTime
   846  
   847  			// Set final window time for the next window.
   848  			finalWindowTime = startWindowTime
   849  		}
   850  
   851  		// Calculate the ideal retarget difficulty for the window based
   852  		// on the actual timespan and weight it exponentially by
   853  		// multiplying it by 2^(window_number) such that the most recent
   854  		// window receives the most weight.
   855  		//
   856  		// Also, since integer division is being used, shift up the
   857  		// number of new tickets 32 bits to avoid losing precision.
   858  		//
   859  		//   windowWeightShift = ((numWindows - i) * weightAlpha)
   860  		//   adjustedTimespan = (actualTimespan << 32) / targetTimespan
   861  		//   weightedTimespanSum += adjustedTimespan << windowWeightShift
   862  		//   weightSum += 1 << windowWeightShift
   863  		windowWeightShift := uint((numWindows - i) * weightAlpha)
   864  		adjustedTimespan.SetInt64(actualTimespan)
   865  		adjustedTimespan.Lsh(adjustedTimespan, 32)
   866  		adjustedTimespan.Div(adjustedTimespan, targetTimespanBig)
   867  		adjustedTimespan.Lsh(adjustedTimespan, windowWeightShift)
   868  		weightedTimespanSum.Add(weightedTimespanSum, adjustedTimespan)
   869  		weight := tempBig.SetInt64(1)
   870  		weight.Lsh(weight, windowWeightShift)
   871  		weightSum.Add(weightSum, weight)
   872  	}
   873  
   874  	// Calculate the retarget difficulty based on the exponential weighted
   875  	// average and shift the result back down 32 bits to account for the
   876  	// previous shift up in order to avoid losing precision.  Then, limit it
   877  	// to the maximum allowed retarget adjustment factor.
   878  	//
   879  	//   nextDiff = (weightedTimespanSum/weightSum * curDiff) >> 32
   880  	curDiffBig := tempBig.SetInt64(curDiff)
   881  	weightedTimespanSum.Div(weightedTimespanSum, weightSum)
   882  	weightedTimespanSum.Mul(weightedTimespanSum, curDiffBig)
   883  	weightedTimespanSum.Rsh(weightedTimespanSum, 32)
   884  	nextDiff := weightedTimespanSum.Int64()
   885  	nextDiff = g.limitRetarget(curDiff, nextDiff)
   886  
   887  	if nextDiff > int64(g.params.PowLimitBits) {
   888  		return g.params.PowLimitBits
   889  	}
   890  	return uint32(nextDiff)
   891  }
   892  
   893  // CalcNextReqStakeDifficulty returns the required stake difficulty (aka
   894  // ticket price) for the block after the provided block the generator is
   895  // associated with.
   896  //
   897  // See the documentation of CalcNextRequiredStakeDifficulty for more details.
   898  func (g *Generator) CalcNextReqStakeDifficulty(prevBlock *wire.MsgBlock) int64 {
   899  	// Stake difficulty before any tickets could possibly be purchased is
   900  	// the minimum value.
   901  	nextHeight := prevBlock.Header.Height + 1
   902  	stakeDiffStartHeight := uint32(g.params.CoinbaseMaturity) + 1
   903  	if nextHeight < stakeDiffStartHeight {
   904  		return g.params.MinimumStakeDiff
   905  	}
   906  
   907  	// Return 0 if the current difficulty is already zero since any scaling
   908  	// of 0 is still 0.  This should never really happen since there is a
   909  	// minimum stake difficulty, but the consensus code checks the condition
   910  	// just in case, so follow suit here.
   911  	curDiff := g.tip.Header.SBits
   912  	if curDiff == 0 {
   913  		return 0
   914  	}
   915  
   916  	// Return the previous block's difficulty requirements if the next block
   917  	// is not at a difficulty retarget interval.
   918  	windowSize := g.params.StakeDiffWindowSize
   919  	if int64(nextHeight)%windowSize != 0 {
   920  		return curDiff
   921  	}
   922  
   923  	// --------------------------------
   924  	// Ideal pool size retarget metric.
   925  	// --------------------------------
   926  
   927  	// Calculate the ideal retarget difficulty for each window based on the
   928  	// actual pool size in the window versus the target pool size and
   929  	// exponentially weight them.
   930  	var weightedPoolSizeSum, weightSum uint64
   931  	ticketsPerBlock := int64(g.params.TicketsPerBlock)
   932  	targetPoolSize := ticketsPerBlock * int64(g.params.TicketPoolSize)
   933  	block := prevBlock
   934  	numWindows := g.params.StakeDiffWindows
   935  	weightAlpha := g.params.StakeDiffAlpha
   936  	for i := int64(0); i < numWindows; i++ {
   937  		// Get the pool size for the block at the start of the window.
   938  		// Use zero if there are not yet enough blocks left to cover the
   939  		// window.
   940  		prevRetargetHeight := nextHeight - uint32(windowSize*(i+1))
   941  		windowPoolSize := int64(0)
   942  		block = g.ancestorBlock(block, prevRetargetHeight, nil)
   943  		if block != nil {
   944  			windowPoolSize = int64(block.Header.PoolSize)
   945  		}
   946  
   947  		// Skew the pool size by the constant weight factor specified in
   948  		// the chain parameters (which is typically the max adjustment
   949  		// factor) in order to help weight the ticket pool size versus
   950  		// tickets per block.  Also, ensure the skewed pool size is a
   951  		// minimum of 1.
   952  		skewedPoolSize := targetPoolSize + (windowPoolSize-
   953  			targetPoolSize)*int64(g.params.TicketPoolSizeWeight)
   954  		if skewedPoolSize <= 0 {
   955  			skewedPoolSize = 1
   956  		}
   957  
   958  		// Calculate the ideal retarget difficulty for the window based
   959  		// on the skewed pool size and weight it exponentially by
   960  		// multiplying it by 2^(window_number) such that the most recent
   961  		// window receives the most weight.
   962  		//
   963  		// Also, since integer division is being used, shift up the
   964  		// number of new tickets 32 bits to avoid losing precision.
   965  		//
   966  		// NOTE: The real algorithm uses big ints, but these purpose
   967  		// built tests won't be using large enough values to overflow,
   968  		// so just use uint64s.
   969  		adjusted := (skewedPoolSize << 32) / targetPoolSize
   970  		adjusted <<= uint64((numWindows - i) * weightAlpha)
   971  		weightedPoolSizeSum += uint64(adjusted)
   972  		weightSum += 1 << uint64((numWindows-i)*weightAlpha)
   973  	}
   974  
   975  	// Calculate the pool size retarget difficulty based on the exponential
   976  	// weighted average and shift the result back down 32 bits to account
   977  	// for the previous shift up in order to avoid losing precision.  Then,
   978  	// limit it to the maximum allowed retarget adjustment factor.
   979  	//
   980  	// This is the first metric used in the final calculated difficulty.
   981  	nextPoolSizeDiff := (int64(weightedPoolSizeSum/weightSum) * curDiff) >> 32
   982  	nextPoolSizeDiff = g.limitRetarget(curDiff, nextPoolSizeDiff)
   983  
   984  	// -----------------------------------------
   985  	// Ideal tickets per window retarget metric.
   986  	// -----------------------------------------
   987  
   988  	// Calculate the ideal retarget difficulty for each window based on the
   989  	// actual number of new tickets in the window versus the target tickets
   990  	// per window and exponentially weight them.
   991  	var weightedTicketsSum uint64
   992  	targetTicketsPerWindow := ticketsPerBlock * windowSize
   993  	block = prevBlock
   994  	for i := int64(0); i < numWindows; i++ {
   995  		// Since the difficulty for the next block after the current tip
   996  		// is being calculated and there is no such block yet, the sum
   997  		// of all new tickets in the first window needs to start with
   998  		// the number of new tickets in the tip block.
   999  		var windowNewTickets int64
  1000  		if i == 0 {
  1001  			windowNewTickets = int64(block.Header.FreshStake)
  1002  		}
  1003  
  1004  		// Tally all of the new tickets in all blocks in the window and
  1005  		// ensure the number of new tickets is a minimum of 1.
  1006  		prevRetargetHeight := nextHeight - uint32(windowSize*(i+1))
  1007  		block = g.ancestorBlock(block, prevRetargetHeight, func(blk *wire.MsgBlock) {
  1008  			windowNewTickets += int64(blk.Header.FreshStake)
  1009  		})
  1010  		if windowNewTickets <= 0 {
  1011  			windowNewTickets = 1
  1012  		}
  1013  
  1014  		// Calculate the ideal retarget difficulty for the window based
  1015  		// on the number of new tickets and weight it exponentially by
  1016  		// multiplying it by 2^(window_number) such that the most recent
  1017  		// window receives the most weight.
  1018  		//
  1019  		// Also, since integer division is being used, shift up the
  1020  		// number of new tickets 32 bits to avoid losing precision.
  1021  		//
  1022  		// NOTE: The real algorithm uses big ints, but these purpose
  1023  		// built tests won't be using large enough values to overflow,
  1024  		// so just use uint64s.
  1025  		adjusted := (windowNewTickets << 32) / targetTicketsPerWindow
  1026  		adjusted <<= uint64((numWindows - i) * weightAlpha)
  1027  		weightedTicketsSum += uint64(adjusted)
  1028  	}
  1029  
  1030  	// Calculate the tickets per window retarget difficulty based on the
  1031  	// exponential weighted average and shift the result back down 32 bits
  1032  	// to account for the previous shift up in order to avoid losing
  1033  	// precision.  Then, limit it to the maximum allowed retarget adjustment
  1034  	// factor.
  1035  	//
  1036  	// This is the second metric used in the final calculated difficulty.
  1037  	nextNewTixDiff := (int64(weightedTicketsSum/weightSum) * curDiff) >> 32
  1038  	nextNewTixDiff = g.limitRetarget(curDiff, nextNewTixDiff)
  1039  
  1040  	// Average the previous two metrics using scaled multiplication and
  1041  	// ensure the result is limited to both the maximum allowed retarget
  1042  	// adjustment factor and the minimum allowed stake difficulty.
  1043  	nextDiff := mergeDifficulty(curDiff, nextPoolSizeDiff, nextNewTixDiff)
  1044  	nextDiff = g.limitRetarget(curDiff, nextDiff)
  1045  	if nextDiff < g.params.MinimumStakeDiff {
  1046  		return g.params.MinimumStakeDiff
  1047  	}
  1048  	return nextDiff
  1049  }
  1050  
  1051  // CalcNextRequiredStakeDifficulty returns the required stake difficulty (aka
  1052  // ticket price) for the block after the current tip block the generator is
  1053  // associated with.
  1054  //
  1055  // An overview of the algorithm is as follows:
  1056  // 1) Use the minimum value for any blocks before any tickets could have
  1057  //    possibly been purchased due to coinbase maturity requirements
  1058  // 2) Return 0 if the current tip block stake difficulty is 0.  This is a
  1059  //    safety check against a condition that should never actually happen.
  1060  // 3) Use the previous block's difficulty if the next block is not at a retarget
  1061  //    interval
  1062  // 4) Calculate the ideal retarget difficulty for each window based on the
  1063  //    actual pool size in the window versus the target pool size skewed by a
  1064  //    constant factor to weight the ticket pool size instead of the tickets per
  1065  //    block and exponentially weight each difficulty such that the most recent
  1066  //    window has the highest weight
  1067  // 5) Calculate the pool size retarget difficulty based on the exponential
  1068  //    weighted average and ensure it is limited to the max retarget adjustment
  1069  //    factor -- This is the first metric used to calculate the final difficulty
  1070  // 6) Calculate the ideal retarget difficulty for each window based on the
  1071  //    actual new tickets in the window versus the target new tickets per window
  1072  //    and exponentially weight each difficulty such that the most recent window
  1073  //    has the highest weight
  1074  // 7) Calculate the tickets per window retarget difficulty based on the
  1075  //    exponential weighted average and ensure it is limited to the max retarget
  1076  //    adjustment factor
  1077  // 8) Calculate the final difficulty by averaging the pool size retarget
  1078  //    difficulty from #5 and the tickets per window retarget difficulty from #7
  1079  //    using scaled multiplication and ensure it is limited to the max retarget
  1080  //    adjustment factor
  1081  //
  1082  // NOTE: In order to simplify the test code, this implementation does not use
  1083  // big integers so it will NOT match the actual consensus code for really big
  1084  // numbers.  However, the parameters on simnet and the pool sizes used in these
  1085  // tests are low enough that this is not an issue for the tests.  Anyone looking
  1086  // at this code should NOT use it for mainnet calculations as is since it will
  1087  // not always yield the correct results.
  1088  func (g *Generator) CalcNextRequiredStakeDifficulty() int64 {
  1089  	return g.CalcNextReqStakeDifficulty(g.tip)
  1090  }
  1091  
  1092  // hash256prng is a determinstic pseudorandom number generator that uses a
  1093  // 256-bit secure hashing function to generate random uint32s starting from
  1094  // an initial seed.
  1095  type hash256prng struct {
  1096  	seed       chainhash.Hash // Initialization seed
  1097  	idx        uint64         // Hash iterator index
  1098  	cachedHash chainhash.Hash // Most recently generated hash
  1099  	hashOffset int            // Offset into most recently generated hash
  1100  }
  1101  
  1102  // newHash256PRNG creates a pointer to a newly created hash256PRNG.
  1103  func newHash256PRNG(seed []byte) *hash256prng {
  1104  	// The provided seed is initialized by appending a constant derived from
  1105  	// the hex representation of pi and hashing the result to give 32 bytes.
  1106  	// This ensures the PRNG is always doing a short number of rounds
  1107  	// regardless of input since it will only need to hash small messages
  1108  	// (less than 64 bytes).
  1109  	seedHash := chainhash.HashFunc(append(seed, hash256prngSeedConst...))
  1110  	return &hash256prng{
  1111  		seed:       seedHash,
  1112  		idx:        0,
  1113  		cachedHash: seedHash,
  1114  	}
  1115  }
  1116  
  1117  // State returns a hash that represents the current state of the deterministic
  1118  // PRNG.
  1119  func (hp *hash256prng) State() chainhash.Hash {
  1120  	// The final state is the hash of the most recently generated hash
  1121  	// concatenated with both the hash iterator index and the offset into
  1122  	// the hash.
  1123  	//
  1124  	//   hash(hp.cachedHash || hp.idx || hp.hashOffset)
  1125  	finalState := make([]byte, len(hp.cachedHash)+4+1)
  1126  	copy(finalState, hp.cachedHash[:])
  1127  	offset := len(hp.cachedHash)
  1128  	binary.BigEndian.PutUint32(finalState[offset:], uint32(hp.idx))
  1129  	offset += 4
  1130  	finalState[offset] = byte(hp.hashOffset)
  1131  	return chainhash.HashH(finalState)
  1132  }
  1133  
  1134  // Hash256Rand returns a uint32 random number using the pseudorandom number
  1135  // generator and updates the state.
  1136  func (hp *hash256prng) Hash256Rand() uint32 {
  1137  	offset := hp.hashOffset * 4
  1138  	r := binary.BigEndian.Uint32(hp.cachedHash[offset : offset+4])
  1139  	hp.hashOffset++
  1140  
  1141  	// Generate a new hash and reset the hash position index once it would
  1142  	// overflow the available bytes in the most recently generated hash.
  1143  	if hp.hashOffset > 7 {
  1144  		// Hash of the seed concatenated with the hash iterator index.
  1145  		//   hash(hp.seed || hp.idx)
  1146  		data := make([]byte, len(hp.seed)+4)
  1147  		copy(data, hp.seed[:])
  1148  		binary.BigEndian.PutUint32(data[len(hp.seed):], uint32(hp.idx))
  1149  		hp.cachedHash = chainhash.HashH(data)
  1150  		hp.idx++
  1151  		hp.hashOffset = 0
  1152  	}
  1153  
  1154  	// Roll over the entire PRNG by re-hashing the seed when the hash
  1155  	// iterator index overlows a uint32.
  1156  	if hp.idx > math.MaxUint32 {
  1157  		hp.seed = chainhash.HashH(hp.seed[:])
  1158  		hp.cachedHash = hp.seed
  1159  		hp.idx = 0
  1160  	}
  1161  
  1162  	return r
  1163  }
  1164  
  1165  // uniformRandom returns a random in the range [0, upperBound) while avoiding
  1166  // modulo bias to ensure a normal distribution within the specified range.
  1167  func (hp *hash256prng) uniformRandom(upperBound uint32) uint32 {
  1168  	if upperBound < 2 {
  1169  		return 0
  1170  	}
  1171  
  1172  	// (2^32 - (x*2)) % x == 2^32 % x when x <= 2^31
  1173  	min := ((math.MaxUint32 - (upperBound * 2)) + 1) % upperBound
  1174  	if upperBound > 0x80000000 {
  1175  		min = 1 + ^upperBound
  1176  	}
  1177  
  1178  	r := hp.Hash256Rand()
  1179  	for r < min {
  1180  		r = hp.Hash256Rand()
  1181  	}
  1182  	return r % upperBound
  1183  }
  1184  
  1185  // winningTickets returns a slice of tickets that are required to vote for the
  1186  // given block being voted on and live ticket pool and the associated underlying
  1187  // deterministic prng state hash.
  1188  func winningTickets(voteBlock *wire.MsgBlock, liveTickets []*stakeTicket, numVotes uint16) ([]*stakeTicket, chainhash.Hash, error) {
  1189  	// Serialize the parent block header used as the seed to the
  1190  	// deterministic pseudo random number generator for vote selection.
  1191  	var buf bytes.Buffer
  1192  	buf.Grow(wire.MaxBlockHeaderPayload)
  1193  	if err := voteBlock.Header.Serialize(&buf); err != nil {
  1194  		return nil, chainhash.Hash{}, err
  1195  	}
  1196  
  1197  	// Ensure the number of live tickets is within the allowable range.
  1198  	numLiveTickets := uint32(len(liveTickets))
  1199  	if numLiveTickets > math.MaxUint32 {
  1200  		return nil, chainhash.Hash{}, fmt.Errorf("live ticket pool "+
  1201  			"has %d tickets which is more than the max allowed of "+
  1202  			"%d", len(liveTickets), uint32(math.MaxUint32))
  1203  	}
  1204  	if uint32(numVotes) > numLiveTickets {
  1205  		return nil, chainhash.Hash{}, fmt.Errorf("live ticket pool "+
  1206  			"has %d tickets, while %d are needed to vote",
  1207  			len(liveTickets), numVotes)
  1208  	}
  1209  
  1210  	// Construct list of winners by generating successive values from the
  1211  	// deterministic prng and using them as indices into the sorted live
  1212  	// ticket pool while skipping any duplicates that might occur.
  1213  	prng := newHash256PRNG(buf.Bytes())
  1214  	winners := make([]*stakeTicket, 0, numVotes)
  1215  	usedOffsets := make(map[uint32]struct{})
  1216  	for uint16(len(winners)) < numVotes {
  1217  		ticketIndex := prng.uniformRandom(numLiveTickets)
  1218  		if _, exists := usedOffsets[ticketIndex]; !exists {
  1219  			usedOffsets[ticketIndex] = struct{}{}
  1220  			winners = append(winners, liveTickets[ticketIndex])
  1221  		}
  1222  	}
  1223  	return winners, prng.State(), nil
  1224  }
  1225  
  1226  // calcFinalLotteryState calculates the final lottery state for a set of winning
  1227  // tickets and the associated deterministic prng state hash after selecting the
  1228  // winners.  It is the first 6 bytes of:
  1229  //   blake256(firstTicketHash || ... || lastTicketHash || prngStateHash)
  1230  func calcFinalLotteryState(winners []*stakeTicket, prngStateHash chainhash.Hash) [6]byte {
  1231  	data := make([]byte, (len(winners)+1)*chainhash.HashSize)
  1232  	for i := 0; i < len(winners); i++ {
  1233  		h := winners[i].tx.CachedTxHash()
  1234  		copy(data[chainhash.HashSize*i:], h[:])
  1235  	}
  1236  	copy(data[chainhash.HashSize*len(winners):], prngStateHash[:])
  1237  	dataHash := chainhash.HashH(data)
  1238  
  1239  	var finalState [6]byte
  1240  	copy(finalState[:], dataHash[0:6])
  1241  	return finalState
  1242  }
  1243  
  1244  // nextPowerOfTwo returns the next highest power of two from a given number if
  1245  // it is not already a power of two.  This is a helper function used during the
  1246  // calculation of a merkle tree.
  1247  func nextPowerOfTwo(n int) int {
  1248  	// Return the number if it's already a power of 2.
  1249  	if n&(n-1) == 0 {
  1250  		return n
  1251  	}
  1252  
  1253  	// Figure out and return the next power of two.
  1254  	exponent := uint(math.Log2(float64(n))) + 1
  1255  	return 1 << exponent // 2^exponent
  1256  }
  1257  
  1258  // hashMerkleBranches takes two hashes, treated as the left and right tree
  1259  // nodes, and returns the hash of their concatenation.  This is a helper
  1260  // function used to aid in the generation of a merkle tree.
  1261  func hashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash {
  1262  	// Concatenate the left and right nodes.
  1263  	var hash [chainhash.HashSize * 2]byte
  1264  	copy(hash[:chainhash.HashSize], left[:])
  1265  	copy(hash[chainhash.HashSize:], right[:])
  1266  
  1267  	newHash := chainhash.HashH(hash[:])
  1268  	return &newHash
  1269  }
  1270  
  1271  // buildMerkleTreeStore creates a merkle tree from a slice of transactions,
  1272  // stores it using a linear array, and returns a slice of the backing array.  A
  1273  // linear array was chosen as opposed to an actual tree structure since it uses
  1274  // about half as much memory.  The following describes a merkle tree and how it
  1275  // is stored in a linear array.
  1276  //
  1277  // A merkle tree is a tree in which every non-leaf node is the hash of its
  1278  // children nodes.  A diagram depicting how this works for Decred transactions
  1279  // where h(x) is a blake256 hash follows:
  1280  //
  1281  //	         root = h1234 = h(h12 + h34)
  1282  //	        /                           \
  1283  //	  h12 = h(h1 + h2)            h34 = h(h3 + h4)
  1284  //	   /            \              /            \
  1285  //	h1 = h(tx1)  h2 = h(tx2)    h3 = h(tx3)  h4 = h(tx4)
  1286  //
  1287  // The above stored as a linear array is as follows:
  1288  //
  1289  // 	[h1 h2 h3 h4 h12 h34 root]
  1290  //
  1291  // As the above shows, the merkle root is always the last element in the array.
  1292  //
  1293  // The number of inputs is not always a power of two which results in a
  1294  // balanced tree structure as above.  In that case, parent nodes with no
  1295  // children are also zero and parent nodes with only a single left node
  1296  // are calculated by concatenating the left node with itself before hashing.
  1297  // Since this function uses nodes that are pointers to the hashes, empty nodes
  1298  // will be nil.
  1299  func buildMerkleTreeStore(transactions []*dcrutil.Tx) []*chainhash.Hash {
  1300  	// If there's an empty stake tree, return totally zeroed out merkle tree root
  1301  	// only.
  1302  	if len(transactions) == 0 {
  1303  		merkles := make([]*chainhash.Hash, 1)
  1304  		merkles[0] = &chainhash.Hash{}
  1305  		return merkles
  1306  	}
  1307  
  1308  	// Calculate how many entries are required to hold the binary merkle
  1309  	// tree as a linear array and create an array of that size.
  1310  	nextPoT := nextPowerOfTwo(len(transactions))
  1311  	arraySize := nextPoT*2 - 1
  1312  	merkles := make([]*chainhash.Hash, arraySize)
  1313  
  1314  	// Create the base transaction hashes and populate the array with them.
  1315  	for i, tx := range transactions {
  1316  		msgTx := tx.MsgTx()
  1317  		txHashFull := msgTx.TxHashFull()
  1318  		merkles[i] = &txHashFull
  1319  	}
  1320  
  1321  	// Start the array offset after the last transaction and adjusted to the
  1322  	// next power of two.
  1323  	offset := nextPoT
  1324  	for i := 0; i < arraySize-1; i += 2 {
  1325  		switch {
  1326  		// When there is no left child node, the parent is nil too.
  1327  		case merkles[i] == nil:
  1328  			merkles[offset] = nil
  1329  
  1330  		// When there is no right child, the parent is generated by
  1331  		// hashing the concatenation of the left child with itself.
  1332  		case merkles[i+1] == nil:
  1333  			newHash := hashMerkleBranches(merkles[i], merkles[i])
  1334  			merkles[offset] = newHash
  1335  
  1336  		// The normal case sets the parent node to the hash of the
  1337  		// concatenation of the left and right children.
  1338  		default:
  1339  			newHash := hashMerkleBranches(merkles[i], merkles[i+1])
  1340  			merkles[offset] = newHash
  1341  		}
  1342  		offset++
  1343  	}
  1344  
  1345  	return merkles
  1346  }
  1347  
  1348  // calcMerkleRoot creates a merkle tree from the slice of transactions and
  1349  // returns the root of the tree.
  1350  func calcMerkleRoot(txns []*wire.MsgTx) chainhash.Hash {
  1351  	utilTxns := make([]*dcrutil.Tx, 0, len(txns))
  1352  	for _, tx := range txns {
  1353  		utilTxns = append(utilTxns, dcrutil.NewTx(tx))
  1354  	}
  1355  	merkles := buildMerkleTreeStore(utilTxns)
  1356  	return *merkles[len(merkles)-1]
  1357  }
  1358  
  1359  // hashToBig converts a chainhash.Hash into a big.Int that can be used to
  1360  // perform math comparisons.
  1361  func hashToBig(hash *chainhash.Hash) *big.Int {
  1362  	// A Hash is in little-endian, but the big package wants the bytes in
  1363  	// big-endian, so reverse them.
  1364  	buf := *hash
  1365  	blen := len(buf)
  1366  	for i := 0; i < blen/2; i++ {
  1367  		buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]
  1368  	}
  1369  
  1370  	return new(big.Int).SetBytes(buf[:])
  1371  }
  1372  
  1373  // compactToBig converts a compact representation of a whole number N to an
  1374  // unsigned 32-bit number.  The representation is similar to IEEE754 floating
  1375  // point numbers.
  1376  //
  1377  // Like IEEE754 floating point, there are three basic components: the sign,
  1378  // the exponent, and the mantissa.  They are broken out as follows:
  1379  //
  1380  //	* the most significant 8 bits represent the unsigned base 256 exponent
  1381  // 	* bit 23 (the 24th bit) represents the sign bit
  1382  //	* the least significant 23 bits represent the mantissa
  1383  //
  1384  //	-------------------------------------------------
  1385  //	|   Exponent     |    Sign    |    Mantissa     |
  1386  //	-------------------------------------------------
  1387  //	| 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] |
  1388  //	-------------------------------------------------
  1389  //
  1390  // The formula to calculate N is:
  1391  // 	N = (-1^sign) * mantissa * 256^(exponent-3)
  1392  //
  1393  // This compact form is only used in Decred to encode unsigned 256-bit numbers
  1394  // which represent difficulty targets, thus there really is not a need for a
  1395  // sign bit, but it is implemented here to stay consistent with bitcoind.
  1396  func compactToBig(compact uint32) *big.Int {
  1397  	// Extract the mantissa, sign bit, and exponent.
  1398  	mantissa := compact & 0x007fffff
  1399  	isNegative := compact&0x00800000 != 0
  1400  	exponent := uint(compact >> 24)
  1401  
  1402  	// Since the base for the exponent is 256, the exponent can be treated
  1403  	// as the number of bytes to represent the full 256-bit number.  So,
  1404  	// treat the exponent as the number of bytes and shift the mantissa
  1405  	// right or left accordingly.  This is equivalent to:
  1406  	// N = mantissa * 256^(exponent-3)
  1407  	var bn *big.Int
  1408  	if exponent <= 3 {
  1409  		mantissa >>= 8 * (3 - exponent)
  1410  		bn = big.NewInt(int64(mantissa))
  1411  	} else {
  1412  		bn = big.NewInt(int64(mantissa))
  1413  		bn.Lsh(bn, 8*(exponent-3))
  1414  	}
  1415  
  1416  	// Make it negative if the sign bit is set.
  1417  	if isNegative {
  1418  		bn = bn.Neg(bn)
  1419  	}
  1420  
  1421  	return bn
  1422  }
  1423  
  1424  // IsSolved returns whether or not the header hashes to a value that is less
  1425  // than or equal to the target difficulty as specified by its bits field.
  1426  func IsSolved(header *wire.BlockHeader) bool {
  1427  	targetDifficulty := compactToBig(header.Bits)
  1428  	hash := header.BlockHash()
  1429  	return hashToBig(&hash).Cmp(targetDifficulty) <= 0
  1430  }
  1431  
  1432  // solveBlock attempts to find a nonce which makes the passed block header hash
  1433  // to a value less than the target difficulty.  When a successful solution is
  1434  // found, true is returned and the nonce field of the passed header is updated
  1435  // with the solution.  False is returned if no solution exists.
  1436  //
  1437  // NOTE: This function will never solve blocks with a nonce of 0.  This is done
  1438  // so the 'NextBlock' function can properly detect when a nonce was modified by
  1439  // a munge function.
  1440  func solveBlock(header *wire.BlockHeader) bool {
  1441  	// sbResult is used by the solver goroutines to send results.
  1442  	type sbResult struct {
  1443  		found bool
  1444  		nonce uint32
  1445  	}
  1446  
  1447  	// solver accepts a block header and a nonce range to test. It is
  1448  	// intended to be run as a goroutine.
  1449  	targetDifficulty := compactToBig(header.Bits)
  1450  	quit := make(chan bool)
  1451  	results := make(chan sbResult)
  1452  	solver := func(hdr wire.BlockHeader, startNonce, stopNonce uint32) {
  1453  		// We need to modify the nonce field of the header, so make sure
  1454  		// we work with a copy of the original header.
  1455  		for i := startNonce; i >= startNonce && i <= stopNonce; i++ {
  1456  			select {
  1457  			case <-quit:
  1458  				results <- sbResult{false, 0}
  1459  				return
  1460  			default:
  1461  				hdr.Nonce = i
  1462  				hash := hdr.BlockHash()
  1463  				if hashToBig(&hash).Cmp(
  1464  					targetDifficulty) <= 0 {
  1465  
  1466  					results <- sbResult{true, i}
  1467  					return
  1468  				}
  1469  			}
  1470  		}
  1471  		results <- sbResult{false, 0}
  1472  	}
  1473  
  1474  	startNonce := uint32(1)
  1475  	stopNonce := uint32(math.MaxUint32)
  1476  	numCores := uint32(runtime.NumCPU())
  1477  	noncesPerCore := (stopNonce - startNonce) / numCores
  1478  	for i := uint32(0); i < numCores; i++ {
  1479  		rangeStart := startNonce + (noncesPerCore * i)
  1480  		rangeStop := startNonce + (noncesPerCore * (i + 1)) - 1
  1481  		if i == numCores-1 {
  1482  			rangeStop = stopNonce
  1483  		}
  1484  		go solver(*header, rangeStart, rangeStop)
  1485  	}
  1486  	var foundResult bool
  1487  	for i := uint32(0); i < numCores; i++ {
  1488  		result := <-results
  1489  		if !foundResult && result.found {
  1490  			close(quit)
  1491  			header.Nonce = result.nonce
  1492  			foundResult = true
  1493  		}
  1494  	}
  1495  
  1496  	return foundResult
  1497  }
  1498  
  1499  // ReplaceWithNVotes returns a function that itself takes a block and modifies
  1500  // it by replacing the votes in the stake tree with specified number of votes.
  1501  //
  1502  // NOTE: This must only be used as a munger to the 'NextBlock' function or it
  1503  // will lead to an invalid live ticket pool.  To help safeguard against improper
  1504  // usage, it will panic if called with a block that does not connect to the
  1505  // current tip block.
  1506  func (g *Generator) ReplaceWithNVotes(numVotes uint16) func(*wire.MsgBlock) {
  1507  	return func(b *wire.MsgBlock) {
  1508  		// Attempt to prevent misuse of this function by ensuring the
  1509  		// provided block connects to the current tip.
  1510  		if b.Header.PrevBlock != g.tip.BlockHash() {
  1511  			panic(fmt.Sprintf("attempt to replace number of votes "+
  1512  				"for block %s with parent %s that is not the "+
  1513  				"current tip %s", b.BlockHash(),
  1514  				b.Header.PrevBlock, g.tip.BlockHash()))
  1515  		}
  1516  
  1517  		// Get the winning tickets for the specified number of votes.
  1518  		parentBlock := g.tip
  1519  		winners, _, err := winningTickets(parentBlock, g.liveTickets,
  1520  			numVotes)
  1521  		if err != nil {
  1522  			panic(err)
  1523  		}
  1524  
  1525  		// Generate vote transactions for the winning tickets.
  1526  		defaultNumVotes := int(g.params.TicketsPerBlock)
  1527  		numExisting := len(b.STransactions) - defaultNumVotes
  1528  		stakeTxns := make([]*wire.MsgTx, 0, numExisting+int(numVotes))
  1529  		for _, ticket := range winners {
  1530  			voteTx := g.createVoteTxFromTicket(parentBlock, ticket)
  1531  			stakeTxns = append(stakeTxns, voteTx)
  1532  		}
  1533  
  1534  		// Add back the original stake transactions other than the
  1535  		// original stake votes that have been replaced.
  1536  		stakeTxns = append(stakeTxns, b.STransactions[defaultNumVotes:]...)
  1537  
  1538  		// Update the block with the new stake transactions and the
  1539  		// header with the new number of votes.
  1540  		b.STransactions = stakeTxns
  1541  		b.Header.Voters = numVotes
  1542  
  1543  		// Recalculate the coinbase amount based on the number of new
  1544  		// votes and update the coinbase so that the adjustment in
  1545  		// subsidy is accounted for.
  1546  		height := b.Header.Height
  1547  		fullSubsidy := g.calcFullSubsidy(height)
  1548  		devSubsidy := g.calcDevSubsidy(fullSubsidy, height, numVotes)
  1549  		powSubsidy := g.calcPoWSubsidy(fullSubsidy, height, numVotes)
  1550  		cbTx := b.Transactions[0]
  1551  		cbTx.TxIn[0].ValueIn = int64(devSubsidy + powSubsidy)
  1552  		cbTx.TxOut = nil
  1553  		g.addCoinbaseTxOutputs(cbTx, height, devSubsidy, powSubsidy)
  1554  	}
  1555  }
  1556  
  1557  // ReplaceVoteBitsN returns a function that itself takes a block and modifies
  1558  // it by replacing the vote bits of the vote located at the provided index.  It
  1559  // will panic if the stake transaction at the provided index is not already a
  1560  // vote.
  1561  //
  1562  // NOTE: This must only be used as a munger to the 'NextBlock' function or it
  1563  // will lead to an invalid live ticket pool.
  1564  func (g *Generator) ReplaceVoteBitsN(voteNum int, voteBits uint16) func(*wire.MsgBlock) {
  1565  	return func(b *wire.MsgBlock) {
  1566  		// Attempt to prevent misuse of this function by ensuring the
  1567  		// provided stake transaction number is actually a vote.
  1568  		stx := b.STransactions[voteNum]
  1569  		if !isVoteTx(stx) {
  1570  			panic(fmt.Sprintf("attempt to replace non-vote "+
  1571  				"transaction #%d for for block %s", voteNum,
  1572  				b.BlockHash()))
  1573  		}
  1574  
  1575  		// Extract the existing vote version.
  1576  		existingScript := stx.TxOut[1].PkScript
  1577  		var voteVersion uint32
  1578  		if len(existingScript) >= 8 {
  1579  			voteVersion = binary.LittleEndian.Uint32(existingScript[4:8])
  1580  		}
  1581  
  1582  		stx.TxOut[1].PkScript = voteBitsScript(voteBits, voteVersion)
  1583  	}
  1584  }
  1585  
  1586  // ReplaceBlockVersion returns a function that itself takes a block and modifies
  1587  // it by replacing the stake version of the header.
  1588  func ReplaceBlockVersion(newVersion int32) func(*wire.MsgBlock) {
  1589  	return func(b *wire.MsgBlock) {
  1590  		b.Header.Version = newVersion
  1591  	}
  1592  }
  1593  
  1594  // ReplaceStakeVersion returns a function that itself takes a block and modifies
  1595  // it by replacing the stake version of the header.
  1596  func ReplaceStakeVersion(newVersion uint32) func(*wire.MsgBlock) {
  1597  	return func(b *wire.MsgBlock) {
  1598  		b.Header.StakeVersion = newVersion
  1599  	}
  1600  }
  1601  
  1602  // ReplaceVoteVersions returns a function that itself takes a block and modifies
  1603  // it by replacing the voter version of the stake transactions.
  1604  //
  1605  // NOTE: This must only be used as a munger to the 'NextBlock' function or it
  1606  // will lead to an invalid live ticket pool.
  1607  func ReplaceVoteVersions(newVersion uint32) func(*wire.MsgBlock) {
  1608  	return func(b *wire.MsgBlock) {
  1609  		for _, stx := range b.STransactions {
  1610  			if isVoteTx(stx) {
  1611  				stx.TxOut[1].PkScript = voteBitsScript(
  1612  					voteBitYes, newVersion)
  1613  			}
  1614  		}
  1615  	}
  1616  }
  1617  
  1618  // ReplaceVotes returns a function that itself takes a block and modifies it by
  1619  // replacing the voter version and bits of the stake transactions.
  1620  //
  1621  // NOTE: This must only be used as a munger to the 'NextBlock' function or it
  1622  // will lead to an invalid live ticket pool.
  1623  func ReplaceVotes(voteBits uint16, newVersion uint32) func(*wire.MsgBlock) {
  1624  	return func(b *wire.MsgBlock) {
  1625  		for _, stx := range b.STransactions {
  1626  			if isVoteTx(stx) {
  1627  				stx.TxOut[1].PkScript = voteBitsScript(voteBits,
  1628  					newVersion)
  1629  			}
  1630  		}
  1631  	}
  1632  }
  1633  
  1634  // CreateSpendTx creates a transaction that spends from the provided spendable
  1635  // output and includes an additional unique OP_RETURN output to ensure the
  1636  // transaction ends up with a unique hash.  The public key script is a simple
  1637  // OP_TRUE p2sh script which avoids the need to track addresses and signature
  1638  // scripts in the tests.  The signature script is the opTrueRedeemScript.
  1639  func (g *Generator) CreateSpendTx(spend *SpendableOut, fee dcrutil.Amount) *wire.MsgTx {
  1640  	spendTx := wire.NewMsgTx()
  1641  	spendTx.AddTxIn(&wire.TxIn{
  1642  		PreviousOutPoint: spend.prevOut,
  1643  		Sequence:         wire.MaxTxInSequenceNum,
  1644  		ValueIn:          int64(spend.amount),
  1645  		BlockHeight:      spend.blockHeight,
  1646  		BlockIndex:       spend.blockIndex,
  1647  		SignatureScript:  opTrueRedeemScript,
  1648  	})
  1649  	spendTx.AddTxOut(wire.NewTxOut(int64(spend.amount-fee),
  1650  		g.p2shOpTrueScript))
  1651  	spendTx.AddTxOut(wire.NewTxOut(0, UniqueOpReturnScript()))
  1652  	return spendTx
  1653  }
  1654  
  1655  // CreateSpendTxForTx creates a transaction that spends from the first output of
  1656  // the provided transaction and includes an additional unique OP_RETURN output
  1657  // to ensure the transaction ends up with a unique hash.  The public key script
  1658  // is a simple OP_TRUE p2sh script which avoids the need to track addresses and
  1659  // signature scripts in the tests.  This signature script the
  1660  // opTrueRedeemScript.
  1661  func (g *Generator) CreateSpendTxForTx(tx *wire.MsgTx, blockHeight, txIndex uint32, fee dcrutil.Amount) *wire.MsgTx {
  1662  	spend := MakeSpendableOutForTx(tx, blockHeight, txIndex, 0)
  1663  	return g.CreateSpendTx(&spend, fee)
  1664  }
  1665  
  1666  // removeTicket removes the passed index from the provided slice of tickets and
  1667  // returns the resulting slice.  This is an in-place modification.
  1668  func removeTicket(tickets []*stakeTicket, index int) []*stakeTicket {
  1669  	copy(tickets[index:], tickets[index+1:])
  1670  	tickets[len(tickets)-1] = nil // Prevent memory leak
  1671  	tickets = tickets[:len(tickets)-1]
  1672  	return tickets
  1673  }
  1674  
  1675  // connectLiveTickets updates the live ticket pool for a new tip block by
  1676  // removing tickets that are now expired from it, removing the passed winners
  1677  // from it, adding any immature tickets which are now mature to it, and
  1678  // resorting it.
  1679  func (g *Generator) connectLiveTickets(blockHash *chainhash.Hash, height uint32, winners, purchases []*stakeTicket) {
  1680  	// Move expired tickets from the live ticket pool to the expired ticket
  1681  	// pool.
  1682  	ticketMaturity := uint32(g.params.TicketMaturity)
  1683  	ticketExpiry := g.params.TicketExpiry
  1684  	for i := 0; i < len(g.liveTickets); i++ {
  1685  		ticket := g.liveTickets[i]
  1686  		liveHeight := ticket.blockHeight + ticketMaturity
  1687  		expireHeight := liveHeight + ticketExpiry
  1688  		if height >= expireHeight {
  1689  			g.liveTickets = removeTicket(g.liveTickets, i)
  1690  			g.expiredTickets = append(g.expiredTickets, ticket)
  1691  
  1692  			// This is required because the ticket at the current
  1693  			// offset was just removed from the slice that is being
  1694  			// iterated, so adjust the offset down one accordingly.
  1695  			i--
  1696  		}
  1697  	}
  1698  
  1699  	// Move winning tickets from the live ticket pool to won tickets pool.
  1700  	for i := 0; i < len(g.liveTickets); i++ {
  1701  		ticket := g.liveTickets[i]
  1702  		for _, winner := range winners {
  1703  			if ticket.tx.CachedTxHash() == winner.tx.CachedTxHash() {
  1704  				g.liveTickets = removeTicket(g.liveTickets, i)
  1705  
  1706  				// This is required because the ticket at the
  1707  				// current offset was just removed from the
  1708  				// slice that is being iterated, so adjust the
  1709  				// offset down one accordingly.
  1710  				i--
  1711  				break
  1712  			}
  1713  		}
  1714  	}
  1715  	g.wonTickets[*blockHash] = winners
  1716  
  1717  	// Move immature tickets which are now mature to the live ticket pool.
  1718  	for i := 0; i < len(g.immatureTickets); i++ {
  1719  		ticket := g.immatureTickets[i]
  1720  		liveHeight := ticket.blockHeight + ticketMaturity
  1721  		if height >= liveHeight {
  1722  			g.immatureTickets = removeTicket(g.immatureTickets, i)
  1723  			g.liveTickets = append(g.liveTickets, ticket)
  1724  
  1725  			// This is required because the ticket at the current
  1726  			// offset was just removed from the slice that is being
  1727  			// iterated, so adjust the offset down one accordingly.
  1728  			i--
  1729  		}
  1730  	}
  1731  
  1732  	// Resort the ticket pool now that all live ticket pool manipulations
  1733  	// are done.
  1734  	sort.Sort(stakeTicketSorter(g.liveTickets))
  1735  
  1736  	// Add new ticket purchases to the immature ticket pool.
  1737  	g.immatureTickets = append(g.immatureTickets, purchases...)
  1738  }
  1739  
  1740  // addMissedVotes adds any of the passed winning tickets as missed votes if the
  1741  // passed block does not cast those votes.
  1742  func (g *Generator) addMissedVotes(blockHash *chainhash.Hash, stakeTxns []*wire.MsgTx, winners []*stakeTicket) {
  1743  	// Nothing to do before there are any winning tickets.
  1744  	if len(winners) == 0 {
  1745  		return
  1746  	}
  1747  
  1748  	// Assume all of the winning tickets were missed.
  1749  	missedVotes := make(map[chainhash.Hash]*stakeTicket)
  1750  	for _, ticket := range winners {
  1751  		missedVotes[ticket.tx.TxHash()] = ticket
  1752  	}
  1753  
  1754  	// Remove the entries for which the block actually contains votes.
  1755  	for _, stx := range stakeTxns {
  1756  		// Ignore all stake transactions that are not votes.
  1757  		if !isVoteTx(stx) {
  1758  			continue
  1759  		}
  1760  
  1761  		// Ignore the vote if it is not for one of the winning tickets.
  1762  		ticketInput := stx.TxIn[1]
  1763  		ticketHash := ticketInput.PreviousOutPoint.Hash
  1764  		missedVote, ok := missedVotes[ticketHash]
  1765  		if !ok || missedVote.blockHeight != ticketInput.BlockHeight ||
  1766  			missedVote.blockIndex != ticketInput.BlockIndex {
  1767  
  1768  			continue
  1769  		}
  1770  
  1771  		delete(missedVotes, ticketHash)
  1772  	}
  1773  
  1774  	// Add the missed votes to the generator state so future blocks will
  1775  	// generate revocations for them.
  1776  	for ticketHash, missedVote := range missedVotes {
  1777  		g.missedVotes[ticketHash] = missedVote
  1778  	}
  1779  }
  1780  
  1781  // connectRevocations updates the missed and revoked ticket data structs
  1782  // according to the revocations in the passed block.
  1783  func (g *Generator) connectRevocations(blockHash *chainhash.Hash, stakeTxns []*wire.MsgTx) {
  1784  	for _, stx := range stakeTxns {
  1785  		// Ignore all stake transactions that are not revocations.
  1786  		if !isRevocationTx(stx) {
  1787  			continue
  1788  		}
  1789  
  1790  		// Ignore the revocation if it is not for a missed ticket.
  1791  		ticketInput := stx.TxIn[0]
  1792  		ticketHash := ticketInput.PreviousOutPoint.Hash
  1793  		ticket, ok := g.missedVotes[ticketHash]
  1794  		if !ok || ticket.blockHeight != ticketInput.BlockHeight ||
  1795  			ticket.blockIndex != ticketInput.BlockIndex {
  1796  
  1797  			continue
  1798  		}
  1799  
  1800  		// Remove the revoked ticket from the missed votes and add it to the
  1801  		// list of tickets revoked by the block.
  1802  		delete(g.missedVotes, ticketHash)
  1803  		g.revokedTickets[*blockHash] = append(g.revokedTickets[*blockHash],
  1804  			ticket)
  1805  	}
  1806  }
  1807  
  1808  // connectBlockTickets updates the live ticket pool and associated data structs
  1809  // by for the passed block.  It will panic if the specified block does not
  1810  // connect to the current tip block.
  1811  func (g *Generator) connectBlockTickets(b *wire.MsgBlock) {
  1812  	// Attempt to prevent misuse of this function by ensuring the provided
  1813  	// block connects to the current tip.
  1814  	blockHash := b.BlockHash()
  1815  	if b.Header.PrevBlock != g.tip.BlockHash() {
  1816  		panic(fmt.Sprintf("attempt to connect block %s with parent %s "+
  1817  			"that is not the current tip %s", blockHash,
  1818  			b.Header.PrevBlock, g.tip.BlockHash()))
  1819  	}
  1820  
  1821  	// Get all of the winning tickets for the block.
  1822  	numVotes := g.params.TicketsPerBlock
  1823  	winners, _, err := winningTickets(g.tip, g.liveTickets, numVotes)
  1824  	if err != nil {
  1825  		panic(err)
  1826  	}
  1827  
  1828  	// Keep track of any missed votes.
  1829  	g.addMissedVotes(&blockHash, b.STransactions, winners)
  1830  
  1831  	// Keep track of revocations.
  1832  	g.connectRevocations(&blockHash, b.STransactions)
  1833  
  1834  	// Extract the ticket purchases (sstx) from the block.
  1835  	var purchases []*stakeTicket
  1836  	blockHeight := g.blockHeight(blockHash)
  1837  	for txIdx, tx := range b.STransactions {
  1838  		if isTicketPurchaseTx(tx) {
  1839  			ticket := &stakeTicket{tx, blockHeight, uint32(txIdx)}
  1840  			purchases = append(purchases, ticket)
  1841  		}
  1842  	}
  1843  
  1844  	// Update the live ticket pool and associated data structures.
  1845  	g.connectLiveTickets(&blockHash, blockHeight, winners, purchases)
  1846  }
  1847  
  1848  // disconnectBlockTickets updates the live ticket pool and associated data
  1849  // structs by unwinding the passed block, which must be the current tip block.
  1850  // It will panic if the specified block is not the current tip block.
  1851  func (g *Generator) disconnectBlockTickets(b *wire.MsgBlock) {
  1852  	// Attempt to prevent misuse of this function by ensuring the provided
  1853  	// block is the current tip.
  1854  	blockHash := b.BlockHash()
  1855  	if b != g.tip {
  1856  		panic(fmt.Sprintf("attempt to disconnect block %s that is not "+
  1857  			"the current tip %s", blockHash, g.tip.BlockHash()))
  1858  	}
  1859  
  1860  	// Move tickets revoked by the block back to the list of missed tickets.
  1861  	for _, ticket := range g.revokedTickets[blockHash] {
  1862  		g.missedVotes[ticket.tx.TxHash()] = ticket
  1863  	}
  1864  
  1865  	// Remove any votes missed by the block.
  1866  	winners := g.wonTickets[blockHash]
  1867  	for _, ticket := range winners {
  1868  		delete(g.missedVotes, ticket.tx.TxHash())
  1869  	}
  1870  
  1871  	// Remove tickets created in the block from the immature ticket pool.
  1872  	blockHeight := g.blockHeight(blockHash)
  1873  	for i := 0; i < len(g.immatureTickets); i++ {
  1874  		ticket := g.immatureTickets[i]
  1875  		if ticket.blockHeight == blockHeight {
  1876  			g.immatureTickets = removeTicket(g.immatureTickets, i)
  1877  
  1878  			// This is required because the ticket at the current
  1879  			// offset was just removed from the slice that is being
  1880  			// iterated, so adjust the offset down one accordingly.
  1881  			i--
  1882  		}
  1883  	}
  1884  
  1885  	// Move tickets that are no longer mature from the live ticket pool to
  1886  	// the immature ticket pool.
  1887  	prevBlockHeight := blockHeight - 1
  1888  	ticketMaturity := uint32(g.params.TicketMaturity)
  1889  	for i := 0; i < len(g.liveTickets); i++ {
  1890  		ticket := g.liveTickets[i]
  1891  		liveHeight := ticket.blockHeight + ticketMaturity
  1892  		if prevBlockHeight < liveHeight {
  1893  			g.liveTickets = removeTicket(g.liveTickets, i)
  1894  			g.immatureTickets = append(g.immatureTickets, ticket)
  1895  
  1896  			// This is required because the ticket at the current
  1897  			// offset was just removed from the slice that is being
  1898  			// iterated, so adjust the offset down one accordingly.
  1899  			i--
  1900  		}
  1901  	}
  1902  
  1903  	// Move tickets that are no longer expired from the expired ticket pool
  1904  	// to the live ticket pool.
  1905  	ticketExpiry := g.params.TicketExpiry
  1906  	for i := 0; i < len(g.expiredTickets); i++ {
  1907  		ticket := g.expiredTickets[i]
  1908  		liveHeight := ticket.blockHeight + ticketMaturity
  1909  		expireHeight := liveHeight + ticketExpiry
  1910  		if prevBlockHeight < expireHeight {
  1911  			g.expiredTickets = removeTicket(g.expiredTickets, i)
  1912  			g.liveTickets = append(g.liveTickets, ticket)
  1913  
  1914  			// This is required because the ticket at the current
  1915  			// offset was just removed from the slice that is being
  1916  			// iterated, so adjust the offset down one accordingly.
  1917  			i--
  1918  		}
  1919  	}
  1920  
  1921  	// Add the winning tickets consumed by the block back to the live ticket
  1922  	// pool.
  1923  	g.liveTickets = append(g.liveTickets, winners...)
  1924  	delete(g.wonTickets, blockHash)
  1925  
  1926  	// Resort the ticket pool now that all live ticket pool manipulations
  1927  	// are done.
  1928  	sort.Sort(stakeTicketSorter(g.liveTickets))
  1929  }
  1930  
  1931  // originalParent returns the original block the passed block was built from.
  1932  // This is necessary because callers might change the previous block hash in a
  1933  // munger which would cause the like ticket pool to be reconstructed improperly.
  1934  func (g *Generator) originalParent(b *wire.MsgBlock) *wire.MsgBlock {
  1935  	parentHash, ok := g.originalParents[b.BlockHash()]
  1936  	if !ok {
  1937  		parentHash = b.Header.PrevBlock
  1938  	}
  1939  	return g.BlockByHash(&parentHash)
  1940  }
  1941  
  1942  // SetTip changes the tip of the instance to the block with the provided name.
  1943  // This is useful since the tip is used for things such as generating subsequent
  1944  // blocks.
  1945  func (g *Generator) SetTip(blockName string) {
  1946  	// Nothing to do if already the tip.
  1947  	if blockName == g.tipName {
  1948  		return
  1949  	}
  1950  
  1951  	newTip := g.blocksByName[blockName]
  1952  	if newTip == nil {
  1953  		panic(fmt.Sprintf("tip block name %s does not exist", blockName))
  1954  	}
  1955  
  1956  	// Create a list of blocks to disconnect and blocks to connect in order
  1957  	// to switch to the new tip.
  1958  	var connect, disconnect []*wire.MsgBlock
  1959  	oldBranch, newBranch := g.tip, newTip
  1960  	for oldBranch != newBranch {
  1961  		oldBranchHeight := g.blockHeight(oldBranch.BlockHash())
  1962  		newBranchHeight := g.blockHeight(newBranch.BlockHash())
  1963  		if oldBranchHeight > newBranchHeight {
  1964  			disconnect = append(disconnect, oldBranch)
  1965  			oldBranch = g.originalParent(oldBranch)
  1966  			continue
  1967  		} else if newBranchHeight > oldBranchHeight {
  1968  			connect = append(connect, newBranch)
  1969  			newBranch = g.originalParent(newBranch)
  1970  			continue
  1971  		}
  1972  
  1973  		// At this point the two branches have the same height, so add
  1974  		// each tip to the appropriate connect or disconnect list and
  1975  		// the tips to their previous block.
  1976  		disconnect = append(disconnect, oldBranch)
  1977  		oldBranch = g.originalParent(oldBranch)
  1978  		connect = append(connect, newBranch)
  1979  		newBranch = g.originalParent(newBranch)
  1980  	}
  1981  
  1982  	// Update the live ticket pool and associated data structs by
  1983  	// disconnecting all blocks back to the fork point.
  1984  	for _, block := range disconnect {
  1985  		g.disconnectBlockTickets(block)
  1986  		g.tip = g.originalParent(block)
  1987  	}
  1988  
  1989  	// Update the live ticket pool and associated data structs by connecting
  1990  	// all blocks after the fork point up to the new tip.  The list of
  1991  	// blocks to connect is iterated in reverse order, because it was
  1992  	// constructed in reverse, and the blocks need to be connected in the
  1993  	// order in which they build the chain.
  1994  	for i := len(connect) - 1; i >= 0; i-- {
  1995  		block := connect[i]
  1996  		g.connectBlockTickets(block)
  1997  		g.tip = block
  1998  	}
  1999  
  2000  	// Ensure the tip is the expected new tip and set the associated name.
  2001  	if g.tip != newTip {
  2002  		panic(fmt.Sprintf("tip %s is not expected new tip %s",
  2003  			g.tip.BlockHash(), newTip.BlockHash()))
  2004  	}
  2005  	g.tipName = blockName
  2006  }
  2007  
  2008  // updateVoteCommitments updates all of the votes in the passed block to commit
  2009  // to the previous block hash and previous height based on the values specified
  2010  // in the header.
  2011  func updateVoteCommitments(block *wire.MsgBlock) {
  2012  	for _, stx := range block.STransactions {
  2013  		if !isVoteTx(stx) {
  2014  			continue
  2015  		}
  2016  
  2017  		stx.TxOut[0].PkScript = VoteCommitmentScript(block.Header.PrevBlock,
  2018  			block.Header.Height-1)
  2019  	}
  2020  }
  2021  
  2022  // NextBlock builds a new block that extends the current tip associated with the
  2023  // generator and updates the generator's tip to the newly generated block.
  2024  //
  2025  // The block will include the following:
  2026  // - A coinbase with the following outputs:
  2027  //   - One that pays the required 10% subsidy to the dev org
  2028  //   - One that contains a standard coinbase OP_RETURN script
  2029  //   - Six that pay the required 60% subsidy to an OP_TRUE p2sh script
  2030  // - When a spendable output is provided:
  2031  //   - A transaction that spends from the provided output the following outputs:
  2032  //     - One that pays the inputs amount minus 1 atom to an OP_TRUE p2sh script
  2033  // - Once the coinbase maturity has been reached:
  2034  //   - A ticket purchase transaction (sstx) for each provided ticket spendable
  2035  //     output with the following outputs:
  2036  //     - One OP_SSTX output that grants voting rights to an OP_TRUE p2sh script
  2037  //     - One OP_RETURN output that contains the required commitment and pays
  2038  //       the subsidy to an OP_TRUE p2sh script
  2039  //     - One OP_SSTXCHANGE output that sends change to an OP_TRUE p2sh script
  2040  // - Once the stake validation height has been reached:
  2041  //   - 5 vote transactions (ssgen) as required according to the live ticket
  2042  //     pool and vote selection rules with the following outputs:
  2043  //     - One OP_RETURN followed by the block hash and height being voted on
  2044  //     - One OP_RETURN followed by the vote bits
  2045  //     - One or more OP_SSGEN outputs with the payouts according to the original
  2046  //       ticket commitments
  2047  //   - Revocation transactions (ssrtx) as required according to any missed votes
  2048  //     with the following outputs:
  2049  //     - One or more OP_SSRTX outputs with the payouts according to the original
  2050  //       ticket commitments
  2051  //
  2052  // Additionally, if one or more munge functions are specified, they will be
  2053  // invoked with the block prior to solving it.  This provides callers with the
  2054  // opportunity to modify the block which is especially useful for testing.
  2055  //
  2056  // In order to simply the logic in the munge functions, the following rules are
  2057  // applied after all munge functions have been invoked:
  2058  // - All votes will have their commitments updated if the previous hash or
  2059  //   height was manually changed after stake validation height has been reached
  2060  // - The merkle root will be recalculated unless it was manually changed
  2061  // - The stake root will be recalculated unless it was manually changed
  2062  // - The size of the block will be recalculated unless it was manually changed
  2063  // - The block will be solved unless the nonce was changed
  2064  func (g *Generator) NextBlock(blockName string, spend *SpendableOut, ticketSpends []SpendableOut, mungers ...func(*wire.MsgBlock)) *wire.MsgBlock {
  2065  	// Prevent block name collisions.
  2066  	if g.blocksByName[blockName] != nil {
  2067  		panic(fmt.Sprintf("block name %s already exists", blockName))
  2068  	}
  2069  
  2070  	// Calculate the next required stake difficulty (aka ticket price).
  2071  	ticketPrice := dcrutil.Amount(g.CalcNextRequiredStakeDifficulty())
  2072  
  2073  	// Generate the appropriate votes and ticket purchases based on the
  2074  	// current tip block and provided ticket spendable outputs.
  2075  	var ticketWinners []*stakeTicket
  2076  	var stakeTxns []*wire.MsgTx
  2077  	var finalState [6]byte
  2078  	nextHeight := g.tip.Header.Height + 1
  2079  	if nextHeight > uint32(g.params.CoinbaseMaturity) {
  2080  		// Generate votes once the stake validation height has been
  2081  		// reached.
  2082  		if int64(nextHeight) >= g.params.StakeValidationHeight {
  2083  			// Generate and add the vote transactions for the
  2084  			// winning tickets to the stake tree.
  2085  			numVotes := g.params.TicketsPerBlock
  2086  			winners, stateHash, err := winningTickets(g.tip,
  2087  				g.liveTickets, numVotes)
  2088  			if err != nil {
  2089  				panic(err)
  2090  			}
  2091  			ticketWinners = winners
  2092  			for _, ticket := range winners {
  2093  				voteTx := g.createVoteTxFromTicket(g.tip, ticket)
  2094  				stakeTxns = append(stakeTxns, voteTx)
  2095  			}
  2096  
  2097  			// Calculate the final lottery state hash for use in the
  2098  			// block header.
  2099  			finalState = calcFinalLotteryState(winners, stateHash)
  2100  		}
  2101  
  2102  		// Generate ticket purchases (sstx) using the provided spendable
  2103  		// outputs.
  2104  		if ticketSpends != nil {
  2105  			const ticketFee = dcrutil.Amount(2)
  2106  			for i := 0; i < len(ticketSpends); i++ {
  2107  				out := &ticketSpends[i]
  2108  				purchaseTx := g.CreateTicketPurchaseTx(out,
  2109  					ticketPrice, ticketFee)
  2110  				stakeTxns = append(stakeTxns, purchaseTx)
  2111  			}
  2112  		}
  2113  
  2114  		// Generate and add revocations for any missed tickets.
  2115  		for _, missedVote := range g.missedVotes {
  2116  			revocationTx := g.createRevocationTxFromTicket(missedVote)
  2117  			stakeTxns = append(stakeTxns, revocationTx)
  2118  		}
  2119  	}
  2120  
  2121  	// Count the ticket purchases (sstx), votes (ssgen,  and ticket revocations
  2122  	// (ssrtx),  and calculate the total PoW fees generated by the stake
  2123  	// transactions.
  2124  	var numVotes uint16
  2125  	var numTicketRevocations uint8
  2126  	var numTicketPurchases uint8
  2127  	var stakeTreeFees dcrutil.Amount
  2128  	for _, tx := range stakeTxns {
  2129  		switch {
  2130  		case isVoteTx(tx):
  2131  			numVotes++
  2132  		case isTicketPurchaseTx(tx):
  2133  			numTicketPurchases++
  2134  		case isRevocationTx(tx):
  2135  			numTicketRevocations++
  2136  		}
  2137  
  2138  		// Calculate any fees for the transaction.
  2139  		var inputSum, outputSum dcrutil.Amount
  2140  		for _, txIn := range tx.TxIn {
  2141  			inputSum += dcrutil.Amount(txIn.ValueIn)
  2142  		}
  2143  		for _, txOut := range tx.TxOut {
  2144  			outputSum += dcrutil.Amount(txOut.Value)
  2145  		}
  2146  		stakeTreeFees += (inputSum - outputSum)
  2147  	}
  2148  
  2149  	// Create a standard coinbase and spending transaction.
  2150  	var regularTxns []*wire.MsgTx
  2151  	{
  2152  		// Create coinbase transaction for the block with no additional
  2153  		// dev or pow subsidy.
  2154  		coinbaseTx := g.CreateCoinbaseTx(nextHeight, numVotes)
  2155  		regularTxns = []*wire.MsgTx{coinbaseTx}
  2156  
  2157  		// Increase the PoW subsidy to account for any fees in the stake
  2158  		// tree.
  2159  		coinbaseTx.TxOut[2].Value += int64(stakeTreeFees)
  2160  
  2161  		// Create a transaction to spend the provided utxo if needed.
  2162  		if spend != nil {
  2163  			// Create the transaction with a fee of 1 atom for the
  2164  			// miner and increase the PoW subsidy accordingly.
  2165  			fee := dcrutil.Amount(1)
  2166  			coinbaseTx.TxOut[2].Value += int64(fee)
  2167  
  2168  			// Create a transaction that spends from the provided
  2169  			// spendable output and includes an additional unique
  2170  			// OP_RETURN output to ensure the transaction ends up
  2171  			// with a unique hash, then add it to the list of
  2172  			// transactions to include in the block.  The script is
  2173  			// a simple OP_TRUE p2sh script in order to avoid the
  2174  			// need to track addresses and signature scripts in the
  2175  			// tests.
  2176  			spendTx := g.CreateSpendTx(spend, fee)
  2177  			regularTxns = append(regularTxns, spendTx)
  2178  		}
  2179  	}
  2180  
  2181  	// Use a timestamp that is 7/8 of target timespan after the previous
  2182  	// block unless this is the first block in which case the current time
  2183  	// is used or the proof-of-work difficulty parameters have been adjusted
  2184  	// such that it's greater than the max 2 hours worth of blocks that can
  2185  	// be tested in which case one second is used.  This helps maintain the
  2186  	// retarget difficulty low as needed.  Also, ensure the timestamp is
  2187  	// limited to one second precision.
  2188  	var ts time.Time
  2189  	if nextHeight == 1 {
  2190  		ts = time.Now()
  2191  	} else {
  2192  		if g.params.WorkDiffWindowSize > 7200 {
  2193  			ts = g.tip.Header.Timestamp.Add(time.Second)
  2194  		} else {
  2195  			addDuration := g.params.TargetTimespan * 7 / 8
  2196  			ts = g.tip.Header.Timestamp.Add(addDuration)
  2197  		}
  2198  	}
  2199  	ts = time.Unix(ts.Unix(), 0)
  2200  
  2201  	// Create the unsolved block.
  2202  	prevHash := g.tip.BlockHash()
  2203  	block := wire.MsgBlock{
  2204  		Header: wire.BlockHeader{
  2205  			Version:      1,
  2206  			PrevBlock:    prevHash,
  2207  			MerkleRoot:   calcMerkleRoot(regularTxns),
  2208  			StakeRoot:    calcMerkleRoot(stakeTxns),
  2209  			VoteBits:     1,
  2210  			FinalState:   finalState,
  2211  			Voters:       numVotes,
  2212  			FreshStake:   numTicketPurchases,
  2213  			Revocations:  numTicketRevocations,
  2214  			PoolSize:     uint32(len(g.liveTickets)),
  2215  			Bits:         g.CalcNextRequiredDifficulty(),
  2216  			SBits:        int64(ticketPrice),
  2217  			Height:       nextHeight,
  2218  			Size:         0, // Filled in below.
  2219  			Timestamp:    ts,
  2220  			Nonce:        0, // To be solved.
  2221  			ExtraData:    [32]byte{},
  2222  			StakeVersion: 0,
  2223  		},
  2224  		Transactions:  regularTxns,
  2225  		STransactions: stakeTxns,
  2226  	}
  2227  	block.Header.Size = uint32(block.SerializeSize())
  2228  
  2229  	// Perform any block munging just before solving.  Once stake validation
  2230  	// height has been reached, update the vote commitments accordingly if the
  2231  	// header height or previous hash was manually changed by a munge function.
  2232  	// Also, only recalculate the merkle roots and block size if they weren't
  2233  	// manually changed by a munge function.
  2234  	curMerkleRoot := block.Header.MerkleRoot
  2235  	curStakeRoot := block.Header.StakeRoot
  2236  	curSize := block.Header.Size
  2237  	curNonce := block.Header.Nonce
  2238  	for _, f := range mungers {
  2239  		f(&block)
  2240  	}
  2241  	if block.Header.Height != nextHeight || block.Header.PrevBlock != prevHash {
  2242  		if int64(nextHeight) >= g.params.StakeValidationHeight {
  2243  			updateVoteCommitments(&block)
  2244  		}
  2245  	}
  2246  	if block.Header.MerkleRoot == curMerkleRoot {
  2247  		block.Header.MerkleRoot = calcMerkleRoot(block.Transactions)
  2248  	}
  2249  	if block.Header.StakeRoot == curStakeRoot {
  2250  		block.Header.StakeRoot = calcMerkleRoot(block.STransactions)
  2251  	}
  2252  	if block.Header.Size == curSize {
  2253  		block.Header.Size = uint32(block.SerializeSize())
  2254  	}
  2255  
  2256  	// Only solve the block if the nonce wasn't manually changed by a munge
  2257  	// function.
  2258  	if block.Header.Nonce == curNonce && !solveBlock(&block.Header) {
  2259  		panic(fmt.Sprintf("unable to solve block at height %d",
  2260  			block.Header.Height))
  2261  	}
  2262  
  2263  	// Create stake tickets for the ticket purchases (sstx) in the block.  This
  2264  	// is done after the mungers to ensure all changes are accurately accounted
  2265  	// for.
  2266  	var ticketPurchases []*stakeTicket
  2267  	for txIdx, tx := range block.STransactions {
  2268  		if isTicketPurchaseTx(tx) {
  2269  			ticket := &stakeTicket{tx, nextHeight, uint32(txIdx)}
  2270  			ticketPurchases = append(ticketPurchases, ticket)
  2271  		}
  2272  	}
  2273  
  2274  	// Update generator state and return the block.
  2275  	blockHash := block.BlockHash()
  2276  	if block.Header.PrevBlock != prevHash {
  2277  		// Save the orignal block this one was built from if it was
  2278  		// manually changed in a munger so the code which deals with
  2279  		// updating the live tickets when changing the tip has access to
  2280  		// it.
  2281  		g.originalParents[blockHash] = prevHash
  2282  	}
  2283  	g.addMissedVotes(&blockHash, block.STransactions, ticketWinners)
  2284  	g.connectRevocations(&blockHash, block.STransactions)
  2285  	g.connectLiveTickets(&blockHash, nextHeight, ticketWinners,
  2286  		ticketPurchases)
  2287  	g.blocks[blockHash] = &block
  2288  	g.blockHeights[blockHash] = nextHeight
  2289  	g.blocksByName[blockName] = &block
  2290  	g.tip = &block
  2291  	g.tipName = blockName
  2292  	return &block
  2293  }
  2294  
  2295  // CreatePremineBlock generates the first block of the chain with the required
  2296  // premine payouts.  The additional amount parameter can be used to create a
  2297  // block that is otherwise a completely valid premine block except it adds the
  2298  // extra amount to each payout and thus create a block that violates consensus.
  2299  func (g *Generator) CreatePremineBlock(blockName string, additionalAmount dcrutil.Amount, mungers ...func(*wire.MsgBlock)) *wire.MsgBlock {
  2300  	coinbaseTx := wire.NewMsgTx()
  2301  	coinbaseTx.AddTxIn(&wire.TxIn{
  2302  		PreviousOutPoint: *wire.NewOutPoint(&chainhash.Hash{},
  2303  			wire.MaxPrevOutIndex, wire.TxTreeRegular),
  2304  		Sequence:        wire.MaxTxInSequenceNum,
  2305  		ValueIn:         0, // Updated below.
  2306  		BlockHeight:     wire.NullBlockHeight,
  2307  		BlockIndex:      wire.NullBlockIndex,
  2308  		SignatureScript: coinbaseSigScript,
  2309  	})
  2310  
  2311  	// Add each required output and tally the total payouts for the coinbase
  2312  	// in order to set the input value appropriately.
  2313  	var totalSubsidy dcrutil.Amount
  2314  	for _, payout := range g.params.BlockOneLedger {
  2315  		payoutAddr, err := dcrutil.DecodeAddress(payout.Address)
  2316  		if err != nil {
  2317  			panic(err)
  2318  		}
  2319  		pkScript, err := txscript.PayToAddrScript(payoutAddr)
  2320  		if err != nil {
  2321  			panic(err)
  2322  		}
  2323  		coinbaseTx.AddTxOut(&wire.TxOut{
  2324  			Value:    payout.Amount + int64(additionalAmount),
  2325  			Version:  0,
  2326  			PkScript: pkScript,
  2327  		})
  2328  
  2329  		totalSubsidy += dcrutil.Amount(payout.Amount)
  2330  	}
  2331  	coinbaseTx.TxIn[0].ValueIn = int64(totalSubsidy)
  2332  
  2333  	// Generate the block with the specially created regular transactions.
  2334  	munger := func(b *wire.MsgBlock) {
  2335  		b.Transactions = []*wire.MsgTx{coinbaseTx}
  2336  	}
  2337  	mungers = append([]func(*wire.MsgBlock){munger}, mungers...)
  2338  	return g.NextBlock(blockName, nil, nil, mungers...)
  2339  }
  2340  
  2341  // UpdateBlockState manually updates the generator state to remove all internal
  2342  // map references to a block via its old hash and insert new ones for the new
  2343  // block hash.  This is useful if the test code has to manually change a block
  2344  // after 'NextBlock' has returned.
  2345  func (g *Generator) UpdateBlockState(oldBlockName string, oldBlockHash chainhash.Hash, newBlockName string, newBlock *wire.MsgBlock) {
  2346  	// Remove existing entries.
  2347  	wonTickets := g.wonTickets[oldBlockHash]
  2348  	existingHeight := g.blockHeights[oldBlockHash]
  2349  	delete(g.blocks, oldBlockHash)
  2350  	delete(g.blockHeights, oldBlockHash)
  2351  	delete(g.blocksByName, oldBlockName)
  2352  	delete(g.wonTickets, oldBlockHash)
  2353  
  2354  	// Add new entries.
  2355  	newBlockHash := newBlock.BlockHash()
  2356  	g.blocks[newBlockHash] = newBlock
  2357  	g.blockHeights[newBlockHash] = existingHeight
  2358  	g.blocksByName[newBlockName] = newBlock
  2359  	g.wonTickets[newBlockHash] = wonTickets
  2360  }
  2361  
  2362  // OldestCoinbaseOuts removes the oldest set of coinbase proof-of-work outputs
  2363  // that was previously saved to the generator and returns the set as a slice.
  2364  func (g *Generator) OldestCoinbaseOuts() []SpendableOut {
  2365  	outs := g.spendableOuts[0]
  2366  	g.spendableOuts = g.spendableOuts[1:]
  2367  	return outs
  2368  }
  2369  
  2370  // NumSpendableCoinbaseOuts returns the number of proof-of-work outputs that
  2371  // were previously saved to the generated but have not yet been collected.
  2372  func (g *Generator) NumSpendableCoinbaseOuts() int {
  2373  	return len(g.spendableOuts)
  2374  }
  2375  
  2376  // saveCoinbaseOuts adds the proof-of-work outputs of the coinbase tx in the
  2377  // passed block to the list of spendable outputs.
  2378  func (g *Generator) saveCoinbaseOuts(b *wire.MsgBlock) {
  2379  	g.spendableOuts = append(g.spendableOuts, []SpendableOut{
  2380  		MakeSpendableOut(b, 0, 2),
  2381  		MakeSpendableOut(b, 0, 3),
  2382  		MakeSpendableOut(b, 0, 4),
  2383  		MakeSpendableOut(b, 0, 5),
  2384  		MakeSpendableOut(b, 0, 6),
  2385  		MakeSpendableOut(b, 0, 7),
  2386  	})
  2387  	g.prevCollectedHash = b.BlockHash()
  2388  }
  2389  
  2390  // SaveTipCoinbaseOuts adds the proof-of-work outputs of the coinbase tx in the
  2391  // current tip block to the list of spendable outputs.
  2392  func (g *Generator) SaveTipCoinbaseOuts() {
  2393  	g.saveCoinbaseOuts(g.tip)
  2394  }
  2395  
  2396  // SaveSpendableCoinbaseOuts adds all proof-of-work coinbase outputs starting
  2397  // from the block after the last block that had its coinbase outputs collected
  2398  // and ending at the current tip.  This is useful to batch the collection of the
  2399  // outputs once the tests reach a stable point so they don't have to manually
  2400  // add them for the right tests which will ultimately end up being the best
  2401  // chain.
  2402  func (g *Generator) SaveSpendableCoinbaseOuts() {
  2403  	// Loop through the ancestors of the current tip until the
  2404  	// reaching the block that has already had the coinbase outputs
  2405  	// collected.
  2406  	var collectBlocks []*wire.MsgBlock
  2407  	for b := g.tip; b != nil; b = g.blocks[b.Header.PrevBlock] {
  2408  		if b.BlockHash() == g.prevCollectedHash {
  2409  			break
  2410  		}
  2411  		collectBlocks = append(collectBlocks, b)
  2412  	}
  2413  	for i := range collectBlocks {
  2414  		g.saveCoinbaseOuts(collectBlocks[len(collectBlocks)-1-i])
  2415  	}
  2416  }
  2417  
  2418  // AssertTipHeight panics if the current tip block associated with the generator
  2419  // does not have the specified height.
  2420  func (g *Generator) AssertTipHeight(expected uint32) {
  2421  	height := g.tip.Header.Height
  2422  	if height != expected {
  2423  		panic(fmt.Sprintf("height for block %q is %d instead of "+
  2424  			"expected %d", g.tipName, height, expected))
  2425  	}
  2426  }
  2427  
  2428  // AssertScriptSigOpsCount panics if the provided script does not have the
  2429  // specified number of signature operations.
  2430  func (g *Generator) AssertScriptSigOpsCount(script []byte, expected int) {
  2431  	numSigOps := txscript.GetSigOpCount(script)
  2432  	if numSigOps != expected {
  2433  		_, file, line, _ := runtime.Caller(1)
  2434  		panic(fmt.Sprintf("assertion failed at %s:%d: generated number "+
  2435  			"of sigops for script is %d instead of expected %d",
  2436  			file, line, numSigOps, expected))
  2437  	}
  2438  }
  2439  
  2440  // countBlockSigOps returns the number of legacy signature operations in the
  2441  // scripts in the passed block.
  2442  func countBlockSigOps(block *wire.MsgBlock) int {
  2443  	totalSigOps := 0
  2444  	for _, tx := range block.Transactions {
  2445  		for _, txIn := range tx.TxIn {
  2446  			numSigOps := txscript.GetSigOpCount(txIn.SignatureScript)
  2447  			totalSigOps += numSigOps
  2448  		}
  2449  		for _, txOut := range tx.TxOut {
  2450  			numSigOps := txscript.GetSigOpCount(txOut.PkScript)
  2451  			totalSigOps += numSigOps
  2452  		}
  2453  	}
  2454  
  2455  	return totalSigOps
  2456  }
  2457  
  2458  // AssertTipBlockSigOpsCount panics if the current tip block associated with the
  2459  // generator does not have the specified number of signature operations.
  2460  func (g *Generator) AssertTipBlockSigOpsCount(expected int) {
  2461  	numSigOps := countBlockSigOps(g.tip)
  2462  	if numSigOps != expected {
  2463  		panic(fmt.Sprintf("generated number of sigops for block %q "+
  2464  			"(height %d) is %d instead of expected %d", g.tipName,
  2465  			g.tip.Header.Height, numSigOps, expected))
  2466  	}
  2467  }
  2468  
  2469  // AssertTipBlockSize panics if the if the current tip block associated with the
  2470  // generator does not have the specified size when serialized.
  2471  func (g *Generator) AssertTipBlockSize(expected int) {
  2472  	serializeSize := g.tip.SerializeSize()
  2473  	if serializeSize != expected {
  2474  		panic(fmt.Sprintf("block size of block %q (height %d) is %d "+
  2475  			"instead of expected %d", g.tipName,
  2476  			g.tip.Header.Height, serializeSize, expected))
  2477  	}
  2478  }
  2479  
  2480  // AssertTipBlockNumTxns panics if the number of transactions in the current tip
  2481  // block associated with the generator does not match the specified value.
  2482  func (g *Generator) AssertTipBlockNumTxns(expected int) {
  2483  	numTxns := len(g.tip.Transactions)
  2484  	if numTxns != expected {
  2485  		panic(fmt.Sprintf("number of txns in block %q (height %d) is "+
  2486  			"%d instead of expected %d", g.tipName,
  2487  			g.tip.Header.Height, numTxns, expected))
  2488  	}
  2489  }
  2490  
  2491  // AssertTipBlockHash panics if the current tip block associated with the
  2492  // generator does not match the specified hash.
  2493  func (g *Generator) AssertTipBlockHash(expected chainhash.Hash) {
  2494  	hash := g.tip.BlockHash()
  2495  	if hash != expected {
  2496  		panic(fmt.Sprintf("block hash of block %q (height %d) is %v "+
  2497  			"instead of expected %v", g.tipName,
  2498  			g.tip.Header.Height, hash, expected))
  2499  	}
  2500  }
  2501  
  2502  // AssertTipBlockMerkleRoot panics if the merkle root in header of the current
  2503  // tip block associated with the generator does not match the specified hash.
  2504  func (g *Generator) AssertTipBlockMerkleRoot(expected chainhash.Hash) {
  2505  	hash := g.tip.Header.MerkleRoot
  2506  	if hash != expected {
  2507  		panic(fmt.Sprintf("merkle root of block %q (height %d) is %v "+
  2508  			"instead of expected %v", g.tipName,
  2509  			g.tip.Header.Height, hash, expected))
  2510  	}
  2511  }
  2512  
  2513  // AssertTipBlockStakeRoot panics if the stake root in header of the current
  2514  // tip block associated with the generator does not match the specified hash.
  2515  func (g *Generator) AssertTipBlockStakeRoot(expected chainhash.Hash) {
  2516  	hash := g.tip.Header.StakeRoot
  2517  	if hash != expected {
  2518  		panic(fmt.Sprintf("stake root of block %q (height %d) is %v "+
  2519  			"instead of expected %v", g.tipName,
  2520  			g.tip.Header.Height, hash, expected))
  2521  	}
  2522  }
  2523  
  2524  // AssertTipBlockTxOutOpReturn panics if the current tip block associated with
  2525  // the generator does not have an OP_RETURN script for the transaction output at
  2526  // the provided tx index and output index.
  2527  func (g *Generator) AssertTipBlockTxOutOpReturn(txIndex, txOutIndex uint32) {
  2528  	if txIndex >= uint32(len(g.tip.Transactions)) {
  2529  		panic(fmt.Sprintf("transaction index %d in block %q "+
  2530  			"(height %d) does not exist", txIndex, g.tipName,
  2531  			g.tip.Header.Height))
  2532  	}
  2533  
  2534  	tx := g.tip.Transactions[txIndex]
  2535  	if txOutIndex >= uint32(len(tx.TxOut)) {
  2536  		panic(fmt.Sprintf("transaction index %d output %d in block %q "+
  2537  			"(height %d) does not exist", txIndex, txOutIndex,
  2538  			g.tipName, g.tip.Header.Height))
  2539  	}
  2540  
  2541  	txOut := tx.TxOut[txOutIndex]
  2542  	if txOut.PkScript[0] != txscript.OP_RETURN {
  2543  		panic(fmt.Sprintf("transaction index %d output %d in block %q "+
  2544  			"(height %d) is not an OP_RETURN", txIndex, txOutIndex,
  2545  			g.tipName, g.tip.Header.Height))
  2546  	}
  2547  }
  2548  
  2549  // AssertStakeVersion panics if the current tip block associated with the
  2550  // generator does not have the specified stake version in the header.
  2551  func (g *Generator) AssertStakeVersion(expected uint32) {
  2552  	stakeVersion := g.tip.Header.StakeVersion
  2553  	if stakeVersion != expected {
  2554  		panic(fmt.Sprintf("stake version for block %q is %d instead of "+
  2555  			"expected %d", g.tipName, stakeVersion, expected))
  2556  	}
  2557  }
  2558  
  2559  // AssertBlockVersion panics if the current tip block associated with the
  2560  // generator does not have the specified block version in the header.
  2561  func (g *Generator) AssertBlockVersion(expected int32) {
  2562  	blockVersion := g.tip.Header.Version
  2563  	if blockVersion != expected {
  2564  		panic(fmt.Sprintf("block version for block %q is %d instead of "+
  2565  			"expected %d", g.tipName, blockVersion, expected))
  2566  	}
  2567  }
  2568  
  2569  // AssertPoolSize panics if the current tip block associated with the generator
  2570  // does not indicate the specified pool size.
  2571  func (g *Generator) AssertPoolSize(expected uint32) {
  2572  	poolSize := g.tip.Header.PoolSize
  2573  	if poolSize != expected {
  2574  		panic(fmt.Sprintf("pool size for block %q is %d instead of expected "+
  2575  			"%d", g.tipName, poolSize, expected))
  2576  	}
  2577  }
  2578  
  2579  // AssertBlockRevocationTx panics if the current tip block associated with the
  2580  // generator does not have a revocation at the specified transaction index
  2581  // provided.
  2582  func (g *Generator) AssertBlockRevocationTx(b *wire.MsgBlock, txIndex uint32) {
  2583  	if !isRevocationTx(b.STransactions[txIndex]) {
  2584  		panic(fmt.Sprintf("stake transaction at index %d in block %q is "+
  2585  			" not a revocation", txIndex, g.tipName))
  2586  	}
  2587  }
  2588  
  2589  // AssertTipNumRevocations panics if the number of revocations in header of the
  2590  // current tip block associated with the generator does not match the specified
  2591  // value.
  2592  func (g *Generator) AssertTipNumRevocations(expected uint8) {
  2593  	numRevocations := g.tip.Header.Revocations
  2594  	if numRevocations != expected {
  2595  		panic(fmt.Sprintf("number of revocations in block %q (height "+
  2596  			"%d) is %d instead of expected %d", g.tipName,
  2597  			g.tip.Header.Height, numRevocations, expected))
  2598  	}
  2599  }
  2600  
  2601  // AssertTipDisapprovesPrevious panics if the current tip block associated with
  2602  // the generator does not disapprove the previous block.
  2603  func (g *Generator) AssertTipDisapprovesPrevious() {
  2604  	if g.tip.Header.VoteBits&voteBitYes == 1 {
  2605  		panic(fmt.Sprintf("block %q (height %d) does not disapprove prev block",
  2606  			g.tipName, g.tip.Header.Height))
  2607  	}
  2608  }