Browse Source

Add sapling support to z_importwallet

pull/4/head
Eirik Ogilvie-Wigley 6 years ago
parent
commit
9bcf90e2de
  1. 20
      qa/rpc-tests/wallet_import_export.py
  2. 20
      src/wallet/rpcdump.cpp
  3. 17
      src/wallet/wallet.cpp
  4. 6
      src/wallet/wallet.h

20
qa/rpc-tests/wallet_import_export.py

@ -16,19 +16,29 @@ class WalletImportExportTest (BitcoinTestFramework):
sapling_address0 = self.nodes[0].z_getnewaddress('sapling') sapling_address0 = self.nodes[0].z_getnewaddress('sapling')
# node 0 should have the keys # node 0 should have the keys
dump_path = self.nodes[0].z_exportwallet('walletdump') dump_path0 = self.nodes[0].z_exportwallet('walletdump')
(t_keys0, sprout_keys0, sapling_keys0) = parse_wallet_file(dump_path) (t_keys0, sprout_keys0, sapling_keys0) = parse_wallet_file(dump_path0)
assert_true(sprout_address0 in sprout_keys0) assert_true(sprout_address0 in sprout_keys0)
assert_true(sapling_address0 in sapling_keys0) assert_true(sapling_address0 in sapling_keys0)
# node 1 should not # node 1 should not have the keys
dump_path = self.nodes[1].z_exportwallet('walletdump') dump_path1 = self.nodes[1].z_exportwallet('walletdumpbefore')
(t_keys1, sprout_keys1, sapling_keys1) = parse_wallet_file(dump_path) (t_keys1, sprout_keys1, sapling_keys1) = parse_wallet_file(dump_path1)
assert_true(sprout_address0 not in sprout_keys1) assert_true(sprout_address0 not in sprout_keys1)
assert_true(sapling_address0 not in sapling_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 # Helper functions
def parse_wallet_file(dump_path): def parse_wallet_file(dump_path):
file_lines = open(dump_path, "r").readlines() file_lines = open(dump_path, "r").readlines()

20
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 // Let's see if the address is a valid Zcash spending key
if (fImportZKeys) { if (fImportZKeys) {
auto spendingkey = DecodeSpendingKey(vstr[0]); auto spendingkey = DecodeSpendingKey(vstr[0]);
int64_t nTime = DecodeDumpTime(vstr[1]);
if (IsValidSpendingKey(spendingkey)) { if (IsValidSpendingKey(spendingkey)) {
// TODO: Add Sapling support. For now, ensure we can freely convert. auto addResult = boost::apply_visitor(
assert(boost::get<libzcash::SproutSpendingKey>(&spendingkey) != nullptr); AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus(), nTime, true), spendingkey);
auto key = boost::get<libzcash::SproutSpendingKey>(spendingkey); if (addResult == KeyAlreadyExists){
auto addr = key.address(); LogPrint("zrpc", "Skipping import of zaddr (key already present)\n");
if (pwalletMain->HaveSproutSpendingKey(addr)) { } else if (addResult == KeyNotAdded) {
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)) {
// Something went wrong // Something went wrong
fGood = false; fGood = false;
continue;
} }
// Successfully imported zaddr. Now import the metadata.
pwalletMain->mapSproutZKeyMetadata[addr].nCreateTime = nTime;
continue; continue;
} else { } else {
LogPrint("zrpc", "Importing detected an error: invalid spending key. Trying as a transparent key...\n"); LogPrint("zrpc", "Importing detected an error: invalid spending key. Trying as a transparent key...\n");

17
src/wallet/wallet.cpp

@ -4570,12 +4570,14 @@ boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator
} }
SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const { SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const {
auto addr = sk.address(); auto addr = sk.address();
// Don't throw error in case a key is already there if (log){
LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr));
}
if (m_wallet->HaveSproutSpendingKey(addr)) { if (m_wallet->HaveSproutSpendingKey(addr)) {
return KeyAlreadyExists; return KeyAlreadyExists;
} else if (m_wallet-> AddSproutZKey(sk)) { } else if (m_wallet-> AddSproutZKey(sk)) {
m_wallet->mapSproutZKeyMetadata[addr].nCreateTime = 1; m_wallet->mapSproutZKeyMetadata[addr].nCreateTime = nTime;
return KeyAdded; return KeyAdded;
} else { } else {
return KeyNotAdded; return KeyNotAdded;
@ -4587,6 +4589,9 @@ SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingE
auto ivk = fvk.in_viewing_key(); auto ivk = fvk.in_viewing_key();
auto addr = sk.DefaultAddress(); 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 // Don't throw error in case a key is already there
if (m_wallet->HaveSaplingSpendingKey(fvk)) { if (m_wallet->HaveSaplingSpendingKey(fvk)) {
return KeyAlreadyExists; return KeyAlreadyExists;
@ -4597,10 +4602,10 @@ SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingE
// Sapling addresses can't have been used in transactions prior to activation. // Sapling addresses can't have been used in transactions prior to activation.
if (params.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight == Consensus::NetworkUpgrade::ALWAYS_ACTIVE) { if (params.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight == Consensus::NetworkUpgrade::ALWAYS_ACTIVE) {
m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = 1; m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = nTime;
} else { } else {
// Friday, 26 October 2018 00:00:00 GMT - definitely before Sapling activates // 154051200 seconds from epoch is Friday, 26 October 2018 00:00:00 GMT - definitely before Sapling activates
m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = 1540512000; m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = std::max((int64_t) 154051200, nTime);
} }
return KeyAdded; return KeyAdded;

6
src/wallet/wallet.h

@ -1387,9 +1387,13 @@ class AddSpendingKeyToWallet : public boost::static_visitor<SpendingKeyAddResult
private: private:
CWallet *m_wallet; CWallet *m_wallet;
const Consensus::Params &params; const Consensus::Params &params;
int64_t nTime;
bool log;
public: public:
AddSpendingKeyToWallet(CWallet *wallet, const Consensus::Params &params) : AddSpendingKeyToWallet(CWallet *wallet, const Consensus::Params &params) :
m_wallet(wallet), params(params) {} m_wallet(wallet), params(params), nTime(1), log(false) {}
AddSpendingKeyToWallet(CWallet *wallet, const Consensus::Params &params, int64_t _nTime, bool _log) :
m_wallet(wallet), params(params), nTime(_nTime), log(_log) {}
SpendingKeyAddResult operator()(const libzcash::SproutSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::SproutSpendingKey &sk) const;
SpendingKeyAddResult operator()(const libzcash::SaplingExtendedSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::SaplingExtendedSpendingKey &sk) const;

Loading…
Cancel
Save