7
7
8
8
#include " addrman.h"
9
9
#include " alert.h"
10
- #include " bloom.h"
11
10
#include " chainparams.h"
12
11
#include " checkpoints.h"
13
12
#include " checkqueue.h"
@@ -126,15 +125,6 @@ namespace {
126
125
127
126
} // anon namespace
128
127
129
- // Bloom filter to limit respend relays to one
130
- static const unsigned int MAX_DOUBLESPEND_BLOOM = 1000 ;
131
- static CBloomFilter doubleSpendFilter;
132
- void InitRespendFilter () {
133
- seed_insecure_rand ();
134
- doubleSpendFilter = CBloomFilter (MAX_DOUBLESPEND_BLOOM, 0.01 , insecure_rand (), BLOOM_UPDATE_NONE);
135
- }
136
-
137
-
138
128
// ////////////////////////////////////////////////////////////////////////////
139
129
//
140
130
// dispatching functions
@@ -161,7 +151,6 @@ struct CMainSignals {
161
151
162
152
} // anon namespace
163
153
164
-
165
154
void RegisterWallet (CWalletInterface* pwalletIn) {
166
155
g_signals.SyncTransaction .connect (boost::bind (&CWalletInterface::SyncTransaction, pwalletIn, _1, _2));
167
156
g_signals.EraseTransaction .connect (boost::bind (&CWalletInterface::EraseFromWallet, pwalletIn, _1));
@@ -881,60 +870,6 @@ int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
881
870
return nMinFee;
882
871
}
883
872
884
- // Exponentially limit the rate of nSize flow to nLimit. nLimit unit is thousands-per-minute.
885
- bool RateLimitExceeded (double & dCount, int64_t & nLastTime, int64_t nLimit, unsigned int nSize)
886
- {
887
- static CCriticalSection csLimiter;
888
- int64_t nNow = GetTime ();
889
-
890
- LOCK (csLimiter);
891
-
892
- dCount *= pow (1.0 - 1.0 /600.0 , (double )(nNow - nLastTime));
893
- nLastTime = nNow;
894
- if (dCount >= nLimit*10 *1000 )
895
- return true ;
896
- dCount += nSize;
897
- return false ;
898
- }
899
-
900
- static bool RelayableRespend (const COutPoint& outPoint, const CTransaction& doubleSpend, bool fInBlock , CBloomFilter& filter)
901
- {
902
- // Relaying double-spend attempts to our peers lets them detect when
903
- // somebody might be trying to cheat them. However, blindly relaying
904
- // every double-spend across the entire network gives attackers
905
- // a denial-of-service attack: just generate a stream of double-spends
906
- // re-spending the same (limited) set of outpoints owned by the attacker.
907
- // So, we use a bloom filter and only relay (at most) the first double
908
- // spend for each outpoint. False-positives ("we have already relayed")
909
- // are OK, because if the peer doesn't hear about the double-spend
910
- // from us they are very likely to hear about it from another peer, since
911
- // each peer uses a different, randomized bloom filter.
912
-
913
- if (fInBlock || filter.contains (outPoint)) return false ;
914
-
915
- // Apply an independent rate limit to double-spend relays
916
- static double dRespendCount;
917
- static int64_t nLastRespendTime;
918
- static int64_t nRespendLimit = GetArg (" -limitrespendrelay" , 100 );
919
- unsigned int nSize = ::GetSerializeSize (doubleSpend, SER_NETWORK, PROTOCOL_VERSION);
920
-
921
- if (RateLimitExceeded (dRespendCount, nLastRespendTime, nRespendLimit, nSize))
922
- {
923
- LogPrint (" mempool" , " Double-spend relay rejected by rate limiter\n " );
924
- return false ;
925
- }
926
-
927
- LogPrint (" mempool" , " Rate limit dRespendCount: %g => %g\n " , dRespendCount, dRespendCount+nSize);
928
-
929
- // Clear the filter on average every MAX_DOUBLE_SPEND_BLOOM
930
- // insertions
931
- if (insecure_rand ()%MAX_DOUBLESPEND_BLOOM == 0 )
932
- filter.clear ();
933
-
934
- filter.insert (outPoint);
935
-
936
- return true ;
937
- }
938
873
939
874
bool AcceptToMemoryPool (CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree ,
940
875
bool * pfMissingInputs, bool fRejectInsaneFee )
@@ -964,18 +899,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
964
899
return false ;
965
900
966
901
// Check for conflicts with in-memory transactions
967
- bool relayableRespend = false ;
968
902
{
969
903
LOCK (pool.cs ); // protect pool.mapNextTx
970
904
for (unsigned int i = 0 ; i < tx.vin .size (); i++)
971
905
{
972
906
COutPoint outpoint = tx.vin [i].prevout ;
973
- // Does tx conflict with a member of the pool, and is it not equivalent to that member?
974
- if (pool.mapNextTx .count (outpoint) && !tx.IsEquivalentTo (*pool.mapNextTx [outpoint].ptx ))
907
+ if (pool.mapNextTx .count (outpoint))
975
908
{
976
- relayableRespend = RelayableRespend (outpoint, tx, false , doubleSpendFilter);
977
- if (!relayableRespend)
978
- return false ;
909
+ // Disable replacement feature for now
910
+ return false ;
979
911
}
980
912
}
981
913
}
@@ -1046,15 +978,23 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
1046
978
// be annoying or make others' transactions take longer to confirm.
1047
979
if (fLimitFree && nFees < ::minRelayTxFee.GetFee (nSize))
1048
980
{
981
+ static CCriticalSection csFreeLimiter;
1049
982
static double dFreeCount;
1050
- static int64_t nLastFreeTime ;
1051
- static int64_t nFreeLimit = GetArg ( " -limitfreerelay " , 15 );
983
+ static int64_t nLastTime ;
984
+ int64_t nNow = GetTime ( );
1052
985
1053
- if (RateLimitExceeded (dFreeCount, nLastFreeTime, nFreeLimit, nSize))
986
+ LOCK (csFreeLimiter);
987
+
988
+ // Use an exponentially decaying ~10-minute window:
989
+ dFreeCount *= pow (1.0 - 1.0 /600.0 , (double )(nNow - nLastTime));
990
+ nLastTime = nNow;
991
+ // -limitfreerelay unit is thousand-bytes-per-minute
992
+ // At default rate it would take over a month to fill 1GB
993
+ if (dFreeCount >= GetArg (" -limitfreerelay" , 15 )*10 *1000 )
1054
994
return state.DoS (0 , error (" AcceptToMemoryPool : free transaction rejected by rate limiter" ),
1055
995
REJECT_INSUFFICIENTFEE, " insufficient priority" );
1056
-
1057
996
LogPrint (" mempool" , " Rate limit dFreeCount: %g => %g\n " , dFreeCount, dFreeCount+nSize);
997
+ dFreeCount += nSize;
1058
998
}
1059
999
1060
1000
if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee (nSize) * 10000 )
@@ -1068,21 +1008,13 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
1068
1008
{
1069
1009
return error (" AcceptToMemoryPool: : ConnectInputs failed %s" , hash.ToString ());
1070
1010
}
1071
-
1072
- if (relayableRespend)
1073
- {
1074
- RelayTransaction (tx);
1075
- }
1076
- else
1077
- {
1078
- // Store transaction in memory
1079
- pool.addUnchecked (hash, entry);
1080
- }
1011
+ // Store transaction in memory
1012
+ pool.addUnchecked (hash, entry);
1081
1013
}
1082
1014
1083
1015
g_signals.SyncTransaction (tx, NULL );
1084
1016
1085
- return !relayableRespend ;
1017
+ return true ;
1086
1018
}
1087
1019
1088
1020
0 commit comments