123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- // Copyright (c) 2009-2010 Satoshi Nakamoto
- // Copyright (c) 2009-2016 The Bitcoin Core developers
- // Distributed under the MIT software license, see the accompanying
- // file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
- #ifndef BITCOIN_MINER_H
- #define BITCOIN_MINER_H
-
- #include "primitives/block.h"
- #include "txmempool.h"
-
- #include <stdint.h>
- #include <memory>
- #include "boost/multi_index_container.hpp"
- #include "boost/multi_index/ordered_index.hpp"
-
- class CBlockIndex;
- class CChainParams;
- class CScript;
-
- namespace Consensus { struct Params; };
-
- static const bool DEFAULT_PRINTPRIORITY = false;
-
- struct CBlockTemplate
- {
- CBlock block;
- std::vector<CAmount> vTxFees;
- std::vector<int64_t> vTxSigOpsCost;
- std::vector<unsigned char> vchCoinbaseCommitment;
- };
-
- // Container for tracking updates to ancestor feerate as we include (parent)
- // transactions in a block
- struct CTxMemPoolModifiedEntry {
- CTxMemPoolModifiedEntry(CTxMemPool::txiter entry)
- {
- iter = entry;
- nSizeWithAncestors = entry->GetSizeWithAncestors();
- nModFeesWithAncestors = entry->GetModFeesWithAncestors();
- nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();
- }
-
- CTxMemPool::txiter iter;
- uint64_t nSizeWithAncestors;
- CAmount nModFeesWithAncestors;
- int64_t nSigOpCostWithAncestors;
- };
-
- /** Comparator for CTxMemPool::txiter objects.
- * It simply compares the internal memory address of the CTxMemPoolEntry object
- * pointed to. This means it has no meaning, and is only useful for using them
- * as key in other indexes.
- */
- struct CompareCTxMemPoolIter {
- bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
- {
- return &(*a) < &(*b);
- }
- };
-
- struct modifiedentry_iter {
- typedef CTxMemPool::txiter result_type;
- result_type operator() (const CTxMemPoolModifiedEntry &entry) const
- {
- return entry.iter;
- }
- };
-
- // This matches the calculation in CompareTxMemPoolEntryByAncestorFee,
- // except operating on CTxMemPoolModifiedEntry.
- // TODO: refactor to avoid duplication of this logic.
- struct CompareModifiedEntry {
- bool operator()(const CTxMemPoolModifiedEntry &a, const CTxMemPoolModifiedEntry &b)
- {
- double f1 = (double)a.nModFeesWithAncestors * b.nSizeWithAncestors;
- double f2 = (double)b.nModFeesWithAncestors * a.nSizeWithAncestors;
- if (f1 == f2) {
- return CTxMemPool::CompareIteratorByHash()(a.iter, b.iter);
- }
- return f1 > f2;
- }
- };
-
- // A comparator that sorts transactions based on number of ancestors.
- // This is sufficient to sort an ancestor package in an order that is valid
- // to appear in a block.
- struct CompareTxIterByAncestorCount {
- bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b)
- {
- if (a->GetCountWithAncestors() != b->GetCountWithAncestors())
- return a->GetCountWithAncestors() < b->GetCountWithAncestors();
- return CTxMemPool::CompareIteratorByHash()(a, b);
- }
- };
-
- typedef boost::multi_index_container<
- CTxMemPoolModifiedEntry,
- boost::multi_index::indexed_by<
- boost::multi_index::ordered_unique<
- modifiedentry_iter,
- CompareCTxMemPoolIter
- >,
- // sorted by modified ancestor fee rate
- boost::multi_index::ordered_non_unique<
- // Reuse same tag from CTxMemPool's similar index
- boost::multi_index::tag<ancestor_score>,
- boost::multi_index::identity<CTxMemPoolModifiedEntry>,
- CompareModifiedEntry
- >
- >
- > indexed_modified_transaction_set;
-
- typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter;
- typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter;
-
- struct update_for_parent_inclusion
- {
- update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {}
-
- void operator() (CTxMemPoolModifiedEntry &e)
- {
- e.nModFeesWithAncestors -= iter->GetFee();
- e.nSizeWithAncestors -= iter->GetTxSize();
- e.nSigOpCostWithAncestors -= iter->GetSigOpCost();
- }
-
- CTxMemPool::txiter iter;
- };
-
- /** Generate a new block, without valid proof-of-work */
- class BlockAssembler
- {
- private:
- // The constructed block template
- std::unique_ptr<CBlockTemplate> pblocktemplate;
- // A convenience pointer that always refers to the CBlock in pblocktemplate
- CBlock* pblock;
-
- // Configuration parameters for the block size
- bool fIncludeWitness;
- unsigned int nBlockMaxWeight;
- CFeeRate blockMinFeeRate;
-
- // Information on the current status of the block
- uint64_t nBlockWeight;
- uint64_t nBlockTx;
- uint64_t nBlockSigOpsCost;
- CAmount nFees;
- CTxMemPool::setEntries inBlock;
-
- // Chain context for the block
- int nHeight;
- int64_t nLockTimeCutoff;
- const CChainParams& chainparams;
-
- public:
- struct Options {
- Options();
- size_t nBlockMaxWeight;
- size_t nBlockMaxSize;
- CFeeRate blockMinFeeRate;
- };
-
- BlockAssembler(const CChainParams& params);
- BlockAssembler(const CChainParams& params, const Options& options);
-
- /** Construct a new block template with coinbase to scriptPubKeyIn */
- std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx=true);
-
- private:
- // utility functions
- /** Clear the block's state and prepare for assembling a new block */
- void resetBlock();
- /** Add a tx to the block */
- void AddToBlock(CTxMemPool::txiter iter);
-
- // Methods for how to add transactions to a block.
- /** Add transactions based on feerate including unconfirmed ancestors
- * Increments nPackagesSelected / nDescendantsUpdated with corresponding
- * statistics from the package selection (for logging statistics). */
- void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated);
-
- // helper functions for addPackageTxs()
- /** Remove confirmed (inBlock) entries from given set */
- void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
- /** Test if a new package would "fit" in the block */
- bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost);
- /** Perform checks on each transaction in a package:
- * locktime, premature-witness, serialized size (if necessary)
- * These checks should always succeed, and they're here
- * only as an extra check in case of suboptimal node configuration */
- bool TestPackageTransactions(const CTxMemPool::setEntries& package);
- /** Return true if given transaction from mapTx has already been evaluated,
- * or if the transaction's cached data in mapTx is incorrect. */
- bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx);
- /** Sort the package in an order that is valid to appear in a block */
- void SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector<CTxMemPool::txiter>& sortedEntries);
- /** Add descendants of given transactions to mapModifiedTx with ancestor
- * state updated assuming given transactions are inBlock. Returns number
- * of updated descendants. */
- int UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx);
- };
-
- /** Modify the extranonce in a block */
- void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
- int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
-
- #endif // BITCOIN_MINER_H
|