aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/fuzz/fees.cpp3
-rw-r--r--src/test/fuzz/integer.cpp17
-rw-r--r--src/test/fuzz/kitchen_sink.cpp25
-rw-r--r--src/test/fuzz/message.cpp48
-rw-r--r--src/test/fuzz/parse_hd_keypath.cpp10
-rw-r--r--src/test/fuzz/policy_estimator.cpp69
-rw-r--r--src/test/fuzz/rbf.cpp47
-rw-r--r--src/test/fuzz/scriptnum_ops.cpp6
-rw-r--r--src/test/fuzz/string.cpp4
-rw-r--r--src/test/fuzz/system.cpp123
-rw-r--r--src/test/fuzz/util.h18
-rw-r--r--src/test/sanity_tests.cpp2
-rw-r--r--src/test/transaction_tests.cpp1
-rw-r--r--src/test/util/logging.cpp8
-rw-r--r--src/test/util/logging.h14
-rw-r--r--src/test/validation_block_tests.cpp34
16 files changed, 409 insertions, 20 deletions
diff --git a/src/test/fuzz/fees.cpp b/src/test/fuzz/fees.cpp
index 090994263e..f29acace23 100644
--- a/src/test/fuzz/fees.cpp
+++ b/src/test/fuzz/fees.cpp
@@ -8,6 +8,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
+#include <util/fees.h>
#include <cstdint>
#include <string>
@@ -23,4 +24,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
const CAmount rounded_fee = fee_filter_rounder.round(current_minimum_fee);
assert(MoneyRange(rounded_fee));
}
+ const FeeReason fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::NONE, FeeReason::HALF_ESTIMATE, FeeReason::FULL_ESTIMATE, FeeReason::DOUBLE_ESTIMATE, FeeReason::CONSERVATIVE, FeeReason::MEMPOOL_MIN, FeeReason::PAYTXFEE, FeeReason::FALLBACK, FeeReason::REQUIRED});
+ (void)StringForFeeReason(fee_reason);
}
diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp
index 9dbf0fcc90..35d6804d4f 100644
--- a/src/test/fuzz/integer.cpp
+++ b/src/test/fuzz/integer.cpp
@@ -24,8 +24,8 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
-#include <time.h>
#include <uint256.h>
+#include <util/check.h>
#include <util/moneystr.h>
#include <util/strencodings.h>
#include <util/string.h>
@@ -35,6 +35,7 @@
#include <cassert>
#include <chrono>
+#include <ctime>
#include <limits>
#include <set>
#include <vector>
@@ -147,11 +148,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
const CScriptNum script_num{i64};
(void)script_num.getint();
- // Avoid negation failure:
- // script/script.h:332:35: runtime error: negation of -9223372036854775808 cannot be represented in type 'int64_t' (aka 'long'); cast to an unsigned type to negate this value to itself
- if (script_num != CScriptNum{std::numeric_limits<int64_t>::min()}) {
- (void)script_num.getvch();
- }
+ (void)script_num.getvch();
const arith_uint256 au256 = UintToArith256(u256);
assert(ArithToUint256(au256) == u256);
@@ -287,8 +284,12 @@ void test_one_input(const std::vector<uint8_t>& buffer)
try {
const uint64_t deserialized_u64 = ReadCompactSize(stream);
assert(u64 == deserialized_u64 && stream.empty());
+ } catch (const std::ios_base::failure&) {
}
- catch (const std::ios_base::failure&) {
- }
+ }
+
+ try {
+ CHECK_NONFATAL(b);
+ } catch (const NonFatalCheckError&) {
}
}
diff --git a/src/test/fuzz/kitchen_sink.cpp b/src/test/fuzz/kitchen_sink.cpp
new file mode 100644
index 0000000000..af6dc71322
--- /dev/null
+++ b/src/test/fuzz/kitchen_sink.cpp
@@ -0,0 +1,25 @@
+// 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 <rpc/util.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <util/error.h>
+
+#include <cstdint>
+#include <vector>
+
+// The fuzzing kitchen sink: Fuzzing harness for functions that need to be
+// fuzzed but a.) don't belong in any existing fuzzing harness file, and
+// b.) are not important enough to warrant their own fuzzing harness file.
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+
+ const TransactionError transaction_error = fuzzed_data_provider.PickValueInArray<TransactionError>({TransactionError::OK, TransactionError::MISSING_INPUTS, TransactionError::ALREADY_IN_CHAIN, TransactionError::P2P_DISABLED, TransactionError::MEMPOOL_REJECTED, TransactionError::MEMPOOL_ERROR, TransactionError::INVALID_PSBT, TransactionError::PSBT_MISMATCH, TransactionError::SIGHASH_MISMATCH, TransactionError::MAX_FEE_EXCEEDED});
+ (void)JSONRPCTransactionError(transaction_error);
+ (void)RPCErrorFromTransactionError(transaction_error);
+ (void)TransactionErrorString(transaction_error);
+}
diff --git a/src/test/fuzz/message.cpp b/src/test/fuzz/message.cpp
new file mode 100644
index 0000000000..dfa98a812b
--- /dev/null
+++ b/src/test/fuzz/message.cpp
@@ -0,0 +1,48 @@
+// 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 <key_io.h>
+#include <optional.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <util/message.h>
+#include <util/strencodings.h>
+
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#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::string random_message = fuzzed_data_provider.ConsumeRandomLengthString(1024);
+ {
+ const std::vector<uint8_t> random_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ CKey private_key;
+ private_key.Set(random_bytes.begin(), random_bytes.end(), fuzzed_data_provider.ConsumeBool());
+ std::string signature;
+ const bool message_signed = MessageSign(private_key, random_message, signature);
+ if (private_key.IsValid()) {
+ assert(message_signed);
+ const MessageVerificationResult verification_result = MessageVerify(EncodeDestination(PKHash(private_key.GetPubKey().GetID())), signature, random_message);
+ assert(verification_result == MessageVerificationResult::OK);
+ }
+ }
+ {
+ (void)MessageHash(random_message);
+ (void)MessageVerify(fuzzed_data_provider.ConsumeRandomLengthString(1024), fuzzed_data_provider.ConsumeRandomLengthString(1024), random_message);
+ (void)SigningResultString(fuzzed_data_provider.PickValueInArray({SigningResult::OK, SigningResult::PRIVATE_KEY_NOT_AVAILABLE, SigningResult::SIGNING_FAILED}));
+ }
+}
diff --git a/src/test/fuzz/parse_hd_keypath.cpp b/src/test/fuzz/parse_hd_keypath.cpp
index 9a23f4b2d4..f668ca8c48 100644
--- a/src/test/fuzz/parse_hd_keypath.cpp
+++ b/src/test/fuzz/parse_hd_keypath.cpp
@@ -2,12 +2,22 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
#include <util/bip32.h>
+#include <cstdint>
+#include <vector>
+
void test_one_input(const std::vector<uint8_t>& buffer)
{
const std::string keypath_str(buffer.begin(), buffer.end());
std::vector<uint32_t> keypath;
(void)ParseHDKeypath(keypath_str, keypath);
+
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ const std::vector<uint32_t> random_keypath = ConsumeRandomLengthIntegralVector<uint32_t>(fuzzed_data_provider);
+ (void)FormatHDKeypath(random_keypath);
+ (void)WriteHDKeypath(random_keypath);
}
diff --git a/src/test/fuzz/policy_estimator.cpp b/src/test/fuzz/policy_estimator.cpp
new file mode 100644
index 0000000000..201f49c87b
--- /dev/null
+++ b/src/test/fuzz/policy_estimator.cpp
@@ -0,0 +1,69 @@
+// 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 <policy/fees.h>
+#include <primitives/transaction.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <txmempool.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());
+ CBlockPolicyEstimator block_policy_estimator;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 3)) {
+ case 0: {
+ const Optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!mtx) {
+ break;
+ }
+ const CTransaction tx{*mtx};
+ block_policy_estimator.processTransaction(ConsumeTxMemPoolEntry(fuzzed_data_provider, tx), fuzzed_data_provider.ConsumeBool());
+ if (fuzzed_data_provider.ConsumeBool()) {
+ (void)block_policy_estimator.removeTx(tx.GetHash(), /* inBlock */ fuzzed_data_provider.ConsumeBool());
+ }
+ break;
+ }
+ case 1: {
+ std::vector<CTxMemPoolEntry> mempool_entries;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const Optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!mtx) {
+ break;
+ }
+ const CTransaction tx{*mtx};
+ mempool_entries.push_back(ConsumeTxMemPoolEntry(fuzzed_data_provider, tx));
+ }
+ std::vector<const CTxMemPoolEntry*> ptrs;
+ ptrs.reserve(mempool_entries.size());
+ for (const CTxMemPoolEntry& mempool_entry : mempool_entries) {
+ ptrs.push_back(&mempool_entry);
+ }
+ block_policy_estimator.processBlock(fuzzed_data_provider.ConsumeIntegral<unsigned int>(), ptrs);
+ break;
+ }
+ case 2: {
+ (void)block_policy_estimator.removeTx(ConsumeUInt256(fuzzed_data_provider), /* inBlock */ fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 3: {
+ block_policy_estimator.FlushUnconfirmed();
+ break;
+ }
+ }
+ (void)block_policy_estimator.estimateFee(fuzzed_data_provider.ConsumeIntegral<int>());
+ EstimationResult result;
+ (void)block_policy_estimator.estimateRawFee(fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeFloatingPoint<double>(), fuzzed_data_provider.PickValueInArray({FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}), fuzzed_data_provider.ConsumeBool() ? &result : nullptr);
+ FeeCalculation fee_calculation;
+ (void)block_policy_estimator.estimateSmartFee(fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeBool() ? &fee_calculation : nullptr, fuzzed_data_provider.ConsumeBool());
+ (void)block_policy_estimator.HighestTargetTracked(fuzzed_data_provider.PickValueInArray({FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}));
+ }
+}
diff --git a/src/test/fuzz/rbf.cpp b/src/test/fuzz/rbf.cpp
new file mode 100644
index 0000000000..eb54b05df9
--- /dev/null
+++ b/src/test/fuzz/rbf.cpp
@@ -0,0 +1,47 @@
+// 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 <policy/rbf.h>
+#include <primitives/transaction.h>
+#include <sync.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <txmempool.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());
+ Optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!mtx) {
+ return;
+ }
+ CTxMemPool pool;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const Optional<CMutableTransaction> another_mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (!another_mtx) {
+ break;
+ }
+ const CTransaction another_tx{*another_mtx};
+ if (fuzzed_data_provider.ConsumeBool() && !mtx->vin.empty()) {
+ mtx->vin[0].prevout = COutPoint{another_tx.GetHash(), 0};
+ }
+ LOCK2(cs_main, pool.cs);
+ pool.addUnchecked(ConsumeTxMemPoolEntry(fuzzed_data_provider, another_tx));
+ }
+ const CTransaction tx{*mtx};
+ if (fuzzed_data_provider.ConsumeBool()) {
+ LOCK2(cs_main, pool.cs);
+ pool.addUnchecked(ConsumeTxMemPoolEntry(fuzzed_data_provider, tx));
+ }
+ {
+ LOCK(pool.cs);
+ (void)IsRBFOptIn(tx, pool);
+ }
+}
diff --git a/src/test/fuzz/scriptnum_ops.cpp b/src/test/fuzz/scriptnum_ops.cpp
index 42b1432f13..f4e079fb89 100644
--- a/src/test/fuzz/scriptnum_ops.cpp
+++ b/src/test/fuzz/scriptnum_ops.cpp
@@ -129,10 +129,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
break;
}
(void)script_num.getint();
- // Avoid negation failure:
- // script/script.h:332:35: runtime error: negation of -9223372036854775808 cannot be represented in type 'int64_t' (aka 'long'); cast to an unsigned type to negate this value to itself
- if (script_num != CScriptNum{std::numeric_limits<int64_t>::min()}) {
- (void)script_num.getvch();
- }
+ (void)script_num.getvch();
}
}
diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp
index 3de0cf8db7..49bee0e81f 100644
--- a/src/test/fuzz/string.cpp
+++ b/src/test/fuzz/string.cpp
@@ -115,4 +115,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(data_stream.empty());
assert(deserialized_string == random_string_1);
}
+ {
+ int64_t amount_out;
+ (void)ParseFixedPoint(random_string_1, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1024), &amount_out);
+ }
}
diff --git a/src/test/fuzz/system.cpp b/src/test/fuzz/system.cpp
new file mode 100644
index 0000000000..7f378c2b13
--- /dev/null
+++ b/src/test/fuzz/system.cpp
@@ -0,0 +1,123 @@
+// 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 <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <util/system.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace {
+std::string GetArgumentName(const std::string& name)
+{
+ size_t idx = name.find('=');
+ if (idx == std::string::npos) {
+ idx = name.size();
+ }
+ return name.substr(0, idx);
+}
+} // namespace
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ ArgsManager args_manager{};
+
+ if (fuzzed_data_provider.ConsumeBool()) {
+ SetupHelpOptions(args_manager);
+ }
+
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 7)) {
+ case 0: {
+ args_manager.SelectConfigNetwork(fuzzed_data_provider.ConsumeRandomLengthString(16));
+ break;
+ }
+ case 1: {
+ args_manager.SoftSetArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeRandomLengthString(16));
+ break;
+ }
+ case 2: {
+ args_manager.ForceSetArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeRandomLengthString(16));
+ break;
+ }
+ case 3: {
+ args_manager.SoftSetBoolArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 4: {
+ const OptionsCategory options_category = fuzzed_data_provider.PickValueInArray<OptionsCategory>({OptionsCategory::OPTIONS, OptionsCategory::CONNECTION, OptionsCategory::WALLET, OptionsCategory::WALLET_DEBUG_TEST, OptionsCategory::ZMQ, OptionsCategory::DEBUG_TEST, OptionsCategory::CHAINPARAMS, OptionsCategory::NODE_RELAY, OptionsCategory::BLOCK_CREATION, OptionsCategory::RPC, OptionsCategory::GUI, OptionsCategory::COMMANDS, OptionsCategory::REGISTER_COMMANDS, OptionsCategory::HIDDEN});
+ // Avoid hitting:
+ // util/system.cpp:425: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed.
+ const std::string argument_name = GetArgumentName(fuzzed_data_provider.ConsumeRandomLengthString(16));
+ if (args_manager.GetArgFlags(argument_name) != nullopt) {
+ break;
+ }
+ args_manager.AddArg(argument_name, fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeIntegral<unsigned int>(), options_category);
+ break;
+ }
+ case 5: {
+ // Avoid hitting:
+ // util/system.cpp:425: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed.
+ const std::vector<std::string> names = ConsumeRandomLengthStringVector(fuzzed_data_provider);
+ std::vector<std::string> hidden_arguments;
+ for (const std::string& name : names) {
+ const std::string hidden_argument = GetArgumentName(name);
+ if (args_manager.GetArgFlags(hidden_argument) != nullopt) {
+ continue;
+ }
+ if (std::find(hidden_arguments.begin(), hidden_arguments.end(), hidden_argument) != hidden_arguments.end()) {
+ continue;
+ }
+ hidden_arguments.push_back(hidden_argument);
+ }
+ args_manager.AddHiddenArgs(hidden_arguments);
+ break;
+ }
+ case 6: {
+ args_manager.ClearArgs();
+ break;
+ }
+ case 7: {
+ const std::vector<std::string> random_arguments = ConsumeRandomLengthStringVector(fuzzed_data_provider);
+ std::vector<const char*> argv;
+ argv.resize(random_arguments.size());
+ for (const std::string& random_argument : random_arguments) {
+ argv.push_back(random_argument.c_str());
+ }
+ try {
+ std::string error;
+ (void)args_manager.ParseParameters(argv.size(), argv.data(), error);
+ } catch (const std::logic_error&) {
+ }
+ break;
+ }
+ }
+ }
+
+ const std::string s1 = fuzzed_data_provider.ConsumeRandomLengthString(16);
+ const std::string s2 = fuzzed_data_provider.ConsumeRandomLengthString(16);
+ const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ const bool b = fuzzed_data_provider.ConsumeBool();
+
+ (void)args_manager.GetArg(s1, i64);
+ (void)args_manager.GetArg(s1, s2);
+ (void)args_manager.GetArgFlags(s1);
+ (void)args_manager.GetArgs(s1);
+ (void)args_manager.GetBoolArg(s1, b);
+ try {
+ (void)args_manager.GetChainName();
+ } catch (const std::runtime_error&) {
+ }
+ (void)args_manager.GetHelpMessage();
+ (void)args_manager.GetUnrecognizedSections();
+ (void)args_manager.GetUnsuitableSectionOnlyArgs();
+ (void)args_manager.IsArgNegated(s1);
+ (void)args_manager.IsArgSet(s1);
+
+ (void)HelpRequested(args_manager);
+}
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 9c7b0d47a2..501bb1de5a 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -8,12 +8,15 @@
#include <amount.h>
#include <arith_uint256.h>
#include <attributes.h>
+#include <consensus/consensus.h>
#include <optional.h>
+#include <primitives/transaction.h>
#include <script/script.h>
#include <serialize.h>
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <txmempool.h>
#include <uint256.h>
#include <version.h>
@@ -97,6 +100,21 @@ NODISCARD inline arith_uint256 ConsumeArithUInt256(FuzzedDataProvider& fuzzed_da
return UintToArith256(ConsumeUInt256(fuzzed_data_provider));
}
+NODISCARD inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider, const CTransaction& tx) noexcept
+{
+ // Avoid:
+ // policy/feerate.cpp:28:34: runtime error: signed integer overflow: 34873208148477500 * 1000 cannot be represented in type 'long'
+ //
+ // Reproduce using CFeeRate(348732081484775, 10).GetFeePerK()
+ const CAmount fee = std::min<CAmount>(ConsumeMoney(fuzzed_data_provider), std::numeric_limits<CAmount>::max() / static_cast<CAmount>(100000));
+ assert(MoneyRange(fee));
+ const int64_t time = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ const unsigned int entry_height = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
+ const bool spends_coinbase = fuzzed_data_provider.ConsumeBool();
+ const unsigned int sig_op_cost = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, MAX_BLOCK_SIGOPS_COST);
+ return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
+}
+
template <typename T>
NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept
{
diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp
index 4d50845256..9a490aaf6b 100644
--- a/src/test/sanity_tests.cpp
+++ b/src/test/sanity_tests.cpp
@@ -14,7 +14,7 @@ BOOST_AUTO_TEST_CASE(basic_sanity)
{
BOOST_CHECK_MESSAGE(glibc_sanity_test() == true, "libc sanity test");
BOOST_CHECK_MESSAGE(glibcxx_sanity_test() == true, "stdlib sanity test");
- BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "openssl ECC test");
+ BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "secp256k1 sanity test");
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 9d0ae56c3f..ddbc68f8e2 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -305,7 +305,6 @@ BOOST_AUTO_TEST_CASE(test_Get)
t1.vout[0].scriptPubKey << OP_1;
BOOST_CHECK(AreInputsStandard(CTransaction(t1), coins));
- BOOST_CHECK_EQUAL(coins.GetValueIn(CTransaction(t1)), (50+21+22)*CENT);
}
static void CreateCreditAndSpend(const FillableSigningProvider& keystore, const CScript& outscript, CTransactionRef& output, CMutableTransaction& input, bool success = true)
diff --git a/src/test/util/logging.cpp b/src/test/util/logging.cpp
index fe2e69104b..65a64f2384 100644
--- a/src/test/util/logging.cpp
+++ b/src/test/util/logging.cpp
@@ -11,13 +11,13 @@
#include <stdexcept>
-DebugLogHelper::DebugLogHelper(std::string message)
- : m_message{std::move(message)}
+DebugLogHelper::DebugLogHelper(std::string message, MatchFn match)
+ : m_message{std::move(message)}, m_match(std::move(match))
{
m_print_connection = LogInstance().PushBackCallback(
[this](const std::string& s) {
if (m_found) return;
- m_found = s.find(m_message) != std::string::npos;
+ m_found = s.find(m_message) != std::string::npos && m_match(&s);
});
noui_test_redirect();
}
@@ -26,7 +26,7 @@ void DebugLogHelper::check_found()
{
noui_reconnect();
LogInstance().DeleteCallback(m_print_connection);
- if (!m_found) {
+ if (!m_found && m_match(nullptr)) {
throw std::runtime_error(strprintf("'%s' not found in debug log\n", m_message));
}
}
diff --git a/src/test/util/logging.h b/src/test/util/logging.h
index 45ec44173c..1fcf7ca305 100644
--- a/src/test/util/logging.h
+++ b/src/test/util/logging.h
@@ -17,10 +17,22 @@ class DebugLogHelper
bool m_found{false};
std::list<std::function<void(const std::string&)>>::iterator m_print_connection;
+ //! Custom match checking function.
+ //!
+ //! Invoked with pointers to lines containing matching strings, and with
+ //! null if check_found() is called without any successful match.
+ //!
+ //! Can return true to enable default DebugLogHelper behavior of:
+ //! (1) ending search after first successful match, and
+ //! (2) raising an error in check_found if no match was found
+ //! Can return false to do the opposite in either case.
+ using MatchFn = std::function<bool(const std::string* line)>;
+ MatchFn m_match;
+
void check_found();
public:
- DebugLogHelper(std::string message);
+ DebugLogHelper(std::string message, MatchFn match = [](const std::string*){ return true; });
~DebugLogHelper() { check_found(); }
};
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index b8af869b8e..c345f1eafb 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -340,4 +340,38 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
rpc_thread.join();
}
}
+
+BOOST_AUTO_TEST_CASE(witness_commitment_index)
+{
+ CScript pubKey;
+ pubKey << 1 << OP_TRUE;
+ auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(pubKey);
+ CBlock pblock = ptemplate->block;
+
+ CTxOut witness;
+ witness.scriptPubKey.resize(MINIMUM_WITNESS_COMMITMENT);
+ witness.scriptPubKey[0] = OP_RETURN;
+ witness.scriptPubKey[1] = 0x24;
+ witness.scriptPubKey[2] = 0xaa;
+ witness.scriptPubKey[3] = 0x21;
+ witness.scriptPubKey[4] = 0xa9;
+ witness.scriptPubKey[5] = 0xed;
+
+ // A witness larger than the minimum size is still valid
+ CTxOut min_plus_one = witness;
+ min_plus_one.scriptPubKey.resize(MINIMUM_WITNESS_COMMITMENT + 1);
+
+ CTxOut invalid = witness;
+ invalid.scriptPubKey[0] = OP_VERIFY;
+
+ CMutableTransaction txCoinbase(*pblock.vtx[0]);
+ txCoinbase.vout.resize(4);
+ txCoinbase.vout[0] = witness;
+ txCoinbase.vout[1] = witness;
+ txCoinbase.vout[2] = min_plus_one;
+ txCoinbase.vout[3] = invalid;
+ pblock.vtx[0] = MakeTransactionRef(std::move(txCoinbase));
+
+ BOOST_CHECK_EQUAL(GetWitnessCommitmentIndex(pblock), 2);
+}
BOOST_AUTO_TEST_SUITE_END()