PIVX Core  5.6.99
P2P Digital Currency
keystore.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2017-2021 The PIVX Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "keystore.h"
8 
9 #include "script/script.h"
10 #include "script/standard.h"
11 #include "util/system.h"
12 
13 
14 bool CKeyStore::AddKey(const CKey& key)
15 {
16  return AddKeyPubKey(key, key.GetPubKey());
17 }
18 
19 bool CBasicKeyStore::GetPubKey(const CKeyID& address, CPubKey& vchPubKeyOut) const
20 {
21  CKey key;
22  if (!GetKey(address, key)) {
23  WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
24  if (it != mapWatchKeys.end()) {
25  vchPubKeyOut = it->second;
26  return true;
27  }
28  return false;
29  }
30  vchPubKeyOut = key.GetPubKey();
31  return true;
32 }
33 
34 bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey& pubkey)
35 {
37  mapKeys[pubkey.GetID()] = key;
38  return true;
39 }
40 
41 bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
42 {
43  if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
44  return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
45 
47  mapScripts[CScriptID(redeemScript)] = redeemScript;
48  return true;
49 }
50 
51 bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const
52 {
54  return mapScripts.count(hash) > 0;
55 }
56 
57 bool CBasicKeyStore::GetCScript(const CScriptID& hash, CScript& redeemScriptOut) const
58 {
60  ScriptMap::const_iterator mi = mapScripts.find(hash);
61  if (mi != mapScripts.end()) {
62  redeemScriptOut = (*mi).second;
63  return true;
64  }
65  return false;
66 }
67 
68 static bool ExtractPubKey(const CScript& dest, CPubKey& pubKeyOut)
69 {
70  //TODO: Use Solver to extract this?
71  CScript::const_iterator pc = dest.begin();
72  opcodetype opcode;
73  std::vector<unsigned char> vch;
74  if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65)
75  return false;
76  pubKeyOut = CPubKey(vch);
77  if (!pubKeyOut.IsFullyValid())
78  return false;
79  if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG || dest.GetOp(pc, opcode, vch))
80  return false;
81  return true;
82 }
83 
85 {
87  setWatchOnly.insert(dest);
88  CPubKey pubKey;
89  if (ExtractPubKey(dest, pubKey))
90  mapWatchKeys[pubKey.GetID()] = pubKey;
91  return true;
92 }
93 
95 {
97  setWatchOnly.erase(dest);
98  CPubKey pubKey;
99  if (ExtractPubKey(dest, pubKey))
100  mapWatchKeys.erase(pubKey.GetID());
101  return true;
102 }
103 
104 bool CBasicKeyStore::HaveWatchOnly(const CScript& dest) const
105 {
106  LOCK(cs_KeyStore);
107  return setWatchOnly.count(dest) > 0;
108 }
109 
111 {
112  LOCK(cs_KeyStore);
113  return (!setWatchOnly.empty());
114 }
115 
116 bool CBasicKeyStore::HaveKey(const CKeyID& address) const
117 {
118  bool result;
119  {
120  LOCK(cs_KeyStore);
121  result = (mapKeys.count(address) > 0);
122  }
123  return result;
124 }
125 
126 std::set<CKeyID> CBasicKeyStore::GetKeys() const
127 {
128  LOCK(cs_KeyStore);
129  std::set<CKeyID> set_address;
130  for (const auto& mi : mapKeys) {
131  set_address.insert(mi.first);
132  }
133  return set_address;
134 }
135 
136 bool CBasicKeyStore::GetKey(const CKeyID& address, CKey& keyOut) const
137 {
138  LOCK(cs_KeyStore);
139  KeyMap::const_iterator mi = mapKeys.find(address);
140  if (mi != mapKeys.end()) {
141  keyOut = mi->second;
142  return true;
143  }
144  return false;
145 }
146 
150 {
151  LOCK(cs_KeyStore);
152  auto extfvk = sk.ToXFVK();
153 
154  // if extfvk is not in SaplingFullViewingKeyMap, add it
155  if (!AddSaplingFullViewingKey(extfvk)) {
156  return false;
157  }
158 
159  mapSaplingSpendingKeys[extfvk] = sk;
160 
161  return true;
162 }
163 
166 {
167  LOCK(cs_KeyStore);
168  auto ivk = extfvk.fvk.in_viewing_key();
169  mapSaplingFullViewingKeys[ivk] = extfvk;
170 
172 }
173 
174 // This function updates the wallet's internal address->ivk map.
175 // If we add an address that is already in the map, the map will
176 // remain unchanged as each address only has one ivk.
180 {
181  LOCK(cs_KeyStore);
182 
183  // Add addr -> SaplingIncomingViewing to SaplingIncomingViewingKeyMap
184  mapSaplingIncomingViewingKeys[addr] = ivk;
185 
186  return true;
187 }
188 
190 {
191  return WITH_LOCK(cs_KeyStore, return mapSaplingSpendingKeys.count(extfvk) > 0);
192 }
193 
195 {
196  return WITH_LOCK(cs_KeyStore, return mapSaplingFullViewingKeys.count(ivk) > 0);
197 }
198 
200 {
201  return WITH_LOCK(cs_KeyStore, return mapSaplingIncomingViewingKeys.count(addr) > 0);
202 }
203 
205 {
206  LOCK(cs_KeyStore);
207  SaplingSpendingKeyMap::const_iterator mi = mapSaplingSpendingKeys.find(extfvk);
208  if (mi != mapSaplingSpendingKeys.end()) {
209  skOut = mi->second;
210  return true;
211  }
212  return false;
213 }
214 
218 {
219  LOCK(cs_KeyStore);
220  SaplingFullViewingKeyMap::const_iterator mi = mapSaplingFullViewingKeys.find(ivk);
221  if (mi != mapSaplingFullViewingKeys.end()) {
222  extfvkOut = mi->second;
223  return true;
224  }
225  return false;
226 }
227 
230 {
231  LOCK(cs_KeyStore);
232  SaplingIncomingViewingKeyMap::const_iterator mi = mapSaplingIncomingViewingKeys.find(addr);
233  if (mi != mapSaplingIncomingViewingKeys.end()) {
234  ivkOut = mi->second;
235  return true;
236  }
237  return false;
238 }
239 
241  libzcash::SaplingExtendedSpendingKey& extskOut) const
242 {
245 
246  LOCK(cs_KeyStore);
247  return GetSaplingIncomingViewingKey(addr, ivk) &&
248  GetSaplingFullViewingKey(ivk, extfvk) &&
249  GetSaplingSpendingKey(extfvk, extskOut);
250 }
251 
252 void CBasicKeyStore::GetSaplingPaymentAddresses(std::set<libzcash::SaplingPaymentAddress>& setAddress) const
253 {
254  setAddress.clear();
255  {
256  LOCK(cs_KeyStore);
257  auto mi = mapSaplingIncomingViewingKeys.begin();
258  while (mi != mapSaplingIncomingViewingKeys.end()) {
259  setAddress.insert((*mi).first);
260  mi++;
261  }
262  }
263 }
virtual bool HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr) const
Definition: keystore.cpp:199
virtual bool RemoveWatchOnly(const CScript &dest)
Definition: keystore.cpp:94
virtual bool AddWatchOnly(const CScript &dest)
Support for Watch-only addresses.
Definition: keystore.cpp:84
SaplingSpendingKeyMap mapSaplingSpendingKeys
Definition: keystore.h:109
WatchKeyMap mapWatchKeys
Definition: keystore.h:102
virtual bool GetSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk, libzcash::SaplingExtendedFullViewingKey &extfvkOut) const
Definition: keystore.cpp:215
virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const
Definition: keystore.cpp:194
void GetSaplingPaymentAddresses(std::set< libzcash::SaplingPaymentAddress > &setAddress) const
Definition: keystore.cpp:252
virtual bool HaveCScript(const CScriptID &hash) const
Definition: keystore.cpp:51
virtual bool AddCScript(const CScript &redeemScript)
Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki.
Definition: keystore.cpp:41
bool GetKey(const CKeyID &address, CKey &keyOut) const
Definition: keystore.cpp:136
virtual bool AddSaplingIncomingViewingKey(const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingPaymentAddress &addr)
Sapling incoming viewing keys.
Definition: keystore.cpp:177
bool HaveSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey &extfvk) const
Definition: keystore.cpp:189
SaplingIncomingViewingKeyMap mapSaplingIncomingViewingKeys
Definition: keystore.h:111
bool GetSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, libzcash::SaplingExtendedSpendingKey &skOut) const
Definition: keystore.cpp:204
ScriptMap mapScripts
Definition: keystore.h:103
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const
Definition: keystore.cpp:57
virtual bool HaveWatchOnly() const
Definition: keystore.cpp:110
virtual bool GetSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr, libzcash::SaplingIncomingViewingKey &ivkOut) const
Definition: keystore.cpp:228
virtual bool AddSaplingFullViewingKey(const libzcash::SaplingExtendedFullViewingKey &extfvk)
Support for Sapling full viewing keys.
Definition: keystore.cpp:164
SaplingFullViewingKeyMap mapSaplingFullViewingKeys
Definition: keystore.h:110
WatchOnlySet setWatchOnly
Definition: keystore.h:104
bool AddSaplingSpendingKey(const libzcash::SaplingExtendedSpendingKey &sk)
Sapling.
Definition: keystore.cpp:148
KeyMap mapKeys
Definition: keystore.h:101
std::set< CKeyID > GetKeys() const
Definition: keystore.cpp:126
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
Add a key to the store.
Definition: keystore.cpp:34
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
Definition: keystore.cpp:19
bool GetSaplingExtendedSpendingKey(const libzcash::SaplingPaymentAddress &addr, libzcash::SaplingExtendedSpendingKey &extskOut) const
Definition: keystore.cpp:240
bool HaveKey(const CKeyID &address) const
Check whether a key corresponding to a given address is present in the store.
Definition: keystore.cpp:116
An encapsulated private key.
Definition: key.h:30
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:186
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
virtual bool AddKey(const CKey &key)
Definition: keystore.cpp:14
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)=0
Add a key to the store.
RecursiveMutex cs_KeyStore
Definition: keystore.h:26
An encapsulated public key.
Definition: pubkey.h:44
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:167
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition: pubkey.cpp:210
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
bool GetOp(iterator &pc, opcodetype &opcodeRet, std::vector< unsigned char > &vchRet)
Definition: script.h:488
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:24
SaplingIncomingViewingKey in_viewing_key() const
Definition: address.cpp:45
Sapling functions.
Definition: address.h:30
size_type size() const
Definition: prevector.h:277
iterator begin()
Definition: prevector.h:285
@ LOCK
Definition: lockunlock.h:16
opcodetype
Script opcodes.
Definition: script.h:50
@ OP_CHECKSIG
Definition: script.h:166
libzcash::SaplingFullViewingKey fvk
Definition: zip32.h:56
libzcash::SaplingPaymentAddress DefaultAddress() const
Definition: zip32.cpp:106
SaplingExtendedFullViewingKey ToXFVK() const
Definition: zip32.cpp:150
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:247
bool error(const char *fmt, const Args &... args)
Definition: system.h:77