mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-09 12:12:41 +01:00
Use importmulti timestamp when importing watch only keys
When importing a watch-only address over importmulti with a specific timestamp, the wallet's nTimeFirstKey is currently set to 1. After this change, the provided timestamp will be used and stored as metadata associated with watch-only key. This can improve wallet performance because it can avoid the need to scan the entire blockchain for watch only addresses when timestamps are provided. Also adds timestamp to validateaddress return value (needed for tests). Fixes #9034.
This commit is contained in:
@@ -120,15 +120,19 @@ bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript)
|
||||
return Write(std::make_pair(std::string("cscript"), hash), *(const CScriptBase*)(&redeemScript), false);
|
||||
}
|
||||
|
||||
bool CWalletDB::WriteWatchOnly(const CScript &dest)
|
||||
bool CWalletDB::WriteWatchOnly(const CScript &dest, const CKeyMetadata& keyMeta)
|
||||
{
|
||||
nWalletDBUpdateCounter++;
|
||||
if (!Write(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest)), keyMeta))
|
||||
return false;
|
||||
return Write(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)), '1');
|
||||
}
|
||||
|
||||
bool CWalletDB::EraseWatchOnly(const CScript &dest)
|
||||
{
|
||||
nWalletDBUpdateCounter++;
|
||||
if (!Erase(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest))))
|
||||
return false;
|
||||
return Erase(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)));
|
||||
}
|
||||
|
||||
@@ -259,6 +263,7 @@ class CWalletScanState {
|
||||
public:
|
||||
unsigned int nKeys;
|
||||
unsigned int nCKeys;
|
||||
unsigned int nWatchKeys;
|
||||
unsigned int nKeyMeta;
|
||||
bool fIsEncrypted;
|
||||
bool fAnyUnordered;
|
||||
@@ -266,7 +271,7 @@ public:
|
||||
vector<uint256> vWalletUpgrade;
|
||||
|
||||
CWalletScanState() {
|
||||
nKeys = nCKeys = nKeyMeta = 0;
|
||||
nKeys = nCKeys = nWatchKeys = nKeyMeta = 0;
|
||||
fIsEncrypted = false;
|
||||
fAnyUnordered = false;
|
||||
nFileVersion = 0;
|
||||
@@ -348,16 +353,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
||||
}
|
||||
else if (strType == "watchs")
|
||||
{
|
||||
wss.nWatchKeys++;
|
||||
CScript script;
|
||||
ssKey >> *(CScriptBase*)(&script);
|
||||
char fYes;
|
||||
ssValue >> fYes;
|
||||
if (fYes == '1')
|
||||
pwallet->LoadWatchOnly(script);
|
||||
|
||||
// Watch-only addresses have no birthday information for now,
|
||||
// so set the wallet birthday to the beginning of time.
|
||||
pwallet->UpdateTimeFirstKey(1);
|
||||
}
|
||||
else if (strType == "key" || strType == "wkey")
|
||||
{
|
||||
@@ -458,15 +460,27 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
||||
}
|
||||
wss.fIsEncrypted = true;
|
||||
}
|
||||
else if (strType == "keymeta")
|
||||
else if (strType == "keymeta" || strType == "watchmeta")
|
||||
{
|
||||
CPubKey vchPubKey;
|
||||
ssKey >> vchPubKey;
|
||||
CTxDestination keyID;
|
||||
if (strType == "keymeta")
|
||||
{
|
||||
CPubKey vchPubKey;
|
||||
ssKey >> vchPubKey;
|
||||
keyID = vchPubKey.GetID();
|
||||
}
|
||||
else if (strType == "watchmeta")
|
||||
{
|
||||
CScript script;
|
||||
ssKey >> *(CScriptBase*)(&script);
|
||||
keyID = CScriptID(script);
|
||||
}
|
||||
|
||||
CKeyMetadata keyMeta;
|
||||
ssValue >> keyMeta;
|
||||
wss.nKeyMeta++;
|
||||
|
||||
pwallet->LoadKeyMetadata(vchPubKey, keyMeta);
|
||||
pwallet->LoadKeyMetadata(keyID, keyMeta);
|
||||
}
|
||||
else if (strType == "defaultkey")
|
||||
{
|
||||
@@ -620,7 +634,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
|
||||
wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys);
|
||||
|
||||
// nTimeFirstKey is only reliable if all keys have metadata
|
||||
if ((wss.nKeys + wss.nCKeys) != wss.nKeyMeta)
|
||||
if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta)
|
||||
pwallet->UpdateTimeFirstKey(1);
|
||||
|
||||
BOOST_FOREACH(uint256 hash, wss.vWalletUpgrade)
|
||||
|
||||
Reference in New Issue
Block a user