[Wallet] Watch-only fixes
This commit is contained in:
parent
29f96e8bc6
commit
ccca27a788
10 changed files with 70 additions and 13 deletions
|
@ -67,6 +67,13 @@ bool CBasicKeyStore::AddWatchOnly(const CScript &dest)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest)
|
||||||
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
|
setWatchOnly.erase(dest);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const
|
bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const
|
||||||
{
|
{
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
|
|
||||||
// Support for Watch-only addresses
|
// Support for Watch-only addresses
|
||||||
virtual bool AddWatchOnly(const CScript &dest) =0;
|
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 CScript &dest) const =0;
|
||||||
virtual bool HaveWatchOnly() const =0;
|
virtual bool HaveWatchOnly() const =0;
|
||||||
};
|
};
|
||||||
|
@ -98,6 +99,7 @@ public:
|
||||||
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const;
|
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const;
|
||||||
|
|
||||||
virtual bool AddWatchOnly(const CScript &dest);
|
virtual bool AddWatchOnly(const CScript &dest);
|
||||||
|
virtual bool RemoveWatchOnly(const CScript &dest);
|
||||||
virtual bool HaveWatchOnly(const CScript &dest) const;
|
virtual bool HaveWatchOnly(const CScript &dest) const;
|
||||||
virtual bool HaveWatchOnly() const;
|
virtual bool HaveWatchOnly() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
|
||||||
{
|
{
|
||||||
QList<TransactionRecord> parts;
|
QList<TransactionRecord> parts;
|
||||||
int64_t nTime = wtx.GetTxTime();
|
int64_t nTime = wtx.GetTxTime();
|
||||||
CAmount nCredit = wtx.GetCredit(true);
|
CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
|
||||||
CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
|
CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
|
||||||
CAmount nNet = nCredit - nDebit;
|
CAmount nNet = nCredit - nDebit;
|
||||||
uint256 hash = wtx.GetHash();
|
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();
|
int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
|
||||||
if (nDepth < 0) continue;
|
if (nDepth < 0) continue;
|
||||||
COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true);
|
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)
|
BOOST_FOREACH(const COutput& out, vCoins)
|
||||||
|
|
|
@ -114,8 +114,6 @@ Value importprivkey(const Array& params, bool fHelp)
|
||||||
CPubKey pubkey = key.GetPubKey();
|
CPubKey pubkey = key.GetPubKey();
|
||||||
CKeyID vchAddress = pubkey.GetID();
|
CKeyID vchAddress = pubkey.GetID();
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
|
||||||
|
|
||||||
pwalletMain->MarkDirty();
|
pwalletMain->MarkDirty();
|
||||||
pwalletMain->SetAddressBook(vchAddress, strLabel, "receive");
|
pwalletMain->SetAddressBook(vchAddress, strLabel, "receive");
|
||||||
|
|
||||||
|
@ -181,7 +179,8 @@ Value importaddress(const Array& params, bool fHelp)
|
||||||
fRescan = params[2].get_bool();
|
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
|
// add to address book or update label
|
||||||
if (address.IsValid())
|
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");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
|
||||||
const CWalletTx& wtx = pwalletMain->mapWallet[hash];
|
const CWalletTx& wtx = pwalletMain->mapWallet[hash];
|
||||||
|
|
||||||
CAmount nCredit = wtx.GetCredit(filter != 0);
|
CAmount nCredit = wtx.GetCredit(filter);
|
||||||
CAmount nDebit = wtx.GetDebit(filter);
|
CAmount nDebit = wtx.GetDebit(filter);
|
||||||
CAmount nNet = nCredit - nDebit;
|
CAmount nNet = nCredit - nDebit;
|
||||||
CAmount nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0);
|
CAmount nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0);
|
||||||
|
|
|
@ -87,6 +87,13 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
|
||||||
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
||||||
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
|
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// check if we need to remove from watch-only
|
||||||
|
CScript script;
|
||||||
|
script = GetScriptForDestination(pubkey.GetID());
|
||||||
|
if (HaveWatchOnly(script))
|
||||||
|
RemoveWatchOnly(script);
|
||||||
|
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
return true;
|
return true;
|
||||||
if (!IsCrypted()) {
|
if (!IsCrypted()) {
|
||||||
|
@ -169,6 +176,20 @@ bool CWallet::AddWatchOnly(const CScript &dest)
|
||||||
return CWalletDB(strWalletFile).WriteWatchOnly(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)
|
bool CWallet::LoadWatchOnly(const CScript &dest)
|
||||||
{
|
{
|
||||||
return CCryptoKeyStore::AddWatchOnly(dest);
|
return CCryptoKeyStore::AddWatchOnly(dest);
|
||||||
|
|
34
src/wallet.h
34
src/wallet.h
|
@ -222,6 +222,7 @@ public:
|
||||||
|
|
||||||
// Adds a watch-only address to the store, and saves it to disk.
|
// Adds a watch-only address to the store, and saves it to disk.
|
||||||
bool AddWatchOnly(const CScript &dest);
|
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)
|
// Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
|
||||||
bool LoadWatchOnly(const CScript &dest);
|
bool LoadWatchOnly(const CScript &dest);
|
||||||
|
|
||||||
|
@ -701,18 +702,37 @@ public:
|
||||||
return debit;
|
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
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// GetBalance can assume transactions in mapWallet won't change
|
int64_t credit = 0;
|
||||||
if (fUseCache && fCreditCached)
|
if (filter & ISMINE_SPENDABLE)
|
||||||
return nCreditCached;
|
{
|
||||||
nCreditCached = pwallet->GetCredit(*this, ISMINE_ALL);
|
// GetBalance can assume transactions in mapWallet won't change
|
||||||
fCreditCached = true;
|
if (fCreditCached)
|
||||||
return nCreditCached;
|
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
|
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');
|
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)
|
bool CWalletDB::WriteBestBlock(const CBlockLocator& locator)
|
||||||
{
|
{
|
||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
|
|
|
@ -96,6 +96,7 @@ public:
|
||||||
bool WriteCScript(const uint160& hash, const CScript& redeemScript);
|
bool WriteCScript(const uint160& hash, const CScript& redeemScript);
|
||||||
|
|
||||||
bool WriteWatchOnly(const CScript &script);
|
bool WriteWatchOnly(const CScript &script);
|
||||||
|
bool EraseWatchOnly(const CScript &script);
|
||||||
|
|
||||||
bool WriteBestBlock(const CBlockLocator& locator);
|
bool WriteBestBlock(const CBlockLocator& locator);
|
||||||
bool ReadBestBlock(CBlockLocator& locator);
|
bool ReadBestBlock(CBlockLocator& locator);
|
||||||
|
|
Loading…
Reference in a new issue