thread safe rand (#1157)
* thread safe InsecureRand class * remove GetInsecureRand, use GetRandInt for performance non-critical parts
This commit is contained in:
parent
e121829e40
commit
c2ec99ba8e
@ -664,7 +664,7 @@ void CDarksendPool::ChargeFees()
|
||||
if(!fMasterNode) return;
|
||||
|
||||
//we don't need to charge collateral for every offence.
|
||||
if(GetInsecureRand(100) > 33) return;
|
||||
if(GetRandInt(100) > 33) return;
|
||||
|
||||
std::vector<CTransaction> vecOffendersCollaterals;
|
||||
|
||||
@ -699,7 +699,7 @@ void CDarksendPool::ChargeFees()
|
||||
if(vecOffendersCollaterals.empty()) return;
|
||||
|
||||
//mostly offending? Charge sometimes
|
||||
if((int)vecOffendersCollaterals.size() >= Params().PoolMaxTransactions() - 1 && GetInsecureRand(100) > 33) return;
|
||||
if((int)vecOffendersCollaterals.size() >= Params().PoolMaxTransactions() - 1 && GetRandInt(100) > 33) return;
|
||||
|
||||
//everyone is an offender? That's not right
|
||||
if((int)vecOffendersCollaterals.size() >= Params().PoolMaxTransactions()) return;
|
||||
@ -740,7 +740,7 @@ void CDarksendPool::ChargeRandomFees()
|
||||
|
||||
BOOST_FOREACH(const CTransaction& txCollateral, vecSessionCollaterals) {
|
||||
|
||||
if(GetInsecureRand(100) > 10) return;
|
||||
if(GetRandInt(100) > 10) return;
|
||||
|
||||
LogPrintf("CDarksendPool::ChargeRandomFees -- charging random fees, txCollateral=%s", txCollateral.ToString());
|
||||
|
||||
@ -1480,7 +1480,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
||||
LogPrint("privatesend", " vecMasternodesUsed: new size: %d, threshold: %d\n", (int)vecMasternodesUsed.size(), nThreshold_high);
|
||||
}
|
||||
|
||||
bool fUseQueue = insecure_rand()%100 > 33;
|
||||
bool fUseQueue = GetRandInt(100) > 33;
|
||||
// don't use the queues all of the time for mixing unless we are a liquidity provider
|
||||
if(nLiquidityProvider || fUseQueue) {
|
||||
|
||||
@ -2014,7 +2014,7 @@ bool CDarksendPool::CreateNewSession(int nDenom, CTransaction txCollateral, Pool
|
||||
|
||||
// start new session
|
||||
nMessageIDRet = MSG_NOERR;
|
||||
nSessionID = GetInsecureRand(999999)+1;
|
||||
nSessionID = GetRandInt(999999)+1;
|
||||
nSessionDenom = nDenom;
|
||||
|
||||
SetState(POOL_STATE_QUEUE);
|
||||
@ -2145,7 +2145,7 @@ int CDarksendPool::GetDenominations(const std::vector<CTxOut>& vecTxOut, bool fS
|
||||
int c = 0;
|
||||
// if the denomination is used, shift the bit on
|
||||
BOOST_FOREACH (PAIRTYPE(CAmount, int)& s, vecDenomUsed) {
|
||||
int bit = (fSingleRandomDenom ? insecure_rand()%2 : 1) & s.second;
|
||||
int bit = (fSingleRandomDenom ? GetRandInt(2) : 1) & s.second;
|
||||
nDenom |= bit << c++;
|
||||
if(fSingleRandomDenom && bit) break; // use just one random denomination
|
||||
}
|
||||
@ -2462,7 +2462,7 @@ void ThreadCheckDarkSendPool()
|
||||
|
||||
if(nDoAutoNextRun == nTick) {
|
||||
darkSendPool.DoAutomaticDenominating();
|
||||
nDoAutoNextRun = nTick + PRIVATESEND_AUTO_TIMEOUT_MIN + GetInsecureRand(PRIVATESEND_AUTO_TIMEOUT_MAX - PRIVATESEND_AUTO_TIMEOUT_MIN);
|
||||
nDoAutoNextRun = nTick + PRIVATESEND_AUTO_TIMEOUT_MIN + GetRandInt(PRIVATESEND_AUTO_TIMEOUT_MAX - PRIVATESEND_AUTO_TIMEOUT_MIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -543,8 +543,9 @@ CMasternode* CMasternodeMan::FindRandomNotInVec(const std::vector<CTxIn> &vecToE
|
||||
vpMasternodesShuffled.push_back(&mn);
|
||||
}
|
||||
|
||||
InsecureRand insecureRand;
|
||||
// shuffle pointers
|
||||
std::random_shuffle(vpMasternodesShuffled.begin(), vpMasternodesShuffled.end(), GetInsecureRand);
|
||||
std::random_shuffle(vpMasternodesShuffled.begin(), vpMasternodesShuffled.end(), insecureRand);
|
||||
bool fExclude;
|
||||
|
||||
// loop through
|
||||
@ -969,7 +970,7 @@ bool CMasternodeMan::SendVerifyRequest(const CAddress& addr, const std::vector<C
|
||||
if(pnode != NULL) {
|
||||
netfulfilledman.AddFulfilledRequest(addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request");
|
||||
// use random nonce, store it and require node to reply with correct one later
|
||||
CMasternodeVerification mnv(addr, GetInsecureRand(999999), pCurrentBlockIndex->nHeight - 1);
|
||||
CMasternodeVerification mnv(addr, GetRandInt(999999), pCurrentBlockIndex->nHeight - 1);
|
||||
mWeAskedForVerification[addr] = mnv;
|
||||
LogPrintf("CMasternodeMan::SendVerifyRequest -- verifying using nonce %d addr=%s\n", mnv.nonce, addr.ToString());
|
||||
pnode->PushMessage(NetMsgType::MNVERIFY, mnv);
|
||||
|
@ -137,3 +137,21 @@ void seed_insecure_rand(bool fDeterministic)
|
||||
insecure_rand_Rw = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
InsecureRand::InsecureRand(bool _fDeterministic)
|
||||
: nRz(11),
|
||||
nRw(11),
|
||||
fDeterministic(_fDeterministic)
|
||||
{
|
||||
// The seed values have some unlikely fixed points which we avoid.
|
||||
if(fDeterministic) return;
|
||||
uint32_t nTmp;
|
||||
do {
|
||||
GetRandBytes((unsigned char*)&nTmp, 4);
|
||||
} while (nTmp == 0 || nTmp == 0x9068ffffU);
|
||||
nRz = nTmp;
|
||||
do {
|
||||
GetRandBytes((unsigned char*)&nTmp, 4);
|
||||
} while (nTmp == 0 || nTmp == 0x464fffffU);
|
||||
nRw = nTmp;
|
||||
}
|
||||
|
27
src/random.h
27
src/random.h
@ -47,10 +47,31 @@ static inline uint32_t insecure_rand(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for std::random_shuffle
|
||||
* PRNG initialized from secure entropy based RNG
|
||||
*/
|
||||
static inline uint32_t GetInsecureRand(uint32_t i){
|
||||
return insecure_rand() % i;
|
||||
class InsecureRand
|
||||
{
|
||||
private:
|
||||
uint32_t nRz;
|
||||
uint32_t nRw;
|
||||
bool fDeterministic;
|
||||
|
||||
public:
|
||||
InsecureRand(bool _fDeterministic = false);
|
||||
|
||||
/**
|
||||
* MWC RNG of George Marsaglia
|
||||
* This is intended to be fast. It has a period of 2^59.3, though the
|
||||
* least significant 16 bits only have a period of about 2^30.1.
|
||||
*
|
||||
* @return random value < nMax
|
||||
*/
|
||||
int64_t operator()(int64_t nMax)
|
||||
{
|
||||
nRz = 36969 * (nRz & 65535) + (nRz >> 16);
|
||||
nRw = 18000 * (nRw & 65535) + (nRw >> 16);
|
||||
return ((nRw << 16) + nRz) % nMax;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BITCOIN_RANDOM_H
|
||||
|
@ -2501,6 +2501,7 @@ bool CWallet::SelectCoinsByDenominations(int nDenom, CAmount nValueMin, CAmount
|
||||
|
||||
int nDenomResult = 0;
|
||||
|
||||
InsecureRand insecureRand;
|
||||
BOOST_FOREACH(const COutput& out, vCoins)
|
||||
{
|
||||
// masternode-like input should not be selected by AvailableCoins now anyway
|
||||
@ -2517,9 +2518,9 @@ bool CWallet::SelectCoinsByDenominations(int nDenom, CAmount nValueMin, CAmount
|
||||
if(out.tx->vout[out.i].nValue == vecPrivateSendDenominations[nBit]) {
|
||||
if(nValueRet >= nValueMin) {
|
||||
//randomly reduce the max amount we'll submit (for anonymity)
|
||||
nValueMax -= (GetInsecureRand(nValueMax/5));
|
||||
nValueMax -= insecureRand(nValueMax/5);
|
||||
//on average use 50% of the inputs or less
|
||||
int r = GetInsecureRand((int)vCoins.size());
|
||||
int r = insecureRand(vCoins.size());
|
||||
if((int)vecTxInRet.size() > r) return true;
|
||||
}
|
||||
txin.prevPubKey = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey
|
||||
|
Loading…
Reference in New Issue
Block a user