aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2019-04-16 07:55:06 -0400
committerMarcoFalke <falke.marco@gmail.com>2019-04-16 07:55:31 -0400
commite57462c6ba6023e0ed5417067364dcea2f88b36d (patch)
tree974d850ceca0b5096c2b03898c88c727e620224e
parentfa3993bfe856133ffd54bff1b7d77838321d372d (diff)
parent235550d01992555a316c9c4639f5bec6255a244f (diff)
downloadbitcoin-e57462c6ba6023e0ed5417067364dcea2f88b36d.tar.xz
Merge #15803: [0.18] Backport 15749: importmulti only imports origin info for PKH outputs
235550d019 Take non-importing keys into account for spendability warning in descriptor import (Pieter Wuille) 802dcd37d1 Import all origin info in importmulti; even for non-importing pubkeys (Pieter Wuille) 7fcbe7dc11 Keep full pubkeys in FlatSigningProvider::origins (Pieter Wuille) Pull request description: Clean backport of #15749 by sipa to 0.18 ACKs for commit 235550: fanquake: utACK 235550d MarcoFalke: ACK 235550d019 (Checked that they are clean cherry-picks) Tree-SHA512: 1ccc19f51137ac4ef971c0bcca4c87ab2383610aa51c5d02680c485b9ce6abd698dddd7f4a45946d56b1aa741cc3fd94b4180ff15901824d20eeba89b4f12853
-rw-r--r--src/script/descriptor.cpp2
-rw-r--r--src/script/sign.cpp8
-rw-r--r--src/script/sign.h2
-rw-r--r--src/test/descriptor_tests.cpp4
-rw-r--r--src/wallet/rpcdump.cpp14
-rwxr-xr-xtest/functional/wallet_importmulti.py3
6 files changed, 21 insertions, 12 deletions
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index 43448d7222..a333d4d4ac 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -436,7 +436,7 @@ public:
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, KeyOriginInfo>(CPubKey(entry.first), std::move(entry.second)));
}
if (m_script_arg) {
for (const auto& subscript : subscripts) {
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index 320956d0c4..36dd68a3d8 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -483,7 +483,13 @@ bool HidingSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& inf
bool FlatSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return LookupHelper(scripts, scriptid, script); }
bool FlatSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const { return LookupHelper(pubkeys, keyid, pubkey); }
-bool FlatSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const { return LookupHelper(origins, keyid, info); }
+bool FlatSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const
+{
+ std::pair<CPubKey, KeyOriginInfo> 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); }
FlatSigningProvider Merge(const FlatSigningProvider& a, const FlatSigningProvider& b)
diff --git a/src/script/sign.h b/src/script/sign.h
index 491fb54c45..f746325b90 100644
--- a/src/script/sign.h
+++ b/src/script/sign.h
@@ -77,7 +77,7 @@ struct FlatSigningProvider final : public SigningProvider
{
std::map<CScriptID, CScript> scripts;
std::map<CKeyID, CPubKey> pubkeys;
- std::map<CKeyID, KeyOriginInfo> origins;
+ std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>> origins;
std::map<CKeyID, CKey> keys;
bool GetCScript(const CScriptID& scriptid, CScript& script) const override;
diff --git a/src/test/descriptor_tests.cpp b/src/test/descriptor_tests.cpp
index ff2b8d4fc9..826615cb51 100644
--- a/src/test/descriptor_tests.cpp
+++ b/src/test/descriptor_tests.cpp
@@ -154,8 +154,8 @@ void Check(const std::string& prv, const std::string& pub, int flags, const std:
// Test whether the observed key path is present in the 'paths' 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), "Unexpected key path: " + prv);
- left_paths.erase(origin.second.path);
+ BOOST_CHECK_MESSAGE(paths.count(origin.second.second.path), "Unexpected key path: " + prv);
+ left_paths.erase(origin.second.second.path);
}
}
}
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index bdf901dee4..ed9742e6c2 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -896,7 +896,7 @@ struct ImportData
// Output data
std::set<CScript> import_scripts;
std::map<CKeyID, bool> used_keys; //!< Import these private keys if available (the value indicates whether if the key is required for solvability)
- std::map<CKeyID, KeyOriginInfo> key_origins;
+ std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>> key_origins;
};
enum class ScriptContext
@@ -1193,6 +1193,9 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID
bool spendable = std::all_of(pubkey_map.begin(), pubkey_map.end(),
[&](const std::pair<CKeyID, CPubKey>& 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<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& entry) {
+ return privkey_map.count(entry.first) > 0;
});
if (!watch_only && !spendable) {
warnings.push_back("Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.");
@@ -1270,7 +1273,10 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
}
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()) {
@@ -1281,10 +1287,6 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
if (!pwallet->GetPubKey(id, temp) && !pwallet->AddWatchOnly(GetScriptForRawPubKey(pubkey), timestamp)) {
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
index c6d0425f22..bfee2fe4c9 100755
--- a/test/functional/wallet_importmulti.py
+++ b/test/functional/wallet_importmulti.py
@@ -630,7 +630,8 @@ class ImportMultiTest(BitcoinTestFramework):
self.log.info("Should import a 1-of-2 bare multisig from descriptor")
self.test_importmulti({"desc": descsum_create("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],
key1.p2pkh_addr,