X-Git-Url: https://repo.jachan.dev/VerusCoin.git/blobdiff_plain/431604c7d9fa1578886409ea985de99bee25cb37..837aaaecb605847ba895b4ff8a2c81b3e0c9cbe4:/src/txmempool.h diff --git a/src/txmempool.h b/src/txmempool.h index a6901fde6..e9bb8f359 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -8,11 +8,17 @@ #include +#include "addressindex.h" +#include "spentindex.h" #include "amount.h" #include "coins.h" #include "primitives/transaction.h" #include "sync.h" +#undef foreach +#include "boost/multi_index_container.hpp" +#include "boost/multi_index/ordered_index.hpp" + class CAutoFile; inline double AllowFreeThreshold() @@ -40,24 +46,55 @@ private: CAmount nFee; //! Cached to avoid expensive parent-transaction lookups size_t nTxSize; //! ... and avoid recomputing tx size size_t nModSize; //! ... and modified size for priority + size_t nUsageSize; //! ... and total memory usage + CFeeRate feeRate; //! ... and fee per kB int64_t nTime; //! Local time when entering the mempool double dPriority; //! Priority when entering the mempool unsigned int nHeight; //! Chain height when entering the mempool bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool + bool spendsCoinbase; //! keep track of transactions that spend a coinbase + uint32_t nBranchId; //! Branch ID this transaction is known to commit to, cached for efficiency public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, - int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false); + int64_t _nTime, double _dPriority, unsigned int _nHeight, + bool poolHasNoInputsOf, bool spendsCoinbase, uint32_t nBranchId); CTxMemPoolEntry(); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return this->tx; } double GetPriority(unsigned int currentHeight) const; CAmount GetFee() const { return nFee; } + CFeeRate GetFeeRate() const { return feeRate; } size_t GetTxSize() const { return nTxSize; } int64_t GetTime() const { return nTime; } unsigned int GetHeight() const { return nHeight; } bool WasClearAtEntry() const { return hadNoDependencies; } + size_t DynamicMemoryUsage() const { return nUsageSize; } + + bool GetSpendsCoinbase() const { return spendsCoinbase; } + uint32_t GetValidatedBranchId() const { return nBranchId; } +}; + +// extracts a TxMemPoolEntry's transaction hash +struct mempoolentry_txid +{ + typedef uint256 result_type; + result_type operator() (const CTxMemPoolEntry &entry) const + { + return entry.GetTx().GetHash(); + } +}; + +class CompareTxMemPoolEntryByFee +{ +public: + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + { + if (a.GetFeeRate() == b.GetFeeRate()) + return a.GetTime() < b.GetTime(); + return a.GetFeeRate() > b.GetFeeRate(); + } }; class CBlockPolicyEstimator; @@ -73,6 +110,7 @@ public: CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; } void SetNull() { ptx = NULL; n = (uint32_t) -1; } bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); } + size_t DynamicMemoryUsage() const { return 0; } }; /** @@ -88,15 +126,44 @@ public: class CTxMemPool { private: - bool fSanityCheck; //! Normally false, true if -checkmempool or -regtest + uint32_t nCheckFrequency; //! Value n means that n times in 2^32 we check. unsigned int nTransactionsUpdated; CBlockPolicyEstimator* minerPolicyEstimator; - uint64_t totalTxSize; //! sum of all mempool tx' byte sizes + uint64_t totalTxSize = 0; //! sum of all mempool tx' byte sizes + uint64_t cachedInnerUsage; //! sum of dynamic memory usage of all the map elements (NOT the maps themselves) public: + typedef boost::multi_index_container< + CTxMemPoolEntry, + boost::multi_index::indexed_by< + // sorted by txid + boost::multi_index::ordered_unique, + // sorted by fee rate + boost::multi_index::ordered_non_unique< + boost::multi_index::identity, + CompareTxMemPoolEntryByFee + > + > + > indexed_transaction_set; + mutable CCriticalSection cs; - std::map mapTx; + indexed_transaction_set mapTx; + +private: + typedef std::map addressDeltaMap; + addressDeltaMap mapAddress; + + typedef std::map > addressDeltaMapInserted; + addressDeltaMapInserted mapAddressInserted; + + typedef std::map mapSpentIndex; + mapSpentIndex mapSpent; + + typedef std::map > mapSpentIndexInserted; + mapSpentIndexInserted mapSpentInserted; + +public: std::map mapNextTx; std::map mapNullifiers; std::map > mapDeltas; @@ -111,15 +178,25 @@ public: * check does nothing. */ void check(const CCoinsViewCache *pcoins) const; - void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; } + void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = dFrequency * 4294967296.0; } bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true); + void addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); + bool getAddressIndex(std::vector > &addresses, + std::vector > &results); + bool removeAddressIndex(const uint256 txhash); + + void addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); + bool getSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); + bool removeSpentIndex(const uint256 txhash); void remove(const CTransaction &tx, std::list& removed, bool fRecursive = false); void removeWithAnchor(const uint256 &invalidRoot); - void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight); + void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeConflicts(const CTransaction &tx, std::list& removed); + void removeExpired(unsigned int nBlockHeight); void removeForBlock(const std::vector& vtx, unsigned int nBlockHeight, std::list& conflicts, bool fCurrentEstimate = true); + void removeWithoutBranchId(uint32_t nMemPoolBranchId); void clear(); void queryHashes(std::vector& vtxid); void pruneSpent(const uint256& hash, CCoins &coins); @@ -141,6 +218,7 @@ public: LOCK(cs); return mapTx.size(); } + uint64_t GetTotalTxSize() { LOCK(cs); @@ -164,6 +242,8 @@ public: /** Write/Read estimates to disk */ bool WriteFeeEstimates(CAutoFile& fileout) const; bool ReadFeeEstimates(CAutoFile& filein); + + size_t DynamicMemoryUsage() const; }; /**