// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "txdb.h"
+#include "db.h"
#include "miner.h"
#include "kernel.h"
int64 nFees = 0;
{
LOCK2(cs_main, mempool.cs);
- CBlockIndex* pindexPrev = pindexBest;
- CTxDB txdb("r");
+ CCoinsViewCache view(*pcoinsTip, true);
// Priority order to process transactions
list<COrphan> vOrphan; // list memory doesn't move
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
// Read prev transaction
- CTransaction txPrev;
- CTxIndex txindex;
- if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
+ CCoins coins;
+ if (!view.GetCoins(txin.prevout.hash, coins))
{
// This should never happen; all transactions in the memory
// pool should connect to either transactions in the chain
nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue;
continue;
}
- int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
+ int64 nValueIn = coins.vout[txin.prevout.n].nValue;
nTotalIn += nValueIn;
- int nConf = txindex.GetDepthInMainChain();
+ int nConf = pindexPrev->nHeight - coins.nHeight;
dPriority += (double)nValueIn * nConf;
}
if (fMissingInputs) continue;
}
// Collect transactions into block
- map<uint256, CTxIndex> mapTestPool;
uint64 nBlockSize = 1000;
uint64 nBlockTx = 0;
int nBlockSigOps = 100;
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)
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
}
- // Connecting shouldn't fail due to dependency on other memory pool transactions
- // because we're already processing them in order of dependency
- map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
- MapPrevTx mapInputs;
- bool fInvalid;
- if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid))
+ if (!tx.CheckInputs(viewTemp, CS_ALWAYS, true, false))
continue;
- int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
+ int64 nTxFees = tx.GetValueIn(viewTemp)-tx.GetValueOut();
if (nTxFees < nMinFee)
continue;
- nTxSigOps += tx.GetP2SHSigOpCount(mapInputs);
+ nTxSigOps += tx.GetP2SHSigOpCount(viewTemp);
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
continue;
- if (!tx.ConnectInputs(txdb, mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true))
+ CTxUndo txundo;
+ if (!tx.UpdateCoins(viewTemp, txundo, pindexPrev->nHeight+1, pblock->nTime))
continue;
- mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size());
- swap(mapTestPool, mapTestPoolTmp);
+
+ // push changes from the second layer cache to the first one
+ viewTemp.Flush();
// Added
pblock->vtx.push_back(tx);