New class CTxMemPool, encapsulating TX memory pool data members
This commit is contained in:
parent
5a701eb7ea
commit
235507ae48
2 changed files with 37 additions and 30 deletions
59
src/main.cpp
59
src/main.cpp
|
@ -23,10 +23,8 @@ set<CWallet*> setpwalletRegistered;
|
||||||
|
|
||||||
CCriticalSection cs_main;
|
CCriticalSection cs_main;
|
||||||
|
|
||||||
static map<uint256, CTransaction> mapTransactions;
|
static CTxMemPool mempool;
|
||||||
CCriticalSection cs_mapTransactions;
|
|
||||||
unsigned int nTransactionsUpdated = 0;
|
unsigned int nTransactionsUpdated = 0;
|
||||||
map<COutPoint, CInPoint> mapNextTx;
|
|
||||||
|
|
||||||
map<uint256, CBlockIndex*> mapBlockIndex;
|
map<uint256, CBlockIndex*> mapBlockIndex;
|
||||||
uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
|
uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
|
||||||
|
@ -474,8 +472,8 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
||||||
// Do we already have it?
|
// Do we already have it?
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
{
|
{
|
||||||
LOCK(cs_mapTransactions);
|
LOCK(mempool.cs);
|
||||||
if (mapTransactions.count(hash))
|
if (mempool.mapTx.count(hash))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (fCheckInputs)
|
if (fCheckInputs)
|
||||||
|
@ -487,7 +485,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
||||||
for (int i = 0; i < vin.size(); i++)
|
for (int i = 0; i < vin.size(); i++)
|
||||||
{
|
{
|
||||||
COutPoint outpoint = vin[i].prevout;
|
COutPoint outpoint = vin[i].prevout;
|
||||||
if (mapNextTx.count(outpoint))
|
if (mempool.mapNextTx.count(outpoint))
|
||||||
{
|
{
|
||||||
// Disable replacement feature for now
|
// Disable replacement feature for now
|
||||||
return false;
|
return false;
|
||||||
|
@ -495,7 +493,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
||||||
// Allow replacing with a newer version of the same transaction
|
// Allow replacing with a newer version of the same transaction
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
return false;
|
return false;
|
||||||
ptxOld = mapNextTx[outpoint].ptx;
|
ptxOld = mempool.mapNextTx[outpoint].ptx;
|
||||||
if (ptxOld->IsFinal())
|
if (ptxOld->IsFinal())
|
||||||
return false;
|
return false;
|
||||||
if (!IsNewerThan(*ptxOld))
|
if (!IsNewerThan(*ptxOld))
|
||||||
|
@ -503,7 +501,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
||||||
for (int i = 0; i < vin.size(); i++)
|
for (int i = 0; i < vin.size(); i++)
|
||||||
{
|
{
|
||||||
COutPoint outpoint = vin[i].prevout;
|
COutPoint outpoint = vin[i].prevout;
|
||||||
if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)
|
if (!mempool.mapNextTx.count(outpoint) || mempool.mapNextTx[outpoint].ptx != ptxOld)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -574,7 +572,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
||||||
|
|
||||||
// Store transaction in memory
|
// Store transaction in memory
|
||||||
{
|
{
|
||||||
LOCK(cs_mapTransactions);
|
LOCK(mempool.cs);
|
||||||
if (ptxOld)
|
if (ptxOld)
|
||||||
{
|
{
|
||||||
printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
|
printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
|
||||||
|
@ -596,15 +594,15 @@ uint64 nPooledTx = 0;
|
||||||
|
|
||||||
bool CTransaction::AddToMemoryPoolUnchecked()
|
bool CTransaction::AddToMemoryPoolUnchecked()
|
||||||
{
|
{
|
||||||
printf("AcceptToMemoryPoolUnchecked(): size %lu\n", mapTransactions.size());
|
printf("AcceptToMemoryPoolUnchecked(): size %lu\n", mempool.mapTx.size());
|
||||||
// Add to memory pool without checking anything. Don't call this directly,
|
// Add to memory pool without checking anything. Don't call this directly,
|
||||||
// call AcceptToMemoryPool to properly check the transaction first.
|
// call AcceptToMemoryPool to properly check the transaction first.
|
||||||
{
|
{
|
||||||
LOCK(cs_mapTransactions);
|
LOCK(mempool.cs);
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
mapTransactions[hash] = *this;
|
mempool.mapTx[hash] = *this;
|
||||||
for (int i = 0; i < vin.size(); i++)
|
for (int i = 0; i < vin.size(); i++)
|
||||||
mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i);
|
mempool.mapNextTx[vin[i].prevout] = CInPoint(&mempool.mapTx[hash], i);
|
||||||
nTransactionsUpdated++;
|
nTransactionsUpdated++;
|
||||||
++nPooledTx;
|
++nPooledTx;
|
||||||
}
|
}
|
||||||
|
@ -616,13 +614,13 @@ bool CTransaction::RemoveFromMemoryPool()
|
||||||
{
|
{
|
||||||
// Remove transaction from memory pool
|
// Remove transaction from memory pool
|
||||||
{
|
{
|
||||||
LOCK(cs_mapTransactions);
|
LOCK(mempool.cs);
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
if (mapTransactions.count(hash))
|
if (mempool.mapTx.count(hash))
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||||
mapNextTx.erase(txin.prevout);
|
mempool.mapNextTx.erase(txin.prevout);
|
||||||
mapTransactions.erase(hash);
|
mempool.mapTx.erase(hash);
|
||||||
nTransactionsUpdated++;
|
nTransactionsUpdated++;
|
||||||
--nPooledTx;
|
--nPooledTx;
|
||||||
}
|
}
|
||||||
|
@ -695,14 +693,14 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
|
||||||
{
|
{
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(cs_mapTransactions);
|
LOCK(mempool.cs);
|
||||||
// Add previous supporting transactions first
|
// Add previous supporting transactions first
|
||||||
BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
|
BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
|
||||||
{
|
{
|
||||||
if (!tx.IsCoinBase())
|
if (!tx.IsCoinBase())
|
||||||
{
|
{
|
||||||
uint256 hash = tx.GetHash();
|
uint256 hash = tx.GetHash();
|
||||||
if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
|
if (!mempool.mapTx.count(hash) && !txdb.ContainsTx(hash))
|
||||||
tx.AcceptToMemoryPool(txdb, fCheckInputs);
|
tx.AcceptToMemoryPool(txdb, fCheckInputs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1017,10 +1015,10 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes
|
||||||
{
|
{
|
||||||
// Get prev tx from single transactions in memory
|
// Get prev tx from single transactions in memory
|
||||||
{
|
{
|
||||||
LOCK(cs_mapTransactions);
|
LOCK(mempool.cs);
|
||||||
if (!mapTransactions.count(prevout.hash))
|
if (!mempool.mapTx.count(prevout.hash))
|
||||||
return error("FetchInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
|
return error("FetchInputs() : %s mempool.mapTx prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
|
||||||
txPrev = mapTransactions[prevout.hash];
|
txPrev = mempool.mapTx[prevout.hash];
|
||||||
}
|
}
|
||||||
if (!fFound)
|
if (!fFound)
|
||||||
txindex.vSpent.resize(txPrev.vout.size());
|
txindex.vSpent.resize(txPrev.vout.size());
|
||||||
|
@ -1183,15 +1181,15 @@ bool CTransaction::ClientConnectInputs()
|
||||||
|
|
||||||
// Take over previous transactions' spent pointers
|
// Take over previous transactions' spent pointers
|
||||||
{
|
{
|
||||||
LOCK(cs_mapTransactions);
|
LOCK(mempool.cs);
|
||||||
int64 nValueIn = 0;
|
int64 nValueIn = 0;
|
||||||
for (int i = 0; i < vin.size(); i++)
|
for (int i = 0; i < vin.size(); i++)
|
||||||
{
|
{
|
||||||
// Get prev tx from single transactions in memory
|
// Get prev tx from single transactions in memory
|
||||||
COutPoint prevout = vin[i].prevout;
|
COutPoint prevout = vin[i].prevout;
|
||||||
if (!mapTransactions.count(prevout.hash))
|
if (!mempool.mapTx.count(prevout.hash))
|
||||||
return false;
|
return false;
|
||||||
CTransaction& txPrev = mapTransactions[prevout.hash];
|
CTransaction& txPrev = mempool.mapTx[prevout.hash];
|
||||||
|
|
||||||
if (prevout.n >= txPrev.vout.size())
|
if (prevout.n >= txPrev.vout.size())
|
||||||
return false;
|
return false;
|
||||||
|
@ -1200,7 +1198,8 @@ bool CTransaction::ClientConnectInputs()
|
||||||
if (!VerifySignature(txPrev, *this, i, true, 0))
|
if (!VerifySignature(txPrev, *this, i, true, 0))
|
||||||
return error("ConnectInputs() : VerifySignature failed");
|
return error("ConnectInputs() : VerifySignature failed");
|
||||||
|
|
||||||
///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of
|
///// this is redundant with the mempool.mapNextTx stuff,
|
||||||
|
///// not sure which I want to get rid of
|
||||||
///// this has to go away now that posNext is gone
|
///// this has to go away now that posNext is gone
|
||||||
// // Check for conflicts
|
// // Check for conflicts
|
||||||
// if (!txPrev.vout[prevout.n].posNext.IsNull())
|
// if (!txPrev.vout[prevout.n].posNext.IsNull())
|
||||||
|
@ -2135,7 +2134,7 @@ bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
|
||||||
{
|
{
|
||||||
switch (inv.type)
|
switch (inv.type)
|
||||||
{
|
{
|
||||||
case MSG_TX: return mapTransactions.count(inv.hash) || mapOrphanTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
|
case MSG_TX: return mempool.mapTx.count(inv.hash) || mapOrphanTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
|
||||||
case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
|
case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
|
||||||
}
|
}
|
||||||
// Don't know what it is, just say we already got one
|
// Don't know what it is, just say we already got one
|
||||||
|
@ -3093,14 +3092,14 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
|
||||||
// Collect memory pool transactions into the block
|
// Collect memory pool transactions into the block
|
||||||
int64 nFees = 0;
|
int64 nFees = 0;
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, cs_mapTransactions);
|
LOCK2(cs_main, mempool.cs);
|
||||||
CTxDB txdb("r");
|
CTxDB txdb("r");
|
||||||
|
|
||||||
// Priority order to process transactions
|
// Priority order to process transactions
|
||||||
list<COrphan> vOrphan; // list memory doesn't move
|
list<COrphan> vOrphan; // list memory doesn't move
|
||||||
map<uint256, vector<COrphan*> > mapDependers;
|
map<uint256, vector<COrphan*> > mapDependers;
|
||||||
multimap<double, CTransaction*> mapPriority;
|
multimap<double, CTransaction*> mapPriority;
|
||||||
for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi)
|
for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
|
||||||
{
|
{
|
||||||
CTransaction& tx = (*mi).second;
|
CTransaction& tx = (*mi).second;
|
||||||
if (tx.IsCoinBase() || !tx.IsFinal())
|
if (tx.IsCoinBase() || !tx.IsFinal())
|
||||||
|
|
|
@ -1608,4 +1608,12 @@ public:
|
||||||
bool ProcessAlert();
|
bool ProcessAlert();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CTxMemPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mutable CCriticalSection cs;
|
||||||
|
std::map<uint256, CTransaction> mapTx;
|
||||||
|
std::map<COutPoint, CInPoint> mapNextTx;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue