wallet: Use util::Error throughout AddWalletDescriptor
32023 changed AddWalletDescriptor to return util::Error, but did not change all of the failure cases to do so. This may result in some callers continuing when there was actually an error. Unify all of the failure cases to use util::Error so that all callers handle AddWalletDescriptor errors in the same way. The encapsulated return type is changed from ScriptPubKeyMan* to std::reference_wrapper<DescriptorScriptPubKeyMan>. This avoids having a value that can be interpreted as a bool, and also removes the need to constantly dynamic_cast the returned value. The only kind of ScriptPubKeyMan that can come out of AddWalletDescriptor is a DescriptorScriptPubKeyMan anyways.
This commit is contained in:
1 parent
c461d15287
commit
785e1407b0
13 files changed
+28
-44
No files matched your search
@@ -50,8 +50,7 @@ static void WalletIsMine(benchmark::Bench& bench, int num_combo = 0)
|
|||||||
std::string error;
|
std::string error;
|
||||||
std::vector<std::unique_ptr<Descriptor>> desc = Parse("combo(" + EncodeSecret(key) + ")", keys, error, /*require_checksum=*/false);
|
std::vector<std::unique_ptr<Descriptor>> desc = Parse("combo(" + EncodeSecret(key) + ")", keys, error, /*require_checksum=*/false);
|
||||||
WalletDescriptor w_desc(std::move(desc.at(0)), /*creation_time=*/0, /*range_start=*/0, /*range_end=*/0, /*next_index=*/0);
|
WalletDescriptor w_desc(std::move(desc.at(0)), /*creation_time=*/0, /*range_start=*/0, /*range_end=*/0, /*next_index=*/0);
|
||||||
auto spk_manager = *Assert(wallet->AddWalletDescriptor(w_desc, keys, /*label=*/"", /*internal=*/false));
|
Assert(wallet->AddWalletDescriptor(w_desc, keys, /*label=*/"", /*internal=*/false));
|
||||||
assert(spk_manager);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -215,8 +215,7 @@ std::shared_ptr<CWallet> SetupDescriptorsWallet(interfaces::Node& node, TestChai
|
|||||||
assert(descs.size() == 1);
|
assert(descs.size() == 1);
|
||||||
auto& desc = descs.at(0);
|
auto& desc = descs.at(0);
|
||||||
WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
|
WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
|
||||||
auto spk_manager = *Assert(wallet->AddWalletDescriptor(w_desc, provider, "", false));
|
Assert(wallet->AddWalletDescriptor(w_desc, provider, "", false));
|
||||||
assert(spk_manager);
|
|
||||||
const PKHash dest{test.coinbaseKey.GetPubKey()};
|
const PKHash dest{test.coinbaseKey.GetPubKey()};
|
||||||
wallet->SetAddressBook(dest, "", wallet::AddressPurpose::RECEIVE);
|
wallet->SetAddressBook(dest, "", wallet::AddressPurpose::RECEIVE);
|
||||||
wallet->SetLastBlockProcessed(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
|
wallet->SetLastBlockProcessed(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
|
||||||
|
|||||||
@@ -59,9 +59,8 @@ struct FuzzedWallet {
|
|||||||
WalletDescriptor w_desc{std::move(parsed_desc), /*creation_time=*/0, /*range_start=*/0, /*range_end=*/1, /*next_index=*/0};
|
WalletDescriptor w_desc{std::move(parsed_desc), /*creation_time=*/0, /*range_start=*/0, /*range_end=*/1, /*next_index=*/0};
|
||||||
assert(!wallet->GetDescriptorScriptPubKeyMan(w_desc));
|
assert(!wallet->GetDescriptorScriptPubKeyMan(w_desc));
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
auto spk_manager = *Assert(wallet->AddWalletDescriptor(w_desc, keys, /*label=*/"", internal));
|
auto& spk_manager = Assert(wallet->AddWalletDescriptor(w_desc, keys, /*label=*/"", internal))->get();
|
||||||
assert(spk_manager);
|
wallet->AddActiveScriptPubKeyMan(spk_manager.GetID(), *Assert(w_desc.descriptor->GetOutputType()), internal);
|
||||||
wallet->AddActiveScriptPubKeyMan(spk_manager->GetID(), *Assert(w_desc.descriptor->GetOutputType()), internal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,25 +262,21 @@ static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, c
|
|||||||
auto spk_manager_res = wallet.AddWalletDescriptor(w_desc, keys, label, desc_internal);
|
auto spk_manager_res = wallet.AddWalletDescriptor(w_desc, keys, label, desc_internal);
|
||||||
|
|
||||||
if (!spk_manager_res) {
|
if (!spk_manager_res) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, util::ErrorString(spk_manager_res).original);
|
throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Could not add descriptor '%s': %s", descriptor, util::ErrorString(spk_manager_res).original));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto spk_manager = spk_manager_res.value();
|
auto& spk_manager = spk_manager_res.value().get();
|
||||||
|
|
||||||
if (spk_manager == nullptr) {
|
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Could not add descriptor '%s'", descriptor));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set descriptor as active if necessary
|
// Set descriptor as active if necessary
|
||||||
if (active) {
|
if (active) {
|
||||||
if (!w_desc.descriptor->GetOutputType()) {
|
if (!w_desc.descriptor->GetOutputType()) {
|
||||||
warnings.push_back("Unknown output type, cannot set descriptor to active.");
|
warnings.push_back("Unknown output type, cannot set descriptor to active.");
|
||||||
} else {
|
} else {
|
||||||
wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), desc_internal);
|
wallet.AddActiveScriptPubKeyMan(spk_manager.GetID(), *w_desc.descriptor->GetOutputType(), desc_internal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (w_desc.descriptor->GetOutputType()) {
|
if (w_desc.descriptor->GetOutputType()) {
|
||||||
wallet.DeactivateScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), desc_internal);
|
wallet.DeactivateScriptPubKeyMan(spk_manager.GetID(), *w_desc.descriptor->GetOutputType(), desc_internal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,12 +80,9 @@ static std::optional<std::pair<WalletDescriptor, FlatSigningProvider>> CreateWal
|
|||||||
static DescriptorScriptPubKeyMan* CreateDescriptor(WalletDescriptor& wallet_desc, FlatSigningProvider& keys, CWallet& keystore)
|
static DescriptorScriptPubKeyMan* CreateDescriptor(WalletDescriptor& wallet_desc, FlatSigningProvider& keys, CWallet& keystore)
|
||||||
{
|
{
|
||||||
LOCK(keystore.cs_wallet);
|
LOCK(keystore.cs_wallet);
|
||||||
DescriptorScriptPubKeyMan* descriptor_spk_manager = nullptr;
|
auto spk_manager_res = keystore.AddWalletDescriptor(wallet_desc, keys, /*label=*/"", /*internal=*/false);
|
||||||
auto spk_manager = *Assert(keystore.AddWalletDescriptor(wallet_desc, keys, /*label=*/"", /*internal=*/false));
|
if (!spk_manager_res) return nullptr;
|
||||||
if (spk_manager) {
|
return &spk_manager_res.value().get();
|
||||||
descriptor_spk_manager = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_manager);
|
|
||||||
}
|
|
||||||
return descriptor_spk_manager;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm)
|
FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm)
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ static void import_descriptor(CWallet& wallet, const std::string& descriptor)
|
|||||||
assert(descs.size() == 1);
|
assert(descs.size() == 1);
|
||||||
auto& desc = descs.at(0);
|
auto& desc = descs.at(0);
|
||||||
WalletDescriptor w_desc(std::move(desc), 0, 0, 10, 0);
|
WalletDescriptor w_desc(std::move(desc), 0, 0, 10, 0);
|
||||||
auto spk_manager = *Assert(wallet.AddWalletDescriptor(w_desc, provider, "", false));
|
Assert(wallet.AddWalletDescriptor(w_desc, provider, "", false));
|
||||||
assert(spk_manager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(psbt_updater_test)
|
BOOST_AUTO_TEST_CASE(psbt_updater_test)
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ BOOST_AUTO_TEST_CASE(DescriptorScriptPubKeyManTests)
|
|||||||
// Verify that a SigningProvider for a pubkey is only returned if its corresponding private key is available
|
// Verify that a SigningProvider for a pubkey is only returned if its corresponding private key is available
|
||||||
auto key_internal = GenerateRandomKey();
|
auto key_internal = GenerateRandomKey();
|
||||||
std::string desc_str = "tr(" + EncodeSecret(key_internal) + ",pk(" + HexStr(key_scriptpath.GetPubKey()) + "))";
|
std::string desc_str = "tr(" + EncodeSecret(key_internal) + ",pk(" + HexStr(key_scriptpath.GetPubKey()) + "))";
|
||||||
auto spk_man1 = dynamic_cast<DescriptorScriptPubKeyMan*>(CreateDescriptor(keystore, desc_str, true));
|
auto spk_man1 = CreateDescriptor(keystore, desc_str, true);
|
||||||
BOOST_CHECK(spk_man1 != nullptr);
|
BOOST_CHECK(spk_man1 != nullptr);
|
||||||
auto signprov_keypath_spendable = spk_man1->GetSigningProvider(key_internal.GetPubKey());
|
auto signprov_keypath_spendable = spk_man1->GetSigningProvider(key_internal.GetPubKey());
|
||||||
BOOST_CHECK(signprov_keypath_spendable != nullptr);
|
BOOST_CHECK(signprov_keypath_spendable != nullptr);
|
||||||
|
|
||||||
desc_str = "tr(" + HexStr(XOnlyPubKey::NUMS_H) + ",pk(" + HexStr(key_scriptpath.GetPubKey()) + "))";
|
desc_str = "tr(" + HexStr(XOnlyPubKey::NUMS_H) + ",pk(" + HexStr(key_scriptpath.GetPubKey()) + "))";
|
||||||
auto spk_man2 = dynamic_cast<DescriptorScriptPubKeyMan*>(CreateDescriptor(keystore, desc_str, true));
|
auto spk_man2 = CreateDescriptor(keystore, desc_str, true);
|
||||||
BOOST_CHECK(spk_man2 != nullptr);
|
BOOST_CHECK(spk_man2 != nullptr);
|
||||||
auto signprov_keypath_nums_h = spk_man2->GetSigningProvider(XOnlyPubKey::NUMS_H.GetEvenCorrespondingCPubKey());
|
auto signprov_keypath_nums_h = spk_man2->GetSigningProvider(XOnlyPubKey::NUMS_H.GetEvenCorrespondingCPubKey());
|
||||||
BOOST_CHECK(signprov_keypath_nums_h == nullptr);
|
BOOST_CHECK(signprov_keypath_nums_h == nullptr);
|
||||||
|
|||||||
@@ -35,8 +35,7 @@ std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cc
|
|||||||
assert(descs.size() == 1);
|
assert(descs.size() == 1);
|
||||||
auto& desc = descs.at(0);
|
auto& desc = descs.at(0);
|
||||||
WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
|
WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
|
||||||
auto spk_manager = *Assert(wallet->AddWalletDescriptor(w_desc, provider, "", false));
|
Assert(wallet->AddWalletDescriptor(w_desc, provider, "", false));
|
||||||
assert(spk_manager);
|
|
||||||
}
|
}
|
||||||
WalletRescanReserver reserver(*wallet);
|
WalletRescanReserver reserver(*wallet);
|
||||||
reserver.reserve();
|
reserver.reserve();
|
||||||
@@ -194,7 +193,7 @@ MockableDatabase& GetMockableDatabase(CWallet& wallet)
|
|||||||
return dynamic_cast<MockableDatabase&>(wallet.GetDatabase());
|
return dynamic_cast<MockableDatabase&>(wallet.GetDatabase());
|
||||||
}
|
}
|
||||||
|
|
||||||
wallet::ScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, const bool success)
|
wallet::DescriptorScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, const bool success)
|
||||||
{
|
{
|
||||||
keystore.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
|
keystore.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
|
||||||
|
|
||||||
@@ -211,6 +210,6 @@ wallet::ScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string&
|
|||||||
|
|
||||||
LOCK(keystore.cs_wallet);
|
LOCK(keystore.cs_wallet);
|
||||||
auto spkm = Assert(keystore.AddWalletDescriptor(w_desc, keys,/*label=*/"", /*internal=*/false));
|
auto spkm = Assert(keystore.AddWalletDescriptor(w_desc, keys,/*label=*/"", /*internal=*/false));
|
||||||
return spkm.value();
|
return &spkm.value().get();
|
||||||
};
|
};
|
||||||
} // namespace wallet
|
} // namespace wallet
|
||||||
@@ -116,7 +116,7 @@ public:
|
|||||||
std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(MockableData records = {});
|
std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(MockableData records = {});
|
||||||
MockableDatabase& GetMockableDatabase(CWallet& wallet);
|
MockableDatabase& GetMockableDatabase(CWallet& wallet);
|
||||||
|
|
||||||
ScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, const bool success);
|
DescriptorScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, const bool success);
|
||||||
} // namespace wallet
|
} // namespace wallet
|
||||||
|
|
||||||
#endif // BITCOIN_WALLET_TEST_UTIL_H
|
#endif // BITCOIN_WALLET_TEST_UTIL_H
|
||||||
@@ -66,8 +66,7 @@ static void AddKey(CWallet& wallet, const CKey& key)
|
|||||||
assert(descs.size() == 1);
|
assert(descs.size() == 1);
|
||||||
auto& desc = descs.at(0);
|
auto& desc = descs.at(0);
|
||||||
WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
|
WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
|
||||||
auto spk_manager = *Assert(wallet.AddWalletDescriptor(w_desc, provider, "", false));
|
Assert(wallet.AddWalletDescriptor(w_desc, provider, "", false));
|
||||||
assert(spk_manager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
|
BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
|
||||||
|
|||||||
@@ -3713,13 +3713,12 @@ std::optional<bool> CWallet::IsInternalScriptPubKeyMan(ScriptPubKeyMan* spk_man)
|
|||||||
return GetScriptPubKeyMan(*type, /* internal= */ true) == desc_spk_man;
|
return GetScriptPubKeyMan(*type, /* internal= */ true) == desc_spk_man;
|
||||||
}
|
}
|
||||||
|
|
||||||
util::Result<ScriptPubKeyMan*> CWallet::AddWalletDescriptor(WalletDescriptor& desc, const FlatSigningProvider& signing_provider, const std::string& label, bool internal)
|
util::Result<std::reference_wrapper<DescriptorScriptPubKeyMan>> CWallet::AddWalletDescriptor(WalletDescriptor& desc, const FlatSigningProvider& signing_provider, const std::string& label, bool internal)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet);
|
AssertLockHeld(cs_wallet);
|
||||||
|
|
||||||
if (!IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
|
if (!IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
|
||||||
WalletLogPrintf("Cannot add WalletDescriptor to a non-descriptor wallet\n");
|
return util::Error{_("Cannot add WalletDescriptor to a non-descriptor wallet")};
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto spk_man = GetDescriptorScriptPubKeyMan(desc);
|
auto spk_man = GetDescriptorScriptPubKeyMan(desc);
|
||||||
@@ -3745,8 +3744,7 @@ util::Result<ScriptPubKeyMan*> CWallet::AddWalletDescriptor(WalletDescriptor& de
|
|||||||
|
|
||||||
// Top up key pool, the manager will generate new scriptPubKeys internally
|
// Top up key pool, the manager will generate new scriptPubKeys internally
|
||||||
if (!spk_man->TopUp()) {
|
if (!spk_man->TopUp()) {
|
||||||
WalletLogPrintf("Could not top up scriptPubKeys\n");
|
return util::Error{_("Could not top up scriptPubKeys")};
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the label if necessary
|
// Apply the label if necessary
|
||||||
@@ -3754,8 +3752,7 @@ util::Result<ScriptPubKeyMan*> CWallet::AddWalletDescriptor(WalletDescriptor& de
|
|||||||
if (!desc.descriptor->IsRange()) {
|
if (!desc.descriptor->IsRange()) {
|
||||||
auto script_pub_keys = spk_man->GetScriptPubKeys();
|
auto script_pub_keys = spk_man->GetScriptPubKeys();
|
||||||
if (script_pub_keys.empty()) {
|
if (script_pub_keys.empty()) {
|
||||||
WalletLogPrintf("Could not generate scriptPubKeys (cache is empty)\n");
|
return util::Error{_("Could not generate scriptPubKeys (cache is empty)")};
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!internal) {
|
if (!internal) {
|
||||||
@@ -3771,7 +3768,7 @@ util::Result<ScriptPubKeyMan*> CWallet::AddWalletDescriptor(WalletDescriptor& de
|
|||||||
// Save the descriptor to DB
|
// Save the descriptor to DB
|
||||||
spk_man->WriteDescriptor();
|
spk_man->WriteDescriptor();
|
||||||
|
|
||||||
return spk_man;
|
return std::reference_wrapper(*spk_man);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::MigrateToSQLite(bilingual_str& error)
|
bool CWallet::MigrateToSQLite(bilingual_str& error)
|
||||||
|
|||||||
+1
-1
@@ -1020,7 +1020,7 @@ public:
|
|||||||
std::optional<bool> IsInternalScriptPubKeyMan(ScriptPubKeyMan* spk_man) const;
|
std::optional<bool> IsInternalScriptPubKeyMan(ScriptPubKeyMan* spk_man) const;
|
||||||
|
|
||||||
//! Add a descriptor to the wallet, return a ScriptPubKeyMan & associated output type
|
//! Add a descriptor to the wallet, return a ScriptPubKeyMan & associated output type
|
||||||
util::Result<ScriptPubKeyMan*> AddWalletDescriptor(WalletDescriptor& desc, const FlatSigningProvider& signing_provider, const std::string& label, bool internal) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
util::Result<std::reference_wrapper<DescriptorScriptPubKeyMan>> AddWalletDescriptor(WalletDescriptor& desc, const FlatSigningProvider& signing_provider, const std::string& label, bool internal) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
|
|
||||||
/** Move all records from the BDB database to a new SQLite database for storage.
|
/** Move all records from the BDB database to a new SQLite database for storage.
|
||||||
* The original BDB file will be deleted and replaced with a new SQLite file.
|
* The original BDB file will be deleted and replaced with a new SQLite file.
|
||||||
|
|||||||
@@ -284,11 +284,11 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
|||||||
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
|
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
|
||||||
|
|
||||||
self.test_importdesc({**range_request, "range": [5, 10]}, wallet=wpriv, success=False,
|
self.test_importdesc({**range_request, "range": [5, 10]}, wallet=wpriv, success=False,
|
||||||
error_code=-8, error_message='new range must include current range = [0,20]')
|
error_code=-4, error_message=f"Could not add descriptor '{range_request['desc']}': new range must include current range = [0,20]")
|
||||||
self.test_importdesc({**range_request, "range": [0, 10]}, wallet=wpriv, success=False,
|
self.test_importdesc({**range_request, "range": [0, 10]}, wallet=wpriv, success=False,
|
||||||
error_code=-8, error_message='new range must include current range = [0,20]')
|
error_code=-4, error_message=f"Could not add descriptor '{range_request['desc']}': new range must include current range = [0,20]")
|
||||||
self.test_importdesc({**range_request, "range": [5, 20]}, wallet=wpriv, success=False,
|
self.test_importdesc({**range_request, "range": [5, 20]}, wallet=wpriv, success=False,
|
||||||
error_code=-8, error_message='new range must include current range = [0,20]')
|
error_code=-4, error_message=f"Could not add descriptor '{range_request['desc']}': new range must include current range = [0,20]")
|
||||||
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
|
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
|
||||||
|
|
||||||
self.log.info("Check we can change descriptor internal flag")
|
self.log.info("Check we can change descriptor internal flag")
|
||||||
|
|||||||
Reference in new issue
Block a user