@@ -967,7 +967,7 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
967967 }
968968}
969969
970- static UniValue ProcessImportLegacy (ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool & have_solving_data, const UniValue& data)
970+ static UniValue ProcessImportLegacy (ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool & have_solving_data, const UniValue& data, std::vector<CKeyID>& ordered_pubkeys )
971971{
972972 UniValue warnings (UniValue::VARR);
973973
@@ -1038,6 +1038,7 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP
10381038 throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Pubkey \" " + str + " \" is not a valid public key" );
10391039 }
10401040 pubkey_map.emplace (pubkey.GetID (), pubkey);
1041+ ordered_pubkeys.push_back (pubkey.GetID ());
10411042 }
10421043 for (size_t i = 0 ; i < keys.size (); ++i) {
10431044 const auto & str = keys[i].get_str ();
@@ -1110,7 +1111,7 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP
11101111 return warnings;
11111112}
11121113
1113- static UniValue ProcessImportDescriptor (ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool & have_solving_data, const UniValue& data)
1114+ static UniValue ProcessImportDescriptor (ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool & have_solving_data, const UniValue& data, std::vector<CKeyID>& ordered_pubkeys )
11141115{
11151116 UniValue warnings (UniValue::VARR);
11161117
@@ -1144,22 +1145,25 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID
11441145
11451146 const UniValue& priv_keys = data.exists (" keys" ) ? data[" keys" ].get_array () : UniValue ();
11461147
1147- FlatSigningProvider out_keys;
1148-
11491148 // Expand all descriptors to get public keys and scripts.
11501149 // TODO: get private keys from descriptors too
11511150 for (int i = range_start; i <= range_end; ++i) {
1151+ FlatSigningProvider out_keys;
11521152 std::vector<CScript> scripts_temp;
11531153 parsed_desc->Expand (i, keys, scripts_temp, out_keys);
11541154 std::copy (scripts_temp.begin (), scripts_temp.end (), std::inserter (script_pub_keys, script_pub_keys.end ()));
1155- }
1155+ for (const auto & key_pair : out_keys.pubkeys ) {
1156+ ordered_pubkeys.push_back (key_pair.first );
1157+ }
11561158
1157- for (const auto & x : out_keys.scripts ) {
1158- import_data.import_scripts .emplace (x.second );
1159+ for (const auto & x : out_keys.scripts ) {
1160+ import_data.import_scripts .emplace (x.second );
1161+ }
1162+
1163+ std::copy (out_keys.pubkeys .begin (), out_keys.pubkeys .end (), std::inserter (pubkey_map, pubkey_map.end ()));
1164+ import_data.key_origins .insert (out_keys.origins .begin (), out_keys.origins .end ());
11591165 }
11601166
1161- std::copy (out_keys.pubkeys .begin (), out_keys.pubkeys .end (), std::inserter (pubkey_map, pubkey_map.end ()));
1162- import_data.key_origins .insert (out_keys.origins .begin (), out_keys.origins .end ());
11631167 for (size_t i = 0 ; i < priv_keys.size (); ++i) {
11641168 const auto & str = priv_keys[i].get_str ();
11651169 CKey key = DecodeSecret (str);
@@ -1218,14 +1222,15 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
12181222 std::map<CKeyID, CPubKey> pubkey_map;
12191223 std::map<CKeyID, CKey> privkey_map;
12201224 std::set<CScript> script_pub_keys;
1225+ std::vector<CKeyID> ordered_pubkeys;
12211226 bool have_solving_data;
12221227
12231228 if (data.exists (" scriptPubKey" ) && data.exists (" desc" )) {
12241229 throw JSONRPCError (RPC_INVALID_PARAMETER, " Both a descriptor and a scriptPubKey should not be provided." );
12251230 } else if (data.exists (" scriptPubKey" )) {
1226- warnings = ProcessImportLegacy (import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data);
1231+ warnings = ProcessImportLegacy (import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data, ordered_pubkeys );
12271232 } else if (data.exists (" desc" )) {
1228- warnings = ProcessImportDescriptor (import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data);
1233+ warnings = ProcessImportDescriptor (import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data, ordered_pubkeys );
12291234 } else {
12301235 throw JSONRPCError (RPC_INVALID_PARAMETER, " Either a descriptor or scriptPubKey must be provided." );
12311236 }
@@ -1247,25 +1252,28 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
12471252 for (const auto & entry : import_data.import_scripts ) {
12481253 if (!pwallet->HaveCScript (CScriptID (entry)) && !pwallet->AddCScript (entry)) {
12491254 throw JSONRPCError (RPC_WALLET_ERROR, " Error adding script to wallet" );
1255+ }
1256+ }
1257+ for (const auto & entry : privkey_map) {
1258+ const CKey& key = entry.second ;
1259+ CPubKey pubkey = key.GetPubKey ();
1260+ const CKeyID& id = entry.first ;
1261+ assert (key.VerifyPubKey (pubkey));
1262+ pwallet->mapKeyMetadata [id].nCreateTime = timestamp;
1263+ // If the private key is not present in the wallet, insert it.
1264+ if (!pwallet->HaveKey (id) && !pwallet->AddKeyPubKey (key, pubkey)) {
1265+ throw JSONRPCError (RPC_WALLET_ERROR, " Error adding key to wallet" );
1266+ }
1267+ pwallet->UpdateTimeFirstKey (timestamp);
1268+ }
1269+ for (const CKeyID& id : ordered_pubkeys) {
1270+ auto entry = pubkey_map.find (id);
1271+ if (entry == pubkey_map.end ()) {
1272+ continue ;
12501273 }
1251- }
1252- for (const auto & entry : privkey_map) {
1253- const CKey& key = entry.second ;
1254- CPubKey pubkey = key.GetPubKey ();
1255- const CKeyID& id = entry.first ;
1256- assert (key.VerifyPubKey (pubkey));
1257- pwallet->mapKeyMetadata [id].nCreateTime = timestamp;
1258- // If the private key is not present in the wallet, insert it.
1259- if (!pwallet->HaveKey (id) && !pwallet->AddKeyPubKey (key, pubkey)) {
1260- throw JSONRPCError (RPC_WALLET_ERROR, " Error adding key to wallet" );
1261- }
1262- pwallet->UpdateTimeFirstKey (timestamp);
1263- }
1264- for (const auto & entry : pubkey_map) {
1265- const CPubKey& pubkey = entry.second ;
1266- const CKeyID& id = entry.first ;
1267- CPubKey temp;
1268- if (!pwallet->GetPubKey (id, temp) && !pwallet->AddWatchOnly (GetScriptForRawPubKey (pubkey), timestamp)) {
1274+ const CPubKey& pubkey = entry->second ;
1275+ CPubKey temp;
1276+ if (!pwallet->GetPubKey (id, temp) && !pwallet->AddWatchOnly (GetScriptForRawPubKey (pubkey), timestamp)) {
12691277 throw JSONRPCError (RPC_WALLET_ERROR, " Error adding address to wallet" );
12701278 }
12711279 const auto & key_orig_it = import_data.key_origins .find (id);
0 commit comments