Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2021 The Bitcoin Core developers 3 : // Copyright (c) 2021 The PIVX Core developers 4 : // Distributed under the MIT software license, see the accompanying 5 : // file COPYING or https://www.opensource.org/licenses/mit-license.php. 6 : 7 : #ifndef PIVX_BLOCKASSEMBLER_H 8 : #define PIVX_BLOCKASSEMBLER_H 9 : 10 : #include "primitives/block.h" 11 : #include "txmempool.h" 12 : 13 : #include <stdint.h> 14 : #include <memory> 15 : #include "boost/multi_index_container.hpp" 16 : #include "boost/multi_index/ordered_index.hpp" 17 : 18 : class CBlockIndex; 19 : class CChainParams; 20 : class CReserveKey; 21 : class CStakeableOutput; 22 : class CScript; 23 : class CWallet; 24 : 25 : namespace Consensus { struct Params; }; 26 : 27 15218 : struct CBlockTemplate 28 : { 29 : CBlock block; 30 : std::vector<CAmount> vTxFees; 31 : std::vector<int64_t> vTxSigOps; 32 : }; 33 : 34 : // Container for tracking updates to ancestor feerate as we include (parent) 35 : // transactions in a block 36 : struct CTxMemPoolModifiedEntry { 37 140811 : explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) 38 140811 : { 39 140811 : iter = entry; 40 140811 : nSizeWithAncestors = entry->GetSizeWithAncestors(); 41 140811 : nModFeesWithAncestors = entry->GetModFeesWithAncestors(); 42 140811 : nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors(); 43 : } 44 : 45 : CTxMemPool::txiter iter; 46 : uint64_t nSizeWithAncestors; 47 : CAmount nModFeesWithAncestors; 48 : unsigned int nSigOpCountWithAncestors; 49 : }; 50 : 51 : /** Comparator for CTxMemPool::txiter objects. 52 : * It simply compares the internal memory address of the CTxMemPoolEntry object 53 : * pointed to. This means it has no meaning, and is only useful for using them 54 : * as key in other indexes. 55 : */ 56 : struct CompareCTxMemPoolIter { 57 14737890 : bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const 58 : { 59 943231 : return &(*a) < &(*b); 60 : } 61 : }; 62 : 63 : struct modifiedentry_iter { 64 : typedef CTxMemPool::txiter result_type; 65 14766450 : result_type operator() (const CTxMemPoolModifiedEntry &entry) const 66 : { 67 13776120 : return entry.iter; 68 : } 69 : }; 70 : 71 : // This matches the calculation in CompareTxMemPoolEntryByAncestorFee, 72 : // except operating on CTxMemPoolModifiedEntry. 73 : // TODO: refactor to avoid duplication of this logic. 74 : struct CompareModifiedEntry { 75 2403235 : bool operator()(const CTxMemPoolModifiedEntry &a, const CTxMemPoolModifiedEntry &b) const 76 : { 77 2403235 : double f1 = (double)a.nModFeesWithAncestors * b.nSizeWithAncestors; 78 2403235 : double f2 = (double)b.nModFeesWithAncestors * a.nSizeWithAncestors; 79 2403235 : if (f1 == f2) { 80 2173966 : return CTxMemPool::CompareIteratorByHash()(a.iter, b.iter); 81 : } 82 229273 : return f1 > f2; 83 : } 84 : }; 85 : 86 : // A comparator that sorts transactions based on number of ancestors. 87 : // This is sufficient to sort an ancestor package in an order that is valid 88 : // to appear in a block. 89 : struct CompareTxIterByAncestorCount { 90 65166 : bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) const 91 : { 92 65166 : if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) 93 62784 : return a->GetCountWithAncestors() < b->GetCountWithAncestors(); 94 2382 : return CTxMemPool::CompareIteratorByHash()(a, b); 95 : } 96 : }; 97 : 98 : typedef boost::multi_index_container< 99 : CTxMemPoolModifiedEntry, 100 : boost::multi_index::indexed_by< 101 : boost::multi_index::ordered_unique< 102 : modifiedentry_iter, 103 : CompareCTxMemPoolIter 104 : >, 105 : // sorted by modified ancestor fee rate 106 : boost::multi_index::ordered_non_unique< 107 : // Reuse same tag from CTxMemPool's similar index 108 : boost::multi_index::tag<ancestor_score>, 109 : boost::multi_index::identity<CTxMemPoolModifiedEntry>, 110 : CompareModifiedEntry 111 : > 112 : > 113 : > indexed_modified_transaction_set; 114 : 115 : typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter; 116 : typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter; 117 : 118 : struct update_for_parent_inclusion 119 : { 120 946356 : explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} 121 : 122 946356 : void operator() (CTxMemPoolModifiedEntry &e) 123 : { 124 946356 : e.nModFeesWithAncestors -= iter->GetFee(); 125 946356 : e.nSizeWithAncestors -= iter->GetTxSize(); 126 946356 : e.nSigOpCountWithAncestors -= iter->GetSigOpCount(); 127 : } 128 : 129 : CTxMemPool::txiter iter; 130 : }; 131 : 132 : 133 : /** Generate a new block */ 134 15218 : class BlockAssembler 135 : { 136 : private: 137 : // The constructed block template 138 : std::unique_ptr<CBlockTemplate> pblocktemplate; 139 : // A convenience pointer that always refers to the CBlock in pblocktemplate 140 : CBlock* pblock{nullptr}; 141 : 142 : // Configuration parameters for the block max size 143 : unsigned int nBlockMaxSize{0}; 144 : 145 : // Information on the current status of the block 146 : uint64_t nBlockSize{0}; 147 : uint64_t nBlockTx{0}; 148 : unsigned int nBlockSigOps{0}; 149 : CAmount nFees{0}; 150 : CTxMemPool::setEntries inBlock; 151 : 152 : // Chain context for the block 153 : int nHeight{0}; 154 : const CChainParams& chainparams; 155 : 156 : // Keep track of block space used for shield txes 157 : unsigned int nSizeShielded{0}; 158 : 159 : // Whether should print priority by default or not 160 : const bool defaultPrintPriority{false}; 161 : 162 : public: 163 : BlockAssembler(const CChainParams& chainparams, const bool defaultPrintPriority); 164 : /** Construct a new block template with coinbase to scriptPubKeyIn */ 165 : std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, 166 : CWallet* pwallet = nullptr, 167 : bool fProofOfStake = false, 168 : std::vector<CStakeableOutput>* availableCoins = nullptr, 169 : bool fNoMempoolTx = false, 170 : bool fTestValidity = true, 171 : CBlockIndex* prevBlock = nullptr, 172 : bool stopPoSOnNewBlock = true, 173 : bool fIncludeQfc = true); 174 : 175 : private: 176 : // utility functions 177 : /** Clear the block's state and prepare for assembling a new block */ 178 : void resetBlock(); 179 : /** Add a tx to the block */ 180 : void AddToBlock(CTxMemPool::txiter iter); 181 : 182 : // Methods for how to add transactions to a block. 183 : /** Add transactions based on feerate including unconfirmed ancestors */ 184 : void addPackageTxs(); 185 : /** Add the tip updated incremental merkle tree to the header */ 186 : void appendSaplingTreeRoot(); 187 : 188 : // helper functions for addPackageTxs() 189 : /** Remove confirmed (inBlock) entries from given set */ 190 : void onlyUnconfirmed(CTxMemPool::setEntries& testSet); 191 : /** Test if a new package would "fit" in the block */ 192 : bool TestPackage(uint64_t packageSize, unsigned int packageSigOps); 193 : /** Test if a set of transactions are all final */ 194 : bool TestPackageFinality(const CTxMemPool::setEntries& package); 195 : /** Return true if given transaction from mapTx has already been evaluated, 196 : * or if the transaction's cached data in mapTx is incorrect. */ 197 : bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx); 198 : /** Sort the package in an order that is valid to appear in a block */ 199 : void SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector<CTxMemPool::txiter>& sortedEntries); 200 : /** Add descendants of given transactions to mapModifiedTx with ancestor 201 : * state updated assuming given transactions are inBlock. */ 202 : void UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx); 203 : 204 : }; 205 : 206 : /** Modify the nonce/extranonce in a block */ 207 : bool SolveBlock(std::shared_ptr<CBlock>& pblock, int nHeight); 208 : void IncrementExtraNonce(std::shared_ptr<CBlock>& pblock, int nHeight, unsigned int& nExtraNonce); 209 : int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); 210 : int32_t ComputeBlockVersion(const Consensus::Params& consensusParams, int nHeight); 211 : 212 : // Visible for testing purposes only 213 : bool CreateCoinbaseTx(CBlock* pblock, const CScript& scriptPubKeyIn, CBlockIndex* pindexPrev); 214 : CMutableTransaction CreateCoinbaseTx(const CScript& scriptPubKeyIn, CBlockIndex* pindexPrev); 215 : 216 : // Visible for testing purposes only 217 : uint256 CalculateSaplingTreeRoot(CBlock* pblock, int nHeight, const CChainParams& chainparams); 218 : 219 : #endif // PIVX_BLOCKASSEMBLER_H