Skip to content

Commit 93ce4a0

Browse files
committed
Move WatchOnly stuff from SigningProvider to CWallet
1 parent 8f5b81e commit 93ce4a0

File tree

4 files changed

+84
-79
lines changed

4 files changed

+84
-79
lines changed

src/script/signingprovider.cpp

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ void FillableSigningProvider::ImplicitlyLearnRelatedKeyScripts(const CPubKey& pu
7373
{
7474
AssertLockHeld(cs_KeyStore);
7575
CKeyID key_id = pubkey.GetID();
76-
// We must actually know about this key already.
77-
assert(HaveKey(key_id) || mapWatchKeys.count(key_id));
7876
// This adds the redeemscripts necessary to detect P2WPKH and P2SH-P2WPKH
7977
// outputs. Technically P2WPKH outputs don't have a redeemscript to be
8078
// spent. However, our current IsMine logic requires the corresponding
@@ -98,12 +96,6 @@ bool FillableSigningProvider::GetPubKey(const CKeyID &address, CPubKey &vchPubKe
9896
{
9997
CKey key;
10098
if (!GetKey(address, key)) {
101-
LOCK(cs_KeyStore);
102-
WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
103-
if (it != mapWatchKeys.end()) {
104-
vchPubKeyOut = it->second;
105-
return true;
106-
}
10799
return false;
108100
}
109101
vchPubKeyOut = key.GetPubKey();
@@ -183,59 +175,6 @@ bool FillableSigningProvider::GetCScript(const CScriptID &hash, CScript& redeemS
183175
return false;
184176
}
185177

186-
static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
187-
{
188-
//TODO: Use Solver to extract this?
189-
CScript::const_iterator pc = dest.begin();
190-
opcodetype opcode;
191-
std::vector<unsigned char> vch;
192-
if (!dest.GetOp(pc, opcode, vch) || !CPubKey::ValidSize(vch))
193-
return false;
194-
pubKeyOut = CPubKey(vch);
195-
if (!pubKeyOut.IsFullyValid())
196-
return false;
197-
if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG || dest.GetOp(pc, opcode, vch))
198-
return false;
199-
return true;
200-
}
201-
202-
bool FillableSigningProvider::AddWatchOnly(const CScript &dest)
203-
{
204-
LOCK(cs_KeyStore);
205-
setWatchOnly.insert(dest);
206-
CPubKey pubKey;
207-
if (ExtractPubKey(dest, pubKey)) {
208-
mapWatchKeys[pubKey.GetID()] = pubKey;
209-
ImplicitlyLearnRelatedKeyScripts(pubKey);
210-
}
211-
return true;
212-
}
213-
214-
bool FillableSigningProvider::RemoveWatchOnly(const CScript &dest)
215-
{
216-
LOCK(cs_KeyStore);
217-
setWatchOnly.erase(dest);
218-
CPubKey pubKey;
219-
if (ExtractPubKey(dest, pubKey)) {
220-
mapWatchKeys.erase(pubKey.GetID());
221-
}
222-
// Related CScripts are not removed; having superfluous scripts around is
223-
// harmless (see comment in ImplicitlyLearnRelatedKeyScripts).
224-
return true;
225-
}
226-
227-
bool FillableSigningProvider::HaveWatchOnly(const CScript &dest) const
228-
{
229-
LOCK(cs_KeyStore);
230-
return setWatchOnly.count(dest) > 0;
231-
}
232-
233-
bool FillableSigningProvider::HaveWatchOnly() const
234-
{
235-
LOCK(cs_KeyStore);
236-
return (!setWatchOnly.empty());
237-
}
238-
239178
CKeyID GetKeyForDestination(const SigningProvider& store, const CTxDestination& dest)
240179
{
241180
// Only supports destinations which map to single public keys, i.e. P2PKH,

src/script/signingprovider.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,10 @@ class FillableSigningProvider : public SigningProvider
6666
mutable CCriticalSection cs_KeyStore;
6767

6868
using KeyMap = std::map<CKeyID, CKey>;
69-
using WatchKeyMap = std::map<CKeyID, CPubKey>;
7069
using ScriptMap = std::map<CScriptID, CScript>;
71-
using WatchOnlySet = std::set<CScript>;
7270

7371
KeyMap mapKeys GUARDED_BY(cs_KeyStore);
74-
WatchKeyMap mapWatchKeys GUARDED_BY(cs_KeyStore);
7572
ScriptMap mapScripts GUARDED_BY(cs_KeyStore);
76-
WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore);
7773

7874
void ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
7975

@@ -88,11 +84,6 @@ class FillableSigningProvider : public SigningProvider
8884
virtual bool HaveCScript(const CScriptID &hash) const override;
8985
virtual std::set<CScriptID> GetCScripts() const;
9086
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const override;
91-
92-
virtual bool AddWatchOnly(const CScript &dest);
93-
virtual bool RemoveWatchOnly(const CScript &dest);
94-
virtual bool HaveWatchOnly(const CScript &dest) const;
95-
virtual bool HaveWatchOnly() const;
9687
};
9788

9889
/** Return the CKeyID of the key involved in a script (if there is a unique one). */

src/wallet/wallet.cpp

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -455,9 +455,37 @@ bool CWallet::LoadCScript(const CScript& redeemScript)
455455
return FillableSigningProvider::AddCScript(redeemScript);
456456
}
457457

458+
static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
459+
{
460+
//TODO: Use Solver to extract this?
461+
CScript::const_iterator pc = dest.begin();
462+
opcodetype opcode;
463+
std::vector<unsigned char> vch;
464+
if (!dest.GetOp(pc, opcode, vch) || !CPubKey::ValidSize(vch))
465+
return false;
466+
pubKeyOut = CPubKey(vch);
467+
if (!pubKeyOut.IsFullyValid())
468+
return false;
469+
if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG || dest.GetOp(pc, opcode, vch))
470+
return false;
471+
return true;
472+
}
473+
474+
bool CWallet::AddWatchOnlyInMem(const CScript &dest)
475+
{
476+
LOCK(cs_KeyStore);
477+
setWatchOnly.insert(dest);
478+
CPubKey pubKey;
479+
if (ExtractPubKey(dest, pubKey)) {
480+
mapWatchKeys[pubKey.GetID()] = pubKey;
481+
ImplicitlyLearnRelatedKeyScripts(pubKey);
482+
}
483+
return true;
484+
}
485+
458486
bool CWallet::AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest)
459487
{
460-
if (!FillableSigningProvider::AddWatchOnly(dest))
488+
if (!AddWatchOnlyInMem(dest))
461489
return false;
462490
const CKeyMetadata& meta = m_script_metadata[CScriptID(dest)];
463491
UpdateTimeFirstKey(meta.nCreateTime);
@@ -490,8 +518,17 @@ bool CWallet::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
490518
bool CWallet::RemoveWatchOnly(const CScript &dest)
491519
{
492520
AssertLockHeld(cs_wallet);
493-
if (!FillableSigningProvider::RemoveWatchOnly(dest))
494-
return false;
521+
{
522+
LOCK(cs_KeyStore);
523+
setWatchOnly.erase(dest);
524+
CPubKey pubKey;
525+
if (ExtractPubKey(dest, pubKey)) {
526+
mapWatchKeys.erase(pubKey.GetID());
527+
}
528+
// Related CScripts are not removed; having superfluous scripts around is
529+
// harmless (see comment in ImplicitlyLearnRelatedKeyScripts).
530+
}
531+
495532
if (!HaveWatchOnly())
496533
NotifyWatchonlyChanged(false);
497534
if (!WalletBatch(*database).EraseWatchOnly(dest))
@@ -502,7 +539,19 @@ bool CWallet::RemoveWatchOnly(const CScript &dest)
502539

503540
bool CWallet::LoadWatchOnly(const CScript &dest)
504541
{
505-
return FillableSigningProvider::AddWatchOnly(dest);
542+
return AddWatchOnlyInMem(dest);
543+
}
544+
545+
bool CWallet::HaveWatchOnly(const CScript &dest) const
546+
{
547+
LOCK(cs_KeyStore);
548+
return setWatchOnly.count(dest) > 0;
549+
}
550+
551+
bool CWallet::HaveWatchOnly() const
552+
{
553+
LOCK(cs_KeyStore);
554+
return (!setWatchOnly.empty());
506555
}
507556

508557
bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys)
@@ -4687,11 +4736,26 @@ bool CWallet::GetKey(const CKeyID &address, CKey& keyOut) const
46874736
return false;
46884737
}
46894738

4739+
bool CWallet::GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
4740+
{
4741+
LOCK(cs_KeyStore);
4742+
WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
4743+
if (it != mapWatchKeys.end()) {
4744+
pubkey_out = it->second;
4745+
return true;
4746+
}
4747+
return false;
4748+
}
4749+
46904750
bool CWallet::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
46914751
{
46924752
LOCK(cs_KeyStore);
4693-
if (!IsCrypted())
4694-
return FillableSigningProvider::GetPubKey(address, vchPubKeyOut);
4753+
if (!IsCrypted()) {
4754+
if (!FillableSigningProvider::GetPubKey(address, vchPubKeyOut)) {
4755+
return GetWatchPubKey(address, vchPubKeyOut);
4756+
}
4757+
return true;
4758+
}
46954759

46964760
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
46974761
if (mi != mapCryptedKeys.end())
@@ -4700,7 +4764,7 @@ bool CWallet::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
47004764
return true;
47014765
}
47024766
// Check for watch-only pubkeys
4703-
return FillableSigningProvider::GetPubKey(address, vchPubKeyOut);
4767+
return GetWatchPubKey(address, vchPubKeyOut);
47044768
}
47054769

47064770
std::set<CKeyID> CWallet::GetKeys() const

src/wallet/wallet.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,8 @@ class CWallet final : public FillableSigningProvider, private interfaces::Chain:
724724
bool fDecryptionThoroughlyChecked;
725725

726726
using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
727+
using WatchOnlySet = std::set<CScript>;
728+
using WatchKeyMap = std::map<CKeyID, CPubKey>;
727729

728730
bool SetCrypted();
729731

@@ -732,6 +734,8 @@ class CWallet final : public FillableSigningProvider, private interfaces::Chain:
732734

733735
bool Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys = false);
734736
CryptedKeyMap mapCryptedKeys GUARDED_BY(cs_KeyStore);
737+
WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore);
738+
WatchKeyMap mapWatchKeys GUARDED_BY(cs_KeyStore);
735739

736740
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
737741
bool AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey);
@@ -818,8 +822,9 @@ class CWallet final : public FillableSigningProvider, private interfaces::Chain:
818822
* of the other AddWatchOnly which accepts a timestamp and sets
819823
* nTimeFirstKey more intelligently for more efficient rescans.
820824
*/
821-
bool AddWatchOnly(const CScript& dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
825+
bool AddWatchOnly(const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
822826
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
827+
bool AddWatchOnlyInMem(const CScript &dest);
823828

824829
/** Add a KeyOriginInfo to the wallet */
825830
bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
@@ -1039,9 +1044,15 @@ class CWallet final : public FillableSigningProvider, private interfaces::Chain:
10391044

10401045
//! Adds a watch-only address to the store, and saves it to disk.
10411046
bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
1042-
bool RemoveWatchOnly(const CScript &dest) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
1047+
bool RemoveWatchOnly(const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
10431048
//! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
10441049
bool LoadWatchOnly(const CScript &dest);
1050+
//! Returns whether the watch-only script is in the wallet
1051+
bool HaveWatchOnly(const CScript &dest) const;
1052+
//! Returns whether there are any watch-only things in the wallet
1053+
bool HaveWatchOnly() const;
1054+
//! Fetches a pubkey from mapWatchKeys if it exists there
1055+
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const;
10451056

10461057
//! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().
10471058
int64_t nRelockTime = 0;

0 commit comments

Comments
 (0)