From 5175a7f07b16b5f761c545a84d17ebd12cafeda1 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 2 Aug 2018 22:34:31 +0100 Subject: [PATCH] Pass SaplingPaymentAddress to store through the CKeyStore --- src/gtest/test_keystore.cpp | 7 +++++++ src/keystore.cpp | 26 ++++++++++++++------------ src/keystore.h | 20 ++++++++++++++------ src/wallet/crypter.cpp | 19 ++++++++++++++----- src/wallet/crypter.h | 10 +++++++--- src/wallet/gtest/test_wallet_zkeys.cpp | 8 ++++---- src/wallet/rpcdump.cpp | 2 +- src/wallet/wallet.cpp | 13 ++++++++----- src/wallet/wallet.h | 10 +++++++--- 9 files changed, 76 insertions(+), 39 deletions(-) diff --git a/src/gtest/test_keystore.cpp b/src/gtest/test_keystore.cpp index 5660f369b..a07052d4a 100644 --- a/src/gtest/test_keystore.cpp +++ b/src/gtest/test_keystore.cpp @@ -185,8 +185,15 @@ TEST(keystore_tests, StoreAndRetrieveSaplingSpendingKey) { EXPECT_FALSE(keyStore.HaveSaplingIncomingViewingKey(addr)); EXPECT_FALSE(keyStore.GetSaplingIncomingViewingKey(addr, ivkOut)); + // If we don't specify the default address, that mapping isn't created keyStore.AddSaplingSpendingKey(sk); 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.HaveSaplingFullViewingKey(ivk)); EXPECT_TRUE(keyStore.GetSaplingFullViewingKey(ivk, fvkOut)); diff --git a/src/keystore.cpp b/src/keystore.cpp index cac20a1ae..2e297935c 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -94,23 +94,20 @@ bool CBasicKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk) } //! Sapling -bool CBasicKeyStore::AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk) +bool CBasicKeyStore::AddSaplingSpendingKey( + const libzcash::SaplingSpendingKey &sk, + const boost::optional &defaultAddr) { LOCK(cs_SpendingKeyStore); auto fvk = sk.full_viewing_key(); - + // if SaplingFullViewingKey is not in SaplingFullViewingKeyMap, add it - if (!AddSaplingFullViewingKey(fvk)){ + if (!AddSaplingFullViewingKey(fvk, defaultAddr)){ return false; } - + mapSaplingSpendingKeys[fvk] = sk; - // Add addr -> SaplingIncomingViewing to SaplingIncomingViewingKeyMap - auto ivk = fvk.in_viewing_key(); - auto addr = sk.default_address(); - mapSaplingIncomingViewingKeys[addr] = ivk; - return true; } @@ -123,13 +120,18 @@ bool CBasicKeyStore::AddViewingKey(const libzcash::SproutViewingKey &vk) return true; } -bool CBasicKeyStore::AddSaplingFullViewingKey(const libzcash::SaplingFullViewingKey &fvk) +bool CBasicKeyStore::AddSaplingFullViewingKey( + const libzcash::SaplingFullViewingKey &fvk, + const boost::optional &defaultAddr) { LOCK(cs_SpendingKeyStore); auto ivk = fvk.in_viewing_key(); mapSaplingFullViewingKeys[ivk] = fvk; - - //! TODO: Note decryptors for Sapling + + if (defaultAddr) { + // Add defaultAddr -> SaplingIncomingViewing to SaplingIncomingViewingKeyMap + mapSaplingIncomingViewingKeys[defaultAddr.get()] = ivk; + } return true; } diff --git a/src/keystore.h b/src/keystore.h index e44001570..bb7fca38b 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -57,14 +57,18 @@ public: virtual void GetPaymentAddresses(std::set &setAddress) const =0; //! 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 &defaultAddr = boost::none) =0; //! 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 AddSaplingFullViewingKey( + const libzcash::SaplingFullViewingKey &fvk, + const boost::optional &defaultAddr = boost::none) =0; virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const =0; virtual bool GetSaplingFullViewingKey( const libzcash::SaplingIncomingViewingKey &ivk, @@ -217,7 +221,9 @@ public: } //! Sapling - bool AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk); + bool AddSaplingSpendingKey( + const libzcash::SaplingSpendingKey &sk, + const boost::optional &defaultAddr = boost::none); bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const { bool result; @@ -241,8 +247,10 @@ public: } return false; } - - virtual bool AddSaplingFullViewingKey(const libzcash::SaplingFullViewingKey &fvk); + + virtual bool AddSaplingFullViewingKey( + const libzcash::SaplingFullViewingKey &fvk, + const boost::optional &defaultAddr = boost::none); virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const; virtual bool GetSaplingFullViewingKey( const libzcash::SaplingIncomingViewingKey &ivk, diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index ea4accf7f..9a5f80f4a 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -354,12 +354,14 @@ bool CCryptoKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk) return true; } -bool CCryptoKeyStore::AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk) +bool CCryptoKeyStore::AddSaplingSpendingKey( + const libzcash::SaplingSpendingKey &sk, + const boost::optional &defaultAddr) { { LOCK(cs_SpendingKeyStore); if (!IsCrypted()) { - return CBasicKeyStore::AddSaplingSpendingKey(sk); + return CBasicKeyStore::AddSaplingSpendingKey(sk, defaultAddr); } if (IsLocked()) { @@ -375,7 +377,7 @@ bool CCryptoKeyStore::AddSaplingSpendingKey(const libzcash::SaplingSpendingKey & return false; } - if (!AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret)) { + if (!AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret, defaultAddr)) { return false; } } @@ -397,8 +399,10 @@ bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress return true; } -bool CCryptoKeyStore::AddCryptedSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, - const std::vector &vchCryptedSecret) +bool CCryptoKeyStore::AddCryptedSaplingSpendingKey( + const libzcash::SaplingFullViewingKey &fvk, + const std::vector &vchCryptedSecret, + const boost::optional &defaultAddr) { { LOCK(cs_SpendingKeyStore); @@ -406,6 +410,11 @@ bool CCryptoKeyStore::AddCryptedSaplingSpendingKey(const libzcash::SaplingFullVi return false; } + // if SaplingFullViewingKey is not in SaplingFullViewingKeyMap, add it + if (!AddSaplingFullViewingKey(fvk, defaultAddr)){ + return false; + } + mapCryptedSaplingSpendingKeys[fvk] = vchCryptedSecret; } return true; diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 817d8de40..bfe8d68ec 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -232,9 +232,13 @@ public: } } //! Sapling - virtual bool AddCryptedSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, - const std::vector &vchCryptedSecret); - bool AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk); + virtual bool AddCryptedSaplingSpendingKey( + const libzcash::SaplingFullViewingKey &fvk, + const std::vector &vchCryptedSecret, + const boost::optional &defaultAddr = boost::none); + bool AddSaplingSpendingKey( + const libzcash::SaplingSpendingKey &sk, + const boost::optional &defaultAddr = boost::none); bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const { { diff --git a/src/wallet/gtest/test_wallet_zkeys.cpp b/src/wallet/gtest/test_wallet_zkeys.cpp index ec7146a17..42a060aa4 100644 --- a/src/wallet/gtest/test_wallet_zkeys.cpp +++ b/src/wallet/gtest/test_wallet_zkeys.cpp @@ -31,7 +31,7 @@ TEST(wallet_zkeys_tests, store_and_load_sapling_zkeys) { // manually add new spending key to wallet auto sk = libzcash::SaplingSpendingKey::random(); - ASSERT_TRUE(wallet.AddSaplingZKey(sk)); + ASSERT_TRUE(wallet.AddSaplingZKey(sk, sk.default_address())); // verify wallet did add it auto fvk = sk.full_viewing_key(); @@ -44,9 +44,9 @@ TEST(wallet_zkeys_tests, store_and_load_sapling_zkeys) { // verify there are two keys wallet.GetSaplingPaymentAddresses(addrs); - ASSERT_EQ(2, addrs.size()); - ASSERT_EQ(1, addrs.count(address)); - ASSERT_EQ(1, addrs.count(sk.default_address())); + EXPECT_EQ(2, addrs.size()); + EXPECT_EQ(1, addrs.count(address)); + EXPECT_EQ(1, addrs.count(sk.default_address())); } /** diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 8ef0f3abd..d8eb37fb3 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -585,7 +585,7 @@ public: } else { 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"); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 373bb9251..18291e960 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -118,7 +118,7 @@ SaplingPaymentAddress CWallet::GenerateNewSaplingZKey() int64_t nCreationTime = GetTime(); mapSaplingZKeyMetadata[addr] = CKeyMetadata(nCreationTime); - if (!AddSaplingZKey(sk)) { + if (!AddSaplingZKey(sk, addr)) { throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed"); } // return default sapling payment address. @@ -126,11 +126,13 @@ SaplingPaymentAddress CWallet::GenerateNewSaplingZKey() } // Add spending key to keystore -bool CWallet::AddSaplingZKey(const libzcash::SaplingSpendingKey &sk) +bool CWallet::AddSaplingZKey( + const libzcash::SaplingSpendingKey &sk, + const boost::optional &defaultAddr) { AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata - if (!CCryptoKeyStore::AddSaplingSpendingKey(sk)) { + if (!CCryptoKeyStore::AddSaplingSpendingKey(sk, defaultAddr)) { return false; } @@ -265,9 +267,10 @@ bool CWallet::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &addres } bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, - const std::vector &vchCryptedSecret) + const std::vector &vchCryptedSecret, + const boost::optional &defaultAddr) { - if (!CCryptoKeyStore::AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret)) + if (!CCryptoKeyStore::AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret, defaultAddr)) return false; if (!fFileBacked) return true; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 7cff16b13..f2986b11a 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1006,9 +1006,13 @@ public: //! Generates new Sapling key libzcash::SaplingPaymentAddress GenerateNewSaplingZKey(); //! Adds Sapling spending key to the store, and saves it to disk - bool AddSaplingZKey(const libzcash::SaplingSpendingKey &key); - bool AddCryptedSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, - const std::vector &vchCryptedSecret); + bool AddSaplingZKey( + const libzcash::SaplingSpendingKey &key, + const boost::optional &defaultAddr = boost::none); + bool AddCryptedSaplingSpendingKey( + const libzcash::SaplingFullViewingKey &fvk, + const std::vector &vchCryptedSecret, + const boost::optional &defaultAddr = boost::none); /** * Increment the next transaction order id