diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/checkqueue_tests.cpp | 23 | ||||
-rw-r--r-- | src/test/fuzz/coins_view.cpp | 294 | ||||
-rw-r--r-- | src/test/fuzz/script.cpp | 39 | ||||
-rw-r--r-- | src/test/fuzz/script_bitcoin_consensus.cpp | 31 | ||||
-rw-r--r-- | src/test/fuzz/script_descriptor_cache.cpp | 42 | ||||
-rw-r--r-- | src/test/fuzz/script_interpreter.cpp | 41 | ||||
-rw-r--r-- | src/test/fuzz/script_sigcache.cpp | 45 | ||||
-rw-r--r-- | src/test/fuzz/script_sign.cpp | 149 | ||||
-rw-r--r-- | src/test/fuzz/string.cpp | 9 | ||||
-rw-r--r-- | src/test/fuzz/util.h | 69 | ||||
-rw-r--r-- | src/test/getarg_tests.cpp | 133 | ||||
-rw-r--r-- | src/test/raii_event_tests.cpp | 19 | ||||
-rw-r--r-- | src/test/script_tests.cpp | 4 |
13 files changed, 815 insertions, 83 deletions
diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp index 0565982215..35750b2ebc 100644 --- a/src/test/checkqueue_tests.cpp +++ b/src/test/checkqueue_tests.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <checkqueue.h> +#include <sync.h> #include <test/util/setup_common.h> #include <util/memory.h> #include <util/system.h> @@ -57,14 +58,14 @@ struct FailingCheck { }; struct UniqueCheck { - static std::mutex m; - static std::unordered_multiset<size_t> results; + static Mutex m; + static std::unordered_multiset<size_t> results GUARDED_BY(m); size_t check_id; UniqueCheck(size_t check_id_in) : check_id(check_id_in){}; UniqueCheck() : check_id(0){}; bool operator()() { - std::lock_guard<std::mutex> l(m); + LOCK(m); results.insert(check_id); return true; } @@ -127,7 +128,7 @@ struct FrozenCleanupCheck { std::mutex FrozenCleanupCheck::m{}; std::atomic<uint64_t> FrozenCleanupCheck::nFrozen{0}; std::condition_variable FrozenCleanupCheck::cv{}; -std::mutex UniqueCheck::m; +Mutex UniqueCheck::m; std::unordered_multiset<size_t> UniqueCheck::results; std::atomic<size_t> FakeCheckCheckCompletion::n_calls{0}; std::atomic<size_t> MemoryCheck::fake_allocated_memory{0}; @@ -290,11 +291,15 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck) control.Add(vChecks); } } - bool r = true; - BOOST_REQUIRE_EQUAL(UniqueCheck::results.size(), COUNT); - for (size_t i = 0; i < COUNT; ++i) - r = r && UniqueCheck::results.count(i) == 1; - BOOST_REQUIRE(r); + { + LOCK(UniqueCheck::m); + bool r = true; + BOOST_REQUIRE_EQUAL(UniqueCheck::results.size(), COUNT); + for (size_t i = 0; i < COUNT; ++i) { + r = r && UniqueCheck::results.count(i) == 1; + } + BOOST_REQUIRE(r); + } tg.interrupt_all(); tg.join_all(); } diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp new file mode 100644 index 0000000000..52dd62a145 --- /dev/null +++ b/src/test/fuzz/coins_view.cpp @@ -0,0 +1,294 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <amount.h> +#include <chainparams.h> +#include <chainparamsbase.h> +#include <coins.h> +#include <consensus/tx_verify.h> +#include <consensus/validation.h> +#include <key.h> +#include <node/coinstats.h> +#include <policy/policy.h> +#include <primitives/transaction.h> +#include <pubkey.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <validation.h> + +#include <cstdint> +#include <limits> +#include <optional> +#include <string> +#include <vector> + +namespace { +const Coin EMPTY_COIN{}; + +bool operator==(const Coin& a, const Coin& b) +{ + if (a.IsSpent() && b.IsSpent()) return true; + return a.fCoinBase == b.fCoinBase && a.nHeight == b.nHeight && a.out == b.out; +} +} // namespace + +void initialize() +{ + static const ECCVerifyHandle ecc_verify_handle; + ECC_Start(); + SelectParams(CBaseChainParams::REGTEST); +} + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + CCoinsView backend_coins_view; + CCoinsViewCache coins_view_cache{&backend_coins_view}; + COutPoint random_out_point; + Coin random_coin; + CMutableTransaction random_mutable_transaction; + while (fuzzed_data_provider.ConsumeBool()) { + switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 9)) { + case 0: { + if (random_coin.IsSpent()) { + break; + } + Coin coin = random_coin; + bool expected_code_path = false; + const bool possible_overwrite = fuzzed_data_provider.ConsumeBool(); + try { + coins_view_cache.AddCoin(random_out_point, std::move(coin), possible_overwrite); + expected_code_path = true; + } catch (const std::logic_error& e) { + if (e.what() == std::string{"Attempted to overwrite an unspent coin (when possible_overwrite is false)"}) { + assert(!possible_overwrite); + expected_code_path = true; + } + } + assert(expected_code_path); + break; + } + case 1: { + (void)coins_view_cache.Flush(); + break; + } + case 2: { + coins_view_cache.SetBestBlock(ConsumeUInt256(fuzzed_data_provider)); + break; + } + case 3: { + Coin move_to; + (void)coins_view_cache.SpendCoin(random_out_point, fuzzed_data_provider.ConsumeBool() ? &move_to : nullptr); + break; + } + case 4: { + coins_view_cache.Uncache(random_out_point); + break; + } + case 5: { + if (fuzzed_data_provider.ConsumeBool()) { + backend_coins_view = CCoinsView{}; + } + coins_view_cache.SetBackend(backend_coins_view); + break; + } + case 6: { + const std::optional<COutPoint> opt_out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider); + if (!opt_out_point) { + break; + } + random_out_point = *opt_out_point; + break; + } + case 7: { + const std::optional<Coin> opt_coin = ConsumeDeserializable<Coin>(fuzzed_data_provider); + if (!opt_coin) { + break; + } + random_coin = *opt_coin; + break; + } + case 8: { + const std::optional<CMutableTransaction> opt_mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + if (!opt_mutable_transaction) { + break; + } + random_mutable_transaction = *opt_mutable_transaction; + break; + } + case 9: { + CCoinsMap coins_map; + while (fuzzed_data_provider.ConsumeBool()) { + CCoinsCacheEntry coins_cache_entry; + coins_cache_entry.flags = fuzzed_data_provider.ConsumeIntegral<unsigned char>(); + if (fuzzed_data_provider.ConsumeBool()) { + coins_cache_entry.coin = random_coin; + } else { + const std::optional<Coin> opt_coin = ConsumeDeserializable<Coin>(fuzzed_data_provider); + if (!opt_coin) { + break; + } + coins_cache_entry.coin = *opt_coin; + } + coins_map.emplace(random_out_point, std::move(coins_cache_entry)); + } + bool expected_code_path = false; + try { + coins_view_cache.BatchWrite(coins_map, fuzzed_data_provider.ConsumeBool() ? ConsumeUInt256(fuzzed_data_provider) : coins_view_cache.GetBestBlock()); + expected_code_path = true; + } catch (const std::logic_error& e) { + if (e.what() == std::string{"FRESH flag misapplied to coin that exists in parent cache"}) { + expected_code_path = true; + } + } + assert(expected_code_path); + break; + } + } + } + + { + const Coin& coin_using_access_coin = coins_view_cache.AccessCoin(random_out_point); + const bool exists_using_access_coin = !(coin_using_access_coin == EMPTY_COIN); + const bool exists_using_have_coin = coins_view_cache.HaveCoin(random_out_point); + const bool exists_using_have_coin_in_cache = coins_view_cache.HaveCoinInCache(random_out_point); + Coin coin_using_get_coin; + const bool exists_using_get_coin = coins_view_cache.GetCoin(random_out_point, coin_using_get_coin); + if (exists_using_get_coin) { + assert(coin_using_get_coin == coin_using_access_coin); + } + assert((exists_using_access_coin && exists_using_have_coin_in_cache && exists_using_have_coin && exists_using_get_coin) || + (!exists_using_access_coin && !exists_using_have_coin_in_cache && !exists_using_have_coin && !exists_using_get_coin)); + const bool exists_using_have_coin_in_backend = backend_coins_view.HaveCoin(random_out_point); + if (exists_using_have_coin_in_backend) { + assert(exists_using_have_coin); + } + Coin coin_using_backend_get_coin; + if (backend_coins_view.GetCoin(random_out_point, coin_using_backend_get_coin)) { + assert(exists_using_have_coin_in_backend); + assert(coin_using_get_coin == coin_using_backend_get_coin); + } else { + assert(!exists_using_have_coin_in_backend); + } + } + + { + bool expected_code_path = false; + try { + (void)coins_view_cache.Cursor(); + } catch (const std::logic_error&) { + expected_code_path = true; + } + assert(expected_code_path); + (void)coins_view_cache.DynamicMemoryUsage(); + (void)coins_view_cache.EstimateSize(); + (void)coins_view_cache.GetBestBlock(); + (void)coins_view_cache.GetCacheSize(); + (void)coins_view_cache.GetHeadBlocks(); + (void)coins_view_cache.HaveInputs(CTransaction{random_mutable_transaction}); + } + + { + const CCoinsViewCursor* coins_view_cursor = backend_coins_view.Cursor(); + assert(coins_view_cursor == nullptr); + (void)backend_coins_view.EstimateSize(); + (void)backend_coins_view.GetBestBlock(); + (void)backend_coins_view.GetHeadBlocks(); + } + + if (fuzzed_data_provider.ConsumeBool()) { + switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 6)) { + case 0: { + const CTransaction transaction{random_mutable_transaction}; + bool is_spent = false; + for (const CTxOut& tx_out : transaction.vout) { + if (Coin{tx_out, 0, transaction.IsCoinBase()}.IsSpent()) { + is_spent = true; + } + } + if (is_spent) { + // Avoid: + // coins.cpp:69: void CCoinsViewCache::AddCoin(const COutPoint &, Coin &&, bool): Assertion `!coin.IsSpent()' failed. + break; + } + bool expected_code_path = false; + const int height = fuzzed_data_provider.ConsumeIntegral<int>(); + const bool possible_overwrite = fuzzed_data_provider.ConsumeBool(); + try { + AddCoins(coins_view_cache, transaction, height, possible_overwrite); + expected_code_path = true; + } catch (const std::logic_error& e) { + if (e.what() == std::string{"Attempted to overwrite an unspent coin (when possible_overwrite is false)"}) { + assert(!possible_overwrite); + expected_code_path = true; + } + } + assert(expected_code_path); + break; + } + case 1: { + (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache); + break; + } + case 2: { + TxValidationState state; + CAmount tx_fee_out; + const CTransaction transaction{random_mutable_transaction}; + if (ContainsSpentInput(transaction, coins_view_cache)) { + // Avoid: + // consensus/tx_verify.cpp:171: bool Consensus::CheckTxInputs(const CTransaction &, TxValidationState &, const CCoinsViewCache &, int, CAmount &): Assertion `!coin.IsSpent()' failed. + break; + } + try { + (void)Consensus::CheckTxInputs(transaction, state, coins_view_cache, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, std::numeric_limits<int>::max()), tx_fee_out); + assert(MoneyRange(tx_fee_out)); + } catch (const std::runtime_error&) { + } + break; + } + case 3: { + const CTransaction transaction{random_mutable_transaction}; + if (ContainsSpentInput(transaction, coins_view_cache)) { + // Avoid: + // consensus/tx_verify.cpp:130: unsigned int GetP2SHSigOpCount(const CTransaction &, const CCoinsViewCache &): Assertion `!coin.IsSpent()' failed. + break; + } + (void)GetP2SHSigOpCount(transaction, coins_view_cache); + break; + } + case 4: { + const CTransaction transaction{random_mutable_transaction}; + if (ContainsSpentInput(transaction, coins_view_cache)) { + // Avoid: + // consensus/tx_verify.cpp:130: unsigned int GetP2SHSigOpCount(const CTransaction &, const CCoinsViewCache &): Assertion `!coin.IsSpent()' failed. + break; + } + const int flags = fuzzed_data_provider.ConsumeIntegral<int>(); + if (!transaction.vin.empty() && (flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) { + // Avoid: + // script/interpreter.cpp:1705: size_t CountWitnessSigOps(const CScript &, const CScript &, const CScriptWitness *, unsigned int): Assertion `(flags & SCRIPT_VERIFY_P2SH) != 0' failed. + break; + } + (void)GetTransactionSigOpCost(transaction, coins_view_cache, flags); + break; + } + case 5: { + CCoinsStats stats; + bool expected_code_path = false; + try { + (void)GetUTXOStats(&coins_view_cache, stats); + } catch (const std::logic_error&) { + expected_code_path = true; + } + assert(expected_code_path); + break; + } + case 6: { + (void)IsWitnessStandard(CTransaction{random_mutable_transaction}, coins_view_cache); + break; + } + } + } +} diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index e0c4ad7eb7..933cf9049d 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -11,6 +11,7 @@ #include <script/descriptor.h> #include <script/interpreter.h> #include <script/script.h> +#include <script/script_error.h> #include <script/sign.h> #include <script/signingprovider.h> #include <script/standard.h> @@ -21,6 +22,8 @@ #include <univalue.h> #include <util/memory.h> +#include <algorithm> +#include <cassert> #include <cstdint> #include <optional> #include <string> @@ -124,4 +127,40 @@ void test_one_input(const std::vector<uint8_t>& buffer) wit.SetNull(); } } + + (void)GetOpName(ConsumeOpcodeType(fuzzed_data_provider)); + (void)ScriptErrorString(static_cast<ScriptError>(fuzzed_data_provider.ConsumeIntegralInRange<int>(0, SCRIPT_ERR_ERROR_COUNT))); + + { + const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider); + CScript append_script{bytes.begin(), bytes.end()}; + append_script << fuzzed_data_provider.ConsumeIntegral<int64_t>(); + append_script << ConsumeOpcodeType(fuzzed_data_provider); + append_script << CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()}; + append_script << ConsumeRandomLengthByteVector(fuzzed_data_provider); + } + + { + WitnessUnknown witness_unknown_1{}; + witness_unknown_1.version = fuzzed_data_provider.ConsumeIntegral<int>(); + const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40); + witness_unknown_1.length = witness_unknown_program_1.size(); + std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown_1.program); + + WitnessUnknown witness_unknown_2{}; + witness_unknown_2.version = fuzzed_data_provider.ConsumeIntegral<int>(); + const std::vector<uint8_t> witness_unknown_program_2 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40); + witness_unknown_2.length = witness_unknown_program_2.size(); + std::copy(witness_unknown_program_2.begin(), witness_unknown_program_2.end(), witness_unknown_2.program); + + (void)(witness_unknown_1 == witness_unknown_2); + (void)(witness_unknown_1 < witness_unknown_2); + } + + { + const CTxDestination tx_destination_1 = ConsumeTxDestination(fuzzed_data_provider); + const CTxDestination tx_destination_2 = ConsumeTxDestination(fuzzed_data_provider); + (void)(tx_destination_1 == tx_destination_2); + (void)(tx_destination_1 < tx_destination_2); + } } diff --git a/src/test/fuzz/script_bitcoin_consensus.cpp b/src/test/fuzz/script_bitcoin_consensus.cpp new file mode 100644 index 0000000000..22f4b4f44a --- /dev/null +++ b/src/test/fuzz/script_bitcoin_consensus.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <script/bitcoinconsensus.h> +#include <script/interpreter.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <string> +#include <vector> + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const std::vector<uint8_t> random_bytes_1 = ConsumeRandomLengthByteVector(fuzzed_data_provider); + const std::vector<uint8_t> random_bytes_2 = ConsumeRandomLengthByteVector(fuzzed_data_provider); + const CAmount money = ConsumeMoney(fuzzed_data_provider); + bitcoinconsensus_error err; + bitcoinconsensus_error* err_p = fuzzed_data_provider.ConsumeBool() ? &err : nullptr; + const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + assert(bitcoinconsensus_version() == BITCOINCONSENSUS_API_VER); + if ((flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) { + return; + } + (void)bitcoinconsensus_verify_script(random_bytes_1.data(), random_bytes_1.size(), random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p); + (void)bitcoinconsensus_verify_script_with_amount(random_bytes_1.data(), random_bytes_1.size(), money, random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p); +} diff --git a/src/test/fuzz/script_descriptor_cache.cpp b/src/test/fuzz/script_descriptor_cache.cpp new file mode 100644 index 0000000000..4bfe61cec7 --- /dev/null +++ b/src/test/fuzz/script_descriptor_cache.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <optional.h> +#include <pubkey.h> +#include <script/descriptor.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <string> +#include <vector> + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + DescriptorCache descriptor_cache; + while (fuzzed_data_provider.ConsumeBool()) { + const std::vector<uint8_t> code = fuzzed_data_provider.ConsumeBytes<uint8_t>(BIP32_EXTKEY_SIZE); + if (code.size() == BIP32_EXTKEY_SIZE) { + CExtPubKey xpub; + xpub.Decode(code.data()); + const uint32_t key_exp_pos = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); + CExtPubKey xpub_fetched; + if (fuzzed_data_provider.ConsumeBool()) { + (void)descriptor_cache.GetCachedParentExtPubKey(key_exp_pos, xpub_fetched); + descriptor_cache.CacheParentExtPubKey(key_exp_pos, xpub); + assert(descriptor_cache.GetCachedParentExtPubKey(key_exp_pos, xpub_fetched)); + } else { + const uint32_t der_index = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); + (void)descriptor_cache.GetCachedDerivedExtPubKey(key_exp_pos, der_index, xpub_fetched); + descriptor_cache.CacheDerivedExtPubKey(key_exp_pos, der_index, xpub); + assert(descriptor_cache.GetCachedDerivedExtPubKey(key_exp_pos, der_index, xpub_fetched)); + } + assert(xpub == xpub_fetched); + } + (void)descriptor_cache.GetCachedParentExtPubKeys(); + (void)descriptor_cache.GetCachedDerivedExtPubKeys(); + } +} diff --git a/src/test/fuzz/script_interpreter.cpp b/src/test/fuzz/script_interpreter.cpp new file mode 100644 index 0000000000..26d5732f24 --- /dev/null +++ b/src/test/fuzz/script_interpreter.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <primitives/transaction.h> +#include <script/interpreter.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <optional> +#include <string> +#include <vector> + +bool CastToBool(const std::vector<unsigned char>& vch); + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + { + const CScript script_code = ConsumeScript(fuzzed_data_provider); + const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + if (mtx) { + const CTransaction tx_to{*mtx}; + const unsigned int in = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + if (in < tx_to.vin.size()) { + (void)SignatureHash(script_code, tx_to, in, fuzzed_data_provider.ConsumeIntegral<int>(), ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0}), nullptr); + const std::optional<CMutableTransaction> mtx_precomputed = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + if (mtx_precomputed) { + const CTransaction tx_precomputed{*mtx_precomputed}; + const PrecomputedTransactionData precomputed_transaction_data{tx_precomputed}; + (void)SignatureHash(script_code, tx_to, in, fuzzed_data_provider.ConsumeIntegral<int>(), ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0}), &precomputed_transaction_data); + } + } + } + } + { + (void)CastToBool(ConsumeRandomLengthByteVector(fuzzed_data_provider)); + } +} diff --git a/src/test/fuzz/script_sigcache.cpp b/src/test/fuzz/script_sigcache.cpp new file mode 100644 index 0000000000..434a47b702 --- /dev/null +++ b/src/test/fuzz/script_sigcache.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <chainparams.h> +#include <chainparamsbase.h> +#include <key.h> +#include <pubkey.h> +#include <script/sigcache.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <optional> +#include <string> +#include <vector> + +void initialize() +{ + static const ECCVerifyHandle ecc_verify_handle; + ECC_Start(); + SelectParams(CBaseChainParams::REGTEST); + InitSignatureCache(); +} + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + + const std::optional<CMutableTransaction> mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + const CTransaction tx = mutable_transaction ? CTransaction{*mutable_transaction} : CTransaction{}; + const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + const CAmount amount = ConsumeMoney(fuzzed_data_provider); + const bool store = fuzzed_data_provider.ConsumeBool(); + PrecomputedTransactionData tx_data; + CachingTransactionSignatureChecker caching_transaction_signature_checker{mutable_transaction ? &tx : nullptr, n_in, amount, store, tx_data}; + const std::optional<CPubKey> pub_key = ConsumeDeserializable<CPubKey>(fuzzed_data_provider); + if (pub_key) { + const std::vector<uint8_t> random_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider); + if (!random_bytes.empty()) { + (void)caching_transaction_signature_checker.VerifySignature(random_bytes, *pub_key, ConsumeUInt256(fuzzed_data_provider)); + } + } +} diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp new file mode 100644 index 0000000000..c626f950e7 --- /dev/null +++ b/src/test/fuzz/script_sign.cpp @@ -0,0 +1,149 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <chainparams.h> +#include <chainparamsbase.h> +#include <key.h> +#include <pubkey.h> +#include <script/keyorigin.h> +#include <script/sign.h> +#include <script/signingprovider.h> +#include <streams.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cassert> +#include <cstdint> +#include <iostream> +#include <map> +#include <optional> +#include <string> +#include <vector> + +void initialize() +{ + static const ECCVerifyHandle ecc_verify_handle; + ECC_Start(); + SelectParams(CBaseChainParams::REGTEST); +} + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const std::vector<uint8_t> key = ConsumeRandomLengthByteVector(fuzzed_data_provider, 128); + + { + CDataStream random_data_stream = ConsumeDataStream(fuzzed_data_provider); + std::map<CPubKey, KeyOriginInfo> hd_keypaths; + try { + DeserializeHDKeypaths(random_data_stream, key, hd_keypaths); + } catch (const std::ios_base::failure&) { + } + CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION}; + SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>()); + } + + { + std::map<CPubKey, KeyOriginInfo> hd_keypaths; + while (fuzzed_data_provider.ConsumeBool()) { + const std::optional<CPubKey> pub_key = ConsumeDeserializable<CPubKey>(fuzzed_data_provider); + if (!pub_key) { + break; + } + const std::optional<KeyOriginInfo> key_origin_info = ConsumeDeserializable<KeyOriginInfo>(fuzzed_data_provider); + if (!key_origin_info) { + break; + } + hd_keypaths[*pub_key] = *key_origin_info; + } + CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION}; + try { + SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>()); + } catch (const std::ios_base::failure&) { + } + std::map<CPubKey, KeyOriginInfo> deserialized_hd_keypaths; + try { + DeserializeHDKeypaths(serialized, key, hd_keypaths); + } catch (const std::ios_base::failure&) { + } + assert(hd_keypaths.size() >= deserialized_hd_keypaths.size()); + } + + { + SignatureData signature_data_1{ConsumeScript(fuzzed_data_provider)}; + SignatureData signature_data_2{ConsumeScript(fuzzed_data_provider)}; + signature_data_1.MergeSignatureData(signature_data_2); + } + + FillableSigningProvider provider; + CKey k; + const std::vector<uint8_t> key_data = ConsumeRandomLengthByteVector(fuzzed_data_provider); + k.Set(key_data.begin(), key_data.end(), fuzzed_data_provider.ConsumeBool()); + if (k.IsValid()) { + provider.AddKey(k); + } + + { + const std::optional<CMutableTransaction> mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + const std::optional<CTxOut> tx_out = ConsumeDeserializable<CTxOut>(fuzzed_data_provider); + const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + if (mutable_transaction && tx_out && mutable_transaction->vin.size() > n_in) { + SignatureData signature_data_1 = DataFromTransaction(*mutable_transaction, n_in, *tx_out); + CTxIn input; + UpdateInput(input, signature_data_1); + const CScript script = ConsumeScript(fuzzed_data_provider); + SignatureData signature_data_2{script}; + signature_data_1.MergeSignatureData(signature_data_2); + } + if (mutable_transaction) { + CTransaction tx_from{*mutable_transaction}; + CMutableTransaction tx_to; + const std::optional<CMutableTransaction> opt_tx_to = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + if (opt_tx_to) { + tx_to = *opt_tx_to; + } + CMutableTransaction script_tx_to = tx_to; + CMutableTransaction sign_transaction_tx_to = tx_to; + if (n_in < tx_to.vin.size() && tx_to.vin[n_in].prevout.n < tx_from.vout.size()) { + (void)SignSignature(provider, tx_from, tx_to, n_in, fuzzed_data_provider.ConsumeIntegral<int>()); + } + if (n_in < script_tx_to.vin.size()) { + (void)SignSignature(provider, ConsumeScript(fuzzed_data_provider), script_tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()); + MutableTransactionSignatureCreator signature_creator{&tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()}; + std::vector<unsigned char> vch_sig; + CKeyID address; + if (fuzzed_data_provider.ConsumeBool()) { + if (k.IsValid()) { + address = k.GetPubKey().GetID(); + } + } else { + address = CKeyID{ConsumeUInt160(fuzzed_data_provider)}; + } + (void)signature_creator.CreateSig(provider, vch_sig, address, ConsumeScript(fuzzed_data_provider), fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0})); + } + std::map<COutPoint, Coin> coins; + while (fuzzed_data_provider.ConsumeBool()) { + const std::optional<COutPoint> outpoint = ConsumeDeserializable<COutPoint>(fuzzed_data_provider); + if (!outpoint) { + break; + } + const std::optional<Coin> coin = ConsumeDeserializable<Coin>(fuzzed_data_provider); + if (!coin) { + break; + } + coins[*outpoint] = *coin; + } + std::map<int, std::string> input_errors; + (void)SignTransaction(sign_transaction_tx_to, &provider, coins, fuzzed_data_provider.ConsumeIntegral<int>(), input_errors); + } + } + + { + SignatureData signature_data_1; + (void)ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, ConsumeScript(fuzzed_data_provider), signature_data_1); + SignatureData signature_data_2; + (void)ProduceSignature(provider, DUMMY_MAXIMUM_SIGNATURE_CREATOR, ConsumeScript(fuzzed_data_provider), signature_data_2); + } +} diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp index 3c1f911f7e..271062dc95 100644 --- a/src/test/fuzz/string.cpp +++ b/src/test/fuzz/string.cpp @@ -12,6 +12,7 @@ #include <rpc/server.h> #include <rpc/util.h> #include <script/descriptor.h> +#include <script/script.h> #include <serialize.h> #include <streams.h> #include <test/fuzz/FuzzedDataProvider.h> @@ -89,11 +90,15 @@ void test_one_input(const std::vector<uint8_t>& buffer) (void)urlDecode(random_string_1); (void)ValidAsCString(random_string_1); (void)_(random_string_1.c_str()); + try { + throw scriptnum_error{random_string_1}; + } catch (const std::runtime_error&) { + } { CDataStream data_stream{SER_NETWORK, INIT_PROTO_VERSION}; std::string s; - LimitedString<10> limited_string = LIMITED_STRING(s, 10); + auto limited_string = LIMITED_STRING(s, 10); data_stream << random_string_1; try { data_stream >> limited_string; @@ -108,7 +113,7 @@ void test_one_input(const std::vector<uint8_t>& buffer) } { CDataStream data_stream{SER_NETWORK, INIT_PROTO_VERSION}; - const LimitedString<10> limited_string = LIMITED_STRING(random_string_1, 10); + const auto limited_string = LIMITED_STRING(random_string_1, 10); data_stream << limited_string; std::string deserialized_string; data_stream >> deserialized_string; diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index f72d9380eb..f26878a704 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -8,9 +8,11 @@ #include <amount.h> #include <arith_uint256.h> #include <attributes.h> +#include <coins.h> #include <consensus/consensus.h> #include <primitives/transaction.h> #include <script/script.h> +#include <script/standard.h> #include <serialize.h> #include <streams.h> #include <test/fuzz/FuzzedDataProvider.h> @@ -19,6 +21,7 @@ #include <uint256.h> #include <version.h> +#include <algorithm> #include <cstdint> #include <optional> #include <string> @@ -30,6 +33,11 @@ NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataPr return {s.begin(), s.end()}; } +NODISCARD inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept +{ + return {ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION}; +} + NODISCARD inline std::vector<std::string> ConsumeRandomLengthStringVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16, const size_t max_string_length = 16) noexcept { const size_t n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size); @@ -86,10 +94,19 @@ NODISCARD inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_pro return CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()}; } +NODISCARD inline uint160 ConsumeUInt160(FuzzedDataProvider& fuzzed_data_provider) noexcept +{ + const std::vector<uint8_t> v160 = fuzzed_data_provider.ConsumeBytes<uint8_t>(160 / 8); + if (v160.size() != 160 / 8) { + return {}; + } + return uint160{v160}; +} + NODISCARD inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept { - const std::vector<unsigned char> v256 = fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint256)); - if (v256.size() != sizeof(uint256)) { + const std::vector<uint8_t> v256 = fuzzed_data_provider.ConsumeBytes<uint8_t>(256 / 8); + if (v256.size() != 256 / 8) { return {}; } return uint256{v256}; @@ -115,6 +132,43 @@ NODISCARD inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzze return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}}; } +NODISCARD inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept +{ + CTxDestination tx_destination; + switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) { + case 0: { + tx_destination = CNoDestination{}; + break; + } + case 1: { + tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)}; + break; + } + case 2: { + tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)}; + break; + } + case 3: { + tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)}; + break; + } + case 4: { + tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)}; + break; + } + case 5: { + WitnessUnknown witness_unknown{}; + witness_unknown.version = fuzzed_data_provider.ConsumeIntegral<int>(); + const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40); + witness_unknown.length = witness_unknown_program_1.size(); + std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program); + tx_destination = witness_unknown; + break; + } + } + return tx_destination; +} + template <typename T> NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept { @@ -149,4 +203,15 @@ NODISCARD bool AdditionOverflow(const T i, const T j) noexcept return std::numeric_limits<T>::max() - i < j; } +NODISCARD inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept +{ + for (const CTxIn& tx_in : tx.vin) { + const Coin& coin = inputs.AccessCoin(tx_in.prevout); + if (coin.IsSpent()) { + return true; + } + } + return false; +} + #endif // BITCOIN_TEST_FUZZ_UTIL_H diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index 512e48f8e5..45c9b90ee9 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -13,9 +13,18 @@ #include <boost/algorithm/string.hpp> #include <boost/test/unit_test.hpp> -BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup) +namespace getarg_tests{ + class LocalTestingSetup : BasicTestingSetup { + protected: + void SetupArgs(const std::vector<std::pair<std::string, unsigned int>>& args); + void ResetArgs(const std::string& strArg); + ArgsManager m_args; + }; +} + +BOOST_FIXTURE_TEST_SUITE(getarg_tests, LocalTestingSetup) -static void ResetArgs(const std::string& strArg) +void LocalTestingSetup :: ResetArgs(const std::string& strArg) { std::vector<std::string> vecArg; if (strArg.size()) @@ -30,14 +39,14 @@ static void ResetArgs(const std::string& strArg) vecChar.push_back(s.c_str()); std::string error; - BOOST_CHECK(gArgs.ParseParameters(vecChar.size(), vecChar.data(), error)); + BOOST_CHECK(m_args.ParseParameters(vecChar.size(), vecChar.data(), error)); } -static void SetupArgs(const std::vector<std::pair<std::string, unsigned int>>& args) +void LocalTestingSetup :: SetupArgs(const std::vector<std::pair<std::string, unsigned int>>& args) { - gArgs.ClearArgs(); + m_args.ClearArgs(); for (const auto& arg : args) { - gArgs.AddArg(arg.first, "", arg.second, OptionsCategory::OPTIONS); + m_args.AddArg(arg.first, "", arg.second, OptionsCategory::OPTIONS); } } @@ -46,52 +55,52 @@ BOOST_AUTO_TEST_CASE(boolarg) const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY); SetupArgs({foo}); ResetArgs("-foo"); - BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(m_args.GetBoolArg("-foo", true)); - BOOST_CHECK(!gArgs.GetBoolArg("-fo", false)); - BOOST_CHECK(gArgs.GetBoolArg("-fo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-fo", false)); + BOOST_CHECK(m_args.GetBoolArg("-fo", true)); - BOOST_CHECK(!gArgs.GetBoolArg("-fooo", false)); - BOOST_CHECK(gArgs.GetBoolArg("-fooo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-fooo", false)); + BOOST_CHECK(m_args.GetBoolArg("-fooo", true)); ResetArgs("-foo=0"); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", true)); ResetArgs("-foo=1"); - BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(m_args.GetBoolArg("-foo", true)); // New 0.6 feature: auto-map -nosomething to !-something: ResetArgs("-nofoo"); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", true)); ResetArgs("-nofoo=1"); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", true)); ResetArgs("-foo -nofoo"); // -nofoo should win - BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", true)); ResetArgs("-foo=1 -nofoo=1"); // -nofoo should win - BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", true)); ResetArgs("-foo=0 -nofoo=0"); // -nofoo=0 should win - BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(m_args.GetBoolArg("-foo", true)); // New 0.6 feature: treat -- same as -: ResetArgs("--foo=1"); - BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(m_args.GetBoolArg("-foo", true)); ResetArgs("--nofoo=1"); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", false)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", true)); } @@ -101,24 +110,24 @@ BOOST_AUTO_TEST_CASE(stringarg) const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY); SetupArgs({foo, bar}); ResetArgs(""); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), ""); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "eleven"); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), "eleven"); ResetArgs("-foo -bar"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), ""); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), ""); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), ""); ResetArgs("-foo="); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), ""); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), ""); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), ""); ResetArgs("-foo=11"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "11"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "11"); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), "11"); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), "11"); ResetArgs("-foo=eleven"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "eleven"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "eleven"); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), "eleven"); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), "eleven"); } @@ -128,20 +137,20 @@ BOOST_AUTO_TEST_CASE(intarg) const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY); SetupArgs({foo, bar}); ResetArgs(""); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 11), 11); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 0), 0); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 11), 11); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 0), 0); ResetArgs("-foo -bar"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 11), 0); - BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 11), 0); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 11), 0); + BOOST_CHECK_EQUAL(m_args.GetArg("-bar", 11), 0); ResetArgs("-foo=11 -bar=12"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 0), 11); - BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 11), 12); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 0), 11); + BOOST_CHECK_EQUAL(m_args.GetArg("-bar", 11), 12); ResetArgs("-foo=NaN -bar=NotANumber"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 1), 0); - BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 11), 0); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 1), 0); + BOOST_CHECK_EQUAL(m_args.GetArg("-bar", 11), 0); } BOOST_AUTO_TEST_CASE(doubledash) @@ -150,11 +159,11 @@ BOOST_AUTO_TEST_CASE(doubledash) const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY); SetupArgs({foo, bar}); ResetArgs("--foo"); - BOOST_CHECK_EQUAL(gArgs.GetBoolArg("-foo", false), true); + BOOST_CHECK_EQUAL(m_args.GetBoolArg("-foo", false), true); ResetArgs("--foo=verbose --bar=1"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "verbose"); - BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 0), 1); + BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), "verbose"); + BOOST_CHECK_EQUAL(m_args.GetArg("-bar", 0), 1); } BOOST_AUTO_TEST_CASE(boolargno) @@ -163,24 +172,24 @@ BOOST_AUTO_TEST_CASE(boolargno) const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY); SetupArgs({foo, bar}); ResetArgs("-nofoo"); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", false)); ResetArgs("-nofoo=1"); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", false)); ResetArgs("-nofoo=0"); - BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); - BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(m_args.GetBoolArg("-foo", true)); + BOOST_CHECK(m_args.GetBoolArg("-foo", false)); ResetArgs("-foo --nofoo"); // --nofoo should win - BOOST_CHECK(!gArgs.GetBoolArg("-foo", true)); - BOOST_CHECK(!gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", true)); + BOOST_CHECK(!m_args.GetBoolArg("-foo", false)); ResetArgs("-nofoo -foo"); // foo always wins: - BOOST_CHECK(gArgs.GetBoolArg("-foo", true)); - BOOST_CHECK(gArgs.GetBoolArg("-foo", false)); + BOOST_CHECK(m_args.GetBoolArg("-foo", true)); + BOOST_CHECK(m_args.GetBoolArg("-foo", false)); } BOOST_AUTO_TEST_CASE(logargs) @@ -200,7 +209,7 @@ BOOST_AUTO_TEST_CASE(logargs) }); // Log the arguments - gArgs.LogArgs(); + m_args.LogArgs(); LogInstance().DeleteCallback(print_connection); // Check that what should appear does, and what shouldn't doesn't. diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp index 04bf7c20c1..8c2712f764 100644 --- a/src/test/raii_event_tests.cpp +++ b/src/test/raii_event_tests.cpp @@ -4,9 +4,6 @@ #include <event2/event.h> -#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED -// It would probably be ideal to define dummy test(s) that report skipped, but boost::test doesn't seem to make that practical (at least not in versions available with common distros) - #include <map> #include <stdlib.h> @@ -16,6 +13,10 @@ #include <boost/test/unit_test.hpp> +BOOST_FIXTURE_TEST_SUITE(raii_event_tests, BasicTestingSetup) + +#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED + static std::map<void*, short> tags; static std::map<void*, uint16_t> orders; static uint16_t tagSequence = 0; @@ -34,8 +35,6 @@ static void tag_free(void* mem) { free(mem); } -BOOST_FIXTURE_TEST_SUITE(raii_event_tests, BasicTestingSetup) - BOOST_AUTO_TEST_CASE(raii_event_creation) { event_set_mem_functions(tag_malloc, realloc, tag_free); @@ -87,6 +86,14 @@ BOOST_AUTO_TEST_CASE(raii_event_order) event_set_mem_functions(malloc, realloc, free); } -BOOST_AUTO_TEST_SUITE_END() +#else + +BOOST_AUTO_TEST_CASE(raii_event_tests_SKIPPED) +{ + // It would probably be ideal to report skipped, but boost::test doesn't seem to make that practical (at least not in versions available with common distros) + BOOST_TEST_MESSAGE("Skipping raii_event_tess: libevent doesn't support event_set_mem_functions"); +} #endif // EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 56454f61f3..cb3ae290d1 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -102,7 +102,7 @@ static ScriptErrorDesc script_errors[]={ {SCRIPT_ERR_SIG_FINDANDDELETE, "SIG_FINDANDDELETE"}, }; -static const char *FormatScriptError(ScriptError_t err) +static std::string FormatScriptError(ScriptError_t err) { for (unsigned int i=0; i<ARRAYLEN(script_errors); ++i) if (script_errors[i].err == err) @@ -134,7 +134,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit); CMutableTransaction tx2 = tx; BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message); - BOOST_CHECK_MESSAGE(err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message); + BOOST_CHECK_MESSAGE(err == scriptError, FormatScriptError(err) + " where " + FormatScriptError((ScriptError_t)scriptError) + " expected: " + message); // Verify that removing flags from a passing test or adding flags to a failing test does not change the result. for (int i = 0; i < 16; ++i) { |