mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 13:03:17 +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 "version.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
|
#include "evo/specialtx.h"
|
||||||
|
#include "evo/providertx.h"
|
||||||
|
|
||||||
CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
|
CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
|
||||||
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
|
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
|
||||||
CAmount _inChainInputValue,
|
CAmount _inChainInputValue,
|
||||||
@ -438,6 +441,16 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
|
|||||||
vTxHashes.emplace_back(hash, newit);
|
vTxHashes.emplace_back(hash, newit);
|
||||||
newit->vTxHashesIdx = vTxHashes.size() - 1;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,6 +626,16 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
|
|||||||
} else
|
} else
|
||||||
vTxHashes.clear();
|
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();
|
totalTxSize -= it->GetTxSize();
|
||||||
cachedInnerUsage -= it->DynamicMemoryUsage();
|
cachedInnerUsage -= it->DynamicMemoryUsage();
|
||||||
cachedInnerUsage -= memusage::DynamicUsage(mapLinks[it].parents) + memusage::DynamicUsage(mapLinks[it].children);
|
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.
|
* 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);
|
RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK);
|
||||||
}
|
}
|
||||||
removeConflicts(*tx);
|
removeConflicts(*tx);
|
||||||
|
removeProTxConflicts(*tx);
|
||||||
ClearPrioritisation(tx->GetHash());
|
ClearPrioritisation(tx->GetHash());
|
||||||
}
|
}
|
||||||
lastRollingFeeUpdate = GetTime();
|
lastRollingFeeUpdate = GetTime();
|
||||||
@ -776,6 +830,8 @@ void CTxMemPool::_clear()
|
|||||||
mapLinks.clear();
|
mapLinks.clear();
|
||||||
mapTx.clear();
|
mapTx.clear();
|
||||||
mapNextTx.clear();
|
mapNextTx.clear();
|
||||||
|
mapProTxRegisterAddresses.clear();
|
||||||
|
mapProTxPubKeyIDs.clear();
|
||||||
totalTxSize = 0;
|
totalTxSize = 0;
|
||||||
cachedInnerUsage = 0;
|
cachedInnerUsage = 0;
|
||||||
lastRollingFeeUpdate = GetTime();
|
lastRollingFeeUpdate = GetTime();
|
||||||
@ -1013,6 +1069,16 @@ TxMempoolInfo CTxMemPool::info(const uint256& hash) const
|
|||||||
return GetInfo(i);
|
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
|
CFeeRate CTxMemPool::estimateFee(int nBlocks) const
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "primitives/transaction.h"
|
#include "primitives/transaction.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
#include "netaddress.h"
|
||||||
|
|
||||||
#undef foreach
|
#undef foreach
|
||||||
#include "boost/multi_index_container.hpp"
|
#include "boost/multi_index_container.hpp"
|
||||||
@ -534,6 +535,9 @@ private:
|
|||||||
typedef std::map<uint256, std::vector<CSpentIndexKey> > mapSpentIndexInserted;
|
typedef std::map<uint256, std::vector<CSpentIndexKey> > mapSpentIndexInserted;
|
||||||
mapSpentIndexInserted mapSpentInserted;
|
mapSpentIndexInserted mapSpentInserted;
|
||||||
|
|
||||||
|
std::map<CService, uint256> mapProTxRegisterAddresses;
|
||||||
|
std::map<CKeyID, uint256> mapProTxPubKeyIDs;
|
||||||
|
|
||||||
void UpdateParent(txiter entry, txiter parent, bool add);
|
void UpdateParent(txiter entry, txiter parent, bool add);
|
||||||
void UpdateChild(txiter entry, txiter child, 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 removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN);
|
||||||
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags);
|
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags);
|
||||||
void removeConflicts(const CTransaction &tx);
|
void removeConflicts(const CTransaction &tx);
|
||||||
|
void removeProTxConflicts(const CTransaction &tx);
|
||||||
void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight);
|
void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
@ -684,6 +689,8 @@ public:
|
|||||||
TxMempoolInfo info(const uint256& hash) const;
|
TxMempoolInfo info(const uint256& hash) const;
|
||||||
std::vector<TxMempoolInfo> infoAll() const;
|
std::vector<TxMempoolInfo> infoAll() const;
|
||||||
|
|
||||||
|
bool existsProviderTxConflict(const CTransaction &tx) const;
|
||||||
|
|
||||||
/** Estimate fee rate needed to get into the next nBlocks
|
/** Estimate fee rate needed to get into the next nBlocks
|
||||||
* If no answer can be given at nBlocks, return an estimate
|
* If no answer can be given at nBlocks, return an estimate
|
||||||
* at the lowest number of blocks where one can be given
|
* 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))
|
if (fRequireStandard && !IsStandardTx(tx, reason))
|
||||||
return state.DoS(0, false, REJECT_NONSTANDARD, 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
|
// 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
|
// block; we don't want our mempool filled up with transactions that can't
|
||||||
// be mined yet.
|
// be mined yet.
|
||||||
|
Loading…
Reference in New Issue
Block a user