mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 04:52:59 +01:00
Conflict handling for ProRegTx in mempool
This commit is contained in:
parent
c772423468
commit
cdd723ede6
@ -21,6 +21,9 @@
|
||||
#include "version.h"
|
||||
#include "hash.h"
|
||||
|
||||
#include "evo/specialtx.h"
|
||||
#include "evo/providertx.h"
|
||||
|
||||
CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
|
||||
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
|
||||
CAmount _inChainInputValue,
|
||||
@ -438,6 +441,16 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
|
||||
vTxHashes.emplace_back(hash, newit);
|
||||
newit->vTxHashesIdx = vTxHashes.size() - 1;
|
||||
|
||||
if (tx.nType == TRANSACTION_PROVIDER_REGISTER) {
|
||||
CProRegTx proTx;
|
||||
if (!GetTxPayload(tx, proTx)) {
|
||||
assert(false);
|
||||
}
|
||||
mapProTxRegisterAddresses.emplace(proTx.addr, tx.GetHash());
|
||||
mapProTxPubKeyIDs.emplace(proTx.keyIDOwner, tx.GetHash());
|
||||
mapProTxPubKeyIDs.emplace(proTx.keyIDOperator, tx.GetHash());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -613,6 +626,16 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
|
||||
} else
|
||||
vTxHashes.clear();
|
||||
|
||||
if (it->GetTx().nVersion >= 3 && it->GetTx().nType == TRANSACTION_PROVIDER_REGISTER) {
|
||||
CProRegTx proTx;
|
||||
if (!GetTxPayload(it->GetTx(), proTx)) {
|
||||
assert(false);
|
||||
}
|
||||
mapProTxRegisterAddresses.erase(proTx.addr);
|
||||
mapProTxPubKeyIDs.erase(proTx.keyIDOwner);
|
||||
mapProTxPubKeyIDs.erase(proTx.keyIDOperator);
|
||||
}
|
||||
|
||||
totalTxSize -= it->GetTxSize();
|
||||
cachedInnerUsage -= it->DynamicMemoryUsage();
|
||||
cachedInnerUsage -= memusage::DynamicUsage(mapLinks[it].parents) + memusage::DynamicUsage(mapLinks[it].children);
|
||||
@ -739,6 +762,36 @@ void CTxMemPool::removeConflicts(const CTransaction &tx)
|
||||
}
|
||||
}
|
||||
|
||||
void CTxMemPool::removeProTxConflicts(const CTransaction &tx)
|
||||
{
|
||||
if (tx.nType != TRANSACTION_PROVIDER_REGISTER)
|
||||
return;
|
||||
|
||||
CProRegTx proTx;
|
||||
if (!GetTxPayload(tx, proTx)) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (mapProTxRegisterAddresses.count(proTx.addr)) {
|
||||
uint256 conflictHash = mapProTxRegisterAddresses[proTx.addr];
|
||||
if (conflictHash != tx.GetHash() && mapTx.count(conflictHash)) {
|
||||
removeRecursive(mapTx.find(conflictHash)->GetTx(), MemPoolRemovalReason::CONFLICT);
|
||||
}
|
||||
}
|
||||
if (mapProTxPubKeyIDs.count(proTx.keyIDOwner)) {
|
||||
uint256 conflictHash = mapProTxPubKeyIDs[proTx.keyIDOwner];
|
||||
if (conflictHash != tx.GetHash() && mapTx.count(conflictHash)) {
|
||||
removeRecursive(mapTx.find(conflictHash)->GetTx(), MemPoolRemovalReason::CONFLICT);
|
||||
}
|
||||
}
|
||||
if (mapProTxPubKeyIDs.count(proTx.keyIDOperator)) {
|
||||
uint256 conflictHash = mapProTxPubKeyIDs[proTx.keyIDOperator];
|
||||
if (conflictHash != tx.GetHash() && mapTx.count(conflictHash)) {
|
||||
removeRecursive(mapTx.find(conflictHash)->GetTx(), MemPoolRemovalReason::CONFLICT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a block is connected. Removes from mempool and updates the miner fee estimator.
|
||||
*/
|
||||
@ -765,6 +818,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne
|
||||
RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK);
|
||||
}
|
||||
removeConflicts(*tx);
|
||||
removeProTxConflicts(*tx);
|
||||
ClearPrioritisation(tx->GetHash());
|
||||
}
|
||||
lastRollingFeeUpdate = GetTime();
|
||||
@ -776,6 +830,8 @@ void CTxMemPool::_clear()
|
||||
mapLinks.clear();
|
||||
mapTx.clear();
|
||||
mapNextTx.clear();
|
||||
mapProTxRegisterAddresses.clear();
|
||||
mapProTxPubKeyIDs.clear();
|
||||
totalTxSize = 0;
|
||||
cachedInnerUsage = 0;
|
||||
lastRollingFeeUpdate = GetTime();
|
||||
@ -1013,6 +1069,16 @@ TxMempoolInfo CTxMemPool::info(const uint256& hash) const
|
||||
return GetInfo(i);
|
||||
}
|
||||
|
||||
bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
|
||||
LOCK(cs);
|
||||
if (tx.nVersion < 3 || tx.nType != TRANSACTION_PROVIDER_REGISTER)
|
||||
return false;
|
||||
CProRegTx proTx;
|
||||
if (!GetTxPayload(tx, proTx))
|
||||
assert(false);
|
||||
return mapProTxRegisterAddresses.count(proTx.addr) || mapProTxPubKeyIDs.count(proTx.keyIDOwner) || mapProTxPubKeyIDs.count(proTx.keyIDOperator);
|
||||
}
|
||||
|
||||
CFeeRate CTxMemPool::estimateFee(int nBlocks) const
|
||||
{
|
||||
LOCK(cs);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "primitives/transaction.h"
|
||||
#include "sync.h"
|
||||
#include "random.h"
|
||||
#include "netaddress.h"
|
||||
|
||||
#undef foreach
|
||||
#include "boost/multi_index_container.hpp"
|
||||
@ -534,6 +535,9 @@ private:
|
||||
typedef std::map<uint256, std::vector<CSpentIndexKey> > mapSpentIndexInserted;
|
||||
mapSpentIndexInserted mapSpentInserted;
|
||||
|
||||
std::map<CService, uint256> mapProTxRegisterAddresses;
|
||||
std::map<CKeyID, uint256> mapProTxPubKeyIDs;
|
||||
|
||||
void UpdateParent(txiter entry, txiter parent, bool add);
|
||||
void UpdateChild(txiter entry, txiter child, bool add);
|
||||
|
||||
@ -576,6 +580,7 @@ public:
|
||||
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN);
|
||||
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags);
|
||||
void removeConflicts(const CTransaction &tx);
|
||||
void removeProTxConflicts(const CTransaction &tx);
|
||||
void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight);
|
||||
|
||||
void clear();
|
||||
@ -684,6 +689,8 @@ public:
|
||||
TxMempoolInfo info(const uint256& hash) const;
|
||||
std::vector<TxMempoolInfo> infoAll() const;
|
||||
|
||||
bool existsProviderTxConflict(const CTransaction &tx) const;
|
||||
|
||||
/** Estimate fee rate needed to get into the next nBlocks
|
||||
* If no answer can be given at nBlocks, return an estimate
|
||||
* at the lowest number of blocks where one can be given
|
||||
|
@ -650,6 +650,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
|
||||
if (fRequireStandard && !IsStandardTx(tx, reason))
|
||||
return state.DoS(0, false, REJECT_NONSTANDARD, reason);
|
||||
|
||||
if (pool.existsProviderTxConflict(tx)) {
|
||||
return state.DoS(0, false, REJECT_DUPLICATE, "protx-dup");
|
||||
}
|
||||
|
||||
// Only accept nLockTime-using transactions that can be mined in the next
|
||||
// block; we don't want our mempool filled up with transactions that can't
|
||||
// be mined yet.
|
||||
|
Loading…
Reference in New Issue
Block a user