From db1eaec482383385156b3e7cb6b2baa9454975f0 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Fri, 11 Mar 2016 20:10:20 +0300 Subject: [PATCH] Keep address labels for pubkey pair addresses. --- src/base58.cpp | 7 ++ src/base58.h | 1 + src/init.cpp | 2 +- src/qt/addresstablemodel.cpp | 20 +++--- src/qt/coincontroldialog.cpp | 16 ++--- src/qt/multisigdialog.cpp | 4 +- src/qt/transactiondesc.cpp | 6 +- src/qt/transactionrecord.cpp | 2 +- src/qt/walletmodel.cpp | 14 ++-- src/rpcdump.cpp | 11 ++-- src/rpcwallet.cpp | 94 +++++++++++++------------- src/script.cpp | 39 ++++++++++- src/script.h | 3 +- src/wallet.cpp | 153 ++++++++++++++++-------------------------- src/wallet.h | 24 ++++--- src/walletdb.cpp | 41 +++++++----- 16 files changed, 226 insertions(+), 211 deletions(-) diff --git a/src/base58.cpp b/src/base58.cpp index 2691ea4..1c26380 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -254,6 +254,13 @@ bool DecodeBase58Check(const std::string& str, std::vector& vchRe return true; } + bool CBitcoinAddress::Set(const CBitcoinAddress &dest) + { + nVersion = dest.nVersion; + vchData = dest.vchData; + return true; + } + bool CBitcoinAddress::IsValid() const { unsigned int nExpectedSize = 20; diff --git a/src/base58.h b/src/base58.h index 2b6e326..0ca0fda 100644 --- a/src/base58.h +++ b/src/base58.h @@ -115,6 +115,7 @@ public: bool Set(const CScriptID &id); bool Set(const CTxDestination &dest); bool Set(const CMalleablePubKey &mpk); + bool Set(const CBitcoinAddress &dest); bool IsValid() const; CBitcoinAddress() diff --git a/src/init.cpp b/src/init.cpp index 417b342..2f237c0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -900,7 +900,7 @@ bool AppInit2() if (!pwalletMain->GetKeyFromPool(newDefaultKey, false)) strErrors << _("Cannot initialize keypool") << "\n"; pwalletMain->SetDefaultKey(newDefaultKey); - if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), "")) + if (!pwalletMain->SetAddressBookName(CBitcoinAddress(pwalletMain->vchDefaultKey.GetID()), "")) strErrors << _("Cannot write default address") << "\n"; } diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 03b09cd..a5dc784 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -59,11 +59,11 @@ public: cachedAddressTable.clear(); { LOCK(wallet->cs_wallet); - BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& item, wallet->mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook) { const CBitcoinAddress& address = item.first; const std::string& strName = item.second; - bool fMine = IsMine(*wallet, address.Get()); + bool fMine = IsMine(*wallet, address); cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending, QString::fromStdString(strName), QString::fromStdString(address.ToString()))); @@ -229,7 +229,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, editStatus = NO_CHANGES; return false; } - wallet->SetAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get(), value.toString().toStdString()); + wallet->SetAddressBookName(CBitcoinAddress(rec->address.toStdString()), value.toString().toStdString()); break; case Address: // Do nothing, if old address == new address @@ -246,7 +246,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, } // Check for duplicate addresses to prevent accidental deletion of addresses, if you try // to paste an existing address over another address (with a different label) - else if(wallet->mapAddressBook.count(CBitcoinAddress(value.toString().toStdString()).Get())) + else if(wallet->mapAddressBook.count(CBitcoinAddress(value.toString().toStdString()))) { editStatus = DUPLICATE_ADDRESS; return false; @@ -257,9 +257,9 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, { LOCK(wallet->cs_wallet); // Remove old entry - wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get()); + wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString())); // Add new entry with new address - wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()).Get(), rec->label.toStdString()); + wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()), rec->label.toStdString()); } } break; @@ -335,7 +335,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con // Check for duplicate addresses { LOCK(wallet->cs_wallet); - if(wallet->mapAddressBook.count(CBitcoinAddress(strAddress).Get())) + if(wallet->mapAddressBook.count(CBitcoinAddress(strAddress))) { editStatus = DUPLICATE_ADDRESS; return QString(); @@ -368,7 +368,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con // Add entry { LOCK(wallet->cs_wallet); - wallet->SetAddressBookName(CBitcoinAddress(strAddress).Get(), strLabel); + wallet->SetAddressBookName(CBitcoinAddress(strAddress), strLabel); } return QString::fromStdString(strAddress); } @@ -385,7 +385,7 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex &parent } { LOCK(wallet->cs_wallet); - wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get()); + wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString())); } return true; } @@ -397,7 +397,7 @@ QString AddressTableModel::labelForAddress(const QString &address) const { LOCK(wallet->cs_wallet); CBitcoinAddress address_parsed(address.toStdString()); - std::map::iterator mi = wallet->mapAddressBook.find(address_parsed.Get()); + std::map::iterator mi = wallet->mapAddressBook.find(address_parsed); if (mi != wallet->mapAddressBook.end()) { return QString::fromStdString(mi->second); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 9ea82a4..7b7472b 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -4,7 +4,7 @@ #include "init.h" #include "base58.h" #include "bitcoinunits.h" -#include "wallet.h" +#include "script.h" #include "walletmodel.h" #include "addresstablemodel.h" #include "optionsmodel.h" @@ -471,16 +471,15 @@ void CoinControlDialog::updateLabels(WalletModel *model, QWidget* dialog) // Bytes CBitcoinAddress address; - if(pwalletMain->ExtractAddress(out.tx->vout[out.i].scriptPubKey, address)) + if(ExtractAddress(*pwalletMain, out.tx->vout[out.i].scriptPubKey, address)) { if (address.IsPair()) nBytesInputs += 213; else if (address.IsPubKey()) { CPubKey pubkey; - CTxDestination dest = address.Get(); - CKeyID *keyid = boost::get< CKeyID >(&dest); - if (keyid && model->getPubKey(*keyid, pubkey)) + CKeyID keyid; + if (address.GetKeyID(keyid) && model->getPubKey(keyid, pubkey)) nBytesInputs += (pubkey.IsCompressed() ? 148 : 180); else nBytesInputs += 148; // in all error cases, simply assume 148 here @@ -640,7 +639,7 @@ void CoinControlDialog::updateView() CBitcoinAddress outputAddress; QString sAddress = ""; - if(pwalletMain->ExtractAddress(out.tx->vout[out.i].scriptPubKey, outputAddress)) + if(ExtractAddress(*pwalletMain, out.tx->vout[out.i].scriptPubKey, outputAddress)) { sAddress = CBitcoinAddress(outputAddress).ToString().c_str(); @@ -651,9 +650,8 @@ void CoinControlDialog::updateView() if (outputAddress.IsPubKey()) { CPubKey pubkey; - CTxDestination dest = outputAddress.Get(); - CKeyID *keyid = boost::get< CKeyID >(&dest); - if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed()) + CKeyID keyid; + if (outputAddress.GetKeyID(keyid) && model->getPubKey(keyid, pubkey) && !pubkey.IsCompressed()) nInputSize = 180; } } diff --git a/src/qt/multisigdialog.cpp b/src/qt/multisigdialog.cpp index 8f9beea..a82f76e 100644 --- a/src/qt/multisigdialog.cpp +++ b/src/qt/multisigdialog.cpp @@ -243,8 +243,8 @@ void MultisigDialog::on_saveMultisigAddressButton_clicked() LOCK(wallet->cs_wallet); if(!wallet->HaveCScript(scriptID)) wallet->AddCScript(script); - if(!wallet->mapAddressBook.count(CBitcoinAddress(address).Get())) - wallet->SetAddressBookName(CBitcoinAddress(address).Get(), label); + if(!wallet->mapAddressBook.count(CBitcoinAddress(address))) + wallet->SetAddressBookName(CBitcoinAddress(address), label); } void MultisigDialog::clear() diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 4033621..72bc460 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -142,9 +142,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) // Online transaction std::string strAddress = wtx.mapValue["to"]; strHTML += "" + tr("To") + ": "; - CTxDestination dest = CBitcoinAddress(strAddress).Get(); - if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].empty()) - strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest]) + " "; + CBitcoinAddress addr(strAddress); + if (wallet->mapAddressBook.count(addr) && !wallet->mapAddressBook[addr].empty()) + strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[addr]) + " "; strHTML += GUIUtil::HtmlEscape(strAddress) + "
"; } diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 98b6171..a4066cf 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -50,7 +50,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * sub.credit = txout.nValue; CBitcoinAddress addressRet; - if (pwalletMain->ExtractAddress(txout.scriptPubKey, addressRet)) + if (ExtractAddress(*pwalletMain, txout.scriptPubKey, addressRet)) { sub.type = TransactionRecord::RecvWithAddress; sub.address = addressRet.ToString(); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index d761fa0..faf5049 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -239,17 +239,17 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QListcs_wallet); - std::map::iterator mi = wallet->mapAddressBook.find(dest); + std::map::iterator mi = wallet->mapAddressBook.find(addr); // Check if we have a new address or an updated label if (mi == wallet->mapAddressBook.end() || mi->second != strLabel) { - wallet->SetAddressBookName(dest, strLabel); + wallet->SetAddressBookName(addr, strLabel); } } } @@ -359,11 +359,11 @@ static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStor QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection); } -static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status) +static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CBitcoinAddress &address, const std::string &label, bool isMine, ChangeType status) { - OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", CBitcoinAddress(address).ToString().c_str(), label.c_str(), isMine, status); + OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", address.ToString().c_str(), label.c_str(), isMine, status); QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection, - Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())), + Q_ARG(QString, QString::fromStdString(address.ToString())), Q_ARG(QString, QString::fromStdString(label)), Q_ARG(bool, isMine), Q_ARG(int, status)); @@ -496,7 +496,7 @@ void WalletModel::listCoins(std::map >& mapCoins) } CBitcoinAddress addressRet; - if(!out.fSpendable || !wallet->ExtractAddress(cout.tx->vout[cout.i].scriptPubKey, addressRet)) + if(!out.fSpendable || !ExtractAddress(*wallet, cout.tx->vout[cout.i].scriptPubKey, addressRet)) continue; mapCoins[addressRet.ToString().c_str()].push_back(out); diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 1499ace..94eaad2 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -62,18 +62,19 @@ Value importprivkey(const Array& params, bool fHelp) bool fCompressed; CSecret secret = vchSecret.GetSecret(fCompressed); key.SetSecret(secret, fCompressed); - CKeyID vchAddress = key.GetPubKey().GetID(); + CKeyID keyid = key.GetPubKey().GetID(); + CBitcoinAddress addr = CBitcoinAddress(keyid); { LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->MarkDirty(); - pwalletMain->SetAddressBookName(vchAddress, strLabel); + pwalletMain->SetAddressBookName(addr, strLabel); // Don't throw error in case a key is already there - if (pwalletMain->HaveKey(vchAddress)) + if (pwalletMain->HaveKey(keyid)) return Value::null; - pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; + pwalletMain->mapKeyMetadata[addr].nCreateTime = 1; if (!pwalletMain->AddKey(key)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); @@ -131,7 +132,7 @@ Value importaddress(const Array& params, bool fHelp) pwalletMain->MarkDirty(); if (address.IsValid()) - pwalletMain->SetAddressBookName(address.Get(), strLabel); + pwalletMain->SetAddressBookName(address, strLabel); if (!pwalletMain->AddWatchOnly(script)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index bab881d..61ee9e9 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -134,11 +134,11 @@ Value getnewaddress(const Array& params, bool fHelp) CPubKey newKey; if (!pwalletMain->GetKeyFromPool(newKey, false)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); - CKeyID keyID = newKey.GetID(); + CBitcoinAddress address(newKey.GetID()); - pwalletMain->SetAddressBookName(keyID, strAccount); + pwalletMain->SetAddressBookName(address, strAccount); - return CBitcoinAddress(keyID).ToString(); + return address.ToString(); } @@ -173,7 +173,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); - pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), strAccount); + pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey.GetID()), strAccount); walletdb.WriteAccount(strAccount, account); } @@ -216,14 +216,14 @@ Value setaccount(const Array& params, bool fHelp) strAccount = AccountFromValue(params[1]); // Detect when changing the account of an address that is the 'unused current key' of another account: - if (pwalletMain->mapAddressBook.count(address.Get())) + if (pwalletMain->mapAddressBook.count(address)) { - string strOldAccount = pwalletMain->mapAddressBook[address.Get()]; + string strOldAccount = pwalletMain->mapAddressBook[address]; if (address == GetAccountAddress(strOldAccount)) GetAccountAddress(strOldAccount, true); } - pwalletMain->SetAddressBookName(address.Get(), strAccount); + pwalletMain->SetAddressBookName(address, strAccount); return Value::null; } @@ -241,7 +241,7 @@ Value getaccount(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address"); string strAccount; - map::iterator mi = pwalletMain->mapAddressBook.find(address.Get()); + map::iterator mi = pwalletMain->mapAddressBook.find(address); if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) strAccount = (*mi).second; return strAccount; @@ -366,19 +366,19 @@ Value listaddressgroupings(const Array& params, bool fHelp) "in past transactions"); Array jsonGroupings; - map balances = pwalletMain->GetAddressBalances(); - BOOST_FOREACH(set grouping, pwalletMain->GetAddressGroupings()) + map balances = pwalletMain->GetAddressBalances(); + BOOST_FOREACH(set grouping, pwalletMain->GetAddressGroupings()) { Array jsonGrouping; - BOOST_FOREACH(CTxDestination address, grouping) + BOOST_FOREACH(CBitcoinAddress address, grouping) { Array addressInfo; - addressInfo.push_back(CBitcoinAddress(address).ToString()); + addressInfo.push_back(address.ToString()); addressInfo.push_back(ValueFromAmount(balances[address])); { LOCK(pwalletMain->cs_wallet); - if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end()) - addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second); + if (pwalletMain->mapAddressBook.find(address) != pwalletMain->mapAddressBook.end()) + addressInfo.push_back(pwalletMain->mapAddressBook.find(address)->second); } jsonGrouping.push_back(addressInfo); } @@ -487,7 +487,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) BOOST_FOREACH(const CTxOut& txout, wtx.vout) { CBitcoinAddress addressRet; - if (!pwalletMain->ExtractAddress(txout.scriptPubKey, addressRet)) + if (!ExtractAddress(*pwalletMain, txout.scriptPubKey, addressRet)) continue; if (addressRet == address) if (wtx.GetDepthInMainChain() >= nMinDepth) @@ -498,11 +498,11 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) return ValueFromAmount(nAmount); } -void GetAccountAddresses(string strAccount, set& setAddress) +void GetAccountAddresses(string strAccount, set& setAddress) { - BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& item, pwalletMain->mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) { - const CTxDestination& address = item.first; + const CBitcoinAddress& address = item.first; const string& strName = item.second; if (strName == strAccount) setAddress.insert(address); @@ -523,7 +523,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) // Get the set of pub keys assigned to account string strAccount = AccountFromValue(params[0]); - set setAddress; + set setAddress; GetAccountAddresses(strAccount, setAddress); // Tally @@ -536,8 +536,8 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) BOOST_FOREACH(const CTxOut& txout, wtx.vout) { - CTxDestination address; - if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) + CBitcoinAddress address; + if (ExtractAddress(*pwalletMain, txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) if (wtx.GetDepthInMainChain() >= nMinDepth) nAmount += txout.nValue; } @@ -614,15 +614,15 @@ Value getbalance(const Array& params, bool fHelp) allGeneratedImmature = allGeneratedMature = allFee = 0; string strSentAccount; - list > listReceived; - list > listSent; + list > listReceived; + list > listSent; wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter); if (wtx.GetDepthInMainChain() >= nMinDepth) { - BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64_t)& r, listReceived) nBalance += r.second; } - BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listSent) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64_t)& r, listSent) nBalance -= r.second; nBalance -= allFee; nBalance += allGeneratedMature; @@ -886,11 +886,11 @@ Value addmultisigaddress(const Array& params, bool fHelp) throw runtime_error( strprintf("redeemScript exceeds size limit: %" PRIszu " > %d", inner.size(), MAX_SCRIPT_ELEMENT_SIZE)); - CScriptID innerID = inner.GetID(); pwalletMain->AddCScript(inner); + CBitcoinAddress address(inner.GetID()); - pwalletMain->SetAddressBookName(innerID, strAccount); - return CBitcoinAddress(innerID).ToString(); + pwalletMain->SetAddressBookName(address, strAccount); + return address.ToString(); } Value addredeemscript(const Array& params, bool fHelp) @@ -910,11 +910,11 @@ Value addredeemscript(const Array& params, bool fHelp) // Construct using pay-to-script-hash: vector innerData = ParseHexV(params[0], "redeemScript"); CScript inner(innerData.begin(), innerData.end()); - CScriptID innerID = inner.GetID(); pwalletMain->AddCScript(inner); + CBitcoinAddress address(inner.GetID()); - pwalletMain->SetAddressBookName(innerID, strAccount); - return CBitcoinAddress(innerID).ToString(); + pwalletMain->SetAddressBookName(address, strAccount); + return address.ToString(); } struct tallyitem @@ -1049,19 +1049,17 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) return ListReceived(params, true); } -static void MaybePushAddress(Object & entry, const CTxDestination &dest) +static void MaybePushAddress(Object & entry, const CBitcoinAddress &dest) { - CBitcoinAddress addr; - if (addr.Set(dest)) - entry.push_back(Pair("address", addr.ToString())); + entry.push_back(Pair("address", dest.ToString())); } void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter) { int64_t nGeneratedImmature, nGeneratedMature, nFee; string strSentAccount; - list > listReceived; - list > listSent; + list > listReceived; + list > listSent; wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount, filter); @@ -1091,7 +1089,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe // Sent if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) { - BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64_t)& s, listSent) { Object entry; entry.push_back(Pair("account", strSentAccount)); @@ -1116,7 +1114,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe // Received if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) { - BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64_t)& r, listReceived) { string account; if (pwalletMain->mapAddressBook.count(r.first)) @@ -1246,7 +1244,7 @@ Value listaccounts(const Array& params, bool fHelp) map mapAccountBalances; - BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) { + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) { if (IsMine(*pwalletMain, entry.first)) // This address belongs to me mapAccountBalances[entry.second] = 0; } @@ -1256,16 +1254,16 @@ Value listaccounts(const Array& params, bool fHelp) const CWalletTx& wtx = (*it).second; int64_t nGeneratedImmature, nGeneratedMature, nFee; string strSentAccount; - list > listReceived; - list > listSent; + list > listReceived; + list > listSent; wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount, includeWatchonly); mapAccountBalances[strSentAccount] -= nFee; - BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64_t)& s, listSent) mapAccountBalances[strSentAccount] -= s.second; if (wtx.GetDepthInMainChain() >= nMinDepth) { mapAccountBalances[""] += nGeneratedMature; - BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64_t)& r, listReceived) if (pwalletMain->mapAddressBook.count(r.first)) mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; else @@ -1750,18 +1748,18 @@ Value validateaddress(const Array& params, bool fHelp) } else { - CTxDestination dest = address.Get(); string currentAddress = address.ToString(); + CTxDestination dest = address.Get(); ret.push_back(Pair("address", currentAddress)); - isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : MINE_NO; + isminetype mine = pwalletMain ? IsMine(*pwalletMain, address) : MINE_NO; ret.push_back(Pair("ismine", mine != MINE_NO)); if (mine != MINE_NO) { ret.push_back(Pair("watchonly", mine == MINE_WATCH_ONLY)); Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); ret.insert(ret.end(), detail.begin(), detail.end()); } - if (pwalletMain->mapAddressBook.count(dest)) - ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest])); + if (pwalletMain->mapAddressBook.count(address)) + ret.push_back(Pair("account", pwalletMain->mapAddressBook[address])); } } return ret; diff --git a/src/script.cpp b/src/script.cpp index 2212fe1..16dfa99 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1640,12 +1640,13 @@ public: bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); } }; +/* isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest) { CScript script; script.SetDestination(dest); return IsMine(keystore, script); -} +}*/ isminetype IsMine(const CKeyStore &keystore, const CBitcoinAddress& dest) { @@ -1744,6 +1745,42 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) return false; } +bool ExtractAddress(const CKeyStore &keystore, const CScript& scriptPubKey, CBitcoinAddress& addressRet) +{ + vector vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_PUBKEY) + { + addressRet = CBitcoinAddress(CPubKey(vSolutions[0]).GetID()); + return true; + } + if (whichType == TX_PUBKEY_DROP) + { + // Pay-to-Pubkey-R + CMalleableKeyView view; + if (!keystore.CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view)) + return false; + + addressRet = CBitcoinAddress(view.GetMalleablePubKey()); + return true; + } + else if (whichType == TX_PUBKEYHASH) + { + addressRet = CBitcoinAddress(CKeyID(uint160(vSolutions[0]))); + return true; + } + else if (whichType == TX_SCRIPTHASH) + { + addressRet = CBitcoinAddress(CScriptID(uint160(vSolutions[0]))); + return true; + } + // Multisig txns have more than one address... + return false; +} + class CAffectedKeysVisitor : public boost::static_visitor { private: const CKeyStore &keystore; diff --git a/src/script.h b/src/script.h index 7177339..c24ab9c 100644 --- a/src/script.h +++ b/src/script.h @@ -637,10 +637,11 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutions); bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); -isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); +//isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); isminetype IsMine(const CKeyStore& keystore, const CBitcoinAddress& dest); void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector &vKeys); bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); +bool ExtractAddress(const CKeyStore &keystore, const CScript& scriptPubKey, CBitcoinAddress& addressRet); bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector& addressRet, int& nRequiredRet); bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); diff --git a/src/wallet.cpp b/src/wallet.cpp index 07518d0..8006674 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -48,7 +48,7 @@ CPubKey CWallet::GenerateNewKey() // Create new metadata int64_t nCreationTime = GetTime(); - mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime); + mapKeyMetadata[CBitcoinAddress(pubkey.GetID())] = CKeyMetadata(nCreationTime); if (!nTimeFirstKey || nCreationTime < nTimeFirstKey) nTimeFirstKey = nCreationTime; @@ -70,7 +70,7 @@ CMalleableKeyView CWallet::GenerateNewMalleableKey() // Create new metadata int64_t nCreationTime = GetTime(); - mapMalleableKeyMetadata[keyView] = CKeyMetadata(nCreationTime); + mapKeyMetadata[CBitcoinAddress(keyView.GetMalleablePubKey())] = CKeyMetadata(nCreationTime); if (!nTimeFirstKey || nCreationTime < nTimeFirstKey) nTimeFirstKey = nCreationTime; @@ -87,7 +87,7 @@ bool CWallet::AddKey(const CKey& key) if (!fFileBacked) return true; if (!IsCrypted()) - return CWalletDB(strWalletFile).WriteKey(pubkey, key.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]); + return CWalletDB(strWalletFile).WriteKey(pubkey, key.GetPrivKey(), mapKeyMetadata[CBitcoinAddress(pubkey.GetID())]); return true; } @@ -100,7 +100,7 @@ bool CWallet::AddMalleableKey(const CMalleableKey& mKey) if (!fFileBacked) return true; if (!IsCrypted()) - return CWalletDB(strWalletFile).WriteMalleableKey(keyView, vchSecretH, mapMalleableKeyMetadata[keyView]); + return CWalletDB(strWalletFile).WriteMalleableKey(keyView, vchSecretH, mapKeyMetadata[CBitcoinAddress(keyView.GetMalleablePubKey())]); return true; } @@ -114,10 +114,11 @@ bool CWallet::AddCryptedMalleableKey(const CMalleableKeyView& keyView, const std { LOCK(cs_wallet); + CBitcoinAddress addr(keyView.GetMalleablePubKey()); if (pwalletdbEncryption) - return pwalletdbEncryption->WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapMalleableKeyMetadata[keyView]); + return pwalletdbEncryption->WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapKeyMetadata[addr]); else - return CWalletDB(strWalletFile).WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapMalleableKeyMetadata[keyView]); + return CWalletDB(strWalletFile).WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapKeyMetadata[addr]); } return true; @@ -138,10 +139,11 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vectorWriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); + return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[addr]); else - return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); + return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[addr]); } return false; } @@ -151,16 +153,16 @@ bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta) if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey)) nTimeFirstKey = meta.nCreateTime; - mapKeyMetadata[pubkey.GetID()] = meta; + mapKeyMetadata[CBitcoinAddress(pubkey.GetID())] = meta; return true; } -bool CWallet::LoadMalleableKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata) +bool CWallet::LoadKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata) { if (metadata.nCreateTime && (!nTimeFirstKey || metadata.nCreateTime < nTimeFirstKey)) nTimeFirstKey = metadata.nCreateTime; - mapMalleableKeyMetadata[keyView] = metadata; + mapKeyMetadata[CBitcoinAddress(keyView.GetMalleablePubKey())] = metadata; return true; } @@ -476,7 +478,7 @@ bool CWallet::DecryptWallet(const SecureString& strWalletPassphrase) CKey key; key.SetSecret((*mi).second.first, (*mi).second.second); pwalletdbDecryption->EraseCryptedKey(key.GetPubKey()); - pwalletdbDecryption->WriteKey(key.GetPubKey(), key.GetPrivKey(), mapKeyMetadata[(*mi).first]); + pwalletdbDecryption->WriteKey(key.GetPubKey(), key.GetPrivKey(), mapKeyMetadata[CBitcoinAddress(mi->first)]); mi++; } @@ -486,7 +488,7 @@ bool CWallet::DecryptWallet(const SecureString& strWalletPassphrase) const CSecret &vchSecretH = mi2->second; const CMalleableKeyView &keyView = mi2->first; pwalletdbDecryption->EraseCryptedMalleableKey(keyView); - pwalletdbDecryption->WriteMalleableKey(keyView, vchSecretH, mapMalleableKeyMetadata[keyView]); + pwalletdbDecryption->WriteMalleableKey(keyView, vchSecretH, mapKeyMetadata[CBitcoinAddress(keyView.GetMalleablePubKey())]); mi2++; } @@ -867,8 +869,8 @@ int CWalletTx::GetRequestCount() const return nRequests; } -void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, list >& listReceived, - list >& listSent, int64_t& nFee, string& strSentAccount, const isminefilter& filter) const +void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, list >& listReceived, + list >& listSent, int64_t& nFee, string& strSentAccount, const isminefilter& filter) const { nGeneratedImmature = nGeneratedMature = nFee = 0; listReceived.clear(); @@ -909,12 +911,12 @@ void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMatur continue; // In either case, we need to get the destination address - CTxDestination address; - if (!ExtractDestination(txout.scriptPubKey, address)) + CBitcoinAddress address; + if (!ExtractAddress(*pwallet, txout.scriptPubKey, address)) { printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", this->GetHash().ToString().c_str()); - address = CNoDestination(); + address = CBitcoinAddress(); } // If we are debited by the transaction, add the output as a "sent" entry @@ -936,25 +938,25 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nGenerated, int64_t allGeneratedImmature, allGeneratedMature, allFee; allGeneratedImmature = allGeneratedMature = allFee = 0; string strSentAccount; - list > listReceived; - list > listSent; + list > listReceived; + list > listSent; GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter); if (strAccount == "") nGenerated = allGeneratedMature; if (strAccount == strSentAccount) { - BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& s, listSent) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64_t)& s, listSent) nSent += s.second; nFee = allFee; } { LOCK(pwallet->cs_wallet); - BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64_t)& r, listReceived) { if (pwallet->mapAddressBook.count(r.first)) { - map::const_iterator mi = pwallet->mapAddressBook.find(r.first); + map::const_iterator mi = pwallet->mapAddressBook.find(r.first); if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount) nReceived += r.second; } @@ -2234,23 +2236,23 @@ DBErrors CWallet::ZapWalletTx() return DB_LOAD_OK; } -bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName) +bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName) { - std::map::iterator mi = mapAddressBook.find(address); + std::map::iterator mi = mapAddressBook.find(address); mapAddressBook[address] = strName; NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != MINE_NO, (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED); if (!fFileBacked) return false; - return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName); + return CWalletDB(strWalletFile).WriteName(address.ToString(), strName); } -bool CWallet::DelAddressBookName(const CTxDestination& address) +bool CWallet::DelAddressBookName(const CBitcoinAddress& address) { mapAddressBook.erase(address); NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != MINE_NO, CT_DELETED); if (!fFileBacked) return false; - return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString()); + return CWalletDB(strWalletFile).EraseName(address.ToString()); } @@ -2470,9 +2472,9 @@ int64_t CWallet::GetOldestKeyPoolTime() return keypool.nTime; } -std::map CWallet::GetAddressBalances() +std::map CWallet::GetAddressBalances() { - map balances; + map balances; { LOCK(cs_wallet); @@ -2492,10 +2494,10 @@ std::map CWallet::GetAddressBalances() for (unsigned int i = 0; i < pcoin->vout.size(); i++) { - CTxDestination addr; + CBitcoinAddress addr; if (!IsMine(pcoin->vout[i])) continue; - if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr)) + if(!ExtractAddress(*this, pcoin->vout[i].scriptPubKey, addr)) continue; int64_t n = pcoin->IsSpent(i) ? 0 : pcoin->vout[i].nValue; @@ -2510,10 +2512,10 @@ std::map CWallet::GetAddressBalances() return balances; } -set< set > CWallet::GetAddressGroupings() +set< set > CWallet::GetAddressGroupings() { - set< set > groupings; - set grouping; + set< set > groupings; + set grouping; BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet) { @@ -2524,8 +2526,8 @@ set< set > CWallet::GetAddressGroupings() // group all input addresses with each other BOOST_FOREACH(CTxIn txin, pcoin->vin) { - CTxDestination address; - if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address)) + CBitcoinAddress address; + if(!ExtractAddress(*this, mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address)) continue; grouping.insert(address); } @@ -2535,8 +2537,8 @@ set< set > CWallet::GetAddressGroupings() if (IsChange(txout)) { CWalletTx tx = mapWallet[pcoin->vin[0].prevout.hash]; - CTxDestination txoutAddr; - if(!ExtractDestination(txout.scriptPubKey, txoutAddr)) + CBitcoinAddress txoutAddr; + if(!ExtractAddress(*this, txout.scriptPubKey, txoutAddr)) continue; grouping.insert(txoutAddr); } @@ -2548,8 +2550,8 @@ set< set > CWallet::GetAddressGroupings() for (unsigned int i = 0; i < pcoin->vout.size(); i++) if (IsMine(pcoin->vout[i])) { - CTxDestination address; - if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address)) + CBitcoinAddress address; + if(!ExtractAddress(*this, pcoin->vout[i].scriptPubKey, address)) continue; grouping.insert(address); groupings.insert(grouping); @@ -2557,20 +2559,20 @@ set< set > CWallet::GetAddressGroupings() } } - set< set* > uniqueGroupings; // a set of pointers to groups of addresses - map< CTxDestination, set* > setmap; // map addresses to the unique group containing it - BOOST_FOREACH(set grouping, groupings) + set< set* > uniqueGroupings; // a set of pointers to groups of addresses + map< CBitcoinAddress, set* > setmap; // map addresses to the unique group containing it + BOOST_FOREACH(set grouping, groupings) { // make a set of all the groups hit by this new group - set< set* > hits; - map< CTxDestination, set* >::iterator it; - BOOST_FOREACH(CTxDestination address, grouping) + set< set* > hits; + map< CBitcoinAddress, set* >::iterator it; + BOOST_FOREACH(CBitcoinAddress address, grouping) if ((it = setmap.find(address)) != setmap.end()) hits.insert((*it).second); // merge all hit groups into a new single group and delete old groups - set* merged = new set(grouping); - BOOST_FOREACH(set* hit, hits) + set* merged = new set(grouping); + BOOST_FOREACH(set* hit, hits) { merged->insert(hit->begin(), hit->end()); uniqueGroupings.erase(hit); @@ -2579,12 +2581,12 @@ set< set > CWallet::GetAddressGroupings() uniqueGroupings.insert(merged); // update setmap - BOOST_FOREACH(CTxDestination element, *merged) + BOOST_FOREACH(CBitcoinAddress element, *merged) setmap[element] = merged; } - set< set > ret; - BOOST_FOREACH(set* uniqueGrouping, uniqueGroupings) + set< set > ret; + BOOST_FOREACH(set* uniqueGrouping, uniqueGroupings) { ret.insert(*uniqueGrouping); delete uniqueGrouping; @@ -2747,14 +2749,8 @@ void CWallet::GetAddresses(std::map &mapAddresses) con mapAddresses.clear(); // get birth times for keys with metadata - for (std::map::const_iterator it = mapMalleableKeyMetadata.begin(); it != mapMalleableKeyMetadata.end(); it++) { - CBitcoinAddress addr(it->first.GetMalleablePubKey()); - mapAddresses[addr] = it->second.nCreateTime ? it->second.nCreateTime : 0; - } - - for (std::map::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) { - CBitcoinAddress addr(it->first); - mapAddresses[addr] = it->second.nCreateTime ? it->second.nCreateTime : 0; + for (std::map::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) { + mapAddresses[it->first] = it->second.nCreateTime ? it->second.nCreateTime : 0; } for (std::map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) { @@ -2767,7 +2763,7 @@ void CWallet::GetAddresses(std::map &mapAddresses) con const CTxOut &out = (*it2); // iterate over all their outputs CBitcoinAddress addressRet; - if (const_cast(this)->ExtractAddress(out.scriptPubKey, addressRet)) { + if (ExtractAddress(*this, out.scriptPubKey, addressRet)) { if (mapAddresses.find(addressRet) != mapAddresses.end() && (mapAddresses[addressRet] == 0 || mapAddresses[addressRet] > wtx.nTime)) mapAddresses[addressRet] = wtx.nTime; } @@ -2805,38 +2801,3 @@ void CWallet::ClearOrphans() EraseFromWallet(*it); } -bool CWallet::ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet) -{ - vector vSolutions; - txnouttype whichType; - if (!Solver(scriptPubKey, whichType, vSolutions)) - return false; - - if (whichType == TX_PUBKEY) - { - addressRet = CBitcoinAddress(CPubKey(vSolutions[0]).GetID()); - return true; - } - if (whichType == TX_PUBKEY_DROP) - { - // Pay-to-Pubkey-R - CMalleableKeyView view; - if (!CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view)) - return false; - - addressRet = CBitcoinAddress(view.GetMalleablePubKey()); - return true; - } - else if (whichType == TX_PUBKEYHASH) - { - addressRet = CBitcoinAddress(CKeyID(uint160(vSolutions[0]))); - return true; - } - else if (whichType == TX_SCRIPTHASH) - { - addressRet = CBitcoinAddress(CScriptID(uint160(vSolutions[0]))); - return true; - } - // Multisig txns have more than one address... - return false; -} diff --git a/src/wallet.h b/src/wallet.h index 6e36e9d..b3d7d33 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -96,8 +96,12 @@ public: std::string strWalletFile; std::set setKeyPool; + /* std::map mapKeyMetadata; std::map mapMalleableKeyMetadata; + */ + + std::map mapKeyMetadata; typedef std::map MasterKeyMap; MasterKeyMap mapMasterKeys; @@ -133,7 +137,7 @@ public: int64_t nOrderPosNext; std::map mapRequestCount; - std::map mapAddressBook; + std::map mapAddressBook; CPubKey vchDefaultKey; int64_t nTimeFirstKey; @@ -159,7 +163,7 @@ public: bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); } // Load metadata (used by LoadWallet) bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata); - bool LoadMalleableKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata); + bool LoadKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata); // Load malleable key without saving it to disk (used by LoadWallet) bool LoadMalleableKey(const CMalleableKeyView &keyView, const CSecret &vchSecretH) { return CCryptoKeyStore::AddMalleableKey(keyView, vchSecretH); } @@ -243,8 +247,8 @@ public: int64_t GetOldestKeyPoolTime(); void GetAllReserveKeys(std::set& setAddress) const; - std::set< std::set > GetAddressGroupings(); - std::map GetAddressBalances(); + std::set< std::set > GetAddressGroupings(); + std::map GetAddressBalances(); isminetype IsMine(const CTxIn& txin) const; int64_t GetDebit(const CTxIn& txin, const isminefilter& filter) const; @@ -315,9 +319,9 @@ public: DBErrors ZapWalletTx(); - bool SetAddressBookName(const CTxDestination& address, const std::string& strName); + bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName); - bool DelAddressBookName(const CTxDestination& address); + bool DelAddressBookName(const CBitcoinAddress& address); void UpdatedTransaction(const uint256 &hashTx); @@ -340,8 +344,6 @@ public: bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); - bool ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet); - bool SetDefaultKey(const CPubKey &vchPubKey); // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower @@ -359,7 +361,7 @@ public: /** Address book entry changed. * @note called with lock cs_wallet held. */ - boost::signals2::signal NotifyAddressBookChanged; + boost::signals2::signal NotifyAddressBookChanged; /** Wallet transaction added, removed or updated. * @note called with lock cs_wallet held. @@ -797,8 +799,8 @@ public: return nChangeCached; } - void GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, std::list >& listReceived, - std::list >& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter) const; + void GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, std::list >& listReceived, + std::list >& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter) const; void GetAccountAmounts(const std::string& strAccount, int64_t& nGenerated, int64_t& nReceived, int64_t& nSent, int64_t& nFee, const isminefilter& filter) const; diff --git a/src/walletdb.cpp b/src/walletdb.cpp index c8e64ca..e44885d 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -225,7 +225,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, { string strAddress; ssKey >> strAddress; - ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()]; + ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress)]; } else if (strType == "tx") { @@ -428,7 +428,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, ssValue >> keyMeta; wss.nKeyMeta++; - pwallet->LoadMalleableKeyMetadata(keyView, keyMeta); + pwallet->LoadKeyMetadata(keyView, keyMeta); } else if (strType == "keymeta") { @@ -460,9 +460,9 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, // 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") @@ -827,7 +827,11 @@ bool DumpWallet(CWallet* pwallet, const string& strDest) continue; CMalleableKey mKey; pwallet->GetMalleableKey(keyView, mKey); - file << strprintf("%s %s # view=%s addr=%s\n", mKey.ToString().c_str(), strTime.c_str(), keyView.ToString().c_str(), strAddr.c_str()); + 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 @@ -839,8 +843,8 @@ bool DumpWallet(CWallet* pwallet, const string& strDest) continue; CSecret secret = key.GetSecret(IsCompressed); file << CBitcoinSecret(secret, IsCompressed).ToString(); - if (pwallet->mapAddressBook.count(keyid)) - file << strprintf(" %s label=%s # addr=%s\n", strTime.c_str(), EncodeDumpString(pwallet->mapAddressBook[keyid]).c_str(), strAddr.c_str()); + 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 @@ -899,6 +903,7 @@ bool ImportWallet(CWallet *pwallet, const string& strLocation) } } + CBitcoinAddress addr; CBitcoinSecret vchSecret; if (vchSecret.SetString(vstr[0])) { // Simple private key @@ -908,20 +913,18 @@ bool ImportWallet(CWallet *pwallet, const string& strLocation) 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", CBitcoinAddress(keyid).ToString().c_str()); + printf("Skipping import of %s (key already present)\n", addr.ToString().c_str()); continue; } - printf("Importing %s...\n", CBitcoinAddress(keyid).ToString().c_str()); + printf("Importing %s...\n", addr.ToString().c_str()); if (!pwallet->AddKey(key)) { fGood = false; continue; } - pwallet->mapKeyMetadata[keyid].nCreateTime = nTime; - if (fLabel) - pwallet->SetAddressBookName(keyid, strLabel); } else { // A pair of private keys @@ -929,18 +932,24 @@ bool ImportWallet(CWallet *pwallet, const string& strLocation) 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", CBitcoinAddress(mPubKey).ToString().c_str()); + printf("Skipping import of %s (key already present)\n", addr.ToString().c_str()); continue; } - printf("Importing %s...\n", CBitcoinAddress(mPubKey).ToString().c_str()); + printf("Importing %s...\n", addr.ToString().c_str()); if (!pwallet->AddMalleableKey(mKey)) { fGood = false; continue; } - pwallet->mapMalleableKeyMetadata[CMalleableKeyView(mKey)].nCreateTime = nTime; } + + pwallet->mapKeyMetadata[addr].nCreateTime = nTime; + if (fLabel) + pwallet->SetAddressBookName(addr, strLabel); + nTimeBegin = std::min(nTimeBegin, nTime); } file.close(); -- 1.7.1