@@ -75,7 +75,7 @@ uint64_t nPruneTarget = 0;
7575bool fAlerts = DEFAULT_ALERTS;
7676
7777/* * Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
78- CFeeRate minRelayTxFee = CFeeRate(5000 );
78+ CFeeRate minRelayTxFee = CFeeRate(1000 );
7979
8080CTxMemPool mempool (::minRelayTxFee);
8181
@@ -740,17 +740,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
740740 return true ;
741741}
742742
743- CAmount GetMinRelayFee (const CTransaction& tx, unsigned int nBytes, bool fAllowFree )
743+ CAmount GetMinRelayFee (const CTransaction& tx, const CTxMemPool& pool, unsigned int nBytes, bool fAllowFree )
744744{
745- {
746- LOCK (mempool.cs );
747- uint256 hash = tx.GetHash ();
748- double dPriorityDelta = 0 ;
749- CAmount nFeeDelta = 0 ;
750- mempool.ApplyDeltas (hash, dPriorityDelta, nFeeDelta);
751- if (dPriorityDelta > 0 || nFeeDelta > 0 )
752- return 0 ;
753- }
745+ uint256 hash = tx.GetHash ();
746+ double dPriorityDelta = 0 ;
747+ CAmount nFeeDelta = 0 ;
748+ pool.ApplyDeltas (hash, dPriorityDelta, nFeeDelta);
749+ if (dPriorityDelta > 0 || nFeeDelta > 0 )
750+ return 0 ;
754751
755752 CAmount nMinFee = ::minRelayTxFee.GetFee (nBytes);
756753
@@ -779,7 +776,7 @@ static std::string FormatStateMessage(const CValidationState &state)
779776}
780777
781778bool AcceptToMemoryPool (CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree ,
782- bool * pfMissingInputs, bool fRejectAbsurdFee )
779+ bool * pfMissingInputs, bool fOverrideMempoolLimit , bool fRejectAbsurdFee )
783780{
784781 AssertLockHeld (cs_main);
785782 if (pfMissingInputs)
@@ -879,17 +876,20 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
879876 CAmount nFees = nValueIn-nValueOut;
880877 double dPriority = view.GetPriority (tx, chainActive.Height ());
881878
882- CTxMemPoolEntry entry (tx, nFees, GetTime (), dPriority, chainActive.Height (), mempool .HasNoInputsOf (tx));
879+ CTxMemPoolEntry entry (tx, nFees, GetTime (), dPriority, chainActive.Height (), pool .HasNoInputsOf (tx));
883880 unsigned int nSize = entry.GetTxSize ();
884881
885882 // Don't accept it if it can't get into a block
886- CAmount txMinFee = GetMinRelayFee (tx, nSize, true );
883+ CAmount txMinFee = GetMinRelayFee (tx, pool, nSize, true );
887884 if (fLimitFree && nFees < txMinFee)
888885 return state.DoS (0 , false , REJECT_INSUFFICIENTFEE, " insufficient fee" , false ,
889886 strprintf (" %d < %d" , nFees, txMinFee));
890887
891- // Require that free transactions have sufficient priority to be mined in the next block.
892- if (GetBoolArg (" -relaypriority" , true ) && nFees < ::minRelayTxFee.GetFee (nSize) && !AllowFree (view.GetPriority (tx, chainActive.Height () + 1 ))) {
888+ CAmount mempoolRejectFee = pool.GetMinFee (GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 ).GetFee (nSize);
889+ if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
890+ return state.DoS (0 , false , REJECT_INSUFFICIENTFEE, " mempool min fee not met" , false , strprintf (" %d < %d" , nFees, mempoolRejectFee));
891+ } else if (GetBoolArg (" -relaypriority" , true ) && nFees < ::minRelayTxFee.GetFee (nSize) && !AllowFree (view.GetPriority (tx, chainActive.Height () + 1 ))) {
892+ // Require that free transactions have sufficient priority to be mined in the next block.
893893 return state.DoS (0 , false , REJECT_INSUFFICIENTFEE, " insufficient priority" );
894894 }
895895
@@ -954,6 +954,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
954954
955955 // Store transaction in memory
956956 pool.addUnchecked (hash, entry, setAncestors, !IsInitialBlockDownload ());
957+
958+ // trim mempool and check if tx was trimmed
959+ if (!fOverrideMempoolLimit ) {
960+ int expired = pool.Expire (GetTime () - GetArg (" -mempoolexpiry" , DEFAULT_MEMPOOL_EXPIRY) * 60 * 60 );
961+ if (expired != 0 )
962+ LogPrint (" mempool" , " Expired %i transactions from the memory pool\n " , expired);
963+
964+ pool.TrimToSize (GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 );
965+ if (!pool.exists (tx.GetHash ()))
966+ return state.DoS (0 , false , REJECT_INSUFFICIENTFEE, " mempool full" );
967+ }
957968 }
958969
959970 SyncWithWallets (tx, NULL );
@@ -2020,7 +2031,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
20202031 }
20212032}
20222033
2023- /* * Disconnect chainActive's tip. */
2034+ /* * Disconnect chainActive's tip. You want to manually re-limit mempool size after this */
20242035bool static DisconnectTip (CValidationState &state) {
20252036 CBlockIndex *pindexDelete = chainActive.Tip ();
20262037 assert (pindexDelete);
@@ -2047,7 +2058,7 @@ bool static DisconnectTip(CValidationState &state) {
20472058 // ignore validation errors in resurrected transactions
20482059 list<CTransaction> removed;
20492060 CValidationState stateDummy;
2050- if (tx.IsCoinBase () || !AcceptToMemoryPool (mempool, stateDummy, tx, false , NULL )) {
2061+ if (tx.IsCoinBase () || !AcceptToMemoryPool (mempool, stateDummy, tx, false , NULL , true )) {
20512062 mempool.remove (tx, removed, true );
20522063 } else if (mempool.exists (tx.GetHash ())) {
20532064 vHashUpdate.push_back (tx.GetHash ());
@@ -2220,9 +2231,11 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
22202231 const CBlockIndex *pindexFork = chainActive.FindFork (pindexMostWork);
22212232
22222233 // Disconnect active blocks which are no longer in the best chain.
2234+ bool fBlocksDisconnected = false ;
22232235 while (chainActive.Tip () && chainActive.Tip () != pindexFork) {
22242236 if (!DisconnectTip (state))
22252237 return false ;
2238+ fBlocksDisconnected = true ;
22262239 }
22272240
22282241 // Build list of new blocks to connect.
@@ -2268,6 +2281,9 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
22682281 }
22692282 }
22702283
2284+ if (fBlocksDisconnected )
2285+ mempool.TrimToSize (GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 );
2286+
22712287 // Callbacks/notifications for a new best chain.
22722288 if (fInvalidFound )
22732289 CheckForkWarningConditionsOnNewFork (vpindexToConnect.back ());
@@ -2354,6 +2370,8 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
23542370 }
23552371 }
23562372
2373+ mempool.TrimToSize (GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 );
2374+
23572375 // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
23582376 // add it again.
23592377 BlockMap::iterator it = mapBlockIndex.begin ();
@@ -4290,10 +4308,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
42904308 RelayTransaction (tx);
42914309 vWorkQueue.push_back (inv.hash );
42924310
4293- LogPrint (" mempool" , " AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u)\n " ,
4311+ LogPrint (" mempool" , " AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB )\n " ,
42944312 pfrom->id ,
42954313 tx.GetHash ().ToString (),
4296- mempool.size ());
4314+ mempool.size (), mempool. DynamicMemoryUsage () / 1000 );
42974315
42984316 // Recursively process any orphan transactions that depended on this one
42994317 set<NodeId> setMisbehaving;
0 commit comments