diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 67 |
1 files changed, 30 insertions, 37 deletions
diff --git a/src/main.cpp b/src/main.cpp index 43b81aaef8..fc8167e40e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -844,12 +844,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa { CCoinsView dummy; - CCoinsViewCache view(dummy); + CCoinsViewCache view(&dummy); CAmount nValueIn = 0; { LOCK(pool.cs); - CCoinsViewMemPool viewMemPool(*pcoinsTip, pool); + CCoinsViewMemPool viewMemPool(pcoinsTip, pool); view.SetBackend(viewMemPool); // do we already have it? @@ -1291,22 +1291,18 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight) { - bool ret; // mark inputs spent if (!tx.IsCoinBase()) { txundo.vprevout.reserve(tx.vin.size()); - for (unsigned int i = 0; i < tx.vin.size(); i++) { - const CTxIn &txin = tx.vin[i]; - CCoins &coins = inputs.GetCoins(txin.prevout.hash); + BOOST_FOREACH(const CTxIn &txin, tx.vin) { txundo.vprevout.push_back(CTxInUndo()); - ret = coins.Spend(txin.prevout, txundo.vprevout.back()); + bool ret = inputs.ModifyCoins(txin.prevout.hash)->Spend(txin.prevout, txundo.vprevout.back()); assert(ret); } } // add outputs - ret = inputs.SetCoins(tx.GetHash(), CCoins(tx, nHeight)); - assert(ret); + inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); } bool CScriptCheck::operator()() const { @@ -1448,21 +1444,23 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex // exactly. Note that transactions with only provably unspendable outputs won't // have outputs available even in the block itself, so we handle that case // specially with outsEmpty. + { CCoins outsEmpty; - CCoins &outs = view.HaveCoins(hash) ? view.GetCoins(hash) : outsEmpty; - outs.ClearUnspendable(); + CCoinsModifier outs = view.ModifyCoins(hash); + outs->ClearUnspendable(); - CCoins outsBlock = CCoins(tx, pindex->nHeight); + CCoins outsBlock(tx, pindex->nHeight); // The CCoins serialization does not serialize negative numbers. // No network rules currently depend on the version here, so an inconsistency is harmless // but it must be corrected before txout nversion ever influences a network rule. if (outsBlock.nVersion < 0) - outs.nVersion = outsBlock.nVersion; - if (outs != outsBlock) + outs->nVersion = outsBlock.nVersion; + if (*outs != outsBlock) fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted"); // remove outputs - outs = CCoins(); + outs->Clear(); + } // restore inputs if (i > 0) { // not coinbases @@ -1472,27 +1470,24 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex for (unsigned int j = tx.vin.size(); j-- > 0;) { const COutPoint &out = tx.vin[j].prevout; const CTxInUndo &undo = txundo.vprevout[j]; - CCoins coins; - view.GetCoins(out.hash, coins); // this can fail if the prevout was already entirely spent + CCoinsModifier coins = view.ModifyCoins(out.hash); if (undo.nHeight != 0) { // undo data contains height: this is the last output of the prevout tx being spent - if (!coins.IsPruned()) + if (!coins->IsPruned()) fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction"); - coins = CCoins(); - coins.fCoinBase = undo.fCoinBase; - coins.nHeight = undo.nHeight; - coins.nVersion = undo.nVersion; + coins->Clear(); + coins->fCoinBase = undo.fCoinBase; + coins->nHeight = undo.nHeight; + coins->nVersion = undo.nVersion; } else { - if (coins.IsPruned()) + if (coins->IsPruned()) fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction"); } - if (coins.IsAvailable(out.n)) + if (coins->IsAvailable(out.n)) fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output"); - if (coins.vout.size() < out.n+1) - coins.vout.resize(out.n+1); - coins.vout[out.n] = undo.txout; - if (!view.SetCoins(out.hash, coins)) - return error("DisconnectBlock() : cannot restore coin inputs"); + if (coins->vout.size() < out.n+1) + coins->vout.resize(out.n+1); + coins->vout[out.n] = undo.txout; } } } @@ -1701,9 +1696,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C return state.Abort("Failed to write transaction index"); // add this block to the view's block chain - bool ret; - ret = view.SetBestBlock(pindex->GetBlockHash()); - assert(ret); + view.SetBestBlock(pindex->GetBlockHash()); int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2; LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001); @@ -1747,10 +1740,10 @@ void static UpdateTip(CBlockIndex *pindexNew) { nTimeBestReceived = GetTime(); mempool.AddTransactionsUpdated(1); - LogPrintf("UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n", + LogPrintf("UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), - Checkpoints::GuessVerificationProgress(chainActive.Tip())); + Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize()); cvBlockChange.notify_all(); @@ -1790,7 +1783,7 @@ bool static DisconnectTip(CValidationState &state) { // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); { - CCoinsViewCache view(*pcoinsTip, true); + CCoinsViewCache view(pcoinsTip); if (!DisconnectBlock(block, state, pindexDelete, view)) return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); assert(view.Flush()); @@ -1843,7 +1836,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * int64_t nTime3; LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); { - CCoinsViewCache view(*pcoinsTip, true); + CCoinsViewCache view(pcoinsTip); CInv inv(MSG_BLOCK, pindexNew->GetBlockHash()); if (!ConnectBlock(*pblock, state, pindexNew, view)) { if (state.IsInvalid()) @@ -2893,7 +2886,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth nCheckDepth = chainActive.Height(); nCheckLevel = std::max(0, std::min(4, nCheckLevel)); LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); - CCoinsViewCache coins(*coinsview, true); + CCoinsViewCache coins(coinsview); CBlockIndex* pindexState = chainActive.Tip(); CBlockIndex* pindexFailure = NULL; int nGoodTransactions = 0; |