Export zip32 metadata with sapling keys

This commit is contained in:
Eirik Ogilvie-Wigley 2018-09-14 17:27:20 -06:00
parent ae807af413
commit 2fe39561ec
4 changed files with 37 additions and 12 deletions

View File

@ -4,7 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_true, start_nodes
from test_framework.util import assert_equal, assert_true, start_nodes
class WalletImportExportTest (BitcoinTestFramework):
def setup_network(self, split=False):
@ -18,6 +18,9 @@ class WalletImportExportTest (BitcoinTestFramework):
# node 0 should have the keys
dump_path0 = self.nodes[0].z_exportwallet('walletdump')
(t_keys0, sprout_keys0, sapling_keys0) = parse_wallet_file(dump_path0)
for sapling_key0 in sapling_keys0.splitlines():
assert_equal(4, len(sapling_key0.split(' #')[0].split()), "Should have 4 parameters before ' #'")
assert_true(sprout_address0 in sprout_keys0)
assert_true(sapling_address0 in sapling_keys0)
@ -39,6 +42,10 @@ class WalletImportExportTest (BitcoinTestFramework):
assert_true(sprout_address0 in sprout_keys1)
assert_true(sapling_address0 in sapling_keys1)
# make sure we have perserved the metadata
for sapling_key0 in sapling_keys0.splitlines():
assert_true(sapling_key0 in sapling_keys1)
# Helper functions
def parse_wallet_file(dump_path):
file_lines = open(dump_path, "r").readlines()
@ -60,7 +67,7 @@ def parse_wallet_file_lines(file_lines, i):
while i < len(file_lines) and not (file_lines[i] == '\n' or file_lines[i].startswith("#")):
keys.append(file_lines[i])
i += 1
return ("".join(keys), i)
return ("\n".join(keys), i)
if __name__ == '__main__':
WalletImportExportTest().main()

View File

@ -298,9 +298,11 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
if (fImportZKeys) {
auto spendingkey = DecodeSpendingKey(vstr[0]);
int64_t nTime = DecodeDumpTime(vstr[1]);
boost::optional<std::string> hdKeypath = (vstr.size() > 2) ? boost::optional<std::string>(vstr[2]) : boost::none;
boost::optional<std::string> seedFpStr = (vstr.size() > 3) ? boost::optional<std::string>(vstr[3]) : boost::none;
if (IsValidSpendingKey(spendingkey)) {
auto addResult = boost::apply_visitor(
AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus(), nTime, true), spendingkey);
AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus(), nTime, hdKeypath, seedFpStr, true), spendingkey);
if (addResult == KeyAlreadyExists){
LogPrint("zrpc", "Skipping import of zaddr (key already present)\n");
} else if (addResult == KeyNotAdded) {
@ -548,8 +550,9 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys)
libzcash::SaplingExtendedSpendingKey extsk;
if (pwalletMain->GetSaplingExtendedSpendingKey(addr, extsk)) {
auto ivk = extsk.expsk.full_viewing_key().in_viewing_key();
std::string strTime = EncodeDumpTime(pwalletMain->mapSaplingZKeyMetadata[ivk].nCreateTime);
file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(extsk), strTime, EncodePaymentAddress(addr));
CKeyMetadata keyMeta = pwalletMain->mapSaplingZKeyMetadata[ivk];
std::string strTime = EncodeDumpTime(keyMeta.nCreateTime);
file << strprintf("%s %s %s %s # zaddr=%s\n", EncodeSpendingKey(extsk), strTime, keyMeta.hdKeypath, keyMeta.seedFp.GetHex(), EncodePaymentAddress(addr));
}
}
file << "\n";
@ -633,8 +636,7 @@ UniValue z_importkey(const UniValue& params, bool fHelp)
}
// Sapling support
auto addResult = boost::apply_visitor(
AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus()), spendingkey);
auto addResult = boost::apply_visitor(AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus()), spendingkey);
if (addResult == KeyAlreadyExists && fIgnoreExistingKey) {
return NullUniValue;
}

View File

@ -4573,7 +4573,7 @@ boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator
}
SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const {
auto addr = sk.address();
auto addr = sk.address();
if (log){
LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr));
}
@ -4610,7 +4610,14 @@ SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingE
// 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);
}
if (hdKeypath) {
m_wallet->mapSaplingZKeyMetadata[ivk].hdKeypath = hdKeypath.get();
}
if (seedFpStr) {
uint256 seedFp;
seedFp.SetHex(seedFpStr.get());
m_wallet->mapSaplingZKeyMetadata[ivk].seedFp = seedFp;
}
return KeyAdded;
}
}

View File

@ -1388,12 +1388,21 @@ private:
CWallet *m_wallet;
const Consensus::Params &params;
int64_t nTime;
boost::optional<std::string> hdKeypath; // currently sapling only
boost::optional<std::string> seedFpStr; // currently sapling only
bool log;
public:
AddSpendingKeyToWallet(CWallet *wallet, const Consensus::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) {}
m_wallet(wallet), params(params), nTime(1), hdKeypath(boost::none), seedFpStr(boost::none), log(false) {}
AddSpendingKeyToWallet(
CWallet *wallet,
const Consensus::Params &params,
int64_t _nTime,
boost::optional<std::string> _hdKeypath,
boost::optional<std::string> _seedFp,
bool _log
) : m_wallet(wallet), params(params), nTime(_nTime), hdKeypath(_hdKeypath), seedFpStr(_seedFp), log(_log) {}
SpendingKeyAddResult operator()(const libzcash::SproutSpendingKey &sk) const;
SpendingKeyAddResult operator()(const libzcash::SaplingExtendedSpendingKey &sk) const;