zcashd/src/wallet/asyncrpcoperation_mergetoad...

214 lines
6.8 KiB
C++
Raw Normal View History

// Copyright (c) 2017-2023 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "asyncrpcoperation_mergetoaddress.h"
#include "amount.h"
#include "asyncrpcoperation_common.h"
#include "asyncrpcqueue.h"
#include "core_io.h"
2020-01-27 06:59:24 -08:00
#include "experimental_features.h"
#include "init.h"
#include "key_io.h"
#include "main.h"
#include "miner.h"
#include "net.h"
#include "netbase.h"
#include "proof_verifier.h"
2016-01-14 16:55:17 -08:00
#include "rpc/protocol.h"
#include "rpc/server.h"
#include "script/interpreter.h"
#include "timedata.h"
#include "uint256.h"
scripted-diff: Move util files to separate directory. -BEGIN VERIFY SCRIPT- mkdir -p src/util git mv src/util.h src/util/system.h git mv src/util.cpp src/util/system.cpp git mv src/utilmoneystr.h src/util/moneystr.h git mv src/utilmoneystr.cpp src/util/moneystr.cpp git mv src/utilstrencodings.h src/util/strencodings.h git mv src/utilstrencodings.cpp src/util/strencodings.cpp git mv src/utiltime.h src/util/time.h git mv src/utiltime.cpp src/util/time.cpp sed -i -e 's/"util\.h"/"util\/system\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') git checkout HEAD -- src/secp256k1 # exclude secp256k1, which has its own "util.h" sed -i -e 's/"utilmoneystr\.h"/"util\/moneystr\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/"utilstrencodings\.h"/"util\/strencodings\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/<utilstrencodings\.h>/<util\/strencodings\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/"utiltime\.h"/"util\/time\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/BITCOIN_UTIL_H/BITCOIN_UTIL_SYSTEM_H/g' src/util/system.h sed -i -e 's/BITCOIN_UTILMONEYSTR_H/BITCOIN_UTIL_MONEYSTR_H/g' src/util/moneystr.h sed -i -e 's/BITCOIN_UTILSTRENCODINGS_H/BITCOIN_UTIL_STRENCODINGS_H/g' src/util/strencodings.h sed -i -e 's/BITCOIN_UTILTIME_H/BITCOIN_UTIL_TIME_H/g' src/util/time.h sed -i -e 's/ util\.\(h\|cpp\)/ util\/system\.\1/g' src/Makefile.am sed -i -e 's/utilmoneystr\.\(h\|cpp\)/util\/moneystr\.\1/g' src/Makefile.am sed -i -e 's/utilstrencodings\.\(h\|cpp\)/util\/strencodings\.\1/g' src/Makefile.am sed -i -e 's/utiltime\.\(h\|cpp\)/util\/time\.\1/g' src/Makefile.am sed -i -e 's/src\/util\.cpp/src\/util\/system\.cpp/g' test/lint/lint-locale-dependence.sh sed -i -e 's/src\/utilmoneystr\.cpp/src\/util\/moneystr\.cpp/g' test/lint/lint-locale-dependence.sh sed -i -e 's/src\/utilstrencodings\.\(h\|cpp\)/src\/util\/strencodings\.\1/g' test/lint/lint-locale-dependence.sh -END VERIFY SCRIPT-
2018-10-22 15:51:11 -07:00
#include "util/system.h"
#include "util/match.h"
scripted-diff: Move util files to separate directory. -BEGIN VERIFY SCRIPT- mkdir -p src/util git mv src/util.h src/util/system.h git mv src/util.cpp src/util/system.cpp git mv src/utilmoneystr.h src/util/moneystr.h git mv src/utilmoneystr.cpp src/util/moneystr.cpp git mv src/utilstrencodings.h src/util/strencodings.h git mv src/utilstrencodings.cpp src/util/strencodings.cpp git mv src/utiltime.h src/util/time.h git mv src/utiltime.cpp src/util/time.cpp sed -i -e 's/"util\.h"/"util\/system\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') git checkout HEAD -- src/secp256k1 # exclude secp256k1, which has its own "util.h" sed -i -e 's/"utilmoneystr\.h"/"util\/moneystr\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/"utilstrencodings\.h"/"util\/strencodings\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/<utilstrencodings\.h>/<util\/strencodings\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/"utiltime\.h"/"util\/time\.h"/g' $(git ls-files 'src/*.h' 'src/*.cpp') sed -i -e 's/BITCOIN_UTIL_H/BITCOIN_UTIL_SYSTEM_H/g' src/util/system.h sed -i -e 's/BITCOIN_UTILMONEYSTR_H/BITCOIN_UTIL_MONEYSTR_H/g' src/util/moneystr.h sed -i -e 's/BITCOIN_UTILSTRENCODINGS_H/BITCOIN_UTIL_STRENCODINGS_H/g' src/util/strencodings.h sed -i -e 's/BITCOIN_UTILTIME_H/BITCOIN_UTIL_TIME_H/g' src/util/time.h sed -i -e 's/ util\.\(h\|cpp\)/ util\/system\.\1/g' src/Makefile.am sed -i -e 's/utilmoneystr\.\(h\|cpp\)/util\/moneystr\.\1/g' src/Makefile.am sed -i -e 's/utilstrencodings\.\(h\|cpp\)/util\/strencodings\.\1/g' src/Makefile.am sed -i -e 's/utiltime\.\(h\|cpp\)/util\/time\.\1/g' src/Makefile.am sed -i -e 's/src\/util\.cpp/src\/util\/system\.cpp/g' test/lint/lint-locale-dependence.sh sed -i -e 's/src\/utilmoneystr\.cpp/src\/util\/moneystr\.cpp/g' test/lint/lint-locale-dependence.sh sed -i -e 's/src\/utilstrencodings\.\(h\|cpp\)/src\/util\/strencodings\.\1/g' test/lint/lint-locale-dependence.sh -END VERIFY SCRIPT-
2018-10-22 15:51:11 -07:00
#include "util/moneystr.h"
#include "util/time.h"
#include "wallet.h"
#include "walletdb.h"
#include "zcash/IncrementalMerkleTree.hpp"
#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <variant>
#include <rust/ed25519.h>
using namespace libzcash;
AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
CWallet& wallet,
TransactionStrategy strategy,
TransactionEffects effects,
UniValue contextInfo)
: strategy_(strategy), effects_(effects), contextinfo_(contextInfo)
{
effects.LockSpendable(*pwalletMain);
KeyIO keyIO(Params());
// Log the context info i.e. the call parameters to z_mergetoaddress
if (LogAcceptCategory("zrpcunsafe")) {
LogPrint("zrpcunsafe", "%s: z_mergetoaddress initialized (params=%s)\n", getId(), contextInfo.write());
} else {
LogPrint("zrpc", "%s: z_mergetoaddress initialized\n", getId());
}
}
AsyncRPCOperation_mergetoaddress::~AsyncRPCOperation_mergetoaddress()
{
}
std::pair<uint256, UniValue>
main_impl(
const CChainParams& chainparams,
CWallet& wallet,
const TransactionStrategy& strategy,
const TransactionEffects& effects,
const std::string& id,
bool testmode);
void AsyncRPCOperation_mergetoaddress::main()
{
set_state(OperationStatus::EXECUTING);
start_execution_clock();
bool success = false;
#ifdef ENABLE_MINING
2015-04-10 03:49:01 -07:00
GenerateBitcoins(false, 0, Params());
#endif
std::optional<uint256> txid;
try {
UniValue sendResult;
std::tie(txid, sendResult) =
main_impl(Params(), *pwalletMain, strategy_, effects_, getId(), testmode);
set_result(sendResult);
} catch (const UniValue& objError) {
int code = find_value(objError, "code").get_int();
std::string message = find_value(objError, "message").get_str();
set_error_code(code);
set_error_message(message);
} catch (const runtime_error& e) {
set_error_code(-1);
set_error_message("runtime error: " + string(e.what()));
} catch (const logic_error& e) {
set_error_code(-1);
set_error_message("logic error: " + string(e.what()));
} catch (const exception& e) {
set_error_code(-1);
set_error_message("general exception: " + string(e.what()));
} catch (...) {
set_error_code(-2);
set_error_message("unknown error");
}
#ifdef ENABLE_MINING
2015-04-10 03:49:01 -07:00
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params());
#endif
stop_execution_clock();
if (txid.has_value()) {
set_state(OperationStatus::SUCCESS);
} else {
set_state(OperationStatus::FAILED);
}
std::string s = strprintf("%s: z_mergetoaddress finished (status=%s", getId(), getStateAsString());
if (txid.has_value()) {
s += strprintf(", txid=%s)\n", txid.value().GetHex());
} else {
s += strprintf(", error=%s)\n", getErrorMessage());
}
LogPrintf("%s", s);
}
std::pair<uint256, UniValue>
main_impl(
const CChainParams& chainparams,
CWallet& wallet,
const TransactionStrategy& strategy,
const TransactionEffects& effects,
const std::string& id,
bool testmode)
{
try {
const auto& spendable = effects.GetSpendable();
const auto& payments = effects.GetPayments();
spendable.LogInputs(id);
bool sendsToShielded = false;
for (const auto& resolvedPayment : payments.GetResolvedPayments()) {
sendsToShielded = sendsToShielded || examine(resolvedPayment.address, match {
[](const CKeyID&) { return true; },
[](const CScriptID&) { return true; },
[](const libzcash::SaplingPaymentAddress&) { return false; },
[](const libzcash::OrchardRawAddress&) { return false; },
});
}
if (spendable.sproutNoteEntries.empty()
&& spendable.saplingNoteEntries.empty()
&& spendable.orchardNoteMetadata.empty()
&& !sendsToShielded) {
LogPrint("zrpc", "%s: spending %s to send %s with fee %s\n",
id,
FormatMoney(payments.Total()),
FormatMoney(spendable.Total()),
FormatMoney(effects.GetFee()));
} else {
LogPrint("zrpcunsafe", "%s: spending %s to send %s with fee %s\n",
id,
FormatMoney(payments.Total()),
FormatMoney(spendable.Total()),
FormatMoney(effects.GetFee()));
}
LogPrint("zrpc", "%s: total transparent input: %s\n", id,
FormatMoney(spendable.GetTransparentTotal()));
LogPrint("zrpcunsafe", "%s: total shielded input: %s\n", id,
FormatMoney(spendable.GetSaplingTotal() + spendable.GetOrchardTotal()));
LogPrint("zrpc", "%s: total transparent output: %s\n", id,
FormatMoney(payments.GetTransparentTotal()));
LogPrint("zrpcunsafe", "%s: total shielded Sapling output: %s\n", id,
FormatMoney(payments.GetSaplingTotal()));
LogPrint("zrpcunsafe", "%s: total shielded Orchard output: %s\n", id,
FormatMoney(payments.GetOrchardTotal()));
LogPrint("zrpc", "%s: fee: %s\n", id, FormatMoney(effects.GetFee()));
auto buildResult = effects.ApproveAndBuild(
chainparams.GetConsensus(),
wallet,
chainActive,
strategy);
auto tx = buildResult.GetTxOrThrow();
UniValue sendResult = SendTransaction(tx, payments.GetResolvedPayments(), std::nullopt, testmode);
effects.UnlockSpendable(wallet);
return {tx.GetHash(), sendResult};
} catch (...) {
effects.UnlockSpendable(wallet);
throw;
}
}
/**
* Override getStatus() to append the operation's input parameters to the default status object.
*/
UniValue AsyncRPCOperation_mergetoaddress::getStatus() const
{
UniValue v = AsyncRPCOperation::getStatus();
if (contextinfo_.isNull()) {
return v;
}
UniValue obj = v.get_obj();
obj.pushKV("method", "z_mergetoaddress");
obj.pushKV("params", contextinfo_);
return obj;
}