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,10 +125,6 @@ namespace {
126
125
127
126
} // anon namespace
128
127
129
- // Forward reference functions defined here:
130
- static const unsigned int MAX_DOUBLESPEND_BLOOM = 1000 ;
131
- static void RelayDoubleSpend (const COutPoint& outPoint, const CTransaction& doubleSpend, bool fInBlock , CBloomFilter& filter);
132
-
133
128
// ////////////////////////////////////////////////////////////////////////////
134
129
//
135
130
// dispatching functions
@@ -152,25 +147,10 @@ struct CMainSignals {
152
147
boost::signals2::signal<void (const uint256 &)> Inventory;
153
148
// Tells listeners to broadcast their data.
154
149
boost::signals2::signal<void ()> Broadcast;
155
- // Notifies listeners of detection of a double-spent transaction. Arguments are outpoint that is
156
- // double-spent, first transaction seen, double-spend transaction, and whether the second double-spend
157
- // transaction was first seen in a block.
158
- // Note: only notifies if the previous transaction is in the memory pool; if previous transction was in a block,
159
- // then the double-spend simply fails when we try to lookup the inputs in the current UTXO set.
160
- boost::signals2::signal<void (const COutPoint&, const CTransaction&, bool )> DetectedDoubleSpend;
161
150
} g_signals;
162
151
163
152
} // anon namespace
164
153
165
- void RegisterInternalSignals () {
166
- static CBloomFilter doubleSpendFilter;
167
- seed_insecure_rand ();
168
- doubleSpendFilter = CBloomFilter (MAX_DOUBLESPEND_BLOOM, 0.01 , insecure_rand (), BLOOM_UPDATE_NONE);
169
-
170
- g_signals.DetectedDoubleSpend .connect (boost::bind (RelayDoubleSpend, _1, _2, _3, doubleSpendFilter));
171
- }
172
-
173
-
174
154
void RegisterWallet (CWalletInterface* pwalletIn) {
175
155
g_signals.SyncTransaction .connect (boost::bind (&CWalletInterface::SyncTransaction, pwalletIn, _1, _2));
176
156
g_signals.EraseTransaction .connect (boost::bind (&CWalletInterface::EraseFromWallet, pwalletIn, _1));
@@ -890,22 +870,6 @@ int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
890
870
return nMinFee;
891
871
}
892
872
893
- // Exponentially limit the rate of nSize flow to nLimit. nLimit unit is thousands-per-minute.
894
- bool RateLimitExceeded (double & dCount, int64_t & nLastTime, int64_t nLimit, unsigned int nSize)
895
- {
896
- static CCriticalSection csLimiter;
897
- int64_t nNow = GetTime ();
898
-
899
- LOCK (csLimiter);
900
-
901
- // Use an exponentially decaying ~10-minute window:
902
- dCount *= pow (1.0 - 1.0 /600.0 , (double )(nNow - nLastTime));
903
- nLastTime = nNow;
904
- if (dCount >= nLimit*10 *1000 )
905
- return true ;
906
- dCount += nSize;
907
- return false ;
908
- }
909
873
910
874
bool AcceptToMemoryPool (CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree ,
911
875
bool * pfMissingInputs, bool fRejectInsaneFee )
@@ -940,10 +904,9 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
940
904
for (unsigned int i = 0 ; i < tx.vin .size (); i++)
941
905
{
942
906
COutPoint outpoint = tx.vin [i].prevout ;
943
- // Does tx conflict with a member of the pool, and is it not equivalent to that member?
944
- if (pool.mapNextTx .count (outpoint) && !tx.IsEquivalentTo (*pool.mapNextTx [outpoint].ptx ))
907
+ if (pool.mapNextTx .count (outpoint))
945
908
{
946
- g_signals. DetectedDoubleSpend (outpoint, tx, false );
909
+ // Disable replacement feature for now
947
910
return false ;
948
911
}
949
912
}
@@ -1015,15 +978,23 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
1015
978
// be annoying or make others' transactions take longer to confirm.
1016
979
if (fLimitFree && nFees < ::minRelayTxFee.GetFee (nSize))
1017
980
{
981
+ static CCriticalSection csFreeLimiter;
1018
982
static double dFreeCount;
1019
- static int64_t nLastFreeTime;
1020
- static int64_t nFreeLimit = GetArg (" -limitfreerelay" , 15 );
983
+ static int64_t nLastTime;
984
+ int64_t nNow = GetTime ();
985
+
986
+ LOCK (csFreeLimiter);
1021
987
1022
- if (RateLimitExceeded (dFreeCount, nLastFreeTime, nFreeLimit, nSize))
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 )
1023
994
return state.DoS (0 , error (" AcceptToMemoryPool : free transaction rejected by rate limiter" ),
1024
995
REJECT_INSUFFICIENTFEE, " insufficient priority" );
1025
-
1026
996
LogPrint (" mempool" , " Rate limit dFreeCount: %g => %g\n " , dFreeCount, dFreeCount+nSize);
997
+ dFreeCount += nSize;
1027
998
}
1028
999
1029
1000
if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee (nSize) * 10000 )
@@ -1046,49 +1017,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
1046
1017
return true ;
1047
1018
}
1048
1019
1049
- static void
1050
- RelayDoubleSpend (const COutPoint& outPoint, const CTransaction& doubleSpend, bool fInBlock , CBloomFilter& filter)
1051
- {
1052
- // Relaying double-spend attempts to our peers lets them detect when
1053
- // somebody might be trying to cheat them. However, blindly relaying
1054
- // every double-spend across the entire network gives attackers
1055
- // a denial-of-service attack: just generate a stream of double-spends
1056
- // re-spending the same (limited) set of outpoints owned by the attacker.
1057
- // So, we use a bloom filter and only relay (at most) the first double
1058
- // spend for each outpoint. False-positives ("we have already relayed")
1059
- // are OK, because if the peer doesn't hear about the double-spend
1060
- // from us they are very likely to hear about it from another peer, since
1061
- // each peer uses a different, randomized bloom filter.
1062
-
1063
- if (fInBlock || filter.contains (outPoint)) return ;
1064
-
1065
- // Apply an independent rate limit to double-spend relays
1066
- static double dRespendCount;
1067
- static int64_t nLastRespendTime;
1068
- static int64_t nRespendLimit = GetArg (" -limitrespendrelay" , 100 );
1069
- unsigned int nSize = ::GetSerializeSize (doubleSpend, SER_NETWORK, PROTOCOL_VERSION);
1070
-
1071
- if (RateLimitExceeded (dRespendCount, nLastRespendTime, nRespendLimit, nSize))
1072
- {
1073
- LogPrint (" mempool" , " Double-spend relay rejected by rate limiter\n " );
1074
- return ;
1075
- }
1076
-
1077
- LogPrint (" mempool" , " Rate limit dRespendCount: %g => %g\n " , dRespendCount, dRespendCount+nSize);
1078
-
1079
- // Clear the filter on average every MAX_DOUBLE_SPEND_BLOOM
1080
- // insertions
1081
- if (insecure_rand ()%MAX_DOUBLESPEND_BLOOM == 0 )
1082
- filter.clear ();
1083
-
1084
- filter.insert (outPoint);
1085
-
1086
- RelayTransaction (doubleSpend);
1087
-
1088
- // Share conflict with wallet
1089
- g_signals.SyncTransaction (doubleSpend, NULL );
1090
- }
1091
-
1092
1020
1093
1021
int CMerkleTx::GetDepthInMainChainINTERNAL (CBlockIndex* &pindexRet) const
1094
1022
{
0 commit comments