From ed2c9450f9032833f459816c3f6f91893fc8fcbe Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 01:20:37 -0400 Subject: [PATCH] desprout --- src/Makefile.am | 2 - src/gtest/test_transaction.cpp | 90 --- src/key_io.cpp | 44 +- src/keystore.cpp | 42 +- src/keystore.h | 8 +- src/paymentdisclosure.h | 1 + src/rpc/misc.cpp | 54 +- src/test/rpc_wallet_tests.cpp | 6 +- src/utiltest.cpp | 154 ----- src/utiltest.h | 19 - src/wallet/asyncrpcoperation_shieldcoinbase.h | 2 +- src/wallet/crypter.cpp | 111 +--- src/wallet/gtest/test_wallet.cpp | 570 +----------------- src/wallet/rpcwallet.cpp | 28 - src/wallet/wallet.h | 5 - src/wallet/walletdb.cpp | 16 +- src/wallet/walletdb.h | 11 +- src/zcash/Address.cpp | 38 +- src/zcbenchmarks.cpp | 34 +- 19 files changed, 52 insertions(+), 1183 deletions(-) delete mode 100644 src/gtest/test_transaction.cpp delete mode 100644 src/utiltest.cpp delete mode 100644 src/utiltest.h diff --git a/src/Makefile.am b/src/Makefile.am index 6277e0f98..2d2d7a691 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -347,8 +347,6 @@ endif libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ - utiltest.cpp \ - utiltest.h \ zcbenchmarks.cpp \ zcbenchmarks.h \ wallet/asyncrpcoperation_mergetoaddress.cpp \ diff --git a/src/gtest/test_transaction.cpp b/src/gtest/test_transaction.cpp deleted file mode 100644 index 1350768ff..000000000 --- a/src/gtest/test_transaction.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include - -#include "primitives/transaction.h" -#include "zcash/Note.hpp" -#include "zcash/Address.hpp" - -#include - -extern ZCJoinSplit* params; -extern int GenZero(int n); -extern int GenMax(int n); - -TEST(Transaction, JSDescriptionRandomized) { - // construct a merkle tree - SproutMerkleTree merkleTree; - - libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random(); - libzcash::SproutPaymentAddress addr = k.address(); - - libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256()); - - // commitment from coin - uint256 commitment = note.cm(); - - // insert commitment into the merkle tree - merkleTree.append(commitment); - - // compute the merkle root we will be working with - uint256 rt = merkleTree.root(); - - auto witness = merkleTree.witness(); - - // create JSDescription - uint256 joinSplitPubKey; - std::array inputs = { - libzcash::JSInput(witness, note, k), - libzcash::JSInput() // dummy input of zero value - }; - std::array outputs = { - libzcash::JSOutput(addr, 50), - libzcash::JSOutput(addr, 50) - }; - std::array inputMap; - std::array outputMap; - - { - auto jsdesc = JSDescription::Randomized( - false, - *params, joinSplitPubKey, rt, - inputs, outputs, - inputMap, outputMap, - 0, 0, false); - - std::set inputSet(inputMap.begin(), inputMap.end()); - std::set expectedInputSet {0, 1}; - EXPECT_EQ(expectedInputSet, inputSet); - - std::set outputSet(outputMap.begin(), outputMap.end()); - std::set expectedOutputSet {0, 1}; - EXPECT_EQ(expectedOutputSet, outputSet); - } - - { - auto jsdesc = JSDescription::Randomized( - false, - *params, joinSplitPubKey, rt, - inputs, outputs, - inputMap, outputMap, - 0, 0, false, nullptr, GenZero); - - std::array expectedInputMap {1, 0}; - std::array expectedOutputMap {1, 0}; - EXPECT_EQ(expectedInputMap, inputMap); - EXPECT_EQ(expectedOutputMap, outputMap); - } - - { - auto jsdesc = JSDescription::Randomized( - false, - *params, joinSplitPubKey, rt, - inputs, outputs, - inputMap, outputMap, - 0, 0, false, nullptr, GenMax); - - std::array expectedInputMap {0, 1}; - std::array expectedOutputMap {0, 1}; - EXPECT_EQ(expectedInputMap, inputMap); - EXPECT_EQ(expectedOutputMap, outputMap); - } -} diff --git a/src/key_io.cpp b/src/key_io.cpp index dd4176fee..dd4bf884c 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2014-2016 The Bitcoin Core developers // Copyright (c) 2016-2018 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -84,15 +85,6 @@ private: 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::SaplingPaymentAddress& zaddr) const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -117,17 +109,6 @@ private: 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::SaplingIncomingViewingKey& vk) const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -152,17 +133,6 @@ private: 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::SaplingExtendedSpendingKey& zkey) const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -324,18 +294,6 @@ std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr) libzcash::PaymentAddress DecodePaymentAddress(const std::string& str) { std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); - if ((data.size() == libzcash::SerializedSproutPaymentAddressSize + zaddr_prefix.size()) && - 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::SproutPaymentAddress ret; - ss >> ret; - return ret; - } - } - data.clear(); auto bech = bech32::Decode(str); if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS) && bech.second.size() == ConvertedSaplingPaymentAddressSize) { diff --git a/src/keystore.cpp b/src/keystore.cpp index 34bab456c..ca4fa3712 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -128,15 +129,6 @@ bool CBasicKeyStore::HaveWatchOnly() const return (!setWatchOnly.empty()); } -bool CBasicKeyStore::AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk) -{ - LOCK(cs_SpendingKeyStore); - auto address = sk.address(); - mapSproutSpendingKeys[address] = sk; - mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(sk.receiving_key()))); - return true; -} - //! Sapling bool CBasicKeyStore::AddSaplingSpendingKey( const libzcash::SaplingExtendedSpendingKey &sk, @@ -155,14 +147,6 @@ bool CBasicKeyStore::AddSaplingSpendingKey( return true; } -bool CBasicKeyStore::AddSproutViewingKey(const libzcash::SproutViewingKey &vk) -{ - LOCK(cs_SpendingKeyStore); - auto address = vk.address(); - mapSproutViewingKeys[address] = vk; - mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(vk.sk_enc))); - return true; -} bool CBasicKeyStore::AddSaplingFullViewingKey( const libzcash::SaplingFullViewingKey &fvk, @@ -190,18 +174,7 @@ bool CBasicKeyStore::AddSaplingIncomingViewingKey( return true; } -bool CBasicKeyStore::RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk) -{ - LOCK(cs_SpendingKeyStore); - mapSproutViewingKeys.erase(vk.address()); - return true; -} -bool CBasicKeyStore::HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const -{ - LOCK(cs_SpendingKeyStore); - return mapSproutViewingKeys.count(address) > 0; -} bool CBasicKeyStore::HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const { @@ -215,19 +188,6 @@ bool CBasicKeyStore::HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymen return mapSaplingIncomingViewingKeys.count(addr) > 0; } -bool CBasicKeyStore::GetSproutViewingKey( - const libzcash::SproutPaymentAddress &address, - libzcash::SproutViewingKey &vkOut) const -{ - LOCK(cs_SpendingKeyStore); - SproutViewingKeyMap::const_iterator mi = mapSproutViewingKeys.find(address); - if (mi != mapSproutViewingKeys.end()) { - vkOut = mi->second; - return true; - } - return false; -} - bool CBasicKeyStore::GetSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk, libzcash::SaplingFullViewingKey &fvkOut) const { diff --git a/src/keystore.h b/src/keystore.h index ac2ccf233..6f34d9bc4 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -120,12 +120,7 @@ protected: KeyMap mapKeys; ScriptMap mapScripts; WatchOnlySet setWatchOnly; - /* - SproutSpendingKeyMap mapSproutSpendingKeys; - SproutViewingKeyMap mapSproutViewingKeys; - NoteDecryptorMap mapNoteDecryptors; - */ - + SaplingSpendingKeyMap mapSaplingSpendingKeys; SaplingFullViewingKeyMap mapSaplingFullViewingKeys; SaplingIncomingViewingKeyMap mapSaplingIncomingViewingKeys; @@ -246,7 +241,6 @@ public: typedef std::vector > CKeyingMaterial; typedef std::map > > CryptedKeyMap; -//typedef std::map > CryptedSproutSpendingKeyMap; //! Sapling typedef std::map > CryptedSaplingSpendingKeyMap; diff --git a/src/paymentdisclosure.h b/src/paymentdisclosure.h index 28a1d4cdc..5c3a20c33 100644 --- a/src/paymentdisclosure.h +++ b/src/paymentdisclosure.h @@ -1,4 +1,5 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index fb3e21137..a41a8169d 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -204,7 +204,7 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"version\": xxxxx, (numeric) the server version\n" " \"protocolversion\": xxxxx, (numeric) the protocol version\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total Komodo balance of the wallet\n" + " \"balance\": xxxxxxx, (numeric) the total Hush balance of the wallet\n" " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" " \"timeoffset\": xxxxx, (numeric) the time offset\n" " \"connections\": xxxxx, (numeric) the number of connections\n" @@ -590,30 +590,6 @@ UniValue validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk } -class DescribePaymentAddressVisitor : public boost::static_visitor -{ -public: - UniValue operator()(const libzcash::InvalidEncoding &zaddr) const { return UniValue(UniValue::VOBJ); } - - UniValue operator()(const libzcash::SaplingPaymentAddress &zaddr) const { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("type", "sapling")); - obj.push_back(Pair("diversifier", HexStr(zaddr.d))); - obj.push_back(Pair("diversifiedtransmissionkey", zaddr.pk_d.GetHex())); -#ifdef ENABLE_WALLET - if (pwalletMain) { - libzcash::SaplingIncomingViewingKey ivk; - libzcash::SaplingFullViewingKey fvk; - bool isMine = pwalletMain->GetSaplingIncomingViewingKey(zaddr, ivk) && - pwalletMain->GetSaplingFullViewingKey(ivk, fvk) && - pwalletMain->HaveSaplingSpendingKey(fvk); - obj.push_back(Pair("ismine", isMine)); - } -#endif - return obj; - } -}; - UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (fHelp || params.size() != 1) @@ -650,11 +626,25 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& my UniValue ret(UniValue::VOBJ); ret.push_back(Pair("isvalid", isValid)); - if (isValid) + auto zaddr = boost::get(&address); + if (isValid && (zaddr != nullptr)) { ret.push_back(Pair("address", strAddress)); - UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(), address); - ret.pushKVs(detail); + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("type", "sapling")); + obj.push_back(Pair("diversifier", HexStr(zaddr->d))); + obj.push_back(Pair("diversifiedtransmissionkey", zaddr->pk_d.GetHex())); +#ifdef ENABLE_WALLET + if (pwalletMain) { + libzcash::SaplingIncomingViewingKey ivk; + libzcash::SaplingFullViewingKey fvk; + bool isMine = pwalletMain->GetSaplingIncomingViewingKey(*zaddr, ivk) && + pwalletMain->GetSaplingFullViewingKey(ivk, fvk) && + pwalletMain->HaveSaplingSpendingKey(fvk); + obj.push_back(Pair("ismine", isMine)); + } +#endif + ret.pushKVs(obj); } return ret; } @@ -733,9 +723,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp, const CPubKey& mypk) "\nArguments:\n" "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" - "2. \"keys\" (string, required) A json array of keys which are Komodo addresses or hex-encoded public keys\n" + "2. \"keys\" (string, required) A json array of keys which are Hush addresses or hex-encoded public keys\n" " [\n" - " \"key\" (string) Komodo address or hex-encoded public key\n" + " \"key\" (string) Hush address or hex-encoded public key\n" " ,...\n" " ]\n" @@ -769,10 +759,10 @@ UniValue verifymessage(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (fHelp || params.size() != 3) throw runtime_error( - "verifymessage \"komodoaddress\" \"signature\" \"message\"\n" + "verifymessage \"hushaddress\" \"signature\" \"message\"\n" "\nVerify a signed message\n" "\nArguments:\n" - "1. \"komodoaddress\" (string, required) The Komodo address to use for the signature.\n" + "1. \"hushaddress\" (string, required) The Hush address to use for the signature.\n" "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n" "3. \"message\" (string, required) The message that was signed.\n" "\nResult:\n" diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 107188779..2abe2d782 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -571,9 +571,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) // Verify number of addresses stored in wallet is n1+n2 int numAddrs = myaddrs.size(); BOOST_CHECK(numAddrs == (2 * n1) + n2); - pwalletMain->GetSproutPaymentAddresses(addrs); pwalletMain->GetSaplingPaymentAddresses(saplingAddrs); - BOOST_CHECK(addrs.size() + saplingAddrs.size() == numAddrs); + BOOST_CHECK(saplingAddrs.size() == numAddrs); // Ask wallet to list addresses BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses")); @@ -595,9 +594,6 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) std::string newaddress = retValue.get_str(); auto address = DecodePaymentAddress(newaddress); BOOST_CHECK(IsValidPaymentAddress(address)); - BOOST_ASSERT(boost::get(&address) != nullptr); - auto newAddr = boost::get(address); - BOOST_CHECK(pwalletMain->HaveSproutSpendingKey(newAddr)); // Check if too many args BOOST_CHECK_THROW(CallRPC("z_getnewaddress toomanyargs"), runtime_error); diff --git a/src/utiltest.cpp b/src/utiltest.cpp deleted file mode 100644 index ead7fe6a0..000000000 --- a/src/utiltest.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2016 The Zcash developers -// Copyright (c) 2019-2020 The Hush developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "utiltest.h" - -#include "consensus/upgrades.h" - -#include - -CWalletTx GetValidReceive(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, CAmount value, - bool randomInputs, - int32_t version /* = 2 */) { - CMutableTransaction mtx; - mtx.nVersion = version; - mtx.vin.resize(2); - if (randomInputs) { - mtx.vin[0].prevout.hash = GetRandHash(); - mtx.vin[1].prevout.hash = GetRandHash(); - } else { - mtx.vin[0].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); - mtx.vin[1].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000002"); - } - mtx.vin[0].prevout.n = 0; - mtx.vin[1].prevout.n = 0; - - // Generate an ephemeral keypair. - uint256 joinSplitPubKey; - unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; - crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); - mtx.joinSplitPubKey = joinSplitPubKey; - - std::array inputs = { - libzcash::JSInput(), // dummy input - libzcash::JSInput() // dummy input - }; - - std::array outputs = { - libzcash::JSOutput(sk.address(), value), - libzcash::JSOutput(sk.address(), value) - }; - - // Prepare JoinSplits - uint256 rt; - JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, - inputs, outputs, 2*value, 0, false}; - mtx.vjoinsplit.push_back(jsdesc); - - if (version >= 4) { - // Shielded Output - OutputDescription od; - mtx.vShieldedOutput.push_back(od); - } - - // Empty output script. - uint32_t consensusBranchId = SPROUT_BRANCH_ID; - CScript scriptCode; - CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); - - // Add the signature - assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, - dataToBeSigned.begin(), 32, - joinSplitPrivKey - ) == 0); - - CTransaction tx {mtx}; - CWalletTx wtx {NULL, tx}; - return wtx; -} - -libzcash::SproutNote GetNote(ZCJoinSplit& params, - 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); - auto note_pt = libzcash::SproutNotePlaintext::decrypt( - decryptor, - tx.vjoinsplit[js].ciphertexts[n], - tx.vjoinsplit[js].ephemeralKey, - hSig, - (unsigned char) n); - return note_pt.note(sk.address()); -} - -CWalletTx GetValidSpend(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, - const libzcash::SproutNote& note, CAmount value) { - CMutableTransaction mtx; - mtx.vout.resize(2); - mtx.vout[0].nValue = value; - mtx.vout[1].nValue = 0; - - // Generate an ephemeral keypair. - uint256 joinSplitPubKey; - unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; - crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); - mtx.joinSplitPubKey = joinSplitPubKey; - - // Fake tree for the unused witness - SproutMerkleTree tree; - - libzcash::JSOutput dummyout; - libzcash::JSInput dummyin; - - { - if (note.value() > value) { - libzcash::SproutSpendingKey dummykey = libzcash::SproutSpendingKey::random(); - libzcash::SproutPaymentAddress dummyaddr = dummykey.address(); - dummyout = libzcash::JSOutput(dummyaddr, note.value() - value); - } else if (note.value() < value) { - 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); - } - } - - tree.append(note.cm()); - - std::array inputs = { - libzcash::JSInput(tree.witness(), note, sk), - dummyin - }; - - std::array outputs = { - dummyout, // dummy output - libzcash::JSOutput() // dummy output - }; - - // Prepare JoinSplits - uint256 rt = tree.root(); - JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, - inputs, outputs, 0, value, false}; - mtx.vjoinsplit.push_back(jsdesc); - - // Empty output script. - uint32_t consensusBranchId = SPROUT_BRANCH_ID; - CScript scriptCode; - CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); - - // Add the signature - assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, - dataToBeSigned.begin(), 32, - joinSplitPrivKey - ) == 0); - CTransaction tx {mtx}; - CWalletTx wtx {NULL, tx}; - return wtx; -} diff --git a/src/utiltest.h b/src/utiltest.h deleted file mode 100644 index 327dc7be4..000000000 --- a/src/utiltest.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2016 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "wallet/wallet.h" -#include "zcash/JoinSplit.hpp" -#include "zcash/Note.hpp" -#include "zcash/NoteEncryption.hpp" - -CWalletTx GetValidReceive(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, CAmount value, - bool randomInputs, - int32_t version = 2); -libzcash::SproutNote GetNote(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, - const CTransaction& tx, size_t js, size_t n); -CWalletTx GetValidSpend(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, - const libzcash::SproutNote& note, CAmount value); diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.h b/src/wallet/asyncrpcoperation_shieldcoinbase.h index b3fef0fc1..db4fb83af 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.h +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.h @@ -1,4 +1,5 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -123,7 +124,6 @@ public: ShieldToAddress(AsyncRPCOperation_shieldcoinbase *op, CAmount sendAmount) : m_op(op), sendAmount(sendAmount) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 38aff1a04..9d11a55fe 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -1,6 +1,7 @@ // Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -168,22 +169,6 @@ static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector& vchCryptedSecret, - const libzcash::SproutPaymentAddress& address, - libzcash::SproutSpendingKey& sk) -{ - CKeyingMaterial vchSecret; - if (!DecryptSecret(vMasterKey, vchCryptedSecret, address.GetHash(), vchSecret)) - return false; - - if (vchSecret.size() != libzcash::SerializedSproutSpendingKeySize) - return false; - - CSecureDataStream ss(vchSecret, SER_NETWORK, PROTOCOL_VERSION); - ss >> sk; - return sk.address() == address; -} static bool DecryptSaplingSpendingKey(const CKeyingMaterial& vMasterKey, const std::vector& vchCryptedSecret, @@ -207,7 +192,7 @@ bool CCryptoKeyStore::SetCrypted() LOCK2(cs_KeyStore, cs_SpendingKeyStore); if (fUseCrypto) return true; - if (!(mapKeys.empty() && mapSproutSpendingKeys.empty() && mapSaplingSpendingKeys.empty())) + if (!(mapKeys.empty() && mapSaplingSpendingKeys.empty())) return false; fUseCrypto = true; return true; @@ -260,21 +245,6 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) if (fDecryptionThoroughlyChecked) break; } - CryptedSproutSpendingKeyMap::const_iterator miSprout = mapCryptedSproutSpendingKeys.begin(); - for (; miSprout != mapCryptedSproutSpendingKeys.end(); ++miSprout) - { - const libzcash::SproutPaymentAddress &address = (*miSprout).first; - const std::vector &vchCryptedSecret = (*miSprout).second; - libzcash::SproutSpendingKey sk; - if (!DecryptSproutSpendingKey(vMasterKeyIn, vchCryptedSecret, address, sk)) - { - keyFail = true; - break; - } - keyPass = true; - if (fDecryptionThoroughlyChecked) - break; - } CryptedSaplingSpendingKeyMap::const_iterator miSapling = mapCryptedSaplingSpendingKeys.begin(); for (; miSapling != mapCryptedSaplingSpendingKeys.end(); ++miSapling) { @@ -292,7 +262,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) } if (keyPass && keyFail) { - LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n"); + LogPrintf("Oh shit! The wallet is probably corrupted: Some keys decrypt but not all.\n"); assert(false); } if (keyFail || !keyPass) @@ -440,30 +410,6 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co return false; } -bool CCryptoKeyStore::AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk) -{ - { - LOCK(cs_SpendingKeyStore); - if (!IsCrypted()) - return CBasicKeyStore::AddSproutSpendingKey(sk); - - if (IsLocked()) - return false; - - std::vector vchCryptedSecret; - CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << sk; - CKeyingMaterial vchSecret(ss.begin(), ss.end()); - auto address = sk.address(); - if (!EncryptSecret(vMasterKey, vchSecret, address.GetHash(), vchCryptedSecret)) - return false; - - if (!AddCryptedSproutSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) - return false; - } - return true; -} - bool CCryptoKeyStore::AddSaplingSpendingKey( const libzcash::SaplingExtendedSpendingKey &sk, const libzcash::SaplingPaymentAddress &defaultAddr) @@ -494,22 +440,6 @@ bool CCryptoKeyStore::AddSaplingSpendingKey( return true; } -bool CCryptoKeyStore::AddCryptedSproutSpendingKey( - const libzcash::SproutPaymentAddress &address, - const libzcash::ReceivingKey &rk, - const std::vector &vchCryptedSecret) -{ - { - LOCK(cs_SpendingKeyStore); - if (!SetCrypted()) - return false; - - mapCryptedSproutSpendingKeys[address] = vchCryptedSecret; - mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(rk))); - } - return true; -} - bool CCryptoKeyStore::AddCryptedSaplingSpendingKey( const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector &vchCryptedSecret, @@ -531,23 +461,6 @@ bool CCryptoKeyStore::AddCryptedSaplingSpendingKey( return true; } -bool CCryptoKeyStore::GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const -{ - { - LOCK(cs_SpendingKeyStore); - if (!IsCrypted()) - return CBasicKeyStore::GetSproutSpendingKey(address, skOut); - - CryptedSproutSpendingKeyMap::const_iterator mi = mapCryptedSproutSpendingKeys.find(address); - if (mi != mapCryptedSproutSpendingKeys.end()) - { - const std::vector &vchCryptedSecret = (*mi).second; - return DecryptSproutSpendingKey(vMasterKey, vchCryptedSecret, address, skOut); - } - } - return false; -} - bool CCryptoKeyStore::GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingExtendedSpendingKey &skOut) const { { @@ -603,22 +516,6 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) } } mapKeys.clear(); - BOOST_FOREACH(SproutSpendingKeyMap::value_type& mSproutSpendingKey, mapSproutSpendingKeys) - { - const libzcash::SproutSpendingKey &sk = mSproutSpendingKey.second; - CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << sk; - CKeyingMaterial vchSecret(ss.begin(), ss.end()); - libzcash::SproutPaymentAddress address = sk.address(); - std::vector vchCryptedSecret; - if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret)) { - return false; - } - if (!AddCryptedSproutSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) { - return false; - } - } - mapSproutSpendingKeys.clear(); //! Sapling key support BOOST_FOREACH(SaplingSpendingKeyMap::value_type& mSaplingSpendingKey, mapSaplingSpendingKeys) { diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index dcc7fdfdd..0ad789137 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -139,341 +139,8 @@ TEST(WalletTests, SetupDatadirLocationRunAsFirstTest) { boost::filesystem::create_directories(pathTemp); mapArgs["-datadir"] = pathTemp.string(); } +/* -TEST(WalletTests, SproutNoteDataSerialisation) { - auto sk = libzcash::SproutSpendingKey::random(); - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - SproutMerkleTree tree; - nd.witnesses.push_front(tree.witness()); - noteData[jsoutpt] = nd; - - CDataStream ss(SER_DISK, CLIENT_VERSION); - ss << noteData; - - mapSproutNoteData_t noteData2; - ss >> noteData2; - - EXPECT_EQ(noteData, noteData2); - EXPECT_EQ(noteData[jsoutpt].witnesses, noteData2[jsoutpt].witnesses); -} - - -TEST(WalletTests, FindUnspentSproutNotes) { - SelectParams(CBaseChainParams::TESTNET); - CWallet wallet; - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - wallet.AddToWallet(wtx, true, NULL); - EXPECT_FALSE(wallet.IsSproutSpent(nullifier)); - - // We currently have an unspent and unconfirmed note in the wallet (depth of -1) - std::vector sproutEntries; - std::vector saplingEntries; - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 0); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", -1); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - - // Fake-mine the transaction - EXPECT_EQ(-1, chainActive.Height()); - CBlock block; - block.vtx.push_back(wtx); - block.hashMerkleRoot = block.BuildMerkleTree(); - auto blockHash = block.GetHash(); - CBlockIndex fakeIndex {block}; - mapBlockIndex.insert(std::make_pair(blockHash, &fakeIndex)); - chainActive.SetTip(&fakeIndex); - EXPECT_TRUE(chainActive.Contains(&fakeIndex)); - EXPECT_EQ(0, chainActive.Height()); - - wtx.SetMerkleBranch(block); - wallet.AddToWallet(wtx, true, NULL); - EXPECT_FALSE(wallet.IsSproutSpent(nullifier)); - - - // We now have an unspent and confirmed note in the wallet (depth of 1) - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 0); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 1); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 2); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - - - // Let's spend the note. - auto wtx2 = GetValidSpend(sk, note, 5); - wallet.AddToWallet(wtx2, true, NULL); - EXPECT_FALSE(wallet.IsSproutSpent(nullifier)); - - // Fake-mine a spend transaction - EXPECT_EQ(0, chainActive.Height()); - CBlock block2; - block2.vtx.push_back(wtx2); - block2.hashMerkleRoot = block2.BuildMerkleTree(); - block2.hashPrevBlock = blockHash; - auto blockHash2 = block2.GetHash(); - CBlockIndex fakeIndex2 {block2}; - mapBlockIndex.insert(std::make_pair(blockHash2, &fakeIndex2)); - fakeIndex2.SetHeight(1); - chainActive.SetTip(&fakeIndex2); - EXPECT_TRUE(chainActive.Contains(&fakeIndex2)); - EXPECT_EQ(1, chainActive.Height()); - - wtx2.SetMerkleBranch(block2); - wallet.AddToWallet(wtx2, true, NULL); - EXPECT_TRUE(wallet.IsSproutSpent(nullifier)); - - // The note has been spent. By default, GetFilteredNotes() ignores spent notes. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 0); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // Let's include spent notes to retrieve it. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 0, false); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // The spent note has two confirmations. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 2, false); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // It does not have 3 confirmations. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 3, false); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - - - // Let's receive a new note - CWalletTx wtx3; - { - auto wtx = GetValidReceive(sk, 20, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - wallet.AddToWallet(wtx, true, NULL); - EXPECT_FALSE(wallet.IsSproutSpent(nullifier)); - - wtx3 = wtx; - } - - // Fake-mine the new transaction - EXPECT_EQ(1, chainActive.Height()); - CBlock block3; - block3.vtx.push_back(wtx3); - block3.hashMerkleRoot = block3.BuildMerkleTree(); - block3.hashPrevBlock = blockHash2; - auto blockHash3 = block3.GetHash(); - CBlockIndex fakeIndex3 {block3}; - mapBlockIndex.insert(std::make_pair(blockHash3, &fakeIndex3)); - fakeIndex3.SetHeight(2); - chainActive.SetTip(&fakeIndex3); - EXPECT_TRUE(chainActive.Contains(&fakeIndex3)); - EXPECT_EQ(2, chainActive.Height()); - - wtx3.SetMerkleBranch(block3); - wallet.AddToWallet(wtx3, true, NULL); - - // We now have an unspent note which has one confirmation, in addition to our spent note. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 1); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // Let's return the spent note too. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 1, false); - EXPECT_EQ(2, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // Increasing number of confirmations will exclude our new unspent note. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 2, false); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // If we also ignore spent notes at this depth, we won't find any notes. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 2, true); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - - // Tear down - chainActive.SetTip(NULL); - mapBlockIndex.erase(blockHash); - mapBlockIndex.erase(blockHash2); - mapBlockIndex.erase(blockHash3); -} - - -TEST(WalletTests, SetSproutNoteAddrsInCWalletTx) { - auto sk = libzcash::SproutSpendingKey::random(); - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - EXPECT_EQ(0, wtx.mapSproutNoteData.size()); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - EXPECT_EQ(noteData, wtx.mapSproutNoteData); -} - -TEST(WalletTests, SetSaplingNoteAddrsInCWalletTx) { - SelectParams(CBaseChainParams::REGTEST); - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); - auto consensusParams = Params().GetConsensus(); - - TestWallet wallet; - - std::vector> rawSeed(32); - HDSeed seed(rawSeed); - auto sk = libzcash::SaplingExtendedSpendingKey::Master(seed); - auto expsk = sk.expsk; - auto fvk = expsk.full_viewing_key(); - auto ivk = fvk.in_viewing_key(); - auto pk = sk.DefaultAddress(); - - libzcash::SaplingNote note(pk, 50000); - auto cm = note.cm().get(); - SaplingMerkleTree tree; - tree.append(cm); - auto anchor = tree.root(); - auto witness = tree.witness(); - - auto nf = note.nullifier(fvk, witness.position()); - ASSERT_TRUE(nf); - uint256 nullifier = nf.get(); - - auto builder = TransactionBuilder(consensusParams, 1); - ASSERT_TRUE(builder.AddSaplingSpend(expsk, note, anchor, witness)); - builder.AddSaplingOutput(fvk.ovk, pk, 50000, {}); - builder.SetFee(0); - auto maybe_tx = builder.Build(); - ASSERT_EQ(static_cast(maybe_tx), true); - auto tx = maybe_tx.get(); - - CWalletTx wtx {&wallet, tx}; - - EXPECT_EQ(0, wtx.mapSaplingNoteData.size()); - mapSaplingNoteData_t noteData; - - SaplingOutPoint op {wtx.GetHash(), 0}; - SaplingNoteData nd; - nd.nullifier = nullifier; - nd.ivk = ivk; - nd.witnesses.push_front(witness); - nd.witnessHeight = 123; - noteData.insert(std::make_pair(op, nd)); - - wtx.SetSaplingNoteData(noteData); - EXPECT_EQ(noteData, wtx.mapSaplingNoteData); - - // Test individual fields in case equality operator is defined/changed. - EXPECT_EQ(ivk, wtx.mapSaplingNoteData[op].ivk); - EXPECT_EQ(nullifier, wtx.mapSaplingNoteData[op].nullifier); - EXPECT_EQ(nd.witnessHeight, wtx.mapSaplingNoteData[op].witnessHeight); - EXPECT_TRUE(witness == wtx.mapSaplingNoteData[op].witnesses.front()); - - // Revert to default - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); -} - -TEST(WalletTests, SetSproutInvalidNoteAddrsInCWalletTx) { - CWalletTx wtx; - EXPECT_EQ(0, wtx.mapSproutNoteData.size()); - - mapSproutNoteData_t noteData; - auto sk = libzcash::SproutSpendingKey::random(); - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), uint256()}; - noteData[jsoutpt] = nd; - - EXPECT_THROW(wtx.SetSproutNoteData(noteData), std::logic_error); -} - -// The following test is the same as SetInvalidSaplingNoteDataInCWalletTx -// TEST(WalletTests, SetSaplingInvalidNoteAddrsInCWalletTx) - -// Cannot add note data for an index which does not exist in tx.vShieldedOutput -TEST(WalletTests, SetInvalidSaplingNoteDataInCWalletTx) { - CWalletTx wtx; - EXPECT_EQ(0, wtx.mapSaplingNoteData.size()); - - mapSaplingNoteData_t noteData; - SaplingOutPoint op {uint256(), 1}; - SaplingNoteData nd; - noteData.insert(std::make_pair(op, nd)); - - EXPECT_THROW(wtx.SetSaplingNoteData(noteData), std::logic_error); -} - -TEST(WalletTests, GetSproutNoteNullifier) { - CWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - auto address = sk.address(); - auto dec = ZCNoteDecryption(sk.receiving_key()); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - auto hSig = wtx.vjoinsplit[0].h_sig( - *params, wtx.joinSplitPubKey); - - auto ret = wallet.GetSproutNoteNullifier( - wtx.vjoinsplit[0], - address, - dec, - hSig, 1); - EXPECT_NE(nullifier, ret); - - wallet.AddSproutSpendingKey(sk); - - ret = wallet.GetSproutNoteNullifier( - wtx.vjoinsplit[0], - address, - dec, - hSig, 1); - EXPECT_EQ(nullifier, ret); -} TEST(WalletTests, FindMySaplingNotes) { SelectParams(CBaseChainParams::REGTEST); @@ -577,92 +244,6 @@ TEST(WalletTests, FindMySaplingNotesWithIvkOnly) { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); } -TEST(WalletTests, FindMySproutNotes) { - CWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - auto sk2 = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk2); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - auto noteMap = wallet.FindMySproutNotes(wtx); - EXPECT_EQ(0, noteMap.size()); - - wallet.AddSproutSpendingKey(sk); - - noteMap = wallet.FindMySproutNotes(wtx); - EXPECT_EQ(2, noteMap.size()); - - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - EXPECT_EQ(1, noteMap.count(jsoutpt)); - EXPECT_EQ(nd, noteMap[jsoutpt]); -} - -TEST(WalletTests, FindMySproutNotesInEncryptedWallet) { - TestWallet wallet; - uint256 r {GetRandHash()}; - CKeyingMaterial vMasterKey (r.begin(), r.end()); - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - ASSERT_TRUE(wallet.EncryptKeys(vMasterKey)); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - auto noteMap = wallet.FindMySproutNotes(wtx); - EXPECT_EQ(2, noteMap.size()); - - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - EXPECT_EQ(1, noteMap.count(jsoutpt)); - EXPECT_NE(nd, noteMap[jsoutpt]); - - ASSERT_TRUE(wallet.Unlock(vMasterKey)); - - noteMap = wallet.FindMySproutNotes(wtx); - EXPECT_EQ(2, noteMap.size()); - EXPECT_EQ(1, noteMap.count(jsoutpt)); - EXPECT_EQ(nd, noteMap[jsoutpt]); -} - -TEST(WalletTests, GetConflictedSproutNotes) { - CWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - auto wtx2 = GetValidSpend(sk, note, 5); - auto wtx3 = GetValidSpend(sk, note, 10); - auto hash2 = wtx2.GetHash(); - auto hash3 = wtx3.GetHash(); - - // No conflicts for no spends - EXPECT_EQ(0, wallet.GetConflicts(hash2).size()); - wallet.AddToWallet(wtx, true, NULL); - EXPECT_EQ(0, wallet.GetConflicts(hash2).size()); - - // No conflicts for one spend - wallet.AddToWallet(wtx2, true, NULL); - EXPECT_EQ(0, wallet.GetConflicts(hash2).size()); - - // Conflicts for two spends - wallet.AddToWallet(wtx3, true, NULL); - auto c3 = wallet.GetConflicts(hash2); - EXPECT_EQ(2, c3.size()); - EXPECT_EQ(std::set({hash2, hash3}), c3); -} - // Generate note A and spend to create note B, from which we spend to create two conflicting transactions TEST(WalletTests, GetConflictedSaplingNotes) { SelectParams(CBaseChainParams::REGTEST); @@ -1735,88 +1316,6 @@ TEST(WalletTests, SetBestChainIgnoresTxsWithoutShieldedData) { wallet.SetBestChain(walletdb, loc); } -TEST(WalletTests, UpdateSproutNullifierNoteMap) { - TestWallet wallet; - uint256 r {GetRandHash()}; - CKeyingMaterial vMasterKey (r.begin(), r.end()); - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - ASSERT_TRUE(wallet.EncryptKeys(vMasterKey)); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - // Pretend that we called FindMySproutNotes while the wallet was locked - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address()}; - noteData[jsoutpt] = nd; - wtx.SetSproutNoteData(noteData); - - wallet.AddToWallet(wtx, true, NULL); - EXPECT_EQ(0, wallet.mapSproutNullifiersToNotes.count(nullifier)); - - EXPECT_FALSE(wallet.UpdateNullifierNoteMap()); - - ASSERT_TRUE(wallet.Unlock(vMasterKey)); - - EXPECT_TRUE(wallet.UpdateNullifierNoteMap()); - EXPECT_EQ(1, wallet.mapSproutNullifiersToNotes.count(nullifier)); - EXPECT_EQ(wtx.GetHash(), wallet.mapSproutNullifiersToNotes[nullifier].hash); - EXPECT_EQ(0, wallet.mapSproutNullifiersToNotes[nullifier].js); - EXPECT_EQ(1, wallet.mapSproutNullifiersToNotes[nullifier].n); -} - -TEST(WalletTests, UpdatedSproutNoteData) { - TestWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 0); - auto note2 = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - auto nullifier2 = note2.nullifier(sk); - auto wtx2 = wtx; - - // First pretend we added the tx to the wallet and - // we don't have the key for the second note - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 0}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - wtx.SetSproutNoteData(noteData); - - // Pretend we mined the tx by adding a fake witness - SproutMerkleTree tree; - wtx.mapSproutNoteData[jsoutpt].witnesses.push_front(tree.witness()); - wtx.mapSproutNoteData[jsoutpt].witnessHeight = 100; - - // Now pretend we added the key for the second note, and - // the tx was "added" to the wallet again to update it. - // This happens via the 'z_importkey' RPC method. - JSOutPoint jsoutpt2 {wtx2.GetHash(), 0, 1}; - SproutNoteData nd2 {sk.address(), nullifier2}; - noteData[jsoutpt2] = nd2; - wtx2.SetSproutNoteData(noteData); - - // The txs should initially be different - EXPECT_NE(wtx.mapSproutNoteData, wtx2.mapSproutNoteData); - EXPECT_EQ(1, wtx.mapSproutNoteData[jsoutpt].witnesses.size()); - EXPECT_EQ(100, wtx.mapSproutNoteData[jsoutpt].witnessHeight); - - // After updating, they should be the same - EXPECT_TRUE(wallet.UpdatedNoteData(wtx2, wtx)); - EXPECT_EQ(wtx.mapSproutNoteData, wtx2.mapSproutNoteData); - EXPECT_EQ(1, wtx.mapSproutNoteData[jsoutpt].witnesses.size()); - EXPECT_EQ(100, wtx.mapSproutNoteData[jsoutpt].witnessHeight); - // TODO: The new note should get witnessed (but maybe not here) (#1350) -} - TEST(WalletTests, UpdatedSaplingNoteData) { SelectParams(CBaseChainParams::REGTEST); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); @@ -1941,37 +1440,6 @@ TEST(WalletTests, UpdatedSaplingNoteData) { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); } -TEST(WalletTests, MarkAffectedSproutTransactionsDirty) { - TestWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto hash = wtx.GetHash(); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - auto wtx2 = GetValidSpend(sk, note, 5); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {hash, 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - wallet.AddToWallet(wtx, true, NULL); - wallet.MarkAffectedTransactionsDirty(wtx); - - // After getting a cached value, the first tx should be clean - wallet.mapWallet[hash].GetDebit(ISMINE_ALL); - EXPECT_TRUE(wallet.mapWallet[hash].fDebitCached); - - // After adding the note spend, the first tx should be dirty - wallet.AddToWallet(wtx2, true, NULL); - wallet.MarkAffectedTransactionsDirty(wtx2); - EXPECT_FALSE(wallet.mapWallet[hash].fDebitCached); -} - TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) { SelectParams(CBaseChainParams::REGTEST); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); @@ -1999,7 +1467,7 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) { auto scriptPubKey = GetScriptForDestination(tsk.GetPubKey().GetID()); // Generate shielding tx from transparent to Sapling - // 0.0005 t-ZEC in, 0.0004 z-ZEC out, 0.0001 t-ZEC fee + // 0.0005 t-HUSH in, 0.0004 z-HUSH out, 0.0001 t-HUSH fee auto builder = TransactionBuilder(consensusParams, 1, &keystore); builder.AddTransparentInput(COutPoint(), scriptPubKey, 50000); builder.AddSaplingOutput(fvk.ovk, pk, 40000, {}); @@ -2093,39 +1561,7 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); } - -TEST(WalletTests, SproutNoteLocking) { - TestWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto wtx2 = GetValidReceive(sk, 10, true); - - JSOutPoint jsoutpt {wtx.GetHash(), 0, 0}; - JSOutPoint jsoutpt2 {wtx2.GetHash(),0, 0}; - - // Test selective locking - wallet.LockNote(jsoutpt); - EXPECT_TRUE(wallet.IsLockedNote(jsoutpt)); - EXPECT_FALSE(wallet.IsLockedNote(jsoutpt2)); - - // Test selective unlocking - wallet.UnlockNote(jsoutpt); - EXPECT_FALSE(wallet.IsLockedNote(jsoutpt)); - - // Test multiple locking - wallet.LockNote(jsoutpt); - wallet.LockNote(jsoutpt2); - EXPECT_TRUE(wallet.IsLockedNote(jsoutpt)); - EXPECT_TRUE(wallet.IsLockedNote(jsoutpt2)); - - // Test unlock all - wallet.UnlockAllSproutNotes(); - EXPECT_FALSE(wallet.IsLockedNote(jsoutpt)); - EXPECT_FALSE(wallet.IsLockedNote(jsoutpt2)); -} +*/ TEST(WalletTests, SaplingNoteLocking) { TestWallet wallet; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 37f67042b..d3d396bbc 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5487,34 +5487,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp "Cannot send between Sprout and Sapling addresses using z_mergetoaddress"); } - // Find unspent notes and update estimated size - for (const CSproutNotePlaintextEntry& entry : sproutEntries) { - noteCounter++; - CAmount nValue = entry.plaintext.value(); - - if (!maxedOutNotesFlag) { - // If we haven't added any notes yet and the merge is to a - // z-address, we have already accounted for the first JoinSplit. - size_t increase = (sproutNoteInputs.empty() && !isToSproutZaddr) || (sproutNoteInputs.size() % 2 == 0) ? JOINSPLIT_SIZE : 0; - if (estimatedTxSize + increase >= max_tx_size || - (sproutNoteLimit > 0 && noteCounter > sproutNoteLimit)) - { - maxedOutNotesFlag = true; - } else { - estimatedTxSize += increase; - auto zaddr = entry.address; - SproutSpendingKey zkey; - pwalletMain->GetSproutSpendingKey(zaddr, zkey); - sproutNoteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey); - mergedNoteValue += nValue; - } - } - - if (maxedOutNotesFlag) { - remainingNoteValue += nValue; - } - } - for (const SaplingNoteEntry& entry : saplingEntries) { noteCounter++; CAmount nValue = entry.note.value(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d82e100ed..f3526c583 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1408,7 +1408,6 @@ private: public: PaymentAddressBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1421,7 +1420,6 @@ private: public: IncomingViewingKeyBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1433,7 +1431,6 @@ private: public: HaveSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1445,7 +1442,6 @@ private: public: GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} - boost::optional operator()(const libzcash::SproutPaymentAddress &zaddr) const; boost::optional operator()(const libzcash::SaplingPaymentAddress &zaddr) const; boost::optional operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1517,7 +1513,6 @@ public: ) : m_wallet(wallet), params(params), nTime(_nTime), hdKeypath(_hdKeypath), seedFpStr(_seedFp), log(_log) {} - SpendingKeyAddResult operator()(const libzcash::SproutSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::SaplingExtendedSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::InvalidEncoding& no) const; }; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 1177bbedd..71331ed93 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -653,6 +653,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "czkey") { + /* libzcash::SproutPaymentAddress addr; ssKey >> addr; // Deserialization of a pair is just one item after another @@ -663,12 +664,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, ssValue >> vchCryptedSecret; wss.nCKeys++; - //if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret)) - //{ - // strErr = "Error reading wallet database: LoadCryptedZKey failed"; - // return false; - //} - //wss.fIsEncrypted = true; + if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret)) + { + strErr = "Error reading wallet database: LoadCryptedZKey failed"; + return false; + } + wss.fIsEncrypted = true; + */ } else if (strType == "csapzkey") { @@ -704,11 +706,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "zkeymeta") { + /* libzcash::SproutPaymentAddress addr; ssKey >> addr; CKeyMetadata keyMeta; ssValue >> keyMeta; wss.nZKeyMeta++; + */ // pwallet->LoadZKeyMetadata(addr, keyMeta); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 9069e3a08..64a4817d9 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -1,7 +1,8 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2013 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -199,23 +200,15 @@ public: bool WriteHDChain(const CHDChain& chain); /// Write spending key to wallet database, where key is payment address and value is spending key. - bool WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta); bool WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingExtendedSpendingKey &key, const CKeyMetadata &keyMeta); bool WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr, const libzcash::SaplingIncomingViewingKey &ivk); - bool WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr, - const libzcash::ReceivingKey & rk, - const std::vector& vchCryptedSecret, - const CKeyMetadata &keyMeta); bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta); - bool WriteSproutViewingKey(const libzcash::SproutViewingKey &vk); - bool EraseSproutViewingKey(const libzcash::SproutViewingKey &vk); - private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); diff --git a/src/zcash/Address.cpp b/src/zcash/Address.cpp index 148cd321c..5ce66a82f 100644 --- a/src/zcash/Address.cpp +++ b/src/zcash/Address.cpp @@ -1,3 +1,7 @@ +// Copyright (c) 2019-2020 The Hush developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php + #include "Address.hpp" #include "NoteEncryption.hpp" #include "hash.h" @@ -13,36 +17,6 @@ const uint32_t SAPLING_BRANCH_ID = 0x76b809bb; namespace libzcash { -uint256 SproutPaymentAddress::GetHash() const { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << *this; - return Hash(ss.begin(), ss.end()); -} - -uint256 ReceivingKey::pk_enc() const { - return ZCNoteEncryption::generate_pubkey(*this); -} - -SproutPaymentAddress SproutViewingKey::address() const { - return SproutPaymentAddress(a_pk, sk_enc.pk_enc()); -} - -ReceivingKey SproutSpendingKey::receiving_key() const { - return ReceivingKey(ZCNoteEncryption::generate_privkey(*this)); -} - -SproutViewingKey SproutSpendingKey::viewing_key() const { - return SproutViewingKey(PRF_addr_a_pk(*this), receiving_key()); -} - -SproutSpendingKey SproutSpendingKey::random() { - return SproutSpendingKey(random_uint252()); -} - -SproutPaymentAddress SproutSpendingKey::address() const { - return viewing_key().address(); -} - //! Sapling uint256 SaplingPaymentAddress::GetHash() const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -119,10 +93,6 @@ class IsValidAddressForNetwork : public boost::static_visitor { public: IsValidAddressForNetwork(uint32_t consensusBranchId) : branchId(consensusBranchId) {} - bool operator()(const libzcash::SproutPaymentAddress &addr) const { - return true; - } - bool operator()(const libzcash::InvalidEncoding &addr) const { return false; } diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 9af3c184a..152ad7295 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -25,7 +25,6 @@ #include "sodium.h" #include "streams.h" #include "txdb.h" -#include "utiltest.h" #include "wallet/wallet.h" #include "zcbenchmarks.h" @@ -41,7 +40,7 @@ void pre_wallet_load() { LogPrintf("%s: In progress...\n", __func__); if (ShutdownRequested()) - throw new std::runtime_error("The node is shutting down"); + throw new std::runtime_error("The Hush node is shutting down"); if (pwalletMain) pwalletMain->Flush(false); @@ -93,37 +92,6 @@ double benchmark_sleep() return timer_stop(tv_start); } -std::vector benchmark_create_joinsplit_threaded(int nThreads) -{ - std::vector ret; - std::vector> tasks; - std::vector threads; - for (int i = 0; i < nThreads; i++) { - std::packaged_task task(&benchmark_create_joinsplit); - tasks.emplace_back(task.get_future()); - threads.emplace_back(std::move(task)); - } - std::future_status status; - for (auto it = tasks.begin(); it != tasks.end(); it++) { - it->wait(); - ret.push_back(it->get()); - } - for (auto it = threads.begin(); it != threads.end(); it++) { - it->join(); - } - return ret; -} - -double benchmark_verify_joinsplit(const JSDescription &joinsplit) -{ - struct timeval tv_start; - timer_start(tv_start); - uint256 joinSplitPubKey; - auto verifier = libzcash::ProofVerifier::Strict(); - joinsplit.Verify(*pzcashParams, verifier, joinSplitPubKey); - return timer_stop(tv_start); -} - #ifdef ENABLE_MINING double benchmark_solve_equihash() {