/** 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)
            {
                MapNextTx.Remove(MapNextTx.FirstOrDefault(w => w.OutPoint == txin.PrevOut));
            }

            if (vTxHashes.Any())
            {
                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();

            totalTxSize      -= it.GetTxSize();
            cachedInnerUsage -= it.DynamicMemoryUsage();
            cachedInnerUsage -= mapLinks[it]?.Parents?.Sum(p => p.DynamicMemoryUsage()) ?? 0 + mapLinks[it]?.Children?.Sum(p => p.DynamicMemoryUsage()) ?? 0;
            mapLinks.Remove(it);
            MapTx.Remove(it);
            nTransactionsUpdated++;
            MinerPolicyEstimator.RemoveTx(hash);
        }
        /**
         * Called when a block is connected. Removes from mempool and updates the miner fee estimator.
         */

        public void RemoveForBlock(IEnumerable <Transaction> vtx, int blockHeight)
        {
            var entries = new List <TxMempoolEntry>();

            foreach (var tx in vtx)
            {
                uint256 hash  = tx.GetHash();
                var     entry = this.MapTx.TryGet(hash);
                if (entry != null)
                {
                    entries.Add(entry);
                }
            }

            // Before the txs in the new block have been removed from the mempool, update policy estimates
            MinerPolicyEstimator.ProcessBlock(blockHeight, entries);
            foreach (var tx in vtx)
            {
                uint256 hash = tx.GetHash();

                var entry = this.MapTx.TryGet(hash);
                if (entry != null)
                {
                    SetEntries stage = new SetEntries();
                    stage.Add(entry);
                    RemoveStaged(stage, true);
                }

                RemoveConflicts(tx);
                ClearPrioritisation(tx.GetHash());
            }
            lastRollingFeeUpdate         = this.TimeProvider.GetTime();
            blockSinceLastRollingFeeBump = true;
        }