mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-18 22:35:39 +01:00
Merge #10195: Switch chainstate db and cache to per-txout model
589827975scripted-diff: various renames for per-utxo consistency (Pieter Wuille)a5e02bc7fIncrease travis unit test timeout (Pieter Wuille)73de2c1ffRename CCoinsCacheEntry::coins to coin (Pieter Wuille)119e552f7Merge CCoinsViewCache's GetOutputFor and AccessCoin (Pieter Wuille)580b02309[MOVEONLY] Move old CCoins class to txdb.cpp (Pieter Wuille)8b25d2c0cUpgrade from per-tx database to per-txout (Pieter Wuille)b2af357f3Reduce reserved memory space for flushing (Pieter Wuille)41aa5b79aPack Coin more tightly (Pieter Wuille)97072d668Remove unused CCoins methods (Pieter Wuille)ce23efaa5Extend coins_tests (Pieter Wuille)508307968Switch CCoinsView and chainstate db from per-txid to per-txout (Pieter Wuille)4ec0d9e79Refactor GetUTXOStats in preparation for per-COutPoint iteration (Pieter Wuille)13870b56fReplace CCoins-based CTxMemPool::pruneSpent with isSpent (Pieter Wuille)05293f3cbRemove ModifyCoins/ModifyNewCoins (Pieter Wuille)961e48397Switch tests from ModifyCoins to AddCoin/SpendCoin (Pieter Wuille)8b3868c1bSwitch CScriptCheck to use Coin instead of CCoins (Pieter Wuille)c87b957a3Only pass things committed to by tx's witness hash to CScriptCheck (Matt Corallo)f68cdfe92Switch from per-tx to per-txout CCoinsViewCache methods in some places (Pieter Wuille)000391132Introduce new per-txout CCoinsViewCache functions (Pieter Wuille)bd83111a0Optimization: Coin&& to ApplyTxInUndo (Pieter Wuille)cb2c7fdacReplace CTxInUndo with Coin (Pieter Wuille)422634e2fIntroduce Coin, a single unspent output (Pieter Wuille)7d991b55dStore/allow tx metadata in all undo records (Pieter Wuille)c3aa0c119Report on-disk size in gettxoutsetinfo (Pieter Wuille)d34242430Remove/ignore tx version in utxo and undo (Pieter Wuille)7e0032290Add specialization of SipHash for 256 + 32 bit data (Pieter Wuille)e484652fcIntroduce CHashVerifier to hash read data (Pieter Wuille)f54580e7eerror() in disconnect for disk corruption, not inconsistency (Pieter Wuille)e66dbde6dAdd SizeEstimate to CDBBatch (Pieter Wuille) Tree-SHA512: ce1fb1e40c77d38915cd02189fab7a8b125c7f44d425c85579d872c3bede3a437760997907c99d7b3017ced1c2de54b2ac7223d99d83a6658fe5ef61edef1de3
This commit is contained in:
@@ -343,17 +343,10 @@ CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator) :
|
||||
nCheckFrequency = 0;
|
||||
}
|
||||
|
||||
void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins)
|
||||
bool CTxMemPool::isSpent(const COutPoint& outpoint)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
auto it = mapNextTx.lower_bound(COutPoint(hashTx, 0));
|
||||
|
||||
// iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx
|
||||
while (it != mapNextTx.end() && it->first->hash == hashTx) {
|
||||
coins.Spend(it->first->n); // and remove those outputs from coins
|
||||
it++;
|
||||
}
|
||||
return mapNextTx.count(outpoint);
|
||||
}
|
||||
|
||||
unsigned int CTxMemPool::GetTransactionsUpdated() const
|
||||
@@ -531,9 +524,9 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem
|
||||
indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
|
||||
if (it2 != mapTx.end())
|
||||
continue;
|
||||
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
|
||||
if (nCheckFrequency != 0) assert(coins);
|
||||
if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
|
||||
const Coin &coin = pcoins->AccessCoin(txin.prevout);
|
||||
if (nCheckFrequency != 0) assert(!coin.IsSpent());
|
||||
if (coin.IsSpent() || (coin.IsCoinBase() && ((signed long)nMemPoolHeight) - coin.nHeight < COINBASE_MATURITY)) {
|
||||
txToRemove.insert(it);
|
||||
break;
|
||||
}
|
||||
@@ -661,8 +654,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
|
||||
parentSigOpCost += it2->GetSigOpCost();
|
||||
}
|
||||
} else {
|
||||
const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash);
|
||||
assert(coins && coins->IsAvailable(txin.prevout.n));
|
||||
assert(pcoins->HaveCoin(txin.prevout));
|
||||
}
|
||||
// Check whether its inputs are marked in mapNextTx.
|
||||
auto it3 = mapNextTx.find(txin.prevout);
|
||||
@@ -898,20 +890,24 @@ bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
|
||||
|
||||
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
|
||||
|
||||
bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const {
|
||||
bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
|
||||
// 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.
|
||||
CTransactionRef ptx = mempool.get(txid);
|
||||
CTransactionRef ptx = mempool.get(outpoint.hash);
|
||||
if (ptx) {
|
||||
coins = CCoins(*ptx, MEMPOOL_HEIGHT);
|
||||
return true;
|
||||
if (outpoint.n < ptx->vout.size()) {
|
||||
coin = Coin(ptx->vout[outpoint.n], MEMPOOL_HEIGHT, false);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return (base->GetCoins(txid, coins) && !coins.IsPruned());
|
||||
return (base->GetCoin(outpoint, coin) && !coin.IsSpent());
|
||||
}
|
||||
|
||||
bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const {
|
||||
return mempool.exists(txid) || base->HaveCoins(txid);
|
||||
bool CCoinsViewMemPool::HaveCoin(const COutPoint &outpoint) const {
|
||||
return mempool.exists(outpoint) || base->HaveCoin(outpoint);
|
||||
}
|
||||
|
||||
size_t CTxMemPool::DynamicMemoryUsage() const {
|
||||
@@ -1022,7 +1018,7 @@ void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) {
|
||||
}
|
||||
}
|
||||
|
||||
void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRemaining) {
|
||||
void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining) {
|
||||
LOCK(cs);
|
||||
|
||||
unsigned nTxnRemoved = 0;
|
||||
@@ -1053,11 +1049,10 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRe
|
||||
if (pvNoSpendsRemaining) {
|
||||
BOOST_FOREACH(const CTransaction& tx, txn) {
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
|
||||
if (exists(txin.prevout.hash))
|
||||
continue;
|
||||
auto iter = mapNextTx.lower_bound(COutPoint(txin.prevout.hash, 0));
|
||||
if (iter == mapNextTx.end() || iter->first->hash != txin.prevout.hash)
|
||||
pvNoSpendsRemaining->push_back(txin.prevout.hash);
|
||||
if (exists(txin.prevout.hash)) continue;
|
||||
if (!mapNextTx.count(txin.prevout)) {
|
||||
pvNoSpendsRemaining->push_back(txin.prevout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1074,3 +1069,5 @@ bool CTxMemPool::TransactionWithinChainLimit(const uint256& txid, size_t chainLi
|
||||
return it == mapTx.end() || (it->GetCountWithAncestors() < chainLimit &&
|
||||
it->GetCountWithDescendants() < chainLimit);
|
||||
}
|
||||
|
||||
SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
|
||||
|
||||
Reference in New Issue
Block a user