Skip to content

Commit 897e348

Browse files
committed
[coins/mempool] extend CCoinsViewMemPool to track temporary coins
1 parent 42cf8b2 commit 897e348

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/txmempool.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,13 @@ bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
922922
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
923923

924924
bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
925+
// Check to see if the inputs are made available by another tx in the package.
926+
// These Coins would not be available in the underlying CoinsView.
927+
if (auto it = m_temp_added.find(outpoint); it != m_temp_added.end()) {
928+
coin = it->second;
929+
return true;
930+
}
931+
925932
// If an entry in the mempool exists, always return that one, as it's guaranteed to never
926933
// conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
927934
// 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 {
937944
return base->GetCoin(outpoint, coin);
938945
}
939946

947+
void CCoinsViewMemPool::PackageAddTransaction(const CTransactionRef& tx)
948+
{
949+
for (unsigned int n = 0; n < tx->vout.size(); ++n) {
950+
m_temp_added.emplace(COutPoint(tx->GetHash(), n), Coin(tx->vout[n], MEMPOOL_HEIGHT, false));
951+
}
952+
}
953+
940954
size_t CTxMemPool::DynamicMemoryUsage() const {
941955
LOCK(cs);
942956
// Estimate the overhead of mapTx to be 15 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented.

src/txmempool.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,8 @@ class CTxMemPool
852852
* CCoinsView that brings transactions from a mempool into view.
853853
* It does not check for spendings by memory pool transactions.
854854
* Instead, it provides access to all Coins which are either unspent in the
855-
* base CCoinsView, or are outputs from any mempool transaction!
855+
* base CCoinsView, are outputs from any mempool transaction, or are
856+
* tracked temporarily to allow transaction dependencies in package validation.
856857
* This allows transaction replacement to work as expected, as you want to
857858
* have all inputs "available" to check signatures, and any cycles in the
858859
* dependency graph are checked directly in AcceptToMemoryPool.
@@ -862,12 +863,19 @@ class CTxMemPool
862863
*/
863864
class CCoinsViewMemPool : public CCoinsViewBacked
864865
{
866+
/**
867+
* Coins made available by transactions being validated. Tracking these allows for package
868+
* validation, since we can access transaction outputs without submitting them to mempool.
869+
*/
870+
std::unordered_map<COutPoint, Coin, SaltedOutpointHasher> m_temp_added;
865871
protected:
866872
const CTxMemPool& mempool;
867873

868874
public:
869875
CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn);
870876
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
877+
/** Add the coins created by this transaction. */
878+
void PackageAddTransaction(const CTransactionRef& tx);
871879
};
872880

873881
/**

0 commit comments

Comments
 (0)