desprout
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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<unsi
|
||||
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,
|
||||
const std::vector<unsigned char>& 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<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();
|
||||
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<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(
|
||||
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<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(
|
||||
const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
||||
const std::vector<unsigned char> &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<unsigned char> &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<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
|
||||
BOOST_FOREACH(SaplingSpendingKeyMap::value_type& mSaplingSpendingKey, mapSaplingSpendingKeys)
|
||||
{
|
||||
|
||||
@@ -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<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) {
|
||||
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<uint256>({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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<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::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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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<unsigned char>& vchCryptedSecret,
|
||||
const CKeyMetadata &keyMeta);
|
||||
bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk,
|
||||
const std::vector<unsigned char>& vchCryptedSecret,
|
||||
const CKeyMetadata &keyMeta);
|
||||
|
||||
bool WriteSproutViewingKey(const libzcash::SproutViewingKey &vk);
|
||||
bool EraseSproutViewingKey(const libzcash::SproutViewingKey &vk);
|
||||
|
||||
private:
|
||||
CWalletDB(const CWalletDB&);
|
||||
void operator=(const CWalletDB&);
|
||||
|
||||
Reference in New Issue
Block a user