Auto merge of #3396 - arcalinea:3389_sapling_crypter, r=str4d

Update CCryptoKeyStore with Sapling support

Sapling crypter overrides for various `CCryptoKeyStore` functions such as:
- `HaveSaplingSpendingKey()`
- `GetSaplingSpendingKey()`

Also includes some changes to prepare for diversified addresses and ZIP 32.

Closes #3389
This commit is contained in:
Homu
2018-08-03 09:48:22 -07:00
20 changed files with 456 additions and 299 deletions

View File

@@ -72,22 +72,22 @@ TEST(keystore_tests, store_and_retrieve_spending_key) {
libzcash::SproutSpendingKey skOut; libzcash::SproutSpendingKey skOut;
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
keyStore.GetPaymentAddresses(addrs); keyStore.GetSproutPaymentAddresses(addrs);
EXPECT_EQ(0, addrs.size()); EXPECT_EQ(0, addrs.size());
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
auto addr = sk.address(); auto addr = sk.address();
// Sanity-check: we can't get a key we haven't added // Sanity-check: we can't get a key we haven't added
EXPECT_FALSE(keyStore.HaveSpendingKey(addr)); EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr));
EXPECT_FALSE(keyStore.GetSpendingKey(addr, skOut)); EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut));
keyStore.AddSpendingKey(sk); keyStore.AddSproutSpendingKey(sk);
EXPECT_TRUE(keyStore.HaveSpendingKey(addr)); EXPECT_TRUE(keyStore.HaveSproutSpendingKey(addr));
EXPECT_TRUE(keyStore.GetSpendingKey(addr, skOut)); EXPECT_TRUE(keyStore.GetSproutSpendingKey(addr, skOut));
EXPECT_EQ(sk, skOut); EXPECT_EQ(sk, skOut);
keyStore.GetPaymentAddresses(addrs); keyStore.GetSproutPaymentAddresses(addrs);
EXPECT_EQ(1, addrs.size()); EXPECT_EQ(1, addrs.size());
EXPECT_EQ(1, addrs.count(addr)); EXPECT_EQ(1, addrs.count(addr));
} }
@@ -101,7 +101,7 @@ TEST(keystore_tests, store_and_retrieve_note_decryptor) {
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
keyStore.AddSpendingKey(sk); keyStore.AddSproutSpendingKey(sk);
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut));
EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut);
} }
@@ -117,27 +117,27 @@ TEST(keystore_tests, StoreAndRetrieveViewingKey) {
auto addr = sk.address(); auto addr = sk.address();
// Sanity-check: we can't get a viewing key we haven't added // Sanity-check: we can't get a viewing key we haven't added
EXPECT_FALSE(keyStore.HaveViewingKey(addr)); EXPECT_FALSE(keyStore.HaveSproutViewingKey(addr));
EXPECT_FALSE(keyStore.GetViewingKey(addr, vkOut)); EXPECT_FALSE(keyStore.GetSproutViewingKey(addr, vkOut));
// and we shouldn't have a spending key or decryptor either // and we shouldn't have a spending key or decryptor either
EXPECT_FALSE(keyStore.HaveSpendingKey(addr)); EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr));
EXPECT_FALSE(keyStore.GetSpendingKey(addr, skOut)); EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut));
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
// and we can't find it in our list of addresses // and we can't find it in our list of addresses
std::set<libzcash::SproutPaymentAddress> addresses; std::set<libzcash::SproutPaymentAddress> addresses;
keyStore.GetPaymentAddresses(addresses); keyStore.GetSproutPaymentAddresses(addresses);
EXPECT_FALSE(addresses.count(addr)); EXPECT_FALSE(addresses.count(addr));
keyStore.AddViewingKey(vk); keyStore.AddSproutViewingKey(vk);
EXPECT_TRUE(keyStore.HaveViewingKey(addr)); EXPECT_TRUE(keyStore.HaveSproutViewingKey(addr));
EXPECT_TRUE(keyStore.GetViewingKey(addr, vkOut)); EXPECT_TRUE(keyStore.GetSproutViewingKey(addr, vkOut));
EXPECT_EQ(vk, vkOut); EXPECT_EQ(vk, vkOut);
// We should still not have the spending key... // We should still not have the spending key...
EXPECT_FALSE(keyStore.HaveSpendingKey(addr)); EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr));
EXPECT_FALSE(keyStore.GetSpendingKey(addr, skOut)); EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut));
// ... but we should have a decryptor // ... but we should have a decryptor
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut));
@@ -145,16 +145,16 @@ TEST(keystore_tests, StoreAndRetrieveViewingKey) {
// ... and we should find it in our list of addresses // ... and we should find it in our list of addresses
addresses.clear(); addresses.clear();
keyStore.GetPaymentAddresses(addresses); keyStore.GetSproutPaymentAddresses(addresses);
EXPECT_TRUE(addresses.count(addr)); EXPECT_TRUE(addresses.count(addr));
keyStore.RemoveViewingKey(vk); keyStore.RemoveSproutViewingKey(vk);
EXPECT_FALSE(keyStore.HaveViewingKey(addr)); EXPECT_FALSE(keyStore.HaveSproutViewingKey(addr));
EXPECT_FALSE(keyStore.GetViewingKey(addr, vkOut)); EXPECT_FALSE(keyStore.GetSproutViewingKey(addr, vkOut));
EXPECT_FALSE(keyStore.HaveSpendingKey(addr)); EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr));
EXPECT_FALSE(keyStore.GetSpendingKey(addr, skOut)); EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut));
addresses.clear(); addresses.clear();
keyStore.GetPaymentAddresses(addresses); keyStore.GetSproutPaymentAddresses(addresses);
EXPECT_FALSE(addresses.count(addr)); EXPECT_FALSE(addresses.count(addr));
// We still have a decryptor because those are cached in memory // We still have a decryptor because those are cached in memory
@@ -185,8 +185,15 @@ TEST(keystore_tests, StoreAndRetrieveSaplingSpendingKey) {
EXPECT_FALSE(keyStore.HaveSaplingIncomingViewingKey(addr)); EXPECT_FALSE(keyStore.HaveSaplingIncomingViewingKey(addr));
EXPECT_FALSE(keyStore.GetSaplingIncomingViewingKey(addr, ivkOut)); EXPECT_FALSE(keyStore.GetSaplingIncomingViewingKey(addr, ivkOut));
// If we don't specify the default address, that mapping isn't created
keyStore.AddSaplingSpendingKey(sk); keyStore.AddSaplingSpendingKey(sk);
EXPECT_TRUE(keyStore.HaveSaplingSpendingKey(fvk)); EXPECT_TRUE(keyStore.HaveSaplingSpendingKey(fvk));
EXPECT_TRUE(keyStore.HaveSaplingFullViewingKey(ivk));
EXPECT_FALSE(keyStore.HaveSaplingIncomingViewingKey(addr));
// When we specify the default address, we get the full mapping
keyStore.AddSaplingSpendingKey(sk, addr);
EXPECT_TRUE(keyStore.HaveSaplingSpendingKey(fvk));
EXPECT_TRUE(keyStore.GetSaplingSpendingKey(fvk, skOut)); EXPECT_TRUE(keyStore.GetSaplingSpendingKey(fvk, skOut));
EXPECT_TRUE(keyStore.HaveSaplingFullViewingKey(ivk)); EXPECT_TRUE(keyStore.HaveSaplingFullViewingKey(ivk));
EXPECT_TRUE(keyStore.GetSaplingFullViewingKey(ivk, fvkOut)); EXPECT_TRUE(keyStore.GetSaplingFullViewingKey(ivk, fvkOut));
@@ -218,16 +225,16 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) {
auto addr = sk.address(); auto addr = sk.address();
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
keyStore.AddSpendingKey(sk); keyStore.AddSproutSpendingKey(sk);
ASSERT_TRUE(keyStore.HaveSpendingKey(addr)); ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr));
ASSERT_TRUE(keyStore.GetSpendingKey(addr, keyOut)); ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr, keyOut));
ASSERT_EQ(sk, keyOut); ASSERT_EQ(sk, keyOut);
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut));
EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut);
ASSERT_TRUE(keyStore.EncryptKeys(vMasterKey)); ASSERT_TRUE(keyStore.EncryptKeys(vMasterKey));
ASSERT_TRUE(keyStore.HaveSpendingKey(addr)); ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr));
ASSERT_FALSE(keyStore.GetSpendingKey(addr, keyOut)); ASSERT_FALSE(keyStore.GetSproutSpendingKey(addr, keyOut));
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut));
EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut);
@@ -243,10 +250,10 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) {
// Unlocking with vMasterKey should succeed // Unlocking with vMasterKey should succeed
ASSERT_TRUE(keyStore.Unlock(vMasterKey)); ASSERT_TRUE(keyStore.Unlock(vMasterKey));
ASSERT_TRUE(keyStore.GetSpendingKey(addr, keyOut)); ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr, keyOut));
ASSERT_EQ(sk, keyOut); ASSERT_EQ(sk, keyOut);
keyStore.GetPaymentAddresses(addrs); keyStore.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(1, addrs.size()); ASSERT_EQ(1, addrs.size());
ASSERT_EQ(1, addrs.count(addr)); ASSERT_EQ(1, addrs.count(addr));
@@ -255,26 +262,26 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) {
auto addr2 = sk2.address(); auto addr2 = sk2.address();
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr2, decOut)); EXPECT_FALSE(keyStore.GetNoteDecryptor(addr2, decOut));
keyStore.AddSpendingKey(sk2); keyStore.AddSproutSpendingKey(sk2);
ASSERT_TRUE(keyStore.HaveSpendingKey(addr2)); ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr2));
ASSERT_TRUE(keyStore.GetSpendingKey(addr2, keyOut)); ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr2, keyOut));
ASSERT_EQ(sk2, keyOut); ASSERT_EQ(sk2, keyOut);
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut)); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut));
EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut); EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut);
ASSERT_TRUE(keyStore.Lock()); ASSERT_TRUE(keyStore.Lock());
ASSERT_TRUE(keyStore.HaveSpendingKey(addr2)); ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr2));
ASSERT_FALSE(keyStore.GetSpendingKey(addr2, keyOut)); ASSERT_FALSE(keyStore.GetSproutSpendingKey(addr2, keyOut));
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut)); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut));
EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut); EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut);
ASSERT_TRUE(keyStore.Unlock(vMasterKey)); ASSERT_TRUE(keyStore.Unlock(vMasterKey));
ASSERT_TRUE(keyStore.GetSpendingKey(addr2, keyOut)); ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr2, keyOut));
ASSERT_EQ(sk2, keyOut); ASSERT_EQ(sk2, keyOut);
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut)); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut));
EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut); EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut);
keyStore.GetPaymentAddresses(addrs); keyStore.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(2, addrs.size()); ASSERT_EQ(2, addrs.size());
ASSERT_EQ(1, addrs.count(addr)); ASSERT_EQ(1, addrs.count(addr));
ASSERT_EQ(1, addrs.count(addr2)); ASSERT_EQ(1, addrs.count(addr2));

View File

@@ -275,7 +275,7 @@ libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
std::vector<unsigned char> data; std::vector<unsigned char> data;
if (DecodeBase58Check(str, data)) { if (DecodeBase58Check(str, data)) {
const std::vector<unsigned char>& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); const std::vector<unsigned char>& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
if ((data.size() == libzcash::SerializedPaymentAddressSize + zaddr_prefix.size()) && if ((data.size() == libzcash::SerializedSproutPaymentAddressSize + zaddr_prefix.size()) &&
std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) { std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) {
CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end()); CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end());
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
@@ -314,7 +314,7 @@ libzcash::ViewingKey DecodeViewingKey(const std::string& str)
std::vector<unsigned char> data; std::vector<unsigned char> data;
if (DecodeBase58Check(str, data)) { if (DecodeBase58Check(str, data)) {
const std::vector<unsigned char>& vk_prefix = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY); const std::vector<unsigned char>& vk_prefix = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY);
if ((data.size() == libzcash::SerializedViewingKeySize + vk_prefix.size()) && if ((data.size() == libzcash::SerializedSproutViewingKeySize + vk_prefix.size()) &&
std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) { std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) {
CSerializeData serialized(data.begin() + vk_prefix.size(), data.end()); CSerializeData serialized(data.begin() + vk_prefix.size(), data.end());
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
@@ -339,7 +339,7 @@ libzcash::SpendingKey DecodeSpendingKey(const std::string& str)
std::vector<unsigned char> data; std::vector<unsigned char> data;
if (DecodeBase58Check(str, data)) { if (DecodeBase58Check(str, data)) {
const std::vector<unsigned char>& zkey_prefix = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY); const std::vector<unsigned char>& zkey_prefix = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY);
if ((data.size() == libzcash::SerializedSpendingKeySize + zkey_prefix.size()) && if ((data.size() == libzcash::SerializedSproutSpendingKeySize + zkey_prefix.size()) &&
std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) { std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) {
CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end()); CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end());
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);

View File

@@ -84,67 +84,69 @@ bool CBasicKeyStore::HaveWatchOnly() const
return (!setWatchOnly.empty()); return (!setWatchOnly.empty());
} }
bool CBasicKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk) bool CBasicKeyStore::AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk)
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
auto address = sk.address(); auto address = sk.address();
mapSpendingKeys[address] = sk; mapSproutSpendingKeys[address] = sk;
mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(sk.receiving_key()))); mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(sk.receiving_key())));
return true; return true;
} }
//! Sapling //! Sapling
bool CBasicKeyStore::AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk) bool CBasicKeyStore::AddSaplingSpendingKey(
const libzcash::SaplingSpendingKey &sk,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr)
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
auto fvk = sk.full_viewing_key(); auto fvk = sk.full_viewing_key();
// if SaplingFullViewingKey is not in SaplingFullViewingKeyMap, add it // if SaplingFullViewingKey is not in SaplingFullViewingKeyMap, add it
if (!AddSaplingFullViewingKey(fvk)){ if (!AddSaplingFullViewingKey(fvk, defaultAddr)){
return false; return false;
} }
mapSaplingSpendingKeys[fvk] = sk; mapSaplingSpendingKeys[fvk] = sk;
// Add addr -> SaplingIncomingViewing to SaplingIncomingViewingKeyMap
auto ivk = fvk.in_viewing_key();
auto addr = sk.default_address();
mapSaplingIncomingViewingKeys[addr] = ivk;
return true; return true;
} }
bool CBasicKeyStore::AddViewingKey(const libzcash::SproutViewingKey &vk) bool CBasicKeyStore::AddSproutViewingKey(const libzcash::SproutViewingKey &vk)
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
auto address = vk.address(); auto address = vk.address();
mapViewingKeys[address] = vk; mapSproutViewingKeys[address] = vk;
mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(vk.sk_enc))); mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(vk.sk_enc)));
return true; return true;
} }
bool CBasicKeyStore::AddSaplingFullViewingKey(const libzcash::SaplingFullViewingKey &fvk) bool CBasicKeyStore::AddSaplingFullViewingKey(
const libzcash::SaplingFullViewingKey &fvk,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr)
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
auto ivk = fvk.in_viewing_key(); auto ivk = fvk.in_viewing_key();
mapSaplingFullViewingKeys[ivk] = fvk; mapSaplingFullViewingKeys[ivk] = fvk;
//! TODO: Note decryptors for Sapling if (defaultAddr) {
// Add defaultAddr -> SaplingIncomingViewing to SaplingIncomingViewingKeyMap
mapSaplingIncomingViewingKeys[defaultAddr.get()] = ivk;
}
return true; return true;
} }
bool CBasicKeyStore::RemoveViewingKey(const libzcash::SproutViewingKey &vk) bool CBasicKeyStore::RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk)
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
mapViewingKeys.erase(vk.address()); mapSproutViewingKeys.erase(vk.address());
return true; return true;
} }
bool CBasicKeyStore::HaveViewingKey(const libzcash::SproutPaymentAddress &address) const bool CBasicKeyStore::HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
return mapViewingKeys.count(address) > 0; return mapSproutViewingKeys.count(address) > 0;
} }
bool CBasicKeyStore::HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const bool CBasicKeyStore::HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const
@@ -159,12 +161,13 @@ bool CBasicKeyStore::HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymen
return mapSaplingIncomingViewingKeys.count(addr) > 0; return mapSaplingIncomingViewingKeys.count(addr) > 0;
} }
bool CBasicKeyStore::GetViewingKey(const libzcash::SproutPaymentAddress &address, bool CBasicKeyStore::GetSproutViewingKey(
libzcash::SproutViewingKey &vkOut) const const libzcash::SproutPaymentAddress &address,
libzcash::SproutViewingKey &vkOut) const
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
ViewingKeyMap::const_iterator mi = mapViewingKeys.find(address); SproutViewingKeyMap::const_iterator mi = mapSproutViewingKeys.find(address);
if (mi != mapViewingKeys.end()) { if (mi != mapSproutViewingKeys.end()) {
vkOut = mi->second; vkOut = mi->second;
return true; return true;
} }

View File

@@ -49,22 +49,26 @@ public:
virtual bool HaveWatchOnly() const =0; virtual bool HaveWatchOnly() const =0;
//! Add a spending key to the store. //! Add a spending key to the store.
virtual bool AddSpendingKey(const libzcash::SproutSpendingKey &sk) =0; virtual bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk) =0;
//! Check whether a spending key corresponding to a given payment address is present in the store. //! Check whether a spending key corresponding to a given payment address is present in the store.
virtual bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const =0; virtual bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const =0;
virtual bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0; virtual bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0;
virtual void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const =0; virtual void GetSproutPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const =0;
//! Add a Sapling spending key to the store. //! Add a Sapling spending key to the store.
virtual bool AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk) =0; virtual bool AddSaplingSpendingKey(
const libzcash::SaplingSpendingKey &sk,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr = boost::none) =0;
//! Check whether a Sapling spending key corresponding to a given Sapling viewing key is present in the store. //! Check whether a Sapling spending key corresponding to a given Sapling viewing key is present in the store.
virtual bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const =0; virtual bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const =0;
virtual bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingSpendingKey& skOut) const =0; virtual bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingSpendingKey& skOut) const =0;
//! Support for Sapling full viewing keys //! Support for Sapling full viewing keys
virtual bool AddSaplingFullViewingKey(const libzcash::SaplingFullViewingKey &fvk) =0; virtual bool AddSaplingFullViewingKey(
const libzcash::SaplingFullViewingKey &fvk,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr = boost::none) =0;
virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const =0; virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const =0;
virtual bool GetSaplingFullViewingKey( virtual bool GetSaplingFullViewingKey(
const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingIncomingViewingKey &ivk,
@@ -77,18 +81,20 @@ public:
libzcash::SaplingIncomingViewingKey& ivkOut) const =0; libzcash::SaplingIncomingViewingKey& ivkOut) const =0;
virtual void GetSaplingPaymentAddresses(std::set<libzcash::SaplingPaymentAddress> &setAddress) const =0; virtual void GetSaplingPaymentAddresses(std::set<libzcash::SaplingPaymentAddress> &setAddress) const =0;
//! Support for viewing keys //! Support for Sprout viewing keys
virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk) =0; virtual bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk) =0;
virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk) =0; virtual bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk) =0;
virtual bool HaveViewingKey(const libzcash::SproutPaymentAddress &address) const =0; virtual bool HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const =0;
virtual bool GetViewingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutViewingKey& vkOut) const =0; virtual bool GetSproutViewingKey(
const libzcash::SproutPaymentAddress &address,
libzcash::SproutViewingKey& vkOut) const =0;
}; };
typedef std::map<CKeyID, CKey> KeyMap; typedef std::map<CKeyID, CKey> KeyMap;
typedef std::map<CScriptID, CScript > ScriptMap; typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet; typedef std::set<CScript> WatchOnlySet;
typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutSpendingKey> SpendingKeyMap; typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutSpendingKey> SproutSpendingKeyMap;
typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutViewingKey> ViewingKeyMap; typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutViewingKey> SproutViewingKeyMap;
typedef std::map<libzcash::SproutPaymentAddress, ZCNoteDecryption> NoteDecryptorMap; typedef std::map<libzcash::SproutPaymentAddress, ZCNoteDecryption> NoteDecryptorMap;
// Full viewing key has equivalent functionality to a transparent address // Full viewing key has equivalent functionality to a transparent address
@@ -106,10 +112,10 @@ protected:
KeyMap mapKeys; KeyMap mapKeys;
ScriptMap mapScripts; ScriptMap mapScripts;
WatchOnlySet setWatchOnly; WatchOnlySet setWatchOnly;
SpendingKeyMap mapSpendingKeys; SproutSpendingKeyMap mapSproutSpendingKeys;
ViewingKeyMap mapViewingKeys; SproutViewingKeyMap mapSproutViewingKeys;
NoteDecryptorMap mapNoteDecryptors; NoteDecryptorMap mapNoteDecryptors;
SaplingSpendingKeyMap mapSaplingSpendingKeys; SaplingSpendingKeyMap mapSaplingSpendingKeys;
SaplingFullViewingKeyMap mapSaplingFullViewingKeys; SaplingFullViewingKeyMap mapSaplingFullViewingKeys;
SaplingIncomingViewingKeyMap mapSaplingIncomingViewingKeys; SaplingIncomingViewingKeyMap mapSaplingIncomingViewingKeys;
@@ -160,22 +166,22 @@ public:
virtual bool HaveWatchOnly(const CScript &dest) const; virtual bool HaveWatchOnly(const CScript &dest) const;
virtual bool HaveWatchOnly() const; virtual bool HaveWatchOnly() const;
bool AddSpendingKey(const libzcash::SproutSpendingKey &sk); bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk);
bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const
{ {
bool result; bool result;
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
result = (mapSpendingKeys.count(address) > 0); result = (mapSproutSpendingKeys.count(address) > 0);
} }
return result; return result;
} }
bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const
{ {
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
SpendingKeyMap::const_iterator mi = mapSpendingKeys.find(address); SproutSpendingKeyMap::const_iterator mi = mapSproutSpendingKeys.find(address);
if (mi != mapSpendingKeys.end()) if (mi != mapSproutSpendingKeys.end())
{ {
skOut = mi->second; skOut = mi->second;
return true; return true;
@@ -196,19 +202,19 @@ public:
} }
return false; return false;
} }
void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const void GetSproutPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const
{ {
setAddress.clear(); setAddress.clear();
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
SpendingKeyMap::const_iterator mi = mapSpendingKeys.begin(); SproutSpendingKeyMap::const_iterator mi = mapSproutSpendingKeys.begin();
while (mi != mapSpendingKeys.end()) while (mi != mapSproutSpendingKeys.end())
{ {
setAddress.insert((*mi).first); setAddress.insert((*mi).first);
mi++; mi++;
} }
ViewingKeyMap::const_iterator mvi = mapViewingKeys.begin(); SproutViewingKeyMap::const_iterator mvi = mapSproutViewingKeys.begin();
while (mvi != mapViewingKeys.end()) while (mvi != mapSproutViewingKeys.end())
{ {
setAddress.insert((*mvi).first); setAddress.insert((*mvi).first);
mvi++; mvi++;
@@ -217,7 +223,9 @@ public:
} }
//! Sapling //! Sapling
bool AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk); bool AddSaplingSpendingKey(
const libzcash::SaplingSpendingKey &sk,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr = boost::none);
bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const
{ {
bool result; bool result;
@@ -241,8 +249,10 @@ public:
} }
return false; return false;
} }
virtual bool AddSaplingFullViewingKey(const libzcash::SaplingFullViewingKey &fvk); virtual bool AddSaplingFullViewingKey(
const libzcash::SaplingFullViewingKey &fvk,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr = boost::none);
virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const; virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const;
virtual bool GetSaplingFullViewingKey( virtual bool GetSaplingFullViewingKey(
const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingIncomingViewingKey &ivk,
@@ -266,15 +276,17 @@ public:
} }
} }
virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk); virtual bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk);
virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk); virtual bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk);
virtual bool HaveViewingKey(const libzcash::SproutPaymentAddress &address) const; virtual bool HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const;
virtual bool GetViewingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutViewingKey& vkOut) const; virtual bool GetSproutViewingKey(
const libzcash::SproutPaymentAddress &address,
libzcash::SproutViewingKey& vkOut) const;
}; };
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial; typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap; typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
typedef std::map<libzcash::SproutPaymentAddress, std::vector<unsigned char> > CryptedSpendingKeyMap; typedef std::map<libzcash::SproutPaymentAddress, std::vector<unsigned char> > CryptedSproutSpendingKeyMap;
//! Sapling //! Sapling
typedef std::map<libzcash::SaplingFullViewingKey, std::vector<unsigned char> > CryptedSaplingSpendingKeyMap; typedef std::map<libzcash::SaplingFullViewingKey, std::vector<unsigned char> > CryptedSaplingSpendingKeyMap;

View File

@@ -218,7 +218,7 @@ public:
obj.push_back(Pair("transmissionkey", zaddr.pk_enc.GetHex())); obj.push_back(Pair("transmissionkey", zaddr.pk_enc.GetHex()));
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
if (pwalletMain) { if (pwalletMain) {
obj.push_back(Pair("ismine", pwalletMain->HaveSpendingKey(zaddr))); obj.push_back(Pair("ismine", pwalletMain->HaveSproutSpendingKey(zaddr)));
} }
#endif #endif
return obj; return obj;

View File

@@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_validateaddress)
// Wallet should be empty // Wallet should be empty
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs); pwalletMain->GetSproutPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0); BOOST_CHECK(addrs.size()==0);
// This address is not valid, it belongs to another network // This address is not valid, it belongs to another network
@@ -400,7 +400,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet)
// wallet should be empty // wallet should be empty
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs); pwalletMain->GetSproutPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0); BOOST_CHECK(addrs.size()==0);
// wallet should have one key // wallet should have one key
@@ -408,7 +408,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet)
BOOST_CHECK(IsValidPaymentAddress(address)); BOOST_CHECK(IsValidPaymentAddress(address));
BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr); BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
auto addr = boost::get<libzcash::SproutPaymentAddress>(address); auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
pwalletMain->GetPaymentAddresses(addrs); pwalletMain->GetSproutPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==1); BOOST_CHECK(addrs.size()==1);
// Set up paths // Set up paths
@@ -433,7 +433,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet)
libzcash::SproutSpendingKey key; libzcash::SproutSpendingKey key;
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, key)); BOOST_CHECK(pwalletMain->GetSproutSpendingKey(addr, key));
std::string s1 = EncodePaymentAddress(addr); std::string s1 = EncodePaymentAddress(addr);
std::string s2 = EncodeSpendingKey(key); std::string s2 = EncodeSpendingKey(key);
@@ -507,14 +507,14 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
// wallet should currently be empty // wallet should currently be empty
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs); pwalletMain->GetSproutPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0); BOOST_CHECK(addrs.size()==0);
// import test data from file into wallet // import test data from file into wallet
BOOST_CHECK_NO_THROW(CallRPC(string("z_importwallet ") + path)); BOOST_CHECK_NO_THROW(CallRPC(string("z_importwallet ") + path));
// wallet should now have one zkey // wallet should now have one zkey
pwalletMain->GetPaymentAddresses(addrs); pwalletMain->GetSproutPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==1); BOOST_CHECK(addrs.size()==1);
// check that we have the spending key for the address // check that we have the spending key for the address
@@ -522,11 +522,11 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
BOOST_CHECK(IsValidPaymentAddress(address)); BOOST_CHECK(IsValidPaymentAddress(address));
BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr); BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
auto addr = boost::get<libzcash::SproutPaymentAddress>(address); auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
BOOST_CHECK(pwalletMain->HaveSpendingKey(addr)); BOOST_CHECK(pwalletMain->HaveSproutSpendingKey(addr));
// Verify the spending key is the same as the test data // Verify the spending key is the same as the test data
libzcash::SproutSpendingKey k; libzcash::SproutSpendingKey k;
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, k)); BOOST_CHECK(pwalletMain->GetSproutSpendingKey(addr, k));
BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k)); BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k));
} }
@@ -559,7 +559,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
// wallet should currently be empty // wallet should currently be empty
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs); pwalletMain->GetSproutPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0); BOOST_CHECK(addrs.size()==0);
std::set<libzcash::SaplingPaymentAddress> saplingAddrs; std::set<libzcash::SaplingPaymentAddress> saplingAddrs;
pwalletMain->GetSaplingPaymentAddresses(saplingAddrs); pwalletMain->GetSaplingPaymentAddresses(saplingAddrs);
@@ -605,7 +605,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
// Verify number of addresses stored in wallet is n1+n2 // Verify number of addresses stored in wallet is n1+n2
int numAddrs = myaddrs.size(); int numAddrs = myaddrs.size();
BOOST_CHECK(numAddrs == (2 * n1) + n2); BOOST_CHECK(numAddrs == (2 * n1) + n2);
pwalletMain->GetPaymentAddresses(addrs); pwalletMain->GetSproutPaymentAddresses(addrs);
pwalletMain->GetSaplingPaymentAddresses(saplingAddrs); pwalletMain->GetSaplingPaymentAddresses(saplingAddrs);
BOOST_CHECK(addrs.size() + saplingAddrs.size() == numAddrs); BOOST_CHECK(addrs.size() + saplingAddrs.size() == numAddrs);
@@ -631,7 +631,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
BOOST_CHECK(IsValidPaymentAddress(address)); BOOST_CHECK(IsValidPaymentAddress(address));
BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr); BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
auto newAddr = boost::get<libzcash::SproutPaymentAddress>(address); auto newAddr = boost::get<libzcash::SproutPaymentAddress>(address);
BOOST_CHECK(pwalletMain->HaveSpendingKey(newAddr)); BOOST_CHECK(pwalletMain->HaveSproutSpendingKey(newAddr));
// Check if too many args // Check if too many args
BOOST_CHECK_THROW(CallRPC("z_getnewaddress toomanyargs"), runtime_error); BOOST_CHECK_THROW(CallRPC("z_getnewaddress toomanyargs"), runtime_error);
@@ -1258,7 +1258,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_zkeys)
// wallet should currently be empty // wallet should currently be empty
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs); pwalletMain->GetSproutPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0); BOOST_CHECK(addrs.size()==0);
// create keys // create keys

View File

@@ -89,7 +89,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
// We don't need to lock on the wallet as spending key related methods are thread-safe // We don't need to lock on the wallet as spending key related methods are thread-safe
SproutSpendingKey key; SproutSpendingKey key;
if (!pwalletMain->GetSpendingKey(addr, key)) { if (!pwalletMain->GetSproutSpendingKey(addr, key)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, no spending key found for zaddr"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, no spending key found for zaddr");
} }

View File

@@ -106,7 +106,7 @@ static bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMateri
CCrypter cKeyCrypter; CCrypter cKeyCrypter;
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE); std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
if(!cKeyCrypter.SetKey(vMasterKey, chIV)) if (!cKeyCrypter.SetKey(vMasterKey, chIV))
return false; return false;
return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext); return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext);
} }
@@ -116,7 +116,7 @@ static bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<u
CCrypter cKeyCrypter; CCrypter cKeyCrypter;
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE); std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
if(!cKeyCrypter.SetKey(vMasterKey, chIV)) if (!cKeyCrypter.SetKey(vMasterKey, chIV))
return false; return false;
return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)); return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
} }
@@ -124,7 +124,7 @@ static bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<u
static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key) static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key)
{ {
CKeyingMaterial vchSecret; CKeyingMaterial vchSecret;
if(!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
return false; return false;
if (vchSecret.size() != 32) if (vchSecret.size() != 32)
@@ -134,16 +134,16 @@ static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsi
return key.VerifyPubKey(vchPubKey); return key.VerifyPubKey(vchPubKey);
} }
static bool DecryptSpendingKey(const CKeyingMaterial& vMasterKey, static bool DecryptSproutSpendingKey(const CKeyingMaterial& vMasterKey,
const std::vector<unsigned char>& vchCryptedSecret, const std::vector<unsigned char>& vchCryptedSecret,
const libzcash::SproutPaymentAddress& address, const libzcash::SproutPaymentAddress& address,
libzcash::SproutSpendingKey& sk) libzcash::SproutSpendingKey& sk)
{ {
CKeyingMaterial vchSecret; CKeyingMaterial vchSecret;
if(!DecryptSecret(vMasterKey, vchCryptedSecret, address.GetHash(), vchSecret)) if (!DecryptSecret(vMasterKey, vchCryptedSecret, address.GetHash(), vchSecret))
return false; return false;
if (vchSecret.size() != libzcash::SerializedSpendingKeySize) if (vchSecret.size() != libzcash::SerializedSproutSpendingKeySize)
return false; return false;
CSecureDataStream ss(vchSecret, SER_NETWORK, PROTOCOL_VERSION); CSecureDataStream ss(vchSecret, SER_NETWORK, PROTOCOL_VERSION);
@@ -151,12 +151,29 @@ static bool DecryptSpendingKey(const CKeyingMaterial& vMasterKey,
return sk.address() == address; return sk.address() == address;
} }
static bool DecryptSaplingSpendingKey(const CKeyingMaterial& vMasterKey,
const std::vector<unsigned char>& vchCryptedSecret,
const libzcash::SaplingFullViewingKey& fvk,
libzcash::SaplingSpendingKey& sk)
{
CKeyingMaterial vchSecret;
if (!DecryptSecret(vMasterKey, vchCryptedSecret, fvk.GetFingerprint(), vchSecret))
return false;
if (vchSecret.size() != libzcash::SerializedSaplingSpendingKeySize)
return false;
CSecureDataStream ss(vchSecret, SER_NETWORK, PROTOCOL_VERSION);
ss >> sk;
return sk.full_viewing_key() == fvk;
}
bool CCryptoKeyStore::SetCrypted() bool CCryptoKeyStore::SetCrypted()
{ {
LOCK2(cs_KeyStore, cs_SpendingKeyStore); LOCK2(cs_KeyStore, cs_SpendingKeyStore);
if (fUseCrypto) if (fUseCrypto)
return true; return true;
if (!(mapKeys.empty() && mapSpendingKeys.empty())) if (!(mapKeys.empty() && mapSproutSpendingKeys.empty() && mapSaplingSpendingKeys.empty()))
return false; return false;
fUseCrypto = true; fUseCrypto = true;
return true; return true;
@@ -200,13 +217,28 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
if (fDecryptionThoroughlyChecked) if (fDecryptionThoroughlyChecked)
break; break;
} }
CryptedSpendingKeyMap::const_iterator skmi = mapCryptedSpendingKeys.begin(); CryptedSproutSpendingKeyMap::const_iterator miSprout = mapCryptedSproutSpendingKeys.begin();
for (; skmi != mapCryptedSpendingKeys.end(); ++skmi) for (; miSprout != mapCryptedSproutSpendingKeys.end(); ++miSprout)
{ {
const libzcash::SproutPaymentAddress &address = (*skmi).first; const libzcash::SproutPaymentAddress &address = (*miSprout).first;
const std::vector<unsigned char> &vchCryptedSecret = (*skmi).second; const std::vector<unsigned char> &vchCryptedSecret = (*miSprout).second;
libzcash::SproutSpendingKey sk; libzcash::SproutSpendingKey sk;
if (!DecryptSpendingKey(vMasterKeyIn, vchCryptedSecret, address, sk)) if (!DecryptSproutSpendingKey(vMasterKeyIn, vchCryptedSecret, address, sk))
{
keyFail = true;
break;
}
keyPass = true;
if (fDecryptionThoroughlyChecked)
break;
}
CryptedSaplingSpendingKeyMap::const_iterator miSapling = mapCryptedSaplingSpendingKeys.begin();
for (; miSapling != mapCryptedSaplingSpendingKeys.end(); ++miSapling)
{
const libzcash::SaplingFullViewingKey &fvk = (*miSapling).first;
const std::vector<unsigned char> &vchCryptedSecret = (*miSapling).second;
libzcash::SaplingSpendingKey sk;
if (!DecryptSaplingSpendingKey(vMasterKeyIn, vchCryptedSecret, fvk, sk))
{ {
keyFail = true; keyFail = true;
break; break;
@@ -298,12 +330,12 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co
return false; return false;
} }
bool CCryptoKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk) bool CCryptoKeyStore::AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk)
{ {
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
if (!IsCrypted()) if (!IsCrypted())
return CBasicKeyStore::AddSpendingKey(sk); return CBasicKeyStore::AddSproutSpendingKey(sk);
if (IsLocked()) if (IsLocked())
return false; return false;
@@ -316,18 +348,20 @@ bool CCryptoKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk)
if (!EncryptSecret(vMasterKey, vchSecret, address.GetHash(), vchCryptedSecret)) if (!EncryptSecret(vMasterKey, vchSecret, address.GetHash(), vchCryptedSecret))
return false; return false;
if (!AddCryptedSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) if (!AddCryptedSproutSpendingKey(address, sk.receiving_key(), vchCryptedSecret))
return false; return false;
} }
return true; return true;
} }
bool CCryptoKeyStore::AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk) bool CCryptoKeyStore::AddSaplingSpendingKey(
const libzcash::SaplingSpendingKey &sk,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr)
{ {
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
if (!IsCrypted()) { if (!IsCrypted()) {
return CBasicKeyStore::AddSaplingSpendingKey(sk); return CBasicKeyStore::AddSaplingSpendingKey(sk, defaultAddr);
} }
if (IsLocked()) { if (IsLocked()) {
@@ -338,37 +372,38 @@ bool CCryptoKeyStore::AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &
CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << sk; ss << sk;
CKeyingMaterial vchSecret(ss.begin(), ss.end()); CKeyingMaterial vchSecret(ss.begin(), ss.end());
auto address = sk.default_address();
auto fvk = sk.full_viewing_key(); auto fvk = sk.full_viewing_key();
if (!EncryptSecret(vMasterKey, vchSecret, address.GetHash(), vchCryptedSecret)) { if (!EncryptSecret(vMasterKey, vchSecret, fvk.GetFingerprint(), vchCryptedSecret)) {
return false; return false;
} }
if (!AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret)) { if (!AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret, defaultAddr)) {
return false; return false;
} }
} }
return true; return true;
} }
bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, bool CCryptoKeyStore::AddCryptedSproutSpendingKey(
const libzcash::ReceivingKey &rk, const libzcash::SproutPaymentAddress &address,
const std::vector<unsigned char> &vchCryptedSecret) const libzcash::ReceivingKey &rk,
const std::vector<unsigned char> &vchCryptedSecret)
{ {
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
if (!SetCrypted()) if (!SetCrypted())
return false; return false;
mapCryptedSpendingKeys[address] = vchCryptedSecret; mapCryptedSproutSpendingKeys[address] = vchCryptedSecret;
mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(rk))); mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(rk)));
} }
return true; return true;
} }
// TODO: Handle note decryptors bool CCryptoKeyStore::AddCryptedSaplingSpendingKey(
bool CCryptoKeyStore::AddCryptedSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, const libzcash::SaplingFullViewingKey &fvk,
const std::vector<unsigned char> &vchCryptedSecret) const std::vector<unsigned char> &vchCryptedSecret,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr)
{ {
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
@@ -376,23 +411,45 @@ bool CCryptoKeyStore::AddCryptedSaplingSpendingKey(const libzcash::SaplingFullVi
return false; return false;
} }
// if SaplingFullViewingKey is not in SaplingFullViewingKeyMap, add it
if (!AddSaplingFullViewingKey(fvk, defaultAddr)){
return false;
}
mapCryptedSaplingSpendingKeys[fvk] = vchCryptedSecret; mapCryptedSaplingSpendingKeys[fvk] = vchCryptedSecret;
} }
return true; return true;
} }
bool CCryptoKeyStore::GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const bool CCryptoKeyStore::GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const
{ {
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
if (!IsCrypted()) if (!IsCrypted())
return CBasicKeyStore::GetSpendingKey(address, skOut); return CBasicKeyStore::GetSproutSpendingKey(address, skOut);
CryptedSpendingKeyMap::const_iterator mi = mapCryptedSpendingKeys.find(address); CryptedSproutSpendingKeyMap::const_iterator mi = mapCryptedSproutSpendingKeys.find(address);
if (mi != mapCryptedSpendingKeys.end()) if (mi != mapCryptedSproutSpendingKeys.end())
{ {
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second; const std::vector<unsigned char> &vchCryptedSecret = (*mi).second;
return DecryptSpendingKey(vMasterKey, vchCryptedSecret, address, skOut); return DecryptSproutSpendingKey(vMasterKey, vchCryptedSecret, address, skOut);
}
}
return false;
}
bool CCryptoKeyStore::GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingSpendingKey &skOut) const
{
{
LOCK(cs_SpendingKeyStore);
if (!IsCrypted())
return CBasicKeyStore::GetSaplingSpendingKey(fvk, skOut);
CryptedSaplingSpendingKeyMap::const_iterator mi = mapCryptedSaplingSpendingKeys.find(fvk);
if (mi != mapCryptedSaplingSpendingKeys.end())
{
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second;
return DecryptSaplingSpendingKey(vMasterKey, vchCryptedSecret, fvk, skOut);
} }
} }
return false; return false;
@@ -412,26 +469,47 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
CPubKey vchPubKey = key.GetPubKey(); CPubKey vchPubKey = key.GetPubKey();
CKeyingMaterial vchSecret(key.begin(), key.end()); CKeyingMaterial vchSecret(key.begin(), key.end());
std::vector<unsigned char> vchCryptedSecret; std::vector<unsigned char> vchCryptedSecret;
if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret)) if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret)) {
return false; return false;
if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) }
if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) {
return false; return false;
}
} }
mapKeys.clear(); mapKeys.clear();
BOOST_FOREACH(SpendingKeyMap::value_type& mSpendingKey, mapSpendingKeys) BOOST_FOREACH(SproutSpendingKeyMap::value_type& mSproutSpendingKey, mapSproutSpendingKeys)
{ {
const libzcash::SproutSpendingKey &sk = mSpendingKey.second; const libzcash::SproutSpendingKey &sk = mSproutSpendingKey.second;
CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << sk; ss << sk;
CKeyingMaterial vchSecret(ss.begin(), ss.end()); CKeyingMaterial vchSecret(ss.begin(), ss.end());
libzcash::SproutPaymentAddress address = sk.address(); libzcash::SproutPaymentAddress address = sk.address();
std::vector<unsigned char> vchCryptedSecret; std::vector<unsigned char> vchCryptedSecret;
if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret)) if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret)) {
return false; return false;
if (!AddCryptedSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) }
if (!AddCryptedSproutSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) {
return false; return false;
}
} }
mapSpendingKeys.clear(); mapSproutSpendingKeys.clear();
//! Sapling key support
BOOST_FOREACH(SaplingSpendingKeyMap::value_type& mSaplingSpendingKey, mapSaplingSpendingKeys)
{
const libzcash::SaplingSpendingKey &sk = mSaplingSpendingKey.second;
CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << sk;
CKeyingMaterial vchSecret(ss.begin(), ss.end());
libzcash::SaplingFullViewingKey fvk = sk.full_viewing_key();
std::vector<unsigned char> vchCryptedSecret;
if (!EncryptSecret(vMasterKeyIn, vchSecret, fvk.GetFingerprint(), vchCryptedSecret)) {
return false;
}
if (!AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret)) {
return false;
}
}
mapSaplingSpendingKeys.clear();
} }
return true; return true;
} }

View File

@@ -128,13 +128,12 @@ class CCryptoKeyStore : public CBasicKeyStore
{ {
private: private:
CryptedKeyMap mapCryptedKeys; CryptedKeyMap mapCryptedKeys;
CryptedSpendingKeyMap mapCryptedSpendingKeys; CryptedSproutSpendingKeyMap mapCryptedSproutSpendingKeys;
CryptedSaplingSpendingKeyMap mapCryptedSaplingSpendingKeys; CryptedSaplingSpendingKeyMap mapCryptedSaplingSpendingKeys;
CKeyingMaterial vMasterKey; CKeyingMaterial vMasterKey;
//! if fUseCrypto is true, mapKeys and mapSpendingKeys must be empty //! if fUseCrypto is true, mapKeys, mapSproutSpendingKeys, and mapSaplingSpendingKeys must be empty
//! if fUseCrypto is false, vMasterKey must be empty //! if fUseCrypto is false, vMasterKey must be empty
bool fUseCrypto; bool fUseCrypto;
@@ -202,40 +201,57 @@ public:
mi++; mi++;
} }
} }
virtual bool AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, virtual bool AddCryptedSproutSpendingKey(
const libzcash::ReceivingKey &rk, const libzcash::SproutPaymentAddress &address,
const std::vector<unsigned char> &vchCryptedSecret); const libzcash::ReceivingKey &rk,
bool AddSpendingKey(const libzcash::SproutSpendingKey &sk); const std::vector<unsigned char> &vchCryptedSecret);
bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk);
bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const
{ {
{ {
LOCK(cs_SpendingKeyStore); LOCK(cs_SpendingKeyStore);
if (!IsCrypted()) if (!IsCrypted())
return CBasicKeyStore::HaveSpendingKey(address); return CBasicKeyStore::HaveSproutSpendingKey(address);
return mapCryptedSpendingKeys.count(address) > 0; return mapCryptedSproutSpendingKeys.count(address) > 0;
} }
return false; return false;
} }
bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const; bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const;
void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const void GetSproutPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const
{ {
if (!IsCrypted()) if (!IsCrypted())
{ {
CBasicKeyStore::GetPaymentAddresses(setAddress); CBasicKeyStore::GetSproutPaymentAddresses(setAddress);
return; return;
} }
setAddress.clear(); setAddress.clear();
CryptedSpendingKeyMap::const_iterator mi = mapCryptedSpendingKeys.begin(); CryptedSproutSpendingKeyMap::const_iterator mi = mapCryptedSproutSpendingKeys.begin();
while (mi != mapCryptedSpendingKeys.end()) while (mi != mapCryptedSproutSpendingKeys.end())
{ {
setAddress.insert((*mi).first); setAddress.insert((*mi).first);
mi++; mi++;
} }
} }
//! Sapling //! Sapling
virtual bool AddCryptedSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, virtual bool AddCryptedSaplingSpendingKey(
const std::vector<unsigned char> &vchCryptedSecret); const libzcash::SaplingFullViewingKey &fvk,
bool AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk); const std::vector<unsigned char> &vchCryptedSecret,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr = boost::none);
bool AddSaplingSpendingKey(
const libzcash::SaplingSpendingKey &sk,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr = boost::none);
bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const
{
{
LOCK(cs_SpendingKeyStore);
if (!IsCrypted())
return CBasicKeyStore::HaveSaplingSpendingKey(fvk);
return mapCryptedSaplingSpendingKeys.count(fvk) > 0;
}
return false;
}
bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingSpendingKey &skOut) const;
/** /**
* Wallet status (encrypted, locked) changed. * Wallet status (encrypted, locked) changed.

View File

@@ -166,7 +166,7 @@ TEST(wallet_tests, find_unspent_notes) {
SelectParams(CBaseChainParams::TESTNET); SelectParams(CBaseChainParams::TESTNET);
CWallet wallet; CWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
auto note = GetNote(sk, wtx, 0, 1); auto note = GetNote(sk, wtx, 0, 1);
@@ -371,7 +371,7 @@ TEST(wallet_tests, GetNoteNullifier) {
hSig, 1); hSig, 1);
EXPECT_NE(nullifier, ret); EXPECT_NE(nullifier, ret);
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
ret = wallet.GetNoteNullifier( ret = wallet.GetNoteNullifier(
wtx.vjoinsplit[0], wtx.vjoinsplit[0],
@@ -386,7 +386,7 @@ TEST(wallet_tests, FindMyNotes) {
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
auto sk2 = libzcash::SproutSpendingKey::random(); auto sk2 = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk2); wallet.AddSproutSpendingKey(sk2);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
auto note = GetNote(sk, wtx, 0, 1); auto note = GetNote(sk, wtx, 0, 1);
@@ -395,7 +395,7 @@ TEST(wallet_tests, FindMyNotes) {
auto noteMap = wallet.FindMyNotes(wtx); auto noteMap = wallet.FindMyNotes(wtx);
EXPECT_EQ(0, noteMap.size()); EXPECT_EQ(0, noteMap.size());
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
noteMap = wallet.FindMyNotes(wtx); noteMap = wallet.FindMyNotes(wtx);
EXPECT_EQ(2, noteMap.size()); EXPECT_EQ(2, noteMap.size());
@@ -412,7 +412,7 @@ TEST(wallet_tests, FindMyNotesInEncryptedWallet) {
CKeyingMaterial vMasterKey (r.begin(), r.end()); CKeyingMaterial vMasterKey (r.begin(), r.end());
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
ASSERT_TRUE(wallet.EncryptKeys(vMasterKey)); ASSERT_TRUE(wallet.EncryptKeys(vMasterKey));
@@ -440,7 +440,7 @@ TEST(wallet_tests, get_conflicted_notes) {
CWallet wallet; CWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
auto note = GetNote(sk, wtx, 0, 1); auto note = GetNote(sk, wtx, 0, 1);
@@ -471,7 +471,7 @@ TEST(wallet_tests, nullifier_is_spent) {
CWallet wallet; CWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
auto note = GetNote(sk, wtx, 0, 1); auto note = GetNote(sk, wtx, 0, 1);
@@ -511,7 +511,7 @@ TEST(wallet_tests, navigate_from_nullifier_to_note) {
CWallet wallet; CWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
auto note = GetNote(sk, wtx, 0, 1); auto note = GetNote(sk, wtx, 0, 1);
@@ -537,7 +537,7 @@ TEST(wallet_tests, spent_note_is_from_me) {
CWallet wallet; CWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
auto note = GetNote(sk, wtx, 0, 1); auto note = GetNote(sk, wtx, 0, 1);
@@ -565,7 +565,7 @@ TEST(wallet_tests, cached_witnesses_empty_chain) {
TestWallet wallet; TestWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true, 4); auto wtx = GetValidReceive(sk, 10, true, 4);
auto note = GetNote(sk, wtx, 0, 0); auto note = GetNote(sk, wtx, 0, 0);
@@ -628,7 +628,7 @@ TEST(wallet_tests, cached_witnesses_chain_tip) {
SaplingMerkleTree saplingTree; SaplingMerkleTree saplingTree;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
{ {
// First block (case tested in _empty_chain) // First block (case tested in _empty_chain)
@@ -728,7 +728,7 @@ TEST(wallet_tests, CachedWitnessesDecrementFirst) {
SaplingMerkleTree saplingTree; SaplingMerkleTree saplingTree;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
{ {
// First block (case tested in _empty_chain) // First block (case tested in _empty_chain)
@@ -818,7 +818,7 @@ TEST(wallet_tests, CachedWitnessesCleanIndex) {
std::vector<boost::optional<SaplingWitness>> saplingWitnesses; std::vector<boost::optional<SaplingWitness>> saplingWitnesses;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
// Generate a chain // Generate a chain
size_t numBlocks = WITNESS_CACHE_SIZE + 10; size_t numBlocks = WITNESS_CACHE_SIZE + 10;
@@ -893,7 +893,7 @@ TEST(wallet_tests, ClearNoteWitnessCache) {
TestWallet wallet; TestWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true, 4); auto wtx = GetValidReceive(sk, 10, true, 4);
auto hash = wtx.GetHash(); auto hash = wtx.GetHash();
@@ -953,7 +953,7 @@ TEST(wallet_tests, WriteWitnessCache) {
CBlockLocator loc; CBlockLocator loc;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
wallet.AddToWallet(wtx, true, NULL); wallet.AddToWallet(wtx, true, NULL);
@@ -1030,7 +1030,7 @@ TEST(wallet_tests, UpdateNullifierNoteMap) {
CKeyingMaterial vMasterKey (r.begin(), r.end()); CKeyingMaterial vMasterKey (r.begin(), r.end());
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
ASSERT_TRUE(wallet.EncryptKeys(vMasterKey)); ASSERT_TRUE(wallet.EncryptKeys(vMasterKey));
@@ -1063,7 +1063,7 @@ TEST(wallet_tests, UpdatedNoteData) {
TestWallet wallet; TestWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
auto note = GetNote(sk, wtx, 0, 0); auto note = GetNote(sk, wtx, 0, 0);
@@ -1110,7 +1110,7 @@ TEST(wallet_tests, MarkAffectedTransactionsDirty) {
TestWallet wallet; TestWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
auto hash = wtx.GetHash(); auto hash = wtx.GetHash();
@@ -1141,7 +1141,7 @@ TEST(wallet_tests, NoteLocking) {
TestWallet wallet; TestWallet wallet;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true); auto wtx = GetValidReceive(sk, 10, true);
auto wtx2 = GetValidReceive(sk, 10, true); auto wtx2 = GetValidReceive(sk, 10, true);

View File

@@ -31,7 +31,7 @@ TEST(wallet_zkeys_tests, store_and_load_sapling_zkeys) {
// manually add new spending key to wallet // manually add new spending key to wallet
auto sk = libzcash::SaplingSpendingKey::random(); auto sk = libzcash::SaplingSpendingKey::random();
ASSERT_TRUE(wallet.AddSaplingZKey(sk)); ASSERT_TRUE(wallet.AddSaplingZKey(sk, sk.default_address()));
// verify wallet did add it // verify wallet did add it
auto fvk = sk.full_viewing_key(); auto fvk = sk.full_viewing_key();
@@ -44,9 +44,9 @@ TEST(wallet_zkeys_tests, store_and_load_sapling_zkeys) {
// verify there are two keys // verify there are two keys
wallet.GetSaplingPaymentAddresses(addrs); wallet.GetSaplingPaymentAddresses(addrs);
ASSERT_EQ(2, addrs.size()); EXPECT_EQ(2, addrs.size());
ASSERT_EQ(1, addrs.count(address)); EXPECT_EQ(1, addrs.count(address));
ASSERT_EQ(1, addrs.count(sk.default_address())); EXPECT_EQ(1, addrs.count(sk.default_address()));
} }
/** /**
@@ -63,18 +63,18 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) {
// wallet should be empty // wallet should be empty
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(0, addrs.size()); ASSERT_EQ(0, addrs.size());
// wallet should have one key // wallet should have one key
auto address = wallet.GenerateNewZKey(); auto address = wallet.GenerateNewZKey();
ASSERT_NE(boost::get<libzcash::SproutPaymentAddress>(&address), nullptr); ASSERT_NE(boost::get<libzcash::SproutPaymentAddress>(&address), nullptr);
auto addr = boost::get<libzcash::SproutPaymentAddress>(address); auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(1, addrs.size()); ASSERT_EQ(1, addrs.size());
// verify wallet has spending key for the address // verify wallet has spending key for the address
ASSERT_TRUE(wallet.HaveSpendingKey(addr)); ASSERT_TRUE(wallet.HaveSproutSpendingKey(addr));
// manually add new spending key to wallet // manually add new spending key to wallet
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
@@ -82,15 +82,15 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) {
// verify wallet did add it // verify wallet did add it
addr = sk.address(); addr = sk.address();
ASSERT_TRUE(wallet.HaveSpendingKey(addr)); ASSERT_TRUE(wallet.HaveSproutSpendingKey(addr));
// verify spending key stored correctly // verify spending key stored correctly
libzcash::SproutSpendingKey keyOut; libzcash::SproutSpendingKey keyOut;
wallet.GetSpendingKey(addr, keyOut); wallet.GetSproutSpendingKey(addr, keyOut);
ASSERT_EQ(sk, keyOut); ASSERT_EQ(sk, keyOut);
// verify there are two keys // verify there are two keys
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(2, addrs.size()); ASSERT_EQ(2, addrs.size());
ASSERT_EQ(1, addrs.count(addr)); ASSERT_EQ(1, addrs.count(addr));
@@ -111,9 +111,9 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) {
/** /**
* This test covers methods on CWallet * This test covers methods on CWallet
* AddViewingKey() * AddSproutViewingKey()
* RemoveViewingKey() * RemoveSproutViewingKey()
* LoadViewingKey() * LoadSproutViewingKey()
*/ */
TEST(wallet_zkeys_tests, StoreAndLoadViewingKeys) { TEST(wallet_zkeys_tests, StoreAndLoadViewingKeys) {
SelectParams(CBaseChainParams::MAIN); SelectParams(CBaseChainParams::MAIN);
@@ -122,38 +122,38 @@ TEST(wallet_zkeys_tests, StoreAndLoadViewingKeys) {
// wallet should be empty // wallet should be empty
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(0, addrs.size()); ASSERT_EQ(0, addrs.size());
// manually add new viewing key to wallet // manually add new viewing key to wallet
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
auto vk = sk.viewing_key(); auto vk = sk.viewing_key();
ASSERT_TRUE(wallet.AddViewingKey(vk)); ASSERT_TRUE(wallet.AddSproutViewingKey(vk));
// verify wallet did add it // verify wallet did add it
auto addr = sk.address(); auto addr = sk.address();
ASSERT_TRUE(wallet.HaveViewingKey(addr)); ASSERT_TRUE(wallet.HaveSproutViewingKey(addr));
// and that we don't have the corresponding spending key // and that we don't have the corresponding spending key
ASSERT_FALSE(wallet.HaveSpendingKey(addr)); ASSERT_FALSE(wallet.HaveSproutSpendingKey(addr));
// verify viewing key stored correctly // verify viewing key stored correctly
libzcash::SproutViewingKey vkOut; libzcash::SproutViewingKey vkOut;
wallet.GetViewingKey(addr, vkOut); wallet.GetSproutViewingKey(addr, vkOut);
ASSERT_EQ(vk, vkOut); ASSERT_EQ(vk, vkOut);
// Load a second viewing key into the wallet // Load a second viewing key into the wallet
auto sk2 = libzcash::SproutSpendingKey::random(); auto sk2 = libzcash::SproutSpendingKey::random();
ASSERT_TRUE(wallet.LoadViewingKey(sk2.viewing_key())); ASSERT_TRUE(wallet.LoadSproutViewingKey(sk2.viewing_key()));
// verify wallet did add it // verify wallet did add it
auto addr2 = sk2.address(); auto addr2 = sk2.address();
ASSERT_TRUE(wallet.HaveViewingKey(addr2)); ASSERT_TRUE(wallet.HaveSproutViewingKey(addr2));
ASSERT_FALSE(wallet.HaveSpendingKey(addr2)); ASSERT_FALSE(wallet.HaveSproutSpendingKey(addr2));
// Remove the first viewing key // Remove the first viewing key
ASSERT_TRUE(wallet.RemoveViewingKey(vk)); ASSERT_TRUE(wallet.RemoveSproutViewingKey(vk));
ASSERT_FALSE(wallet.HaveViewingKey(addr)); ASSERT_FALSE(wallet.HaveSproutViewingKey(addr));
ASSERT_TRUE(wallet.HaveViewingKey(addr2)); ASSERT_TRUE(wallet.HaveSproutViewingKey(addr2));
} }
/** /**
@@ -178,14 +178,14 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) {
// wallet should be empty // wallet should be empty
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(0, addrs.size()); ASSERT_EQ(0, addrs.size());
// Add random key to the wallet // Add random key to the wallet
auto paymentAddress = wallet.GenerateNewZKey(); auto paymentAddress = wallet.GenerateNewZKey();
// wallet should have one key // wallet should have one key
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(1, addrs.size()); ASSERT_EQ(1, addrs.size());
// create random key and add it to database directly, bypassing wallet // create random key and add it to database directly, bypassing wallet
@@ -197,10 +197,10 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) {
db.WriteZKey(addr, sk, meta); db.WriteZKey(addr, sk, meta);
// wallet should not be aware of key // wallet should not be aware of key
ASSERT_FALSE(wallet.HaveSpendingKey(addr)); ASSERT_FALSE(wallet.HaveSproutSpendingKey(addr));
// wallet sees one key // wallet sees one key
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(1, addrs.size()); ASSERT_EQ(1, addrs.size());
// wallet should have default metadata for addr with null createtime // wallet should have default metadata for addr with null createtime
@@ -212,15 +212,15 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) {
ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun)); ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun));
// wallet can now see the spending key // wallet can now see the spending key
ASSERT_TRUE(wallet.HaveSpendingKey(addr)); ASSERT_TRUE(wallet.HaveSproutSpendingKey(addr));
// check key is the same // check key is the same
libzcash::SproutSpendingKey keyOut; libzcash::SproutSpendingKey keyOut;
wallet.GetSpendingKey(addr, keyOut); wallet.GetSproutSpendingKey(addr, keyOut);
ASSERT_EQ(sk, keyOut); ASSERT_EQ(sk, keyOut);
// wallet should have two keys // wallet should have two keys
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(2, addrs.size()); ASSERT_EQ(2, addrs.size());
// check metadata is now the same // check metadata is now the same
@@ -230,7 +230,7 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) {
/** /**
* This test covers methods on CWalletDB * This test covers methods on CWalletDB
* WriteViewingKey() * WriteSproutViewingKey()
*/ */
TEST(wallet_zkeys_tests, WriteViewingKeyDirectToDB) { TEST(wallet_zkeys_tests, WriteViewingKeyDirectToDB) {
SelectParams(CBaseChainParams::TESTNET); SelectParams(CBaseChainParams::TESTNET);
@@ -255,20 +255,20 @@ TEST(wallet_zkeys_tests, WriteViewingKeyDirectToDB) {
int64_t now = GetTime(); int64_t now = GetTime();
CKeyMetadata meta(now); CKeyMetadata meta(now);
CWalletDB db("wallet-vkey.dat"); CWalletDB db("wallet-vkey.dat");
db.WriteViewingKey(vk); db.WriteSproutViewingKey(vk);
// wallet should not be aware of viewing key // wallet should not be aware of viewing key
ASSERT_FALSE(wallet.HaveViewingKey(addr)); ASSERT_FALSE(wallet.HaveSproutViewingKey(addr));
// load the wallet again // load the wallet again
ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun)); ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun));
// wallet can now see the viewing key // wallet can now see the viewing key
ASSERT_TRUE(wallet.HaveViewingKey(addr)); ASSERT_TRUE(wallet.HaveSproutViewingKey(addr));
// check key is the same // check key is the same
libzcash::SproutViewingKey vkOut; libzcash::SproutViewingKey vkOut;
wallet.GetViewingKey(addr, vkOut); wallet.GetSproutViewingKey(addr, vkOut);
ASSERT_EQ(vk, vkOut); ASSERT_EQ(vk, vkOut);
} }
@@ -295,7 +295,7 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) {
// wallet should be empty // wallet should be empty
std::set<libzcash::SproutPaymentAddress> addrs; std::set<libzcash::SproutPaymentAddress> addrs;
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(0, addrs.size()); ASSERT_EQ(0, addrs.size());
// Add random key to the wallet // Add random key to the wallet
@@ -304,7 +304,7 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) {
auto paymentAddress = boost::get<libzcash::SproutPaymentAddress>(address); auto paymentAddress = boost::get<libzcash::SproutPaymentAddress>(address);
// wallet should have one key // wallet should have one key
wallet.GetPaymentAddresses(addrs); wallet.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(1, addrs.size()); ASSERT_EQ(1, addrs.size());
// encrypt wallet // encrypt wallet
@@ -330,7 +330,7 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) {
ASSERT_TRUE(&wallet != &wallet2); ASSERT_TRUE(&wallet != &wallet2);
// wallet should have two keys // wallet should have two keys
wallet2.GetPaymentAddresses(addrs); wallet2.GetSproutPaymentAddresses(addrs);
ASSERT_EQ(2, addrs.size()); ASSERT_EQ(2, addrs.size());
// check we have entries for our payment addresses // check we have entries for our payment addresses
@@ -339,16 +339,16 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) {
// spending key is crypted, so we can't extract valid payment address // spending key is crypted, so we can't extract valid payment address
libzcash::SproutSpendingKey keyOut; libzcash::SproutSpendingKey keyOut;
wallet2.GetSpendingKey(paymentAddress, keyOut); wallet2.GetSproutSpendingKey(paymentAddress, keyOut);
ASSERT_FALSE(paymentAddress == keyOut.address()); ASSERT_FALSE(paymentAddress == keyOut.address());
// unlock wallet to get spending keys and verify payment addresses // unlock wallet to get spending keys and verify payment addresses
wallet2.Unlock(strWalletPass); wallet2.Unlock(strWalletPass);
wallet2.GetSpendingKey(paymentAddress, keyOut); wallet2.GetSproutSpendingKey(paymentAddress, keyOut);
ASSERT_EQ(paymentAddress, keyOut.address()); ASSERT_EQ(paymentAddress, keyOut.address());
wallet2.GetSpendingKey(paymentAddress2, keyOut); wallet2.GetSproutSpendingKey(paymentAddress2, keyOut);
ASSERT_EQ(paymentAddress2, keyOut.address()); ASSERT_EQ(paymentAddress2, keyOut.address());
} }

View File

@@ -302,7 +302,7 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
assert(boost::get<libzcash::SproutSpendingKey>(&spendingkey) != nullptr); assert(boost::get<libzcash::SproutSpendingKey>(&spendingkey) != nullptr);
auto key = boost::get<libzcash::SproutSpendingKey>(spendingkey); auto key = boost::get<libzcash::SproutSpendingKey>(spendingkey);
auto addr = key.address(); auto addr = key.address();
if (pwalletMain->HaveSpendingKey(addr)) { if (pwalletMain->HaveSproutSpendingKey(addr)) {
LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", EncodePaymentAddress(addr)); LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", EncodePaymentAddress(addr));
continue; continue;
} }
@@ -530,13 +530,13 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys)
if (fDumpZKeys) { if (fDumpZKeys) {
std::set<libzcash::SproutPaymentAddress> addresses; std::set<libzcash::SproutPaymentAddress> addresses;
pwalletMain->GetPaymentAddresses(addresses); pwalletMain->GetSproutPaymentAddresses(addresses);
file << "\n"; file << "\n";
file << "# Zkeys\n"; file << "# Zkeys\n";
file << "\n"; file << "\n";
for (auto addr : addresses ) { for (auto addr : addresses ) {
libzcash::SproutSpendingKey key; libzcash::SproutSpendingKey key;
if (pwalletMain->GetSpendingKey(addr, key)) { if (pwalletMain->GetSproutSpendingKey(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", EncodeSpendingKey(key), strTime, EncodePaymentAddress(addr)); file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(key), strTime, EncodePaymentAddress(addr));
} }
@@ -560,7 +560,7 @@ public:
bool operator()(const libzcash::SproutSpendingKey &sk) const { bool 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 // Don't throw error in case a key is already there
if (m_wallet->HaveSpendingKey(addr)) { if (m_wallet->HaveSproutSpendingKey(addr)) {
return true; return true;
} else { } else {
m_wallet->MarkDirty(); m_wallet->MarkDirty();
@@ -585,7 +585,7 @@ public:
} else { } else {
m_wallet->MarkDirty(); m_wallet->MarkDirty();
if (!m_wallet-> AddSaplingZKey(sk)) { if (!m_wallet-> AddSaplingZKey(sk, addr)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding spending key to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding spending key to wallet");
} }
@@ -758,19 +758,19 @@ UniValue z_importviewingkey(const UniValue& params, bool fHelp)
auto addr = vkey.address(); auto addr = vkey.address();
{ {
if (pwalletMain->HaveSpendingKey(addr)) { if (pwalletMain->HaveSproutSpendingKey(addr)) {
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this viewing key"); throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this viewing key");
} }
// Don't throw error in case a viewing key is already there // Don't throw error in case a viewing key is already there
if (pwalletMain->HaveViewingKey(addr)) { if (pwalletMain->HaveSproutViewingKey(addr)) {
if (fIgnoreExistingKey) { if (fIgnoreExistingKey) {
return NullUniValue; return NullUniValue;
} }
} else { } else {
pwalletMain->MarkDirty(); pwalletMain->MarkDirty();
if (!pwalletMain->AddViewingKey(vkey)) { if (!pwalletMain->AddSproutViewingKey(vkey)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding viewing key to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding viewing key to wallet");
} }
} }
@@ -794,7 +794,7 @@ public:
libzcash::SpendingKey operator()(const libzcash::SproutPaymentAddress &zaddr) const libzcash::SpendingKey operator()(const libzcash::SproutPaymentAddress &zaddr) const
{ {
libzcash::SproutSpendingKey k; libzcash::SproutSpendingKey k;
if (!pwalletMain->GetSpendingKey(zaddr, k)) { if (!pwalletMain->GetSproutSpendingKey(zaddr, k)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr"); throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr");
} }
return k; return k;
@@ -889,9 +889,9 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
auto addr = boost::get<libzcash::SproutPaymentAddress>(address); auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
libzcash::SproutViewingKey vk; libzcash::SproutViewingKey vk;
if (!pwalletMain->GetViewingKey(addr, vk)) { if (!pwalletMain->GetSproutViewingKey(addr, vk)) {
libzcash::SproutSpendingKey k; libzcash::SproutSpendingKey k;
if (!pwalletMain->GetSpendingKey(addr, k)) { if (!pwalletMain->GetSproutSpendingKey(addr, k)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr"); throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr");
} }
vk = k.viewing_key(); vk = k.viewing_key();

View File

@@ -2531,7 +2531,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
// TODO: Add Sapling support. For now, ensure we can freely convert. // TODO: Add Sapling support. For now, ensure we can freely convert.
assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr); assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr);
libzcash::SproutPaymentAddress addr = boost::get<libzcash::SproutPaymentAddress>(zaddr); libzcash::SproutPaymentAddress addr = boost::get<libzcash::SproutPaymentAddress>(zaddr);
if (!fIncludeWatchonly && !pwalletMain->HaveSpendingKey(addr)) { if (!fIncludeWatchonly && !pwalletMain->HaveSproutSpendingKey(addr)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, spending key for address does not belong to wallet: ") + address); throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, spending key for address does not belong to wallet: ") + address);
} }
zaddrs.insert(addr); zaddrs.insert(addr);
@@ -2549,7 +2549,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
// User did not provide zaddrs, so use default i.e. all addresses // User did not provide zaddrs, so use default i.e. all addresses
// TODO: Add Sapling support // TODO: Add Sapling support
std::set<libzcash::SproutPaymentAddress> sproutzaddrs = {}; std::set<libzcash::SproutPaymentAddress> sproutzaddrs = {};
pwalletMain->GetPaymentAddresses(sproutzaddrs); pwalletMain->GetSproutPaymentAddresses(sproutzaddrs);
zaddrs.insert(sproutzaddrs.begin(), sproutzaddrs.end()); zaddrs.insert(sproutzaddrs.begin(), sproutzaddrs.end());
} }
@@ -2565,7 +2565,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
obj.push_back(Pair("jsindex", (int)entry.jsop.js )); obj.push_back(Pair("jsindex", (int)entry.jsop.js ));
obj.push_back(Pair("jsoutindex", (int)entry.jsop.n)); obj.push_back(Pair("jsoutindex", (int)entry.jsop.n));
obj.push_back(Pair("confirmations", entry.nHeight)); obj.push_back(Pair("confirmations", entry.nHeight));
obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(boost::get<libzcash::SproutPaymentAddress>(entry.address)))); obj.push_back(Pair("spendable", pwalletMain->HaveSproutSpendingKey(boost::get<libzcash::SproutPaymentAddress>(entry.address))));
obj.push_back(Pair("address", EncodePaymentAddress(entry.address))); obj.push_back(Pair("address", EncodePaymentAddress(entry.address)));
obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value())))); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value()))));
std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end());
@@ -3171,9 +3171,9 @@ UniValue z_listaddresses(const UniValue& params, bool fHelp)
UniValue ret(UniValue::VARR); UniValue ret(UniValue::VARR);
{ {
std::set<libzcash::SproutPaymentAddress> addresses; std::set<libzcash::SproutPaymentAddress> addresses;
pwalletMain->GetPaymentAddresses(addresses); pwalletMain->GetSproutPaymentAddresses(addresses);
for (auto addr : addresses) { for (auto addr : addresses) {
if (fIncludeWatchonly || pwalletMain->HaveSpendingKey(addr)) { if (fIncludeWatchonly || pwalletMain->HaveSproutSpendingKey(addr)) {
ret.push_back(EncodePaymentAddress(addr)); ret.push_back(EncodePaymentAddress(addr));
} }
} }
@@ -3296,7 +3296,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr); assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr);
auto sproutzaddr = boost::get<libzcash::SproutPaymentAddress>(zaddr); auto sproutzaddr = boost::get<libzcash::SproutPaymentAddress>(zaddr);
if (!(pwalletMain->HaveSpendingKey(sproutzaddr) || pwalletMain->HaveViewingKey(sproutzaddr))) { if (!(pwalletMain->HaveSproutSpendingKey(sproutzaddr) || pwalletMain->HaveSproutViewingKey(sproutzaddr))) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found."); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
} }
@@ -3368,7 +3368,7 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
// TODO: Add Sapling support. For now, ensure we can freely convert. // TODO: Add Sapling support. For now, ensure we can freely convert.
assert(boost::get<libzcash::SproutPaymentAddress>(&res) != nullptr); assert(boost::get<libzcash::SproutPaymentAddress>(&res) != nullptr);
auto zaddr = boost::get<libzcash::SproutPaymentAddress>(res); auto zaddr = boost::get<libzcash::SproutPaymentAddress>(res);
if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) { if (!(pwalletMain->HaveSproutSpendingKey(zaddr) || pwalletMain->HaveSproutViewingKey(zaddr))) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found."); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
} }
} }
@@ -3610,7 +3610,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
// Check that we have the spending key // Check that we have the spending key
if (!fromTaddr) { if (!fromTaddr) {
if (!pwalletMain->HaveSpendingKey(zaddr)) { if (!pwalletMain->HaveSproutSpendingKey(zaddr)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key not found."); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key not found.");
} }
} }
@@ -4259,7 +4259,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
// TODO: Add Sapling support // TODO: Add Sapling support
auto zaddr = boost::get<SproutPaymentAddress>(entry.address); auto zaddr = boost::get<SproutPaymentAddress>(entry.address);
SproutSpendingKey zkey; SproutSpendingKey zkey;
pwalletMain->GetSpendingKey(zaddr, zkey); pwalletMain->GetSproutSpendingKey(zaddr, zkey);
noteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey); noteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey);
mergedNoteValue += nValue; mergedNoteValue += nValue;
} }

View File

@@ -88,7 +88,7 @@ libzcash::PaymentAddress CWallet::GenerateNewZKey()
auto addr = k.address(); auto addr = k.address();
// Check for collision, even though it is unlikely to ever occur // Check for collision, even though it is unlikely to ever occur
if (CCryptoKeyStore::HaveSpendingKey(addr)) if (CCryptoKeyStore::HaveSproutSpendingKey(addr))
throw std::runtime_error("CWallet::GenerateNewZKey(): Collision detected"); throw std::runtime_error("CWallet::GenerateNewZKey(): Collision detected");
// Create new metadata // Create new metadata
@@ -118,7 +118,7 @@ SaplingPaymentAddress CWallet::GenerateNewSaplingZKey()
int64_t nCreationTime = GetTime(); int64_t nCreationTime = GetTime();
mapSaplingZKeyMetadata[addr] = CKeyMetadata(nCreationTime); mapSaplingZKeyMetadata[addr] = CKeyMetadata(nCreationTime);
if (!AddSaplingZKey(sk)) { if (!AddSaplingZKey(sk, addr)) {
throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed"); throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed");
} }
// return default sapling payment address. // return default sapling payment address.
@@ -126,11 +126,13 @@ SaplingPaymentAddress CWallet::GenerateNewSaplingZKey()
} }
// Add spending key to keystore // Add spending key to keystore
bool CWallet::AddSaplingZKey(const libzcash::SaplingSpendingKey &sk) bool CWallet::AddSaplingZKey(
const libzcash::SaplingSpendingKey &sk,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr)
{ {
AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
if (!CCryptoKeyStore::AddSaplingSpendingKey(sk)) { if (!CCryptoKeyStore::AddSaplingSpendingKey(sk, defaultAddr)) {
return false; return false;
} }
@@ -150,12 +152,12 @@ bool CWallet::AddZKey(const libzcash::SproutSpendingKey &key)
AssertLockHeld(cs_wallet); // mapZKeyMetadata AssertLockHeld(cs_wallet); // mapZKeyMetadata
auto addr = key.address(); auto addr = key.address();
if (!CCryptoKeyStore::AddSpendingKey(key)) if (!CCryptoKeyStore::AddSproutSpendingKey(key))
return false; return false;
// check if we need to remove from viewing keys // check if we need to remove from viewing keys
if (HaveViewingKey(addr)) if (HaveSproutViewingKey(addr))
RemoveViewingKey(key.viewing_key()); RemoveSproutViewingKey(key.viewing_key());
if (!fFileBacked) if (!fFileBacked)
return true; return true;
@@ -239,11 +241,12 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
} }
bool CWallet::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, bool CWallet::AddCryptedSproutSpendingKey(
const libzcash::ReceivingKey &rk, const libzcash::SproutPaymentAddress &address,
const std::vector<unsigned char> &vchCryptedSecret) const libzcash::ReceivingKey &rk,
const std::vector<unsigned char> &vchCryptedSecret)
{ {
if (!CCryptoKeyStore::AddCryptedSpendingKey(address, rk, vchCryptedSecret)) if (!CCryptoKeyStore::AddCryptedSproutSpendingKey(address, rk, vchCryptedSecret))
return false; return false;
if (!fFileBacked) if (!fFileBacked)
return true; return true;
@@ -264,6 +267,20 @@ bool CWallet::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &addres
return false; return false;
} }
bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk,
const std::vector<unsigned char> &vchCryptedSecret,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr)
{
if (!CCryptoKeyStore::AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret, defaultAddr))
return false;
if (!fFileBacked)
return true;
{
// TODO: Sapling - Write to disk
}
return false;
}
bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta) bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
{ {
AssertLockHeld(cs_wallet); // mapKeyMetadata AssertLockHeld(cs_wallet); // mapKeyMetadata
@@ -288,34 +305,34 @@ bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigne
bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret) bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret)
{ {
return CCryptoKeyStore::AddCryptedSpendingKey(addr, rk, vchCryptedSecret); return CCryptoKeyStore::AddCryptedSproutSpendingKey(addr, rk, vchCryptedSecret);
} }
bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key) bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key)
{ {
return CCryptoKeyStore::AddSpendingKey(key); return CCryptoKeyStore::AddSproutSpendingKey(key);
} }
bool CWallet::AddViewingKey(const libzcash::SproutViewingKey &vk) bool CWallet::AddSproutViewingKey(const libzcash::SproutViewingKey &vk)
{ {
if (!CCryptoKeyStore::AddViewingKey(vk)) { if (!CCryptoKeyStore::AddSproutViewingKey(vk)) {
return false; return false;
} }
nTimeFirstKey = 1; // No birthday information for viewing keys. nTimeFirstKey = 1; // No birthday information for viewing keys.
if (!fFileBacked) { if (!fFileBacked) {
return true; return true;
} }
return CWalletDB(strWalletFile).WriteViewingKey(vk); return CWalletDB(strWalletFile).WriteSproutViewingKey(vk);
} }
bool CWallet::RemoveViewingKey(const libzcash::SproutViewingKey &vk) bool CWallet::RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk)
{ {
AssertLockHeld(cs_wallet); AssertLockHeld(cs_wallet);
if (!CCryptoKeyStore::RemoveViewingKey(vk)) { if (!CCryptoKeyStore::RemoveSproutViewingKey(vk)) {
return false; return false;
} }
if (fFileBacked) { if (fFileBacked) {
if (!CWalletDB(strWalletFile).EraseViewingKey(vk)) { if (!CWalletDB(strWalletFile).EraseSproutViewingKey(vk)) {
return false; return false;
} }
} }
@@ -323,9 +340,9 @@ bool CWallet::RemoveViewingKey(const libzcash::SproutViewingKey &vk)
return true; return true;
} }
bool CWallet::LoadViewingKey(const libzcash::SproutViewingKey &vk) bool CWallet::LoadSproutViewingKey(const libzcash::SproutViewingKey &vk)
{ {
return CCryptoKeyStore::AddViewingKey(vk); return CCryptoKeyStore::AddSproutViewingKey(vk);
} }
bool CWallet::AddCScript(const CScript& redeemScript) bool CWallet::AddCScript(const CScript& redeemScript)
@@ -1404,7 +1421,7 @@ boost::optional<uint256> CWallet::GetNoteNullifier(const JSDescription& jsdesc,
// - We have them (this isn't a viewing key) // - We have them (this isn't a viewing key)
// - The wallet is unlocked // - The wallet is unlocked
libzcash::SproutSpendingKey key; libzcash::SproutSpendingKey key;
if (GetSpendingKey(address, key)) { if (GetSproutSpendingKey(address, key)) {
ret = note.nullifier(key); ret = note.nullifier(key);
} }
return ret; return ret;
@@ -3935,7 +3952,7 @@ void CWallet::GetFilteredNotes(
} }
// skip notes which cannot be spent // skip notes which cannot be spent
if (ignoreUnspendable && !HaveSpendingKey(pa)) { if (ignoreUnspendable && !HaveSproutSpendingKey(pa)) {
continue; continue;
} }
@@ -4016,7 +4033,7 @@ void CWallet::GetUnspentFilteredNotes(
} }
// skip notes where the spending key is not available // skip notes where the spending key is not available
if (requireSpendingKey && !HaveSpendingKey(pa)) { if (requireSpendingKey && !HaveSproutSpendingKey(pa)) {
continue; continue;
} }

View File

@@ -992,21 +992,30 @@ public:
//! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet) //! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet)
bool LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret); bool LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret);
//! Adds an encrypted spending key to the store, and saves it to disk (virtual method, declared in crypter.h) //! Adds an encrypted spending key to the store, and saves it to disk (virtual method, declared in crypter.h)
bool AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret); bool AddCryptedSproutSpendingKey(
const libzcash::SproutPaymentAddress &address,
const libzcash::ReceivingKey &rk,
const std::vector<unsigned char> &vchCryptedSecret);
//! Adds a Sprout viewing key to the store, and saves it to disk.
bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk);
bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk);
//! Adds a Sprout viewing key to the store, without saving it to disk (used by LoadWallet)
bool LoadSproutViewingKey(const libzcash::SproutViewingKey &dest);
//! Adds a viewing key to the store, and saves it to disk.
bool AddViewingKey(const libzcash::SproutViewingKey &vk);
bool RemoveViewingKey(const libzcash::SproutViewingKey &vk);
//! Adds a viewing key to the store, without saving it to disk (used by LoadWallet)
bool LoadViewingKey(const libzcash::SproutViewingKey &dest);
/** /**
* Sapling ZKeys * Sapling ZKeys
*/ */
//! Generates new Sapling key //! Generates new Sapling key
libzcash::SaplingPaymentAddress GenerateNewSaplingZKey(); libzcash::SaplingPaymentAddress GenerateNewSaplingZKey();
//! Adds Sapling spending key to the store, and saves it to disk //! Adds Sapling spending key to the store, and saves it to disk
bool AddSaplingZKey(const libzcash::SaplingSpendingKey &key); bool AddSaplingZKey(
const libzcash::SaplingSpendingKey &key,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr = boost::none);
bool AddCryptedSaplingSpendingKey(
const libzcash::SaplingFullViewingKey &fvk,
const std::vector<unsigned char> &vchCryptedSecret,
const boost::optional<libzcash::SaplingPaymentAddress> &defaultAddr = boost::none);
/** /**
* Increment the next transaction order id * Increment the next transaction order id

View File

@@ -142,13 +142,13 @@ bool CWalletDB::WriteZKey(const libzcash::SproutPaymentAddress& addr, const libz
return Write(std::make_pair(std::string("zkey"), addr), key, false); return Write(std::make_pair(std::string("zkey"), addr), key, false);
} }
bool CWalletDB::WriteViewingKey(const libzcash::SproutViewingKey &vk) bool CWalletDB::WriteSproutViewingKey(const libzcash::SproutViewingKey &vk)
{ {
nWalletDBUpdated++; nWalletDBUpdated++;
return Write(std::make_pair(std::string("vkey"), vk), '1'); return Write(std::make_pair(std::string("vkey"), vk), '1');
} }
bool CWalletDB::EraseViewingKey(const libzcash::SproutViewingKey &vk) bool CWalletDB::EraseSproutViewingKey(const libzcash::SproutViewingKey &vk)
{ {
nWalletDBUpdated++; nWalletDBUpdated++;
return Erase(std::make_pair(std::string("vkey"), vk)); return Erase(std::make_pair(std::string("vkey"), vk));
@@ -490,7 +490,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
char fYes; char fYes;
ssValue >> fYes; ssValue >> fYes;
if (fYes == '1') if (fYes == '1')
pwallet->LoadViewingKey(vk); pwallet->LoadSproutViewingKey(vk);
// Viewing keys have no birthday information for now, // Viewing keys have no birthday information for now,
// so set the wallet birthday to the beginning of time. // so set the wallet birthday to the beginning of time.

View File

@@ -139,8 +139,8 @@ public:
const std::vector<unsigned char>& vchCryptedSecret, const std::vector<unsigned char>& vchCryptedSecret,
const CKeyMetadata &keyMeta); const CKeyMetadata &keyMeta);
bool WriteViewingKey(const libzcash::SproutViewingKey &vk); bool WriteSproutViewingKey(const libzcash::SproutViewingKey &vk);
bool EraseViewingKey(const libzcash::SproutViewingKey &vk); bool EraseSproutViewingKey(const libzcash::SproutViewingKey &vk);
private: private:
CWalletDB(const CWalletDB&); CWalletDB(const CWalletDB&);

View File

@@ -6,6 +6,9 @@
#include <librustzcash.h> #include <librustzcash.h>
const unsigned char ZCASH_SAPLING_FVFP_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] =
{'Z', 'c', 'a', 's', 'h', 'S', 'a', 'p', 'l', 'i', 'n', 'g', 'F', 'V', 'F', 'P'};
namespace libzcash { namespace libzcash {
uint256 SproutPaymentAddress::GetHash() const { uint256 SproutPaymentAddress::GetHash() const {
@@ -73,6 +76,13 @@ bool SaplingFullViewingKey::is_valid() const {
return !ivk.IsNull(); return !ivk.IsNull();
} }
uint256 SaplingFullViewingKey::GetFingerprint() const {
CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SAPLING_FVFP_PERSONALIZATION);
ss << *this;
return ss.GetHash();
}
SaplingSpendingKey SaplingSpendingKey::random() { SaplingSpendingKey SaplingSpendingKey::random() {
while (true) { while (true) {
auto sk = SaplingSpendingKey(random_uint256()); auto sk = SaplingSpendingKey(random_uint256());

View File

@@ -15,9 +15,11 @@ public:
friend bool operator<(const InvalidEncoding &a, const InvalidEncoding &b) { return true; } friend bool operator<(const InvalidEncoding &a, const InvalidEncoding &b) { return true; }
}; };
const size_t SerializedPaymentAddressSize = 64; const size_t SerializedSproutPaymentAddressSize = 64;
const size_t SerializedViewingKeySize = 64; const size_t SerializedSproutViewingKeySize = 64;
const size_t SerializedSpendingKeySize = 32; const size_t SerializedSproutSpendingKeySize = 32;
const size_t SerializedSaplingSpendingKeySize = 32;
typedef std::array<unsigned char, ZC_DIVERSIFIER_SIZE> diversifier_t; typedef std::array<unsigned char, ZC_DIVERSIFIER_SIZE> diversifier_t;
@@ -146,12 +148,15 @@ public:
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation> template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(ak); READWRITE(ak);
READWRITE(nk); READWRITE(nk);
READWRITE(ovk); READWRITE(ovk);
} }
//! Get the fingerprint of this full viewing key (as defined in ZIP 32).
uint256 GetFingerprint() const;
SaplingIncomingViewingKey in_viewing_key() const; SaplingIncomingViewingKey in_viewing_key() const;
bool is_valid() const; bool is_valid() const;
@@ -178,7 +183,7 @@ public:
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation> template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(ask); READWRITE(ask);
READWRITE(nsk); READWRITE(nsk);
READWRITE(ovk); READWRITE(ovk);

View File

@@ -283,7 +283,7 @@ double benchmark_try_decrypt_notes(size_t nAddrs)
CWallet wallet; CWallet wallet;
for (int i = 0; i < nAddrs; i++) { for (int i = 0; i < nAddrs; i++) {
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
} }
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
@@ -302,7 +302,7 @@ double benchmark_increment_note_witnesses(size_t nTxs)
SaplingMerkleTree saplingTree; SaplingMerkleTree saplingTree;
auto sk = libzcash::SproutSpendingKey::random(); auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk); wallet.AddSproutSpendingKey(sk);
// First block // First block
CBlock block1; CBlock block1;