mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-15 11:36:00 -05:00
tx pool: Use class methods to hide raw map iterator impl details
This commit is contained in:
parent
4799b0932a
commit
faa1a74942
3 changed files with 46 additions and 29 deletions
|
@ -156,9 +156,9 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntr
|
||||||
// GetMemPoolParents() is only valid for entries in the mempool, so we
|
// GetMemPoolParents() is only valid for entries in the mempool, so we
|
||||||
// iterate mapTx to find parents.
|
// iterate mapTx to find parents.
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
||||||
txiter piter = mapTx.find(tx.vin[i].prevout.hash);
|
boost::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash);
|
||||||
if (piter != mapTx.end()) {
|
if (piter) {
|
||||||
parentHashes.insert(piter);
|
parentHashes.insert(*piter);
|
||||||
if (parentHashes.size() + 1 > limitAncestorCount) {
|
if (parentHashes.size() + 1 > limitAncestorCount) {
|
||||||
errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
|
errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
|
||||||
return false;
|
return false;
|
||||||
|
@ -364,13 +364,11 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
|
||||||
// Update transaction for any feeDelta created by PrioritiseTransaction
|
// Update transaction for any feeDelta created by PrioritiseTransaction
|
||||||
// TODO: refactor so that the fee delta is calculated before inserting
|
// TODO: refactor so that the fee delta is calculated before inserting
|
||||||
// into mapTx.
|
// into mapTx.
|
||||||
std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(entry.GetTx().GetHash());
|
CAmount delta{0};
|
||||||
if (pos != mapDeltas.end()) {
|
ApplyDelta(entry.GetTx().GetHash(), delta);
|
||||||
const CAmount &delta = pos->second;
|
|
||||||
if (delta) {
|
if (delta) {
|
||||||
mapTx.modify(newit, update_fee_delta(delta));
|
mapTx.modify(newit, update_fee_delta(delta));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Update cachedInnerUsage to include contained transaction's usage.
|
// Update cachedInnerUsage to include contained transaction's usage.
|
||||||
// (When we update the entry for in-mempool parents, memory usage will be
|
// (When we update the entry for in-mempool parents, memory usage will be
|
||||||
|
@ -391,12 +389,9 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
|
||||||
// to clean up the mess we're leaving here.
|
// to clean up the mess we're leaving here.
|
||||||
|
|
||||||
// Update ancestors with information about this tx
|
// Update ancestors with information about this tx
|
||||||
for (const uint256 &phash : setParentTransactions) {
|
for (const auto& pit : GetIterSet(setParentTransactions)) {
|
||||||
txiter pit = mapTx.find(phash);
|
|
||||||
if (pit != mapTx.end()) {
|
|
||||||
UpdateParent(newit, pit, true);
|
UpdateParent(newit, pit, true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
UpdateAncestorsOf(true, newit, setAncestors);
|
UpdateAncestorsOf(true, newit, setAncestors);
|
||||||
UpdateEntryForAncestors(newit, setAncestors);
|
UpdateEntryForAncestors(newit, setAncestors);
|
||||||
|
|
||||||
|
@ -864,6 +859,29 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash)
|
||||||
mapDeltas.erase(hash);
|
mapDeltas.erase(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const
|
||||||
|
{
|
||||||
|
const auto it = mapNextTx.find(prevout);
|
||||||
|
return it == mapNextTx.end() ? nullptr : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const uint256& txid) const
|
||||||
|
{
|
||||||
|
auto it = mapTx.find(txid);
|
||||||
|
if (it != mapTx.end()) return it;
|
||||||
|
return boost::optional<txiter>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set<uint256>& hashes) const
|
||||||
|
{
|
||||||
|
CTxMemPool::setEntries ret;
|
||||||
|
for (const auto& h : hashes) {
|
||||||
|
const auto mi = GetIter(h);
|
||||||
|
if (mi) ret.insert(*mi);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
|
bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
||||||
|
|
|
@ -566,7 +566,15 @@ public:
|
||||||
void ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const;
|
void ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const;
|
||||||
void ClearPrioritisation(const uint256 hash);
|
void ClearPrioritisation(const uint256 hash);
|
||||||
|
|
||||||
public:
|
/** Get the transaction in the pool that spends the same prevout */
|
||||||
|
const CTransaction* GetConflictTx(const COutPoint& prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||||
|
|
||||||
|
/** Returns an iterator to the given hash, if found */
|
||||||
|
boost::optional<txiter> GetIter(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||||
|
|
||||||
|
/** Translate a set of hashes into a set of pool iterators to avoid repeated lookups */
|
||||||
|
setEntries GetIterSet(const std::set<uint256>& hashes) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||||
|
|
||||||
/** Remove a set of transactions from the mempool.
|
/** Remove a set of transactions from the mempool.
|
||||||
* If a transaction is in this set, then all in-mempool descendants must
|
* If a transaction is in this set, then all in-mempool descendants must
|
||||||
* also be in the set, unless this transaction is being removed for being
|
* also be in the set, unless this transaction is being removed for being
|
||||||
|
@ -639,7 +647,7 @@ public:
|
||||||
return totalTxSize;
|
return totalTxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exists(uint256 hash) const
|
bool exists(const uint256& hash) const
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
return (mapTx.count(hash) != 0);
|
return (mapTx.count(hash) != 0);
|
||||||
|
|
|
@ -602,10 +602,8 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
||||||
std::set<uint256> setConflicts;
|
std::set<uint256> setConflicts;
|
||||||
for (const CTxIn &txin : tx.vin)
|
for (const CTxIn &txin : tx.vin)
|
||||||
{
|
{
|
||||||
auto itConflicting = pool.mapNextTx.find(txin.prevout);
|
const CTransaction* ptxConflicting = pool.GetConflictTx(txin.prevout);
|
||||||
if (itConflicting != pool.mapNextTx.end())
|
if (ptxConflicting) {
|
||||||
{
|
|
||||||
const CTransaction *ptxConflicting = itConflicting->second;
|
|
||||||
if (!setConflicts.count(ptxConflicting->GetHash()))
|
if (!setConflicts.count(ptxConflicting->GetHash()))
|
||||||
{
|
{
|
||||||
// Allow opt-out of transaction replacement by setting
|
// Allow opt-out of transaction replacement by setting
|
||||||
|
@ -786,16 +784,8 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
||||||
CFeeRate newFeeRate(nModifiedFees, nSize);
|
CFeeRate newFeeRate(nModifiedFees, nSize);
|
||||||
std::set<uint256> setConflictsParents;
|
std::set<uint256> setConflictsParents;
|
||||||
const int maxDescendantsToVisit = 100;
|
const int maxDescendantsToVisit = 100;
|
||||||
CTxMemPool::setEntries setIterConflicting;
|
const CTxMemPool::setEntries setIterConflicting = pool.GetIterSet(setConflicts);
|
||||||
for (const uint256 &hashConflicting : setConflicts)
|
for (const auto& mi : setIterConflicting) {
|
||||||
{
|
|
||||||
CTxMemPool::txiter mi = pool.mapTx.find(hashConflicting);
|
|
||||||
if (mi == pool.mapTx.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Save these to avoid repeated lookups
|
|
||||||
setIterConflicting.insert(mi);
|
|
||||||
|
|
||||||
// Don't allow the replacement to reduce the feerate of the
|
// Don't allow the replacement to reduce the feerate of the
|
||||||
// mempool.
|
// mempool.
|
||||||
//
|
//
|
||||||
|
@ -861,13 +851,14 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
||||||
// Rather than check the UTXO set - potentially expensive -
|
// Rather than check the UTXO set - potentially expensive -
|
||||||
// it's cheaper to just check if the new input refers to a
|
// it's cheaper to just check if the new input refers to a
|
||||||
// tx that's in the mempool.
|
// tx that's in the mempool.
|
||||||
if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end())
|
if (pool.exists(tx.vin[j].prevout.hash)) {
|
||||||
return state.DoS(0, false,
|
return state.DoS(0, false,
|
||||||
REJECT_NONSTANDARD, "replacement-adds-unconfirmed", false,
|
REJECT_NONSTANDARD, "replacement-adds-unconfirmed", false,
|
||||||
strprintf("replacement %s adds unconfirmed input, idx %d",
|
strprintf("replacement %s adds unconfirmed input, idx %d",
|
||||||
hash.ToString(), j));
|
hash.ToString(), j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The replacement must pay greater fees than the transactions it
|
// The replacement must pay greater fees than the transactions it
|
||||||
// replaces - if we did the bandwidth used by those conflicting
|
// replaces - if we did the bandwidth used by those conflicting
|
||||||
|
|
Loading…
Add table
Reference in a new issue