Skip to content

Commit b5c5021

Browse files
committed
Refactor importwallet to extract data from the file and then import
Instead of importing keys and scripts as each line in the file is read, first extract the data then import them.
1 parent 1f77f67 commit b5c5021

File tree

1 file changed

+55
-34
lines changed

1 file changed

+55
-34
lines changed

src/wallet/rpcdump.cpp

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,10 @@ UniValue importwallet(const JSONRPCRequest& request)
578578
// Use uiInterface.ShowProgress instead of pwallet.ShowProgress because pwallet.ShowProgress has a cancel button tied to AbortRescan which
579579
// we don't want for this progress bar showing the import progress. uiInterface.ShowProgress does not have a cancel button.
580580
uiInterface.ShowProgress(strprintf("%s " + _("Importing..."), pwallet->GetDisplayName()), 0, false); // show progress dialog in GUI
581+
std::vector<std::tuple<CKey, int64_t, bool, std::string>> keys;
582+
std::vector<std::pair<CScript, int64_t>> scripts;
581583
while (file.good()) {
582-
uiInterface.ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))), false);
584+
uiInterface.ShowProgress("", std::max(1, std::min(50, (int)(((double)file.tellg() / (double)nFilesize) * 100))), false);
583585
std::string line;
584586
std::getline(file, line);
585587
if (line.empty() || line[0] == '#')
@@ -591,13 +593,6 @@ UniValue importwallet(const JSONRPCRequest& request)
591593
continue;
592594
CKey key = DecodeSecret(vstr[0]);
593595
if (key.IsValid()) {
594-
CPubKey pubkey = key.GetPubKey();
595-
assert(key.VerifyPubKey(pubkey));
596-
CKeyID keyid = pubkey.GetID();
597-
if (pwallet->HaveKey(keyid)) {
598-
pwallet->WalletLogPrintf("Skipping import of %s (key already present)\n", EncodeDestination(keyid));
599-
continue;
600-
}
601596
int64_t nTime = DecodeDumpTime(vstr[1]);
602597
std::string strLabel;
603598
bool fLabel = true;
@@ -613,36 +608,62 @@ UniValue importwallet(const JSONRPCRequest& request)
613608
fLabel = true;
614609
}
615610
}
616-
pwallet->WalletLogPrintf("Importing %s...\n", EncodeDestination(keyid));
617-
if (!pwallet->AddKeyPubKey(key, pubkey)) {
618-
fGood = false;
619-
continue;
620-
}
621-
pwallet->mapKeyMetadata[keyid].nCreateTime = nTime;
622-
if (fLabel)
623-
pwallet->SetAddressBook(keyid, strLabel, "receive");
624-
nTimeBegin = std::min(nTimeBegin, nTime);
611+
keys.push_back(std::make_tuple(key, nTime, fLabel, strLabel));
625612
} else if(IsHex(vstr[0])) {
626-
std::vector<unsigned char> vData(ParseHex(vstr[0]));
627-
CScript script = CScript(vData.begin(), vData.end());
628-
CScriptID id(script);
629-
if (pwallet->HaveCScript(id)) {
630-
pwallet->WalletLogPrintf("Skipping import of %s (script already present)\n", vstr[0]);
631-
continue;
632-
}
633-
if(!pwallet->AddCScript(script)) {
634-
pwallet->WalletLogPrintf("Error importing script %s\n", vstr[0]);
635-
fGood = false;
636-
continue;
637-
}
638-
int64_t birth_time = DecodeDumpTime(vstr[1]);
639-
if (birth_time > 0) {
640-
pwallet->m_script_metadata[id].nCreateTime = birth_time;
641-
nTimeBegin = std::min(nTimeBegin, birth_time);
642-
}
613+
std::vector<unsigned char> vData(ParseHex(vstr[0]));
614+
CScript script = CScript(vData.begin(), vData.end());
615+
int64_t birth_time = DecodeDumpTime(vstr[1]);
616+
scripts.push_back(std::pair<CScript, int64_t>(script, birth_time));
643617
}
644618
}
645619
file.close();
620+
double total = (double)(keys.size() + scripts.size());
621+
double progress = 0;
622+
for (const auto& key_tuple : keys) {
623+
uiInterface.ShowProgress("", std::max(50, std::min(75, (int)((progress / total) * 100) + 50)), false);
624+
const CKey& key = std::get<0>(key_tuple);
625+
int64_t time = std::get<1>(key_tuple);
626+
bool has_label = std::get<2>(key_tuple);
627+
std::string label = std::get<3>(key_tuple);
628+
629+
CPubKey pubkey = key.GetPubKey();
630+
assert(key.VerifyPubKey(pubkey));
631+
CKeyID keyid = pubkey.GetID();
632+
if (pwallet->HaveKey(keyid)) {
633+
pwallet->WalletLogPrintf("Skipping import of %s (key already present)\n", EncodeDestination(keyid));
634+
continue;
635+
}
636+
pwallet->WalletLogPrintf("Importing %s...\n", EncodeDestination(keyid));
637+
if (!pwallet->AddKeyPubKey(key, pubkey)) {
638+
fGood = false;
639+
continue;
640+
}
641+
pwallet->mapKeyMetadata[keyid].nCreateTime = time;
642+
if (has_label)
643+
pwallet->SetAddressBook(keyid, label, "receive");
644+
nTimeBegin = std::min(nTimeBegin, time);
645+
progress++;
646+
}
647+
for (const auto& script_pair : scripts) {
648+
uiInterface.ShowProgress("", std::max(50, std::min(75, (int)((progress / total) * 100) + 50)), false);
649+
const CScript& script = script_pair.first;
650+
int64_t time = script_pair.second;
651+
CScriptID id(script);
652+
if (pwallet->HaveCScript(id)) {
653+
pwallet->WalletLogPrintf("Skipping import of %s (script already present)\n", HexStr(script));
654+
continue;
655+
}
656+
if(!pwallet->AddCScript(script)) {
657+
pwallet->WalletLogPrintf("Error importing script %s\n", HexStr(script));
658+
fGood = false;
659+
continue;
660+
}
661+
if (time > 0) {
662+
pwallet->m_script_metadata[id].nCreateTime = time;
663+
nTimeBegin = std::min(nTimeBegin, time);
664+
}
665+
progress++;
666+
}
646667
uiInterface.ShowProgress("", 100, false); // hide progress dialog in GUI
647668
pwallet->UpdateTimeFirstKey(nTimeBegin);
648669
}

0 commit comments

Comments
 (0)