desprout
This commit is contained in:
@@ -347,8 +347,6 @@ endif
|
|||||||
libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||||
libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
libbitcoin_wallet_a_SOURCES = \
|
libbitcoin_wallet_a_SOURCES = \
|
||||||
utiltest.cpp \
|
|
||||||
utiltest.h \
|
|
||||||
zcbenchmarks.cpp \
|
zcbenchmarks.cpp \
|
||||||
zcbenchmarks.h \
|
zcbenchmarks.h \
|
||||||
wallet/asyncrpcoperation_mergetoaddress.cpp \
|
wallet/asyncrpcoperation_mergetoaddress.cpp \
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
#include "primitives/transaction.h"
|
|
||||||
#include "zcash/Note.hpp"
|
|
||||||
#include "zcash/Address.hpp"
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
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<libzcash::JSInput, ZC_NUM_JS_INPUTS> inputs = {
|
|
||||||
libzcash::JSInput(witness, note, k),
|
|
||||||
libzcash::JSInput() // dummy input of zero value
|
|
||||||
};
|
|
||||||
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs = {
|
|
||||||
libzcash::JSOutput(addr, 50),
|
|
||||||
libzcash::JSOutput(addr, 50)
|
|
||||||
};
|
|
||||||
std::array<size_t, ZC_NUM_JS_INPUTS> inputMap;
|
|
||||||
std::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap;
|
|
||||||
|
|
||||||
{
|
|
||||||
auto jsdesc = JSDescription::Randomized(
|
|
||||||
false,
|
|
||||||
*params, joinSplitPubKey, rt,
|
|
||||||
inputs, outputs,
|
|
||||||
inputMap, outputMap,
|
|
||||||
0, 0, false);
|
|
||||||
|
|
||||||
std::set<size_t> inputSet(inputMap.begin(), inputMap.end());
|
|
||||||
std::set<size_t> expectedInputSet {0, 1};
|
|
||||||
EXPECT_EQ(expectedInputSet, inputSet);
|
|
||||||
|
|
||||||
std::set<size_t> outputSet(outputMap.begin(), outputMap.end());
|
|
||||||
std::set<size_t> 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<size_t, ZC_NUM_JS_INPUTS> expectedInputMap {1, 0};
|
|
||||||
std::array<size_t, ZC_NUM_JS_OUTPUTS> 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<size_t, ZC_NUM_JS_INPUTS> expectedInputMap {0, 1};
|
|
||||||
std::array<size_t, ZC_NUM_JS_OUTPUTS> expectedOutputMap {0, 1};
|
|
||||||
EXPECT_EQ(expectedInputMap, inputMap);
|
|
||||||
EXPECT_EQ(expectedOutputMap, outputMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright (c) 2014-2016 The Bitcoin Core developers
|
// Copyright (c) 2014-2016 The Bitcoin Core developers
|
||||||
// Copyright (c) 2016-2018 The Zcash developers
|
// Copyright (c) 2016-2018 The Zcash developers
|
||||||
|
// Copyright (c) 2019-2020 The Hush developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
@@ -84,15 +85,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
PaymentAddressEncoder(const CChainParams& params) : m_params(params) {}
|
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<unsigned char> 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
|
std::string operator()(const libzcash::SaplingPaymentAddress& zaddr) const
|
||||||
{
|
{
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
@@ -117,17 +109,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
ViewingKeyEncoder(const CChainParams& params) : m_params(params) {}
|
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<unsigned char> 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
|
std::string operator()(const libzcash::SaplingIncomingViewingKey& vk) const
|
||||||
{
|
{
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
@@ -152,17 +133,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
SpendingKeyEncoder(const CChainParams& params) : m_params(params) {}
|
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<unsigned char> 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
|
std::string operator()(const libzcash::SaplingExtendedSpendingKey& zkey) const
|
||||||
{
|
{
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
@@ -324,18 +294,6 @@ std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
|
|||||||
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
|
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> data;
|
std::vector<unsigned char> data;
|
||||||
if (DecodeBase58Check(str, data)) {
|
|
||||||
const std::vector<unsigned char>& 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);
|
auto bech = bech32::Decode(str);
|
||||||
if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS) &&
|
if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS) &&
|
||||||
bech.second.size() == ConvertedSaplingPaymentAddressSize) {
|
bech.second.size() == ConvertedSaplingPaymentAddressSize) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||||
|
// Copyright (c) 2019-2020 The Hush developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
@@ -128,15 +129,6 @@ bool CBasicKeyStore::HaveWatchOnly() const
|
|||||||
return (!setWatchOnly.empty());
|
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
|
//! Sapling
|
||||||
bool CBasicKeyStore::AddSaplingSpendingKey(
|
bool CBasicKeyStore::AddSaplingSpendingKey(
|
||||||
const libzcash::SaplingExtendedSpendingKey &sk,
|
const libzcash::SaplingExtendedSpendingKey &sk,
|
||||||
@@ -155,14 +147,6 @@ bool CBasicKeyStore::AddSaplingSpendingKey(
|
|||||||
return true;
|
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(
|
bool CBasicKeyStore::AddSaplingFullViewingKey(
|
||||||
const libzcash::SaplingFullViewingKey &fvk,
|
const libzcash::SaplingFullViewingKey &fvk,
|
||||||
@@ -190,18 +174,7 @@ bool CBasicKeyStore::AddSaplingIncomingViewingKey(
|
|||||||
return true;
|
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
|
bool CBasicKeyStore::HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const
|
||||||
{
|
{
|
||||||
@@ -215,19 +188,6 @@ bool CBasicKeyStore::HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymen
|
|||||||
return mapSaplingIncomingViewingKeys.count(addr) > 0;
|
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,
|
bool CBasicKeyStore::GetSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk,
|
||||||
libzcash::SaplingFullViewingKey &fvkOut) const
|
libzcash::SaplingFullViewingKey &fvkOut) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,11 +120,6 @@ protected:
|
|||||||
KeyMap mapKeys;
|
KeyMap mapKeys;
|
||||||
ScriptMap mapScripts;
|
ScriptMap mapScripts;
|
||||||
WatchOnlySet setWatchOnly;
|
WatchOnlySet setWatchOnly;
|
||||||
/*
|
|
||||||
SproutSpendingKeyMap mapSproutSpendingKeys;
|
|
||||||
SproutViewingKeyMap mapSproutViewingKeys;
|
|
||||||
NoteDecryptorMap mapNoteDecryptors;
|
|
||||||
*/
|
|
||||||
|
|
||||||
SaplingSpendingKeyMap mapSaplingSpendingKeys;
|
SaplingSpendingKeyMap mapSaplingSpendingKeys;
|
||||||
SaplingFullViewingKeyMap mapSaplingFullViewingKeys;
|
SaplingFullViewingKeyMap mapSaplingFullViewingKeys;
|
||||||
@@ -246,7 +241,6 @@ public:
|
|||||||
|
|
||||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
||||||
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
||||||
//typedef std::map<libzcash::SproutPaymentAddress, std::vector<unsigned char> > CryptedSproutSpendingKeyMap;
|
|
||||||
|
|
||||||
//! Sapling
|
//! Sapling
|
||||||
typedef std::map<libzcash::SaplingExtendedFullViewingKey, std::vector<unsigned char> > CryptedSaplingSpendingKeyMap;
|
typedef std::map<libzcash::SaplingExtendedFullViewingKey, std::vector<unsigned char> > CryptedSaplingSpendingKeyMap;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// Copyright (c) 2017 The Zcash developers
|
// Copyright (c) 2017 The Zcash developers
|
||||||
|
// Copyright (c) 2019-2020 The Hush developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
|||||||
" \"version\": xxxxx, (numeric) the server version\n"
|
" \"version\": xxxxx, (numeric) the server version\n"
|
||||||
" \"protocolversion\": xxxxx, (numeric) the protocol version\n"
|
" \"protocolversion\": xxxxx, (numeric) the protocol version\n"
|
||||||
" \"walletversion\": xxxxx, (numeric) the wallet 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"
|
" \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
|
||||||
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
|
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
|
||||||
" \"connections\": xxxxx, (numeric) the number of connections\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<UniValue>
|
|
||||||
{
|
|
||||||
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)
|
UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() != 1)
|
if (fHelp || params.size() != 1)
|
||||||
@@ -650,11 +626,25 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& my
|
|||||||
|
|
||||||
UniValue ret(UniValue::VOBJ);
|
UniValue ret(UniValue::VOBJ);
|
||||||
ret.push_back(Pair("isvalid", isValid));
|
ret.push_back(Pair("isvalid", isValid));
|
||||||
if (isValid)
|
auto zaddr = boost::get<libzcash::SaplingPaymentAddress>(&address);
|
||||||
|
if (isValid && (zaddr != nullptr))
|
||||||
{
|
{
|
||||||
ret.push_back(Pair("address", strAddress));
|
ret.push_back(Pair("address", strAddress));
|
||||||
UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(), address);
|
UniValue obj(UniValue::VOBJ);
|
||||||
ret.pushKVs(detail);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -733,9 +723,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
|||||||
|
|
||||||
"\nArguments:\n"
|
"\nArguments:\n"
|
||||||
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\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"
|
" [\n"
|
||||||
" \"key\" (string) Komodo address or hex-encoded public key\n"
|
" \"key\" (string) Hush address or hex-encoded public key\n"
|
||||||
" ,...\n"
|
" ,...\n"
|
||||||
" ]\n"
|
" ]\n"
|
||||||
|
|
||||||
@@ -769,10 +759,10 @@ UniValue verifymessage(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
|||||||
{
|
{
|
||||||
if (fHelp || params.size() != 3)
|
if (fHelp || params.size() != 3)
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"verifymessage \"komodoaddress\" \"signature\" \"message\"\n"
|
"verifymessage \"hushaddress\" \"signature\" \"message\"\n"
|
||||||
"\nVerify a signed message\n"
|
"\nVerify a signed message\n"
|
||||||
"\nArguments:\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"
|
"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"
|
"3. \"message\" (string, required) The message that was signed.\n"
|
||||||
"\nResult:\n"
|
"\nResult:\n"
|
||||||
|
|||||||
@@ -571,9 +571,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
|||||||
// Verify number of addresses stored in wallet is n1+n2
|
// Verify number of addresses stored in wallet is n1+n2
|
||||||
int numAddrs = myaddrs.size();
|
int numAddrs = myaddrs.size();
|
||||||
BOOST_CHECK(numAddrs == (2 * n1) + n2);
|
BOOST_CHECK(numAddrs == (2 * n1) + n2);
|
||||||
pwalletMain->GetSproutPaymentAddresses(addrs);
|
|
||||||
pwalletMain->GetSaplingPaymentAddresses(saplingAddrs);
|
pwalletMain->GetSaplingPaymentAddresses(saplingAddrs);
|
||||||
BOOST_CHECK(addrs.size() + saplingAddrs.size() == numAddrs);
|
BOOST_CHECK(saplingAddrs.size() == numAddrs);
|
||||||
|
|
||||||
// Ask wallet to list addresses
|
// Ask wallet to list addresses
|
||||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses"));
|
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();
|
std::string newaddress = retValue.get_str();
|
||||||
auto address = DecodePaymentAddress(newaddress);
|
auto address = DecodePaymentAddress(newaddress);
|
||||||
BOOST_CHECK(IsValidPaymentAddress(address));
|
BOOST_CHECK(IsValidPaymentAddress(address));
|
||||||
BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
|
||||||
auto newAddr = boost::get<libzcash::SproutPaymentAddress>(address);
|
|
||||||
BOOST_CHECK(pwalletMain->HaveSproutSpendingKey(newAddr));
|
|
||||||
|
|
||||||
// Check if too many args
|
// Check if too many args
|
||||||
BOOST_CHECK_THROW(CallRPC("z_getnewaddress toomanyargs"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC("z_getnewaddress toomanyargs"), runtime_error);
|
||||||
|
|||||||
154
src/utiltest.cpp
154
src/utiltest.cpp
@@ -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 <array>
|
|
||||||
|
|
||||||
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<libzcash::JSInput, 2> inputs = {
|
|
||||||
libzcash::JSInput(), // dummy input
|
|
||||||
libzcash::JSInput() // dummy input
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<libzcash::JSOutput, 2> 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<libzcash::JSInput, 2> inputs = {
|
|
||||||
libzcash::JSInput(tree.witness(), note, sk),
|
|
||||||
dummyin
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<libzcash::JSOutput, 2> 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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
// Copyright (c) 2017 The Zcash developers
|
// Copyright (c) 2017 The Zcash developers
|
||||||
|
// Copyright (c) 2019-2020 The Hush developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
@@ -123,7 +124,6 @@ public:
|
|||||||
ShieldToAddress(AsyncRPCOperation_shieldcoinbase *op, CAmount sendAmount) :
|
ShieldToAddress(AsyncRPCOperation_shieldcoinbase *op, CAmount sendAmount) :
|
||||||
m_op(op), sendAmount(sendAmount) {}
|
m_op(op), sendAmount(sendAmount) {}
|
||||||
|
|
||||||
bool operator()(const libzcash::SproutPaymentAddress &zaddr) const;
|
|
||||||
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
||||||
bool operator()(const libzcash::InvalidEncoding& no) const;
|
bool operator()(const libzcash::InvalidEncoding& no) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2009-2013 The Bitcoin Core developers
|
// Copyright (c) 2009-2013 The Bitcoin Core developers
|
||||||
|
// Copyright (c) 2019-2020 The Hush developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// 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. *
|
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||||
@@ -168,22 +169,6 @@ static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsi
|
|||||||
return key.VerifyPubKey(vchPubKey);
|
return key.VerifyPubKey(vchPubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DecryptSproutSpendingKey(const CKeyingMaterial& vMasterKey,
|
|
||||||
const std::vector<unsigned char>& 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,
|
static bool DecryptSaplingSpendingKey(const CKeyingMaterial& vMasterKey,
|
||||||
const std::vector<unsigned char>& vchCryptedSecret,
|
const std::vector<unsigned char>& vchCryptedSecret,
|
||||||
@@ -207,7 +192,7 @@ bool CCryptoKeyStore::SetCrypted()
|
|||||||
LOCK2(cs_KeyStore, cs_SpendingKeyStore);
|
LOCK2(cs_KeyStore, cs_SpendingKeyStore);
|
||||||
if (fUseCrypto)
|
if (fUseCrypto)
|
||||||
return true;
|
return true;
|
||||||
if (!(mapKeys.empty() && mapSproutSpendingKeys.empty() && mapSaplingSpendingKeys.empty()))
|
if (!(mapKeys.empty() && mapSaplingSpendingKeys.empty()))
|
||||||
return false;
|
return false;
|
||||||
fUseCrypto = true;
|
fUseCrypto = true;
|
||||||
return true;
|
return true;
|
||||||
@@ -260,21 +245,6 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
|||||||
if (fDecryptionThoroughlyChecked)
|
if (fDecryptionThoroughlyChecked)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CryptedSproutSpendingKeyMap::const_iterator miSprout = mapCryptedSproutSpendingKeys.begin();
|
|
||||||
for (; miSprout != mapCryptedSproutSpendingKeys.end(); ++miSprout)
|
|
||||||
{
|
|
||||||
const libzcash::SproutPaymentAddress &address = (*miSprout).first;
|
|
||||||
const std::vector<unsigned char> &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();
|
CryptedSaplingSpendingKeyMap::const_iterator miSapling = mapCryptedSaplingSpendingKeys.begin();
|
||||||
for (; miSapling != mapCryptedSaplingSpendingKeys.end(); ++miSapling)
|
for (; miSapling != mapCryptedSaplingSpendingKeys.end(); ++miSapling)
|
||||||
{
|
{
|
||||||
@@ -292,7 +262,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
|||||||
}
|
}
|
||||||
if (keyPass && keyFail)
|
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);
|
assert(false);
|
||||||
}
|
}
|
||||||
if (keyFail || !keyPass)
|
if (keyFail || !keyPass)
|
||||||
@@ -440,30 +410,6 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_SpendingKeyStore);
|
|
||||||
if (!IsCrypted())
|
|
||||||
return CBasicKeyStore::AddSproutSpendingKey(sk);
|
|
||||||
|
|
||||||
if (IsLocked())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::vector<unsigned char> 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(
|
bool CCryptoKeyStore::AddSaplingSpendingKey(
|
||||||
const libzcash::SaplingExtendedSpendingKey &sk,
|
const libzcash::SaplingExtendedSpendingKey &sk,
|
||||||
const libzcash::SaplingPaymentAddress &defaultAddr)
|
const libzcash::SaplingPaymentAddress &defaultAddr)
|
||||||
@@ -494,22 +440,6 @@ bool CCryptoKeyStore::AddSaplingSpendingKey(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddCryptedSproutSpendingKey(
|
|
||||||
const libzcash::SproutPaymentAddress &address,
|
|
||||||
const libzcash::ReceivingKey &rk,
|
|
||||||
const std::vector<unsigned char> &vchCryptedSecret)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_SpendingKeyStore);
|
|
||||||
if (!SetCrypted())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mapCryptedSproutSpendingKeys[address] = vchCryptedSecret;
|
|
||||||
mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(rk)));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddCryptedSaplingSpendingKey(
|
bool CCryptoKeyStore::AddCryptedSaplingSpendingKey(
|
||||||
const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
||||||
const std::vector<unsigned char> &vchCryptedSecret,
|
const std::vector<unsigned char> &vchCryptedSecret,
|
||||||
@@ -531,23 +461,6 @@ bool CCryptoKeyStore::AddCryptedSaplingSpendingKey(
|
|||||||
return true;
|
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<unsigned char> &vchCryptedSecret = (*mi).second;
|
|
||||||
return DecryptSproutSpendingKey(vMasterKey, vchCryptedSecret, address, skOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingExtendedSpendingKey &skOut) const
|
bool CCryptoKeyStore::GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingExtendedSpendingKey &skOut) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -603,22 +516,6 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mapKeys.clear();
|
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<unsigned char> vchCryptedSecret;
|
|
||||||
if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!AddCryptedSproutSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mapSproutSpendingKeys.clear();
|
|
||||||
//! Sapling key support
|
//! Sapling key support
|
||||||
BOOST_FOREACH(SaplingSpendingKeyMap::value_type& mSaplingSpendingKey, mapSaplingSpendingKeys)
|
BOOST_FOREACH(SaplingSpendingKeyMap::value_type& mSaplingSpendingKey, mapSaplingSpendingKeys)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -139,341 +139,8 @@ TEST(WalletTests, SetupDatadirLocationRunAsFirstTest) {
|
|||||||
boost::filesystem::create_directories(pathTemp);
|
boost::filesystem::create_directories(pathTemp);
|
||||||
mapArgs["-datadir"] = pathTemp.string();
|
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<CSproutNotePlaintextEntry> sproutEntries;
|
|
||||||
std::vector<SaplingNoteEntry> 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<unsigned char, secure_allocator<unsigned char>> 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<bool>(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) {
|
TEST(WalletTests, FindMySaplingNotes) {
|
||||||
SelectParams(CBaseChainParams::REGTEST);
|
SelectParams(CBaseChainParams::REGTEST);
|
||||||
@@ -577,92 +244,6 @@ TEST(WalletTests, FindMySaplingNotesWithIvkOnly) {
|
|||||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT);
|
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<uint256>({hash2, hash3}), c3);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate note A and spend to create note B, from which we spend to create two conflicting transactions
|
// Generate note A and spend to create note B, from which we spend to create two conflicting transactions
|
||||||
TEST(WalletTests, GetConflictedSaplingNotes) {
|
TEST(WalletTests, GetConflictedSaplingNotes) {
|
||||||
SelectParams(CBaseChainParams::REGTEST);
|
SelectParams(CBaseChainParams::REGTEST);
|
||||||
@@ -1735,88 +1316,6 @@ TEST(WalletTests, SetBestChainIgnoresTxsWithoutShieldedData) {
|
|||||||
wallet.SetBestChain(walletdb, loc);
|
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) {
|
TEST(WalletTests, UpdatedSaplingNoteData) {
|
||||||
SelectParams(CBaseChainParams::REGTEST);
|
SelectParams(CBaseChainParams::REGTEST);
|
||||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
|
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
|
||||||
@@ -1941,37 +1440,6 @@ TEST(WalletTests, UpdatedSaplingNoteData) {
|
|||||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT);
|
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) {
|
TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) {
|
||||||
SelectParams(CBaseChainParams::REGTEST);
|
SelectParams(CBaseChainParams::REGTEST);
|
||||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
|
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
|
||||||
@@ -1999,7 +1467,7 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) {
|
|||||||
auto scriptPubKey = GetScriptForDestination(tsk.GetPubKey().GetID());
|
auto scriptPubKey = GetScriptForDestination(tsk.GetPubKey().GetID());
|
||||||
|
|
||||||
// Generate shielding tx from transparent to Sapling
|
// 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);
|
auto builder = TransactionBuilder(consensusParams, 1, &keystore);
|
||||||
builder.AddTransparentInput(COutPoint(), scriptPubKey, 50000);
|
builder.AddTransparentInput(COutPoint(), scriptPubKey, 50000);
|
||||||
builder.AddSaplingOutput(fvk.ovk, pk, 40000, {});
|
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_SAPLING, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT);
|
||||||
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, 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) {
|
TEST(WalletTests, SaplingNoteLocking) {
|
||||||
TestWallet wallet;
|
TestWallet wallet;
|
||||||
|
|||||||
@@ -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");
|
"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) {
|
for (const SaplingNoteEntry& entry : saplingEntries) {
|
||||||
noteCounter++;
|
noteCounter++;
|
||||||
CAmount nValue = entry.note.value();
|
CAmount nValue = entry.note.value();
|
||||||
|
|||||||
@@ -1408,7 +1408,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
PaymentAddressBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {}
|
PaymentAddressBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {}
|
||||||
|
|
||||||
bool operator()(const libzcash::SproutPaymentAddress &zaddr) const;
|
|
||||||
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
||||||
bool operator()(const libzcash::InvalidEncoding& no) const;
|
bool operator()(const libzcash::InvalidEncoding& no) const;
|
||||||
};
|
};
|
||||||
@@ -1421,7 +1420,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
IncomingViewingKeyBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {}
|
IncomingViewingKeyBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {}
|
||||||
|
|
||||||
bool operator()(const libzcash::SproutPaymentAddress &zaddr) const;
|
|
||||||
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
||||||
bool operator()(const libzcash::InvalidEncoding& no) const;
|
bool operator()(const libzcash::InvalidEncoding& no) const;
|
||||||
};
|
};
|
||||||
@@ -1433,7 +1431,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
HaveSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
|
HaveSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
|
||||||
|
|
||||||
bool operator()(const libzcash::SproutPaymentAddress &zaddr) const;
|
|
||||||
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
||||||
bool operator()(const libzcash::InvalidEncoding& no) const;
|
bool operator()(const libzcash::InvalidEncoding& no) const;
|
||||||
};
|
};
|
||||||
@@ -1445,7 +1442,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
|
GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
|
||||||
|
|
||||||
boost::optional<libzcash::SpendingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
|
|
||||||
boost::optional<libzcash::SpendingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
boost::optional<libzcash::SpendingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
||||||
boost::optional<libzcash::SpendingKey> operator()(const libzcash::InvalidEncoding& no) const;
|
boost::optional<libzcash::SpendingKey> operator()(const libzcash::InvalidEncoding& no) const;
|
||||||
};
|
};
|
||||||
@@ -1517,7 +1513,6 @@ public:
|
|||||||
) : m_wallet(wallet), params(params), nTime(_nTime), hdKeypath(_hdKeypath), seedFpStr(_seedFp), log(_log) {}
|
) : 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::SaplingExtendedSpendingKey &sk) const;
|
||||||
SpendingKeyAddResult operator()(const libzcash::InvalidEncoding& no) const;
|
SpendingKeyAddResult operator()(const libzcash::InvalidEncoding& no) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -653,6 +653,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||||||
}
|
}
|
||||||
else if (strType == "czkey")
|
else if (strType == "czkey")
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
libzcash::SproutPaymentAddress addr;
|
libzcash::SproutPaymentAddress addr;
|
||||||
ssKey >> addr;
|
ssKey >> addr;
|
||||||
// Deserialization of a pair is just one item after another
|
// Deserialization of a pair is just one item after another
|
||||||
@@ -663,12 +664,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||||||
ssValue >> vchCryptedSecret;
|
ssValue >> vchCryptedSecret;
|
||||||
wss.nCKeys++;
|
wss.nCKeys++;
|
||||||
|
|
||||||
//if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret))
|
if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret))
|
||||||
//{
|
{
|
||||||
// strErr = "Error reading wallet database: LoadCryptedZKey failed";
|
strErr = "Error reading wallet database: LoadCryptedZKey failed";
|
||||||
// return false;
|
return false;
|
||||||
//}
|
}
|
||||||
//wss.fIsEncrypted = true;
|
wss.fIsEncrypted = true;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else if (strType == "csapzkey")
|
else if (strType == "csapzkey")
|
||||||
{
|
{
|
||||||
@@ -704,11 +706,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||||||
}
|
}
|
||||||
else if (strType == "zkeymeta")
|
else if (strType == "zkeymeta")
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
libzcash::SproutPaymentAddress addr;
|
libzcash::SproutPaymentAddress addr;
|
||||||
ssKey >> addr;
|
ssKey >> addr;
|
||||||
CKeyMetadata keyMeta;
|
CKeyMetadata keyMeta;
|
||||||
ssValue >> keyMeta;
|
ssValue >> keyMeta;
|
||||||
wss.nZKeyMeta++;
|
wss.nZKeyMeta++;
|
||||||
|
*/
|
||||||
|
|
||||||
// pwallet->LoadZKeyMetadata(addr, keyMeta);
|
// pwallet->LoadZKeyMetadata(addr, keyMeta);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
// Copyright (c) 2009-2013 The Bitcoin Core developers
|
// Copyright (c) 2009-2013 The Bitcoin Core developers
|
||||||
|
// Copyright (c) 2009-2013 The Hush developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// 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. *
|
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||||
@@ -199,23 +200,15 @@ public:
|
|||||||
bool WriteHDChain(const CHDChain& chain);
|
bool WriteHDChain(const CHDChain& chain);
|
||||||
|
|
||||||
/// Write spending key to wallet database, where key is payment address and value is spending key.
|
/// 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,
|
bool WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk,
|
||||||
const libzcash::SaplingExtendedSpendingKey &key,
|
const libzcash::SaplingExtendedSpendingKey &key,
|
||||||
const CKeyMetadata &keyMeta);
|
const CKeyMetadata &keyMeta);
|
||||||
bool WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr,
|
bool WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr,
|
||||||
const libzcash::SaplingIncomingViewingKey &ivk);
|
const libzcash::SaplingIncomingViewingKey &ivk);
|
||||||
bool WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr,
|
|
||||||
const libzcash::ReceivingKey & rk,
|
|
||||||
const std::vector<unsigned char>& vchCryptedSecret,
|
|
||||||
const CKeyMetadata &keyMeta);
|
|
||||||
bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
||||||
const std::vector<unsigned char>& vchCryptedSecret,
|
const std::vector<unsigned char>& vchCryptedSecret,
|
||||||
const CKeyMetadata &keyMeta);
|
const CKeyMetadata &keyMeta);
|
||||||
|
|
||||||
bool WriteSproutViewingKey(const libzcash::SproutViewingKey &vk);
|
|
||||||
bool EraseSproutViewingKey(const libzcash::SproutViewingKey &vk);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CWalletDB(const CWalletDB&);
|
CWalletDB(const CWalletDB&);
|
||||||
void operator=(const CWalletDB&);
|
void operator=(const CWalletDB&);
|
||||||
|
|||||||
@@ -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 "Address.hpp"
|
||||||
#include "NoteEncryption.hpp"
|
#include "NoteEncryption.hpp"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
@@ -13,36 +17,6 @@ const uint32_t SAPLING_BRANCH_ID = 0x76b809bb;
|
|||||||
|
|
||||||
namespace libzcash {
|
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
|
//! Sapling
|
||||||
uint256 SaplingPaymentAddress::GetHash() const {
|
uint256 SaplingPaymentAddress::GetHash() const {
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
@@ -119,10 +93,6 @@ class IsValidAddressForNetwork : public boost::static_visitor<bool> {
|
|||||||
public:
|
public:
|
||||||
IsValidAddressForNetwork(uint32_t consensusBranchId) : branchId(consensusBranchId) {}
|
IsValidAddressForNetwork(uint32_t consensusBranchId) : branchId(consensusBranchId) {}
|
||||||
|
|
||||||
bool operator()(const libzcash::SproutPaymentAddress &addr) const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const libzcash::InvalidEncoding &addr) const {
|
bool operator()(const libzcash::InvalidEncoding &addr) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include "sodium.h"
|
#include "sodium.h"
|
||||||
#include "streams.h"
|
#include "streams.h"
|
||||||
#include "txdb.h"
|
#include "txdb.h"
|
||||||
#include "utiltest.h"
|
|
||||||
#include "wallet/wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
#include "zcbenchmarks.h"
|
#include "zcbenchmarks.h"
|
||||||
@@ -41,7 +40,7 @@ void pre_wallet_load()
|
|||||||
{
|
{
|
||||||
LogPrintf("%s: In progress...\n", __func__);
|
LogPrintf("%s: In progress...\n", __func__);
|
||||||
if (ShutdownRequested())
|
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)
|
if (pwalletMain)
|
||||||
pwalletMain->Flush(false);
|
pwalletMain->Flush(false);
|
||||||
@@ -93,37 +92,6 @@ double benchmark_sleep()
|
|||||||
return timer_stop(tv_start);
|
return timer_stop(tv_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<double> benchmark_create_joinsplit_threaded(int nThreads)
|
|
||||||
{
|
|
||||||
std::vector<double> ret;
|
|
||||||
std::vector<std::future<double>> tasks;
|
|
||||||
std::vector<std::thread> threads;
|
|
||||||
for (int i = 0; i < nThreads; i++) {
|
|
||||||
std::packaged_task<double(void)> 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
|
#ifdef ENABLE_MINING
|
||||||
double benchmark_solve_equihash()
|
double benchmark_solve_equihash()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user