From a58370e6a2d4dce50eefbcab5bde9f14facef8fc Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Tue, 8 Nov 2016 16:28:20 -0500 Subject: Dedup nTimeFirstKey update logic Also make nTimeFirstKey member variable private. This is just a cleanup change, it doesn't change behavior in any significant way. --- src/wallet/walletdb.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/wallet/walletdb.cpp') diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index b00ce36b7..15e1e4c45 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -357,7 +357,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, // Watch-only addresses have no birthday information for now, // so set the wallet birthday to the beginning of time. - pwallet->nTimeFirstKey = 1; + pwallet->UpdateTimeFirstKey(1); } else if (strType == "key" || strType == "wkey") { @@ -467,11 +467,6 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, wss.nKeyMeta++; pwallet->LoadKeyMetadata(vchPubKey, keyMeta); - - // find earliest key creation time, as wallet birthday - if (!pwallet->nTimeFirstKey || - (keyMeta.nCreateTime < pwallet->nTimeFirstKey)) - pwallet->nTimeFirstKey = keyMeta.nCreateTime; } else if (strType == "defaultkey") { @@ -626,7 +621,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) // nTimeFirstKey is only reliable if all keys have metadata if ((wss.nKeys + wss.nCKeys) != wss.nKeyMeta) - pwallet->nTimeFirstKey = 1; // 0 would be considered 'no value' + pwallet->UpdateTimeFirstKey(1); BOOST_FOREACH(uint256 hash, wss.vWalletUpgrade) WriteTx(pwallet->mapWallet[hash]); -- cgit v1.2.3 From a80f98b1c7a49432dc53d18d0fb51ac334de96be Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Tue, 8 Nov 2016 16:55:02 -0500 Subject: 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. --- src/wallet/walletdb.cpp | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'src/wallet/walletdb.cpp') diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 15e1e4c45..106a59d56 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -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 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) -- cgit v1.2.3