aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reikher <david.reikher@gmail.com>2019-09-15 16:04:57 +0300
committerDavid Reikher <david.reikher@gmail.com>2020-07-21 09:18:57 +0300
commit4455949d6f0218b40d33d7fe6de6555f8f62192f (patch)
treeef5fe6712f1f6052b7fe0279537dbb56038a6c55
parent090d87716074434bdc6c7656ec44d049197a793a (diff)
downloadbitcoin-4455949d6f0218b40d33d7fe6de6555f8f62192f.tar.xz
Make test DoS_mapOrphans deterministic
The RandomOrphan function and the function ecdsa_signature_parse_der_lax in pubkey.cpp were causing non-deterministic test coverage. Force seed in the beginning of the test to make it deterministic. The seed is selected carefully so that all branches of the function ecdsa_signature_parse_der_lax are executed. Prior to this fix, the test was exhibiting non-deterministic coverage since none of the ECDSA signatures that were generated during the test had leading zeroes in either R, S, or both, resulting in some branches of said function not being executed. The seed ensures that both conditions are hit. Removed denialofservice_tests test entry from the list of non-deterministic tests in the coverage script.
-rwxr-xr-xcontrib/devtools/test_deterministic_coverage.sh1
-rw-r--r--src/test/denialofservice_tests.cpp20
2 files changed, 19 insertions, 2 deletions
diff --git a/contrib/devtools/test_deterministic_coverage.sh b/contrib/devtools/test_deterministic_coverage.sh
index 95b1553215..8501c72f04 100755
--- a/contrib/devtools/test_deterministic_coverage.sh
+++ b/contrib/devtools/test_deterministic_coverage.sh
@@ -16,7 +16,6 @@ GCOV_EXECUTABLE="gcov"
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))
- "denialofservice_tests/DoS_mapOrphans" # denialofservice_tests.cpp: it = mapOrphanTransactions.lower_bound(InsecureRand256());
"fs_tests/fsbridge_fstream" # deterministic test failure?
"miner_tests/CreateNewBlock_validity" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"scheduler_tests/manythreads" # scheduler.cpp: CScheduler::serviceQueue()
diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp
index fdc63cd70e..b1a635d9da 100644
--- a/src/test/denialofservice_tests.cpp
+++ b/src/test/denialofservice_tests.cpp
@@ -4,10 +4,12 @@
// Unit tests for denial-of-service detection/prevention code
+#include <arith_uint256.h>
#include <banman.h>
#include <chainparams.h>
#include <net.h>
#include <net_processing.h>
+#include <pubkey.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <script/standard.h>
@@ -314,10 +316,26 @@ static CTransactionRef RandomOrphan()
return it->second.tx;
}
+static void MakeNewKeyWithFastRandomContext(CKey& key)
+{
+ std::vector<unsigned char> keydata;
+ keydata = g_insecure_rand_ctx.randbytes(32);
+ key.Set(keydata.data(), keydata.data() + keydata.size(), /*fCompressedIn*/ true);
+ assert(key.IsValid());
+}
+
BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
{
+ // This test had non-deterministic coverage due to
+ // randomly selected seeds.
+ // This seed is chosen so that all branches of the function
+ // ecdsa_signature_parse_der_lax are executed during this test.
+ // Specifically branches that run only when an ECDSA
+ // signature's R and S values have leading zeros.
+ g_insecure_rand_ctx = FastRandomContext(ArithToUint256(arith_uint256(33)));
+
CKey key;
- key.MakeNewKey(true);
+ MakeNewKeyWithFastRandomContext(key);
FillableSigningProvider keystore;
BOOST_CHECK(keystore.AddKey(key));