git / moonbite-core / src/miner.h · raw

// Copyright (c) 2009-2010 Satoshi Nakamoto// Copyright (c) 2009-2020 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 <optional.h>#include <primitives/block.h>#include <txmempool.h>#include <validation.h>#include <mweb/mweb_miner.h>#include <memory>#include <stdint.h>#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 blockstruct CTxMemPoolModifiedEntry {    explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry)    {        iter = entry;        nSizeWithAncestors = entry->GetSizeWithAncestors();        nModFeesWithAncestors = entry->GetModFeesWithAncestors();        nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();        nMWEBWeightWithAncestors = entry->GetMWEBWeightWithAncestors();    }    int64_t GetModifiedFee() const { return iter->GetModifiedFee(); }    uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }    CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }    int64_t GetMWEBWeightWithAncestors() const { return nMWEBWeightWithAncestors; }    size_t GetTxSize() const { return iter->GetTxSize(); }    uint64_t GetMWEBWeight() const { return iter->GetMWEBWeight(); }    const CTransaction& GetTx() const { return iter->GetTx(); }    CTxMemPool::txiter iter;    uint64_t nSizeWithAncestors;    CAmount nModFeesWithAncestors;    int64_t nSigOpCostWithAncestors;    int64_t nMWEBWeightWithAncestors;};/** 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;    }};// 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) const    {        if (a->GetCountWithAncestors() != b->GetCountWithAncestors())            return a->GetCountWithAncestors() < b->GetCountWithAncestors();        return 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>,            CompareTxMemPoolEntryByAncestorFee        >    >> 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{    explicit 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();        e.nMWEBWeightWithAncestors -= iter->GetMWEBWeight();    }    CTxMemPool::txiter iter;};/** Generate a new block, without valid proof-of-work */class BlockAssembler{private:    // The constructed block template    std::unique_ptr<CBlockTemplate> pblocktemplate;    // MWEB Attributes    MWEB::Miner mweb_miner;    // Configuration parameters for the block size    bool fIncludeWitness;    bool fIncludeMWEB;    unsigned int nBlockMaxWeight;    CFeeRate blockMinFeeRate;    // Information on the current status of the block    uint64_t nBlockWeight;    uint64_t nBlockTx;    uint64_t nBlockSigOpsCost;    uint64_t nBlockMWEBWeight;    CAmount nFees;    CTxMemPool::setEntries inBlock;    // Chain context for the block    int nHeight;    int64_t nLockTimeCutoff;    const CChainParams& chainparams;    const CTxMemPool& m_mempool;public:    struct Options {        Options();        size_t nBlockMaxWeight;        CFeeRate blockMinFeeRate;    };    explicit BlockAssembler(const CTxMemPool& mempool, const CChainParams& params);    explicit BlockAssembler(const CTxMemPool& mempool, const CChainParams& params, const Options& options);    /** Construct a new block template with coinbase to scriptPubKeyIn */    std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);    static Optional<int64_t> m_last_block_num_txs;    static Optional<int64_t> m_last_block_weight;    static Optional<int64_t> m_last_block_mweb_weight;private:    // utility functions    /** Clear the block's state and prepare for assembling a new block */    void resetBlock();    /** Add a tx to the block */    bool 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) EXCLUSIVE_LOCKS_REQUIRED(m_mempool.cs);    // 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, int64_t packageMWEBWeight) const;    /** 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, const CTxMemPool::setEntries& failedTxs);    /** 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) EXCLUSIVE_LOCKS_REQUIRED(m_mempool.cs);    /** Sort the package in an order that is valid to appear in a block */    void SortForBlock(const CTxMemPool::setEntries& package, 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) EXCLUSIVE_LOCKS_REQUIRED(m_mempool.cs);};/** 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);/** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */void RegenerateCommitments(CBlock& block);#endif // BITCOIN_MINER_H