@@ -127,7 +127,7 @@ namespace {
127
127
128
128
// Forward reference functions defined here:
129
129
static const unsigned int MAX_DOUBLESPEND_BLOOM = 1000 ;
130
- static void RelayDoubleSpend (const COutPoint& outPoint, const CTransaction& doubleSpend, bool fInBlock , CBloomFilter& filter);
130
+ static bool RelayableRespend (const COutPoint& outPoint, const CTransaction& doubleSpend, bool fInBlock , CBloomFilter& filter);
131
131
132
132
// ////////////////////////////////////////////////////////////////////////////
133
133
//
@@ -156,7 +156,7 @@ struct CMainSignals {
156
156
// transaction was first seen in a block.
157
157
// Note: only notifies if the previous transaction is in the memory pool; if previous transction was in a block,
158
158
// then the double-spend simply fails when we try to lookup the inputs in the current UTXO set.
159
- boost::signals2::signal<void (const COutPoint&, const CTransaction&, bool )> DetectedDoubleSpend;
159
+ boost::signals2::signal<bool (const COutPoint&, const CTransaction&, bool )> DetectedDoubleSpend;
160
160
} g_signals;
161
161
162
162
} // anon namespace
@@ -166,7 +166,7 @@ void RegisterInternalSignals() {
166
166
seed_insecure_rand ();
167
167
doubleSpendFilter = CBloomFilter (MAX_DOUBLESPEND_BLOOM, 0.01 , insecure_rand (), BLOOM_UPDATE_NONE);
168
168
169
- g_signals.DetectedDoubleSpend .connect (boost::bind (RelayDoubleSpend , _1, _2, _3, doubleSpendFilter));
169
+ g_signals.DetectedDoubleSpend .connect (boost::bind (RelayableRespend , _1, _2, _3, doubleSpendFilter));
170
170
}
171
171
172
172
@@ -936,6 +936,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
936
936
return false ;
937
937
938
938
// Check for conflicts with in-memory transactions
939
+ bool relayableRespend = false ;
939
940
{
940
941
LOCK (pool.cs ); // protect pool.mapNextTx
941
942
for (unsigned int i = 0 ; i < tx.vin .size (); i++)
@@ -944,8 +945,9 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
944
945
// Does tx conflict with a member of the pool, and is it not equivalent to that member?
945
946
if (pool.mapNextTx .count (outpoint) && !tx.IsEquivalentTo (*pool.mapNextTx [outpoint].ptx ))
946
947
{
947
- g_signals.DetectedDoubleSpend (outpoint, tx, false );
948
- return false ;
948
+ relayableRespend = g_signals.DetectedDoubleSpend (outpoint, tx, false );
949
+ if (!relayableRespend)
950
+ return false ;
949
951
}
950
952
}
951
953
}
@@ -1038,16 +1040,24 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
1038
1040
{
1039
1041
return error (" AcceptToMemoryPool: : ConnectInputs failed %s" , hash.ToString ());
1040
1042
}
1041
- // Store transaction in memory
1042
- pool.addUnchecked (hash, entry);
1043
+
1044
+ if (relayableRespend)
1045
+ {
1046
+ RelayTransaction (tx);
1047
+ }
1048
+ else
1049
+ {
1050
+ // Store transaction in memory
1051
+ pool.addUnchecked (hash, entry);
1052
+ }
1043
1053
}
1044
1054
1045
1055
g_signals.SyncTransaction (tx, NULL );
1046
1056
1047
- return true ;
1057
+ return !relayableRespend ;
1048
1058
}
1049
1059
1050
- static void RelayDoubleSpend (const COutPoint& outPoint, const CTransaction& doubleSpend, bool fInBlock , CBloomFilter& filter)
1060
+ static bool RelayableRespend (const COutPoint& outPoint, const CTransaction& doubleSpend, bool fInBlock , CBloomFilter& filter)
1051
1061
{
1052
1062
// Relaying double-spend attempts to our peers lets them detect when
1053
1063
// somebody might be trying to cheat them. However, blindly relaying
@@ -1060,7 +1070,7 @@ static void RelayDoubleSpend(const COutPoint& outPoint, const CTransaction& doub
1060
1070
// from us they are very likely to hear about it from another peer, since
1061
1071
// each peer uses a different, randomized bloom filter.
1062
1072
1063
- if (fInBlock || filter.contains (outPoint)) return ;
1073
+ if (fInBlock || filter.contains (outPoint)) return false ;
1064
1074
1065
1075
// Apply an independent rate limit to double-spend relays
1066
1076
static double dRespendCount;
@@ -1071,7 +1081,7 @@ static void RelayDoubleSpend(const COutPoint& outPoint, const CTransaction& doub
1071
1081
if (RateLimitExceeded (dRespendCount, nLastRespendTime, nRespendLimit, nSize))
1072
1082
{
1073
1083
LogPrint (" mempool" , " Double-spend relay rejected by rate limiter\n " );
1074
- return ;
1084
+ return false ;
1075
1085
}
1076
1086
1077
1087
LogPrint (" mempool" , " Rate limit dRespendCount: %g => %g\n " , dRespendCount, dRespendCount+nSize);
@@ -1083,10 +1093,7 @@ static void RelayDoubleSpend(const COutPoint& outPoint, const CTransaction& doub
1083
1093
1084
1094
filter.insert (outPoint);
1085
1095
1086
- RelayTransaction (doubleSpend);
1087
-
1088
- // Share conflict with wallet
1089
- g_signals.SyncTransaction (doubleSpend, NULL );
1096
+ return true ;
1090
1097
}
1091
1098
1092
1099
0 commit comments