@@ -75,7 +75,7 @@ uint64_t nPruneTarget = 0;
75
75
bool fAlerts = DEFAULT_ALERTS;
76
76
77
77
/* * Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
78
- CFeeRate minRelayTxFee = CFeeRate(5000 );
78
+ CFeeRate minRelayTxFee = CFeeRate(1000 );
79
79
80
80
CTxMemPool mempool (::minRelayTxFee);
81
81
@@ -740,17 +740,14 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
740
740
return true ;
741
741
}
742
742
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 )
744
744
{
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 ;
754
751
755
752
CAmount nMinFee = ::minRelayTxFee.GetFee (nBytes);
756
753
@@ -779,7 +776,7 @@ static std::string FormatStateMessage(const CValidationState &state)
779
776
}
780
777
781
778
bool AcceptToMemoryPool (CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree ,
782
- bool * pfMissingInputs, bool fRejectAbsurdFee )
779
+ bool * pfMissingInputs, bool fOverrideMempoolLimit , bool fRejectAbsurdFee )
783
780
{
784
781
AssertLockHeld (cs_main);
785
782
if (pfMissingInputs)
@@ -879,17 +876,20 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
879
876
CAmount nFees = nValueIn-nValueOut;
880
877
double dPriority = view.GetPriority (tx, chainActive.Height ());
881
878
882
- CTxMemPoolEntry entry (tx, nFees, GetTime (), dPriority, chainActive.Height (), mempool .HasNoInputsOf (tx));
879
+ CTxMemPoolEntry entry (tx, nFees, GetTime (), dPriority, chainActive.Height (), pool .HasNoInputsOf (tx));
883
880
unsigned int nSize = entry.GetTxSize ();
884
881
885
882
// 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 );
887
884
if (fLimitFree && nFees < txMinFee)
888
885
return state.DoS (0 , false , REJECT_INSUFFICIENTFEE, " insufficient fee" , false ,
889
886
strprintf (" %d < %d" , nFees, txMinFee));
890
887
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.
893
893
return state.DoS (0 , false , REJECT_INSUFFICIENTFEE, " insufficient priority" );
894
894
}
895
895
@@ -954,6 +954,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
954
954
955
955
// Store transaction in memory
956
956
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
+ }
957
968
}
958
969
959
970
SyncWithWallets (tx, NULL );
@@ -2020,7 +2031,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
2020
2031
}
2021
2032
}
2022
2033
2023
- /* * Disconnect chainActive's tip. */
2034
+ /* * Disconnect chainActive's tip. You want to manually re-limit mempool size after this */
2024
2035
bool static DisconnectTip (CValidationState &state) {
2025
2036
CBlockIndex *pindexDelete = chainActive.Tip ();
2026
2037
assert (pindexDelete);
@@ -2047,7 +2058,7 @@ bool static DisconnectTip(CValidationState &state) {
2047
2058
// ignore validation errors in resurrected transactions
2048
2059
list<CTransaction> removed;
2049
2060
CValidationState stateDummy;
2050
- if (tx.IsCoinBase () || !AcceptToMemoryPool (mempool, stateDummy, tx, false , NULL )) {
2061
+ if (tx.IsCoinBase () || !AcceptToMemoryPool (mempool, stateDummy, tx, false , NULL , true )) {
2051
2062
mempool.remove (tx, removed, true );
2052
2063
} else if (mempool.exists (tx.GetHash ())) {
2053
2064
vHashUpdate.push_back (tx.GetHash ());
@@ -2220,9 +2231,11 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
2220
2231
const CBlockIndex *pindexFork = chainActive.FindFork (pindexMostWork);
2221
2232
2222
2233
// Disconnect active blocks which are no longer in the best chain.
2234
+ bool fBlocksDisconnected = false ;
2223
2235
while (chainActive.Tip () && chainActive.Tip () != pindexFork) {
2224
2236
if (!DisconnectTip (state))
2225
2237
return false ;
2238
+ fBlocksDisconnected = true ;
2226
2239
}
2227
2240
2228
2241
// Build list of new blocks to connect.
@@ -2268,6 +2281,9 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
2268
2281
}
2269
2282
}
2270
2283
2284
+ if (fBlocksDisconnected )
2285
+ mempool.TrimToSize (GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 );
2286
+
2271
2287
// Callbacks/notifications for a new best chain.
2272
2288
if (fInvalidFound )
2273
2289
CheckForkWarningConditionsOnNewFork (vpindexToConnect.back ());
@@ -2354,6 +2370,8 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
2354
2370
}
2355
2371
}
2356
2372
2373
+ mempool.TrimToSize (GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 );
2374
+
2357
2375
// The resulting new best tip may not be in setBlockIndexCandidates anymore, so
2358
2376
// add it again.
2359
2377
BlockMap::iterator it = mapBlockIndex.begin ();
@@ -4290,10 +4308,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
4290
4308
RelayTransaction (tx);
4291
4309
vWorkQueue.push_back (inv.hash );
4292
4310
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 " ,
4294
4312
pfrom->id ,
4295
4313
tx.GetHash ().ToString (),
4296
- mempool.size ());
4314
+ mempool.size (), mempool. DynamicMemoryUsage () / 1000 );
4297
4315
4298
4316
// Recursively process any orphan transactions that depended on this one
4299
4317
set<NodeId> setMisbehaving;
0 commit comments