Browse Source

Only call TrimToSize once per reorg/blocks disconnect

0.13
Matt Corallo 9 years ago
parent
commit
d355cf4420
  1. 27
      src/main.cpp
  2. 2
      src/main.h
  3. 2
      src/rpcrawtransaction.cpp
  4. 2
      src/test/txvalidationcache_tests.cpp
  5. 2
      src/wallet/wallet.cpp

27
src/main.cpp

@ -776,7 +776,7 @@ static std::string FormatStateMessage(const CValidationState &state)
} }
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
bool* pfMissingInputs, bool fRejectAbsurdFee) bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
if (pfMissingInputs) if (pfMissingInputs)
@ -956,13 +956,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload()); pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload());
// trim mempool and check if tx was trimmed // trim mempool and check if tx was trimmed
int expired = pool.Expire(GetTime() - GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); if (!fOverrideMempoolLimit) {
if (expired != 0) int expired = pool.Expire(GetTime() - GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired); if (expired != 0)
LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
pool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); pool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
if (!pool.exists(tx.GetHash())) if (!pool.exists(tx.GetHash()))
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full"); return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full");
}
} }
SyncWithWallets(tx, NULL); SyncWithWallets(tx, NULL);
@ -2029,7 +2031,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
} }
} }
/** Disconnect chainActive's tip. */ /** Disconnect chainActive's tip. You want to manually re-limit mempool size after this */
bool static DisconnectTip(CValidationState &state) { bool static DisconnectTip(CValidationState &state) {
CBlockIndex *pindexDelete = chainActive.Tip(); CBlockIndex *pindexDelete = chainActive.Tip();
assert(pindexDelete); assert(pindexDelete);
@ -2056,7 +2058,7 @@ bool static DisconnectTip(CValidationState &state) {
// ignore validation errors in resurrected transactions // ignore validation errors in resurrected transactions
list<CTransaction> removed; list<CTransaction> removed;
CValidationState stateDummy; CValidationState stateDummy;
if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) { if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) {
mempool.remove(tx, removed, true); mempool.remove(tx, removed, true);
} else if (mempool.exists(tx.GetHash())) { } else if (mempool.exists(tx.GetHash())) {
vHashUpdate.push_back(tx.GetHash()); vHashUpdate.push_back(tx.GetHash());
@ -2229,9 +2231,11 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork); const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
// Disconnect active blocks which are no longer in the best chain. // Disconnect active blocks which are no longer in the best chain.
bool fBlocksDisconnected = false;
while (chainActive.Tip() && chainActive.Tip() != pindexFork) { while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
if (!DisconnectTip(state)) if (!DisconnectTip(state))
return false; return false;
fBlocksDisconnected = true;
} }
// Build list of new blocks to connect. // Build list of new blocks to connect.
@ -2277,6 +2281,9 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
} }
} }
if (fBlocksDisconnected)
mempool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
// Callbacks/notifications for a new best chain. // Callbacks/notifications for a new best chain.
if (fInvalidFound) if (fInvalidFound)
CheckForkWarningConditionsOnNewFork(vpindexToConnect.back()); CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
@ -2363,6 +2370,8 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
} }
} }
mempool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
// The resulting new best tip may not be in setBlockIndexCandidates anymore, so // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
// add it again. // add it again.
BlockMap::iterator it = mapBlockIndex.begin(); BlockMap::iterator it = mapBlockIndex.begin();

2
src/main.h

@ -229,7 +229,7 @@ void PruneAndFlush();
/** (try to) add transaction to memory pool **/ /** (try to) add transaction to memory pool **/
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
bool* pfMissingInputs, bool fRejectAbsurdFee=false); bool* pfMissingInputs, bool fOverrideMempoolLimit=false, bool fRejectAbsurdFee=false);
struct CNodeStateStats { struct CNodeStateStats {

2
src/rpcrawtransaction.cpp

@ -809,7 +809,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp)
// push to local node and sync with wallets // push to local node and sync with wallets
CValidationState state; CValidationState state;
bool fMissingInputs; bool fMissingInputs;
if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) { if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, false, !fOverrideFees)) {
if (state.IsInvalid()) { if (state.IsInvalid()) {
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
} else { } else {

2
src/test/txvalidationcache_tests.cpp

@ -23,7 +23,7 @@ ToMemPool(CMutableTransaction& tx)
LOCK(cs_main); LOCK(cs_main);
CValidationState state; CValidationState state;
return AcceptToMemoryPool(mempool, state, tx, false, NULL, false); return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, false);
} }
BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)

2
src/wallet/wallet.cpp

@ -2863,6 +2863,6 @@ int CMerkleTx::GetBlocksToMaturity() const
bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
{ {
CValidationState state; CValidationState state;
return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee); return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, fRejectAbsurdFee);
} }

Loading…
Cancel
Save