diff options
Diffstat (limited to 'src/test/fuzz')
-rw-r--r-- | src/test/fuzz/buffered_file.cpp | 4 | ||||
-rw-r--r-- | src/test/fuzz/coinscache_sim.cpp | 4 | ||||
-rw-r--r-- | src/test/fuzz/descriptor_parse.cpp | 96 | ||||
-rw-r--r-- | src/test/fuzz/load_external_block_file.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/mini_miner.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/package_eval.cpp | 4 | ||||
-rw-r--r-- | src/test/fuzz/script_flags.cpp | 21 | ||||
-rw-r--r-- | src/test/fuzz/script_sign.cpp | 13 | ||||
-rw-r--r-- | src/test/fuzz/tx_pool.cpp | 12 | ||||
-rw-r--r-- | src/test/fuzz/txorphan.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/util.cpp | 22 | ||||
-rw-r--r-- | src/test/fuzz/util.h | 4 | ||||
-rw-r--r-- | src/test/fuzz/util/descriptor.cpp | 72 | ||||
-rw-r--r-- | src/test/fuzz/util/descriptor.h | 48 |
14 files changed, 169 insertions, 137 deletions
diff --git a/src/test/fuzz/buffered_file.cpp b/src/test/fuzz/buffered_file.cpp index 813af63738..e30c19b265 100644 --- a/src/test/fuzz/buffered_file.cpp +++ b/src/test/fuzz/buffered_file.cpp @@ -20,9 +20,8 @@ FUZZ_TARGET(buffered_file) FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedFileProvider fuzzed_file_provider{fuzzed_data_provider}; std::optional<BufferedFile> opt_buffered_file; - CAutoFile fuzzed_file{ + AutoFile fuzzed_file{ fuzzed_file_provider.open(), - 0, ConsumeRandomLengthByteVector<std::byte>(fuzzed_data_provider), }; try { @@ -65,6 +64,5 @@ FUZZ_TARGET(buffered_file) }); } opt_buffered_file->GetPos(); - opt_buffered_file->GetVersion(); } } diff --git a/src/test/fuzz/coinscache_sim.cpp b/src/test/fuzz/coinscache_sim.cpp index f350c9d032..648e96b4a0 100644 --- a/src/test/fuzz/coinscache_sim.cpp +++ b/src/test/fuzz/coinscache_sim.cpp @@ -43,7 +43,9 @@ struct PrecomputedData for (uint32_t i = 0; i < NUM_OUTPOINTS; ++i) { uint32_t idx = (i * 1200U) >> 12; /* Map 3 or 4 entries to same txid. */ const uint8_t ser[4] = {uint8_t(idx), uint8_t(idx >> 8), uint8_t(idx >> 16), uint8_t(idx >> 24)}; - CSHA256().Write(PREFIX_O, 1).Write(ser, sizeof(ser)).Finalize(outpoints[i].hash.begin()); + uint256 txid; + CSHA256().Write(PREFIX_O, 1).Write(ser, sizeof(ser)).Finalize(txid.begin()); + outpoints[i].hash = Txid::FromUint256(txid); outpoints[i].n = i; } diff --git a/src/test/fuzz/descriptor_parse.cpp b/src/test/fuzz/descriptor_parse.cpp index 57129a60b8..5474b38204 100644 --- a/src/test/fuzz/descriptor_parse.cpp +++ b/src/test/fuzz/descriptor_parse.cpp @@ -7,104 +7,10 @@ #include <pubkey.h> #include <script/descriptor.h> #include <test/fuzz/fuzz.h> +#include <test/fuzz/util/descriptor.h> #include <util/chaintype.h> #include <util/strencodings.h> -//! Types are raw (un)compressed pubkeys, raw xonly pubkeys, raw privkeys (WIF), xpubs, xprvs. -static constexpr uint8_t KEY_TYPES_COUNT{6}; -//! How many keys we'll generate in total. -static constexpr size_t TOTAL_KEYS_GENERATED{std::numeric_limits<uint8_t>::max() + 1}; - -/** - * Converts a mocked descriptor string to a valid one. Every key in a mocked descriptor key is - * represented by 2 hex characters preceded by the '%' character. We parse the two hex characters - * as an index in a list of pre-generated keys. This list contains keys of the various types - * accepted in descriptor keys expressions. - */ -class MockedDescriptorConverter { - //! 256 keys of various types. - std::array<std::string, TOTAL_KEYS_GENERATED> keys_str; - -public: - // We derive the type of key to generate from the 1-byte id parsed from hex. - bool IdIsCompPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 0; } - bool IdIsUnCompPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 1; } - bool IdIsXOnlyPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 2; } - bool IdIsConstPrivKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 3; } - bool IdIsXpub(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 4; } - bool IdIsXprv(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 5; } - - //! When initializing the target, populate the list of keys. - void Init() { - // The data to use as a private key or a seed for an xprv. - std::array<std::byte, 32> key_data{std::byte{1}}; - // Generate keys of all kinds and store them in the keys array. - for (size_t i{0}; i < TOTAL_KEYS_GENERATED; i++) { - key_data[31] = std::byte(i); - - // If this is a "raw" key, generate a normal privkey. Otherwise generate - // an extended one. - if (IdIsCompPubKey(i) || IdIsUnCompPubKey(i) || IdIsXOnlyPubKey(i) || IdIsConstPrivKey(i)) { - CKey privkey; - privkey.Set(UCharCast(key_data.begin()), UCharCast(key_data.end()), !IdIsUnCompPubKey(i)); - if (IdIsCompPubKey(i) || IdIsUnCompPubKey(i)) { - CPubKey pubkey{privkey.GetPubKey()}; - keys_str[i] = HexStr(pubkey); - } else if (IdIsXOnlyPubKey(i)) { - const XOnlyPubKey pubkey{privkey.GetPubKey()}; - keys_str[i] = HexStr(pubkey); - } else { - keys_str[i] = EncodeSecret(privkey); - } - } else { - CExtKey ext_privkey; - ext_privkey.SetSeed(key_data); - if (IdIsXprv(i)) { - keys_str[i] = EncodeExtKey(ext_privkey); - } else { - const CExtPubKey ext_pubkey{ext_privkey.Neuter()}; - keys_str[i] = EncodeExtPubKey(ext_pubkey); - } - } - } - } - - //! Parse an id in the keys vectors from a 2-characters hex string. - std::optional<uint8_t> IdxFromHex(std::string_view hex_characters) const { - if (hex_characters.size() != 2) return {}; - auto idx = ParseHex(hex_characters); - if (idx.size() != 1) return {}; - return idx[0]; - } - - //! Get an actual descriptor string from a descriptor string whose keys were mocked. - std::optional<std::string> GetDescriptor(std::string_view mocked_desc) const { - // The smallest fragment would be "pk(%00)" - if (mocked_desc.size() < 7) return {}; - - // The actual descriptor string to be returned. - std::string desc; - desc.reserve(mocked_desc.size()); - - // Replace all occurrences of '%' followed by two hex characters with the corresponding key. - for (size_t i = 0; i < mocked_desc.size();) { - if (mocked_desc[i] == '%') { - if (i + 3 >= mocked_desc.size()) return {}; - if (const auto idx = IdxFromHex(mocked_desc.substr(i + 1, 2))) { - desc += keys_str[*idx]; - i += 3; - } else { - return {}; - } - } else { - desc += mocked_desc[i++]; - } - } - - return desc; - } -}; - //! The converter of mocked descriptors, needs to be initialized when the target is. MockedDescriptorConverter MOCKED_DESC_CONVERTER; diff --git a/src/test/fuzz/load_external_block_file.cpp b/src/test/fuzz/load_external_block_file.cpp index ae4f5d089b..6460261f0f 100644 --- a/src/test/fuzz/load_external_block_file.cpp +++ b/src/test/fuzz/load_external_block_file.cpp @@ -28,7 +28,7 @@ FUZZ_TARGET(load_external_block_file, .init = initialize_load_external_block_fil { FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedFileProvider fuzzed_file_provider{fuzzed_data_provider}; - CAutoFile fuzzed_block_file{fuzzed_file_provider.open(), CLIENT_VERSION}; + AutoFile fuzzed_block_file{fuzzed_file_provider.open()}; if (fuzzed_block_file.IsNull()) { return; } diff --git a/src/test/fuzz/mini_miner.cpp b/src/test/fuzz/mini_miner.cpp index 2f53943c31..84f9bb4ad0 100644 --- a/src/test/fuzz/mini_miner.cpp +++ b/src/test/fuzz/mini_miner.cpp @@ -25,7 +25,7 @@ void initialize_miner() static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); g_setup = testing_setup.get(); for (uint32_t i = 0; i < uint32_t{100}; ++i) { - g_available_coins.emplace_back(uint256::ZERO, i); + g_available_coins.emplace_back(Txid::FromUint256(uint256::ZERO), i); } } diff --git a/src/test/fuzz/package_eval.cpp b/src/test/fuzz/package_eval.cpp index 8658c0b45a..064930c5aa 100644 --- a/src/test/fuzz/package_eval.cpp +++ b/src/test/fuzz/package_eval.cpp @@ -252,10 +252,10 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool) } if (fuzzed_data_provider.ConsumeBool()) { const auto& txid = fuzzed_data_provider.ConsumeBool() ? - txs.back()->GetHash().ToUint256() : + txs.back()->GetHash() : PickValue(fuzzed_data_provider, mempool_outpoints).hash; const auto delta = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-50 * COIN, +50 * COIN); - tx_pool.PrioritiseTransaction(txid, delta); + tx_pool.PrioritiseTransaction(txid.ToUint256(), delta); } // Remember all added transactions diff --git a/src/test/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp index 3b8f5c068d..accb32f1cc 100644 --- a/src/test/fuzz/script_flags.cpp +++ b/src/test/fuzz/script_flags.cpp @@ -3,25 +3,22 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <consensus/amount.h> -#include <pubkey.h> +#include <primitives/transaction.h> #include <script/interpreter.h> +#include <serialize.h> #include <streams.h> +#include <test/fuzz/fuzz.h> #include <test/util/script.h> -#include <version.h> -#include <test/fuzz/fuzz.h> +#include <cassert> +#include <ios> +#include <utility> +#include <vector> FUZZ_TARGET(script_flags) { - CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); - try { - int nVersion; - ds >> nVersion; - ds.SetVersion(nVersion); - } catch (const std::ios_base::failure&) { - return; - } - + if (buffer.size() > 100'000) return; + DataStream ds{buffer}; try { const CTransaction tx(deserialize, TX_WITH_WITNESS, ds); diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp index 0944c91c4a..9c2966e0cb 100644 --- a/src/test/fuzz/script_sign.cpp +++ b/src/test/fuzz/script_sign.cpp @@ -125,18 +125,7 @@ FUZZ_TARGET(script_sign, .init = initialize_script_sign) } (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; - LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) { - 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<COutPoint, Coin> coins{ConsumeCoins(fuzzed_data_provider)}; std::map<int, bilingual_str> input_errors; (void)SignTransaction(sign_transaction_tx_to, &provider, coins, fuzzed_data_provider.ConsumeIntegral<int>(), input_errors); } diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp index 96095539ec..ffa0c1216e 100644 --- a/src/test/fuzz/tx_pool.cpp +++ b/src/test/fuzz/tx_pool.cpp @@ -277,10 +277,10 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool) } if (fuzzed_data_provider.ConsumeBool()) { const auto& txid = fuzzed_data_provider.ConsumeBool() ? - tx->GetHash().ToUint256() : + tx->GetHash() : PickValue(fuzzed_data_provider, outpoints_rbf).hash; const auto delta = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-50 * COIN, +50 * COIN); - tx_pool.PrioritiseTransaction(txid, delta); + tx_pool.PrioritiseTransaction(txid.ToUint256(), delta); } // Remember all removed and added transactions @@ -367,7 +367,7 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool) MockTime(fuzzed_data_provider, chainstate); - std::vector<uint256> txids; + std::vector<Txid> txids; txids.reserve(g_outpoints_coinbase_init_mature.size()); for (const auto& outpoint : g_outpoints_coinbase_init_mature) { txids.push_back(outpoint.hash); @@ -375,7 +375,7 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool) for (int i{0}; i <= 3; ++i) { // Add some immature and non-existent outpoints txids.push_back(g_outpoints_coinbase_init_immature.at(i).hash); - txids.push_back(ConsumeUInt256(fuzzed_data_provider)); + txids.push_back(Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider))); } SetMempoolConstraints(*node.args, fuzzed_data_provider); @@ -396,10 +396,10 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool) } if (fuzzed_data_provider.ConsumeBool()) { const auto txid = fuzzed_data_provider.ConsumeBool() ? - mut_tx.GetHash().ToUint256() : + mut_tx.GetHash() : PickValue(fuzzed_data_provider, txids); const auto delta = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-50 * COIN, +50 * COIN); - tx_pool.PrioritiseTransaction(txid, delta); + tx_pool.PrioritiseTransaction(txid.ToUint256(), delta); } const auto tx = MakeTransactionRef(mut_tx); diff --git a/src/test/fuzz/txorphan.cpp b/src/test/fuzz/txorphan.cpp index a84dc951fc..e9ceb299fe 100644 --- a/src/test/fuzz/txorphan.cpp +++ b/src/test/fuzz/txorphan.cpp @@ -39,7 +39,7 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage) std::vector<COutPoint> outpoints; // initial outpoints used to construct transactions later for (uint8_t i = 0; i < 4; i++) { - outpoints.emplace_back(uint256{i}, 0); + outpoints.emplace_back(Txid::FromUint256(uint256{i}), 0); } // if true, allow duplicate input when constructing tx const bool duplicate_input = fuzzed_data_provider.ConsumeBool(); diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp index 87ca2f6aed..90ef58d437 100644 --- a/src/test/fuzz/util.cpp +++ b/src/test/fuzz/util.cpp @@ -40,7 +40,7 @@ int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optiona return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(min.value_or(time_min), max.value_or(time_max)); } -CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<uint256>>& prevout_txids, const int max_num_in, const int max_num_out) noexcept +CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<Txid>>& prevout_txids, const int max_num_in, const int max_num_out) noexcept { CMutableTransaction tx_mut; const auto p2wsh_op_true = fuzzed_data_provider.ConsumeBool(); @@ -53,7 +53,7 @@ CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, for (int i = 0; i < num_in; ++i) { const auto& txid_prev = prevout_txids ? PickValue(fuzzed_data_provider, *prevout_txids) : - ConsumeUInt256(fuzzed_data_provider); + Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider)); const auto index_out = fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, max_num_out); const auto sequence = ConsumeSequence(fuzzed_data_provider); const auto script_sig = p2wsh_op_true ? CScript{} : ConsumeScript(fuzzed_data_provider); @@ -164,6 +164,24 @@ uint32_t ConsumeSequence(FuzzedDataProvider& fuzzed_data_provider) noexcept fuzzed_data_provider.ConsumeIntegral<uint32_t>(); } +std::map<COutPoint, Coin> ConsumeCoins(FuzzedDataProvider& fuzzed_data_provider) noexcept +{ + std::map<COutPoint, Coin> coins; + LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) { + 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; + } + + return coins; +} + CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept { CTxDestination tx_destination; diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 0ad2ed6128..045476ab86 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -145,7 +145,7 @@ template <typename WeakEnumType, size_t size> [[nodiscard]] int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min = std::nullopt, const std::optional<int64_t>& max = std::nullopt) noexcept; -[[nodiscard]] CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<uint256>>& prevout_txids, const int max_num_in = 10, const int max_num_out = 10) noexcept; +[[nodiscard]] CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<Txid>>& prevout_txids, const int max_num_in = 10, const int max_num_out = 10) noexcept; [[nodiscard]] CScriptWitness ConsumeScriptWitness(FuzzedDataProvider& fuzzed_data_provider, const size_t max_stack_elem_size = 32) noexcept; @@ -181,6 +181,8 @@ template <typename WeakEnumType, size_t size> return UintToArith256(ConsumeUInt256(fuzzed_data_provider)); } +[[nodiscard]] std::map<COutPoint, Coin> ConsumeCoins(FuzzedDataProvider& fuzzed_data_provider) noexcept; + [[nodiscard]] CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept; [[nodiscard]] CKey ConsumePrivateKey(FuzzedDataProvider& fuzzed_data_provider, std::optional<bool> compressed = std::nullopt) noexcept; diff --git a/src/test/fuzz/util/descriptor.cpp b/src/test/fuzz/util/descriptor.cpp new file mode 100644 index 0000000000..5bfd2721ce --- /dev/null +++ b/src/test/fuzz/util/descriptor.cpp @@ -0,0 +1,72 @@ +// Copyright (c) 2023-present 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/util/descriptor.h> + +void MockedDescriptorConverter::Init() { + // The data to use as a private key or a seed for an xprv. + std::array<std::byte, 32> key_data{std::byte{1}}; + // Generate keys of all kinds and store them in the keys array. + for (size_t i{0}; i < TOTAL_KEYS_GENERATED; i++) { + key_data[31] = std::byte(i); + + // If this is a "raw" key, generate a normal privkey. Otherwise generate + // an extended one. + if (IdIsCompPubKey(i) || IdIsUnCompPubKey(i) || IdIsXOnlyPubKey(i) || IdIsConstPrivKey(i)) { + CKey privkey; + privkey.Set(UCharCast(key_data.begin()), UCharCast(key_data.end()), !IdIsUnCompPubKey(i)); + if (IdIsCompPubKey(i) || IdIsUnCompPubKey(i)) { + CPubKey pubkey{privkey.GetPubKey()}; + keys_str[i] = HexStr(pubkey); + } else if (IdIsXOnlyPubKey(i)) { + const XOnlyPubKey pubkey{privkey.GetPubKey()}; + keys_str[i] = HexStr(pubkey); + } else { + keys_str[i] = EncodeSecret(privkey); + } + } else { + CExtKey ext_privkey; + ext_privkey.SetSeed(key_data); + if (IdIsXprv(i)) { + keys_str[i] = EncodeExtKey(ext_privkey); + } else { + const CExtPubKey ext_pubkey{ext_privkey.Neuter()}; + keys_str[i] = EncodeExtPubKey(ext_pubkey); + } + } + } +} + +std::optional<uint8_t> MockedDescriptorConverter::IdxFromHex(std::string_view hex_characters) const { + if (hex_characters.size() != 2) return {}; + auto idx = ParseHex(hex_characters); + if (idx.size() != 1) return {}; + return idx[0]; +} + +std::optional<std::string> MockedDescriptorConverter::GetDescriptor(std::string_view mocked_desc) const { + // The smallest fragment would be "pk(%00)" + if (mocked_desc.size() < 7) return {}; + + // The actual descriptor string to be returned. + std::string desc; + desc.reserve(mocked_desc.size()); + + // Replace all occurrences of '%' followed by two hex characters with the corresponding key. + for (size_t i = 0; i < mocked_desc.size();) { + if (mocked_desc[i] == '%') { + if (i + 3 >= mocked_desc.size()) return {}; + if (const auto idx = IdxFromHex(mocked_desc.substr(i + 1, 2))) { + desc += keys_str[*idx]; + i += 3; + } else { + return {}; + } + } else { + desc += mocked_desc[i++]; + } + } + + return desc; +} diff --git a/src/test/fuzz/util/descriptor.h b/src/test/fuzz/util/descriptor.h new file mode 100644 index 0000000000..6289b91b07 --- /dev/null +++ b/src/test/fuzz/util/descriptor.h @@ -0,0 +1,48 @@ +// Copyright (c) 2023-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H +#define BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H + +#include <key_io.h> +#include <util/strencodings.h> +#include <script/descriptor.h> + +#include <functional> + +/** + * Converts a mocked descriptor string to a valid one. Every key in a mocked descriptor key is + * represented by 2 hex characters preceded by the '%' character. We parse the two hex characters + * as an index in a list of pre-generated keys. This list contains keys of the various types + * accepted in descriptor keys expressions. + */ +class MockedDescriptorConverter { +private: + //! Types are raw (un)compressed pubkeys, raw xonly pubkeys, raw privkeys (WIF), xpubs, xprvs. + static constexpr uint8_t KEY_TYPES_COUNT{6}; + //! How many keys we'll generate in total. + static constexpr size_t TOTAL_KEYS_GENERATED{std::numeric_limits<uint8_t>::max() + 1}; + //! 256 keys of various types. + std::array<std::string, TOTAL_KEYS_GENERATED> keys_str; + +public: + // We derive the type of key to generate from the 1-byte id parsed from hex. + bool IdIsCompPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 0; } + bool IdIsUnCompPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 1; } + bool IdIsXOnlyPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 2; } + bool IdIsConstPrivKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 3; } + bool IdIsXpub(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 4; } + bool IdIsXprv(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 5; } + + //! When initializing the target, populate the list of keys. + void Init(); + + //! Parse an id in the keys vectors from a 2-characters hex string. + std::optional<uint8_t> IdxFromHex(std::string_view hex_characters) const; + + //! Get an actual descriptor string from a descriptor string whose keys were mocked. + std::optional<std::string> GetDescriptor(std::string_view mocked_desc) const; +}; + +#endif // BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H |