Skip to content

Commit

Permalink
Merge #11854: Split up key and script metadata for better type safety
Browse files Browse the repository at this point in the history
9c8eca7 Split up key and script metadata for better type safety (Russell Yanofsky)

Pull request description:

  Suggested by @TheBlueMatt
  bitcoin/bitcoin#11403 (comment)

  Combining the maps was probably never a good arrangement but is more
  problematic now in presence of WitnessV0ScriptHash and WitnessV0KeyHash types.

Tree-SHA512: 9263e9c01090fb49221e91d88a88241a9691dda3e92d86041c8e284306a64d3af5e2438249f9dcc3e6e4a5c11c1a89f975a86d55690adf95bf2636f15f99f92a
  • Loading branch information
laanwj authored and malbit committed Nov 5, 2021
1 parent 6ad7ca8 commit c141d9f
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 34 deletions.
28 changes: 18 additions & 10 deletions src/rpc/misc.cpp
Expand Up @@ -304,20 +304,28 @@ UniValue validateaddress(const JSONRPCRequest& request)
ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name));
}
if (pwallet) {
const auto& meta = pwallet->mapKeyMetadata;
const CKeyMetadata* meta = nullptr;
const CKeyID *keyID = boost::get<CKeyID>(&dest);
auto it = keyID ? meta.find(*keyID) : meta.end();
if (it == meta.end()) {
it = meta.find(CScriptID(scriptPubKey));
if (const CKeyID* key_id = boost::get<CKeyID>(&dest)) {
auto it = pwallet->mapKeyMetadata.find(*key_id);
if (it != pwallet->mapKeyMetadata.end()) {
meta = &it->second;
}
}
if (it != meta.end()) {
ret.push_back(Pair("timestamp", it->second.nCreateTime));
if (!meta) {
auto it = pwallet->m_script_metadata.find(CScriptID(scriptPubKey));
if (it != pwallet->m_script_metadata.end()) {
meta = &it->second;
}
}
if (meta) {
ret.push_back(Pair("timestamp", meta->nCreateTime));
CHDChain hdChainCurrent;
if (pwallet->mapHdPubKeys.count(*keyID) && pwallet->GetHDChain(hdChainCurrent)) {
ret.push_back(Pair("hdkeypath", pwallet->mapHdPubKeys[*keyID].GetKeyPath()));
ret.push_back(Pair("hdchainid", hdChainCurrent.GetID().GetHex()));
}

CHDChain hdChainCurrent;
if (keyID && pwallet->mapHdPubKeys.count(*keyID) && pwallet->GetHDChain(hdChainCurrent)) {
ret.push_back(Pair("hdkeypath", pwallet->mapHdPubKeys[*keyID].GetKeyPath()));
ret.push_back(Pair("hdchainid", hdChainCurrent.GetID().GetHex()));
}
}
#endif
Expand Down
14 changes: 11 additions & 3 deletions src/wallet/wallet.cpp
Expand Up @@ -387,14 +387,22 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
}
}

bool CWallet::LoadKeyMetadata(const CTxDestination& keyID, const CKeyMetadata &meta)
bool CWallet::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &meta)
{
AssertLockHeld(cs_wallet); // mapKeyMetadata
UpdateTimeFirstKey(meta.nCreateTime);
mapKeyMetadata[keyID] = meta;
return true;
}

bool CWallet::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &meta)
{
AssertLockHeld(cs_wallet); // m_script_metadata
UpdateTimeFirstKey(meta.nCreateTime);
m_script_metadata[script_id] = meta;
return true;
}

bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
{
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
Expand Down Expand Up @@ -443,15 +451,15 @@ bool CWallet::AddWatchOnly(const CScript& dest)
{
if (!CCryptoKeyStore::AddWatchOnly(dest))
return false;
const CKeyMetadata& meta = mapKeyMetadata[CScriptID(dest)];
const CKeyMetadata& meta = m_script_metadata[CScriptID(dest)];
UpdateTimeFirstKey(meta.nCreateTime);
NotifyWatchonlyChanged(true);
return CWalletDB(*dbw).WriteWatchOnly(dest, meta);
}

bool CWallet::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
{
mapKeyMetadata[CScriptID(dest)].nCreateTime = nCreateTime;
m_script_metadata[CScriptID(dest)].nCreateTime = nCreateTime;
return AddWatchOnly(dest);
}

Expand Down
11 changes: 7 additions & 4 deletions src/wallet/wallet.h
Expand Up @@ -824,9 +824,11 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface

void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool);

// Map from Key ID (for regular keys) or Script ID (for watch-only keys) to
// key metadata.
std::map<CTxDestination, CKeyMetadata> mapKeyMetadata;
// Map from Key ID to key metadata.
std::map<CKeyID, CKeyMetadata> mapKeyMetadata;

// Map from Script ID to key metadata (for watch-only keys).
std::map<CScriptID, CKeyMetadata> m_script_metadata;

typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
MasterKeyMap mapMasterKeys;
Expand Down Expand Up @@ -978,7 +980,8 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
//! Load metadata (used by LoadWallet)
bool LoadKeyMetadata(const CTxDestination& pubKey, const CKeyMetadata &metadata);
bool LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &metadata);
bool LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata);

bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
void UpdateTimeFirstKey(int64_t nCreateTime);
Expand Down
30 changes: 13 additions & 17 deletions src/wallet/walletdb.cpp
Expand Up @@ -426,27 +426,23 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
}
wss.fIsEncrypted = true;
}
else if (strType == "keymeta" || strType == "watchmeta")
else if (strType == "keymeta")
{
CTxDestination keyID;
if (strType == "keymeta")
{
CPubKey vchPubKey;
ssKey >> vchPubKey;
keyID = vchPubKey.GetID();
}
else if (strType == "watchmeta")
{
CScript script;
ssKey >> script;
keyID = CScriptID(script);
}

CPubKey vchPubKey;
ssKey >> vchPubKey;
CKeyMetadata keyMeta;
ssValue >> keyMeta;
wss.nKeyMeta++;

pwallet->LoadKeyMetadata(keyID, keyMeta);
pwallet->LoadKeyMetadata(vchPubKey.GetID(), keyMeta);
}
else if (strType == "watchmeta")
{
CScript script;
ssKey >> script;
CKeyMetadata keyMeta;
ssValue >> keyMeta;
wss.nKeyMeta++;
pwallet->LoadScriptMetadata(CScriptID(script), keyMeta);
}
else if (strType == "defaultkey")
{
Expand Down

0 comments on commit c141d9f

Please sign in to comment.