6#include <chainparams.h>
26#include <validation.h>
50 static const auto testing_setup{MakeNoLogFileContext<const TestingSetup>()};
55void initialize_spkm_migration()
57 static const auto testing_setup{MakeNoLogFileContext<const TestingSetup>()};
65 if (!desc_str.has_value())
return std::nullopt;
70 std::vector<std::unique_ptr<Descriptor>> parsed_descs =
Parse(desc_str.value(),
keys, error,
false);
71 if (parsed_descs.empty())
return std::nullopt;
76 std::vector<CScript> scripts_temp;
78 if (!parsed_descs.at(0)->Expand(0,
keys, scripts_temp, out_keys, &temp_cache))
return std::nullopt;
80 WalletDescriptor w_desc{std::move(parsed_descs.at(0)), 0, 0, 1, 1};
81 return std::make_pair(w_desc,
keys);
86 LOCK(keystore.cs_wallet);
87 auto spk_manager_res = keystore.AddWalletDescriptor(wallet_desc,
keys,
"",
false);
88 if (!spk_manager_res)
return nullptr;
89 return &spk_manager_res.value().get();
100 CWallet&
wallet{*wallet_ptr};
104 wallet.SetLastBlockProcessed(chainstate.m_chain.Height(), chainstate.m_chain.Tip()->GetBlockHash());
105 wallet.m_keypool_size = 1;
109 if (!wallet_desc.has_value())
return;
111 if (spk_manager ==
nullptr)
return;
115 if (!wallet_desc.has_value()) {
119 if (spk_manager->CanUpdateToWalletDescriptor(wallet_desc->first, error)) {
121 if (new_spk_manager !=
nullptr) spk_manager = new_spk_manager;
125 bool good_data{
true};
131 if (spk_manager->IsMine(
script)) {
132 assert(spk_manager->GetScriptPubKeys().contains(
script));
136 auto spks{spk_manager->GetScriptPubKeys()};
137 for (
const CScript& spk : spks) {
138 assert(spk_manager->IsMine(spk));
144 *std::get_if<PKHash>(&dest) :
147 (void)spk_manager->SignMessage(
msg, pk_hash, str_sig);
148 (void)spk_manager->GetMetadata(dest);
153 auto spks{spk_manager->GetScriptPubKeys()};
156 (void)spk_manager->MarkUnusedAddresses(spk);
160 LOCK(spk_manager->cs_desc_man);
161 auto wallet_desc{spk_manager->GetWalletDescriptor()};
162 if (wallet_desc.descriptor->IsSingleType()) {
163 auto output_type{wallet_desc.descriptor->GetOutputType()};
164 if (output_type.has_value()) {
165 auto dest{spk_manager->GetNewDestination(*output_type)};
168 assert(spk_manager->IsHDEnabled());
184 std::map<int, bilingual_str> input_errors;
185 (void)spk_manager->SignTransaction(tx_to, coins, sighash, input_errors);
188 std::optional<PartiallySignedTransaction> opt_psbt{ConsumeDeserializableConstructor<PartiallySignedTransaction>(
fuzzed_data_provider)};
193 auto psbt{*opt_psbt};
205 if (options.sighash_type == 151) options.sighash_type = std::nullopt;
206 (void)spk_manager->FillPSBT(psbt, txdata, options);
211 std::string descriptor;
213 (void)spk_manager->GetEndRange();
214 (void)spk_manager->GetKeyPoolSize();
226 CWallet&
wallet{*wallet_ptr};
227 wallet.m_keypool_size = 1;
231 wallet.SetLastBlockProcessed(chainstate.m_chain.Height(), chainstate.m_chain.Tip()->GetBlockHash());
234 auto& legacy_data{*
wallet.GetOrCreateLegacyDataSPKM()};
236 std::vector<CKey>
keys;
239 if (!key.IsValid())
return;
241 if (!pub_key.IsFullyValid())
return;
242 if (legacy_data.LoadKey(key, pub_key) && std::find(
keys.begin(),
keys.end(), key) ==
keys.end())
keys.push_back(key);
245 size_t added_chains = 0;
252 hd_chain.nVersion = version;
254 legacy_data.LoadHDChain(hd_chain);
259 if (add_inactive_hd_chain) {
262 bool dup_chain = hd_key.
IsValid() && std::equal(hd_key.
begin(), hd_key.
end(), inactive_hd_key.
begin());
264 legacy_data.AddInactiveHDChain(hd_chain);
265 if (!dup_chain) added_chains++;
268 bool watch_only =
false;
270 if (!pub_key || !pub_key->IsFullyValid())
return;
275 if (legacy_data.LoadWatchOnly(script_dest)) watch_only =
true;
277 size_t added_script{0};
278 bool good_data{
true};
285 key = PickValue(fuzzed_data_provider, keys);
287 key = ConsumePrivateKey(fuzzed_data_provider, fuzzed_data_provider.ConsumeBool());
290 auto pub_key{key.GetPubKey()};
306 script = script_opt.value();
321 std::vector<CPubKey> pubkeys;
323 for (
size_t i = 1; i < num_keys; i++) {
332 if (pubkeys.size() < num_keys)
return;
334 if (!legacy_data.HaveCScript(
CScriptID(multisig_script)) && legacy_data.AddCScript(multisig_script)) {
341 auto result{legacy_data.MigrateToDescriptor()};
346 size_t added_size{
keys.size() + added_chains};
347 if (added_script > 0) {
348 assert(result->desc_spkms.size() >= added_size);
350 assert(result->desc_spkms.size() == added_size);
352 if (watch_only)
assert(!result->watch_descs.empty());
353 if (!result->solvable_descs.empty())
assert(added_script > 0);
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
const TestingSetup * g_setup
An encapsulated private key.
bool IsValid() const
Check whether this private key is valid.
const std::byte * begin() const
CPubKey GetPubKey() const
Compute the public key from a private key.
const std::byte * end() const
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Cache for single descriptor's derived extended pubkeys.
Helper to initialize the global NodeClock, let a duration elapse, and reset it after use in a test.
std::string ConsumeRandomLengthString(size_t max_length)
T ConsumeIntegralInRange(T min, T max)
Converts a mocked descriptor string to a valid one.
void Init()
When initializing the target, populate the list of keys.
std::optional< std::string > GetDescriptor(std::string_view mocked_desc) const
Get an actual descriptor string from a descriptor string whose keys were mocked.
static const int VERSION_HD_BASE
static const int VERSION_HD_CHAIN_SPLIT
static UniValue Parse(std::string_view raw, ParamFormat format=ParamFormat::JSON)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
MockedDescriptorConverter MOCKED_DESC_CONVERTER
The converter of mocked descriptors, needs to be initialized when the target is.
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
wallet::DescriptorScriptPubKeyMan * CreateDescriptor(CWallet &keystore, const std::string &desc_str, const bool success)
std::unique_ptr< WalletDatabase > CreateMockableWalletDatabase()
FUZZ_TARGET(coin_grinder)
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
static constexpr TransactionSerParams TX_WITH_WITNESS
std::optional< PrecomputedTransactionData > PrecomputePSBTData(const PartiallySignedTransaction &psbt)
Compute a PrecomputedTransactionData object from a psbt.
static const int MAX_PUBKEYS_PER_MULTISIG
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
constexpr auto MakeUCharSpan(const V &v) -> decltype(UCharSpanCast(std::span{v}))
Like the std::span constructor, but for (const) unsigned char member types only.
A mutable version of CTransaction.
Testing setup that configures a complete environment.
Instructions for how a PSBT should be signed or filled with information.
bool sign
Whether to sign or not.
std::vector< uint16_t > keys
SeedRandomStateForTest(SeedRand::ZEROS)
bool IsTooExpensive(std::span< const uint8_t > buffer)
Deriving "expensive" descriptors will consume useful fuzz compute. The compute is better spent on a s...
NodeSeconds ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
CScript ConsumeScript(FuzzedDataProvider &fuzzed_data_provider, const bool maybe_p2wsh) noexcept
CKey ConsumePrivateKey(FuzzedDataProvider &fuzzed_data_provider, std::optional< bool > compressed) noexcept
std::map< COutPoint, Coin > ConsumeCoins(FuzzedDataProvider &fuzzed_data_provider) noexcept
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
uint160 ConsumeUInt160(FuzzedDataProvider &fuzzed_data_provider) noexcept
@ ZEROS
Seed with a compile time constant of zeros.
FuzzedDataProvider & fuzzed_data_provider
is a home for public enum and struct type definitions that are used by internally by wallet code,...