{
string strAddress;
ssKey >> strAddress;
- ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()];
+ ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress)];
}
else if (strType == "tx")
{
}
else if (strType == "malpair")
{
- string strKey, strKeyView;
+ string strKeyView;
CSecret vchSecret;
- CMalleableKeyView keyView;
-
ssKey >> strKeyView;
- keyView.SetString(strKeyView);
ssValue >> vchSecret;
- CMalleableKey mKey = keyView.GetMalleableKey(vchSecret);
-
- if (mKey.IsNull())
+ CMalleableKeyView keyView(strKeyView);
+ if (!pwallet->LoadKey(keyView, vchSecret))
{
- strErr = "Error reading wallet database: CMalleableKey is corrupt";
- return false;
- }
- if (mKey.GetID() != keyView.GetID())
- {
- strErr = "Error reading wallet database: CMalleableKey view inconsistency";
+ strErr = "Error reading wallet database: LoadKey failed";
return false;
}
+ }
+ else if (strType == "malcpair")
+ {
+ string strKeyView;
- if (!pwallet->LoadMalleableKey(mKey))
+ std::vector<unsigned char> vchCryptedSecret;
+ ssKey >> strKeyView;
+ ssValue >> vchCryptedSecret;
+
+ CMalleableKeyView keyView(strKeyView);
+ if (!pwallet->LoadCryptedKey(keyView, vchCryptedSecret))
{
- strErr = "Error reading wallet database: LoadMalleableKey failed";
+ strErr = "Error reading wallet database: LoadCryptedKey failed";
return false;
}
}
ssValue >> keyMeta;
wss.nKeyMeta++;
- pwallet->LoadMalleableKeyMetadata(keyView, keyMeta);
+ pwallet->LoadKeyMetadata(keyView, keyMeta);
}
else if (strType == "keymeta")
{
// If no metadata exists yet, create a default with the pool key's
// creation time. Note that this may be overwritten by actually
// stored metadata for that key later, which is fine.
- CKeyID keyid = keypool.vchPubKey.GetID();
- if (pwallet->mapKeyMetadata.count(keyid) == 0)
- pwallet->mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
+ CBitcoinAddress addr = CBitcoinAddress(keypool.vchPubKey.GetID());
+ if (pwallet->mapKeyMetadata.count(addr) == 0)
+ pwallet->mapKeyMetadata[addr] = CKeyMetadata(keypool.nTime);
}
else if (strType == "version")
static bool IsKeyType(string strType)
{
return (strType== "key" || strType == "wkey" ||
- strType == "mkey" || strType == "ckey" || strType == "malpair");
+ strType == "mkey" || strType == "ckey" || strType == "malpair" || strType == "malcpair");
}
DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
bool DumpWallet(CWallet* pwallet, const string& strDest)
{
+ if (!pwallet->fFileBacked)
+ return false;
- if (!pwallet->fFileBacked)
- return false;
- while (!fShutdown)
- {
- // Populate maps
- std::map<CKeyID, int64_t> mapKeyBirth;
- std::set<CKeyID> setKeyPool;
- pwallet->GetKeyBirthTimes(mapKeyBirth);
- pwallet->GetAllReserveKeys(setKeyPool);
-
- // sort time/key pairs
- std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
- for (std::map<CKeyID, int64_t>::const_iterator it = mapKeyBirth.begin(); it != mapKeyBirth.end(); it++) {
- vKeyBirth.push_back(std::make_pair(it->second, it->first));
- }
- mapKeyBirth.clear();
- std::sort(vKeyBirth.begin(), vKeyBirth.end());
-
- // open outputfile as a stream
- ofstream file;
- file.open(strDest.c_str());
- if (!file.is_open())
- return false;
-
- // produce output
- file << strprintf("# Wallet dump created by NovaCoin %s (%s)\n", CLIENT_BUILD.c_str(), CLIENT_DATE.c_str());
- file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()).c_str());
- file << strprintf("# * Best block at time of backup was %i (%s),\n", nBestHeight, hashBestChain.ToString().c_str());
- file << strprintf("# mined on %s\n", EncodeDumpTime(pindexBest->nTime).c_str());
- file << "\n";
- for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {
- const CKeyID &keyid = it->second;
- std::string strTime = EncodeDumpTime(it->first);
- std::string strAddr = CBitcoinAddress(keyid).ToString();
- bool IsCompressed;
-
- CKey key;
- if (pwallet->GetKey(keyid, key)) {
- if (pwallet->mapAddressBook.count(keyid)) {
- CSecret secret = key.GetSecret(IsCompressed);
- file << strprintf("%s %s label=%s # addr=%s\n",
- CBitcoinSecret(secret, IsCompressed).ToString().c_str(),
- strTime.c_str(),
- EncodeDumpString(pwallet->mapAddressBook[keyid]).c_str(),
- strAddr.c_str());
- } else if (setKeyPool.count(keyid)) {
- CSecret secret = key.GetSecret(IsCompressed);
- file << strprintf("%s %s reserve=1 # addr=%s\n",
- CBitcoinSecret(secret, IsCompressed).ToString().c_str(),
- strTime.c_str(),
- strAddr.c_str());
- } else {
- CSecret secret = key.GetSecret(IsCompressed);
- file << strprintf("%s %s change=1 # addr=%s\n",
- CBitcoinSecret(secret, IsCompressed).ToString().c_str(),
- strTime.c_str(),
- strAddr.c_str());
- }
- }
- }
- file << "\n";
- file << "# End of dump\n";
- file.close();
- return true;
- }
- return false;
-}
+ std::map<CBitcoinAddress, int64_t> mapAddresses;
+ std::set<CKeyID> setKeyPool;
+
+ pwallet->GetAddresses(mapAddresses);
+ pwallet->GetAllReserveKeys(setKeyPool);
+
+ // sort time/key pairs
+ std::vector<std::pair<int64_t, CBitcoinAddress> > vAddresses;
+ for (std::map<CBitcoinAddress, int64_t>::const_iterator it = mapAddresses.begin(); it != mapAddresses.end(); it++) {
+ vAddresses.push_back(std::make_pair(it->second, it->first));
+ }
+ mapAddresses.clear();
+ std::sort(vAddresses.begin(), vAddresses.end());
+ // open outputfile as a stream
+ ofstream file;
+ file.open(strDest.c_str());
+ if (!file.is_open())
+ return false;
+
+ // produce output
+ file << strprintf("# Wallet dump created by NovaCoin %s (%s)\n", CLIENT_BUILD.c_str(), CLIENT_DATE.c_str());
+ file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()).c_str());
+ file << strprintf("# * Best block at time of backup was %i (%s),\n", nBestHeight, hashBestChain.ToString().c_str());
+ file << strprintf("# mined on %s\n", EncodeDumpTime(pindexBest->nTime).c_str());
+ file << "\n";
+
+ for (std::vector<std::pair<int64_t, CBitcoinAddress> >::const_iterator it = vAddresses.begin(); it != vAddresses.end(); it++) {
+ const CBitcoinAddress &addr = it->second;
+ std::string strTime = EncodeDumpTime(it->first);
+ std::string strAddr = addr.ToString();
+
+ if (addr.IsPair()) {
+ // Pubkey pair address
+ CMalleableKeyView keyView;
+ CMalleablePubKey mPubKey(addr.GetData());
+ if (!pwallet->GetMalleableView(mPubKey, keyView))
+ continue;
+ CMalleableKey mKey;
+ pwallet->GetMalleableKey(keyView, mKey);
+ file << mKey.ToString();
+ if (pwallet->mapAddressBook.count(addr))
+ file << strprintf(" %s label=%s # view=%s addr=%s\n", strTime.c_str(), EncodeDumpString(pwallet->mapAddressBook[addr]).c_str(), keyView.ToString().c_str(), strAddr.c_str());
+ else
+ file << strprintf(" %s # view=%s addr=%s\n", strTime.c_str(), keyView.ToString().c_str(), strAddr.c_str());
+ }
+ else {
+ // Pubkey hash address
+ CKeyID keyid;
+ addr.GetKeyID(keyid);
+ bool IsCompressed;
+ CKey key;
+ if (!pwallet->GetKey(keyid, key))
+ continue;
+ CSecret secret = key.GetSecret(IsCompressed);
+ file << CBitcoinSecret(secret, IsCompressed).ToString();
+ if (pwallet->mapAddressBook.count(addr))
+ file << strprintf(" %s label=%s # addr=%s\n", strTime.c_str(), EncodeDumpString(pwallet->mapAddressBook[addr]).c_str(), strAddr.c_str());
+ else if (setKeyPool.count(keyid))
+ file << strprintf(" %s reserve=1 # addr=%s\n", strTime.c_str(), strAddr.c_str());
+ else
+ file << strprintf(" %s change=1 # addr=%s\n", strTime.c_str(), strAddr.c_str());
+ }
+ }
+
+ file << "\n";
+ file << "# End of dump\n";
+ file.close();
+
+ return true;
+}
bool ImportWallet(CWallet *pwallet, const string& strLocation)
{
if (!pwallet->fFileBacked)
return false;
- while (!fShutdown)
- {
- // open inputfile as stream
- ifstream file;
- file.open(strLocation.c_str());
- if (!file.is_open())
- return false;
-
- int64_t nTimeBegin = pindexBest->nTime;
-
- bool fGood = true;
-
- // read through input file checking and importing keys into wallet.
- while (file.good()) {
- std::string line;
- std::getline(file, line);
- if (line.empty() || line[0] == '#')
- continue;
-
- std::vector<std::string> vstr;
- boost::split(vstr, line, boost::is_any_of(" "));
- if (vstr.size() < 2)
- continue;
- CBitcoinSecret vchSecret;
- if (!vchSecret.SetString(vstr[0]))
- continue;
-
- bool fCompressed;
- CKey key;
- CSecret secret = vchSecret.GetSecret(fCompressed);
- key.SetSecret(secret, fCompressed);
- CKeyID keyid = key.GetPubKey().GetID();
-
- if (pwallet->HaveKey(keyid)) {
- printf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString().c_str());
- continue;
- }
- int64_t nTime = DecodeDumpTime(vstr[1]);
- std::string strLabel;
- bool fLabel = true;
- for (unsigned int nStr = 2; nStr < vstr.size(); nStr++) {
- if (boost::algorithm::starts_with(vstr[nStr], "#"))
- break;
- if (vstr[nStr] == "change=1")
- fLabel = false;
- if (vstr[nStr] == "reserve=1")
- fLabel = false;
- if (boost::algorithm::starts_with(vstr[nStr], "label=")) {
- strLabel = DecodeDumpString(vstr[nStr].substr(6));
- fLabel = true;
- }
- }
- printf("Importing %s...\n", CBitcoinAddress(keyid).ToString().c_str());
- if (!pwallet->AddKey(key)) {
- fGood = false;
- continue;
- }
- pwallet->mapKeyMetadata[keyid].nCreateTime = nTime;
- if (fLabel)
- pwallet->SetAddressBookName(keyid, strLabel);
- nTimeBegin = std::min(nTimeBegin, nTime);
- }
- file.close();
-
- // rescan block chain looking for coins from new keys
- CBlockIndex *pindex = pindexBest;
- while (pindex && pindex->pprev && pindex->nTime > nTimeBegin - 7200)
- pindex = pindex->pprev;
-
- printf("Rescanning last %i blocks\n", pindexBest->nHeight - pindex->nHeight + 1);
- pwallet->ScanForWalletTransactions(pindex);
- pwallet->ReacceptWalletTransactions();
- pwallet->MarkDirty();
-
- return fGood;
-
- }
-
- return false;
-}
+ // open inputfile as stream
+ ifstream file;
+ file.open(strLocation.c_str());
+ if (!file.is_open())
+ return false;
+ bool fGood = true;
+ int64_t nTimeBegin = pindexBest->nTime;
+
+ // read through input file checking and importing keys into wallet.
+ while (file.good()) {
+ std::string line;
+ std::getline(file, line);
+ if (line.empty() || line[0] == '#')
+ continue; // Skip comments and empty lines
+
+ std::vector<std::string> vstr;
+ istringstream iss(line);
+ copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter(vstr));
+ if (vstr.size() < 2)
+ continue;
+
+ int64_t nTime = DecodeDumpTime(vstr[1]);
+ std::string strLabel;
+ bool fLabel = true;
+ for (unsigned int nStr = 2; nStr < vstr.size(); nStr++) {
+ if (boost::algorithm::starts_with(vstr[nStr], "#"))
+ break;
+ if (vstr[nStr] == "change=1")
+ fLabel = false;
+ if (vstr[nStr] == "reserve=1")
+ fLabel = false;
+ if (boost::algorithm::starts_with(vstr[nStr], "label=")) {
+ strLabel = DecodeDumpString(vstr[nStr].substr(6));
+ fLabel = true;
+ }
+ }
+
+ CBitcoinAddress addr;
+ CBitcoinSecret vchSecret;
+ if (vchSecret.SetString(vstr[0])) {
+ // Simple private key
+
+ bool fCompressed;
+ CKey key;
+ CSecret secret = vchSecret.GetSecret(fCompressed);
+ key.SetSecret(secret, fCompressed);
+ CKeyID keyid = key.GetPubKey().GetID();
+ addr = CBitcoinAddress(keyid);
+
+ if (pwallet->HaveKey(keyid)) {
+ printf("Skipping import of %s (key already present)\n", addr.ToString().c_str());
+ continue;
+ }
+
+ printf("Importing %s...\n", addr.ToString().c_str());
+ if (!pwallet->AddKey(key)) {
+ fGood = false;
+ continue;
+ }
+ } else {
+ // A pair of private keys
+
+ CMalleableKey mKey;
+ if (!mKey.SetString(vstr[0]))
+ continue;
+ CMalleablePubKey mPubKey = mKey.GetMalleablePubKey();
+ addr = CBitcoinAddress(mPubKey);
+
+ if (pwallet->CheckOwnership(mPubKey)) {
+ printf("Skipping import of %s (key already present)\n", addr.ToString().c_str());
+ continue;
+ }
+
+ printf("Importing %s...\n", addr.ToString().c_str());
+ if (!pwallet->AddKey(mKey)) {
+ fGood = false;
+ continue;
+ }
+ }
+
+ pwallet->mapKeyMetadata[addr].nCreateTime = nTime;
+ if (fLabel)
+ pwallet->SetAddressBookName(addr, strLabel);
+
+ nTimeBegin = std::min(nTimeBegin, nTime);
+ }
+ file.close();
+
+ // rescan block chain looking for coins from new keys
+ CBlockIndex *pindex = pindexBest;
+ while (pindex && pindex->pprev && pindex->nTime > nTimeBegin - 7200)
+ pindex = pindex->pprev;
+
+ printf("Rescanning last %i blocks\n", pindexBest->nHeight - pindex->nHeight + 1);
+ pwallet->ScanForWalletTransactions(pindex);
+ pwallet->ReacceptWalletTransactions();
+ pwallet->MarkDirty();
+
+ return fGood;
+}
//
// Try to (very carefully!) recover wallet.dat if there is a problem.