From 9bcf90e2de13d96f0209b61b9d8bb5be15686d12 Mon Sep 17 00:00:00 2001 From: Eirik Ogilvie-Wigley Date: Wed, 12 Sep 2018 05:03:45 -0600 Subject: [PATCH] Add sapling support to z_importwallet --- qa/rpc-tests/wallet_import_export.py | 20 +++++++++++++++----- src/wallet/rpcdump.cpp | 20 ++++++-------------- src/wallet/wallet.cpp | 17 +++++++++++------ src/wallet/wallet.h | 6 +++++- 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/qa/rpc-tests/wallet_import_export.py b/qa/rpc-tests/wallet_import_export.py index b23143c9e..6577acb53 100755 --- a/qa/rpc-tests/wallet_import_export.py +++ b/qa/rpc-tests/wallet_import_export.py @@ -16,19 +16,29 @@ class WalletImportExportTest (BitcoinTestFramework): sapling_address0 = self.nodes[0].z_getnewaddress('sapling') # node 0 should have the keys - dump_path = self.nodes[0].z_exportwallet('walletdump') - (t_keys0, sprout_keys0, sapling_keys0) = parse_wallet_file(dump_path) + dump_path0 = self.nodes[0].z_exportwallet('walletdump') + (t_keys0, sprout_keys0, sapling_keys0) = parse_wallet_file(dump_path0) assert_true(sprout_address0 in sprout_keys0) assert_true(sapling_address0 in sapling_keys0) - # node 1 should not - dump_path = self.nodes[1].z_exportwallet('walletdump') - (t_keys1, sprout_keys1, sapling_keys1) = parse_wallet_file(dump_path) + # node 1 should not have the keys + dump_path1 = self.nodes[1].z_exportwallet('walletdumpbefore') + (t_keys1, sprout_keys1, sapling_keys1) = parse_wallet_file(dump_path1) assert_true(sprout_address0 not in sprout_keys1) assert_true(sapling_address0 not in sapling_keys1) + # import wallet to node 1 + self.nodes[1].z_importwallet(dump_path0) + + # node 1 should now have the keys + dump_path1 = self.nodes[1].z_exportwallet('walletdumpafter') + (t_keys1, sprout_keys1, sapling_keys1) = parse_wallet_file(dump_path1) + + assert_true(sprout_address0 in sprout_keys1) + assert_true(sapling_address0 in sapling_keys1) + # Helper functions def parse_wallet_file(dump_path): file_lines = open(dump_path, "r").readlines() diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 9dc7f69fc..42023de4a 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -297,24 +297,16 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys // Let's see if the address is a valid Zcash spending key if (fImportZKeys) { auto spendingkey = DecodeSpendingKey(vstr[0]); + int64_t nTime = DecodeDumpTime(vstr[1]); if (IsValidSpendingKey(spendingkey)) { - // TODO: Add Sapling support. For now, ensure we can freely convert. - assert(boost::get(&spendingkey) != nullptr); - auto key = boost::get(spendingkey); - auto addr = key.address(); - if (pwalletMain->HaveSproutSpendingKey(addr)) { - LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", EncodePaymentAddress(addr)); - continue; - } - int64_t nTime = DecodeDumpTime(vstr[1]); - LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr)); - if (!pwalletMain->AddSproutZKey(key)) { + auto addResult = boost::apply_visitor( + AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus(), nTime, true), spendingkey); + if (addResult == KeyAlreadyExists){ + LogPrint("zrpc", "Skipping import of zaddr (key already present)\n"); + } else if (addResult == KeyNotAdded) { // Something went wrong fGood = false; - continue; } - // Successfully imported zaddr. Now import the metadata. - pwalletMain->mapSproutZKeyMetadata[addr].nCreateTime = nTime; continue; } else { LogPrint("zrpc", "Importing detected an error: invalid spending key. Trying as a transparent key...\n"); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e4695b301..7fd20d69b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4570,12 +4570,14 @@ boost::optional GetSpendingKeyForPaymentAddress::operator } SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const { - auto addr = sk.address(); - // Don't throw error in case a key is already there + auto addr = sk.address(); + if (log){ + LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr)); + } if (m_wallet->HaveSproutSpendingKey(addr)) { return KeyAlreadyExists; } else if (m_wallet-> AddSproutZKey(sk)) { - m_wallet->mapSproutZKeyMetadata[addr].nCreateTime = 1; + m_wallet->mapSproutZKeyMetadata[addr].nCreateTime = nTime; return KeyAdded; } else { return KeyNotAdded; @@ -4587,6 +4589,9 @@ SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingE auto ivk = fvk.in_viewing_key(); auto addr = sk.DefaultAddress(); { + if (log){ + LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr)); + } // Don't throw error in case a key is already there if (m_wallet->HaveSaplingSpendingKey(fvk)) { return KeyAlreadyExists; @@ -4597,10 +4602,10 @@ SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingE // Sapling addresses can't have been used in transactions prior to activation. if (params.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight == Consensus::NetworkUpgrade::ALWAYS_ACTIVE) { - m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = 1; + m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = nTime; } else { - // Friday, 26 October 2018 00:00:00 GMT - definitely before Sapling activates - m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = 1540512000; + // 154051200 seconds from epoch is Friday, 26 October 2018 00:00:00 GMT - definitely before Sapling activates + m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = std::max((int64_t) 154051200, nTime); } return KeyAdded; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 0032138e1..5b2d6731d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1387,9 +1387,13 @@ class AddSpendingKeyToWallet : public boost::static_visitor