Persist Sapling key material in the wallet to disk
This commit is contained in:
parent
1b79de781c
commit
2fcf06077f
|
@ -23,6 +23,7 @@ testScripts=(
|
|||
'wallet_mergetoaddress.py'
|
||||
'wallet.py'
|
||||
'wallet_overwintertx.py'
|
||||
'wallet_persistence.py'
|
||||
'wallet_nullifiers.py'
|
||||
'wallet_1941.py'
|
||||
'wallet_addresses.py'
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2018 The Zcash developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# 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, stop_nodes, \
|
||||
wait_bitcoinds
|
||||
|
||||
class WalletPersistenceTest (BitcoinTestFramework):
|
||||
|
||||
def setup_network(self, split=False):
|
||||
self.nodes = start_nodes(1, self.options.tmpdir)
|
||||
self.is_network_split = False
|
||||
self.sync_all()
|
||||
|
||||
def run_test(self):
|
||||
sapling_addr = self.nodes[0].z_getnewaddress('sapling')
|
||||
addresses = self.nodes[0].z_listaddresses()
|
||||
# make sure the node has the addresss
|
||||
assert_true(sapling_addr in addresses, "Should contain address before restart")
|
||||
# restart the nodes
|
||||
stop_nodes(self.nodes)
|
||||
wait_bitcoinds()
|
||||
self.nodes = self.setup_nodes()
|
||||
addresses = self.nodes[0].z_listaddresses()
|
||||
# make sure we still have the address after restarting
|
||||
assert_true(sapling_addr in addresses, "Should contain address after restart")
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletPersistenceTest().main()
|
|
@ -166,7 +166,10 @@ bool CWallet::AddSaplingZKey(
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO: Persist to disk
|
||||
if (!IsCrypted()) {
|
||||
auto ivk = sk.expsk.full_viewing_key().in_viewing_key();
|
||||
return CWalletDB(strWalletFile).WriteSaplingZKey(ivk, sk, mapSaplingZKeyMetadata[ivk]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -302,7 +305,16 @@ bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingExtendedFullVi
|
|||
if (!fFileBacked)
|
||||
return true;
|
||||
{
|
||||
// TODO: Sapling - Write to disk
|
||||
LOCK(cs_wallet);
|
||||
if (pwalletdbEncryption) {
|
||||
return pwalletdbEncryption->WriteCryptedSaplingZKey(extfvk,
|
||||
vchCryptedSecret,
|
||||
mapSaplingZKeyMetadata[extfvk.fvk.in_viewing_key()]);
|
||||
} else {
|
||||
return CWalletDB(strWalletFile).WriteCryptedSaplingZKey(extfvk,
|
||||
vchCryptedSecret,
|
||||
mapSaplingZKeyMetadata[extfvk.fvk.in_viewing_key()]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -334,6 +346,25 @@ bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const
|
|||
return CCryptoKeyStore::AddCryptedSproutSpendingKey(addr, rk, vchCryptedSecret);
|
||||
}
|
||||
|
||||
bool CWallet::LoadCryptedSaplingZKey(
|
||||
const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
||||
const std::vector<unsigned char> &vchCryptedSecret)
|
||||
{
|
||||
return CCryptoKeyStore::AddCryptedSaplingSpendingKey(extfvk, vchCryptedSecret, extfvk.DefaultAddress());
|
||||
}
|
||||
|
||||
bool CWallet::LoadSaplingZKeyMetadata(const libzcash::SaplingIncomingViewingKey &ivk, const CKeyMetadata &meta)
|
||||
{
|
||||
AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
|
||||
mapSaplingZKeyMetadata[ivk] = meta;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::LoadSaplingZKey(const libzcash::SaplingExtendedSpendingKey &key)
|
||||
{
|
||||
return CCryptoKeyStore::AddSaplingSpendingKey(key, key.DefaultAddress());
|
||||
}
|
||||
|
||||
bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key)
|
||||
{
|
||||
return CCryptoKeyStore::AddSproutSpendingKey(key);
|
||||
|
|
|
@ -1063,6 +1063,13 @@ public:
|
|||
const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
||||
const std::vector<unsigned char> &vchCryptedSecret,
|
||||
const libzcash::SaplingPaymentAddress &defaultAddr);
|
||||
//! Adds spending key to the store, without saving it to disk (used by LoadWallet)
|
||||
bool LoadSaplingZKey(const libzcash::SaplingExtendedSpendingKey &key);
|
||||
//! Load spending key metadata (used by LoadWallet)
|
||||
bool LoadSaplingZKeyMetadata(const libzcash::SaplingIncomingViewingKey &ivk, const CKeyMetadata &meta);
|
||||
//! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet)
|
||||
bool LoadCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
||||
const std::vector<unsigned char> &vchCryptedSecret);
|
||||
|
||||
/**
|
||||
* Increment the next transaction order id
|
||||
|
|
|
@ -125,6 +125,28 @@ bool CWalletDB::WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CWalletDB::WriteCryptedSaplingZKey(
|
||||
const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
||||
const std::vector<unsigned char>& vchCryptedSecret,
|
||||
const CKeyMetadata &keyMeta)
|
||||
{
|
||||
const bool fEraseUnencryptedKey = true;
|
||||
nWalletDBUpdated++;
|
||||
auto ivk = extfvk.fvk.in_viewing_key();
|
||||
|
||||
if (!Write(std::make_pair(std::string("sapzkeymeta"), ivk), keyMeta))
|
||||
return false;
|
||||
|
||||
if (!Write(std::make_pair(std::string("csapzkey"), ivk), std::make_pair(extfvk, vchCryptedSecret), false))
|
||||
return false;
|
||||
|
||||
if (fEraseUnencryptedKey)
|
||||
{
|
||||
Erase(std::make_pair(std::string("sapzkey"), ivk));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
|
@ -141,6 +163,17 @@ bool CWalletDB::WriteZKey(const libzcash::SproutPaymentAddress& addr, const libz
|
|||
// pair is: tuple_key("zkey", paymentaddress) --> secretkey
|
||||
return Write(std::make_pair(std::string("zkey"), addr), key, false);
|
||||
}
|
||||
bool CWalletDB::WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk,
|
||||
const libzcash::SaplingExtendedSpendingKey &key,
|
||||
const CKeyMetadata &keyMeta)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
|
||||
if (!Write(std::make_pair(std::string("sapzkeymeta"), ivk), keyMeta))
|
||||
return false;
|
||||
|
||||
return Write(std::make_pair(std::string("sapzkey"), ivk), key, false);
|
||||
}
|
||||
|
||||
bool CWalletDB::WriteSproutViewingKey(const libzcash::SproutViewingKey &vk)
|
||||
{
|
||||
|
@ -511,6 +544,23 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||
|
||||
wss.nZKeys++;
|
||||
}
|
||||
else if (strType == "sapzkey")
|
||||
{
|
||||
libzcash::SaplingIncomingViewingKey ivk;
|
||||
ssKey >> ivk;
|
||||
libzcash::SaplingExtendedSpendingKey key;
|
||||
ssValue >> key;
|
||||
|
||||
if (!pwallet->LoadSaplingZKey(key))
|
||||
{
|
||||
strErr = "Error reading wallet database: LoadSaplingZKey failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
//add checks for integrity
|
||||
wss.nZKeys++;
|
||||
}
|
||||
|
||||
else if (strType == "key" || strType == "wkey")
|
||||
{
|
||||
CPubKey vchPubKey;
|
||||
|
@ -624,6 +674,23 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||
}
|
||||
wss.fIsEncrypted = true;
|
||||
}
|
||||
else if (strType == "csapzkey")
|
||||
{
|
||||
libzcash::SaplingIncomingViewingKey ivk;
|
||||
ssKey >> ivk;
|
||||
libzcash::SaplingExtendedFullViewingKey extfvk;
|
||||
ssValue >> extfvk;
|
||||
vector<unsigned char> vchCryptedSecret;
|
||||
ssValue >> vchCryptedSecret;
|
||||
wss.nCKeys++;
|
||||
|
||||
if (!pwallet->LoadCryptedSaplingZKey(extfvk, vchCryptedSecret))
|
||||
{
|
||||
strErr = "Error reading wallet database: LoadCryptedSaplingZKey failed";
|
||||
return false;
|
||||
}
|
||||
wss.fIsEncrypted = true;
|
||||
}
|
||||
else if (strType == "keymeta")
|
||||
{
|
||||
CPubKey vchPubKey;
|
||||
|
@ -651,6 +718,17 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||
|
||||
// ignore earliest key creation time as taddr will exist before any zaddr
|
||||
}
|
||||
else if (strType == "sapzkeymeta")
|
||||
{
|
||||
libzcash::SaplingIncomingViewingKey ivk;
|
||||
ssKey >> ivk;
|
||||
CKeyMetadata keyMeta;
|
||||
ssValue >> keyMeta;
|
||||
|
||||
wss.nZKeyMeta++;
|
||||
|
||||
pwallet->LoadSaplingZKeyMetadata(ivk, keyMeta);
|
||||
}
|
||||
else if (strType == "defaultkey")
|
||||
{
|
||||
ssValue >> pwallet->vchDefaultKey;
|
||||
|
@ -736,7 +814,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||
ssValue >> vchCryptedSecret;
|
||||
if (!pwallet->LoadCryptedHDSeed(seedFp, vchCryptedSecret))
|
||||
{
|
||||
strErr = "Error reading wallet database: LoadCryptedSeed failed";
|
||||
strErr = "Error reading wallet database: LoadCryptedHDSeed failed";
|
||||
return false;
|
||||
}
|
||||
wss.fIsEncrypted = true;
|
||||
|
@ -759,6 +837,7 @@ static bool IsKeyType(string strType)
|
|||
return (strType== "key" || strType == "wkey" ||
|
||||
strType == "hdseed" || strType == "chdseed" ||
|
||||
strType == "zkey" || strType == "czkey" ||
|
||||
strType == "sapzkey" || strType == "csapzkey" ||
|
||||
strType == "vkey" ||
|
||||
strType == "mkey" || strType == "ckey");
|
||||
}
|
||||
|
|
|
@ -184,10 +184,16 @@ public:
|
|||
|
||||
/// Write spending key to wallet database, where key is payment address and value is spending key.
|
||||
bool WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta);
|
||||
bool WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk,
|
||||
const libzcash::SaplingExtendedSpendingKey &key,
|
||||
const CKeyMetadata &keyMeta);
|
||||
bool WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr,
|
||||
const libzcash::ReceivingKey & rk,
|
||||
const std::vector<unsigned char>& vchCryptedSecret,
|
||||
const CKeyMetadata &keyMeta);
|
||||
bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
||||
const std::vector<unsigned char>& vchCryptedSecret,
|
||||
const CKeyMetadata &keyMeta);
|
||||
|
||||
bool WriteSproutViewingKey(const libzcash::SproutViewingKey &vk);
|
||||
bool EraseSproutViewingKey(const libzcash::SproutViewingKey &vk);
|
||||
|
|
Loading…
Reference in New Issue