aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2014-10-13 13:56:54 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2014-10-13 13:57:07 +0200
commitd7e195048342afae9168377cebfc22ab000728a5 (patch)
treeee5b07604ef073ef35d8aa13598fb7d6a4877bc4
parentf98bd4eae1bc6d57c27cc13d0495941f15eddf19 (diff)
parentccca27a788fe1ae13661308243c20a1d7a3d0074 (diff)
Merge pull request #4937
ccca27a [Wallet] Watch-only fixes (Cozz Lovan)
-rw-r--r--src/keystore.cpp7
-rw-r--r--src/keystore.h2
-rw-r--r--src/qt/transactionrecord.cpp2
-rw-r--r--src/qt/walletmodel.cpp3
-rw-r--r--src/rpcdump.cpp5
-rw-r--r--src/rpcwallet.cpp2
-rw-r--r--src/wallet.cpp21
-rw-r--r--src/wallet.h34
-rw-r--r--src/walletdb.cpp6
-rw-r--r--src/walletdb.h1
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);