Skip to content

Commit

Permalink
get rid of mapPubKeys
Browse files Browse the repository at this point in the history
Make CKeyStore's interface work on uint160's instead of pubkeys, so
no separate global mapPubKeys is necessary anymore.
  • Loading branch information
sipa committed Jul 17, 2011
1 parent 133ccbe commit 03fbd79
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 110 deletions.
1 change: 0 additions & 1 deletion src/init.cpp
Expand Up @@ -425,7 +425,6 @@ bool AppInit2(int argc, char* argv[])
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
printf("nBestHeight = %d\n", nBestHeight);
printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());

Expand Down
58 changes: 40 additions & 18 deletions src/keystore.cpp
Expand Up @@ -16,14 +16,19 @@ std::vector<unsigned char> CKeyStore::GenerateNewKey()
return key.GetPubKey();
}

bool CKeyStore::GetPubKey(const uint160 &hashAddress, std::vector<unsigned char> &vchPubKeyOut) const
{
CKey key;
if (!GetKey(hashAddress, key))
return false;
vchPubKeyOut = key.GetPubKey();
return true;
}

bool CBasicKeyStore::AddKey(const CKey& key)
{
CRITICAL_BLOCK(cs_mapPubKeys)
CRITICAL_BLOCK(cs_KeyStore)
{
mapKeys[key.GetPubKey()] = key.GetPrivKey();
mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey();
}
mapKeys[Hash160(key.GetPubKey())] = key.GetSecret();
return true;
}

Expand All @@ -44,11 +49,11 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
if (!SetCrypted())
return false;

std::map<std::vector<unsigned char>, std::vector<unsigned char> >::const_iterator mi = mapCryptedKeys.begin();
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
for (; mi != mapCryptedKeys.end(); ++mi)
{
const std::vector<unsigned char> &vchPubKey = (*mi).first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second;
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
CSecret vchSecret;
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
return false;
Expand Down Expand Up @@ -88,31 +93,30 @@ bool CCryptoKeyStore::AddKey(const CKey& key)

bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
{
CRITICAL_BLOCK(cs_mapPubKeys)
CRITICAL_BLOCK(cs_KeyStore)
{
if (!SetCrypted())
return false;

mapCryptedKeys[vchPubKey] = vchCryptedSecret;
mapPubKeys[Hash160(vchPubKey)] = vchPubKey;
mapCryptedKeys[Hash160(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
}
return true;
}

bool CCryptoKeyStore::GetPrivKey(const std::vector<unsigned char> &vchPubKey, CKey& keyOut) const
bool CCryptoKeyStore::GetKey(const uint160 &hashAddress, CKey& keyOut) const
{
CRITICAL_BLOCK(cs_vMasterKey)
{
if (!IsCrypted())
return CBasicKeyStore::GetPrivKey(vchPubKey, keyOut);
return CBasicKeyStore::GetKey(hashAddress, keyOut);

std::map<std::vector<unsigned char>, std::vector<unsigned char> >::const_iterator mi = mapCryptedKeys.find(vchPubKey);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(hashAddress);
if (mi != mapCryptedKeys.end())
{
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second;
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
CSecret vchSecret;
if (!DecryptSecret(vMasterKey, (*mi).second, Hash((*mi).first.begin(), (*mi).first.end()), vchSecret))
if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
return false;
keyOut.SetSecret(vchSecret);
return true;
Expand All @@ -121,6 +125,23 @@ bool CCryptoKeyStore::GetPrivKey(const std::vector<unsigned char> &vchPubKey, CK
return false;
}

bool CCryptoKeyStore::GetPubKey(const uint160 &hashAddress, std::vector<unsigned char>& vchPubKeyOut) const
{
CRITICAL_BLOCK(cs_vMasterKey)
{
if (!IsCrypted())
return CKeyStore::GetPubKey(hashAddress, vchPubKeyOut);

CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(hashAddress);
if (mi != mapCryptedKeys.end())
{
vchPubKeyOut = (*mi).second.first;
return true;
}
}
return false;
}

bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
{
CRITICAL_BLOCK(cs_KeyStore)
Expand All @@ -135,10 +156,11 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
{
if (!key.SetPrivKey(mKey.second))
return false;
const std::vector<unsigned char> vchPubKey = key.GetPubKey();
std::vector<unsigned char> vchCryptedSecret;
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(mKey.first.begin(), mKey.first.end()), vchCryptedSecret))
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
return false;
if (!AddCryptedKey(mKey.first, vchCryptedSecret))
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
return false;
}
mapKeys.clear();
Expand Down
30 changes: 17 additions & 13 deletions src/keystore.h
Expand Up @@ -12,12 +12,13 @@ class CKeyStore
mutable CCriticalSection cs_KeyStore;

virtual bool AddKey(const CKey& key) =0;
virtual bool HaveKey(const std::vector<unsigned char> &vchPubKey) const =0;
virtual bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CKey& keyOut) const =0;
virtual bool HaveKey(const uint160 &hashAddress) const =0;
virtual bool GetKey(const uint160 &hashAddress, CKey& keyOut) const =0;
virtual bool GetPubKey(const uint160 &hashAddress, std::vector<unsigned char>& vchPubKeyOut) const;
virtual std::vector<unsigned char> GenerateNewKey();
};

typedef std::map<std::vector<unsigned char>, CPrivKey> KeyMap;
typedef std::map<uint160, CSecret> KeyMap;

class CBasicKeyStore : public CKeyStore
{
Expand All @@ -26,26 +27,28 @@ class CBasicKeyStore : public CKeyStore

public:
bool AddKey(const CKey& key);
bool HaveKey(const std::vector<unsigned char> &vchPubKey) const
bool HaveKey(const uint160 &hashAddress) const
{
return (mapKeys.count(vchPubKey) > 0);
return (mapKeys.count(hashAddress) > 0);
}
bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CKey& keyOut) const
bool GetKey(const uint160 &hashAddress, CKey& keyOut) const
{
std::map<std::vector<unsigned char>, CPrivKey>::const_iterator mi = mapKeys.find(vchPubKey);
KeyMap::const_iterator mi = mapKeys.find(hashAddress);
if (mi != mapKeys.end())
{
keyOut.SetPrivKey((*mi).second);
keyOut.SetSecret((*mi).second);
return true;
}
return false;
}
};

typedef std::map<uint160, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;

class CCryptoKeyStore : public CBasicKeyStore
{
private:
std::map<std::vector<unsigned char>, std::vector<unsigned char> > mapCryptedKeys;
CryptedKeyMap mapCryptedKeys;

CKeyingMaterial vMasterKey;

Expand Down Expand Up @@ -103,13 +106,14 @@ class CCryptoKeyStore : public CBasicKeyStore
virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
std::vector<unsigned char> GenerateNewKey();
bool AddKey(const CKey& key);
bool HaveKey(const std::vector<unsigned char> &vchPubKey) const
bool HaveKey(const uint160 &hashAddress) const
{
if (!IsCrypted())
return CBasicKeyStore::HaveKey(vchPubKey);
return mapCryptedKeys.count(vchPubKey) > 0;
return CBasicKeyStore::HaveKey(hashAddress);
return mapCryptedKeys.count(hashAddress) > 0;
}
bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CKey& keyOut) const;
bool GetKey(const uint160 &hashAddress, CKey& keyOut) const;
bool GetPubKey(const uint160 &hashAddress, std::vector<unsigned char>& vchPubKeyOut) const;
};

#endif
3 changes: 0 additions & 3 deletions src/main.cpp
Expand Up @@ -21,9 +21,6 @@ set<CWallet*> setpwalletRegistered;

CCriticalSection cs_main;

CCriticalSection cs_mapPubKeys;
map<uint160, vector<unsigned char> > mapPubKeys;

map<uint256, CTransaction> mapTransactions;
CCriticalSection cs_mapTransactions;
unsigned int nTransactionsUpdated = 0;
Expand Down
2 changes: 0 additions & 2 deletions src/main.h
Expand Up @@ -1568,7 +1568,5 @@ class CAlert : public CUnsignedAlert


extern std::map<uint256, CTransaction> mapTransactions;
extern std::map<uint160, std::vector<unsigned char> > mapPubKeys;
extern CCriticalSection cs_mapPubKeys;

#endif
6 changes: 3 additions & 3 deletions src/rpc.cpp
Expand Up @@ -967,7 +967,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
{
// Only counting our own bitcoin addresses and not ip addresses
uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160();
if (hash160 == 0 || !mapPubKeys.count(hash160)) // IsMine
if (hash160 == 0 || !pwalletMain->HaveKey(hash160)) // IsMine
continue;

tallyitem& item = mapTally[hash160];
Expand Down Expand Up @@ -1242,7 +1242,7 @@ Value listaccounts(const Array& params, bool fHelp)
{
BOOST_FOREACH(const PAIRTYPE(string, string)& entry, pwalletMain->mapAddressBook) {
uint160 hash160;
if(AddressToHash160(entry.first, hash160) && mapPubKeys.count(hash160)) // This address belongs to me
if(AddressToHash160(entry.first, hash160) && pwalletMain->HaveKey(hash160)) // This address belongs to me
mapAccountBalances[entry.second] = 0;
}

Expand Down Expand Up @@ -1564,7 +1564,7 @@ Value validateaddress(const Array& params, bool fHelp)
// version of the address:
string currentAddress = Hash160ToAddress(hash160);
ret.push_back(Pair("address", currentAddress));
ret.push_back(Pair("ismine", (mapPubKeys.count(hash160) > 0)));
ret.push_back(Pair("ismine", (pwalletMain->HaveKey(hash160) > 0)));
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
if (pwalletMain->mapAddressBook.count(currentAddress))
Expand Down
64 changes: 17 additions & 47 deletions src/script.cpp
Expand Up @@ -1041,7 +1041,9 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
// Sign
const valtype& vchPubKey = item.second;
CKey key;
if (!keystore.GetPrivKey(vchPubKey, key))
if (!keystore.GetKey(Hash160(vchPubKey), key))
return false;
if (key.GetPubKey() != vchPubKey)
return false;
if (hash != 0)
{
Expand All @@ -1055,20 +1057,16 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
else if (item.first == OP_PUBKEYHASH)
{
// Sign and give pubkey
map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));
if (mi == mapPubKeys.end())
return false;
const vector<unsigned char>& vchPubKey = (*mi).second;
CKey key;
if (!keystore.GetPrivKey(vchPubKey, key))
if (!keystore.GetKey(uint160(item.second), key))
return false;
if (hash != 0)
{
vector<unsigned char> vchSig;
if (!key.Sign(hash, vchSig))
return false;
vchSig.push_back((unsigned char)nHashType);
scriptSigRet << vchSig << vchPubKey;
scriptSigRet << vchSig << key.GetPubKey();
}
}
else
Expand Down Expand Up @@ -1102,19 +1100,16 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
{
if (item.first == OP_PUBKEY)
{
// Sign
const valtype& vchPubKey = item.second;
if (!keystore.HaveKey(vchPubKey))
vector<unsigned char> vchPubKeyFound;
if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
return false;
if (vchPubKeyFound != vchPubKey)
return false;
}
else if (item.first == OP_PUBKEYHASH)
{
// Sign and give pubkey
map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));
if (mi == mapPubKeys.end())
return false;
const vector<unsigned char>& vchPubKey = (*mi).second;
if (!keystore.HaveKey(vchPubKey))
if (!keystore.HaveKey(uint160(item.second)))
return false;
}
else
Expand All @@ -1128,33 +1123,28 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
}


bool ExtractPubKey(const CScript& scriptPubKey, const CKeyStore* keystore, vector<unsigned char>& vchPubKeyRet)
bool ExtractHash160(const CScript& scriptPubKey, const CKeyStore* keystore, uint160& hash160Ret)
{
vchPubKeyRet.clear();

vector<pair<opcodetype, valtype> > vSolution;
if (!Solver(scriptPubKey, vSolution))
return false;

CRITICAL_BLOCK(cs_mapPubKeys)
CRITICAL_BLOCK(keystore->cs_KeyStore)
{
BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
{
valtype vchPubKey;
uint160 hash160;
if (item.first == OP_PUBKEY)
{
vchPubKey = item.second;
hash160 = Hash160(item.second);
}
else if (item.first == OP_PUBKEYHASH)
{
map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));
if (mi == mapPubKeys.end())
continue;
vchPubKey = (*mi).second;
hash160 = uint160(item.second);
}
if (keystore == NULL || keystore->HaveKey(vchPubKey))
if (keystore == NULL || keystore->HaveKey(hash160))
{
vchPubKeyRet = vchPubKey;
hash160Ret = hash160;
return true;
}
}
Expand All @@ -1163,26 +1153,6 @@ bool ExtractPubKey(const CScript& scriptPubKey, const CKeyStore* keystore, vecto
}


bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret)
{
hash160Ret = 0;

vector<pair<opcodetype, valtype> > vSolution;
if (!Solver(scriptPubKey, vSolution))
return false;

BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
{
if (item.first == OP_PUBKEYHASH)
{
hash160Ret = uint160(item.second);
return true;
}
}
return false;
}


bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
vector<vector<unsigned char> > stack;
Expand Down
3 changes: 1 addition & 2 deletions src/script.h
Expand Up @@ -710,8 +710,7 @@ class CScript : public std::vector<unsigned char>

bool IsStandard(const CScript& scriptPubKey);
bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
bool ExtractPubKey(const CScript& scriptPubKey, const CKeyStore* pkeystore, std::vector<unsigned char>& vchPubKeyRet);
bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret);
bool ExtractHash160(const CScript& scriptPubKey, const CKeyStore* pkeystore, uint160& hash160Ret);
bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript());
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);

Expand Down

0 comments on commit 03fbd79

Please sign in to comment.