Skip to content

Commit

Permalink
Merge pull request #2368 from div72/rand
Browse files Browse the repository at this point in the history
random: port upstream random changes
  • Loading branch information
jamescowens authored Oct 31, 2021
2 parents 8290f22 + 73ead7d commit 16a61a2
Show file tree
Hide file tree
Showing 33 changed files with 1,722 additions and 293 deletions.
23 changes: 2 additions & 21 deletions contrib/devtools/test_deterministic_coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,9 @@ export LC_ALL=C
GCOV_EXECUTABLE="gcov"

# Disable tests known to cause non-deterministic behaviour and document the source or point of non-determinism.
NON_DETERMINISTIC_TESTS=(
"blockfilter_index_tests/blockfilter_index_initial_sync" # src/checkqueue.h: In CCheckQueue::Loop(): while (queue.empty()) { ... }
"coinselector_tests/knapsack_solver_test" # coinselector_tests.cpp: if (equal_sets(setCoinsRet, setCoinsRet2))
"fs_tests/fsbridge_fstream" # deterministic test failure?
"miner_tests/CreateNewBlock_validity" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"scheduler_tests/manythreads" # scheduler.cpp: CScheduler::serviceQueue()
"scheduler_tests/singlethreadedscheduler_ordered" # scheduler.cpp: CScheduler::serviceQueue()
"txvalidationcache_tests/checkinputs_test" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"txvalidationcache_tests/tx_mempool_block_doublespend" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"txindex_tests/txindex_initial_sync" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"txvalidation_tests/tx_mempool_reject_coinbase" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"validation_block_tests/processnewblock_signals_ordering" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"wallet_tests/coin_mark_dirty_immature_credit" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"wallet_tests/dummy_input_size_test" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"wallet_tests/importmulti_rescan" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"wallet_tests/importwallet_rescan" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"wallet_tests/ListCoins" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"wallet_tests/scan_for_wallet_transactions" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"wallet_tests/wallet_disableprivkeys" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
)
NON_DETERMINISTIC_TESTS=()

TEST_BITCOIN_BINARY="src/test/test_bitcoin"
TEST_BITCOIN_BINARY="src/test/test_gridcoin"

print_usage() {
echo "Usage: $0 [custom test filter (default: all but known non-deterministic tests)] [number of test runs (default: 2)]"
Expand Down
4 changes: 4 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ GRIDCOIN_CORE_H = \
prevector.h \
primitives/transaction.h \
protocol.h \
random.h \
randomenv.h \
reverselock.h \
rpc/blockchain.h \
rpc/client.h \
Expand Down Expand Up @@ -257,6 +259,8 @@ GRIDCOIN_CORE_CPP = addrdb.cpp \
policy/policy.cpp \
primitives/transaction.cpp \
protocol.cpp \
random.cpp \
randomenv.cpp \
rpc/blockchain.cpp \
rpc/client.cpp \
rpc/dataacq.cpp \
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ GRIDCOIN_TESTS =\
test/mruset_tests.cpp \
test/multisig_tests.cpp \
test/netbase_tests.cpp \
test/random_tests.cpp \
test/rpc_tests.cpp \
test/sanity_tests.cpp \
test/scheduler_tests.cpp \
Expand Down
4 changes: 2 additions & 2 deletions src/addrdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <chainparams.h>
#include <clientversion.h>
#include <hash.h>
// #include <random.h>
#include <random.h>
// #include <streams.h>
#include <tinyformat.h>
// #include <util/system.h>
Expand Down Expand Up @@ -41,7 +41,7 @@ bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data
{
// Generate random temporary filename
unsigned short randv = 0;
RAND_bytes((unsigned char*)&randv, sizeof(randv));
GetRandBytes((unsigned char*)&randv, sizeof(randv));
std::string tmpfn = strprintf("%s.%04x", prefix, randv);

// open temp output file, and associate with CAutoFile
Expand Down
1 change: 1 addition & 0 deletions src/addrman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include "addrman.h"
#include "random.h"
#include "streams.h"

using namespace std;
Expand Down
5 changes: 3 additions & 2 deletions src/addrman.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "netbase.h"
#include "protocol.h"
#include "random.h"
#include "util.h"
#include "sync.h"

Expand Down Expand Up @@ -383,7 +384,7 @@ class CAddrMan
CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int>(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set<int>())
{
nKey.resize(32);
RAND_bytes(&nKey[0], 32);
GetRandBytes(nKey.data(), 32);

nIdCount = 0;
nTried = 0;
Expand Down Expand Up @@ -504,7 +505,7 @@ class CAddrMan
{
LOCK(cs);
std::vector<int>().swap(vRandom);
RAND_bytes(&nKey[0], 32);
GetRandBytes(nKey.data(), 32);
vvTried = std::vector<std::vector<int>>(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int>(0));
vvNew = std::vector<std::set<int>>(ADDRMAN_NEW_BUCKET_COUNT, std::set<int>());
// Will need for Bitcoin rebase
Expand Down
3 changes: 2 additions & 1 deletion src/crypto/sha512.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2014-2016 The Bitcoin Core developers
// Copyright (c) 2014-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

Expand All @@ -23,6 +23,7 @@ class CSHA512
CSHA512& Write(const unsigned char* data, size_t len);
void Finalize(unsigned char hash[OUTPUT_SIZE]);
CSHA512& Reset();
uint64_t Size() const { return bytes; }
};

#endif // BITCOIN_CRYPTO_SHA512_H
1 change: 1 addition & 0 deletions src/gridcoin/scraper/scraper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "main.h"
#include "node/ui_interface.h"
#include "random.h"

#include "gridcoin/appcache.h"
#include "gridcoin/beacon.h"
Expand Down
1 change: 1 addition & 0 deletions src/gridcoin/staking/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "gridcoin/staking/kernel.h"
#include "txdb.h"
#include "main.h"
#include "random.h"
#include "streams.h"
#include "util.h"

Expand Down
1 change: 1 addition & 0 deletions src/gridcoin/staking/spam.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "kernel.h"
#include "uint256.h"
#include "random.h"

#include <array>
#include <cmath>
Expand Down
17 changes: 12 additions & 5 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "txdb.h"
#include "wallet/walletdb.h"
#include "banman.h"
#include "random.h"
#include "rpc/server.h"
#include "init.h"
#include "node/ui_interface.h"
Expand Down Expand Up @@ -606,6 +607,10 @@ bool InitSanityCheck(void)
return false;
}

if (!Random_SanityCheck()) {
return InitError("OS cryptographic RNG sanity check failure. Aborting.");
}

return true;
}

Expand Down Expand Up @@ -929,6 +934,7 @@ bool AppInit2(ThreadHandlerPtr threads)
// Initialize internal hashing code with SSE/AVX2 optimizations. In the future we will also have ARM/NEON optimizations.
std::string sha256_algo = SHA256AutoDetect();
LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
RandomInit();

LogPrintf("Block version 11 hard fork configured for block %d", Params().GetConsensus().BlockV11Height);

Expand Down Expand Up @@ -1268,12 +1274,10 @@ bool AppInit2(ThreadHandlerPtr threads)

if (fFirstRun)
{
// Create new keyUser and set as default key
RandAddSeedPerfmon();

// So Clang doesn't complain, even though we are really essentially single-threaded here.
LOCK(pwalletMain->cs_wallet);

// Create new keyUser and set as default key
CPubKey newDefaultKey;
if (pwalletMain->GetKeyFromPool(newDefaultKey, false)) {
pwalletMain->SetDefaultKey(newDefaultKey);
Expand Down Expand Up @@ -1385,8 +1389,6 @@ bool AppInit2(ThreadHandlerPtr threads)
if (!CheckDiskSpace())
return false;

RandAddSeedPerfmon();

if (!GRC::Initialize(threads, pindexBest)) {
return false;
}
Expand Down Expand Up @@ -1426,6 +1428,11 @@ bool AppInit2(ThreadHandlerPtr threads)
CScheduler::Function serviceLoop = std::bind(&CScheduler::serviceQueue, &scheduler);
threadGroup.create_thread(std::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));

// Gather some entropy once per minute.
scheduler.scheduleEvery([]{
RandAddPeriodic();
}, std::chrono::minutes{1});

// TODO: Do we need this? It would require porting the Bitcoin signal handler.
// GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);

Expand Down
9 changes: 6 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "node/blockstorage.h"
#include "policy/fees.h"
#include "policy/policy.h"
#include "random.h"
#include "validation.h"

#include <boost/algorithm/string/replace.hpp>
Expand Down Expand Up @@ -2918,8 +2919,6 @@ bool static AlreadyHave(CTxDB& txdb, const CInv& inv)

bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
RandAddSeedPerfmon();

LogPrint(BCLog::LogFlags::NOISY, "received: %s from %s (%" PRIszu " bytes)", strCommand, pfrom->addrName, vRecv.size());

if (strCommand == "aries")
Expand Down Expand Up @@ -3782,6 +3781,10 @@ bool ProcessMessages(CNode* pfrom)
// Checksum
CDataStream& vRecv = msg.vRecv;
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);

// We just received a message off the wire, harvest entropy from the time (and the message checksum)
RandAddEvent(ReadLE32(hash.begin()));

// TODO: hardcoded checksum size;
// will no longer be used once we adopt CNetMessage from Bitcoin
uint8_t nChecksum[CMessageHeader::CHECKSUM_SIZE];
Expand Down Expand Up @@ -3878,7 +3881,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
{
uint64_t nonce = 0;
while (nonce == 0) {
RAND_bytes((unsigned char*)&nonce, sizeof(nonce));
GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
}
pto->fPingQueued = false;
pto->nPingUsecStart = GetTimeMicros();
Expand Down
6 changes: 2 additions & 4 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
#include "gridcoin/tally.h"
#include "policy/policy.h"
#include "policy/fees.h"
#include "random.h"
#include "util.h"
#include "validation.h"
#include "wallet/wallet.h"

#include <memory>
#include <algorithm>
#include <tuple>
#include <random>

using namespace std;

Expand Down Expand Up @@ -685,9 +685,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake
// the percentages is done.
if (vSideStakeAlloc.size() > nMaxSideStakeOutputs)
{
unsigned int seed = static_cast<unsigned int>(GetAdjustedTime());

std::shuffle(vSideStakeAlloc.begin(), vSideStakeAlloc.end(), std::default_random_engine(seed));
Shuffle(vSideStakeAlloc.begin(), vSideStakeAlloc.end(), FastRandomContext());
}

// Initialize remaining stake output value to the total value of output for stake, which also includes
Expand Down
10 changes: 9 additions & 1 deletion src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "net.h"
#include "init.h"
#include "node/ui_interface.h"
#include "random.h"
#include "util.h"
#include "util/threadnames.h"

Expand Down Expand Up @@ -405,6 +406,10 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
}

pnode->nTimeConnected = GetAdjustedTime();

// We're making a new connection, harvest entropy from the time (and our peer count)
RandAddEvent((uint32_t)pnode->GetId());

return pnode;
}
else
Expand Down Expand Up @@ -481,7 +486,7 @@ void CNode::PushVersion()
int64_t nTime = GetAdjustedTime();
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
CAddress addrMe = GetLocalAddress(&addr);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
LogPrint(BCLog::LogFlags::NET, "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s",
PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), addr.ToString());

Expand Down Expand Up @@ -966,6 +971,9 @@ void ThreadSocketHandler2(void* parg)
LOCK(cs_vNodes);
vNodes.push_back(pnode);
}

// We received a new connection, harvest entropy from the time (and our peer count)
RandAddEvent((uint32_t)pnode->GetId());
}
}

Expand Down
1 change: 0 additions & 1 deletion src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <array>
#include <boost/thread.hpp>
#include <atomic>
#include <openssl/rand.h>

#include "netbase.h"
#include "mruset.h"
Expand Down
2 changes: 0 additions & 2 deletions src/qt/winshutdownmonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

#include <QDebug>

#include <openssl/rand.h>

// If we don't want a message to be processed by Qt, return true and set result to
// the value that the window procedure should return. Otherwise return false.
bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pnResult)
Expand Down
Loading

0 comments on commit 16a61a2

Please sign in to comment.