Move CCoins-related logic to coins.{cpp.h}
This commit is contained in:
170
src/main.cpp
170
src/main.cpp
@@ -228,128 +228,6 @@ CBlockIndex *CChain::FindFork(const CBlockLocator &locator) const {
|
||||
return Genesis();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CCoinsView implementations
|
||||
//
|
||||
|
||||
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) { return false; }
|
||||
bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; }
|
||||
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
|
||||
uint256 CCoinsView::GetBestBlock() { return uint256(0); }
|
||||
bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; }
|
||||
bool CCoinsView::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) { return false; }
|
||||
bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
|
||||
|
||||
|
||||
CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { }
|
||||
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) { return base->GetCoins(txid, coins); }
|
||||
bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); }
|
||||
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(txid); }
|
||||
uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
|
||||
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
|
||||
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
|
||||
bool CCoinsViewBacked::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
|
||||
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
|
||||
|
||||
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { }
|
||||
|
||||
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
|
||||
if (cacheCoins.count(txid)) {
|
||||
coins = cacheCoins[txid];
|
||||
return true;
|
||||
}
|
||||
if (base->GetCoins(txid, coins)) {
|
||||
cacheCoins[txid] = coins;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<uint256,CCoins>::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
|
||||
std::map<uint256,CCoins>::iterator it = cacheCoins.lower_bound(txid);
|
||||
if (it != cacheCoins.end() && it->first == txid)
|
||||
return it;
|
||||
CCoins tmp;
|
||||
if (!base->GetCoins(txid,tmp))
|
||||
return cacheCoins.end();
|
||||
std::map<uint256,CCoins>::iterator ret = cacheCoins.insert(it, std::make_pair(txid, CCoins()));
|
||||
tmp.swap(ret->second);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) {
|
||||
std::map<uint256,CCoins>::iterator it = FetchCoins(txid);
|
||||
assert(it != cacheCoins.end());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) {
|
||||
cacheCoins[txid] = coins;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
|
||||
return FetchCoins(txid) != cacheCoins.end();
|
||||
}
|
||||
|
||||
uint256 CCoinsViewCache::GetBestBlock() {
|
||||
if (hashBlock == uint256(0))
|
||||
hashBlock = base->GetBestBlock();
|
||||
return hashBlock;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
|
||||
hashBlock = hashBlockIn;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlockIn) {
|
||||
for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
|
||||
cacheCoins[it->first] = it->second;
|
||||
hashBlock = hashBlockIn;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::Flush() {
|
||||
bool fOk = base->BatchWrite(cacheCoins, hashBlock);
|
||||
if (fOk)
|
||||
cacheCoins.clear();
|
||||
return fOk;
|
||||
}
|
||||
|
||||
unsigned int CCoinsViewCache::GetCacheSize() {
|
||||
return cacheCoins.size();
|
||||
}
|
||||
|
||||
/** Helper; lookup from tip (used calling mempool.check()
|
||||
NOTE: code calling this MUST hold the cs_main lock so
|
||||
another thread doesn't modify pcoinsTip. When we switch
|
||||
to C++11 this should be replaced by lambda expressions...
|
||||
**/
|
||||
static CCoins &LookupFromTip(const uint256& hash) {
|
||||
return pcoinsTip->GetCoins(hash);
|
||||
}
|
||||
|
||||
/** CCoinsView that brings transactions from a memorypool into view.
|
||||
It does not check for spendings by memory pool transactions. */
|
||||
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
|
||||
|
||||
bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
|
||||
if (base->GetCoins(txid, coins))
|
||||
return true;
|
||||
CTransaction tx;
|
||||
if (mempool.lookup(txid, tx)) {
|
||||
coins = CCoins(tx, MEMPOOL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) {
|
||||
return mempool.exists(txid) || base->HaveCoins(txid);
|
||||
}
|
||||
|
||||
CCoinsViewCache *pcoinsTip = NULL;
|
||||
CBlockTreeDB *pblocktree = NULL;
|
||||
|
||||
@@ -1416,25 +1294,6 @@ void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev)
|
||||
|
||||
|
||||
|
||||
const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input)
|
||||
{
|
||||
const CCoins &coins = GetCoins(input.prevout.hash);
|
||||
assert(coins.IsAvailable(input.prevout.n));
|
||||
return coins.vout[input.prevout.n];
|
||||
}
|
||||
|
||||
int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx)
|
||||
{
|
||||
if (tx.IsCoinBase())
|
||||
return 0;
|
||||
|
||||
int64_t nResult = 0;
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
||||
nResult += GetOutputFor(tx.vin[i]).nValue;
|
||||
|
||||
return nResult;
|
||||
}
|
||||
|
||||
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash)
|
||||
{
|
||||
// mark inputs spent
|
||||
@@ -1451,27 +1310,6 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
|
||||
assert(inputs.SetCoins(txhash, CCoins(tx, nHeight)));
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::HaveInputs(const CTransaction& tx)
|
||||
{
|
||||
if (!tx.IsCoinBase()) {
|
||||
// first check whether information about the prevout hash is available
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
||||
const COutPoint &prevout = tx.vin[i].prevout;
|
||||
if (!HaveCoins(prevout.hash))
|
||||
return false;
|
||||
}
|
||||
|
||||
// then check whether the actual outputs are available
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
||||
const COutPoint &prevout = tx.vin[i].prevout;
|
||||
const CCoins &coins = GetCoins(prevout.hash);
|
||||
if (!coins.IsAvailable(prevout.n))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CScriptCheck::operator()() const {
|
||||
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
|
||||
if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags, nHashType))
|
||||
@@ -1841,7 +1679,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
||||
|
||||
bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
|
||||
{
|
||||
mempool.check(&LookupFromTip);
|
||||
mempool.check(pcoinsTip);
|
||||
|
||||
// All modifications to the coin state will be done in this cache.
|
||||
// Only when all have succeeded, we push it to pcoinsTip.
|
||||
@@ -1966,7 +1804,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
|
||||
mempool.removeConflicts(tx);
|
||||
}
|
||||
|
||||
mempool.check(&LookupFromTip);
|
||||
mempool.check(pcoinsTip);
|
||||
|
||||
// Update best block in wallet (so we can detect restored wallets)
|
||||
if ((pindexNew->nHeight % 20160) == 0 || (!fIsInitialDownload && (pindexNew->nHeight % 144) == 0))
|
||||
@@ -3540,7 +3378,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
CValidationState state;
|
||||
if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
|
||||
{
|
||||
mempool.check(&LookupFromTip);
|
||||
mempool.check(pcoinsTip);
|
||||
RelayTransaction(tx, inv.hash);
|
||||
mapAlreadyAskedFor.erase(inv);
|
||||
vWorkQueue.push_back(inv.hash);
|
||||
@@ -3576,7 +3414,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
vEraseQueue.push_back(orphanHash);
|
||||
LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString().c_str());
|
||||
}
|
||||
mempool.check(&LookupFromTip);
|
||||
mempool.check(pcoinsTip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user