Skip to content

Commit 9c8eca7

Browse files
committed
Split up key and script metadata for better type safety
Suggested by Matt Corallo <[email protected]> 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.
1 parent 4ef4dfe commit 9c8eca7

File tree

4 files changed

+48
-34
lines changed

4 files changed

+48
-34
lines changed

src/rpc/misc.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -187,17 +187,24 @@ UniValue validateaddress(const JSONRPCRequest& request)
187187
ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name));
188188
}
189189
if (pwallet) {
190-
const auto& meta = pwallet->mapKeyMetadata;
191-
const CKeyID *keyID = boost::get<CKeyID>(&dest);
192-
auto it = keyID ? meta.find(*keyID) : meta.end();
193-
if (it == meta.end()) {
194-
it = meta.find(CScriptID(scriptPubKey));
190+
const CKeyMetadata* meta = nullptr;
191+
if (const CKeyID* key_id = boost::get<CKeyID>(&dest)) {
192+
auto it = pwallet->mapKeyMetadata.find(*key_id);
193+
if (it != pwallet->mapKeyMetadata.end()) {
194+
meta = &it->second;
195+
}
196+
}
197+
if (!meta) {
198+
auto it = pwallet->m_script_metadata.find(CScriptID(scriptPubKey));
199+
if (it != pwallet->m_script_metadata.end()) {
200+
meta = &it->second;
201+
}
195202
}
196-
if (it != meta.end()) {
197-
ret.push_back(Pair("timestamp", it->second.nCreateTime));
198-
if (!it->second.hdKeypath.empty()) {
199-
ret.push_back(Pair("hdkeypath", it->second.hdKeypath));
200-
ret.push_back(Pair("hdmasterkeyid", it->second.hdMasterKeyID.GetHex()));
203+
if (meta) {
204+
ret.push_back(Pair("timestamp", meta->nCreateTime));
205+
if (!meta->hdKeypath.empty()) {
206+
ret.push_back(Pair("hdkeypath", meta->hdKeypath));
207+
ret.push_back(Pair("hdmasterkeyid", meta->hdMasterKeyID.GetHex()));
201208
}
202209
}
203210
}

src/wallet/wallet.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,14 +284,22 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
284284
}
285285
}
286286

287-
bool CWallet::LoadKeyMetadata(const CTxDestination& keyID, const CKeyMetadata &meta)
287+
bool CWallet::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &meta)
288288
{
289289
AssertLockHeld(cs_wallet); // mapKeyMetadata
290290
UpdateTimeFirstKey(meta.nCreateTime);
291291
mapKeyMetadata[keyID] = meta;
292292
return true;
293293
}
294294

295+
bool CWallet::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &meta)
296+
{
297+
AssertLockHeld(cs_wallet); // m_script_metadata
298+
UpdateTimeFirstKey(meta.nCreateTime);
299+
m_script_metadata[script_id] = meta;
300+
return true;
301+
}
302+
295303
bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
296304
{
297305
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
@@ -340,15 +348,15 @@ bool CWallet::AddWatchOnly(const CScript& dest)
340348
{
341349
if (!CCryptoKeyStore::AddWatchOnly(dest))
342350
return false;
343-
const CKeyMetadata& meta = mapKeyMetadata[CScriptID(dest)];
351+
const CKeyMetadata& meta = m_script_metadata[CScriptID(dest)];
344352
UpdateTimeFirstKey(meta.nCreateTime);
345353
NotifyWatchonlyChanged(true);
346354
return CWalletDB(*dbw).WriteWatchOnly(dest, meta);
347355
}
348356

349357
bool CWallet::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
350358
{
351-
mapKeyMetadata[CScriptID(dest)].nCreateTime = nCreateTime;
359+
m_script_metadata[CScriptID(dest)].nCreateTime = nCreateTime;
352360
return AddWatchOnly(dest);
353361
}
354362

src/wallet/wallet.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -761,9 +761,11 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
761761

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

764-
// Map from Key ID (for regular keys) or Script ID (for watch-only keys) to
765-
// key metadata.
766-
std::map<CTxDestination, CKeyMetadata> mapKeyMetadata;
764+
// Map from Key ID to key metadata.
765+
std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
766+
767+
// Map from Script ID to key metadata (for watch-only keys).
768+
std::map<CScriptID, CKeyMetadata> m_script_metadata;
767769

768770
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
769771
MasterKeyMap mapMasterKeys;
@@ -874,7 +876,8 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
874876
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
875877
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
876878
//! Load metadata (used by LoadWallet)
877-
bool LoadKeyMetadata(const CTxDestination& pubKey, const CKeyMetadata &metadata);
879+
bool LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &metadata);
880+
bool LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata);
878881

879882
bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
880883
void UpdateTimeFirstKey(int64_t nCreateTime);

src/wallet/walletdb.cpp

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -423,27 +423,23 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
423423
}
424424
wss.fIsEncrypted = true;
425425
}
426-
else if (strType == "keymeta" || strType == "watchmeta")
426+
else if (strType == "keymeta")
427427
{
428-
CTxDestination keyID;
429-
if (strType == "keymeta")
430-
{
431-
CPubKey vchPubKey;
432-
ssKey >> vchPubKey;
433-
keyID = vchPubKey.GetID();
434-
}
435-
else if (strType == "watchmeta")
436-
{
437-
CScript script;
438-
ssKey >> script;
439-
keyID = CScriptID(script);
440-
}
441-
428+
CPubKey vchPubKey;
429+
ssKey >> vchPubKey;
442430
CKeyMetadata keyMeta;
443431
ssValue >> keyMeta;
444432
wss.nKeyMeta++;
445-
446-
pwallet->LoadKeyMetadata(keyID, keyMeta);
433+
pwallet->LoadKeyMetadata(vchPubKey.GetID(), keyMeta);
434+
}
435+
else if (strType == "watchmeta")
436+
{
437+
CScript script;
438+
ssKey >> script;
439+
CKeyMetadata keyMeta;
440+
ssValue >> keyMeta;
441+
wss.nKeyMeta++;
442+
pwallet->LoadScriptMetadata(CScriptID(script), keyMeta);
447443
}
448444
else if (strType == "defaultkey")
449445
{

0 commit comments

Comments
 (0)