Browse Source

Merge pull request #2677 from sipa/fastcreate

CreateNewBlock performance improvements
miguelfreitas
Gavin Andresen 12 years ago
parent
commit
6b99cfae3c
  1. 28
      src/main.cpp
  2. 2
      src/main.h

28
src/main.cpp

@ -1342,7 +1342,7 @@ unsigned int CTransaction::GetP2SHSigOpCount(CCoinsViewCache& inputs) const
return nSigOps; 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 // mark inputs spent
if (!IsCoinBase()) { if (!IsCoinBase()) {
@ -1356,8 +1356,6 @@ bool CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs,
// add outputs // add outputs
assert(inputs.SetCoins(txhash, CCoins(*this, nHeight))); assert(inputs.SetCoins(txhash, CCoins(*this, nHeight)));
return true;
} }
bool CTransaction::HaveInputs(CCoinsViewCache &inputs) const bool CTransaction::HaveInputs(CCoinsViewCache &inputs) const
@ -1683,8 +1681,7 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi
} }
CTxUndo txundo; CTxUndo txundo;
if (!tx.UpdateCoins(state, view, txundo, pindex->nHeight, GetTxHash(i))) tx.UpdateCoins(state, view, txundo, pindex->nHeight, GetTxHash(i));
return error("ConnectBlock() : UpdateInputs failed");
if (!tx.IsCoinBase()) if (!tx.IsCoinBase())
blockundo.vtxundo.push_back(txundo); blockundo.vtxundo.push_back(txundo);
@ -4233,8 +4230,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
BOOST_FOREACH(const CTxIn& txin, tx.vin) BOOST_FOREACH(const CTxIn& txin, tx.vin)
{ {
// Read prev transaction // Read prev transaction
CCoins coins; if (!view.HaveCoins(txin.prevout.hash))
if (!view.GetCoins(txin.prevout.hash, coins))
{ {
// This should never happen; all transactions in the memory // This should never happen; all transactions in the memory
// pool should connect to either transactions in the chain // 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; nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue;
continue; continue;
} }
const CCoins &coins = view.GetCoins(txin.prevout.hash);
int64 nValueIn = coins.vout[txin.prevout.n].nValue; int64 nValueIn = coins.vout[txin.prevout.n].nValue;
nTotalIn += nValueIn; nTotalIn += nValueIn;
@ -4308,9 +4305,6 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
vecPriority.pop_back(); vecPriority.pop_back();
// second layer cached modifications just for this transaction
CCoinsViewCache viewTemp(view, true);
// Size limits // Size limits
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
if (nBlockSize + nTxSize >= nBlockMaxSize) if (nBlockSize + nTxSize >= nBlockMaxSize)
@ -4335,26 +4329,22 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
} }
if (!tx.HaveInputs(viewTemp)) if (!tx.HaveInputs(view))
continue; 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) if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
continue; continue;
CValidationState state; CValidationState state;
if (!tx.CheckInputs(state, viewTemp, true, SCRIPT_VERIFY_P2SH)) if (!tx.CheckInputs(state, view, true, SCRIPT_VERIFY_P2SH))
continue; continue;
CTxUndo txundo; CTxUndo txundo;
uint256 hash = tx.GetHash(); uint256 hash = tx.GetHash();
if (!tx.UpdateCoins(state, viewTemp, txundo, pindexPrev->nHeight+1, hash)) tx.UpdateCoins(state, view, txundo, pindexPrev->nHeight+1, hash);
continue;
// push changes from the second layer cache to the first one
viewTemp.Flush();
// Added // Added
pblock->vtx.push_back(tx); pblock->vtx.push_back(tx);

2
src/main.h

@ -659,7 +659,7 @@ public:
std::vector<CScriptCheck> *pvChecks = NULL) const; std::vector<CScriptCheck> *pvChecks = NULL) const;
// Apply the effects of this transaction on the UTXO set represented by view // 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 // Context-independent validity checks
bool CheckTransaction(CValidationState &state) const; bool CheckTransaction(CValidationState &state) const;

Loading…
Cancel
Save