Browse Source

desprout

pull/117/head
Duke Leto 4 years ago
parent
commit
5be12774f4
  1. 186
      src/wallet/asyncrpcoperation_mergetoaddress.cpp
  2. 189
      src/wallet/asyncrpcoperation_shieldcoinbase.cpp
  3. 140
      src/wallet/wallet.cpp
  4. 76
      src/wallet/walletdb.cpp

186
src/wallet/asyncrpcoperation_mergetoaddress.cpp

@ -518,186 +518,6 @@ void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj)
tx_ = tx;
}
UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info)
{
std::vector<boost::optional<SproutWitness>> witnesses;
uint256 anchor;
{
LOCK(cs_main);
anchor = pcoinsTip->GetBestAnchor(SPROUT); // As there are no inputs, ask the wallet for the best anchor
}
return perform_joinsplit(info, witnesses, anchor);
}
UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info, std::vector<JSOutPoint>& outPoints)
{
std::vector<boost::optional<SproutWitness>> witnesses;
uint256 anchor;
return perform_joinsplit(info, witnesses, anchor);
}
UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
MergeToAddressJSInfo& info,
std::vector<boost::optional<SproutWitness>> witnesses,
uint256 anchor)
{
if (anchor.IsNull()) {
throw std::runtime_error("anchor is null");
}
if (witnesses.size() != info.notes.size()) {
throw runtime_error("number of notes and witnesses do not match");
}
if (info.notes.size() != info.zkeys.size()) {
throw runtime_error("number of notes and spending keys do not match");
}
for (size_t i = 0; i < witnesses.size(); i++) {
if (!witnesses[i]) {
throw runtime_error("joinsplit input could not be found in tree");
}
info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], info.zkeys[i]));
}
// Make sure there are two inputs and two outputs
while (info.vjsin.size() < ZC_NUM_JS_INPUTS) {
info.vjsin.push_back(JSInput());
}
while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) {
info.vjsout.push_back(JSOutput());
}
if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) {
throw runtime_error("unsupported joinsplit input/output counts");
}
CMutableTransaction mtx(tx_);
LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n",
getId(),
tx_.vjoinsplit.size(),
FormatMoney(info.vpub_old), FormatMoney(info.vpub_new),
FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()),
FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value));
// Generate the proof, this can take over a minute.
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS> inputs{info.vjsin[0], info.vjsin[1]};
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs{info.vjsout[0], info.vjsout[1]};
std::array<size_t, ZC_NUM_JS_INPUTS> inputMap;
std::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap;
uint256 esk; // payment disclosure - secret
JSDescription jsdesc = JSDescription::Randomized(
*pzcashParams,
joinSplitPubKey_,
anchor,
inputs,
outputs,
inputMap,
outputMap,
info.vpub_old,
info.vpub_new,
!this->testmode,
&esk); // parameter expects pointer to esk, so pass in address
{
auto verifier = libzcash::ProofVerifier::Strict();
if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) {
throw std::runtime_error("error verifying joinsplit");
}
}
mtx.vjoinsplit.push_back(jsdesc);
// Empty output script.
CScript scriptCode;
CTransaction signTx(mtx);
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_);
// Add the signature
if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
dataToBeSigned.begin(), 32,
joinSplitPrivKey_) == 0)) {
throw std::runtime_error("crypto_sign_detached failed");
}
// Sanity check
if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0],
dataToBeSigned.begin(), 32,
mtx.joinSplitPubKey.begin()) == 0)) {
throw std::runtime_error("crypto_sign_verify_detached failed");
}
CTransaction rawTx(mtx);
tx_ = rawTx;
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << rawTx;
std::string encryptedNote1;
std::string encryptedNote2;
{
CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
ss2 << ((unsigned char)0x00);
ss2 << jsdesc.ephemeralKey;
ss2 << jsdesc.ciphertexts[0];
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
}
{
CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
ss2 << ((unsigned char)0x01);
ss2 << jsdesc.ephemeralKey;
ss2 << jsdesc.ciphertexts[1];
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
}
UniValue arrInputMap(UniValue::VARR);
UniValue arrOutputMap(UniValue::VARR);
for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) {
arrInputMap.push_back(static_cast<uint64_t>(inputMap[i]));
}
for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) {
arrOutputMap.push_back(static_cast<uint64_t>(outputMap[i]));
}
// !!! Payment disclosure START
unsigned char buffer[32] = {0};
memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer
std::vector<unsigned char> vch(&buffer[0], &buffer[0] + 32);
uint256 joinSplitPrivKey = uint256(vch);
size_t js_index = tx_.vjoinsplit.size() - 1;
uint256 placeholder;
for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) {
uint8_t mapped_index = outputMap[i];
// placeholder for txid will be filled in later when tx has been finalized and signed.
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
JSOutput output = outputs[mapped_index];
libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr));
}
// !!! Payment disclosure END
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("encryptednote1", encryptedNote1));
obj.push_back(Pair("encryptednote2", encryptedNote2));
obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end())));
obj.push_back(Pair("inputmap", arrInputMap));
obj.push_back(Pair("outputmap", arrOutputMap));
return obj;
}
std::array<unsigned char, ZC_MEMO_SIZE> AsyncRPCOperation_mergetoaddress::get_memo_from_hex_string(std::string s)
{
std::array<unsigned char, ZC_MEMO_SIZE> memo = {{0x00}};
@ -764,9 +584,6 @@ void AsyncRPCOperation_mergetoaddress::unlock_utxos() {
*/
void AsyncRPCOperation_mergetoaddress::lock_notes() {
LOCK2(cs_main, pwalletMain->cs_wallet);
for (auto note : sproutNoteInputs_) {
pwalletMain->LockNote(std::get<0>(note));
}
for (auto note : saplingNoteInputs_) {
pwalletMain->LockNote(std::get<0>(note));
}
@ -777,9 +594,6 @@ void AsyncRPCOperation_mergetoaddress::lock_notes() {
*/
void AsyncRPCOperation_mergetoaddress::unlock_notes() {
LOCK2(cs_main, pwalletMain->cs_wallet);
for (auto note : sproutNoteInputs_) {
pwalletMain->UnlockNote(std::get<0>(note));
}
for (auto note : saplingNoteInputs_) {
pwalletMain->UnlockNote(std::get<0>(note));
}

189
src/wallet/asyncrpcoperation_shieldcoinbase.cpp

@ -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.
@ -234,37 +235,6 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() {
return boost::apply_visitor(ShieldToAddress(this, sendAmount), tozaddr_);
}
bool ShieldToAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const {
// update the transaction with these inputs
CMutableTransaction rawTx(m_op->tx_);
for (ShieldCoinbaseUTXO & t : m_op->inputs_) {
CTxIn in(COutPoint(t.txid, t.vout));
if (t.amount >= ASSETCHAINS_TIMELOCKGTE)
in.nSequence = 0xfffffffe;
rawTx.vin.push_back(in);
}
m_op->tx_ = CTransaction(rawTx);
// Prepare raw transaction to handle JoinSplits
CMutableTransaction mtx(m_op->tx_);
crypto_sign_keypair(m_op->joinSplitPubKey_.begin(), m_op->joinSplitPrivKey_);
mtx.joinSplitPubKey = m_op->joinSplitPubKey_;
m_op->tx_ = CTransaction(mtx);
// Create joinsplit
UniValue obj(UniValue::VOBJ);
ShieldCoinbaseJSInfo info;
info.vpub_old = sendAmount;
info.vpub_new = 0;
JSOutput jso = JSOutput(zaddr, sendAmount);
info.vjsout.push_back(jso);
obj = m_op->perform_joinsplit(info);
m_op->sign_send_raw_transaction(obj);
return true;
}
extern UniValue signrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk);
extern UniValue sendrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk);
@ -406,163 +376,6 @@ void AsyncRPCOperation_shieldcoinbase::sign_send_raw_transaction(UniValue obj)
}
UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInfo & info) {
uint32_t consensusBranchId;
uint256 anchor;
{
LOCK(cs_main);
consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
anchor = pcoinsTip->GetBestAnchor(SPROUT);
}
if (anchor.IsNull()) {
throw std::runtime_error("anchor is null");
}
// Make sure there are two inputs and two outputs
while (info.vjsin.size() < ZC_NUM_JS_INPUTS) {
info.vjsin.push_back(JSInput());
}
while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) {
info.vjsout.push_back(JSOutput());
}
if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) {
throw runtime_error("unsupported joinsplit input/output counts");
}
CMutableTransaction mtx(tx_);
LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n",
getId(),
tx_.vjoinsplit.size(),
FormatMoney(info.vpub_old), FormatMoney(info.vpub_new),
FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()),
FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value)
);
// Generate the proof, this can take over a minute.
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS> inputs
{info.vjsin[0], info.vjsin[1]};
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs
{info.vjsout[0], info.vjsout[1]};
std::array<size_t, ZC_NUM_JS_INPUTS> inputMap;
std::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap;
uint256 esk; // payment disclosure - secret
JSDescription jsdesc = JSDescription::Randomized(
*pzcashParams,
joinSplitPubKey_,
anchor,
inputs,
outputs,
inputMap,
outputMap,
info.vpub_old,
info.vpub_new,
!this->testmode,
&esk); // parameter expects pointer to esk, so pass in address
{
auto verifier = libzcash::ProofVerifier::Strict();
if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) {
throw std::runtime_error("error verifying joinsplit");
}
}
mtx.vjoinsplit.push_back(jsdesc);
// Empty output script.
CScript scriptCode;
CTransaction signTx(mtx);
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
// Add the signature
if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
dataToBeSigned.begin(), 32,
joinSplitPrivKey_
) == 0))
{
throw std::runtime_error("crypto_sign_detached failed");
}
// Sanity check
if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0],
dataToBeSigned.begin(), 32,
mtx.joinSplitPubKey.begin()
) == 0))
{
throw std::runtime_error("crypto_sign_verify_detached failed");
}
CTransaction rawTx(mtx);
tx_ = rawTx;
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << rawTx;
std::string encryptedNote1;
std::string encryptedNote2;
{
CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
ss2 << ((unsigned char) 0x00);
ss2 << jsdesc.ephemeralKey;
ss2 << jsdesc.ciphertexts[0];
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
}
{
CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
ss2 << ((unsigned char) 0x01);
ss2 << jsdesc.ephemeralKey;
ss2 << jsdesc.ciphertexts[1];
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
}
UniValue arrInputMap(UniValue::VARR);
UniValue arrOutputMap(UniValue::VARR);
for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) {
arrInputMap.push_back(static_cast<uint64_t>(inputMap[i]));
}
for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) {
arrOutputMap.push_back(static_cast<uint64_t>(outputMap[i]));
}
// !!! Payment disclosure START
unsigned char buffer[32] = {0};
memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer
std::vector<unsigned char> vch(&buffer[0], &buffer[0] + 32);
uint256 joinSplitPrivKey = uint256(vch);
size_t js_index = tx_.vjoinsplit.size() - 1;
uint256 placeholder;
for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) {
uint8_t mapped_index = outputMap[i];
// placeholder for txid will be filled in later when tx has been finalized and signed.
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
JSOutput output = outputs[mapped_index];
libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr));
}
// !!! Payment disclosure END
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("encryptednote1", encryptedNote1));
obj.push_back(Pair("encryptednote2", encryptedNote2));
obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end())));
obj.push_back(Pair("inputmap", arrInputMap));
obj.push_back(Pair("outputmap", arrOutputMap));
return obj;
}
/**
* Override getStatus() to append the operation's context object to the default status object.
*/

140
src/wallet/wallet.cpp

@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2019 The Hush 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.
@ -314,22 +314,11 @@ bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
return true;
}
bool CWallet::LoadZKeyMetadata(const SproutPaymentAddress &addr, const CKeyMetadata &meta)
{
AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata
mapSproutZKeyMetadata[addr] = meta;
return true;
}
bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
{
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
}
bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret)
{
return CCryptoKeyStore::AddCryptedSproutSpendingKey(addr, rk, vchCryptedSecret);
}
bool CWallet::LoadCryptedSaplingZKey(
const libzcash::SaplingExtendedFullViewingKey &extfvk,
@ -357,10 +346,6 @@ bool CWallet::LoadSaplingPaymentAddress(
return CCryptoKeyStore::AddSaplingIncomingViewingKey(ivk, addr);
}
bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key)
{
return CCryptoKeyStore::AddSproutSpendingKey(key);
}
bool CWallet::LoadCScript(const CScript& redeemScript)
{
@ -650,20 +635,6 @@ set<uint256> CWallet::GetConflicts(const uint256& txid) const
result.insert(it->second);
}
std::pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range_n;
for (const JSDescription& jsdesc : wtx.vjoinsplit) {
for (const uint256& nullifier : jsdesc.nullifiers) {
if (mapTxSproutNullifiers.count(nullifier) <= 1) {
continue; // No conflict if zero or one spends
}
range_n = mapTxSproutNullifiers.equal_range(nullifier);
for (TxNullifiers::const_iterator it = range_n.first; it != range_n.second; ++it) {
result.insert(it->second);
}
}
}
std::pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range_o;
for (const SpendDescription &spend : wtx.vShieldedSpend) {
@ -1367,7 +1338,6 @@ void CWallet::UpdateNullifierNoteMapForBlock(const CBlock *pblock) {
auto hash = tx.GetHash();
bool txIsOurs = mapWallet.count(hash);
if (txIsOurs) {
UpdateSproutNullifierNoteMapWithTx(mapWallet[hash]);
UpdateSaplingNullifierNoteMapWithTx(mapWallet[hash]);
}
}
@ -1750,7 +1720,7 @@ void CWallet::GetSaplingNoteWitnesses(std::vector<SaplingOutPoint> notes,
} else {
if(*rt == witnesses[i]->root()) {
// Something is fucky
std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root:" << rt.GetHash();
std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root!";
throw std::logic_error(err);
}
@ -2104,10 +2074,6 @@ bool CWallet::LoadCryptedHDSeed(const uint256& seedFp, const std::vector<unsigne
return CCryptoKeyStore::SetCryptedHDSeed(seedFp, seed);
}
void CWalletTx::SetSproutNoteData(mapSproutNoteData_t &noteData)
{
}
void CWalletTx::SetSaplingNoteData(mapSaplingNoteData_t &noteData)
{
mapSaplingNoteData.clear();
@ -2251,36 +2217,6 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
if (isFromMyTaddr) {
CAmount myVpubOld = 0;
CAmount myVpubNew = 0;
for (const JSDescription& js : vjoinsplit) {
bool fMyJSDesc = false;
// Check input side
for (const uint256& nullifier : js.nullifiers) {
if (pwallet->IsSproutNullifierFromMe(nullifier)) {
fMyJSDesc = true;
break;
}
}
// Check output side
if (!fMyJSDesc) {
for (const std::pair<JSOutPoint, SproutNoteData> nd : this->mapSproutNoteData) {
if (nd.first.js < vjoinsplit.size() && nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
fMyJSDesc = true;
break;
}
}
}
if (fMyJSDesc) {
myVpubOld += js.vpub_old;
myVpubNew += js.vpub_new;
}
if (!MoneyRange(js.vpub_old) || !MoneyRange(js.vpub_new) || !MoneyRange(myVpubOld) || !MoneyRange(myVpubNew)) {
throw std::runtime_error("CWalletTx::GetAmounts: value out of range");
}
}
// Create an output for the value taken from or added to the transparent value pool by JoinSplits
if (myVpubOld > myVpubNew) {
@ -4580,38 +4516,6 @@ void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
// Note Locking Operations
void CWallet::LockNote(const JSOutPoint& output)
{
AssertLockHeld(cs_wallet); // setLockedSproutNotes
setLockedSproutNotes.insert(output);
}
void CWallet::UnlockNote(const JSOutPoint& output)
{
AssertLockHeld(cs_wallet); // setLockedSproutNotes
setLockedSproutNotes.erase(output);
}
void CWallet::UnlockAllSproutNotes()
{
AssertLockHeld(cs_wallet); // setLockedSproutNotes
setLockedSproutNotes.clear();
}
bool CWallet::IsLockedNote(const JSOutPoint& outpt) const
{
AssertLockHeld(cs_wallet); // setLockedSproutNotes
return (setLockedSproutNotes.count(outpt) > 0);
}
std::vector<JSOutPoint> CWallet::ListLockedSproutNotes()
{
AssertLockHeld(cs_wallet); // setLockedSproutNotes
std::vector<JSOutPoint> vOutpts(setLockedSproutNotes.begin(), setLockedSproutNotes.end());
return vOutpts;
}
void CWallet::LockNote(const SaplingOutPoint& output)
{
AssertLockHeld(cs_wallet);
@ -4988,11 +4892,6 @@ void CWallet::GetFilteredNotes(
// Shielded key and address generalizations
//
bool IncomingViewingKeyBelongsToWallet::operator()(const libzcash::SproutPaymentAddress &zaddr) const
{
return m_wallet->HaveSproutViewingKey(zaddr);
}
bool IncomingViewingKeyBelongsToWallet::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
{
libzcash::SaplingIncomingViewingKey ivk;
@ -5004,11 +4903,6 @@ bool IncomingViewingKeyBelongsToWallet::operator()(const libzcash::InvalidEncodi
return false;
}
bool PaymentAddressBelongsToWallet::operator()(const libzcash::SproutPaymentAddress &zaddr) const
{
return m_wallet->HaveSproutSpendingKey(zaddr) || m_wallet->HaveSproutViewingKey(zaddr);
}
bool PaymentAddressBelongsToWallet::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
{
libzcash::SaplingIncomingViewingKey ivk;
@ -5024,11 +4918,6 @@ bool PaymentAddressBelongsToWallet::operator()(const libzcash::InvalidEncoding&
return false;
}
bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const
{
return m_wallet->HaveSproutSpendingKey(zaddr);
}
bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
{
libzcash::SaplingIncomingViewingKey ivk;
@ -5044,17 +4933,6 @@ bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::InvalidEncodin
return false;
}
boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const libzcash::SproutPaymentAddress &zaddr) const
{
libzcash::SproutSpendingKey k;
if (m_wallet->GetSproutSpendingKey(zaddr, k)) {
return libzcash::SpendingKey(k);
} else {
return boost::none;
}
}
boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const
{
@ -5073,20 +4951,6 @@ boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator
return libzcash::SpendingKey();
}
SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const {
auto addr = sk.address();
if (log){
LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr));
}
if (m_wallet->HaveSproutSpendingKey(addr)) {
return KeyAlreadyExists;
} else if (m_wallet-> AddSproutZKey(sk)) {
m_wallet->mapSproutZKeyMetadata[addr].nCreateTime = nTime;
return KeyAdded;
} else {
return KeyNotAdded;
}
}
SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingExtendedSpendingKey &sk) const {
auto fvk = sk.expsk.full_viewing_key();

76
src/wallet/walletdb.cpp

@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2019 The Hush 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.
@ -124,26 +124,6 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey,
return true;
}
bool CWalletDB::WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr,
const libzcash::ReceivingKey &rk,
const std::vector<unsigned char>& vchCryptedSecret,
const CKeyMetadata &keyMeta)
{
const bool fEraseUnencryptedKey = true;
nWalletDBUpdated++;
if (!Write(std::make_pair(std::string("zkeymeta"), addr), keyMeta))
return false;
if (!Write(std::make_pair(std::string("czkey"), addr), std::make_pair(rk, vchCryptedSecret), false))
return false;
if (fEraseUnencryptedKey)
{
Erase(std::make_pair(std::string("zkey"), addr));
}
return true;
}
bool CWalletDB::WriteCryptedSaplingZKey(
const libzcash::SaplingExtendedFullViewingKey &extfvk,
const std::vector<unsigned char>& vchCryptedSecret,
@ -172,16 +152,6 @@ bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
}
bool CWalletDB::WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta)
{
nWalletDBUpdated++;
if (!Write(std::make_pair(std::string("zkeymeta"), addr), keyMeta))
return false;
// pair is: tuple_key("zkey", paymentaddress) --> secretkey
return Write(std::make_pair(std::string("zkey"), addr), key, false);
}
bool CWalletDB::WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk,
const libzcash::SaplingExtendedSpendingKey &key,
const CKeyMetadata &keyMeta)
@ -203,18 +173,6 @@ bool CWalletDB::WriteSaplingPaymentAddress(
return Write(std::make_pair(std::string("sapzaddr"), addr), ivk, false);
}
bool CWalletDB::WriteSproutViewingKey(const libzcash::SproutViewingKey &vk)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("vkey"), vk), '1');
}
bool CWalletDB::EraseSproutViewingKey(const libzcash::SproutViewingKey &vk)
{
nWalletDBUpdated++;
return Erase(std::make_pair(std::string("vkey"), vk));
}
bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript)
{
nWalletDBUpdated++;
@ -552,6 +510,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
}
else if (strType == "vkey")
{
/*
libzcash::SproutViewingKey vk;
ssKey >> vk;
char fYes;
@ -559,24 +518,27 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
if (fYes == '1')
pwallet->LoadSproutViewingKey(vk);
// Viewing keys have no birthday information for now,
// so set the wallet birthday to the beginning of time.
Viewing keys have no birthday information for now,
so set the wallet birthday to the beginning of time.
pwallet->nTimeFirstKey = 1;
*/
}
else if (strType == "zkey")
{
/*
libzcash::SproutPaymentAddress addr;
ssKey >> addr;
libzcash::SproutSpendingKey key;
ssValue >> key;
if (!pwallet->LoadZKey(key))
{
strErr = "Error reading wallet database: LoadZKey failed";
return false;
}
//if (!pwallet->LoadZKey(key))
//{
// strErr = "Error reading wallet database: LoadZKey failed";
// return false;
//}
wss.nZKeys++;
*/
}
else if (strType == "sapzkey")
{
@ -701,12 +663,12 @@ 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")
{
@ -748,7 +710,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
ssValue >> keyMeta;
wss.nZKeyMeta++;
pwallet->LoadZKeyMetadata(addr, keyMeta);
// pwallet->LoadZKeyMetadata(addr, keyMeta);
// ignore earliest key creation time as taddr will exist before any zaddr
}

Loading…
Cancel
Save