Merge pull request #4937
ccca27a
[Wallet] Watch-only fixes (Cozz Lovan)
This commit is contained in:
commit
d7e1950483
10 changed files with 70 additions and 13 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
34
src/wallet.h
34
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
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue