|
18 | 18 | #include <util/moneystr.h> |
19 | 19 | #include <util/system.h> |
20 | 20 | #include <util/time.h> |
21 | | -#include <validation.h> |
22 | 21 | #include <validationinterface.h> |
23 | 22 |
|
24 | 23 | #include <evo/specialtx.h> |
@@ -82,6 +81,24 @@ struct update_lock_points |
82 | 81 | const LockPoints& lp; |
83 | 82 | }; |
84 | 83 |
|
| 84 | +bool TestLockPointValidity(CChain& active_chain, const LockPoints* lp) |
| 85 | +{ |
| 86 | + AssertLockHeld(cs_main); |
| 87 | + assert(lp); |
| 88 | + // If there are relative lock times then the maxInputBlock will be set |
| 89 | + // If there are no relative lock times, the LockPoints don't depend on the chain |
| 90 | + if (lp->maxInputBlock) { |
| 91 | + // Check whether active_chain is an extension of the block at which the LockPoints |
| 92 | + // calculation was valid. If not LockPoints are no longer valid |
| 93 | + if (!active_chain.Contains(lp->maxInputBlock)) { |
| 94 | + return false; |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + // LockPoints still valid |
| 99 | + return true; |
| 100 | +} |
| 101 | + |
85 | 102 | CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee, |
86 | 103 | int64_t time, unsigned int entry_height, |
87 | 104 | bool spends_coinbase, int64_t sigops_count, LockPoints lp) |
@@ -859,44 +876,27 @@ void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReaso |
859 | 876 | RemoveStaged(setAllRemoves, false, reason); |
860 | 877 | } |
861 | 878 |
|
862 | | -void CTxMemPool::removeForReorg(CChainState& active_chainstate, int flags) EXCLUSIVE_LOCKS_REQUIRED(cs_main) |
| 879 | +void CTxMemPool::removeForReorg(CChain& chain, std::function<bool(txiter)> check_final_and_mature) EXCLUSIVE_LOCKS_REQUIRED(cs_main) |
863 | 880 | { |
864 | 881 | // Remove transactions spending a coinbase which are now immature and no-longer-final transactions |
865 | 882 | AssertLockHeld(cs); |
| 883 | + AssertLockHeld(::cs_main); |
| 884 | + |
866 | 885 | setEntries txToRemove; |
867 | 886 | for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { |
868 | | - const CTransaction& tx = it->GetTx(); |
869 | | - LockPoints lp = it->GetLockPoints(); |
870 | | - bool validLP = TestLockPointValidity(active_chainstate.m_chain, &lp); |
871 | | - CCoinsViewMemPool view_mempool(&active_chainstate.CoinsTip(), *this); |
872 | | - if (!CheckFinalTx(active_chainstate.m_chain.Tip(), tx, flags) |
873 | | - || !CheckSequenceLocks(active_chainstate.m_chain.Tip(), view_mempool, tx, flags, &lp, validLP)) { |
874 | | - // Note if CheckSequenceLocks fails the LockPoints may still be invalid |
875 | | - // So it's critical that we remove the tx and not depend on the LockPoints. |
876 | | - txToRemove.insert(it); |
877 | | - } else if (it->GetSpendsCoinbase()) { |
878 | | - for (const CTxIn& txin : tx.vin) { |
879 | | - indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); |
880 | | - if (it2 != mapTx.end()) |
881 | | - continue; |
882 | | - const Coin &coin = active_chainstate.CoinsTip().AccessCoin(txin.prevout); |
883 | | - if (m_check_ratio != 0) assert(!coin.IsSpent()); |
884 | | - unsigned int nMemPoolHeight = active_chainstate.m_chain.Tip()->nHeight + 1; |
885 | | - if (coin.IsSpent() || (coin.IsCoinBase() && ((signed long)nMemPoolHeight) - coin.nHeight < COINBASE_MATURITY)) { |
886 | | - txToRemove.insert(it); |
887 | | - break; |
888 | | - } |
889 | | - } |
890 | | - } |
891 | | - if (!validLP) { |
892 | | - mapTx.modify(it, update_lock_points(lp)); |
893 | | - } |
| 887 | + if (check_final_and_mature(it)) txToRemove.insert(it); |
894 | 888 | } |
895 | 889 | setEntries setAllRemoves; |
896 | 890 | for (txiter it : txToRemove) { |
897 | 891 | CalculateDescendants(it, setAllRemoves); |
898 | 892 | } |
899 | 893 | RemoveStaged(setAllRemoves, false, MemPoolRemovalReason::REORG); |
| 894 | + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { |
| 895 | + LockPoints lp = it->GetLockPoints(); |
| 896 | + if (!TestLockPointValidity(chain, &lp)) { |
| 897 | + mapTx.modify(it, update_lock_points(lp)); |
| 898 | + } |
| 899 | + } |
900 | 900 | } |
901 | 901 |
|
902 | 902 | void CTxMemPool::removeConflicts(const CTransaction &tx) |
|
0 commit comments