OSDN Git Service

Optimize log printing (#1590)
[bytom/bytom.git] / mining / mining.go
old mode 100755 (executable)
new mode 100644 (file)
index a68f417..e635976
-// Copyright (c) 2014-2016 The btcsuite developers\r
-// Use of this source code is governed by an ISC\r
-// license that can be found in the LICENSE file.\r
-\r
-package mining\r
-\r
-import (\r
-       "container/heap"\r
-       "fmt"\r
-       "time"\r
-\r
-       "github.com/btcsuite/btcd/blockchain"\r
-       "github.com/btcsuite/btcd/chaincfg"\r
-       "github.com/btcsuite/btcd/chaincfg/chainhash"\r
-       "github.com/btcsuite/btcd/txscript"\r
-       "github.com/btcsuite/btcd/wire"\r
-       "github.com/btcsuite/btcutil"\r
-)\r
-\r
-const (\r
-       // MinHighPriority is the minimum priority value that allows a\r
-       // transaction to be considered high priority.\r
-       MinHighPriority = btcutil.SatoshiPerBitcoin * 144.0 / 250\r
-\r
-       // blockHeaderOverhead is the max number of bytes it takes to serialize\r
-       // a block header and max possible transaction count.\r
-       blockHeaderOverhead = wire.MaxBlockHeaderPayload + wire.MaxVarIntPayload\r
-\r
-       // CoinbaseFlags is added to the coinbase script of a generated block\r
-       // and is used to monitor BIP16 support as well as blocks that are\r
-       // generated via btcd.\r
-       CoinbaseFlags = "/P2SH/btcd/"\r
-)\r
-\r
-// TxDesc is a descriptor about a transaction in a transaction source along with\r
-// additional metadata.\r
-type TxDesc struct {\r
-       // Tx is the transaction associated with the entry.\r
-       Tx *btcutil.Tx\r
-\r
-       // Added is the time when the entry was added to the source pool.\r
-       Added time.Time\r
-\r
-       // Height is the block height when the entry was added to the the source\r
-       // pool.\r
-       Height int32\r
-\r
-       // Fee is the total fee the transaction associated with the entry pays.\r
-       Fee int64\r
-\r
-       // FeePerKB is the fee the transaction pays in Satoshi per 1000 bytes.\r
-       FeePerKB int64\r
-}\r
-\r
-// TxSource represents a source of transactions to consider for inclusion in\r
-// new blocks.\r
-//\r
-// The interface contract requires that all of these methods are safe for\r
-// concurrent access with respect to the source.\r
-type TxSource interface {\r
-       // LastUpdated returns the last time a transaction was added to or\r
-       // removed from the source pool.\r
-       LastUpdated() time.Time\r
-\r
-       // MiningDescs returns a slice of mining descriptors for all the\r
-       // transactions in the source pool.\r
-       MiningDescs() []*TxDesc\r
-\r
-       // HaveTransaction returns whether or not the passed transaction hash\r
-       // exists in the source pool.\r
-       HaveTransaction(hash *chainhash.Hash) bool\r
-}\r
-\r
-// txPrioItem houses a transaction along with extra information that allows the\r
-// transaction to be prioritized and track dependencies on other transactions\r
-// which have not been mined into a block yet.\r
-type txPrioItem struct {\r
-       tx       *btcutil.Tx\r
-       fee      int64\r
-       priority float64\r
-       feePerKB int64\r
-\r
-       // dependsOn holds a map of transaction hashes which this one depends\r
-       // on.  It will only be set when the transaction references other\r
-       // transactions in the source pool and hence must come after them in\r
-       // a block.\r
-       dependsOn map[chainhash.Hash]struct{}\r
-}\r
-\r
-// txPriorityQueueLessFunc describes a function that can be used as a compare\r
-// function for a transaction priority queue (txPriorityQueue).\r
-type txPriorityQueueLessFunc func(*txPriorityQueue, int, int) bool\r
-\r
-// txPriorityQueue implements a priority queue of txPrioItem elements that\r
-// supports an arbitrary compare function as defined by txPriorityQueueLessFunc.\r
-type txPriorityQueue struct {\r
-       lessFunc txPriorityQueueLessFunc\r
-       items    []*txPrioItem\r
-}\r
-\r
-// Len returns the number of items in the priority queue.  It is part of the\r
-// heap.Interface implementation.\r
-func (pq *txPriorityQueue) Len() int {\r
-       return len(pq.items)\r
-}\r
-\r
-// Less returns whether the item in the priority queue with index i should sort\r
-// before the item with index j by deferring to the assigned less function.  It\r
-// is part of the heap.Interface implementation.\r
-func (pq *txPriorityQueue) Less(i, j int) bool {\r
-       return pq.lessFunc(pq, i, j)\r
-}\r
-\r
-// Swap swaps the items at the passed indices in the priority queue.  It is\r
-// part of the heap.Interface implementation.\r
-func (pq *txPriorityQueue) Swap(i, j int) {\r
-       pq.items[i], pq.items[j] = pq.items[j], pq.items[i]\r
-}\r
-\r
-// Push pushes the passed item onto the priority queue.  It is part of the\r
-// heap.Interface implementation.\r
-func (pq *txPriorityQueue) Push(x interface{}) {\r
-       pq.items = append(pq.items, x.(*txPrioItem))\r
-}\r
-\r
-// Pop removes the highest priority item (according to Less) from the priority\r
-// queue and returns it.  It is part of the heap.Interface implementation.\r
-func (pq *txPriorityQueue) Pop() interface{} {\r
-       n := len(pq.items)\r
-       item := pq.items[n-1]\r
-       pq.items[n-1] = nil\r
-       pq.items = pq.items[0 : n-1]\r
-       return item\r
-}\r
-\r
-// SetLessFunc sets the compare function for the priority queue to the provided\r
-// function.  It also invokes heap.Init on the priority queue using the new\r
-// function so it can immediately be used with heap.Push/Pop.\r
-func (pq *txPriorityQueue) SetLessFunc(lessFunc txPriorityQueueLessFunc) {\r
-       pq.lessFunc = lessFunc\r
-       heap.Init(pq)\r
-}\r
-\r
-// txPQByPriority sorts a txPriorityQueue by transaction priority and then fees\r
-// per kilobyte.\r
-func txPQByPriority(pq *txPriorityQueue, i, j int) bool {\r
-       // Using > here so that pop gives the highest priority item as opposed\r
-       // to the lowest.  Sort by priority first, then fee.\r
-       if pq.items[i].priority == pq.items[j].priority {\r
-               return pq.items[i].feePerKB > pq.items[j].feePerKB\r
-       }\r
-       return pq.items[i].priority > pq.items[j].priority\r
-\r
-}\r
-\r
-// txPQByFee sorts a txPriorityQueue by fees per kilobyte and then transaction\r
-// priority.\r
-func txPQByFee(pq *txPriorityQueue, i, j int) bool {\r
-       // Using > here so that pop gives the highest fee item as opposed\r
-       // to the lowest.  Sort by fee first, then priority.\r
-       if pq.items[i].feePerKB == pq.items[j].feePerKB {\r
-               return pq.items[i].priority > pq.items[j].priority\r
-       }\r
-       return pq.items[i].feePerKB > pq.items[j].feePerKB\r
-}\r
-\r
-// newTxPriorityQueue returns a new transaction priority queue that reserves the\r
-// passed amount of space for the elements.  The new priority queue uses either\r
-// the txPQByPriority or the txPQByFee compare function depending on the\r
-// sortByFee parameter and is already initialized for use with heap.Push/Pop.\r
-// The priority queue can grow larger than the reserved space, but extra copies\r
-// of the underlying array can be avoided by reserving a sane value.\r
-func newTxPriorityQueue(reserve int, sortByFee bool) *txPriorityQueue {\r
-       pq := &txPriorityQueue{\r
-               items: make([]*txPrioItem, 0, reserve),\r
-       }\r
-       if sortByFee {\r
-               pq.SetLessFunc(txPQByFee)\r
-       } else {\r
-               pq.SetLessFunc(txPQByPriority)\r
-       }\r
-       return pq\r
-}\r
-\r
-// BlockTemplate houses a block that has yet to be solved along with additional\r
-// details about the fees and the number of signature operations for each\r
-// transaction in the block.\r
-type BlockTemplate struct {\r
-       // Block is a block that is ready to be solved by miners.  Thus, it is\r
-       // completely valid with the exception of satisfying the proof-of-work\r
-       // requirement.\r
-       Block *wire.MsgBlock\r
-\r
-       // Fees contains the amount of fees each transaction in the generated\r
-       // template pays in base units.  Since the first transaction is the\r
-       // coinbase, the first entry (offset 0) will contain the negative of the\r
-       // sum of the fees of all other transactions.\r
-       Fees []int64\r
-\r
-       // SigOpCounts contains the number of signature operations each\r
-       // transaction in the generated template performs.\r
-       SigOpCounts []int64\r
-\r
-       // Height is the height at which the block template connects to the main\r
-       // chain.\r
-       Height int32\r
-\r
-       // ValidPayAddress indicates whether or not the template coinbase pays\r
-       // to an address or is redeemable by anyone.  See the documentation on\r
-       // NewBlockTemplate for details on which this can be useful to generate\r
-       // templates without a coinbase payment address.\r
-       ValidPayAddress bool\r
-}\r
-\r
-// mergeUtxoView adds all of the entries in view to viewA.  The result is that\r
-// viewA will contain all of its original entries plus all of the entries\r
-// in viewB.  It will replace any entries in viewB which also exist in viewA\r
-// if the entry in viewA is fully spent.\r
-func mergeUtxoView(viewA *blockchain.UtxoViewpoint, viewB *blockchain.UtxoViewpoint) {\r
-       viewAEntries := viewA.Entries()\r
-       for hash, entryB := range viewB.Entries() {\r
-               if entryA, exists := viewAEntries[hash]; !exists ||\r
-                       entryA == nil || entryA.IsFullySpent() {\r
-\r
-                       viewAEntries[hash] = entryB\r
-               }\r
-       }\r
-}\r
-\r
-// standardCoinbaseScript returns a standard script suitable for use as the\r
-// signature script of the coinbase transaction of a new block.  In particular,\r
-// it starts with the block height that is required by version 2 blocks and adds\r
-// the extra nonce as well as additional coinbase flags.\r
-func standardCoinbaseScript(nextBlockHeight int32, extraNonce uint64) ([]byte, error) {\r
-       return txscript.NewScriptBuilder().AddInt64(int64(nextBlockHeight)).\r
-               AddInt64(int64(extraNonce)).AddData([]byte(CoinbaseFlags)).\r
-               Script()\r
-}\r
-\r
-// createCoinbaseTx returns a coinbase transaction paying an appropriate subsidy\r
-// based on the passed block height to the provided address.  When the address\r
-// is nil, the coinbase transaction will instead be redeemable by anyone.\r
-//\r
-// See the comment for NewBlockTemplate for more information about why the nil\r
-// address handling is useful.\r
-func createCoinbaseTx(params *chaincfg.Params, coinbaseScript []byte, nextBlockHeight int32, addr btcutil.Address) (*btcutil.Tx, error) {\r
-       // Create the script to pay to the provided payment address if one was\r
-       // specified.  Otherwise create a script that allows the coinbase to be\r
-       // redeemable by anyone.\r
-       var pkScript []byte\r
-       if addr != nil {\r
-               var err error\r
-               pkScript, err = txscript.PayToAddrScript(addr)\r
-               if err != nil {\r
-                       return nil, err\r
-               }\r
-       } else {\r
-               var err error\r
-               scriptBuilder := txscript.NewScriptBuilder()\r
-               pkScript, err = scriptBuilder.AddOp(txscript.OP_TRUE).Script()\r
-               if err != nil {\r
-                       return nil, err\r
-               }\r
-       }\r
-\r
-       tx := wire.NewMsgTx(wire.TxVersion)\r
-       tx.AddTxIn(&wire.TxIn{\r
-               // Coinbase transactions have no inputs, so previous outpoint is\r
-               // zero hash and max index.\r
-               PreviousOutPoint: *wire.NewOutPoint(&chainhash.Hash{},\r
-                       wire.MaxPrevOutIndex),\r
-               SignatureScript: coinbaseScript,\r
-               Sequence:        wire.MaxTxInSequenceNum,\r
-       })\r
-       tx.AddTxOut(&wire.TxOut{\r
-               Value:    blockchain.CalcBlockSubsidy(nextBlockHeight, params),\r
-               PkScript: pkScript,\r
-       })\r
-       return btcutil.NewTx(tx), nil\r
-}\r
-\r
-// spendTransaction updates the passed view by marking the inputs to the passed\r
-// transaction as spent.  It also adds all outputs in the passed transaction\r
-// which are not provably unspendable as available unspent transaction outputs.\r
-func spendTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil.Tx, height int32) error {\r
-       for _, txIn := range tx.MsgTx().TxIn {\r
-               originHash := &txIn.PreviousOutPoint.Hash\r
-               originIndex := txIn.PreviousOutPoint.Index\r
-               entry := utxoView.LookupEntry(originHash)\r
-               if entry != nil {\r
-                       entry.SpendOutput(originIndex)\r
-               }\r
-       }\r
-\r
-       utxoView.AddTxOuts(tx, height)\r
-       return nil\r
-}\r
-\r
-// logSkippedDeps logs any dependencies which are also skipped as a result of\r
-// skipping a transaction while generating a block template at the trace level.\r
-func logSkippedDeps(tx *btcutil.Tx, deps map[chainhash.Hash]*txPrioItem) {\r
-       if deps == nil {\r
-               return\r
-       }\r
-\r
-       for _, item := range deps {\r
-               log.Tracef("Skipping tx %s since it depends on %s\n",\r
-                       item.tx.Hash(), tx.Hash())\r
-       }\r
-}\r
-\r
-// MinimumMedianTime returns the minimum allowed timestamp for a block building\r
-// on the end of the provided best chain.  In particular, it is one second after\r
-// the median timestamp of the last several blocks per the chain consensus\r
-// rules.\r
-func MinimumMedianTime(chainState *blockchain.BestState) time.Time {\r
-       return chainState.MedianTime.Add(time.Second)\r
-}\r
-\r
-// medianAdjustedTime returns the current time adjusted to ensure it is at least\r
-// one second after the median timestamp of the last several blocks per the\r
-// chain consensus rules.\r
-func medianAdjustedTime(chainState *blockchain.BestState, timeSource blockchain.MedianTimeSource) time.Time {\r
-       // The timestamp for the block must not be before the median timestamp\r
-       // of the last several blocks.  Thus, choose the maximum between the\r
-       // current time and one second after the past median time.  The current\r
-       // timestamp is truncated to a second boundary before comparison since a\r
-       // block timestamp does not supported a precision greater than one\r
-       // second.\r
-       newTimestamp := timeSource.AdjustedTime()\r
-       minTimestamp := MinimumMedianTime(chainState)\r
-       if newTimestamp.Before(minTimestamp) {\r
-               newTimestamp = minTimestamp\r
-       }\r
-\r
-       return newTimestamp\r
-}\r
-\r
-// BlkTmplGenerator provides a type that can be used to generate block templates\r
-// based on a given mining policy and source of transactions to choose from.\r
-// It also houses additional state required in order to ensure the templates\r
-// are built on top of the current best chain and adhere to the consensus rules.\r
-type BlkTmplGenerator struct {\r
-       policy      *Policy\r
-       chainParams *chaincfg.Params\r
-       txSource    TxSource\r
-       chain       *blockchain.BlockChain\r
-       timeSource  blockchain.MedianTimeSource\r
-       sigCache    *txscript.SigCache\r
-}\r
-\r
-// NewBlkTmplGenerator returns a new block template generator for the given\r
-// policy using transactions from the provided transaction source.\r
-//\r
-// The additional state-related fields are required in order to ensure the\r
-// templates are built on top of the current best chain and adhere to the\r
-// consensus rules.\r
-func NewBlkTmplGenerator(policy *Policy, params *chaincfg.Params,\r
-       txSource TxSource, chain *blockchain.BlockChain,\r
-       timeSource blockchain.MedianTimeSource,\r
-       sigCache *txscript.SigCache) *BlkTmplGenerator {\r
-\r
-       return &BlkTmplGenerator{\r
-               policy:      policy,\r
-               chainParams: params,\r
-               txSource:    txSource,\r
-               chain:       chain,\r
-               timeSource:  timeSource,\r
-               sigCache:    sigCache,\r
-       }\r
-}\r
-\r
-// NewBlockTemplate returns a new block template that is ready to be solved\r
-// using the transactions from the passed transaction source pool and a coinbase\r
-// that either pays to the passed address if it is not nil, or a coinbase that\r
-// is redeemable by anyone if the passed address is nil.  The nil address\r
-// functionality is useful since there are cases such as the getblocktemplate\r
-// RPC where external mining software is responsible for creating their own\r
-// coinbase which will replace the one generated for the block template.  Thus\r
-// the need to have configured address can be avoided.\r
-//\r
-// The transactions selected and included are prioritized according to several\r
-// factors.  First, each transaction has a priority calculated based on its\r
-// value, age of inputs, and size.  Transactions which consist of larger\r
-// amounts, older inputs, and small sizes have the highest priority.  Second, a\r
-// fee per kilobyte is calculated for each transaction.  Transactions with a\r
-// higher fee per kilobyte are preferred.  Finally, the block generation related\r
-// policy settings are all taken into account.\r
-//\r
-// Transactions which only spend outputs from other transactions already in the\r
-// block chain are immediately added to a priority queue which either\r
-// prioritizes based on the priority (then fee per kilobyte) or the fee per\r
-// kilobyte (then priority) depending on whether or not the BlockPrioritySize\r
-// policy setting allots space for high-priority transactions.  Transactions\r
-// which spend outputs from other transactions in the source pool are added to a\r
-// dependency map so they can be added to the priority queue once the\r
-// transactions they depend on have been included.\r
-//\r
-// Once the high-priority area (if configured) has been filled with\r
-// transactions, or the priority falls below what is considered high-priority,\r
-// the priority queue is updated to prioritize by fees per kilobyte (then\r
-// priority).\r
-//\r
-// When the fees per kilobyte drop below the TxMinFreeFee policy setting, the\r
-// transaction will be skipped unless the BlockMinSize policy setting is\r
-// nonzero, in which case the block will be filled with the low-fee/free\r
-// transactions until the block size reaches that minimum size.\r
-//\r
-// Any transactions which would cause the block to exceed the BlockMaxSize\r
-// policy setting, exceed the maximum allowed signature operations per block, or\r
-// otherwise cause the block to be invalid are skipped.\r
-//\r
-// Given the above, a block generated by this function is of the following form:\r
-//\r
-//   -----------------------------------  --  --\r
-//  |      Coinbase Transaction         |   |   |\r
-//  |-----------------------------------|   |   |\r
-//  |                                   |   |   | ----- policy.BlockPrioritySize\r
-//  |   High-priority Transactions      |   |   |\r
-//  |                                   |   |   |\r
-//  |-----------------------------------|   | --\r
-//  |                                   |   |\r
-//  |                                   |   |\r
-//  |                                   |   |--- policy.BlockMaxSize\r
-//  |  Transactions prioritized by fee  |   |\r
-//  |  until <= policy.TxMinFreeFee     |   |\r
-//  |                                   |   |\r
-//  |                                   |   |\r
-//  |                                   |   |\r
-//  |-----------------------------------|   |\r
-//  |  Low-fee/Non high-priority (free) |   |\r
-//  |  transactions (while block size   |   |\r
-//  |  <= policy.BlockMinSize)          |   |\r
-//   -----------------------------------  --\r
-func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress btcutil.Address) (*BlockTemplate, error) {\r
-       // Extend the most recently known best block.\r
-       best := g.chain.BestSnapshot()\r
-       prevHash := &best.Hash\r
-       nextBlockHeight := best.Height + 1\r
-\r
-       // Create a standard coinbase transaction paying to the provided\r
-       // address.  NOTE: The coinbase value will be updated to include the\r
-       // fees from the selected transactions later after they have actually\r
-       // been selected.  It is created here to detect any errors early\r
-       // before potentially doing a lot of work below.  The extra nonce helps\r
-       // ensure the transaction is not a duplicate transaction (paying the\r
-       // same value to the same public key address would otherwise be an\r
-       // identical transaction for block version 1).\r
-       extraNonce := uint64(0)\r
-       coinbaseScript, err := standardCoinbaseScript(nextBlockHeight, extraNonce)\r
-       if err != nil {\r
-               return nil, err\r
-       }\r
-       coinbaseTx, err := createCoinbaseTx(g.chainParams, coinbaseScript,\r
-               nextBlockHeight, payToAddress)\r
-       if err != nil {\r
-               return nil, err\r
-       }\r
-       numCoinbaseSigOps := int64(blockchain.CountSigOps(coinbaseTx))\r
-\r
-       // Get the current source transactions and create a priority queue to\r
-       // hold the transactions which are ready for inclusion into a block\r
-       // along with some priority related and fee metadata.  Reserve the same\r
-       // number of items that are available for the priority queue.  Also,\r
-       // choose the initial sort order for the priority queue based on whether\r
-       // or not there is an area allocated for high-priority transactions.\r
-       sourceTxns := g.txSource.MiningDescs()\r
-       sortedByFee := g.policy.BlockPrioritySize == 0\r
-       priorityQueue := newTxPriorityQueue(len(sourceTxns), sortedByFee)\r
-\r
-       // Create a slice to hold the transactions to be included in the\r
-       // generated block with reserved space.  Also create a utxo view to\r
-       // house all of the input transactions so multiple lookups can be\r
-       // avoided.\r
-       blockTxns := make([]*btcutil.Tx, 0, len(sourceTxns))\r
-       blockTxns = append(blockTxns, coinbaseTx)\r
-       blockUtxos := blockchain.NewUtxoViewpoint()\r
-\r
-       // dependers is used to track transactions which depend on another\r
-       // transaction in the source pool.  This, in conjunction with the\r
-       // dependsOn map kept with each dependent transaction helps quickly\r
-       // determine which dependent transactions are now eligible for inclusion\r
-       // in the block once each transaction has been included.\r
-       dependers := make(map[chainhash.Hash]map[chainhash.Hash]*txPrioItem)\r
-\r
-       // Create slices to hold the fees and number of signature operations\r
-       // for each of the selected transactions and add an entry for the\r
-       // coinbase.  This allows the code below to simply append details about\r
-       // a transaction as it is selected for inclusion in the final block.\r
-       // However, since the total fees aren't known yet, use a dummy value for\r
-       // the coinbase fee which will be updated later.\r
-       txFees := make([]int64, 0, len(sourceTxns))\r
-       txSigOpCounts := make([]int64, 0, len(sourceTxns))\r
-       txFees = append(txFees, -1) // Updated once known\r
-       txSigOpCounts = append(txSigOpCounts, numCoinbaseSigOps)\r
-\r
-       log.Debugf("Considering %d transactions for inclusion to new block",\r
-               len(sourceTxns))\r
-\r
-mempoolLoop:\r
-       for _, txDesc := range sourceTxns {\r
-               // A block can't have more than one coinbase or contain\r
-               // non-finalized transactions.\r
-               tx := txDesc.Tx\r
-               if blockchain.IsCoinBase(tx) {\r
-                       log.Tracef("Skipping coinbase tx %s", tx.Hash())\r
-                       continue\r
-               }\r
-               if !blockchain.IsFinalizedTransaction(tx, nextBlockHeight,\r
-                       g.timeSource.AdjustedTime()) {\r
-\r
-                       log.Tracef("Skipping non-finalized tx %s", tx.Hash())\r
-                       continue\r
-               }\r
-\r
-               // Fetch all of the utxos referenced by the this transaction.\r
-               // NOTE: This intentionally does not fetch inputs from the\r
-               // mempool since a transaction which depends on other\r
-               // transactions in the mempool must come after those\r
-               // dependencies in the final generated block.\r
-               utxos, err := g.chain.FetchUtxoView(tx)\r
-               if err != nil {\r
-                       log.Warnf("Unable to fetch utxo view for tx %s: %v",\r
-                               tx.Hash(), err)\r
-                       continue\r
-               }\r
-\r
-               // Setup dependencies for any transactions which reference\r
-               // other transactions in the mempool so they can be properly\r
-               // ordered below.\r
-               prioItem := &txPrioItem{tx: tx}\r
-               for _, txIn := range tx.MsgTx().TxIn {\r
-                       originHash := &txIn.PreviousOutPoint.Hash\r
-                       originIndex := txIn.PreviousOutPoint.Index\r
-                       utxoEntry := utxos.LookupEntry(originHash)\r
-                       if utxoEntry == nil || utxoEntry.IsOutputSpent(originIndex) {\r
-                               if !g.txSource.HaveTransaction(originHash) {\r
-                                       log.Tracef("Skipping tx %s because it "+\r
-                                               "references unspent output %s "+\r
-                                               "which is not available",\r
-                                               tx.Hash(), txIn.PreviousOutPoint)\r
-                                       continue mempoolLoop\r
-                               }\r
-\r
-                               // The transaction is referencing another\r
-                               // transaction in the source pool, so setup an\r
-                               // ordering dependency.\r
-                               deps, exists := dependers[*originHash]\r
-                               if !exists {\r
-                                       deps = make(map[chainhash.Hash]*txPrioItem)\r
-                                       dependers[*originHash] = deps\r
-                               }\r
-                               deps[*prioItem.tx.Hash()] = prioItem\r
-                               if prioItem.dependsOn == nil {\r
-                                       prioItem.dependsOn = make(\r
-                                               map[chainhash.Hash]struct{})\r
-                               }\r
-                               prioItem.dependsOn[*originHash] = struct{}{}\r
-\r
-                               // Skip the check below. We already know the\r
-                               // referenced transaction is available.\r
-                               continue\r
-                       }\r
-               }\r
-\r
-               // Calculate the final transaction priority using the input\r
-               // value age sum as well as the adjusted transaction size.  The\r
-               // formula is: sum(inputValue * inputAge) / adjustedTxSize\r
-               prioItem.priority = CalcPriority(tx.MsgTx(), utxos,\r
-                       nextBlockHeight)\r
-\r
-               // Calculate the fee in Satoshi/kB.\r
-               prioItem.feePerKB = txDesc.FeePerKB\r
-               prioItem.fee = txDesc.Fee\r
-\r
-               // Add the transaction to the priority queue to mark it ready\r
-               // for inclusion in the block unless it has dependencies.\r
-               if prioItem.dependsOn == nil {\r
-                       heap.Push(priorityQueue, prioItem)\r
-               }\r
-\r
-               // Merge the referenced outputs from the input transactions to\r
-               // this transaction into the block utxo view.  This allows the\r
-               // code below to avoid a second lookup.\r
-               mergeUtxoView(blockUtxos, utxos)\r
-       }\r
-\r
-       log.Tracef("Priority queue len %d, dependers len %d",\r
-               priorityQueue.Len(), len(dependers))\r
-\r
-       // The starting block size is the size of the block header plus the max\r
-       // possible transaction count size, plus the size of the coinbase\r
-       // transaction.\r
-       blockSize := blockHeaderOverhead + uint32(coinbaseTx.MsgTx().SerializeSize())\r
-       blockSigOps := numCoinbaseSigOps\r
-       totalFees := int64(0)\r
-\r
-       // Choose which transactions make it into the block.\r
-       for priorityQueue.Len() > 0 {\r
-               // Grab the highest priority (or highest fee per kilobyte\r
-               // depending on the sort order) transaction.\r
-               prioItem := heap.Pop(priorityQueue).(*txPrioItem)\r
-               tx := prioItem.tx\r
-\r
-               // Grab any transactions which depend on this one.\r
-               deps := dependers[*tx.Hash()]\r
-\r
-               // Enforce maximum block size.  Also check for overflow.\r
-               txSize := uint32(tx.MsgTx().SerializeSize())\r
-               blockPlusTxSize := blockSize + txSize\r
-               if blockPlusTxSize < blockSize ||\r
-                       blockPlusTxSize >= g.policy.BlockMaxSize {\r
-\r
-                       log.Tracef("Skipping tx %s because it would exceed "+\r
-                               "the max block size", tx.Hash())\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-\r
-               // Enforce maximum signature operations per block.  Also check\r
-               // for overflow.\r
-               numSigOps := int64(blockchain.CountSigOps(tx))\r
-               if blockSigOps+numSigOps < blockSigOps ||\r
-                       blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {\r
-                       log.Tracef("Skipping tx %s because it would exceed "+\r
-                               "the maximum sigops per block", tx.Hash())\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-               numP2SHSigOps, err := blockchain.CountP2SHSigOps(tx, false,\r
-                       blockUtxos)\r
-               if err != nil {\r
-                       log.Tracef("Skipping tx %s due to error in "+\r
-                               "CountP2SHSigOps: %v", tx.Hash(), err)\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-               numSigOps += int64(numP2SHSigOps)\r
-               if blockSigOps+numSigOps < blockSigOps ||\r
-                       blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {\r
-                       log.Tracef("Skipping tx %s because it would exceed "+\r
-                               "the maximum sigops per block (p2sh)",\r
-                               tx.Hash())\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-\r
-               // Skip free transactions once the block is larger than the\r
-               // minimum block size.\r
-               if sortedByFee &&\r
-                       prioItem.feePerKB < int64(g.policy.TxMinFreeFee) &&\r
-                       blockPlusTxSize >= g.policy.BlockMinSize {\r
-\r
-                       log.Tracef("Skipping tx %s with feePerKB %.2f "+\r
-                               "< TxMinFreeFee %d and block size %d >= "+\r
-                               "minBlockSize %d", tx.Hash(), prioItem.feePerKB,\r
-                               g.policy.TxMinFreeFee, blockPlusTxSize,\r
-                               g.policy.BlockMinSize)\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-\r
-               // Prioritize by fee per kilobyte once the block is larger than\r
-               // the priority size or there are no more high-priority\r
-               // transactions.\r
-               if !sortedByFee && (blockPlusTxSize >= g.policy.BlockPrioritySize ||\r
-                       prioItem.priority <= MinHighPriority) {\r
-\r
-                       log.Tracef("Switching to sort by fees per kilobyte "+\r
-                               "blockSize %d >= BlockPrioritySize %d || "+\r
-                               "priority %.2f <= minHighPriority %.2f",\r
-                               blockPlusTxSize, g.policy.BlockPrioritySize,\r
-                               prioItem.priority, MinHighPriority)\r
-\r
-                       sortedByFee = true\r
-                       priorityQueue.SetLessFunc(txPQByFee)\r
-\r
-                       // Put the transaction back into the priority queue and\r
-                       // skip it so it is re-priortized by fees if it won't\r
-                       // fit into the high-priority section or the priority is\r
-                       // too low.  Otherwise this transaction will be the\r
-                       // final one in the high-priority section, so just fall\r
-                       // though to the code below so it is added now.\r
-                       if blockPlusTxSize > g.policy.BlockPrioritySize ||\r
-                               prioItem.priority < MinHighPriority {\r
-\r
-                               heap.Push(priorityQueue, prioItem)\r
-                               continue\r
-                       }\r
-               }\r
-\r
-               // Ensure the transaction inputs pass all of the necessary\r
-               // preconditions before allowing it to be added to the block.\r
-               _, err = blockchain.CheckTransactionInputs(tx, nextBlockHeight,\r
-                       blockUtxos, g.chainParams)\r
-               if err != nil {\r
-                       log.Tracef("Skipping tx %s due to error in "+\r
-                               "CheckTransactionInputs: %v", tx.Hash(), err)\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-               err = blockchain.ValidateTransactionScripts(tx, blockUtxos,\r
-                       txscript.StandardVerifyFlags, g.sigCache)\r
-               if err != nil {\r
-                       log.Tracef("Skipping tx %s due to error in "+\r
-                               "ValidateTransactionScripts: %v", tx.Hash(),\r
-                               err)\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-\r
-               // Spend the transaction inputs in the block utxo view and add\r
-               // an entry for it to ensure any transactions which reference\r
-               // this one have it available as an input and can ensure they\r
-               // aren't double spending.\r
-               spendTransaction(blockUtxos, tx, nextBlockHeight)\r
-\r
-               // Add the transaction to the block, increment counters, and\r
-               // save the fees and signature operation counts to the block\r
-               // template.\r
-               blockTxns = append(blockTxns, tx)\r
-               blockSize += txSize\r
-               blockSigOps += numSigOps\r
-               totalFees += prioItem.fee\r
-               txFees = append(txFees, prioItem.fee)\r
-               txSigOpCounts = append(txSigOpCounts, numSigOps)\r
-\r
-               log.Tracef("Adding tx %s (priority %.2f, feePerKB %.2f)",\r
-                       prioItem.tx.Hash(), prioItem.priority, prioItem.feePerKB)\r
-\r
-               // Add transactions which depend on this one (and also do not\r
-               // have any other unsatisified dependencies) to the priority\r
-               // queue.\r
-               for _, item := range deps {\r
-                       // Add the transaction to the priority queue if there\r
-                       // are no more dependencies after this one.\r
-                       delete(item.dependsOn, *tx.Hash())\r
-                       if len(item.dependsOn) == 0 {\r
-                               heap.Push(priorityQueue, item)\r
-                       }\r
-               }\r
-       }\r
-\r
-       // Now that the actual transactions have been selected, update the\r
-       // block size for the real transaction count and coinbase value with\r
-       // the total fees accordingly.\r
-       blockSize -= wire.MaxVarIntPayload -\r
-               uint32(wire.VarIntSerializeSize(uint64(len(blockTxns))))\r
-       coinbaseTx.MsgTx().TxOut[0].Value += totalFees\r
-       txFees[0] = -totalFees\r
-\r
-       // Calculate the required difficulty for the block.  The timestamp\r
-       // is potentially adjusted to ensure it comes after the median time of\r
-       // the last several blocks per the chain consensus rules.\r
-       ts := medianAdjustedTime(best, g.timeSource)\r
-       reqDifficulty, err := g.chain.CalcNextRequiredDifficulty(ts)\r
-       if err != nil {\r
-               return nil, err\r
-       }\r
-\r
-       // Calculate the next expected block version based on the state of the\r
-       // rule change deployments.\r
-       nextBlockVersion, err := g.chain.CalcNextBlockVersion()\r
-       if err != nil {\r
-               return nil, err\r
-       }\r
-\r
-       // Create a new block ready to be solved.\r
-       merkles := blockchain.BuildMerkleTreeStore(blockTxns)\r
-       var msgBlock wire.MsgBlock\r
-       msgBlock.Header = wire.BlockHeader{\r
-               Version:    nextBlockVersion,\r
-               PrevBlock:  *prevHash,\r
-               MerkleRoot: *merkles[len(merkles)-1],\r
-               Timestamp:  ts,\r
-               Bits:       reqDifficulty,\r
-       }\r
-       for _, tx := range blockTxns {\r
-               if err := msgBlock.AddTransaction(tx.MsgTx()); err != nil {\r
-                       return nil, err\r
-               }\r
-       }\r
-\r
-       // Finally, perform a full check on the created block against the chain\r
-       // consensus rules to ensure it properly connects to the current best\r
-       // chain with no issues.\r
-       block := btcutil.NewBlock(&msgBlock)\r
-       block.SetHeight(nextBlockHeight)\r
-       if err := g.chain.CheckConnectBlock(block); err != nil {\r
-               return nil, err\r
-       }\r
-\r
-       log.Debugf("Created new block template (%d transactions, %d in fees, "+\r
-               "%d signature operations, %d bytes, target difficulty %064x)",\r
-               len(msgBlock.Transactions), totalFees, blockSigOps, blockSize,\r
-               blockchain.CompactToBig(msgBlock.Header.Bits))\r
-\r
-       return &BlockTemplate{\r
-               Block:           &msgBlock,\r
-               Fees:            txFees,\r
-               SigOpCounts:     txSigOpCounts,\r
-               Height:          nextBlockHeight,\r
-               ValidPayAddress: payToAddress != nil,\r
-       }, nil\r
-}\r
-\r
-// UpdateBlockTime updates the timestamp in the header of the passed block to\r
-// the current time while taking into account the median time of the last\r
-// several blocks to ensure the new time is after that time per the chain\r
-// consensus rules.  Finally, it will update the target difficulty if needed\r
-// based on the new time for the test networks since their target difficulty can\r
-// change based upon time.\r
-func (g *BlkTmplGenerator) UpdateBlockTime(msgBlock *wire.MsgBlock) error {\r
-       // The new timestamp is potentially adjusted to ensure it comes after\r
-       // the median time of the last several blocks per the chain consensus\r
-       // rules.\r
-       newTime := medianAdjustedTime(g.chain.BestSnapshot(), g.timeSource)\r
-       msgBlock.Header.Timestamp = newTime\r
-\r
-       // Recalculate the difficulty if running on a network that requires it.\r
-       if g.chainParams.ReduceMinDifficulty {\r
-               difficulty, err := g.chain.CalcNextRequiredDifficulty(newTime)\r
-               if err != nil {\r
-                       return err\r
-               }\r
-               msgBlock.Header.Bits = difficulty\r
-       }\r
-\r
-       return nil\r
-}\r
-\r
-// UpdateExtraNonce updates the extra nonce in the coinbase script of the passed\r
-// block by regenerating the coinbase script with the passed value and block\r
-// height.  It also recalculates and updates the new merkle root that results\r
-// from changing the coinbase script.\r
-func (g *BlkTmplGenerator) UpdateExtraNonce(msgBlock *wire.MsgBlock, blockHeight int32, extraNonce uint64) error {\r
-       coinbaseScript, err := standardCoinbaseScript(blockHeight, extraNonce)\r
-       if err != nil {\r
-               return err\r
-       }\r
-       if len(coinbaseScript) > blockchain.MaxCoinbaseScriptLen {\r
-               return fmt.Errorf("coinbase transaction script length "+\r
-                       "of %d is out of range (min: %d, max: %d)",\r
-                       len(coinbaseScript), blockchain.MinCoinbaseScriptLen,\r
-                       blockchain.MaxCoinbaseScriptLen)\r
-       }\r
-       msgBlock.Transactions[0].TxIn[0].SignatureScript = coinbaseScript\r
-\r
-       // TODO(davec): A btcutil.Block should use saved in the state to avoid\r
-       // recalculating all of the other transaction hashes.\r
-       // block.Transactions[0].InvalidateCache()\r
-\r
-       // Recalculate the merkle root with the updated extra nonce.\r
-       block := btcutil.NewBlock(msgBlock)\r
-       merkles := blockchain.BuildMerkleTreeStore(block.Transactions())\r
-       msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1]\r
-       return nil\r
-}\r
-\r
-// BestSnapshot returns information about the current best chain block and\r
-// related state as of the current point in time using the chain instance\r
-// associated with the block template generator.  The returned state must be\r
-// treated as immutable since it is shared by all callers.\r
-//\r
-// This function is safe for concurrent access.\r
-func (g *BlkTmplGenerator) BestSnapshot() *blockchain.BestState {\r
-       return g.chain.BestSnapshot()\r
-}\r
-\r
-// TxSource returns the associated transaction source.\r
-//\r
-// This function is safe for concurrent access.\r
-func (g *BlkTmplGenerator) TxSource() TxSource {\r
-       return g.txSource\r
-}\r
+package mining
+
+import (
+       "sort"
+       "strconv"
+       "time"
+
+       log "github.com/sirupsen/logrus"
+
+       "github.com/bytom/account"
+       "github.com/bytom/blockchain/txbuilder"
+       "github.com/bytom/consensus"
+       "github.com/bytom/errors"
+       "github.com/bytom/protocol"
+       "github.com/bytom/protocol/bc"
+       "github.com/bytom/protocol/bc/types"
+       "github.com/bytom/protocol/state"
+       "github.com/bytom/protocol/validation"
+       "github.com/bytom/protocol/vm/vmutil"
+)
+
+const logModule = "mining"
+
+// createCoinbaseTx returns a coinbase transaction paying an appropriate subsidy
+// based on the passed block height to the provided address.  When the address
+// is nil, the coinbase transaction will instead be redeemable by anyone.
+func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeight uint64) (tx *types.Tx, err error) {
+       amount += consensus.BlockSubsidy(blockHeight)
+       arbitrary := append([]byte{0x00}, []byte(strconv.FormatUint(blockHeight, 10))...)
+
+       var script []byte
+       if accountManager == nil {
+               script, err = vmutil.DefaultCoinbaseProgram()
+       } else {
+               script, err = accountManager.GetCoinbaseControlProgram()
+               arbitrary = append(arbitrary, accountManager.GetCoinbaseArbitrary()...)
+       }
+       if err != nil {
+               return nil, err
+       }
+
+       if len(arbitrary) > consensus.CoinbaseArbitrarySizeLimit {
+               return nil, validation.ErrCoinbaseArbitraryOversize
+       }
+
+       builder := txbuilder.NewBuilder(time.Now())
+       if err = builder.AddInput(types.NewCoinbaseInput(arbitrary), &txbuilder.SigningInstruction{}); err != nil {
+               return nil, err
+       }
+       if err = builder.AddOutput(types.NewTxOutput(*consensus.BTMAssetID, amount, script)); err != nil {
+               return nil, err
+       }
+       _, txData, err := builder.Build()
+       if err != nil {
+               return nil, err
+       }
+
+       byteData, err := txData.MarshalText()
+       if err != nil {
+               return nil, err
+       }
+       txData.SerializedSize = uint64(len(byteData))
+
+       tx = &types.Tx{
+               TxData: *txData,
+               Tx:     types.MapTx(txData),
+       }
+       return tx, nil
+}
+
+// NewBlockTemplate returns a new block template that is ready to be solved
+func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager *account.Manager) (b *types.Block, err error) {
+       view := state.NewUtxoViewpoint()
+       txStatus := bc.NewTransactionStatus()
+       if err := txStatus.SetStatus(0, false); err != nil {
+               return nil, err
+       }
+       txEntries := []*bc.Tx{nil}
+       gasUsed := uint64(0)
+       txFee := uint64(0)
+
+       // get preblock info for generate next block
+       preBlockHeader := c.BestBlockHeader()
+       preBlockHash := preBlockHeader.Hash()
+       nextBlockHeight := preBlockHeader.Height + 1
+       nextBits, err := c.CalcNextBits(&preBlockHash)
+       if err != nil {
+               return nil, err
+       }
+
+       b = &types.Block{
+               BlockHeader: types.BlockHeader{
+                       Version:           1,
+                       Height:            nextBlockHeight,
+                       PreviousBlockHash: preBlockHash,
+                       Timestamp:         uint64(time.Now().Unix()),
+                       BlockCommitment:   types.BlockCommitment{},
+                       Bits:              nextBits,
+               },
+       }
+       bcBlock := &bc.Block{BlockHeader: &bc.BlockHeader{Height: nextBlockHeight}}
+       b.Transactions = []*types.Tx{nil}
+
+       txs := txPool.GetTransactions()
+       sort.Sort(byTime(txs))
+       for _, txDesc := range txs {
+               tx := txDesc.Tx.Tx
+               gasOnlyTx := false
+
+               if err := c.GetTransactionsUtxo(view, []*bc.Tx{tx}); err != nil {
+                       blkGenSkipTxForErr(txPool, &tx.ID, err)
+                       continue
+               }
+
+               gasStatus, err := validation.ValidateTx(tx, bcBlock)
+               if err != nil {
+                       if !gasStatus.GasValid {
+                               blkGenSkipTxForErr(txPool, &tx.ID, err)
+                               continue
+                       }
+                       gasOnlyTx = true
+               }
+
+               if gasUsed+uint64(gasStatus.GasUsed) > consensus.MaxBlockGas {
+                       break
+               }
+
+               if err := view.ApplyTransaction(bcBlock, tx, gasOnlyTx); err != nil {
+                       blkGenSkipTxForErr(txPool, &tx.ID, err)
+                       continue
+               }
+
+               if err := txStatus.SetStatus(len(b.Transactions), gasOnlyTx); err != nil {
+                       return nil, err
+               }
+
+               b.Transactions = append(b.Transactions, txDesc.Tx)
+               txEntries = append(txEntries, tx)
+               gasUsed += uint64(gasStatus.GasUsed)
+               txFee += txDesc.Fee
+
+               if gasUsed == consensus.MaxBlockGas {
+                       break
+               }
+       }
+
+       // creater coinbase transaction
+       b.Transactions[0], err = createCoinbaseTx(accountManager, txFee, nextBlockHeight)
+       if err != nil {
+               return nil, errors.Wrap(err, "fail on createCoinbaseTx")
+       }
+       txEntries[0] = b.Transactions[0].Tx
+
+       b.BlockHeader.BlockCommitment.TransactionsMerkleRoot, err = types.TxMerkleRoot(txEntries)
+       if err != nil {
+               return nil, err
+       }
+
+       b.BlockHeader.BlockCommitment.TransactionStatusHash, err = types.TxStatusMerkleRoot(txStatus.VerifyStatus)
+       return b, err
+}
+
+func blkGenSkipTxForErr(txPool *protocol.TxPool, txHash *bc.Hash, err error) {
+       log.WithFields(log.Fields{"module": logModule, "error": err}).Error("mining block generation: skip tx due to")
+       txPool.RemoveTransaction(txHash)
+}