mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-01-11 07:17:53 +00:00
mempool/cinv now indexed by userhash (all tx must be indexed by userhash btw)
This commit is contained in:
parent
b0716cdc3d
commit
4652b9f01b
91
src/main.cpp
91
src/main.cpp
@ -492,21 +492,6 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins)
|
|
||||||
{
|
|
||||||
LOCK(cs);
|
|
||||||
|
|
||||||
/*
|
|
||||||
std::map<COutPoint, CInPoint>::iterator it = mapNextTx.lower_bound(COutPoint(hashTx, 0));
|
|
||||||
|
|
||||||
// iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx
|
|
||||||
while (it != mapNextTx.end() && it->first.hash == hashTx) {
|
|
||||||
coins.Spend(it->first.n); // and remove those outputs from coins
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// [MF] check if tx duplicated (mapTx and ccoins)
|
// [MF] check if tx duplicated (mapTx and ccoins)
|
||||||
bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fLimitFree,
|
bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fLimitFree,
|
||||||
bool* pfMissingInputs)
|
bool* pfMissingInputs)
|
||||||
@ -528,15 +513,16 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fLimitFr
|
|||||||
reason.c_str());
|
reason.c_str());
|
||||||
|
|
||||||
// is it already in the memory pool?
|
// is it already in the memory pool?
|
||||||
uint256 hash = tx.GetHash();
|
uint256 userhash = tx.GetUsernameHash();
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
if (mapTx.count(hash))
|
if (mapTx.count(userhash))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// [MF] check txIndex here instead of coins
|
// [MF] FIXME: check txIndex here instead of coins
|
||||||
|
|
||||||
CCoinsView dummy;
|
CCoinsView dummy;
|
||||||
CCoinsViewCache view(dummy);
|
CCoinsViewCache view(dummy);
|
||||||
|
|
||||||
@ -585,29 +571,25 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fLimitFr
|
|||||||
// Store transaction in memory
|
// Store transaction in memory
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
addUnchecked(hash, tx); // adds to mapTx
|
addUnchecked(userhash, tx); // adds to mapTx
|
||||||
}
|
}
|
||||||
|
|
||||||
///// are we sure this is ok when loading transactions or restoring block txes
|
///// are we sure this is ok when loading transactions or restoring block txes
|
||||||
SyncWithWallets(hash, tx, NULL, true);
|
SyncWithWallets(userhash, tx, NULL, true);
|
||||||
|
|
||||||
printf("CTxMemPool::accept() : accepted %s (poolsz %"PRIszu")\n",
|
printf("CTxMemPool::accept() : accepted %s (poolsz %"PRIszu")\n",
|
||||||
hash.ToString().c_str(),
|
userhash.ToString().c_str(),
|
||||||
mapTx.size());
|
mapTx.size());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx)
|
bool CTxMemPool::addUnchecked(const uint256& userhash, CTransaction &tx)
|
||||||
{
|
{
|
||||||
// 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 CTxMemPool::accept to properly check the transaction first.
|
// call CTxMemPool::accept to properly check the transaction first.
|
||||||
{
|
{
|
||||||
mapTx[hash] = tx;
|
mapTx[userhash] = tx;
|
||||||
/* [MF]
|
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
|
||||||
mapNextTx[tx.vin[i].prevout] = CInPoint(&mapTx[hash], i);
|
|
||||||
*/
|
|
||||||
nTransactionsUpdated++;
|
nTransactionsUpdated++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -619,22 +601,9 @@ bool CTxMemPool::remove(const CTransaction &tx, bool fRecursive)
|
|||||||
// Remove transaction from memory pool
|
// Remove transaction from memory pool
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
uint256 hash = tx.GetHash();
|
uint256 hash = tx.GetUsernameHash();
|
||||||
if (mapTx.count(hash))
|
if (mapTx.count(hash))
|
||||||
{
|
{
|
||||||
if (fRecursive) {
|
|
||||||
/*
|
|
||||||
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
|
||||||
std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i));
|
|
||||||
if (it != mapNextTx.end())
|
|
||||||
remove(*it->second.ptx, true);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
|
||||||
mapNextTx.erase(txin.prevout);
|
|
||||||
*/
|
|
||||||
mapTx.erase(hash);
|
mapTx.erase(hash);
|
||||||
nTransactionsUpdated++;
|
nTransactionsUpdated++;
|
||||||
}
|
}
|
||||||
@ -642,28 +611,10 @@ bool CTxMemPool::remove(const CTransaction &tx, bool fRecursive)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTxMemPool::removeConflicts(const CTransaction &tx)
|
|
||||||
{
|
|
||||||
// Remove transactions which depend on inputs of tx, recursively
|
|
||||||
LOCK(cs);
|
|
||||||
/* [MF]
|
|
||||||
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
|
|
||||||
std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout);
|
|
||||||
if (it != mapNextTx.end()) {
|
|
||||||
const CTransaction &txConflict = *it->second.ptx;
|
|
||||||
if (txConflict != tx)
|
|
||||||
remove(txConflict, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CTxMemPool::clear()
|
void CTxMemPool::clear()
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
mapTx.clear();
|
mapTx.clear();
|
||||||
mapNextTx.clear();
|
|
||||||
++nTransactionsUpdated;
|
++nTransactionsUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,23 +684,23 @@ bool CWalletTx::AcceptWalletTransaction()
|
|||||||
|
|
||||||
|
|
||||||
// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
|
// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
|
||||||
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
|
bool GetTransaction(const uint256 &userhash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
|
||||||
{
|
{
|
||||||
CBlockIndex *pindexSlow = NULL;
|
CBlockIndex *pindexSlow = NULL;
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
{
|
{
|
||||||
LOCK(mempool.cs);
|
LOCK(mempool.cs);
|
||||||
if (mempool.exists(hash))
|
if (mempool.exists(userhash))
|
||||||
{
|
{
|
||||||
txOut = mempool.lookup(hash);
|
txOut = mempool.lookup(userhash);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fTxIndex) {
|
if (fTxIndex) {
|
||||||
CDiskTxPos postx;
|
CDiskTxPos postx;
|
||||||
if (pblocktree->ReadTxIndex(hash, postx)) {
|
if (pblocktree->ReadTxIndex(userhash, postx)) {
|
||||||
CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
|
CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
|
||||||
CBlockHeader header;
|
CBlockHeader header;
|
||||||
try {
|
try {
|
||||||
@ -760,7 +711,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
|
|||||||
return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
|
return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
|
||||||
}
|
}
|
||||||
hashBlock = header.GetHash();
|
hashBlock = header.GetHash();
|
||||||
if (txOut.GetHash() != hash)
|
if (txOut.GetUsernameHash() != userhash)
|
||||||
return error("%s() : txid mismatch", __PRETTY_FUNCTION__);
|
return error("%s() : txid mismatch", __PRETTY_FUNCTION__);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -771,7 +722,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
|
|||||||
{
|
{
|
||||||
CCoinsViewCache &view = *pcoinsTip;
|
CCoinsViewCache &view = *pcoinsTip;
|
||||||
CCoins coins;
|
CCoins coins;
|
||||||
if (view.GetCoins(hash, coins))
|
if (view.GetCoins(userhash, coins))
|
||||||
nHeight = coins.nHeight;
|
nHeight = coins.nHeight;
|
||||||
}
|
}
|
||||||
if (nHeight > 0)
|
if (nHeight > 0)
|
||||||
@ -783,7 +734,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
|
|||||||
CBlock block;
|
CBlock block;
|
||||||
if (ReadBlockFromDisk(block, pindexSlow)) {
|
if (ReadBlockFromDisk(block, pindexSlow)) {
|
||||||
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
|
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
|
||||||
if (tx.GetHash() == hash) {
|
if (tx.GetHash() == userhash) {
|
||||||
txOut = tx;
|
txOut = tx;
|
||||||
hashBlock = pindexSlow->GetBlockHash();
|
hashBlock = pindexSlow->GetBlockHash();
|
||||||
return true;
|
return true;
|
||||||
@ -1185,6 +1136,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
|||||||
return error("DisconnectBlock() : block and undo data inconsistent");
|
return error("DisconnectBlock() : block and undo data inconsistent");
|
||||||
|
|
||||||
// undo transactions in reverse order
|
// undo transactions in reverse order
|
||||||
|
// [MF] FIXME: remove from txIndex
|
||||||
for (int i = block.vtx.size() - 1; i >= 0; i--) {
|
for (int i = block.vtx.size() - 1; i >= 0; i--) {
|
||||||
const CTransaction &tx = block.vtx[i];
|
const CTransaction &tx = block.vtx[i];
|
||||||
uint256 hash = tx.GetHash();
|
uint256 hash = tx.GetHash();
|
||||||
@ -1483,7 +1435,6 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
|
|||||||
// Delete redundant memory transactions that are in the connected branch
|
// Delete redundant memory transactions that are in the connected branch
|
||||||
BOOST_FOREACH(CTransaction& tx, vDelete) {
|
BOOST_FOREACH(CTransaction& tx, vDelete) {
|
||||||
mempool.remove(tx);
|
mempool.remove(tx);
|
||||||
mempool.removeConflicts(tx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update best block in wallet (so we can detect restored wallets)
|
// Update best block in wallet (so we can detect restored wallets)
|
||||||
@ -1928,7 +1879,7 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
|
|||||||
if (filter.IsRelevantAndUpdate(block.vtx[i], hash))
|
if (filter.IsRelevantAndUpdate(block.vtx[i], hash))
|
||||||
{
|
{
|
||||||
vMatch.push_back(true);
|
vMatch.push_back(true);
|
||||||
vMatchedTxn.push_back(make_pair(i, hash));
|
vMatchedTxn.push_back(make_pair(i, block.vtx[i].GetUsernameHash()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vMatch.push_back(false);
|
vMatch.push_back(false);
|
||||||
@ -2625,6 +2576,7 @@ void static ProcessGetData(CNode* pfrom)
|
|||||||
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
|
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
|
||||||
// however we MUST always provide at least what the remote peer needs
|
// however we MUST always provide at least what the remote peer needs
|
||||||
typedef std::pair<unsigned int, uint256> PairType;
|
typedef std::pair<unsigned int, uint256> PairType;
|
||||||
|
// [MF] check if vMatchedTxn is userhash
|
||||||
BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
|
BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
|
||||||
if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
|
if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
|
||||||
pfrom->PushMessage("tx", block.vtx[pair.first]);
|
pfrom->PushMessage("tx", block.vtx[pair.first]);
|
||||||
@ -3038,7 +2990,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
CTransaction tx;
|
CTransaction tx;
|
||||||
vRecv >> tx;
|
vRecv >> tx;
|
||||||
|
|
||||||
CInv inv(MSG_TX, tx.GetHash());
|
CInv inv(MSG_TX, tx.GetUsernameHash());
|
||||||
pfrom->AddInventoryKnown(inv);
|
pfrom->AddInventoryKnown(inv);
|
||||||
|
|
||||||
// Truncate messages to the size of the tx in them
|
// Truncate messages to the size of the tx in them
|
||||||
@ -3460,7 +3412,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||||||
if (!fTrickleWait)
|
if (!fTrickleWait)
|
||||||
{
|
{
|
||||||
CWalletTx wtx;
|
CWalletTx wtx;
|
||||||
// [MF] TODO: use userhash
|
|
||||||
if (GetTransaction(inv.hash, wtx))
|
if (GetTransaction(inv.hash, wtx))
|
||||||
if (wtx.fFromMe)
|
if (wtx.fFromMe)
|
||||||
fTrickleWait = true;
|
fTrickleWait = true;
|
||||||
|
15
src/main.h
15
src/main.h
@ -1006,16 +1006,13 @@ class CTxMemPool
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mutable CCriticalSection cs;
|
mutable CCriticalSection cs;
|
||||||
std::map<uint256, CTransaction> mapTx;
|
std::map<uint256, CTransaction> mapTx; // [MF] hash is now userhash
|
||||||
std::map<COutPoint, CInPoint> mapNextTx;
|
|
||||||
|
|
||||||
bool accept(CValidationState &state, CTransaction &tx, bool fLimitFree, bool* pfMissingInputs);
|
bool accept(CValidationState &state, CTransaction &tx, bool fLimitFree, bool* pfMissingInputs);
|
||||||
bool addUnchecked(const uint256& hash, CTransaction &tx);
|
bool addUnchecked(const uint256& userhash, CTransaction &tx);
|
||||||
bool remove(const CTransaction &tx, bool fRecursive = false);
|
bool remove(const CTransaction &tx, bool fRecursive = false);
|
||||||
bool removeConflicts(const CTransaction &tx);
|
|
||||||
void clear();
|
void clear();
|
||||||
void queryHashes(std::vector<uint256>& vtxid);
|
void queryHashes(std::vector<uint256>& vtxid);
|
||||||
void pruneSpent(const uint256& hash, CCoins &coins);
|
|
||||||
|
|
||||||
unsigned long size()
|
unsigned long size()
|
||||||
{
|
{
|
||||||
@ -1023,14 +1020,14 @@ public:
|
|||||||
return mapTx.size();
|
return mapTx.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exists(uint256 hash)
|
bool exists(uint256 userhash)
|
||||||
{
|
{
|
||||||
return (mapTx.count(hash) != 0);
|
return (mapTx.count(userhash) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTransaction& lookup(uint256 hash)
|
CTransaction& lookup(uint256 userhash)
|
||||||
{
|
{
|
||||||
return mapTx[hash];
|
return mapTx[userhash];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
10
src/net.cpp
10
src/net.cpp
@ -1792,17 +1792,17 @@ instance_of_cnetcleanup;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RelayTransaction(const CTransaction& tx, const uint256& hash)
|
void RelayTransaction(const CTransaction& tx, const uint256& userhash)
|
||||||
{
|
{
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ss.reserve(10000);
|
ss.reserve(10000);
|
||||||
ss << tx;
|
ss << tx;
|
||||||
RelayTransaction(tx, hash, ss);
|
RelayTransaction(tx, userhash, ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
|
void RelayTransaction(const CTransaction& tx, const uint256& userhash, const CDataStream& ss)
|
||||||
{
|
{
|
||||||
CInv inv(MSG_TX, hash);
|
CInv inv(MSG_TX, userhash);
|
||||||
{
|
{
|
||||||
LOCK(cs_mapRelay);
|
LOCK(cs_mapRelay);
|
||||||
// Expire old relay messages
|
// Expire old relay messages
|
||||||
@ -1824,7 +1824,7 @@ void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataSt
|
|||||||
LOCK(pnode->cs_filter);
|
LOCK(pnode->cs_filter);
|
||||||
if (pnode->pfilter)
|
if (pnode->pfilter)
|
||||||
{
|
{
|
||||||
if (pnode->pfilter->IsRelevantAndUpdate(tx, hash))
|
if (pnode->pfilter->IsRelevantAndUpdate(tx, userhash))
|
||||||
pnode->PushInventory(inv);
|
pnode->PushInventory(inv);
|
||||||
} else
|
} else
|
||||||
pnode->PushInventory(inv);
|
pnode->PushInventory(inv);
|
||||||
|
@ -644,7 +644,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
class CTransaction;
|
class CTransaction;
|
||||||
void RelayTransaction(const CTransaction& tx, const uint256& hash);
|
void RelayTransaction(const CTransaction& tx, const uint256& userhash);
|
||||||
void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
|
void RelayTransaction(const CTransaction& tx, const uint256& userhash, const CDataStream& ss);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -126,6 +126,7 @@ Value getrawmempool(const Array& params, bool fHelp)
|
|||||||
"getrawmempool\n"
|
"getrawmempool\n"
|
||||||
"Returns all transaction ids in memory pool.");
|
"Returns all transaction ids in memory pool.");
|
||||||
|
|
||||||
|
// [MF] check: hashes are now userhash
|
||||||
vector<uint256> vtxid;
|
vector<uint256> vtxid;
|
||||||
mempool.queryHashes(vtxid);
|
mempool.queryHashes(vtxid);
|
||||||
|
|
||||||
@ -229,7 +230,7 @@ Value gettxout(const Array& params, bool fHelp)
|
|||||||
CCoinsViewMemPool view(*pcoinsTip, mempool);
|
CCoinsViewMemPool view(*pcoinsTip, mempool);
|
||||||
if (!view.GetCoins(hash, coins))
|
if (!view.GetCoins(hash, coins))
|
||||||
return Value::null;
|
return Value::null;
|
||||||
mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
|
//mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
|
||||||
} else {
|
} else {
|
||||||
if (!pcoinsTip->GetCoins(hash, coins))
|
if (!pcoinsTip->GetCoins(hash, coins))
|
||||||
return Value::null;
|
return Value::null;
|
||||||
|
@ -557,7 +557,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
|||||||
catch (std::exception &e) {
|
catch (std::exception &e) {
|
||||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
||||||
}
|
}
|
||||||
uint256 hashTx = tx.GetHash();
|
uint256 hashTx = tx.GetUsernameHash();
|
||||||
|
|
||||||
bool fHave = false;
|
bool fHave = false;
|
||||||
CCoinsViewCache &view = *pcoinsTip;
|
CCoinsViewCache &view = *pcoinsTip;
|
||||||
|
@ -766,7 +766,7 @@ void CWalletTx::RelayWalletTransaction()
|
|||||||
if (!IsSpamMessage())
|
if (!IsSpamMessage())
|
||||||
{
|
{
|
||||||
if (GetDepthInMainChain() == 0) {
|
if (GetDepthInMainChain() == 0) {
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetUsernameHash();
|
||||||
printf("Relaying wtx %s\n", hash.ToString().c_str());
|
printf("Relaying wtx %s\n", hash.ToString().c_str());
|
||||||
RelayTransaction((CTransaction)*this, hash);
|
RelayTransaction((CTransaction)*this, hash);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user