X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Frpcdump.cpp;h=138fc00a700e43e156b2f1ade24562e167d7aa39;hb=1c4fc9052a444c114d9c1501d2c6d1305de650d0;hp=a5a2dad218ce495ad764e9ea2a36dd4cd1af3f37;hpb=ac92f740d9fe40de422e8446aa514a254f250f27;p=novacoin.git diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index a5a2dad..138fc00 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -2,19 +2,11 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include -#include - #include "init.h" // for pwalletMain #include "bitcoinrpc.h" #include "ui_interface.h" #include "base58.h" -#include -#include -#include -#include - #define printf OutputDebugStringF using namespace json_spirit; @@ -22,49 +14,6 @@ using namespace std; void EnsureWalletIsUnlocked(); -std::string static EncodeDumpTime(int64 nTime) { - return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); -} - -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 EncodeDumpString(const std::string &str) { - std::stringstream ret; - BOOST_FOREACH(unsigned char c, str) { - if (c <= 32 || c >= 128 || c == '%') { - ret << '%' << HexStr(&c, &c + 1); - } else { - ret << c; - } - } - return ret.str(); -} - -std::string DecodeDumpString(const std::string &str) { - std::stringstream ret; - for (unsigned int pos = 0; pos < str.length(); pos++) { - unsigned char c = str[pos]; - if (c == '%' && pos+2 < str.length()) { - c = (((str[pos+1]>>6)*9+((str[pos+1]-'0')&15)) << 4) | - ((str[pos+2]>>6)*9+((str[pos+2]-'0')&15)); - pos += 2; - } - ret << c; - } - return ret.str(); -} - class CTxDump { public: @@ -122,90 +71,74 @@ Value importprivkey(const Array& params, bool fHelp) return Value::null; } -Value importwallet(const Array& params, bool fHelp) +Value importaddress(const Array& params, bool fHelp) { - if (fHelp || params.size() != 1) + if (fHelp || params.size() < 1 || params.size() > 3) throw runtime_error( - "importwallet \n" - "Imports keys from a wallet dump file (see dumpwallet)."); + "importaddress
[label] [rescan=true]\n" + "Adds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend."); + + CScript script; + CBitcoinAddress address(params[0].get_str()); + if (address.IsValid()) { + script.SetDestination(address.Get()); + } else if (IsHex(params[0].get_str())) { + std::vector data(ParseHex(params[0].get_str())); + script = CScript(data.begin(), data.end()); + } else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Novacoin address or script"); + } - EnsureWalletIsUnlocked(); + string strLabel = ""; + if (params.size() > 1) + strLabel = params[1].get_str(); - ifstream file; - file.open(params[0].get_str().c_str()); - if (!file.is_open()) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); - - int64 nTimeBegin = pindexBest->nTime; - - bool fGood = true; - - while (file.good()) { - std::string line; - std::getline(file, line); - if (line.empty() || line[0] == '#') - continue; - - std::vector vstr; - boost::split(vstr, line, boost::is_any_of(" ")); - if (vstr.size() < 2) - continue; - CBitcoinSecret vchSecret; - if (!vchSecret.SetString(vstr[0])) - continue; - bool isCompressed; - CKey key; - CSecret secret = vchSecret.GetSecret(isCompressed); - key.SetSecret(secret, isCompressed); - CPubKey pubkey = key.GetPubKey(); - CKeyID keyid = pubkey.GetID(); - if (pwalletMain->HaveKey(keyid)) { - printf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString().c_str()); - continue; - } - int64 nTime = DecodeDumpTime(vstr[1]); - std::string strLabel; - bool fLabel = true; - for (unsigned int nStr = 2; nStr < vstr.size(); nStr++) { - if (boost::algorithm::starts_with(vstr[nStr], "#")) - break; - if (vstr[nStr] == "change=1") - fLabel = false; - if (vstr[nStr] == "reserve=1") - fLabel = false; - if (boost::algorithm::starts_with(vstr[nStr], "label=")) { - strLabel = DecodeDumpString(vstr[nStr].substr(6)); - fLabel = true; - } - } - printf("Importing %s...\n", CBitcoinAddress(keyid).ToString().c_str()); - if (!pwalletMain->AddKey(key)) { - fGood = false; - continue; + // Whether to perform rescan after import + bool fRescan = true; + if (params.size() > 2) + fRescan = params[2].get_bool(); + + { + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Don't throw error in case an address is already there + if (pwalletMain->HaveWatchOnly(script)) + return Value::null; + + pwalletMain->MarkDirty(); + + if (address.IsValid()) + pwalletMain->SetAddressBookName(address.Get(), strLabel); + + if (!pwalletMain->AddWatchOnly(script)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true); + pwalletMain->ReacceptWalletTransactions(); } - pwalletMain->mapKeyMetadata[keyid].nCreateTime = nTime; - if (fLabel) - pwalletMain->SetAddressBookName(keyid, strLabel); - nTimeBegin = std::min(nTimeBegin, nTime); } - file.close(); - CBlockIndex *pindex = pindexBest; - while (pindex && pindex->pprev && pindex->nTime > nTimeBegin - 7200) - pindex = pindex->pprev; + return Value::null; +} + +Value importwallet(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "importwallet \n" + "Imports keys from a wallet dump file (see dumpwallet)." + + HelpRequiringPassphrase()); - printf("Rescanning last %i blocks\n", pindexBest->nHeight - pindex->nHeight + 1); - pwalletMain->ScanForWalletTransactions(pindex); - pwalletMain->ReacceptWalletTransactions(); - pwalletMain->MarkDirty(); + EnsureWalletIsUnlocked(); - if (!fGood) - throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet"); + if(!ImportWallet(pwalletMain, params[0].get_str().c_str())) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet"); return Value::null; } - Value dumpprivkey(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -213,6 +146,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)) @@ -234,59 +169,13 @@ Value dumpwallet(const Array& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "dumpwallet \n" - "Dumps all wallet keys in a human-readable format."); + "Dumps all wallet keys in a human-readable format." + + HelpRequiringPassphrase()); EnsureWalletIsUnlocked(); - ofstream file; - file.open(params[0].get_str().c_str()); - if (!file.is_open()) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); - - std::map mapKeyBirth; + if(!DumpWallet(pwalletMain, params[0].get_str().c_str() )) + throw JSONRPCError(RPC_WALLET_ERROR, "Error dumping wallet keys to file"); - std::set setKeyPool; - - pwalletMain->GetKeyBirthTimes(mapKeyBirth); - - pwalletMain->GetAllReserveKeys(setKeyPool); - - // sort time/key pairs - std::vector > vKeyBirth; - for (std::map::const_iterator it = mapKeyBirth.begin(); it != mapKeyBirth.end(); it++) { - vKeyBirth.push_back(std::make_pair(it->second, it->first)); - } - mapKeyBirth.clear(); - std::sort(vKeyBirth.begin(), vKeyBirth.end()); - - // produce output - file << strprintf("# Wallet dump created by NovaCoin %s (%s)\n", CLIENT_BUILD.c_str(), CLIENT_DATE.c_str()); - file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()).c_str()); - file << strprintf("# * Best block at time of backup was %i (%s),\n", nBestHeight, hashBestChain.ToString().c_str()); - file << strprintf("# mined on %s\n", EncodeDumpTime(pindexBest->nTime).c_str()); - file << "\n"; - for (std::vector >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) { - const CKeyID &keyid = it->second; - std::string strTime = EncodeDumpTime(it->first); - std::string strAddr = CBitcoinAddress(keyid).ToString(); - bool IsCompressed; - - CKey key; - if (pwalletMain->GetKey(keyid, key)) { - if (pwalletMain->mapAddressBook.count(keyid)) { - CSecret secret = key.GetSecret(IsCompressed); - file << strprintf("%s %s label=%s # addr=%s\n", CBitcoinSecret(secret, IsCompressed).ToString().c_str(), strTime.c_str(), EncodeDumpString(pwalletMain->mapAddressBook[keyid]).c_str(), strAddr.c_str()); - } else if (setKeyPool.count(keyid)) { - CSecret secret = key.GetSecret(IsCompressed); - file << strprintf("%s %s reserve=1 # addr=%s\n", CBitcoinSecret(secret, IsCompressed).ToString().c_str(), strTime.c_str(), strAddr.c_str()); - } else { - CSecret secret = key.GetSecret(IsCompressed); - file << strprintf("%s %s change=1 # addr=%s\n", CBitcoinSecret(secret, IsCompressed).ToString().c_str(), strTime.c_str(), strAddr.c_str()); - } - } - } - file << "\n"; - file << "# End of dump\n"; - file.close(); return Value::null; }