From dfd0524d74a0970a7cbcc110b3c1b42e89deb32f Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 29 Jul 2013 03:07:03 +0400 Subject: [PATCH] Key metadata update + new timestamp conversion function --- src/rpcdump.cpp | 64 ++++++++++++++++++++++++++++++++++++++---------------- src/wallet.cpp | 28 ++++++++++++------------ src/wallet.h | 4 +- src/walletdb.h | 10 +++----- 4 files changed, 65 insertions(+), 41 deletions(-) diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index a5a2dad..b0284f9 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -10,8 +10,8 @@ #include "ui_interface.h" #include "base58.h" -#include #include +#include #include #include @@ -22,21 +22,44 @@ using namespace std; void EnsureWalletIsUnlocked(); -std::string static EncodeDumpTime(int64 nTime) { - return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); +namespace bt = boost::posix_time; + +// Extended DecodeDumpTime implementation, see this page for details: +// http://stackoverflow.com/questions/3786201/parsing-of-date-time-from-string-boost +const std::locale formats[] = { + std::locale(std::locale::classic(),new bt::time_input_facet("%Y-%m-%dT%H:%M:%SZ")), + std::locale(std::locale::classic(),new bt::time_input_facet("%Y-%m-%d %H:%M:%S")), + std::locale(std::locale::classic(),new bt::time_input_facet("%Y/%m/%d %H:%M:%S")), + std::locale(std::locale::classic(),new bt::time_input_facet("%d.%m.%Y %H:%M:%S")), + std::locale(std::locale::classic(),new bt::time_input_facet("%Y-%m-%d")) +}; + +const size_t formats_n = sizeof(formats)/sizeof(formats[0]); + +std::time_t pt_to_time_t(const bt::ptime& pt) +{ + bt::ptime timet_start(boost::gregorian::date(1970,1,1)); + bt::time_duration diff = pt - timet_start; + return diff.ticks()/bt::time_duration::rep_type::ticks_per_second; +} + +int64 DecodeDumpTime(const std::string& s) +{ + bt::ptime pt; + + for(size_t i=0; i> pt; + if(pt != bt::ptime()) break; + } + + return pt_to_time_t(pt); } -int64 static DecodeDumpTime(const std::string &str) { - static const boost::posix_time::time_input_facet facet("%Y-%m-%dT%H:%M:%SZ"); - static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0); - const std::locale loc(std::locale::classic(), &facet); - std::istringstream iss(str); - iss.imbue(loc); - boost::posix_time::ptime ptime(boost::date_time::not_a_date_time); - iss >> ptime; - if (ptime.is_not_a_date_time()) - return 0; - return (ptime - epoch).total_seconds(); +std::string static EncodeDumpTime(int64 nTime) { + return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); } std::string static EncodeDumpString(const std::string &str) { @@ -153,12 +176,13 @@ Value importwallet(const Array& params, bool fHelp) CBitcoinSecret vchSecret; if (!vchSecret.SetString(vstr[0])) continue; - bool isCompressed; + + bool fCompressed; CKey key; - CSecret secret = vchSecret.GetSecret(isCompressed); - key.SetSecret(secret, isCompressed); - CPubKey pubkey = key.GetPubKey(); - CKeyID keyid = pubkey.GetID(); + CSecret secret = vchSecret.GetSecret(fCompressed); + key.SetSecret(secret, fCompressed); + CKeyID keyid = key.GetPubKey().GetID(); + if (pwalletMain->HaveKey(keyid)) { printf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString().c_str()); continue; @@ -213,6 +237,8 @@ Value dumpprivkey(const Array& params, bool fHelp) "dumpprivkey \n" "Reveals the private key corresponding to ."); + EnsureWalletIsUnlocked(); + string strAddress = params[0].get_str(); CBitcoinAddress address; if (!address.SetString(strAddress)) diff --git a/src/wallet.cpp b/src/wallet.cpp index 9a37be5..64e3318 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -40,34 +40,34 @@ CPubKey CWallet::GenerateNewKey() if (fCompressed) SetMinVersion(FEATURE_COMPRPUBKEY); + CPubKey pubkey = key.GetPubKey(); + + // Create new metadata + int64 nCreationTime = GetTime(); + mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime); + if (!nTimeFirstKey || nCreationTime < nTimeFirstKey) + nTimeFirstKey = nCreationTime; + if (!AddKey(key)) throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed"); return key.GetPubKey(); } -bool CWallet::AddKey(const CKey& key, int64 nCreateTime) +bool CWallet::AddKey(const CKey& key) { - if(!nCreateTime) - nCreateTime = GetTime(); - if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) - nTimeFirstKey = nCreateTime; + CPubKey pubkey = key.GetPubKey(); if (!CCryptoKeyStore::AddKey(key)) return false; if (!fFileBacked) return true; if (!IsCrypted()) - return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey(), nCreateTime); + return CWalletDB(strWalletFile).WriteKey(pubkey, key.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]); return true; } -bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector &vchCryptedSecret, int64 nCreateTime) +bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector &vchCryptedSecret) { - if(!nCreateTime) - nCreateTime = GetTime(); - if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) - nTimeFirstKey = nCreateTime; - if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) return false; if (!fFileBacked) @@ -75,9 +75,9 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vectorWriteCryptedKey(vchPubKey, vchCryptedSecret, nCreateTime); + return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); else - return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, nCreateTime); + return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); } return false; } diff --git a/src/wallet.h b/src/wallet.h index 3060238..9fc58d5 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -139,7 +139,7 @@ public: // Generate a new key CPubKey GenerateNewKey(); // Adds a key to the store, and saves it to disk. - bool AddKey(const CKey& key, int64 nCreateTime = 0); + bool AddKey(const CKey& key); // Adds a key to the store, without saving it to disk (used by LoadWallet) bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); } // Load metadata (used by LoadWallet) @@ -148,7 +148,7 @@ public: bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } // Adds an encrypted key to the store, and saves it to disk. - bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret, int64 nCreateTime = 0); + bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret); // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } bool AddCScript(const CScript& redeemScript); diff --git a/src/walletdb.h b/src/walletdb.h index 748bee5..7097e49 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -82,24 +82,22 @@ public: return Erase(std::make_pair(std::string("tx"), hash)); } - bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, int64 nCreateTime) + bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta) { nWalletDBUpdated++; - CKeyMetadata keyMeta(nCreateTime); - if(!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta, false)) + if(!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta)) return false; return Write(std::make_pair(std::string("key"), vchPubKey.Raw()), vchPrivKey, false); } - bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector& vchCryptedSecret, int64 nCreateTime) + bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta) { nWalletDBUpdated++; bool fEraseUnencryptedKey = true; - CKeyMetadata keyMeta(nCreateTime); - if(!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta, false)) + if(!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta)) return false; if (!Write(std::make_pair(std::string("ckey"), vchPubKey.Raw()), vchCryptedSecret, false)) -- 1.7.1