Use txgraph to calculate ancestors
This commit is contained in:
1 parent
241a3e666b
commit
c8b6f70d64
4 files changed
+35
-65
No files matched your search
+1
-1
@@ -39,7 +39,7 @@ RBFTransactionState IsRBFOptIn(const CTransaction& tx, const CTxMemPool& pool)
|
|||||||
// If all the inputs have nSequence >= maxint-1, it still might be
|
// If all the inputs have nSequence >= maxint-1, it still might be
|
||||||
// signaled for RBF if any unconfirmed parents have signaled.
|
// signaled for RBF if any unconfirmed parents have signaled.
|
||||||
const auto& entry{*Assert(pool.GetEntry(tx.GetHash()))};
|
const auto& entry{*Assert(pool.GetEntry(tx.GetHash()))};
|
||||||
auto ancestors{pool.CalculateMemPoolAncestors(entry, /*fSearchForParents=*/false)};
|
auto ancestors{pool.CalculateMemPoolAncestors(entry)};
|
||||||
|
|
||||||
for (CTxMemPool::txiter it : ancestors) {
|
for (CTxMemPool::txiter it : ancestors) {
|
||||||
if (SignalsOptInRBF(it->GetTx())) {
|
if (SignalsOptInRBF(it->GetTx())) {
|
||||||
|
|||||||
+1
-1
@@ -474,7 +474,7 @@ static RPCHelpMan getmempoolancestors()
|
|||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ancestors{mempool.CalculateMemPoolAncestors(*entry, /*fSearchForParents=*/false)};
|
auto ancestors{mempool.CalculateMemPoolAncestors(*entry)};
|
||||||
|
|
||||||
if (!fVerbose) {
|
if (!fVerbose) {
|
||||||
UniValue o(UniValue::VARR);
|
UniValue o(UniValue::VARR);
|
||||||
|
|||||||
+31
-45
@@ -99,31 +99,6 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<Txid>& vHashesToU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxMemPool::setEntries CTxMemPool::CalculateAncestors(CTxMemPoolEntry::Parents& staged_ancestors) const
|
|
||||||
{
|
|
||||||
setEntries ancestors;
|
|
||||||
|
|
||||||
while (!staged_ancestors.empty()) {
|
|
||||||
const CTxMemPoolEntry& stage = staged_ancestors.begin()->get();
|
|
||||||
txiter stageit = mapTx.iterator_to(stage);
|
|
||||||
|
|
||||||
ancestors.insert(stageit);
|
|
||||||
staged_ancestors.erase(stage);
|
|
||||||
|
|
||||||
const CTxMemPoolEntry::Parents& parents = stageit->GetMemPoolParentsConst();
|
|
||||||
for (const CTxMemPoolEntry& parent : parents) {
|
|
||||||
txiter parent_it = mapTx.iterator_to(parent);
|
|
||||||
|
|
||||||
// If this is a new ancestor, add it.
|
|
||||||
if (ancestors.count(parent_it) == 0) {
|
|
||||||
staged_ancestors.insert(parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ancestors;
|
|
||||||
}
|
|
||||||
|
|
||||||
util::Result<void> CTxMemPool::CheckPackageLimits(const Package& package,
|
util::Result<void> CTxMemPool::CheckPackageLimits(const Package& package,
|
||||||
const int64_t total_vsize) const
|
const int64_t total_vsize) const
|
||||||
{
|
{
|
||||||
@@ -138,31 +113,42 @@ bool CTxMemPool::HasDescendants(const Txid& txid) const
|
|||||||
return m_txgraph->GetDescendants(*entry, TxGraph::Level::MAIN).size() > 1;
|
return m_txgraph->GetDescendants(*entry, TxGraph::Level::MAIN).size() > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxMemPool::setEntries CTxMemPool::CalculateMemPoolAncestors(
|
CTxMemPool::setEntries CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry) const
|
||||||
const CTxMemPoolEntry &entry,
|
|
||||||
bool fSearchForParents /* = true */) const
|
|
||||||
{
|
{
|
||||||
CTxMemPoolEntry::Parents staged_ancestors;
|
auto ancestors = m_txgraph->GetAncestors(entry, TxGraph::Level::MAIN);
|
||||||
const CTransaction &tx = entry.GetTx();
|
setEntries ret;
|
||||||
|
if (ancestors.size() > 0) {
|
||||||
if (fSearchForParents) {
|
for (auto ancestor : ancestors) {
|
||||||
// Get parents of this transaction that are in the mempool
|
if (ancestor != &entry) {
|
||||||
// GetMemPoolParents() is only valid for entries in the mempool, so we
|
ret.insert(mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*ancestor)));
|
||||||
// iterate mapTx to find parents.
|
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
|
||||||
std::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash);
|
|
||||||
if (piter) {
|
|
||||||
staged_ancestors.insert(**piter);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
return ret;
|
||||||
// If we're not searching for parents, we require this to already be an
|
|
||||||
// entry in the mempool and use the entry's cached parents.
|
|
||||||
txiter it = mapTx.iterator_to(entry);
|
|
||||||
staged_ancestors = it->GetMemPoolParentsConst();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CalculateAncestors(staged_ancestors);
|
// If we didn't get anything back, the transaction is not in the graph.
|
||||||
|
// Find each parent and call GetAncestors on each.
|
||||||
|
setEntries staged_parents;
|
||||||
|
const CTransaction &tx = entry.GetTx();
|
||||||
|
|
||||||
|
// Get parents of this transaction that are in the mempool
|
||||||
|
// GetMemPoolParents() is only valid for entries in the mempool, so we
|
||||||
|
// iterate mapTx to find parents.
|
||||||
|
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
||||||
|
std::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash);
|
||||||
|
if (piter) {
|
||||||
|
staged_parents.insert(*piter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& parent : staged_parents) {
|
||||||
|
auto parent_ancestors = m_txgraph->GetAncestors(*parent, TxGraph::Level::MAIN);
|
||||||
|
for (auto ancestor : parent_ancestors) {
|
||||||
|
ret.insert(mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*ancestor)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTxMemPool::UpdateAncestorsOf(bool add, txiter it)
|
void CTxMemPool::UpdateAncestorsOf(bool add, txiter it)
|
||||||
|
|||||||
+2
-18
@@ -304,17 +304,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
std::set<Txid> m_unbroadcast_txids GUARDED_BY(cs);
|
std::set<Txid> m_unbroadcast_txids GUARDED_BY(cs);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to calculate all in-mempool ancestors of staged_ancestors
|
|
||||||
*
|
|
||||||
* @param[in] staged_ancestors Should contain entries in the mempool.
|
|
||||||
*
|
|
||||||
* @return all in-mempool ancestors
|
|
||||||
*/
|
|
||||||
setEntries CalculateAncestors(CTxMemPoolEntry::Parents &staged_ancestors)
|
|
||||||
const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
|
||||||
|
|
||||||
static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
|
static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
|
||||||
{
|
{
|
||||||
return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
|
return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
|
||||||
@@ -429,18 +418,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate all in-mempool ancestors of entry.
|
* Calculate all in-mempool ancestors of entry (not including the tx itself)
|
||||||
* (these are all calculated including the tx itself)
|
|
||||||
*
|
*
|
||||||
* @param[in] entry CTxMemPoolEntry of which all in-mempool ancestors are calculated
|
* @param[in] entry CTxMemPoolEntry of which all in-mempool ancestors are calculated
|
||||||
* @param[in] fSearchForParents Whether to search a tx's vin for in-mempool parents, or look
|
|
||||||
* up parents from mapLinks. Must be true for entries not in
|
|
||||||
* the mempool
|
|
||||||
*
|
*
|
||||||
* @return all in-mempool ancestors
|
* @return all in-mempool ancestors
|
||||||
*/
|
*/
|
||||||
setEntries CalculateMemPoolAncestors(const CTxMemPoolEntry& entry,
|
setEntries CalculateMemPoolAncestors(const CTxMemPoolEntry& entry) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||||
bool fSearchForParents = true) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
|
||||||
|
|
||||||
bool HasDescendants(const Txid& txid) const;
|
bool HasDescendants(const Txid& txid) const;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user