From f4207d0c0ef563666e1b5823784500bd4a1da6f5 Mon Sep 17 00:00:00 2001 From: Jay Graber Date: Thu, 5 Jul 2018 14:52:46 -0700 Subject: [PATCH] Add SaplingIncomingViewingKeys map, SaplingFullViewingKey methods --- src/keystore.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++- src/keystore.h | 30 ++++++++++++++++++++++ src/wallet/wallet.cpp | 14 ++++------ 3 files changed, 94 insertions(+), 10 deletions(-) diff --git a/src/keystore.cpp b/src/keystore.cpp index 1a3742ac1..828cae677 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -99,7 +99,19 @@ bool CBasicKeyStore::AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &s LOCK(cs_SpendingKeyStore); auto fvk = sk.full_viewing_key(); mapSaplingSpendingKeys[fvk] = sk; - //! TODO: Note decryptors for Sapling + + // if SaplingFullViewingKey is not in SaplingFullViewingKeyMap, add it + AddSaplingFullViewingKey(fvk); + + // Add addr -> SaplingIncomingViewing to SaplingIncomingViewingKeyMap + auto ivk = fvk.in_viewing_key(); + auto addrOpt = sk.default_address(); + if (addrOpt){ + auto addr = addrOpt.value(); + mapSaplingIncomingViewingKeys[addr] = ivk; + } else { + return false; + } return true; } @@ -112,6 +124,16 @@ bool CBasicKeyStore::AddViewingKey(const libzcash::SproutViewingKey &vk) return true; } +bool CBasicKeyStore::AddSaplingFullViewingKey(const libzcash::SaplingFullViewingKey &fvk) +{ + LOCK(cs_SpendingKeyStore); + auto ivk = fvk.in_viewing_key(); + mapSaplingFullViewingKeys[ivk] = fvk; + //! TODO: Note decryptors for Sapling + // mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(vk.sk_enc))); + return true; +} + bool CBasicKeyStore::RemoveViewingKey(const libzcash::SproutViewingKey &vk) { LOCK(cs_SpendingKeyStore); @@ -125,6 +147,18 @@ bool CBasicKeyStore::HaveViewingKey(const libzcash::SproutPaymentAddress &addres return mapViewingKeys.count(address) > 0; } +bool CBasicKeyStore::HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const +{ + LOCK(cs_SpendingKeyStore); + return mapSaplingFullViewingKeys.count(ivk) > 0; +} + +bool CBasicKeyStore::HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr) const +{ + LOCK(cs_SpendingKeyStore); + return mapSaplingIncomingViewingKeys.count(addr) > 0; +} + bool CBasicKeyStore::GetViewingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutViewingKey &vkOut) const { @@ -136,3 +170,27 @@ bool CBasicKeyStore::GetViewingKey(const libzcash::SproutPaymentAddress &address } return false; } + +bool CBasicKeyStore::GetSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk, + libzcash::SaplingFullViewingKey &fvkOut) const +{ + LOCK(cs_SpendingKeyStore); + SaplingFullViewingKeyMap::const_iterator mi = mapSaplingFullViewingKeys.find(ivk); + if (mi != mapSaplingFullViewingKeys.end()) { + fvkOut = mi->second; + return true; + } + return false; +} + +bool CBasicKeyStore::GetSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr, + libzcash::SaplingIncomingViewingKey &ivkOut) const +{ + LOCK(cs_SpendingKeyStore); + SaplingIncomingViewingKeyMap::const_iterator mi = mapSaplingIncomingViewingKeys.find(addr); + if (mi != mapSaplingIncomingViewingKeys.end()) { + ivkOut = mi->second; + return true; + } + return false; +} diff --git a/src/keystore.h b/src/keystore.h index d75e7bef3..3d230dc37 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -62,6 +62,19 @@ public: //! 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 GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingSpendingKey& skOut) const =0; + + //! Support for Sapling full viewing keys + virtual bool AddSaplingFullViewingKey(const libzcash::SaplingFullViewingKey &fvk) =0; + virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const =0; + virtual bool GetSaplingFullViewingKey( + const libzcash::SaplingIncomingViewingKey &ivk, + libzcash::SaplingFullViewingKey& fvkOut) const =0; + + //! Sapling incoming viewing keys + virtual bool HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr) const =0; + virtual bool GetSaplingIncomingViewingKey( + const libzcash::SaplingPaymentAddress &addr, + libzcash::SaplingIncomingViewingKey& ivkOut) const =0; //! Support for viewing keys virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk) =0; @@ -77,8 +90,12 @@ typedef std::map Sp typedef std::map ViewingKeyMap; typedef std::map NoteDecryptorMap; +// Full viewing key has equivalent functionality to a transparent address +// When encrypting wallet, encrypt SaplingSpendingKeyMap, while leaving SaplingFullViewingKeyMap unencrypted typedef std::map SaplingSpendingKeyMap; typedef std::map SaplingFullViewingKeyMap; +// Only maps from default addresses to ivk, may need to be reworked when adding diversified addresses. +typedef std::map SaplingIncomingViewingKeyMap; /** Basic key store, that keeps keys in an address->secret map */ class CBasicKeyStore : public CKeyStore @@ -92,6 +109,8 @@ protected: NoteDecryptorMap mapNoteDecryptors; SaplingSpendingKeyMap mapSaplingSpendingKeys; + SaplingFullViewingKeyMap mapSaplingFullViewingKeys; + SaplingIncomingViewingKeyMap mapSaplingIncomingViewingKeys; public: bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); @@ -220,6 +239,17 @@ public: } return false; } + + virtual bool AddSaplingFullViewingKey(const libzcash::SaplingFullViewingKey &fvk); + virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const; + virtual bool GetSaplingFullViewingKey( + const libzcash::SaplingIncomingViewingKey &ivk, + libzcash::SaplingFullViewingKey& fvkOut) const; + + virtual bool HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr) const; + virtual bool GetSaplingIncomingViewingKey( + const libzcash::SaplingPaymentAddress &addr, + libzcash::SaplingIncomingViewingKey& ivkOut) const; virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk); virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index cee277fd8..b1bb54dac 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -138,16 +138,12 @@ bool CWallet::AddSaplingZKey(const libzcash::SaplingSpendingKey &sk) if (!CCryptoKeyStore::AddSaplingSpendingKey(sk)) { return false; } + + if (!fFileBacked) { + return true; + } - // // check if we need to remove from viewing keys - // if (HaveViewingKey(addr)) { - // RemoveViewingKey(key.viewing_key()); - // } - - // if (!fFileBacked) { - // return true; - // } - + // TODO: Persist to disk // if (!IsCrypted()) { // return CWalletDB(strWalletFile).WriteSaplingZKey(addr, // sk,