diff options
author | glozow <gzhao408@berkeley.edu> | 2021-05-10 09:30:14 -0700 |
---|---|---|
committer | glozow <gzhao408@berkeley.edu> | 2021-05-20 21:34:31 +0100 |
commit | 897e348f5987eadd8559981a973c045c471b3ad8 (patch) | |
tree | 945a1f4e40e229d19b74db6029441ad8a055fa1b /src | |
parent | 42cf8b25df07c45562b7210e0e15c3fd5edb2c11 (diff) |
[coins/mempool] extend CCoinsViewMemPool to track temporary coins
Diffstat (limited to 'src')
-rw-r--r-- | src/txmempool.cpp | 14 | ||||
-rw-r--r-- | src/txmempool.h | 10 |
2 files changed, 23 insertions, 1 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 8bd6e2a6a6..4413da7ea7 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -922,6 +922,13 @@ bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const { + // Check to see if the inputs are made available by another tx in the package. + // These Coins would not be available in the underlying CoinsView. + if (auto it = m_temp_added.find(outpoint); it != m_temp_added.end()) { + coin = it->second; + return true; + } + // If an entry in the mempool exists, always return that one, as it's guaranteed to never // conflict with the underlying cache, and it cannot have pruned entries (as it contains full) // transactions. First checking the underlying cache risks returning a pruned entry instead. @@ -937,6 +944,13 @@ bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const { return base->GetCoin(outpoint, coin); } +void CCoinsViewMemPool::PackageAddTransaction(const CTransactionRef& tx) +{ + for (unsigned int n = 0; n < tx->vout.size(); ++n) { + m_temp_added.emplace(COutPoint(tx->GetHash(), n), Coin(tx->vout[n], MEMPOOL_HEIGHT, false)); + } +} + size_t CTxMemPool::DynamicMemoryUsage() const { LOCK(cs); // Estimate the overhead of mapTx to be 15 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. diff --git a/src/txmempool.h b/src/txmempool.h index c3a9bd851d..ca856a5abc 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -852,7 +852,8 @@ public: * CCoinsView that brings transactions from a mempool into view. * It does not check for spendings by memory pool transactions. * Instead, it provides access to all Coins which are either unspent in the - * base CCoinsView, or are outputs from any mempool transaction! + * base CCoinsView, are outputs from any mempool transaction, or are + * tracked temporarily to allow transaction dependencies in package validation. * This allows transaction replacement to work as expected, as you want to * have all inputs "available" to check signatures, and any cycles in the * dependency graph are checked directly in AcceptToMemoryPool. @@ -862,12 +863,19 @@ public: */ class CCoinsViewMemPool : public CCoinsViewBacked { + /** + * Coins made available by transactions being validated. Tracking these allows for package + * validation, since we can access transaction outputs without submitting them to mempool. + */ + std::unordered_map<COutPoint, Coin, SaltedOutpointHasher> m_temp_added; protected: const CTxMemPool& mempool; public: CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn); bool GetCoin(const COutPoint &outpoint, Coin &coin) const override; + /** Add the coins created by this transaction. */ + void PackageAddTransaction(const CTransactionRef& tx); }; /** |