diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2014-10-13 13:56:54 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2014-10-13 13:57:07 +0200 |
commit | d7e195048342afae9168377cebfc22ab000728a5 (patch) | |
tree | ee5b07604ef073ef35d8aa13598fb7d6a4877bc4 | |
parent | f98bd4eae1bc6d57c27cc13d0495941f15eddf19 (diff) | |
parent | ccca27a788fe1ae13661308243c20a1d7a3d0074 (diff) |
Merge pull request #4937
ccca27a [Wallet] Watch-only fixes (Cozz Lovan)
-rw-r--r-- | src/keystore.cpp | 7 | ||||
-rw-r--r-- | src/keystore.h | 2 | ||||
-rw-r--r-- | src/qt/transactionrecord.cpp | 2 | ||||
-rw-r--r-- | src/qt/walletmodel.cpp | 3 | ||||
-rw-r--r-- | src/rpcdump.cpp | 5 | ||||
-rw-r--r-- | src/rpcwallet.cpp | 2 | ||||
-rw-r--r-- | src/wallet.cpp | 21 | ||||
-rw-r--r-- | src/wallet.h | 34 | ||||
-rw-r--r-- | src/walletdb.cpp | 6 | ||||
-rw-r--r-- | src/walletdb.h | 1 |
10 files changed, 70 insertions, 13 deletions
diff --git a/src/keystore.cpp b/src/keystore.cpp index 98bc0e9e28..755defa26d 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -67,6 +67,13 @@ bool CBasicKeyStore::AddWatchOnly(const CScript &dest) return true; } +bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest) +{ + LOCK(cs_KeyStore); + setWatchOnly.erase(dest); + return true; +} + bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const { LOCK(cs_KeyStore); diff --git a/src/keystore.h b/src/keystore.h index 3b49e282d9..d3478f7672 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -40,6 +40,7 @@ public: // Support for Watch-only addresses virtual bool AddWatchOnly(const CScript &dest) =0; + virtual bool RemoveWatchOnly(const CScript &dest) =0; virtual bool HaveWatchOnly(const CScript &dest) const =0; virtual bool HaveWatchOnly() const =0; }; @@ -98,6 +99,7 @@ public: virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const; virtual bool AddWatchOnly(const CScript &dest); + virtual bool RemoveWatchOnly(const CScript &dest); virtual bool HaveWatchOnly(const CScript &dest) const; virtual bool HaveWatchOnly() const; }; diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index afb343f349..5278c8673a 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -32,7 +32,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * { QList<TransactionRecord> parts; int64_t nTime = wtx.GetTxTime(); - CAmount nCredit = wtx.GetCredit(true); + CAmount nCredit = wtx.GetCredit(ISMINE_ALL); CAmount nDebit = wtx.GetDebit(ISMINE_ALL); CAmount nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index b8701a23a6..b4733d369e 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -605,7 +605,8 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); if (nDepth < 0) continue; COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true); - vCoins.push_back(out); + if (outpoint.n < out.tx->vout.size() && wallet->IsMine(out.tx->vout[outpoint.n]) == ISMINE_SPENDABLE) + vCoins.push_back(out); } BOOST_FOREACH(const COutput& out, vCoins) diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 1ac7024550..9da0a7d091 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -114,8 +114,6 @@ Value importprivkey(const Array& params, bool fHelp) CPubKey pubkey = key.GetPubKey(); CKeyID vchAddress = pubkey.GetID(); { - LOCK2(cs_main, pwalletMain->cs_wallet); - pwalletMain->MarkDirty(); pwalletMain->SetAddressBook(vchAddress, strLabel, "receive"); @@ -181,7 +179,8 @@ Value importaddress(const Array& params, bool fHelp) fRescan = params[2].get_bool(); { - LOCK2(cs_main, pwalletMain->cs_wallet); + if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) + throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); // add to address book or update label if (address.IsValid()) diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index d7c0c0ef5c..d11455e389 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1539,7 +1539,7 @@ Value gettransaction(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); const CWalletTx& wtx = pwalletMain->mapWallet[hash]; - CAmount nCredit = wtx.GetCredit(filter != 0); + CAmount nCredit = wtx.GetCredit(filter); CAmount nDebit = wtx.GetDebit(filter); CAmount nNet = nCredit - nDebit; CAmount nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0); diff --git a/src/wallet.cpp b/src/wallet.cpp index 026c53aa2e..19e43f6ec2 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -89,6 +89,13 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) AssertLockHeld(cs_wallet); // mapKeyMetadata if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) return false; + + // check if we need to remove from watch-only + CScript script; + script = GetScriptForDestination(pubkey.GetID()); + if (HaveWatchOnly(script)) + RemoveWatchOnly(script); + if (!fFileBacked) return true; if (!IsCrypted()) { @@ -171,6 +178,20 @@ bool CWallet::AddWatchOnly(const CScript &dest) return CWalletDB(strWalletFile).WriteWatchOnly(dest); } +bool CWallet::RemoveWatchOnly(const CScript &dest) +{ + AssertLockHeld(cs_wallet); + if (!CCryptoKeyStore::RemoveWatchOnly(dest)) + return false; + if (!HaveWatchOnly()) + NotifyWatchonlyChanged(false); + if (fFileBacked) + if (!CWalletDB(strWalletFile).EraseWatchOnly(dest)) + return false; + + return true; +} + bool CWallet::LoadWatchOnly(const CScript &dest) { return CCryptoKeyStore::AddWatchOnly(dest); diff --git a/src/wallet.h b/src/wallet.h index 58e285b7eb..fa8a94dfc1 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -230,6 +230,7 @@ public: // Adds a watch-only address to the store, and saves it to disk. bool AddWatchOnly(const CScript &dest); + bool RemoveWatchOnly(const CScript &dest); // Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) bool LoadWatchOnly(const CScript &dest); @@ -709,18 +710,37 @@ public: return debit; } - CAmount GetCredit(bool fUseCache=true) const + CAmount GetCredit(const isminefilter& filter) const { // Must wait until coinbase is safely deep enough in the chain before valuing it if (IsCoinBase() && GetBlocksToMaturity() > 0) return 0; - // GetBalance can assume transactions in mapWallet won't change - if (fUseCache && fCreditCached) - return nCreditCached; - nCreditCached = pwallet->GetCredit(*this, ISMINE_ALL); - fCreditCached = true; - return nCreditCached; + int64_t credit = 0; + if (filter & ISMINE_SPENDABLE) + { + // GetBalance can assume transactions in mapWallet won't change + if (fCreditCached) + credit += nCreditCached; + else + { + nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE); + fCreditCached = true; + credit += nCreditCached; + } + } + if (filter & ISMINE_WATCH_ONLY) + { + if (fWatchCreditCached) + credit += nWatchCreditCached; + else + { + nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY); + fWatchCreditCached = true; + credit += nWatchCreditCached; + } + } + return credit; } CAmount GetImmatureCredit(bool fUseCache=true) const diff --git a/src/walletdb.cpp b/src/walletdb.cpp index e09bb8d1b2..783f766f6f 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -121,6 +121,12 @@ bool CWalletDB::WriteWatchOnly(const CScript &dest) return Write(std::make_pair(std::string("watchs"), dest), '1'); } +bool CWalletDB::EraseWatchOnly(const CScript &dest) +{ + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("watchs"), dest)); +} + bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) { nWalletDBUpdated++; diff --git a/src/walletdb.h b/src/walletdb.h index f3d6e61f8b..7ff41c7c8d 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -96,6 +96,7 @@ public: bool WriteCScript(const uint160& hash, const CScript& redeemScript); bool WriteWatchOnly(const CScript &script); + bool EraseWatchOnly(const CScript &script); bool WriteBestBlock(const CBlockLocator& locator); bool ReadBestBlock(CBlockLocator& locator); |