diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -404,7 +404,10 @@ pubkeys.reserve(entries.size()); for (auto &entry : entries) { pubkeys.push_back(entry.first); - out.origins.emplace(entry.first.GetID(), std::move(entry.second)); + out.origins.emplace( + entry.first.GetID(), + std::make_pair( + CPubKey(entry.first), std::move(entry.second))); } if (m_script_arg) { for (const auto &subscript : subscripts) { diff --git a/src/script/sign.h b/src/script/sign.h --- a/src/script/sign.h +++ b/src/script/sign.h @@ -85,7 +85,7 @@ struct FlatSigningProvider final : public SigningProvider { std::map scripts; std::map pubkeys; - std::map origins; + std::map> origins; std::map keys; bool GetCScript(const CScriptID &scriptid, CScript &script) const override; diff --git a/src/script/sign.cpp b/src/script/sign.cpp --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -470,7 +470,12 @@ } bool FlatSigningProvider::GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const { - return LookupHelper(origins, keyid, info); + std::pair out; + bool ret = LookupHelper(origins, keyid, out); + if (ret) { + info = std::move(out.second); + } + return ret; } bool FlatSigningProvider::GetKey(const CKeyID &keyid, CKey &key) const { return LookupHelper(keys, keyid, key); diff --git a/src/test/descriptor_tests.cpp b/src/test/descriptor_tests.cpp --- a/src/test/descriptor_tests.cpp +++ b/src/test/descriptor_tests.cpp @@ -179,9 +179,9 @@ // variable (which contains expected, unobserved paths), and then // remove it from that set. for (const auto &origin : script_provider.origins) { - BOOST_CHECK_MESSAGE(paths.count(origin.second.path), + BOOST_CHECK_MESSAGE(paths.count(origin.second.second.path), "Unexpected key path: " + prv); - left_paths.erase(origin.second.path); + left_paths.erase(origin.second.second.path); } } } diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1076,7 +1076,7 @@ //! Import these private keys if available (the value indicates whether if //! the key is required for solvability) std::map used_keys; - std::map key_origins; + std::map> key_origins; }; enum class ScriptContext { @@ -1426,7 +1426,11 @@ std::all_of(pubkey_map.begin(), pubkey_map.end(), [&](const std::pair &used_key) { return privkey_map.count(used_key.first) > 0; - }); + }) && + std::all_of( + import_data.key_origins.begin(), import_data.key_origins.end(), + [&](const std::pair> + &entry) { return privkey_map.count(entry.first) > 0; }); if (!watch_only && !spendable) { warnings.push_back( "Some private keys are missing, outputs will be considered " @@ -1535,6 +1539,9 @@ } pwallet->UpdateTimeFirstKey(timestamp); } + for (const auto &entry : import_data.key_origins) { + pwallet->AddKeyOrigin(entry.second.first, entry.second.second); + } for (const CKeyID &id : ordered_pubkeys) { auto entry = pubkey_map.find(id); if (entry == pubkey_map.end()) { @@ -1548,10 +1555,6 @@ throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } - const auto &key_orig_it = import_data.key_origins.find(id); - if (key_orig_it != import_data.key_origins.end()) { - pwallet->AddKeyOrigin(pubkey, key_orig_it->second); - } pwallet->mapKeyMetadata[id].nCreateTime = timestamp; // Add to keypool only works with pubkeys diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py --- a/test/functional/wallet_importmulti.py +++ b/test/functional/wallet_importmulti.py @@ -506,7 +506,8 @@ self.log.info("Should import a 1-of-2 bare multisig from descriptor") self.test_importmulti({"desc": "multi(1," + key1.pubkey + "," + key2.pubkey + ")", "timestamp": "now"}, - success=True) + success=True, + warnings=["Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag."]) self.log.info( "Should not treat individual keys from the imported bare multisig as watchonly") test_address(self.nodes[1],