Add z_importwallet and z_exportwallet to handle keys for both

taddr and zaddr.  Restore behaviour of dumpwallet and importwallet
to only handle taddr.
This commit is contained in:
Simon
2016-08-10 14:35:37 -07:00
parent c1c4594371
commit 92444edc00
3 changed files with 96 additions and 33 deletions

View File

@@ -384,7 +384,9 @@ static const CRPCCommand vRPCCommands[] =
{ "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true }, { "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true },
{ "wallet", "z_getnewaddress", &z_getnewaddress, true }, { "wallet", "z_getnewaddress", &z_getnewaddress, true },
{ "wallet", "z_exportkey", &z_exportkey, true }, { "wallet", "z_exportkey", &z_exportkey, true },
{ "wallet", "z_importkey", &z_importkey, true } { "wallet", "z_importkey", &z_importkey, true },
{ "wallet", "z_exportwallet", &z_exportwallet, true },
{ "wallet", "z_importwallet", &z_importwallet, true }
#endif // ENABLE_WALLET #endif // ENABLE_WALLET
}; };

View File

@@ -246,6 +246,8 @@ extern json_spirit::Value getblocksubsidy(const json_spirit::Array& params, bool
extern json_spirit::Value z_exportkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp extern json_spirit::Value z_exportkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
extern json_spirit::Value z_importkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp extern json_spirit::Value z_importkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
extern json_spirit::Value z_getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp extern json_spirit::Value z_getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
extern json_spirit::Value z_exportwallet(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
extern json_spirit::Value z_importwallet(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
// in rest.cpp // in rest.cpp
extern bool HTTPReq_REST(AcceptedConnection *conn, extern bool HTTPReq_REST(AcceptedConnection *conn,

View File

@@ -27,6 +27,10 @@ using namespace std;
void EnsureWalletIsUnlocked(); void EnsureWalletIsUnlocked();
bool EnsureWalletIsAvailable(bool avoidException); bool EnsureWalletIsAvailable(bool avoidException);
Value _dumpwallet(const Array& params, bool fHelp, bool fDumpZKeys);
Value _importwallet(const Array& params, bool fHelp, bool fImportZKeys);
std::string static EncodeDumpTime(int64_t nTime) { std::string static EncodeDumpTime(int64_t nTime) {
return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime);
} }
@@ -217,6 +221,29 @@ Value importaddress(const Array& params, bool fHelp)
return Value::null; return Value::null;
} }
Value z_importwallet(const Array& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
return Value::null;
if (fHelp || params.size() != 1)
throw runtime_error(
"z_importwallet \"filename\"\n"
"\nImports taddr and zaddr keys from a wallet export file (see z_exportwallet).\n"
"\nArguments:\n"
"1. \"filename\" (string, required) The wallet file\n"
"\nExamples:\n"
"\nDump the wallet\n"
+ HelpExampleCli("z_exportwallet", "\"test\"") +
"\nImport the wallet\n"
+ HelpExampleCli("z_importwallet", "\"test\"") +
"\nImport using the json rpc call\n"
+ HelpExampleRpc("z_importwallet", "\"test\"")
);
return _importwallet(params, fHelp, true);
}
Value importwallet(const Array& params, bool fHelp) Value importwallet(const Array& params, bool fHelp)
{ {
if (!EnsureWalletIsAvailable(fHelp)) if (!EnsureWalletIsAvailable(fHelp))
@@ -237,6 +264,11 @@ Value importwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("importwallet", "\"test\"") + HelpExampleRpc("importwallet", "\"test\"")
); );
return _importwallet(params, fHelp, false);
}
Value _importwallet(const Array& params, bool fHelp, bool fImportZKeys)
{
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked();
@@ -267,29 +299,30 @@ Value importwallet(const Array& params, bool fHelp)
continue; continue;
// Let's see if the address is a valid Zcash spending key // Let's see if the address is a valid Zcash spending key
try { if (fImportZKeys) {
CZCSpendingKey spendingkey(vstr[0]); try {
libzcash::SpendingKey key = spendingkey.Get(); CZCSpendingKey spendingkey(vstr[0]);
libzcash::PaymentAddress addr = key.address(); libzcash::SpendingKey key = spendingkey.Get();
if (pwalletMain->HaveSpendingKey(addr)) { libzcash::PaymentAddress addr = key.address();
LogPrintf("Skipping import of zaddr %s (key already present)\n", CZCPaymentAddress(addr).ToString()); if (pwalletMain->HaveSpendingKey(addr)) {
LogPrintf("Skipping import of zaddr %s (key already present)\n", CZCPaymentAddress(addr).ToString());
continue;
}
int64_t nTime = DecodeDumpTime(vstr[1]);
LogPrintf("Importing zaddr %s...\n", CZCPaymentAddress(addr).ToString());
if (!pwalletMain->AddZKey(key)) {
// Something went wrong
fGood = false;
continue;
}
// Successfully imported zaddr. Now import the metadata.
pwalletMain->mapZKeyMetadata[addr].nCreateTime = nTime;
continue; continue;
} }
int64_t nTime = DecodeDumpTime(vstr[1]); catch (...) {
LogPrintf("Importing zaddr %s...\n", CZCPaymentAddress(addr).ToString()); // Not a valid spending key, so carry on and see if it's a Bitcoin style address.
if (!pwalletMain->AddZKey(key)) {
// Something went wrong
fGood = false;
continue;
} }
// Successfully imported zaddr. Now import the metadata.
pwalletMain->mapZKeyMetadata[addr].nCreateTime = nTime;
continue;
} }
catch (...) {
// Not a valid spending key, so carry on and see if it's a Bitcoin style address.
}
CBitcoinSecret vchSecret; CBitcoinSecret vchSecret;
if (!vchSecret.SetString(vstr[0])) if (!vchSecret.SetString(vstr[0]))
@@ -385,6 +418,26 @@ Value dumpprivkey(const Array& params, bool fHelp)
} }
Value z_exportwallet(const Array& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
return Value::null;
if (fHelp || params.size() != 1)
throw runtime_error(
"z_exportwallet \"filename\"\n"
"\nExports all wallet keys, for taddr and zaddr, in a human-readable format.\n"
"\nArguments:\n"
"1. \"filename\" (string, required) The filename\n"
"\nExamples:\n"
+ HelpExampleCli("z_exportwallet", "\"test\"")
+ HelpExampleRpc("z_exportwallet", "\"test\"")
);
return _dumpwallet(params, fHelp, true);
}
Value dumpwallet(const Array& params, bool fHelp) Value dumpwallet(const Array& params, bool fHelp)
{ {
if (!EnsureWalletIsAvailable(fHelp)) if (!EnsureWalletIsAvailable(fHelp))
@@ -401,6 +454,11 @@ Value dumpwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("dumpwallet", "\"test\"") + HelpExampleRpc("dumpwallet", "\"test\"")
); );
return _dumpwallet(params, fHelp, false);
}
Value _dumpwallet(const Array& params, bool fHelp, bool fDumpZKeys)
{
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked(); EnsureWalletIsUnlocked();
@@ -446,20 +504,21 @@ Value dumpwallet(const Array& params, bool fHelp)
} }
file << "\n"; file << "\n";
// dump the zkeys if (fDumpZKeys) {
std::set<libzcash::PaymentAddress> addresses; std::set<libzcash::PaymentAddress> addresses;
pwalletMain->GetPaymentAddresses(addresses); pwalletMain->GetPaymentAddresses(addresses);
file << "\n"; file << "\n";
file << "# Zkeys\n"; file << "# Zkeys\n";
file << "\n"; file << "\n";
for (auto addr : addresses ) { for (auto addr : addresses ) {
libzcash::SpendingKey key; libzcash::SpendingKey key;
if (pwalletMain->GetSpendingKey(addr, key)) { if (pwalletMain->GetSpendingKey(addr, key)) {
std::string strTime = EncodeDumpTime(pwalletMain->mapZKeyMetadata[addr].nCreateTime); std::string strTime = EncodeDumpTime(pwalletMain->mapZKeyMetadata[addr].nCreateTime);
file << strprintf("%s %s # zaddr=%s\n", CZCSpendingKey(key).ToString(), strTime, CZCPaymentAddress(addr).ToString()); file << strprintf("%s %s # zaddr=%s\n", CZCSpendingKey(key).ToString(), strTime, CZCPaymentAddress(addr).ToString());
}
} }
file << "\n";
} }
file << "\n";
file << "# End of dump\n"; file << "# End of dump\n";
file.close(); file.close();