* Called when a block is connected. Removes from mempool and updates the miner fee estimator. */
| 712 | * Called when a block is connected. Removes from mempool and updates the miner fee estimator. |
| 713 | */ |
| 714 | void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight, const CBlockIndex* p_block_index_new) |
| 715 | { |
| 716 | AssertLockHeld(cs); |
| 717 | std::vector<const CTxMemPoolEntry*> entries; |
| 718 | for (const auto& tx : vtx) |
| 719 | { |
| 720 | uint256 hash = tx->GetHash(); |
| 721 | |
| 722 | indexed_transaction_set::iterator i = mapTx.find(hash); |
| 723 | if (i != mapTx.end()) |
| 724 | entries.push_back(&*i); |
| 725 | } |
| 726 | // Before the txs in the new block have been removed from the mempool, update policy estimates |
| 727 | if (minerPolicyEstimator) {minerPolicyEstimator->processBlock(nBlockHeight, entries);} |
| 728 | for (const auto& tx : vtx) |
| 729 | { |
| 730 | txiter it = mapTx.find(tx->GetHash()); |
| 731 | if (it != mapTx.end()) { |
| 732 | setEntries stage; |
| 733 | stage.insert(it); |
| 734 | RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK); |
| 735 | } |
| 736 | removeConflicts(*tx); |
| 737 | ClearPrioritisation(tx->GetHash()); |
| 738 | } |
| 739 | |
| 740 | // Eject transactions that are invalid for *following* block due to transition |
| 741 | // We check every epoch_length blocks due to peg-ins expiring an epoch after |
| 742 | // being changed |
| 743 | if (p_block_index_new) { |
| 744 | const CChainParams& chainparams = Params(); |
| 745 | uint32_t epoch_length = chainparams.GetConsensus().dynamic_epoch_length; |
| 746 | if ((p_block_index_new->nHeight+1) % epoch_length == 0) { |
| 747 | CPAKList enforced_paklist = GetActivePAKList(p_block_index_new, chainparams.GetConsensus()); |
| 748 | std::vector<CTransactionRef> tx_to_remove; |
| 749 | for (const auto& entry : mapTx) { |
| 750 | const CTransaction& tx = entry.GetTx(); |
| 751 | if (chainparams.GetEnforcePak() && !IsPAKValidTx(tx, enforced_paklist, chainparams.ParentGenesisBlockHash(), chainparams.GetConsensus().pegged_asset)) { |
| 752 | tx_to_remove.push_back(MakeTransactionRef(tx)); |
| 753 | continue; |
| 754 | } |
| 755 | |
| 756 | const auto& fedpegscripts = GetValidFedpegScripts(p_block_index_new, chainparams.GetConsensus(), true /* nextblock_validation */); |
| 757 | for (size_t nIn = 0; nIn < tx.vin.size(); nIn++) { |
| 758 | const CTxIn& in = tx.vin[nIn]; |
| 759 | std::string err; |
| 760 | if (in.m_is_pegin && (!tx.HasWitness() || !IsValidPeginWitness(tx.witness.vtxinwit[nIn].m_pegin_witness, fedpegscripts, in.prevout, err, true /* check_depth */))) { |
| 761 | tx_to_remove.push_back(MakeTransactionRef(tx)); |
| 762 | break; |
| 763 | } |
| 764 | } |
| 765 | } |
| 766 | for (auto& tx : tx_to_remove) { |
| 767 | const uint256 tx_id = tx->GetHash(); |
| 768 | removeRecursive(*tx, MemPoolRemovalReason::BLOCK); |
| 769 | ClearPrioritisation(tx_id); |
| 770 | } |
| 771 | } |