Browse Source

Add logic to track pubkeys as watch-only, not just scripts

0.13
Matt Corallo 10 years ago
parent
commit
f5813bdd3e
  1. 41
      src/keystore.cpp
  2. 5
      src/keystore.h
  3. 3
      src/qt/sendcoinsdialog.cpp
  4. 5
      src/qt/walletmodel.cpp
  5. 1
      src/qt/walletmodel.h
  6. 4
      src/wallet/crypter.cpp

41
src/keystore.cpp

@ -6,23 +6,30 @@
#include "keystore.h" #include "keystore.h"
#include "key.h" #include "key.h"
#include "pubkey.h"
#include "util.h" #include "util.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const bool CKeyStore::AddKey(const CKey &key) {
return AddKeyPubKey(key, key.GetPubKey());
}
bool CBasicKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
{ {
CKey key; CKey key;
if (!GetKey(address, key)) if (!GetKey(address, key)) {
WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
if (it != mapWatchKeys.end()) {
vchPubKeyOut = it->second;
return true;
}
return false; return false;
}
vchPubKeyOut = key.GetPubKey(); vchPubKeyOut = key.GetPubKey();
return true; return true;
} }
bool CKeyStore::AddKey(const CKey &key) {
return AddKeyPubKey(key, key.GetPubKey());
}
bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey) bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
{ {
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
@ -58,10 +65,29 @@ bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut)
return false; return false;
} }
static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
{
//TODO: Use Solver to extract this?
CScript::const_iterator pc = dest.begin();
opcodetype opcode;
std::vector<unsigned char> vch;
if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65)
return false;
pubKeyOut = CPubKey(vch);
if (!pubKeyOut.IsFullyValid())
return false;
if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG || dest.GetOp(pc, opcode, vch))
return false;
return true;
}
bool CBasicKeyStore::AddWatchOnly(const CScript &dest) bool CBasicKeyStore::AddWatchOnly(const CScript &dest)
{ {
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
setWatchOnly.insert(dest); setWatchOnly.insert(dest);
CPubKey pubKey;
if (ExtractPubKey(dest, pubKey))
mapWatchKeys[pubKey.GetID()] = pubKey;
return true; return true;
} }
@ -69,6 +95,9 @@ bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest)
{ {
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
setWatchOnly.erase(dest); setWatchOnly.erase(dest);
CPubKey pubKey;
if (ExtractPubKey(dest, pubKey))
mapWatchKeys.erase(pubKey.GetID());
return true; return true;
} }

5
src/keystore.h

@ -32,7 +32,7 @@ public:
virtual bool HaveKey(const CKeyID &address) const =0; virtual bool HaveKey(const CKeyID &address) const =0;
virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0; virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;
virtual void GetKeys(std::set<CKeyID> &setAddress) const =0; virtual void GetKeys(std::set<CKeyID> &setAddress) const =0;
virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const =0;
//! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki //! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki
virtual bool AddCScript(const CScript& redeemScript) =0; virtual bool AddCScript(const CScript& redeemScript) =0;
@ -47,6 +47,7 @@ public:
}; };
typedef std::map<CKeyID, CKey> KeyMap; typedef std::map<CKeyID, CKey> KeyMap;
typedef std::map<CKeyID, CPubKey> WatchKeyMap;
typedef std::map<CScriptID, CScript > ScriptMap; typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet; typedef std::set<CScript> WatchOnlySet;
@ -55,11 +56,13 @@ class CBasicKeyStore : public CKeyStore
{ {
protected: protected:
KeyMap mapKeys; KeyMap mapKeys;
WatchKeyMap mapWatchKeys;
ScriptMap mapScripts; ScriptMap mapScripts;
WatchOnlySet setWatchOnly; WatchOnlySet setWatchOnly;
public: public:
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
bool HaveKey(const CKeyID &address) const bool HaveKey(const CKeyID &address) const
{ {
bool result; bool result;

3
src/qt/sendcoinsdialog.cpp

@ -752,10 +752,9 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
} }
else // Valid address else // Valid address
{ {
CPubKey pubkey;
CKeyID keyid; CKeyID keyid;
addr.GetKeyID(keyid); addr.GetKeyID(keyid);
if (!model->getPubKey(keyid, pubkey)) // Unknown change address if (!model->havePrivKey(keyid)) // Unknown change address
{ {
ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address")); ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address"));
} }

5
src/qt/walletmodel.cpp

@ -554,6 +554,11 @@ bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
return wallet->GetPubKey(address, vchPubKeyOut); return wallet->GetPubKey(address, vchPubKeyOut);
} }
bool WalletModel::havePrivKey(const CKeyID &address) const
{
return wallet->HaveKey(address);
}
// returns a list of COutputs from COutPoints // returns a list of COutputs from COutPoints
void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs) void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs)
{ {

1
src/qt/walletmodel.h

@ -186,6 +186,7 @@ public:
UnlockContext requestUnlock(); UnlockContext requestUnlock();
bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
bool havePrivKey(const CKeyID &address) const;
void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs); void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
bool isSpent(const COutPoint& outpoint) const; bool isSpent(const COutPoint& outpoint) const;
void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const; void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;

4
src/wallet/crypter.cpp

@ -255,7 +255,7 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co
{ {
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
if (!IsCrypted()) if (!IsCrypted())
return CKeyStore::GetPubKey(address, vchPubKeyOut); return CBasicKeyStore::GetPubKey(address, vchPubKeyOut);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end()) if (mi != mapCryptedKeys.end())
@ -263,6 +263,8 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co
vchPubKeyOut = (*mi).second.first; vchPubKeyOut = (*mi).second.first;
return true; return true;
} }
// Check for watch-only pubkeys
return CBasicKeyStore::GetPubKey(address, vchPubKeyOut);
} }
return false; return false;
} }

Loading…
Cancel
Save