private void UpdateChild(TxMempoolEntry entry, TxMempoolEntry child, bool add) { // todo: find how to take a memory size of SetEntries //setEntries s; if (add && this.mapLinks[entry].Children.Add(child)) { this.cachedInnerUsage += child.DynamicMemoryUsage(); } else if (!add && this.mapLinks[entry].Children.Remove(child)) { this.cachedInnerUsage -= child.DynamicMemoryUsage(); } }
private void UpdateParent(TxMempoolEntry entry, TxMempoolEntry parent, bool add) { // todo: find how to take a memory size of SetEntries //SetEntries s; if (add && this.mapLinks[entry].Parents.Add(parent)) { this.cachedInnerUsage += parent.DynamicMemoryUsage(); } else if (!add && this.mapLinks[entry].Parents.Remove(parent)) { this.cachedInnerUsage -= parent.DynamicMemoryUsage(); } }
/** Before calling removeUnchecked for a given transaction, * UpdateForRemoveFromMempool must be called on the entire (dependent) set * of transactions being removed at the same time. We use each * CTxMemPoolEntry's setMemPoolParents in order to walk ancestors of a * given transaction that is removed, so we can't remove intermediate * transactions in a chain before we've updated all the state for the * removal. */ private void RemoveUnchecked(TxMempoolEntry it) { var hash = it.TransactionHash; foreach (var txin in it.Transaction.Inputs) { this.MapNextTx.Remove(this.MapNextTx.FirstOrDefault(w => w.OutPoint == txin.PrevOut)); } if (this.vTxHashes.Any()) { this.vTxHashes.Remove(it); //vTxHashes[it] = std::move(vTxHashes.back()); //vTxHashes[it].second->vTxHashesIdx = it->vTxHashesIdx; //vTxHashes.pop_back(); //if (vTxHashes.size() * 2 < vTxHashes.capacity()) // vTxHashes.shrink_to_fit(); } //else // vTxHashes.clear(); this.totalTxSize -= it.GetTxSize(); this.cachedInnerUsage -= it.DynamicMemoryUsage(); this.cachedInnerUsage -= this.mapLinks[it]?.Parents?.Sum(p => p.DynamicMemoryUsage()) ?? 0 + this.mapLinks[it]?.Children?.Sum(p => p.DynamicMemoryUsage()) ?? 0; this.mapLinks.Remove(it); this.MapTx.Remove(it); this.nTransactionsUpdated++; this.MinerPolicyEstimator.RemoveTx(hash); }
public bool AddUnchecked(uint256 hash, TxMempoolEntry entry, SetEntries setAncestors, bool validFeeEstimate = true) { // Add to memory pool without checking anything. // Used by main.cpp AcceptToMemoryPool(), which DOES do // all the appropriate checks. //LOCK(cs); this.MapTx.Add(entry); this.mapLinks.Add(entry, new TxLinks { Parents = new SetEntries(), Children = new SetEntries() }); // Update transaction for any feeDelta created by PrioritiseTransaction // TODO: refactor so that the fee delta is calculated before inserting // into mapTx. var pos = this.mapDeltas.TryGet(hash); if (pos != null) { if (pos.Amount != null) { entry.UpdateFeeDelta(pos.Amount.Satoshi); } } // Update cachedInnerUsage to include contained transaction's usage. // (When we update the entry for in-mempool parents, memory usage will be // further updated.) this.cachedInnerUsage += entry.DynamicMemoryUsage(); var tx = entry.Transaction; HashSet <uint256> setParentTransactions = new HashSet <uint256>(); foreach (var txInput in tx.Inputs) { this.MapNextTx.Add(new NextTxPair { OutPoint = txInput.PrevOut, Transaction = tx }); setParentTransactions.Add(txInput.PrevOut.Hash); } // Don't bother worrying about child transactions of this one. // Normal case of a new transaction arriving is that there can't be any // children, because such children would be orphans. // An exception to that is if a transaction enters that used to be in a block. // In that case, our disconnect block logic will call UpdateTransactionsFromBlock // to clean up the mess we're leaving here. // Update ancestors with information about this tx foreach (var phash in setParentTransactions) { var pit = this.MapTx.TryGet(phash); if (pit != null) { this.UpdateParent(entry, pit, true); } } this.UpdateAncestorsOf(true, entry, setAncestors); this.UpdateEntryForAncestors(entry, setAncestors); this.nTransactionsUpdated++; this.totalTxSize += entry.GetTxSize(); this.MinerPolicyEstimator.ProcessTransaction(entry, validFeeEstimate); this.vTxHashes.Add(entry, tx.GetWitHash()); //entry.vTxHashesIdx = vTxHashes.size() - 1; return(true); }