diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 671e96ea..0a69e1f4 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -686,75 +686,25 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { bool AsyncRPCOperation_sendmany::find_unspent_notes() { - - LOCK2(cs_main, pwalletMain->cs_wallet); - - for (auto & p : pwalletMain->mapWallet) { - CWalletTx wtx = p.second; - - // Filter the transactions before checking for notes - if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < mindepth_) { - continue; - } - - mapNoteData_t mapNoteData = pwalletMain->FindMyNotes(wtx); - - if (mapNoteData.size() == 0) { - continue; - } - - for (auto & pair : mapNoteData) { - JSOutPoint jsop = pair.first; - CNoteData nd = pair.second; - PaymentAddress pa = nd.address; - - // skip notes which belong to a different payment address in the wallet - if (!(pa == frompaymentaddress_)) { - continue; - } - - // skip note which has been spent - if (pwalletMain->IsSpent(nd.nullifier)) { - continue; - } - - int i = jsop.js; // Index into CTransaction.vjoinsplit - int j = jsop.n; // Index into JSDescription.ciphertexts - - // Get cached decryptor - ZCNoteDecryption decryptor; - if (!pwalletMain->GetNoteDecryptor(pa, decryptor)) { - // Note decryptors are created when the wallet is loaded, so it should always exist - throw JSONRPCError(RPC_WALLET_ERROR, "Could not find note decryptor"); - } - - // determine amount of funds in the note - auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey); - try { - NotePlaintext plaintext = NotePlaintext::decrypt( - decryptor, - wtx.vjoinsplit[i].ciphertexts[j], - wtx.vjoinsplit[i].ephemeralKey, - hSig, - (unsigned char) j); - - z_inputs_.push_back(SendManyInputJSOP(jsop, plaintext.note(pa), CAmount(plaintext.value))); - - std::string data(plaintext.memo.begin(), plaintext.memo.end()); - LogPrint("asyncrpc", "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n", - getId().substr(0,10), - wtx.GetTxid().ToString().substr(0,10), - i, j, - FormatMoney(plaintext.value, false), - HexStr(data).substr(0,10) - ); - - } catch (const std::exception &) { - // Couldn't decrypt with this spending key - } - } + std::vector entries; + { + LOCK2(cs_main, pwalletMain->cs_wallet); + pwalletMain->GetUnspentNotes(entries, fromaddress_, mindepth_); } + for (CNotePlaintextEntry & entry : entries) { + z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(frompaymentaddress_), CAmount(entry.plaintext.value))); + std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end()); + LogPrint("asyncrpc", "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n", + getId().substr(0, 10), + entry.jsop.hash.ToString().substr(0, 10), + entry.jsop.js, + int(entry.jsop.n), // uint8_t + FormatMoney(entry.plaintext.value, false), + HexStr(data).substr(0, 10) + ); + } + if (z_inputs_.size() == 0) { return false; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 66a2f2a3..3ff206b4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2874,76 +2874,14 @@ CAmount getBalanceTaddr(std::string transparentAddress, size_t minDepth=1) { return balance; } -CAmount getBalanceZaddr(std::string address, size_t minDepth=1) -{ +CAmount getBalanceZaddr(std::string address, size_t minDepth = 1) { CAmount balance = 0; - bool fFilterAddress = false; - PaymentAddress filterPaymentAddress; - if (address.length()>0) { - filterPaymentAddress = CZCPaymentAddress(address).Get(); - fFilterAddress = true; - } - + std::vector entries; LOCK2(cs_main, pwalletMain->cs_wallet); - - for (auto & p : pwalletMain->mapWallet) { - CWalletTx wtx = p.second; - - // Filter the transactions before checking for notes - if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < minDepth) { - continue; - } - - mapNoteData_t mapNoteData = pwalletMain->FindMyNotes(wtx); - - if (mapNoteData.size() == 0) { - continue; - } - - for (auto & pair : mapNoteData) { - JSOutPoint jsop = pair.first; - CNoteData nd = pair.second; - PaymentAddress pa = nd.address; - - // skip notes which belong to a different payment address in the wallet - if (fFilterAddress && !(pa == filterPaymentAddress)) { - continue; - } - - // skip note which has been spent - if (pwalletMain->IsSpent(nd.nullifier)) { - continue; - } - - int i = jsop.js; // Index into CTransaction.vjoinsplit - int j = jsop.n; // Index into JSDescription.ciphertexts - - // Get cached decryptor - ZCNoteDecryption decryptor; - if (!pwalletMain->GetNoteDecryptor(pa, decryptor)) { - // Note decryptors are created when the wallet is loaded, so it should always exist - throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", CZCPaymentAddress(pa).ToString())); - } - - // determine amount of funds in the note - auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey); - try { - NotePlaintext plaintext = NotePlaintext::decrypt( - decryptor, - wtx.vjoinsplit[i].ciphertexts[j], - wtx.vjoinsplit[i].ephemeralKey, - hSig, - (unsigned char) j); - - balance += CAmount(plaintext.value); - - } catch (const std::exception &) { - // Couldn't decrypt with this spending key - throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", CZCPaymentAddress(pa).ToString())); - } - } + pwalletMain->GetUnspentNotes(entries, address, minDepth); + for (auto & entry : entries) { + balance += CAmount(entry.plaintext.value); } - return balance; }