diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index a713fe7dd..c7f4577a3 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -25,8 +25,8 @@ void test_full_api(ZCJoinSplit* js) auto verifier = libzcash::ProofVerifier::Strict(); // The recipient's information. - SpendingKey recipient_key = SpendingKey::random(); - PaymentAddress recipient_addr = recipient_key.address(); + SproutSpendingKey recipient_key = SproutSpendingKey::random(); + SproutPaymentAddress recipient_addr = recipient_key.address(); // Create the commitment tree ZCIncrementalMerkleTree tree; @@ -122,8 +122,8 @@ void test_full_api(ZCJoinSplit* js) JSInput(witness_recipient, decrypted_note, recipient_key) }; - SpendingKey second_recipient = SpendingKey::random(); - PaymentAddress second_addr = second_recipient.address(); + SproutSpendingKey second_recipient = SproutSpendingKey::random(); + SproutPaymentAddress second_addr = second_recipient.address(); boost::array outputs = { JSOutput(second_addr, 9), @@ -317,8 +317,8 @@ TEST(joinsplit, full_api_test) std::vector witnesses; ZCIncrementalMerkleTree tree; increment_note_witnesses(uint256(), witnesses, tree); - SpendingKey sk = SpendingKey::random(); - PaymentAddress addr = sk.address(); + SproutSpendingKey sk = SproutSpendingKey::random(); + SproutPaymentAddress addr = sk.address(); SproutNote note1(addr.a_pk, 100, random_uint256(), random_uint256()); increment_note_witnesses(note1.cm(), witnesses, tree); SproutNote note2(addr.a_pk, 100, random_uint256(), random_uint256()); @@ -422,7 +422,7 @@ TEST(joinsplit, full_api_test) // Wrong secret key invokeAPIFailure(params, { - JSInput(witnesses[1], note1, SpendingKey::random()), + JSInput(witnesses[1], note1, SproutSpendingKey::random()), JSInput() }, { @@ -519,7 +519,7 @@ TEST(joinsplit, note_plaintexts) uint256 a_pk = PRF_addr_a_pk(a_sk); uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk); uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc); - PaymentAddress addr_pk(a_pk, pk_enc); + SproutPaymentAddress addr_pk(a_pk, pk_enc); uint256 h_sig; @@ -572,7 +572,7 @@ TEST(joinsplit, note_class) uint256 a_pk = PRF_addr_a_pk(a_sk); uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk); uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc); - PaymentAddress addr_pk(a_pk, pk_enc); + SproutPaymentAddress addr_pk(a_pk, pk_enc); SproutNote note(a_pk, 1945813, diff --git a/src/gtest/test_keystore.cpp b/src/gtest/test_keystore.cpp index 76b57cd9f..22e009e76 100644 --- a/src/gtest/test_keystore.cpp +++ b/src/gtest/test_keystore.cpp @@ -9,13 +9,13 @@ TEST(keystore_tests, store_and_retrieve_spending_key) { CBasicKeyStore keyStore; - libzcash::SpendingKey skOut; + libzcash::SproutSpendingKey skOut; - std::set addrs; + std::set addrs; keyStore.GetPaymentAddresses(addrs); EXPECT_EQ(0, addrs.size()); - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto addr = sk.address(); // Sanity-check: we can't get a key we haven't added @@ -36,7 +36,7 @@ TEST(keystore_tests, store_and_retrieve_note_decryptor) { CBasicKeyStore keyStore; ZCNoteDecryption decOut; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto addr = sk.address(); EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); @@ -48,11 +48,11 @@ TEST(keystore_tests, store_and_retrieve_note_decryptor) { TEST(keystore_tests, StoreAndRetrieveViewingKey) { CBasicKeyStore keyStore; - libzcash::ViewingKey vkOut; - libzcash::SpendingKey skOut; + libzcash::SproutViewingKey vkOut; + libzcash::SproutSpendingKey skOut; ZCNoteDecryption decOut; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto vk = sk.viewing_key(); auto addr = sk.address(); @@ -66,7 +66,7 @@ TEST(keystore_tests, StoreAndRetrieveViewingKey) { EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); // and we can't find it in our list of addresses - std::set addresses; + std::set addresses; keyStore.GetPaymentAddresses(addresses); EXPECT_FALSE(addresses.count(addr)); @@ -115,12 +115,12 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) { TestCCryptoKeyStore keyStore; uint256 r {GetRandHash()}; CKeyingMaterial vMasterKey (r.begin(), r.end()); - libzcash::SpendingKey keyOut; + libzcash::SproutSpendingKey keyOut; ZCNoteDecryption decOut; - std::set addrs; + std::set addrs; // 1) Test adding a key to an unencrypted key store, then encrypting it - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto addr = sk.address(); EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); @@ -157,7 +157,7 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) { ASSERT_EQ(1, addrs.count(addr)); // 2) Test adding a spending key to an already-encrypted key store - auto sk2 = libzcash::SpendingKey::random(); + auto sk2 = libzcash::SproutSpendingKey::random(); auto addr2 = sk2.address(); EXPECT_FALSE(keyStore.GetNoteDecryptor(addr2, decOut)); diff --git a/src/gtest/test_paymentdisclosure.cpp b/src/gtest/test_paymentdisclosure.cpp index ddab3c7e6..e9768a6fd 100644 --- a/src/gtest/test_paymentdisclosure.cpp +++ b/src/gtest/test_paymentdisclosure.cpp @@ -120,7 +120,7 @@ TEST(paymentdisclosure, mainnet) { PaymentDisclosureInfo info; info.esk = random_uint256(); info.joinSplitPrivKey = joinSplitPrivKey; - info.zaddr = libzcash::SpendingKey::random().address(); + info.zaddr = libzcash::SproutSpendingKey::random().address(); ASSERT_TRUE(mydb.Put(key, info)); // Retrieve info from test database into new local variable and test it matches @@ -131,7 +131,7 @@ TEST(paymentdisclosure, mainnet) { // Modify this local variable and confirm it no longer matches info2.esk = random_uint256(); info2.joinSplitPrivKey = random_uint256(); - info2.zaddr = libzcash::SpendingKey::random().address(); + info2.zaddr = libzcash::SproutSpendingKey::random().address(); ASSERT_NE(info, info2); // Using the payment info object, let's create a dummy payload diff --git a/src/gtest/test_transaction.cpp b/src/gtest/test_transaction.cpp index 0f78fcb39..ee674c6e2 100644 --- a/src/gtest/test_transaction.cpp +++ b/src/gtest/test_transaction.cpp @@ -12,8 +12,8 @@ TEST(Transaction, JSDescriptionRandomized) { // construct a merkle tree ZCIncrementalMerkleTree merkleTree; - libzcash::SpendingKey k = libzcash::SpendingKey::random(); - libzcash::PaymentAddress addr = k.address(); + libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random(); + libzcash::SproutPaymentAddress addr = k.address(); libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256()); diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp index 8609c93ba..5059a2046 100644 --- a/src/gtest/test_validation.cpp +++ b/src/gtest/test_validation.cpp @@ -87,7 +87,7 @@ TEST(Validation, ContextualCheckInputsPassesWithCoinbase) { } TEST(Validation, ReceivedBlockTransactions) { - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); // Create a fake genesis block CBlock block1; diff --git a/src/key_io.cpp b/src/key_io.cpp index 77d63cca4..a7f614f25 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -67,6 +67,70 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par } return CNoDestination(); } + +class PaymentAddressEncoder : public boost::static_visitor +{ +private: + const CChainParams& m_params; + +public: + PaymentAddressEncoder(const CChainParams& params) : m_params(params) {} + + std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const + { + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << zaddr; + std::vector data = m_params.Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); + data.insert(data.end(), ss.begin(), ss.end()); + return EncodeBase58Check(data); + } + + std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; } +}; + +class ViewingKeyEncoder : public boost::static_visitor +{ +private: + const CChainParams& m_params; + +public: + ViewingKeyEncoder(const CChainParams& params) : m_params(params) {} + + std::string operator()(const libzcash::SproutViewingKey& vk) const + { + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << vk; + std::vector data = m_params.Base58Prefix(CChainParams::ZCVIEWING_KEY); + data.insert(data.end(), ss.begin(), ss.end()); + std::string ret = EncodeBase58Check(data); + memory_cleanse(data.data(), data.size()); + return ret; + } + + std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; } +}; + +class SpendingKeyEncoder : public boost::static_visitor +{ +private: + const CChainParams& m_params; + +public: + SpendingKeyEncoder(const CChainParams& params) : m_params(params) {} + + std::string operator()(const libzcash::SproutSpendingKey& zkey) const + { + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << zkey; + std::vector data = m_params.Base58Prefix(CChainParams::ZCSPENDING_KEY); + data.insert(data.end(), ss.begin(), ss.end()); + std::string ret = EncodeBase58Check(data); + memory_cleanse(data.data(), data.size()); + return ret; + } + + std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; } +}; } // namespace CKey DecodeSecret(const std::string& str) @@ -167,14 +231,10 @@ bool IsValidDestinationString(const std::string& str) std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr) { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << zaddr; - std::vector data = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); - data.insert(data.end(), ss.begin(), ss.end()); - return EncodeBase58Check(data); + return boost::apply_visitor(PaymentAddressEncoder(Params()), zaddr); } -boost::optional DecodePaymentAddress(const std::string& str) +libzcash::PaymentAddress DecodePaymentAddress(const std::string& str) { std::vector data; if (DecodeBase58Check(str, data)) { @@ -183,26 +243,24 @@ boost::optional DecodePaymentAddress(const std::string std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) { CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end()); CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::PaymentAddress ret; + libzcash::SproutPaymentAddress ret; ss >> ret; return ret; } } - return boost::none; + return libzcash::InvalidEncoding(); +} + +bool IsValidPaymentAddressString(const std::string& str) { + return IsValidPaymentAddress(DecodePaymentAddress(str)); } std::string EncodeViewingKey(const libzcash::ViewingKey& vk) { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << vk; - std::vector data = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY); - data.insert(data.end(), ss.begin(), ss.end()); - std::string ret = EncodeBase58Check(data); - memory_cleanse(data.data(), data.size()); - return ret; + return boost::apply_visitor(ViewingKeyEncoder(Params()), vk); } -boost::optional DecodeViewingKey(const std::string& str) +libzcash::ViewingKey DecodeViewingKey(const std::string& str) { std::vector data; if (DecodeBase58Check(str, data)) { @@ -211,7 +269,7 @@ boost::optional DecodeViewingKey(const std::string& str) std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) { CSerializeData serialized(data.begin() + vk_prefix.size(), data.end()); CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::ViewingKey ret; + libzcash::SproutViewingKey ret; ss >> ret; memory_cleanse(serialized.data(), serialized.size()); memory_cleanse(data.data(), data.size()); @@ -219,21 +277,15 @@ boost::optional DecodeViewingKey(const std::string& str) } } memory_cleanse(data.data(), data.size()); - return boost::none; + return libzcash::InvalidEncoding(); } std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey) { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << zkey; - std::vector data = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY); - data.insert(data.end(), ss.begin(), ss.end()); - std::string ret = EncodeBase58Check(data); - memory_cleanse(data.data(), data.size()); - return ret; + return boost::apply_visitor(SpendingKeyEncoder(Params()), zkey); } -boost::optional DecodeSpendingKey(const std::string& str) +libzcash::SpendingKey DecodeSpendingKey(const std::string& str) { std::vector data; if (DecodeBase58Check(str, data)) { @@ -242,7 +294,7 @@ boost::optional DecodeSpendingKey(const std::string& str) std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) { CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end()); CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::SpendingKey ret; + libzcash::SproutSpendingKey ret; ss >> ret; memory_cleanse(serialized.data(), serialized.size()); memory_cleanse(data.data(), data.size()); @@ -250,5 +302,5 @@ boost::optional DecodeSpendingKey(const std::string& str) } } memory_cleanse(data.data(), data.size()); - return boost::none; + return libzcash::InvalidEncoding(); } diff --git a/src/key_io.h b/src/key_io.h index dd95976a3..c01d1d836 100644 --- a/src/key_io.h +++ b/src/key_io.h @@ -29,12 +29,13 @@ bool IsValidDestinationString(const std::string& str); bool IsValidDestinationString(const std::string& str, const CChainParams& params); std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr); -boost::optional DecodePaymentAddress(const std::string& str); +libzcash::PaymentAddress DecodePaymentAddress(const std::string& str); +bool IsValidPaymentAddressString(const std::string& str); std::string EncodeViewingKey(const libzcash::ViewingKey& vk); -boost::optional DecodeViewingKey(const std::string& str); +libzcash::ViewingKey DecodeViewingKey(const std::string& str); std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey); -boost::optional DecodeSpendingKey(const std::string& str); +libzcash::SpendingKey DecodeSpendingKey(const std::string& str); #endif // BITCOIN_KEYIO_H diff --git a/src/keystore.cpp b/src/keystore.cpp index 323fe710c..edab1e50a 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -84,7 +84,7 @@ bool CBasicKeyStore::HaveWatchOnly() const return (!setWatchOnly.empty()); } -bool CBasicKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk) +bool CBasicKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk) { LOCK(cs_SpendingKeyStore); auto address = sk.address(); @@ -93,7 +93,7 @@ bool CBasicKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk) return true; } -bool CBasicKeyStore::AddViewingKey(const libzcash::ViewingKey &vk) +bool CBasicKeyStore::AddViewingKey(const libzcash::SproutViewingKey &vk) { LOCK(cs_SpendingKeyStore); auto address = vk.address(); @@ -102,21 +102,21 @@ bool CBasicKeyStore::AddViewingKey(const libzcash::ViewingKey &vk) return true; } -bool CBasicKeyStore::RemoveViewingKey(const libzcash::ViewingKey &vk) +bool CBasicKeyStore::RemoveViewingKey(const libzcash::SproutViewingKey &vk) { LOCK(cs_SpendingKeyStore); mapViewingKeys.erase(vk.address()); return true; } -bool CBasicKeyStore::HaveViewingKey(const libzcash::PaymentAddress &address) const +bool CBasicKeyStore::HaveViewingKey(const libzcash::SproutPaymentAddress &address) const { LOCK(cs_SpendingKeyStore); return mapViewingKeys.count(address) > 0; } -bool CBasicKeyStore::GetViewingKey(const libzcash::PaymentAddress &address, - libzcash::ViewingKey &vkOut) const +bool CBasicKeyStore::GetViewingKey(const libzcash::SproutPaymentAddress &address, + libzcash::SproutViewingKey &vkOut) const { LOCK(cs_SpendingKeyStore); ViewingKeyMap::const_iterator mi = mapViewingKeys.find(address); diff --git a/src/keystore.h b/src/keystore.h index b1ad32a42..3195c40b3 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -49,26 +49,26 @@ public: virtual bool HaveWatchOnly() const =0; //! Add a spending key to the store. - virtual bool AddSpendingKey(const libzcash::SpendingKey &sk) =0; + virtual bool AddSpendingKey(const libzcash::SproutSpendingKey &sk) =0; //! Check whether a spending key corresponding to a given payment address is present in the store. - virtual bool HaveSpendingKey(const libzcash::PaymentAddress &address) const =0; - virtual bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey& skOut) const =0; - virtual void GetPaymentAddresses(std::set &setAddress) const =0; + virtual bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const =0; + virtual bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0; + virtual void GetPaymentAddresses(std::set &setAddress) const =0; //! Support for viewing keys - virtual bool AddViewingKey(const libzcash::ViewingKey &vk) =0; - virtual bool RemoveViewingKey(const libzcash::ViewingKey &vk) =0; - virtual bool HaveViewingKey(const libzcash::PaymentAddress &address) const =0; - virtual bool GetViewingKey(const libzcash::PaymentAddress &address, libzcash::ViewingKey& vkOut) const =0; + virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk) =0; + virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk) =0; + virtual bool HaveViewingKey(const libzcash::SproutPaymentAddress &address) const =0; + virtual bool GetViewingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutViewingKey& vkOut) const =0; }; typedef std::map KeyMap; typedef std::map ScriptMap; typedef std::set WatchOnlySet; -typedef std::map SpendingKeyMap; -typedef std::map ViewingKeyMap; -typedef std::map NoteDecryptorMap; +typedef std::map SpendingKeyMap; +typedef std::map ViewingKeyMap; +typedef std::map NoteDecryptorMap; /** Basic key store, that keeps keys in an address->secret map */ class CBasicKeyStore : public CKeyStore @@ -127,8 +127,8 @@ public: virtual bool HaveWatchOnly(const CScript &dest) const; virtual bool HaveWatchOnly() const; - bool AddSpendingKey(const libzcash::SpendingKey &sk); - bool HaveSpendingKey(const libzcash::PaymentAddress &address) const + bool AddSpendingKey(const libzcash::SproutSpendingKey &sk); + bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const { bool result; { @@ -137,7 +137,7 @@ public: } return result; } - bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const + bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const { { LOCK(cs_SpendingKeyStore); @@ -150,7 +150,7 @@ public: } return false; } - bool GetNoteDecryptor(const libzcash::PaymentAddress &address, ZCNoteDecryption &decOut) const + bool GetNoteDecryptor(const libzcash::SproutPaymentAddress &address, ZCNoteDecryption &decOut) const { { LOCK(cs_SpendingKeyStore); @@ -163,7 +163,7 @@ public: } return false; } - void GetPaymentAddresses(std::set &setAddress) const + void GetPaymentAddresses(std::set &setAddress) const { setAddress.clear(); { @@ -183,14 +183,14 @@ public: } } - virtual bool AddViewingKey(const libzcash::ViewingKey &vk); - virtual bool RemoveViewingKey(const libzcash::ViewingKey &vk); - virtual bool HaveViewingKey(const libzcash::PaymentAddress &address) const; - virtual bool GetViewingKey(const libzcash::PaymentAddress &address, libzcash::ViewingKey& vkOut) const; + virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk); + virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk); + virtual bool HaveViewingKey(const libzcash::SproutPaymentAddress &address) const; + virtual bool GetViewingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutViewingKey& vkOut) const; }; typedef std::vector > CKeyingMaterial; typedef std::map > > CryptedKeyMap; -typedef std::map > CryptedSpendingKeyMap; +typedef std::map > CryptedSpendingKeyMap; #endif // BITCOIN_KEYSTORE_H diff --git a/src/paymentdisclosure.h b/src/paymentdisclosure.h index b3681affc..eea0fda10 100644 --- a/src/paymentdisclosure.h +++ b/src/paymentdisclosure.h @@ -38,12 +38,12 @@ struct PaymentDisclosureInfo { uint256 joinSplitPrivKey; // primitives/transaction.h // ed25519 - not tied to implementation e.g. libsodium, see ed25519 rfc - libzcash::PaymentAddress zaddr; + libzcash::SproutPaymentAddress zaddr; PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) { } - PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::PaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { } + PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::SproutPaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { } ADD_SERIALIZE_METHODS; @@ -75,7 +75,7 @@ struct PaymentDisclosurePayload { uint256 txid; // primitives/transaction.h uint64_t js; // Index into CTransaction.vjoinsplit uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS - libzcash::PaymentAddress zaddr; // zcash/Address.hpp + libzcash::SproutPaymentAddress zaddr; // zcash/Address.hpp std::string message; // parameter to RPC call ADD_SERIALIZE_METHODS; diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 473918c9c..6359e507c 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -239,9 +239,12 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp) std::string payingKey, transmissionKey; string strAddress = params[0].get_str(); - auto isValid = DecodePaymentAddress(strAddress); + auto address = DecodePaymentAddress(strAddress); + bool isValid = IsValidPaymentAddress(address); if (isValid) { - libzcash::PaymentAddress addr = *isValid; + // TODO: Add Sapling support + assert(boost::get(&address) != nullptr); + libzcash::SproutPaymentAddress addr = boost::get(address); #ifdef ENABLE_WALLET isMine = pwalletMain->HaveSpendingKey(addr); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index c1bd8a553..837ddea81 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -247,8 +247,8 @@ public: uint256 appendRandomCommitment(ZCIncrementalMerkleTree &tree) { - libzcash::SpendingKey k = libzcash::SpendingKey::random(); - libzcash::PaymentAddress addr = k.address(); + libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random(); + libzcash::SproutPaymentAddress addr = k.address(); libzcash::SproutNote note(addr.a_pk, 0, uint256(), uint256()); diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 890d126f9..9c7385419 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(key_test1) BOOST_AUTO_TEST_CASE(zc_address_test) { for (size_t i = 0; i < 1000; i++) { - auto sk = SpendingKey::random(); + auto sk = SproutSpendingKey::random(); { string sk_string = EncodeSpendingKey(sk); @@ -196,8 +196,9 @@ BOOST_AUTO_TEST_CASE(zc_address_test) BOOST_CHECK(sk_string[1] == 'K'); auto spendingkey2 = DecodeSpendingKey(sk_string); - BOOST_ASSERT(static_cast(spendingkey2)); - SpendingKey sk2 = *spendingkey2; + BOOST_CHECK(IsValidSpendingKey(spendingkey2)); + BOOST_ASSERT(boost::get(&spendingkey2) != nullptr); + auto sk2 = boost::get(spendingkey2); BOOST_CHECK(sk.inner() == sk2.inner()); } { @@ -209,9 +210,10 @@ BOOST_AUTO_TEST_CASE(zc_address_test) BOOST_CHECK(addr_string[1] == 'c'); auto paymentaddr2 = DecodePaymentAddress(addr_string); - BOOST_ASSERT(static_cast(paymentaddr2)); + BOOST_ASSERT(IsValidPaymentAddress(paymentaddr2)); - PaymentAddress addr2 = *paymentaddr2; + BOOST_ASSERT(boost::get(&paymentaddr2) != nullptr); + auto addr2 = boost::get(paymentaddr2); BOOST_CHECK(addr.a_pk == addr2.a_pk); BOOST_CHECK(addr.pk_enc == addr2.pk_enc); } diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 0e09e5b14..47c85722a 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_validateaddress) BOOST_CHECK_THROW(CallRPC("z_validateaddress toomany args"), runtime_error); // Wallet should be empty - std::set addrs; + std::set addrs; pwalletMain->GetPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==0); @@ -381,12 +381,15 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet) LOCK2(cs_main, pwalletMain->cs_wallet); // wallet should be empty - std::set addrs; + std::set addrs; pwalletMain->GetPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==0); // wallet should have one key - auto addr = pwalletMain->GenerateNewZKey(); + auto address = pwalletMain->GenerateNewZKey(); + BOOST_CHECK(IsValidPaymentAddress(address)); + BOOST_ASSERT(boost::get(&address) != nullptr); + auto addr = boost::get(address); pwalletMain->GetPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==1); @@ -411,7 +414,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet) BOOST_CHECK_NO_THROW(CallRPC(string("z_exportwallet ") + tmpfilename.string())); - libzcash::SpendingKey key; + libzcash::SproutSpendingKey key; BOOST_CHECK(pwalletMain->GetSpendingKey(addr, key)); std::string s1 = EncodePaymentAddress(addr); @@ -456,7 +459,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) BOOST_CHECK_THROW(CallRPC("z_importwallet toomany args"), runtime_error); // create a random key locally - auto testSpendingKey = libzcash::SpendingKey::random(); + auto testSpendingKey = libzcash::SproutSpendingKey::random(); auto testPaymentAddress = testSpendingKey.address(); std::string testAddr = EncodePaymentAddress(testPaymentAddress); std::string testKey = EncodeSpendingKey(testSpendingKey); @@ -485,7 +488,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) file << std::flush; // wallet should currently be empty - std::set addrs; + std::set addrs; pwalletMain->GetPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==0); @@ -497,11 +500,14 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) BOOST_CHECK(addrs.size()==1); // check that we have the spending key for the address - auto addr = *DecodePaymentAddress(testAddr); + auto address = DecodePaymentAddress(testAddr); + BOOST_CHECK(IsValidPaymentAddress(address)); + BOOST_ASSERT(boost::get(&address) != nullptr); + auto addr = boost::get(address); BOOST_CHECK(pwalletMain->HaveSpendingKey(addr)); // Verify the spending key is the same as the test data - libzcash::SpendingKey k; + libzcash::SproutSpendingKey k; BOOST_CHECK(pwalletMain->GetSpendingKey(addr, k)); BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k)); } @@ -526,7 +532,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) BOOST_CHECK_THROW(CallRPC("z_exportkey toomany args"), runtime_error); // error if invalid args - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); std::string prefix = std::string("z_importkey ") + EncodeSpendingKey(sk) + " yes "; BOOST_CHECK_THROW(CallRPC(prefix + "-1"), runtime_error); BOOST_CHECK_THROW(CallRPC(prefix + "2147483647"), runtime_error); // allowed, but > height of active chain tip @@ -534,14 +540,14 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) BOOST_CHECK_THROW(CallRPC(prefix + "100badchars"), runtime_error); // wallet should currently be empty - std::set addrs; + std::set addrs; pwalletMain->GetPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==0); // verify import and export key for (int i = 0; i < n1; i++) { // create a random key locally - auto testSpendingKey = libzcash::SpendingKey::random(); + auto testSpendingKey = libzcash::SproutSpendingKey::random(); auto testPaymentAddress = testSpendingKey.address(); std::string testAddr = EncodePaymentAddress(testPaymentAddress); std::string testKey = EncodeSpendingKey(testSpendingKey); @@ -590,7 +596,10 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) // Add one more address BOOST_CHECK_NO_THROW(retValue = CallRPC("z_getnewaddress")); std::string newaddress = retValue.get_str(); - auto newAddr = *DecodePaymentAddress(newaddress); + auto address = DecodePaymentAddress(newaddress); + BOOST_CHECK(IsValidPaymentAddress(address)); + BOOST_ASSERT(boost::get(&address) != nullptr); + auto newAddr = boost::get(address); BOOST_CHECK(pwalletMain->HaveSpendingKey(newAddr)); // Check if too many args @@ -1217,7 +1226,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_zkeys) int n = 100; // wallet should currently be empty - std::set addrs; + std::set addrs; pwalletMain->GetPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==0); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 4702f10e5..fa1238edc 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -342,8 +342,8 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification) // construct a merkle tree ZCIncrementalMerkleTree merkleTree; - libzcash::SpendingKey k = libzcash::SpendingKey::random(); - libzcash::PaymentAddress addr = k.address(); + auto k = libzcash::SproutSpendingKey::random(); + auto addr = k.address(); libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256()); diff --git a/src/utiltest.cpp b/src/utiltest.cpp index e1b7b8275..6f43afbfa 100644 --- a/src/utiltest.cpp +++ b/src/utiltest.cpp @@ -7,7 +7,7 @@ #include "consensus/upgrades.h" CWalletTx GetValidReceive(ZCJoinSplit& params, - const libzcash::SpendingKey& sk, CAmount value, + const libzcash::SproutSpendingKey& sk, CAmount value, bool randomInputs) { CMutableTransaction mtx; mtx.nVersion = 2; // Enable JoinSplits @@ -62,7 +62,7 @@ CWalletTx GetValidReceive(ZCJoinSplit& params, } libzcash::SproutNote GetNote(ZCJoinSplit& params, - const libzcash::SpendingKey& sk, + const libzcash::SproutSpendingKey& sk, const CTransaction& tx, size_t js, size_t n) { ZCNoteDecryption decryptor {sk.receiving_key()}; auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey); @@ -76,7 +76,7 @@ libzcash::SproutNote GetNote(ZCJoinSplit& params, } CWalletTx GetValidSpend(ZCJoinSplit& params, - const libzcash::SpendingKey& sk, + const libzcash::SproutSpendingKey& sk, const libzcash::SproutNote& note, CAmount value) { CMutableTransaction mtx; mtx.vout.resize(2); @@ -97,12 +97,12 @@ CWalletTx GetValidSpend(ZCJoinSplit& params, { if (note.value() > value) { - libzcash::SpendingKey dummykey = libzcash::SpendingKey::random(); - libzcash::PaymentAddress dummyaddr = dummykey.address(); + libzcash::SproutSpendingKey dummykey = libzcash::SproutSpendingKey::random(); + libzcash::SproutPaymentAddress dummyaddr = dummykey.address(); dummyout = libzcash::JSOutput(dummyaddr, note.value() - value); } else if (note.value() < value) { - libzcash::SpendingKey dummykey = libzcash::SpendingKey::random(); - libzcash::PaymentAddress dummyaddr = dummykey.address(); + libzcash::SproutSpendingKey dummykey = libzcash::SproutSpendingKey::random(); + libzcash::SproutPaymentAddress dummyaddr = dummykey.address(); libzcash::SproutNote dummynote(dummyaddr.a_pk, (value - note.value()), uint256(), uint256()); tree.append(dummynote.cm()); dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey); diff --git a/src/utiltest.h b/src/utiltest.h index d9da2a1de..722930609 100644 --- a/src/utiltest.h +++ b/src/utiltest.h @@ -8,11 +8,11 @@ #include "zcash/NoteEncryption.hpp" CWalletTx GetValidReceive(ZCJoinSplit& params, - const libzcash::SpendingKey& sk, CAmount value, + const libzcash::SproutSpendingKey& sk, CAmount value, bool randomInputs); libzcash::SproutNote GetNote(ZCJoinSplit& params, - const libzcash::SpendingKey& sk, + const libzcash::SproutSpendingKey& sk, const CTransaction& tx, size_t js, size_t n); CWalletTx GetValidSpend(ZCJoinSplit& params, - const libzcash::SpendingKey& sk, + const libzcash::SproutSpendingKey& sk, const libzcash::SproutNote& note, CAmount value); diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index aa8abf782..4ea230c4f 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -80,9 +80,11 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress( if (!isToTaddr_) { auto address = DecodePaymentAddress(std::get<0>(recipient)); - if (address) { + if (IsValidPaymentAddress(address)) { isToZaddr_ = true; - toPaymentAddress_ = *address; + // TODO: Add Sapling support. For now, ensure we can later convert freely. + assert(boost::get(&address) != nullptr); + toPaymentAddress_ = address; } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address"); } @@ -307,7 +309,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() info.vpub_old = sendAmount; info.vpub_new = 0; - JSOutput jso = JSOutput(toPaymentAddress_, sendAmount); + JSOutput jso = JSOutput(boost::get(toPaymentAddress_), sendAmount); if (hexMemo.size() > 0) { jso.memo = get_memo_from_hex_string(hexMemo); } @@ -326,6 +328,8 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() // Copy zinputs to more flexible containers std::deque zInputsDeque; for (auto o : noteInputs_) { + // TODO: Add Sapling support. For now, ensure we can later convert freely. + assert(boost::get(&std::get<3>(o)) != nullptr); zInputsDeque.push_back(o); } @@ -365,8 +369,8 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() // At this point, we are guaranteed to have at least one input note. // Use address of first input note as the temporary change address. - SpendingKey changeKey = std::get<3>(zInputsDeque.front()); - PaymentAddress changeAddress = changeKey.address(); + SproutSpendingKey changeKey = boost::get(std::get<3>(zInputsDeque.front())); + SproutPaymentAddress changeAddress = changeKey.address(); CAmount vpubOldTarget = 0; CAmount vpubNewTarget = 0; @@ -481,7 +485,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() // Consume spendable non-change notes // std::vector vInputNotes; - std::vector vInputZKeys; + std::vector vInputZKeys; std::vector vOutPoints; std::vector> vInputWitnesses; uint256 inputAnchor; @@ -491,7 +495,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() JSOutPoint jso = std::get<0>(t); SproutNote note = std::get<1>(t); CAmount noteFunds = std::get<2>(t); - SpendingKey zkey = std::get<3>(t); + SproutSpendingKey zkey = boost::get(std::get<3>(t)); zInputsDeque.pop_front(); MergeToAddressWitnessAnchorData wad = jsopWitnessAnchorMap[jso.ToString()]; @@ -590,7 +594,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() // If this is the final output, set the target and memo if (isToZaddr_ && vpubNewProcessed) { outputType = "target"; - jso.addr = toPaymentAddress_; + jso.addr = boost::get(toPaymentAddress_); if (!hexMemo.empty()) { jso.memo = get_memo_from_hex_string(hexMemo); } @@ -852,7 +856,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( // placeholder for txid will be filled in later when tx has been finalized and signed. PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; JSOutput output = outputs[mapped_index]; - libzcash::PaymentAddress zaddr = output.addr; // randomized output + libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index e6c8207e5..541a9541a 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -37,7 +37,7 @@ struct MergeToAddressJSInfo { std::vector vjsin; std::vector vjsout; std::vector notes; - std::vector zkeys; + std::vector zkeys; CAmount vpub_old = 0; CAmount vpub_new = 0; }; diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index e7aad3760..1df7bcd93 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -81,11 +81,13 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( if (!isfromtaddr_) { auto address = DecodePaymentAddress(fromAddress); - if (address) { - PaymentAddress addr = *address; + if (IsValidPaymentAddress(address)) { + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&address) != nullptr); + SproutPaymentAddress addr = boost::get(address); // We don't need to lock on the wallet as spending key related methods are thread-safe - SpendingKey key; + SproutSpendingKey key; if (!pwalletMain->GetSpendingKey(addr, key)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, no spending key found for zaddr"); } @@ -401,6 +403,9 @@ bool AsyncRPCOperation_sendmany::main_impl() { } std::deque zOutputsDeque; for (auto o : z_outputs_) { + // TODO: Add Sapling support. For now, ensure we can later convert freely. + auto addr = DecodePaymentAddress(std::get<0>(o)); + assert(boost::get(&addr) != nullptr); zOutputsDeque.push_back(o); } @@ -468,8 +473,8 @@ bool AsyncRPCOperation_sendmany::main_impl() { std::string hexMemo = std::get<2>(smr); zOutputsDeque.pop_front(); - PaymentAddress pa = *DecodePaymentAddress(address); - JSOutput jso = JSOutput(pa, value); + PaymentAddress pa = DecodePaymentAddress(address); + JSOutput jso = JSOutput(boost::get(pa), value); if (hexMemo.size() > 0) { jso.memo = get_memo_from_hex_string(hexMemo); } @@ -569,7 +574,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries) // Decrypt the change note's ciphertext to retrieve some data we need - ZCNoteDecryption decryptor(spendingkey_.receiving_key()); + ZCNoteDecryption decryptor(boost::get(spendingkey_).receiving_key()); auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey); try { SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( @@ -579,7 +584,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { hSig, (unsigned char) changeOutputIndex); - SproutNote note = plaintext.note(frompaymentaddress_); + SproutNote note = plaintext.note(boost::get(frompaymentaddress_)); info.notes.push_back(note); jsInputValue += plaintext.value(); @@ -727,8 +732,8 @@ bool AsyncRPCOperation_sendmany::main_impl() { assert(value==0); info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new } else { - PaymentAddress pa = *DecodePaymentAddress(address); - JSOutput jso = JSOutput(pa, value); + PaymentAddress pa = DecodePaymentAddress(address); + JSOutput jso = JSOutput(boost::get(pa), value); if (hexMemo.size() > 0) { jso.memo = get_memo_from_hex_string(hexMemo); } @@ -737,7 +742,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { // create output for any change if (jsChange>0) { - info.vjsout.push_back(JSOutput(frompaymentaddress_, jsChange)); + info.vjsout.push_back(JSOutput(boost::get(frompaymentaddress_), jsChange)); LogPrint("zrpcunsafe", "%s: generating note for change (amount=%s)\n", getId(), @@ -886,7 +891,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { } for (CSproutNotePlaintextEntry & entry : entries) { - z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(frompaymentaddress_), CAmount(entry.plaintext.value()))); + z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(boost::get(frompaymentaddress_)), CAmount(entry.plaintext.value()))); std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); LogPrint("zrpcunsafe", "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n", getId(), @@ -948,7 +953,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( if (!witnesses[i]) { throw runtime_error("joinsplit input could not be found in tree"); } - info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], spendingkey_)); + info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], boost::get(spendingkey_))); } // Make sure there are two inputs and two outputs @@ -1077,7 +1082,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( // placeholder for txid will be filled in later when tx has been finalized and signed. PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; JSOutput output = outputs[mapped_index]; - libzcash::PaymentAddress zaddr = output.addr; // randomized output + libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 9546a4491..2cb5a7499 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -73,8 +73,10 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase( // Check the destination address is valid for this network i.e. not testnet being used on mainnet auto address = DecodePaymentAddress(toAddress); - if (address) { - tozaddr_ = *address; + if (IsValidPaymentAddress(address)) { + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&address) != nullptr); + tozaddr_ = address; } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid to address"); } @@ -233,7 +235,7 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() { ShieldCoinbaseJSInfo info; info.vpub_old = sendAmount; info.vpub_new = 0; - JSOutput jso = JSOutput(tozaddr_, sendAmount); + JSOutput jso = JSOutput(boost::get(tozaddr_), sendAmount); info.vjsout.push_back(jso); obj = perform_joinsplit(info); @@ -448,7 +450,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf // placeholder for txid will be filled in later when tx has been finalized and signed. PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; JSOutput output = outputs[mapped_index]; - libzcash::PaymentAddress zaddr = output.addr; // randomized output + libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 69a2649b1..57ce0c428 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -136,8 +136,8 @@ static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector& vchCryptedSecret, - const libzcash::PaymentAddress& address, - libzcash::SpendingKey& sk) + const libzcash::SproutPaymentAddress& address, + libzcash::SproutSpendingKey& sk) { CKeyingMaterial vchSecret; if(!DecryptSecret(vMasterKey, vchCryptedSecret, address.GetHash(), vchSecret)) @@ -203,9 +203,9 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) CryptedSpendingKeyMap::const_iterator skmi = mapCryptedSpendingKeys.begin(); for (; skmi != mapCryptedSpendingKeys.end(); ++skmi) { - const libzcash::PaymentAddress &address = (*skmi).first; + const libzcash::SproutPaymentAddress &address = (*skmi).first; const std::vector &vchCryptedSecret = (*skmi).second; - libzcash::SpendingKey sk; + libzcash::SproutSpendingKey sk; if (!DecryptSpendingKey(vMasterKeyIn, vchCryptedSecret, address, sk)) { keyFail = true; @@ -298,7 +298,7 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co return false; } -bool CCryptoKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk) +bool CCryptoKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk) { { LOCK(cs_SpendingKeyStore); @@ -322,7 +322,7 @@ bool CCryptoKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk) return true; } -bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::PaymentAddress &address, +bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret) { @@ -337,7 +337,7 @@ bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::PaymentAddress &addr return true; } -bool CCryptoKeyStore::GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const +bool CCryptoKeyStore::GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const { { LOCK(cs_SpendingKeyStore); @@ -376,11 +376,11 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) mapKeys.clear(); BOOST_FOREACH(SpendingKeyMap::value_type& mSpendingKey, mapSpendingKeys) { - const libzcash::SpendingKey &sk = mSpendingKey.second; + const libzcash::SproutSpendingKey &sk = mSpendingKey.second; CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << sk; CKeyingMaterial vchSecret(ss.begin(), ss.end()); - libzcash::PaymentAddress address = sk.address(); + libzcash::SproutPaymentAddress address = sk.address(); std::vector vchCryptedSecret; if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret)) return false; diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index e0d91ee5a..e42f5868a 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -200,11 +200,11 @@ public: mi++; } } - virtual bool AddCryptedSpendingKey(const libzcash::PaymentAddress &address, + virtual bool AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); - bool AddSpendingKey(const libzcash::SpendingKey &sk); - bool HaveSpendingKey(const libzcash::PaymentAddress &address) const + bool AddSpendingKey(const libzcash::SproutSpendingKey &sk); + bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const { { LOCK(cs_SpendingKeyStore); @@ -214,8 +214,8 @@ public: } return false; } - bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const; - void GetPaymentAddresses(std::set &setAddress) const + bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const; + void GetPaymentAddresses(std::set &setAddress) const { if (!IsCrypted()) { diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index ceea292d8..b2987cc17 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -68,22 +68,22 @@ public: } }; -CWalletTx GetValidReceive(const libzcash::SpendingKey& sk, CAmount value, bool randomInputs) { +CWalletTx GetValidReceive(const libzcash::SproutSpendingKey& sk, CAmount value, bool randomInputs) { return GetValidReceive(*params, sk, value, randomInputs); } -libzcash::SproutNote GetNote(const libzcash::SpendingKey& sk, +libzcash::SproutNote GetNote(const libzcash::SproutSpendingKey& sk, const CTransaction& tx, size_t js, size_t n) { return GetNote(*params, sk, tx, js, n); } -CWalletTx GetValidSpend(const libzcash::SpendingKey& sk, +CWalletTx GetValidSpend(const libzcash::SproutSpendingKey& sk, const libzcash::SproutNote& note, CAmount value) { return GetValidSpend(*params, sk, note, value); } JSOutPoint CreateValidBlock(TestWallet& wallet, - const libzcash::SpendingKey& sk, + const libzcash::SproutSpendingKey& sk, const CBlockIndex& index, CBlock& block, ZCIncrementalMerkleTree& tree) { @@ -112,7 +112,7 @@ TEST(wallet_tests, setup_datadir_location_run_as_first_test) { } TEST(wallet_tests, note_data_serialisation) { - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto wtx = GetValidReceive(sk, 10, true); auto note = GetNote(sk, wtx, 0, 1); auto nullifier = note.nullifier(sk); @@ -138,7 +138,7 @@ TEST(wallet_tests, note_data_serialisation) { TEST(wallet_tests, find_unspent_notes) { SelectParams(CBaseChainParams::TESTNET); CWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -295,7 +295,7 @@ TEST(wallet_tests, find_unspent_notes) { TEST(wallet_tests, set_note_addrs_in_cwallettx) { - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto wtx = GetValidReceive(sk, 10, true); auto note = GetNote(sk, wtx, 0, 1); auto nullifier = note.nullifier(sk); @@ -315,7 +315,7 @@ TEST(wallet_tests, set_invalid_note_addrs_in_cwallettx) { EXPECT_EQ(0, wtx.mapNoteData.size()); mapNoteData_t noteData; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; CNoteData nd {sk.address(), uint256()}; noteData[jsoutpt] = nd; @@ -326,7 +326,7 @@ TEST(wallet_tests, set_invalid_note_addrs_in_cwallettx) { TEST(wallet_tests, GetNoteNullifier) { CWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto address = sk.address(); auto dec = ZCNoteDecryption(sk.receiving_key()); @@ -357,8 +357,8 @@ TEST(wallet_tests, GetNoteNullifier) { TEST(wallet_tests, FindMyNotes) { CWallet wallet; - auto sk = libzcash::SpendingKey::random(); - auto sk2 = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); + auto sk2 = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk2); auto wtx = GetValidReceive(sk, 10, true); @@ -384,7 +384,7 @@ TEST(wallet_tests, FindMyNotesInEncryptedWallet) { uint256 r {GetRandHash()}; CKeyingMaterial vMasterKey (r.begin(), r.end()); - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); ASSERT_TRUE(wallet.EncryptKeys(vMasterKey)); @@ -412,7 +412,7 @@ TEST(wallet_tests, FindMyNotesInEncryptedWallet) { TEST(wallet_tests, get_conflicted_notes) { CWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -443,7 +443,7 @@ TEST(wallet_tests, get_conflicted_notes) { TEST(wallet_tests, nullifier_is_spent) { CWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -483,7 +483,7 @@ TEST(wallet_tests, nullifier_is_spent) { TEST(wallet_tests, navigate_from_nullifier_to_note) { CWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -509,7 +509,7 @@ TEST(wallet_tests, navigate_from_nullifier_to_note) { TEST(wallet_tests, spent_note_is_from_me) { CWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -537,7 +537,7 @@ TEST(wallet_tests, spent_note_is_from_me) { TEST(wallet_tests, cached_witnesses_empty_chain) { TestWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -590,7 +590,7 @@ TEST(wallet_tests, cached_witnesses_chain_tip) { CBlock block1; ZCIncrementalMerkleTree tree; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); { @@ -672,7 +672,7 @@ TEST(wallet_tests, CachedWitnessesDecrementFirst) { CBlockIndex index2(block2); ZCIncrementalMerkleTree tree; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); { @@ -744,7 +744,7 @@ TEST(wallet_tests, CachedWitnessesCleanIndex) { ZCIncrementalMerkleTree riTree = tree; std::vector> witnesses; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); // Generate a chain @@ -813,7 +813,7 @@ TEST(wallet_tests, CachedWitnessesCleanIndex) { TEST(wallet_tests, ClearNoteWitnessCache) { TestWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -862,7 +862,7 @@ TEST(wallet_tests, WriteWitnessCache) { MockWalletDB walletdb; CBlockLocator loc; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -939,7 +939,7 @@ TEST(wallet_tests, UpdateNullifierNoteMap) { uint256 r {GetRandHash()}; CKeyingMaterial vMasterKey (r.begin(), r.end()); - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); ASSERT_TRUE(wallet.EncryptKeys(vMasterKey)); @@ -972,7 +972,7 @@ TEST(wallet_tests, UpdateNullifierNoteMap) { TEST(wallet_tests, UpdatedNoteData) { TestWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -1019,7 +1019,7 @@ TEST(wallet_tests, UpdatedNoteData) { TEST(wallet_tests, MarkAffectedTransactionsDirty) { TestWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); @@ -1050,7 +1050,7 @@ TEST(wallet_tests, MarkAffectedTransactionsDirty) { TEST(wallet_tests, NoteLocking) { TestWallet wallet; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); auto wtx = GetValidReceive(sk, 10, true); diff --git a/src/wallet/gtest/test_wallet_zkeys.cpp b/src/wallet/gtest/test_wallet_zkeys.cpp index 474656474..efc06b962 100644 --- a/src/wallet/gtest/test_wallet_zkeys.cpp +++ b/src/wallet/gtest/test_wallet_zkeys.cpp @@ -20,12 +20,14 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) { CWallet wallet; // wallet should be empty - std::set addrs; + std::set addrs; wallet.GetPaymentAddresses(addrs); ASSERT_EQ(0, addrs.size()); // wallet should have one key - auto addr = wallet.GenerateNewZKey(); + auto address = wallet.GenerateNewZKey(); + ASSERT_NE(boost::get(&address), nullptr); + auto addr = boost::get(address); wallet.GetPaymentAddresses(addrs); ASSERT_EQ(1, addrs.size()); @@ -33,7 +35,7 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) { ASSERT_TRUE(wallet.HaveSpendingKey(addr)); // manually add new spending key to wallet - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); ASSERT_TRUE(wallet.AddZKey(sk)); // verify wallet did add it @@ -41,7 +43,7 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) { ASSERT_TRUE(wallet.HaveSpendingKey(addr)); // verify spending key stored correctly - libzcash::SpendingKey keyOut; + libzcash::SproutSpendingKey keyOut; wallet.GetSpendingKey(addr, keyOut); ASSERT_EQ(sk, keyOut); @@ -51,7 +53,7 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) { ASSERT_EQ(1, addrs.count(addr)); // Load a third key into the wallet - sk = libzcash::SpendingKey::random(); + sk = libzcash::SproutSpendingKey::random(); ASSERT_TRUE(wallet.LoadZKey(sk)); // attach metadata to this third key @@ -77,12 +79,12 @@ TEST(wallet_zkeys_tests, StoreAndLoadViewingKeys) { CWallet wallet; // wallet should be empty - std::set addrs; + std::set addrs; wallet.GetPaymentAddresses(addrs); ASSERT_EQ(0, addrs.size()); // manually add new viewing key to wallet - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto vk = sk.viewing_key(); ASSERT_TRUE(wallet.AddViewingKey(vk)); @@ -93,12 +95,12 @@ TEST(wallet_zkeys_tests, StoreAndLoadViewingKeys) { ASSERT_FALSE(wallet.HaveSpendingKey(addr)); // verify viewing key stored correctly - libzcash::ViewingKey vkOut; + libzcash::SproutViewingKey vkOut; wallet.GetViewingKey(addr, vkOut); ASSERT_EQ(vk, vkOut); // Load a second viewing key into the wallet - auto sk2 = libzcash::SpendingKey::random(); + auto sk2 = libzcash::SproutSpendingKey::random(); ASSERT_TRUE(wallet.LoadViewingKey(sk2.viewing_key())); // verify wallet did add it @@ -133,7 +135,7 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) { ASSERT_TRUE(fFirstRun); // wallet should be empty - std::set addrs; + std::set addrs; wallet.GetPaymentAddresses(addrs); ASSERT_EQ(0, addrs.size()); @@ -145,7 +147,7 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) { ASSERT_EQ(1, addrs.size()); // create random key and add it to database directly, bypassing wallet - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto addr = sk.address(); int64_t now = GetTime(); CKeyMetadata meta(now); @@ -171,7 +173,7 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) { ASSERT_TRUE(wallet.HaveSpendingKey(addr)); // check key is the same - libzcash::SpendingKey keyOut; + libzcash::SproutSpendingKey keyOut; wallet.GetSpendingKey(addr, keyOut); ASSERT_EQ(sk, keyOut); @@ -205,7 +207,7 @@ TEST(wallet_zkeys_tests, WriteViewingKeyDirectToDB) { ASSERT_TRUE(fFirstRun); // create random viewing key and add it to database directly, bypassing wallet - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto vk = sk.viewing_key(); auto addr = sk.address(); int64_t now = GetTime(); @@ -223,7 +225,7 @@ TEST(wallet_zkeys_tests, WriteViewingKeyDirectToDB) { ASSERT_TRUE(wallet.HaveViewingKey(addr)); // check key is the same - libzcash::ViewingKey vkOut; + libzcash::SproutViewingKey vkOut; wallet.GetViewingKey(addr, vkOut); ASSERT_EQ(vk, vkOut); } @@ -252,12 +254,14 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) { ASSERT_TRUE(fFirstRun); // wallet should be empty - std::set addrs; + std::set addrs; wallet.GetPaymentAddresses(addrs); ASSERT_EQ(0, addrs.size()); // Add random key to the wallet - auto paymentAddress = wallet.GenerateNewZKey(); + auto address = wallet.GenerateNewZKey(); + ASSERT_NE(boost::get(&address), nullptr); + auto paymentAddress = boost::get(address); // wallet should have one key wallet.GetPaymentAddresses(addrs); @@ -274,7 +278,9 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) { // unlock wallet and then add wallet.Unlock(strWalletPass); - auto paymentAddress2 = wallet.GenerateNewZKey(); + auto address2 = wallet.GenerateNewZKey(); + ASSERT_NE(boost::get(&address2), nullptr); + auto paymentAddress2 = boost::get(address2); // Create a new wallet from the existing wallet path CWallet wallet2("wallet_crypted.dat"); @@ -292,7 +298,7 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) { ASSERT_TRUE(addrs.count(paymentAddress2)); // spending key is crypted, so we can't extract valid payment address - libzcash::SpendingKey keyOut; + libzcash::SproutSpendingKey keyOut; wallet2.GetSpendingKey(paymentAddress, keyOut); ASSERT_FALSE(paymentAddress == keyOut.address()); diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp index cfc8262b0..42e447160 100644 --- a/src/wallet/rpcdisclosure.cpp +++ b/src/wallet/rpcdisclosure.cpp @@ -253,7 +253,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) } // Check the payment address is valid - PaymentAddress zaddr = pd.payload.zaddr; + SproutPaymentAddress zaddr = pd.payload.zaddr; { o.push_back(Pair("paymentAddress", EncodePaymentAddress(zaddr))); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 0a91c92eb..c84c41e46 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -296,9 +296,11 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys // Let's see if the address is a valid Zcash spending key if (fImportZKeys) { auto spendingkey = DecodeSpendingKey(vstr[0]); - if (spendingkey) { - libzcash::SpendingKey key = *spendingkey; - libzcash::PaymentAddress addr = key.address(); + if (IsValidSpendingKey(spendingkey)) { + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&spendingkey) != nullptr); + auto key = boost::get(spendingkey); + auto addr = key.address(); if (pwalletMain->HaveSpendingKey(addr)) { LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", EncodePaymentAddress(addr)); continue; @@ -526,13 +528,13 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys) file << "\n"; if (fDumpZKeys) { - std::set addresses; + std::set addresses; pwalletMain->GetPaymentAddresses(addresses); file << "\n"; file << "# Zkeys\n"; file << "\n"; for (auto addr : addresses ) { - libzcash::SpendingKey key; + libzcash::SproutSpendingKey key; if (pwalletMain->GetSpendingKey(addr, key)) { std::string strTime = EncodeDumpTime(pwalletMain->mapZKeyMetadata[addr].nCreateTime); file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(key), strTime, EncodePaymentAddress(addr)); @@ -614,10 +616,12 @@ UniValue z_importkey(const UniValue& params, bool fHelp) string strSecret = params[0].get_str(); auto spendingkey = DecodeSpendingKey(strSecret); - if (!spendingkey) { + if (!IsValidSpendingKey(spendingkey)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key"); } - auto key = *spendingkey; + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&spendingkey) != nullptr); + auto key = boost::get(spendingkey); auto addr = key.address(); { @@ -706,10 +710,12 @@ UniValue z_importviewingkey(const UniValue& params, bool fHelp) string strVKey = params[0].get_str(); auto viewingkey = DecodeViewingKey(strVKey); - if (!viewingkey) { + if (!IsValidViewingKey(viewingkey)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid viewing key"); } - auto vkey = *viewingkey; + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&viewingkey) != nullptr); + auto vkey = boost::get(viewingkey); auto addr = vkey.address(); { @@ -766,12 +772,14 @@ UniValue z_exportkey(const UniValue& params, bool fHelp) string strAddress = params[0].get_str(); auto address = DecodePaymentAddress(strAddress); - if (!address) { + if (!IsValidPaymentAddress(address)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr"); } - auto addr = *address; + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&address) != nullptr); + auto addr = boost::get(address); - libzcash::SpendingKey k; + libzcash::SproutSpendingKey k; if (!pwalletMain->GetSpendingKey(addr, k)) throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr"); @@ -804,14 +812,16 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp) string strAddress = params[0].get_str(); auto address = DecodePaymentAddress(strAddress); - if (!address) { + if (!IsValidPaymentAddress(address)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr"); } - auto addr = *address; + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&address) != nullptr); + auto addr = boost::get(address); - libzcash::ViewingKey vk; + libzcash::SproutViewingKey vk; if (!pwalletMain->GetViewingKey(addr, vk)) { - libzcash::SpendingKey k; + libzcash::SproutSpendingKey k; if (!pwalletMain->GetSpendingKey(addr, k)) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr"); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e39693069..e372c1cf4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2522,8 +2522,10 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) } string address = o.get_str(); auto zaddr = DecodePaymentAddress(address); - if (zaddr) { - libzcash::PaymentAddress addr = *zaddr; + if (IsValidPaymentAddress(zaddr)) { + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&zaddr) != nullptr); + libzcash::SproutPaymentAddress addr = boost::get(zaddr); if (!fIncludeWatchonly && !pwalletMain->HaveSpendingKey(addr)) { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, spending key for address does not belong to wallet: ") + address); } @@ -2540,7 +2542,10 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) } else { // User did not provide zaddrs, so use default i.e. all addresses - pwalletMain->GetPaymentAddresses(zaddrs); + // TODO: Add Sapling support + std::set sproutzaddrs = {}; + pwalletMain->GetPaymentAddresses(sproutzaddrs); + zaddrs.insert(sproutzaddrs.begin(), sproutzaddrs.end()); } UniValue results(UniValue::VARR); @@ -2554,7 +2559,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) obj.push_back(Pair("jsindex", (int)entry.jsop.js )); obj.push_back(Pair("jsoutindex", (int)entry.jsop.n)); obj.push_back(Pair("confirmations", entry.nHeight)); - obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(entry.address))); + obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(boost::get(entry.address)))); obj.push_back(Pair("address", EncodePaymentAddress(entry.address))); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value())))); std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); @@ -2793,10 +2798,13 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp) LOCK(cs_main); auto spendingkey = DecodeSpendingKey(params[0].get_str()); - if (!spendingkey) { + if (!IsValidSpendingKey(spendingkey)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key"); } - SpendingKey k = *spendingkey; + if (boost::get(&spendingkey) == nullptr) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys"); + } + SproutSpendingKey k = boost::get(spendingkey); uint256 epk; unsigned char nonce; @@ -2826,7 +2834,7 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp) h_sig, nonce ); - PaymentAddress payment_addr = k.address(); + SproutPaymentAddress payment_addr = k.address(); SproutNote decrypted_note = npt.note(payment_addr); assert(pwalletMain != NULL); @@ -2902,15 +2910,18 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) std::vector vjsin; std::vector vjsout; std::vector notes; - std::vector keys; + std::vector keys; std::vector commitments; for (const string& name_ : inputs.getKeys()) { auto spendingkey = DecodeSpendingKey(inputs[name_].get_str()); - if (!spendingkey) { + if (!IsValidSpendingKey(spendingkey)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key"); } - SpendingKey k = *spendingkey; + if (boost::get(&spendingkey) == nullptr) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys"); + } + SproutSpendingKey k = boost::get(spendingkey); keys.push_back(k); @@ -2921,7 +2932,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) ssData >> npt; } - PaymentAddress addr = k.address(); + SproutPaymentAddress addr = k.address(); SproutNote note = npt.note(addr); notes.push_back(note); commitments.push_back(note.cm()); @@ -2952,12 +2963,15 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) for (const string& name_ : outputs.getKeys()) { auto addrTo = DecodePaymentAddress(name_); - if (!addrTo) { + if (!IsValidPaymentAddress(addrTo)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address."); } + if (boost::get(&addrTo) == nullptr) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout payment addresses"); + } CAmount nAmount = AmountFromValue(outputs[name_]); - vjsout.push_back(JSOutput(*addrTo, nAmount)); + vjsout.push_back(JSOutput(boost::get(addrTo), nAmount)); } while (vjsout.size() < ZC_NUM_JS_OUTPUTS) { @@ -3063,7 +3077,7 @@ UniValue zc_raw_keygen(const UniValue& params, bool fHelp) ); } - auto k = SpendingKey::random(); + auto k = SproutSpendingKey::random(); auto addr = k.address(); auto viewing_key = k.viewing_key(); @@ -3130,7 +3144,8 @@ UniValue z_listaddresses(const UniValue& params, bool fHelp) } UniValue ret(UniValue::VARR); - std::set addresses; + // TODO: Add Sapling support + std::set addresses; pwalletMain->GetPaymentAddresses(addresses); for (auto addr : addresses ) { if (fIncludeWatchonly || pwalletMain->HaveSpendingKey(addr)) { @@ -3232,11 +3247,14 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) auto fromaddress = params[0].get_str(); auto zaddr = DecodePaymentAddress(fromaddress); - if (!zaddr) { + if (!IsValidPaymentAddress(zaddr)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr."); } + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&zaddr) != nullptr); + auto sproutzaddr = boost::get(zaddr); - if (!(pwalletMain->HaveSpendingKey(*zaddr) || pwalletMain->HaveViewingKey(*zaddr))) { + if (!(pwalletMain->HaveSpendingKey(sproutzaddr) || pwalletMain->HaveViewingKey(sproutzaddr))) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found."); } @@ -3299,13 +3317,14 @@ UniValue z_getbalance(const UniValue& params, bool fHelp) bool fromTaddr = false; CTxDestination taddr = DecodeDestination(fromaddress); fromTaddr = IsValidDestination(taddr); - libzcash::PaymentAddress zaddr; if (!fromTaddr) { auto res = DecodePaymentAddress(fromaddress); - if (!res) { + if (!IsValidPaymentAddress(res)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr."); } - zaddr = *res; + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&res) != nullptr); + auto zaddr = boost::get(res); if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found."); } @@ -3534,14 +3553,16 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) bool fromTaddr = false; CTxDestination taddr = DecodeDestination(fromaddress); fromTaddr = IsValidDestination(taddr); - libzcash::PaymentAddress zaddr; + libzcash::SproutPaymentAddress zaddr; if (!fromTaddr) { auto res = DecodePaymentAddress(fromaddress); - if (!res) { + if (!IsValidPaymentAddress(res)) { // invalid throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr."); } - zaddr = *res; + // TODO: Add Sapling support. For now, ensure we can freely convert. + assert(boost::get(&res) != nullptr); + zaddr = boost::get(res); } // Check that we have the spending key @@ -3579,7 +3600,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) bool isZaddr = false; CTxDestination taddr = DecodeDestination(address); if (!IsValidDestination(taddr)) { - if (DecodePaymentAddress(address)) { + if (IsValidPaymentAddressString(address)) { isZaddr = true; } else { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address ); @@ -3773,7 +3794,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) // Validate the destination address auto destaddress = params[1].get_str(); - if (!DecodePaymentAddress(destaddress)) { + if (!IsValidPaymentAddressString(destaddress)) { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress ); } @@ -4015,10 +4036,10 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) } } else { auto zaddr = DecodePaymentAddress(address); - if (zaddr) { + if (IsValidPaymentAddress(zaddr)) { // Ignore listed z-addrs if we are using all of them if (!(useAny || useAnyNote)) { - zaddrs.insert(*zaddr); + zaddrs.insert(zaddr); } } else { throw JSONRPCError( @@ -4038,7 +4059,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) bool isToZaddr = false; CTxDestination taddr = DecodeDestination(destaddress); if (!IsValidDestination(taddr)) { - if (DecodePaymentAddress(destaddress)) { + if (IsValidPaymentAddressString(destaddress)) { isToZaddr = true; } else { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress ); @@ -4174,9 +4195,11 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) maxedOutNotesFlag = true; } else { estimatedTxSize += increase; - SpendingKey zkey; - pwalletMain->GetSpendingKey(entry.address, zkey); - noteInputs.emplace_back(entry.jsop, entry.plaintext.note(entry.address), nValue, zkey); + // TODO: Add Sapling support + auto zaddr = boost::get(entry.address); + SproutSpendingKey zkey; + pwalletMain->GetSpendingKey(zaddr, zkey); + noteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey); mergedNoteValue += nValue; } } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index eb9093235..27f96af58 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -83,7 +83,8 @@ const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const libzcash::PaymentAddress CWallet::GenerateNewZKey() { AssertLockHeld(cs_wallet); // mapZKeyMetadata - auto k = SpendingKey::random(); + // TODO: Add Sapling support + auto k = SproutSpendingKey::random(); auto addr = k.address(); // Check for collision, even though it is unlikely to ever occur @@ -100,7 +101,8 @@ libzcash::PaymentAddress CWallet::GenerateNewZKey() } // Add spending key to keystore and persist to disk -bool CWallet::AddZKey(const libzcash::SpendingKey &key) +// TODO: Add Sapling support +bool CWallet::AddZKey(const libzcash::SproutSpendingKey &key) { AssertLockHeld(cs_wallet); // mapZKeyMetadata auto addr = key.address(); @@ -194,7 +196,7 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, } -bool CWallet::AddCryptedSpendingKey(const libzcash::PaymentAddress &address, +bool CWallet::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret) { @@ -229,7 +231,7 @@ bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta) return true; } -bool CWallet::LoadZKeyMetadata(const PaymentAddress &addr, const CKeyMetadata &meta) +bool CWallet::LoadZKeyMetadata(const SproutPaymentAddress &addr, const CKeyMetadata &meta) { AssertLockHeld(cs_wallet); // mapZKeyMetadata mapZKeyMetadata[addr] = meta; @@ -241,17 +243,17 @@ bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) +bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret) { return CCryptoKeyStore::AddCryptedSpendingKey(addr, rk, vchCryptedSecret); } -bool CWallet::LoadZKey(const libzcash::SpendingKey &key) +bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key) { return CCryptoKeyStore::AddSpendingKey(key); } -bool CWallet::AddViewingKey(const libzcash::ViewingKey &vk) +bool CWallet::AddViewingKey(const libzcash::SproutViewingKey &vk) { if (!CCryptoKeyStore::AddViewingKey(vk)) { return false; @@ -263,7 +265,7 @@ bool CWallet::AddViewingKey(const libzcash::ViewingKey &vk) return CWalletDB(strWalletFile).WriteViewingKey(vk); } -bool CWallet::RemoveViewingKey(const libzcash::ViewingKey &vk) +bool CWallet::RemoveViewingKey(const libzcash::SproutViewingKey &vk) { AssertLockHeld(cs_wallet); if (!CCryptoKeyStore::RemoveViewingKey(vk)) { @@ -278,7 +280,7 @@ bool CWallet::RemoveViewingKey(const libzcash::ViewingKey &vk) return true; } -bool CWallet::LoadViewingKey(const libzcash::ViewingKey &vk) +bool CWallet::LoadViewingKey(const libzcash::SproutViewingKey &vk) { return CCryptoKeyStore::AddViewingKey(vk); } @@ -1257,7 +1259,7 @@ void CWallet::EraseFromWallet(const uint256 &hash) * Throws std::runtime_error if the decryptor doesn't match this note */ boost::optional CWallet::GetNoteNullifier(const JSDescription& jsdesc, - const libzcash::PaymentAddress& address, + const libzcash::SproutPaymentAddress& address, const ZCNoteDecryption& dec, const uint256& hSig, uint8_t n) const @@ -1273,7 +1275,7 @@ boost::optional CWallet::GetNoteNullifier(const JSDescription& jsdesc, // SpendingKeys are only available if: // - We have them (this isn't a viewing key) // - The wallet is unlocked - libzcash::SpendingKey key; + libzcash::SproutSpendingKey key; if (GetSpendingKey(address, key)) { ret = note.nullifier(key); } @@ -3715,7 +3717,7 @@ void CWallet::GetFilteredNotes(std::vector & outEntri std::set filterAddresses; if (address.length() > 0) { - filterAddresses.insert(*DecodePaymentAddress(address)); + filterAddresses.insert(DecodePaymentAddress(address)); } GetFilteredNotes(outEntries, filterAddresses, minDepth, ignoreSpent, ignoreUnspendable); @@ -3749,7 +3751,7 @@ void CWallet::GetFilteredNotes( for (auto & pair : wtx.mapNoteData) { JSOutPoint jsop = pair.first; CNoteData nd = pair.second; - PaymentAddress pa = nd.address; + SproutPaymentAddress pa = nd.address; // skip notes which belong to a different payment address in the wallet if (!(filterAddresses.empty() || filterAddresses.count(pa))) { @@ -3830,7 +3832,7 @@ void CWallet::GetUnspentFilteredNotes( for (auto & pair : wtx.mapNoteData) { JSOutPoint jsop = pair.first; CNoteData nd = pair.second; - PaymentAddress pa = nd.address; + SproutPaymentAddress pa = nd.address; // skip notes which belong to a different payment address in the wallet if (!(filterAddresses.empty() || filterAddresses.count(pa))) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index a9b8bc7e1..df99a001f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -199,7 +199,7 @@ public: class CNoteData { public: - libzcash::PaymentAddress address; + libzcash::SproutPaymentAddress address; /** * Cached note nullifier. May not be set if the wallet was not unlocked when @@ -233,9 +233,9 @@ public: int witnessHeight; CNoteData() : address(), nullifier(), witnessHeight {-1} { } - CNoteData(libzcash::PaymentAddress a) : + CNoteData(libzcash::SproutPaymentAddress a) : address {a}, nullifier(), witnessHeight {-1} { } - CNoteData(libzcash::PaymentAddress a, uint256 n) : + CNoteData(libzcash::SproutPaymentAddress a, uint256 n) : address {a}, nullifier {n}, witnessHeight {-1} { } ADD_SERIALIZE_METHODS; @@ -268,14 +268,14 @@ typedef std::map mapNoteData_t; struct CSproutNotePlaintextEntry { JSOutPoint jsop; - libzcash::PaymentAddress address; + libzcash::SproutPaymentAddress address; libzcash::SproutNotePlaintext plaintext; }; /** Decrypted note, location in a transaction, and confirmation height. */ struct CUnspentSproutNotePlaintextEntry { JSOutPoint jsop; - libzcash::PaymentAddress address; + libzcash::SproutPaymentAddress address; libzcash::SproutNotePlaintext plaintext; int nHeight; }; @@ -785,7 +785,7 @@ public: std::set setKeyPool; std::map mapKeyMetadata; - std::map mapZKeyMetadata; + std::map mapZKeyMetadata; typedef std::map MasterKeyMap; MasterKeyMap mapMasterKeys; @@ -962,21 +962,21 @@ public: //! Generates a new zaddr libzcash::PaymentAddress GenerateNewZKey(); //! Adds spending key to the store, and saves it to disk - bool AddZKey(const libzcash::SpendingKey &key); + bool AddZKey(const libzcash::SproutSpendingKey &key); //! Adds spending key to the store, without saving it to disk (used by LoadWallet) - bool LoadZKey(const libzcash::SpendingKey &key); + bool LoadZKey(const libzcash::SproutSpendingKey &key); //! Load spending key metadata (used by LoadWallet) - bool LoadZKeyMetadata(const libzcash::PaymentAddress &addr, const CKeyMetadata &meta); + bool LoadZKeyMetadata(const libzcash::SproutPaymentAddress &addr, const CKeyMetadata &meta); //! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet) - bool LoadCryptedZKey(const libzcash::PaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); + bool LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); //! Adds an encrypted spending key to the store, and saves it to disk (virtual method, declared in crypter.h) - bool AddCryptedSpendingKey(const libzcash::PaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); + bool AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); //! Adds a viewing key to the store, and saves it to disk. - bool AddViewingKey(const libzcash::ViewingKey &vk); - bool RemoveViewingKey(const libzcash::ViewingKey &vk); + 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::ViewingKey &dest); + bool LoadViewingKey(const libzcash::SproutViewingKey &dest); /** * Increment the next transaction order id @@ -1039,7 +1039,7 @@ public: boost::optional GetNoteNullifier( const JSDescription& jsdesc, - const libzcash::PaymentAddress& address, + const libzcash::SproutPaymentAddress& address, const ZCNoteDecryption& dec, const uint256& hSig, uint8_t n) const; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 7bb222651..568843f74 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -105,7 +105,7 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, return true; } -bool CWalletDB::WriteCryptedZKey(const libzcash::PaymentAddress & addr, +bool CWalletDB::WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr, const libzcash::ReceivingKey &rk, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta) @@ -131,7 +131,7 @@ bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); } -bool CWalletDB::WriteZKey(const libzcash::PaymentAddress& addr, const libzcash::SpendingKey& key, const CKeyMetadata &keyMeta) +bool CWalletDB::WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta) { nWalletDBUpdated++; @@ -142,13 +142,13 @@ bool CWalletDB::WriteZKey(const libzcash::PaymentAddress& addr, const libzcash:: return Write(std::make_pair(std::string("zkey"), addr), key, false); } -bool CWalletDB::WriteViewingKey(const libzcash::ViewingKey &vk) +bool CWalletDB::WriteViewingKey(const libzcash::SproutViewingKey &vk) { nWalletDBUpdated++; return Write(std::make_pair(std::string("vkey"), vk), '1'); } -bool CWalletDB::EraseViewingKey(const libzcash::ViewingKey &vk) +bool CWalletDB::EraseViewingKey(const libzcash::SproutViewingKey &vk) { nWalletDBUpdated++; return Erase(std::make_pair(std::string("vkey"), vk)); @@ -485,7 +485,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "vkey") { - libzcash::ViewingKey vk; + libzcash::SproutViewingKey vk; ssKey >> vk; char fYes; ssValue >> fYes; @@ -498,9 +498,9 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "zkey") { - libzcash::PaymentAddress addr; + libzcash::SproutPaymentAddress addr; ssKey >> addr; - libzcash::SpendingKey key; + libzcash::SproutSpendingKey key; ssValue >> key; if (!pwallet->LoadZKey(key)) @@ -607,7 +607,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "czkey") { - libzcash::PaymentAddress addr; + libzcash::SproutPaymentAddress addr; ssKey >> addr; // Deserialization of a pair is just one item after another uint256 rkValue; @@ -641,7 +641,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "zkeymeta") { - libzcash::PaymentAddress addr; + libzcash::SproutPaymentAddress addr; ssKey >> addr; CKeyMetadata keyMeta; ssValue >> keyMeta; diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index c388921f0..318993a65 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -133,14 +133,14 @@ public: static bool Recover(CDBEnv& dbenv, const std::string& filename); /// Write spending key to wallet database, where key is payment address and value is spending key. - bool WriteZKey(const libzcash::PaymentAddress& addr, const libzcash::SpendingKey& key, const CKeyMetadata &keyMeta); - bool WriteCryptedZKey(const libzcash::PaymentAddress & addr, + bool WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta); + bool WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr, const libzcash::ReceivingKey & rk, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta); - bool WriteViewingKey(const libzcash::ViewingKey &vk); - bool EraseViewingKey(const libzcash::ViewingKey &vk); + bool WriteViewingKey(const libzcash::SproutViewingKey &vk); + bool EraseViewingKey(const libzcash::SproutViewingKey &vk); private: CWalletDB(const CWalletDB&); diff --git a/src/zcash/Address.cpp b/src/zcash/Address.cpp index baefeae4e..270119512 100644 --- a/src/zcash/Address.cpp +++ b/src/zcash/Address.cpp @@ -6,7 +6,7 @@ namespace libzcash { -uint256 PaymentAddress::GetHash() const { +uint256 SproutPaymentAddress::GetHash() const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << *this; return Hash(ss.begin(), ss.end()); @@ -16,24 +16,37 @@ uint256 ReceivingKey::pk_enc() const { return ZCNoteEncryption::generate_pubkey(*this); } -PaymentAddress ViewingKey::address() const { - return PaymentAddress(a_pk, sk_enc.pk_enc()); +SproutPaymentAddress SproutViewingKey::address() const { + return SproutPaymentAddress(a_pk, sk_enc.pk_enc()); } -ReceivingKey SpendingKey::receiving_key() const { +ReceivingKey SproutSpendingKey::receiving_key() const { return ReceivingKey(ZCNoteEncryption::generate_privkey(*this)); } -ViewingKey SpendingKey::viewing_key() const { - return ViewingKey(PRF_addr_a_pk(*this), receiving_key()); +SproutViewingKey SproutSpendingKey::viewing_key() const { + return SproutViewingKey(PRF_addr_a_pk(*this), receiving_key()); } -SpendingKey SpendingKey::random() { - return SpendingKey(random_uint252()); +SproutSpendingKey SproutSpendingKey::random() { + return SproutSpendingKey(random_uint252()); } -PaymentAddress SpendingKey::address() const { +SproutPaymentAddress SproutSpendingKey::address() const { return viewing_key().address(); } } + + +bool IsValidPaymentAddress(const libzcash::PaymentAddress& zaddr) { + return zaddr.which() != 0; +} + +bool IsValidViewingKey(const libzcash::ViewingKey& vk) { + return vk.which() != 0; +} + +bool IsValidSpendingKey(const libzcash::SpendingKey& zkey) { + return zkey.which() != 0; +} diff --git a/src/zcash/Address.hpp b/src/zcash/Address.hpp index c165c20dd..1fba11d9d 100644 --- a/src/zcash/Address.hpp +++ b/src/zcash/Address.hpp @@ -5,19 +5,26 @@ #include "uint252.h" #include "serialize.h" +#include + namespace libzcash { +class InvalidEncoding { +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 SerializedViewingKeySize = 64; const size_t SerializedSpendingKeySize = 32; -class PaymentAddress { +class SproutPaymentAddress { public: uint256 a_pk; uint256 pk_enc; - PaymentAddress() : a_pk(), pk_enc() { } - PaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { } + SproutPaymentAddress() : a_pk(), pk_enc() { } + SproutPaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { } ADD_SERIALIZE_METHODS; @@ -30,10 +37,10 @@ public: //! Get the 256-bit SHA256d hash of this payment address. uint256 GetHash() const; - friend inline bool operator==(const PaymentAddress& a, const PaymentAddress& b) { + friend inline bool operator==(const SproutPaymentAddress& a, const SproutPaymentAddress& b) { return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc; } - friend inline bool operator<(const PaymentAddress& a, const PaymentAddress& b) { + friend inline bool operator<(const SproutPaymentAddress& a, const SproutPaymentAddress& b) { return (a.a_pk < b.a_pk || (a.a_pk == b.a_pk && a.pk_enc < b.pk_enc)); } @@ -47,13 +54,13 @@ public: uint256 pk_enc() const; }; -class ViewingKey { +class SproutViewingKey { public: uint256 a_pk; ReceivingKey sk_enc; - ViewingKey() : a_pk(), sk_enc() { } - ViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { } + SproutViewingKey() : a_pk(), sk_enc() { } + SproutViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { } ADD_SERIALIZE_METHODS; @@ -63,29 +70,42 @@ public: READWRITE(sk_enc); } - PaymentAddress address() const; + SproutPaymentAddress address() const; - friend inline bool operator==(const ViewingKey& a, const ViewingKey& b) { + friend inline bool operator==(const SproutViewingKey& a, const SproutViewingKey& b) { return a.a_pk == b.a_pk && a.sk_enc == b.sk_enc; } - friend inline bool operator<(const ViewingKey& a, const ViewingKey& b) { + friend inline bool operator<(const SproutViewingKey& a, const SproutViewingKey& b) { return (a.a_pk < b.a_pk || (a.a_pk == b.a_pk && a.sk_enc < b.sk_enc)); } }; -class SpendingKey : public uint252 { +class SproutSpendingKey : public uint252 { public: - SpendingKey() : uint252() { } - SpendingKey(uint252 a_sk) : uint252(a_sk) { } + SproutSpendingKey() : uint252() { } + SproutSpendingKey(uint252 a_sk) : uint252(a_sk) { } - static SpendingKey random(); + static SproutSpendingKey random(); ReceivingKey receiving_key() const; - ViewingKey viewing_key() const; - PaymentAddress address() const; + SproutViewingKey viewing_key() const; + SproutPaymentAddress address() const; }; +typedef boost::variant PaymentAddress; +typedef boost::variant ViewingKey; +typedef boost::variant SpendingKey; + } +/** Check whether a PaymentAddress is not an InvalidEncoding. */ +bool IsValidPaymentAddress(const libzcash::PaymentAddress& zaddr); + +/** Check whether a ViewingKey is not an InvalidEncoding. */ +bool IsValidViewingKey(const libzcash::ViewingKey& vk); + +/** Check whether a SpendingKey is not an InvalidEncoding. */ +bool IsValidSpendingKey(const libzcash::SpendingKey& zkey); + #endif // ZC_ADDRESS_H_ diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index 1dd0da0b4..a503cb455 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -370,12 +370,12 @@ SproutNote JSOutput::note(const uint252& phi, const uint256& r, size_t i, const } JSOutput::JSOutput() : addr(uint256(), uint256()), value(0) { - SpendingKey a_sk = SpendingKey::random(); + SproutSpendingKey a_sk = SproutSpendingKey::random(); addr = a_sk.address(); } JSInput::JSInput() : witness(ZCIncrementalMerkleTree().witness()), - key(SpendingKey::random()) { + key(SproutSpendingKey::random()) { note = SproutNote(key.address().a_pk, 0, random_uint256(), random_uint256()); ZCIncrementalMerkleTree dummy_tree; dummy_tree.append(note.cm()); diff --git a/src/zcash/JoinSplit.hpp b/src/zcash/JoinSplit.hpp index 28ca98e97..03c499ff0 100644 --- a/src/zcash/JoinSplit.hpp +++ b/src/zcash/JoinSplit.hpp @@ -19,12 +19,12 @@ class JSInput { public: ZCIncrementalWitness witness; SproutNote note; - SpendingKey key; + SproutSpendingKey key; JSInput(); JSInput(ZCIncrementalWitness witness, SproutNote note, - SpendingKey key) : witness(witness), note(note), key(key) { } + SproutSpendingKey key) : witness(witness), note(note), key(key) { } uint256 nullifier() const { return note.nullifier(key); @@ -33,12 +33,12 @@ public: class JSOutput { public: - PaymentAddress addr; + SproutPaymentAddress addr; uint64_t value; boost::array memo = {{0xF6}}; // 0xF6 is invalid UTF8 as per spec, rest of array is 0x00 JSOutput(); - JSOutput(PaymentAddress addr, uint64_t value) : addr(addr), value(value) { } + JSOutput(SproutPaymentAddress addr, uint64_t value) : addr(addr), value(value) { } SproutNote note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const; }; diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index 407925e15..3315a7c45 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -34,7 +34,7 @@ uint256 SproutNote::cm() const { return result; } -uint256 SproutNote::nullifier(const SpendingKey& a_sk) const { +uint256 SproutNote::nullifier(const SproutSpendingKey& a_sk) const { return PRF_nf(a_sk, rho); } @@ -46,7 +46,7 @@ SproutNotePlaintext::SproutNotePlaintext( r = note.r; } -SproutNote SproutNotePlaintext::note(const PaymentAddress& addr) const +SproutNote SproutNotePlaintext::note(const SproutPaymentAddress& addr) const { return SproutNote(addr.a_pk, value_, rho, r); } diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index 7c7f0c561..ac785fe1b 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -35,7 +35,7 @@ public: virtual uint256 cm() const override; - uint256 nullifier(const SpendingKey& a_sk) const; + uint256 nullifier(const SproutSpendingKey& a_sk) const; }; class BaseNotePlaintext { @@ -61,7 +61,7 @@ public: SproutNotePlaintext(const SproutNote& note, boost::array memo); - SproutNote note(const PaymentAddress& addr) const; + SproutNote note(const SproutPaymentAddress& addr) const; virtual ~SproutNotePlaintext() {} diff --git a/src/zcash/circuit/note.tcc b/src/zcash/circuit/note.tcc index d1534ec4b..c598c62ee 100644 --- a/src/zcash/circuit/note.tcc +++ b/src/zcash/circuit/note.tcc @@ -118,7 +118,7 @@ public: void generate_r1cs_witness( const MerklePath& path, - const SpendingKey& key, + const SproutSpendingKey& key, const SproutNote& note ) { note_gadget::generate_r1cs_witness(note); diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 80c726b5a..9a794089c 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -281,11 +281,11 @@ double benchmark_try_decrypt_notes(size_t nAddrs) { CWallet wallet; for (int i = 0; i < nAddrs; i++) { - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); } - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); auto tx = GetValidReceive(*pzcashParams, sk, 10, true); struct timeval tv_start; @@ -299,7 +299,7 @@ double benchmark_increment_note_witnesses(size_t nTxs) CWallet wallet; ZCIncrementalMerkleTree tree; - auto sk = libzcash::SpendingKey::random(); + auto sk = libzcash::SproutSpendingKey::random(); wallet.AddSpendingKey(sk); // First block