From 2ec349bc420d7f4541bf91acf8b830377a1421f3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 21 May 2013 02:36:48 +0200 Subject: [PATCH] CreateNewBlock performance improvements --- src/main.cpp | 28 +++++++++------------------- src/main.h | 2 +- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e2bed52787..2d22541baf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1342,7 +1342,7 @@ unsigned int CTransaction::GetP2SHSigOpCount(CCoinsViewCache& inputs) const return nSigOps; } -bool CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash) const +void CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash) const { // mark inputs spent if (!IsCoinBase()) { @@ -1356,8 +1356,6 @@ bool CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs, // add outputs assert(inputs.SetCoins(txhash, CCoins(*this, nHeight))); - - return true; } bool CTransaction::HaveInputs(CCoinsViewCache &inputs) const @@ -1683,8 +1681,7 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi } CTxUndo txundo; - if (!tx.UpdateCoins(state, view, txundo, pindex->nHeight, GetTxHash(i))) - return error("ConnectBlock() : UpdateInputs failed"); + tx.UpdateCoins(state, view, txundo, pindex->nHeight, GetTxHash(i)); if (!tx.IsCoinBase()) blockundo.vtxundo.push_back(txundo); @@ -4233,8 +4230,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) BOOST_FOREACH(const CTxIn& txin, tx.vin) { // Read prev transaction - CCoins coins; - if (!view.GetCoins(txin.prevout.hash, coins)) + if (!view.HaveCoins(txin.prevout.hash)) { // This should never happen; all transactions in the memory // pool should connect to either transactions in the chain @@ -4261,6 +4257,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue; continue; } + const CCoins &coins = view.GetCoins(txin.prevout.hash); int64 nValueIn = coins.vout[txin.prevout.n].nValue; nTotalIn += nValueIn; @@ -4308,9 +4305,6 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); vecPriority.pop_back(); - // second layer cached modifications just for this transaction - CCoinsViewCache viewTemp(view, true); - // Size limits unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); if (nBlockSize + nTxSize >= nBlockMaxSize) @@ -4335,26 +4329,22 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); } - if (!tx.HaveInputs(viewTemp)) + if (!tx.HaveInputs(view)) continue; - int64 nTxFees = tx.GetValueIn(viewTemp)-tx.GetValueOut(); + int64 nTxFees = tx.GetValueIn(view)-tx.GetValueOut(); - nTxSigOps += tx.GetP2SHSigOpCount(viewTemp); + nTxSigOps += tx.GetP2SHSigOpCount(view); if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) continue; CValidationState state; - if (!tx.CheckInputs(state, viewTemp, true, SCRIPT_VERIFY_P2SH)) + if (!tx.CheckInputs(state, view, true, SCRIPT_VERIFY_P2SH)) continue; CTxUndo txundo; uint256 hash = tx.GetHash(); - if (!tx.UpdateCoins(state, viewTemp, txundo, pindexPrev->nHeight+1, hash)) - continue; - - // push changes from the second layer cache to the first one - viewTemp.Flush(); + tx.UpdateCoins(state, view, txundo, pindexPrev->nHeight+1, hash); // Added pblock->vtx.push_back(tx); diff --git a/src/main.h b/src/main.h index cba8421c85..8e71e66cc8 100644 --- a/src/main.h +++ b/src/main.h @@ -659,7 +659,7 @@ public: std::vector *pvChecks = NULL) const; // Apply the effects of this transaction on the UTXO set represented by view - bool UpdateCoins(CValidationState &state, CCoinsViewCache &view, CTxUndo &txundo, int nHeight, const uint256 &txhash) const; + void UpdateCoins(CValidationState &state, CCoinsViewCache &view, CTxUndo &txundo, int nHeight, const uint256 &txhash) const; // Context-independent validity checks bool CheckTransaction(CValidationState &state) const;