Merge pull request #28 from ch4ot1c/improvement/build-without-disablewallet
Improvement: Build without -disablewallet
This commit is contained in:
commit
18227b4fea
|
@ -242,7 +242,7 @@ cov: test_bitcoin.coverage/.dirstamp cov-zcash total.coverage/.dirstamp
|
|||
|
||||
endif
|
||||
|
||||
dist_bin_SCRIPTS = #zcutil/fetch-params.sh
|
||||
dist_bin_SCRIPTS = scripts/fetch-zcash-params.sh
|
||||
dist_noinst_SCRIPTS = autogen.sh
|
||||
|
||||
EXTRA_DIST = $(DIST_SHARE) test/functional/test_runner.py test/functional test/zcash $(DIST_CONTRIB) $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS)
|
||||
|
@ -302,8 +302,6 @@ EXTRA_DIST += \
|
|||
test/util/rpcauth-test.py
|
||||
|
||||
CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER)
|
||||
install-exec-hook:
|
||||
mv $(DESTDIR)$(bindir)/fetch-params.sh $(DESTDIR)$(bindir)/zcash-fetch-params
|
||||
|
||||
.INTERMEDIATE: $(COVERAGE_INFO)
|
||||
|
||||
|
|
|
@ -1161,7 +1161,7 @@ AX_CHECK_COMPILE_FLAG([-fwrapv],[CXXFLAGS="$CXXFLAGS -fwrapv"])
|
|||
AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"])
|
||||
AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]])
|
||||
|
||||
LIBZCASH_LIBS="-lgmp -lgmpxx $BOOST_SYSTEM_LIB -lcrypto -lsodium $RUST_LIBS"
|
||||
LIBZCASH_LIBS="-lgomp -lgmp -lgmpxx $BOOST_SYSTEM_LIB -lcrypto -lsodium $RUST_LIBS"
|
||||
|
||||
BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
|
||||
|
||||
|
|
|
@ -103,5 +103,5 @@ ld -v
|
|||
|
||||
HOST="$HOST" BUILD="$BUILD" "$MAKE" "$@" -C ./depends/ V=1
|
||||
./autogen.sh
|
||||
CC="$CC" CXX="$CXX" ./configure --disable-wallet --prefix="${PREFIX}" --host="$HOST" --build="$BUILD" "$HARDENING_ARG" "$LCOV_ARG" "$TEST_ARG" "$MINING_ARG" $CONFIGURE_FLAGS --enable-werror CXXFLAGS='-g'
|
||||
CC="$CC" CXX="$CXX" ./configure --prefix="${PREFIX}" --host="$HOST" --build="$BUILD" "$HARDENING_ARG" "$LCOV_ARG" "$TEST_ARG" "$MINING_ARG" $CONFIGURE_FLAGS --enable-werror CXXFLAGS='-g'
|
||||
"$MAKE" "$@" V=1
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
PARAMS_DIR="$HOME/Library/Application Support/ZcashParams"
|
||||
else
|
||||
PARAMS_DIR="$HOME/.zcash-params"
|
||||
fi
|
||||
|
||||
SPROUT_PKEY_NAME='sprout-proving.key'
|
||||
SPROUT_VKEY_NAME='sprout-verifying.key'
|
||||
SPROUT_URL="https://z.cash/downloads"
|
||||
SPROUT_IPFS="/ipfs/QmZKKx7Xup7LiAtFRhYsE1M7waXcv9ir9eCECyXAFGxhEo"
|
||||
|
||||
SHA256CMD="$(command -v sha256sum || echo shasum)"
|
||||
SHA256ARGS="$(command -v sha256sum >/dev/null || echo '-a 256')"
|
||||
|
||||
WGETCMD="$(command -v wget || echo '')"
|
||||
IPFSCMD="$(command -v ipfs || echo '')"
|
||||
CURLCMD="$(command -v curl || echo '')"
|
||||
|
||||
# fetch methods can be disabled with ZC_DISABLE_SOMETHING=1
|
||||
ZC_DISABLE_WGET="${ZC_DISABLE_WGET:-}"
|
||||
ZC_DISABLE_IPFS="${ZC_DISABLE_IPFS:-}"
|
||||
ZC_DISABLE_CURL="${ZC_DISABLE_CURL:-}"
|
||||
|
||||
function fetch_wget {
|
||||
if [ -z "$WGETCMD" ] || ! [ -z "$ZC_DISABLE_WGET" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local filename="$1"
|
||||
local dlname="$2"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Retrieving (wget): $SPROUT_URL/$filename
|
||||
EOF
|
||||
|
||||
wget \
|
||||
--progress=dot:giga \
|
||||
--output-document="$dlname" \
|
||||
--continue \
|
||||
--retry-connrefused --waitretry=3 --timeout=30 \
|
||||
"$SPROUT_URL/$filename"
|
||||
}
|
||||
|
||||
function fetch_ipfs {
|
||||
if [ -z "$IPFSCMD" ] || ! [ -z "$ZC_DISABLE_IPFS" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local filename="$1"
|
||||
local dlname="$2"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Retrieving (ipfs): $SPROUT_IPFS/$filename
|
||||
EOF
|
||||
|
||||
ipfs get --output "$dlname" "$SPROUT_IPFS/$filename"
|
||||
}
|
||||
|
||||
function fetch_curl {
|
||||
if [ -z "$CURLCMD" ] || ! [ -z "$ZC_DISABLE_CURL" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local filename="$1"
|
||||
local dlname="$2"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Retrieving (curl): $SPROUT_URL/$filename
|
||||
EOF
|
||||
|
||||
curl \
|
||||
--output "$dlname" \
|
||||
-# -L -C - \
|
||||
"$SPROUT_URL/$filename"
|
||||
|
||||
}
|
||||
|
||||
function fetch_failure {
|
||||
cat >&2 <<EOF
|
||||
|
||||
Failed to fetch the Zcash/BTCP zkSNARK parameters!
|
||||
Try installing one of the following programs and make sure you're online:
|
||||
|
||||
* ipfs
|
||||
* wget
|
||||
* curl
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
function fetch_params {
|
||||
local filename="$1"
|
||||
local output="$2"
|
||||
local dlname="${output}.dl"
|
||||
local expectedhash="$3"
|
||||
|
||||
if ! [ -f "$output" ]
|
||||
then
|
||||
for method in wget ipfs curl failure; do
|
||||
if "fetch_$method" "$filename" "$dlname"; then
|
||||
echo "Download successful!"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
"$SHA256CMD" $SHA256ARGS -c <<EOF
|
||||
$expectedhash $dlname
|
||||
EOF
|
||||
|
||||
# Check the exit code of the shasum command:
|
||||
CHECKSUM_RESULT=$?
|
||||
if [ $CHECKSUM_RESULT -eq 0 ]; then
|
||||
mv -v "$dlname" "$output"
|
||||
else
|
||||
echo "Failed to verify parameter checksums!" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Use flock to prevent parallel execution.
|
||||
function lock() {
|
||||
local lockfile=/tmp/fetch_params.lock
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
if shlock -f ${lockfile} -p $$; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
# create lock file
|
||||
eval "exec 200>/$lockfile"
|
||||
# acquire the lock
|
||||
flock -n 200 \
|
||||
&& return 0 \
|
||||
|| return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function exit_locked_error {
|
||||
echo "Only one instance of fetch-zcash-params.sh can be run at a time." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
||||
lock fetch-zcash-params.sh \
|
||||
|| exit_locked_error
|
||||
|
||||
cat <<EOF
|
||||
Bitcoin Private - fetch-zcash-params.sh
|
||||
Copyright (c) 2016-2018 The Zcash developers
|
||||
|
||||
This script will fetch the zkSNARK parameters from the Zcash ceremony
|
||||
and verify their integrity with sha256sum. Bitcoin Private uses these
|
||||
parameters the same way as in Zcash: to enable Zero-Knowledge proofs
|
||||
that allow for shielded transactions to be constructed.
|
||||
|
||||
NOTE: If you're using testnet or regtest, you will need to invoke this
|
||||
script with --testnet in order to download additional parameters. This
|
||||
is temporary.
|
||||
|
||||
If they already exist locally, it will exit now and do nothing else.
|
||||
EOF
|
||||
|
||||
# Now create PARAMS_DIR and insert a README if necessary:
|
||||
if ! [ -d "$PARAMS_DIR" ]
|
||||
then
|
||||
mkdir -p "$PARAMS_DIR"
|
||||
README_PATH="$PARAMS_DIR/README"
|
||||
cat >> "$README_PATH" <<EOF
|
||||
This directory stores Zcash/BTCP zkSNARK parameters. Note that it is
|
||||
distinct from the daemon's -datadir argument because the parameters are
|
||||
large and may be shared across multiple distinct -datadir's such as when
|
||||
setting up test networks.
|
||||
EOF
|
||||
|
||||
# This may be the first time the user's run this script, so give
|
||||
# them some info, especially about bandwidth usage:
|
||||
cat <<EOF
|
||||
The parameters are currently just under 911MB in size, so plan accordingly
|
||||
for your bandwidth constraints. If the files are already present and
|
||||
have the correct sha256sum, no networking is used.
|
||||
|
||||
Creating params directory. For details about this directory, see:
|
||||
$README_PATH
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
cd "$PARAMS_DIR"
|
||||
|
||||
fetch_params "$SPROUT_PKEY_NAME" "$PARAMS_DIR/$SPROUT_PKEY_NAME" "8bc20a7f013b2b58970cddd2e7ea028975c88ae7ceb9259a5344a16bc2c0eef7"
|
||||
fetch_params "$SPROUT_VKEY_NAME" "$PARAMS_DIR/$SPROUT_VKEY_NAME" "4bd498dae0aacfd8e98dc306338d017d9c08dd0918ead18172bd0aec2fc5df82"
|
||||
|
||||
if [ "x${1:-}" = 'x--testnet' ]
|
||||
then
|
||||
echo "(NOTE) Testnet parameters enabled."
|
||||
fetch_params "$SPROUT_PKEY_NAME" "$PARAMS_DIR/$SPROUT_PKEY_NAME" "8bc20a7f013b2b58970cddd2e7ea028975c88ae7ceb9259a5344a16bc2c0eef7"
|
||||
fetch_params "$SPROUT_VKEY_NAME" "$PARAMS_DIR/$SPROUT_VKEY_NAME" "4bd498dae0aacfd8e98dc306338d017d9c08dd0918ead18172bd0aec2fc5df82"
|
||||
fi
|
||||
}
|
||||
|
||||
main ${1:-}
|
||||
rm -f /tmp/fetch_params.lock
|
||||
exit 0
|
||||
|
|
@ -201,9 +201,6 @@ BITCOIN_CORE_H = \
|
|||
validationinterface.h \
|
||||
versionbits.h \
|
||||
walletinitinterface.h \
|
||||
wallet/asyncrpcoperation_mergetoaddress.h \
|
||||
wallet/asyncrpcoperation_sendmany.h \
|
||||
wallet/asyncrpcoperation_shieldcoinbase.h \
|
||||
wallet/coincontrol.h \
|
||||
wallet/crypter.h \
|
||||
wallet/db.h \
|
||||
|
@ -293,9 +290,6 @@ libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
|||
libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_wallet_a_SOURCES = \
|
||||
interfaces/wallet.cpp \
|
||||
wallet/asyncrpcoperation_mergetoaddress.cpp \
|
||||
wallet/asyncrpcoperation_sendmany.cpp \
|
||||
wallet/asyncrpcoperation_shieldcoinbase.cpp \
|
||||
wallet/crypter.cpp \
|
||||
wallet/db.cpp \
|
||||
wallet/feebumper.cpp \
|
||||
|
@ -303,7 +297,6 @@ libbitcoin_wallet_a_SOURCES = \
|
|||
wallet/init.cpp \
|
||||
paymentdisclosure.cpp \
|
||||
paymentdisclosuredb.cpp \
|
||||
wallet/rpcdisclosure.cpp \
|
||||
wallet/rpcdump.cpp \
|
||||
wallet/rpcwallet.cpp \
|
||||
wallet/wallet.cpp \
|
||||
|
|
|
@ -355,19 +355,19 @@ public:
|
|||
|
||||
nPruneAfterHeight = 1000;
|
||||
|
||||
nEquihashN = 48;
|
||||
nEquihashK = 5;
|
||||
nEquihashN = 200;
|
||||
nEquihashK = 9;
|
||||
|
||||
uint256 nNonce = uint256S("0000000000000000000000000000000000000000000000000000000000000009");
|
||||
genesis = CreateGenesisBlock(1482971059, nNonce, 0x200f0f0f, 4, 0, GenesisSolutions::REGTEST);
|
||||
consensus.hashGenesisBlock = genesis.GetHash();
|
||||
assert(consensus.hashGenesisBlock == uint256S("0x0575f78ee8dc057deee78ef691876e3be29833aaee5e189bb0459c087451305a"));
|
||||
|
||||
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
|
||||
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
|
||||
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
|
||||
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
|
||||
base58Prefixes[PUBKEY_ADDRESS] = {0x19,0x57};
|
||||
base58Prefixes[SCRIPT_ADDRESS] = {0x19,0xE0};
|
||||
base58Prefixes[SECRET_KEY] = {0xEF};
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
|
||||
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
|
||||
base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xC0};
|
||||
base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08};
|
||||
bech32_hrp = "regbtcp";
|
||||
|
|
|
@ -32,7 +32,7 @@ bool CheckTransactionJoinsplits(const CTransaction& tx, CValidationState &state)
|
|||
// Ensure that zk-SNARKs verify
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
for(const JSDescription &joinsplit : tx.vjoinsplit) {
|
||||
if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
|
||||
if (!joinsplit.Verify(pzcashParams.get(), verifier, tx.joinSplitPubKey)) {
|
||||
return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
|
||||
REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
|
||||
}
|
||||
|
|
42
src/init.cpp
42
src/init.cpp
|
@ -60,6 +60,8 @@
|
|||
#include <boost/thread.hpp>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include <libsnark/common/profiling.hpp>
|
||||
|
||||
#if ENABLE_ZMQ
|
||||
#include <zmq/zmqnotificationinterface.h>
|
||||
#endif
|
||||
|
@ -72,6 +74,8 @@ static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
|
|||
std::unique_ptr<CConnman> g_connman;
|
||||
std::unique_ptr<PeerLogicValidation> peerLogic;
|
||||
|
||||
std::unique_ptr<ZCJoinSplit> pzcashParams;
|
||||
|
||||
#if !(ENABLE_WALLET)
|
||||
class DummyWalletInit : public WalletInitInterface {
|
||||
public:
|
||||
|
@ -289,6 +293,7 @@ void Shutdown()
|
|||
GetMainSignals().UnregisterWithMempoolSignals(mempool);
|
||||
g_wallet_init_interface.Close();
|
||||
globalVerifyHandle.reset();
|
||||
|
||||
ECC_Stop();
|
||||
LogPrintf("%s: done\n", __func__);
|
||||
}
|
||||
|
@ -698,6 +703,35 @@ static void ThreadImport(std::vector<fs::path> vImportFiles)
|
|||
g_is_mempool_loaded = !fRequestShutdown;
|
||||
}
|
||||
|
||||
static void ZC_LoadParams()
|
||||
{
|
||||
struct timeval tv_start, tv_end;
|
||||
float elapsed;
|
||||
|
||||
boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key";
|
||||
boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key";
|
||||
|
||||
if (!(boost::filesystem::exists(pk_path) && boost::filesystem::exists(vk_path))) {
|
||||
uiInterface.ThreadSafeMessageBox(strprintf(
|
||||
_("Cannot find the Zcash ceremony parameters for BTCP in the following directory:\n"
|
||||
"%s\n"
|
||||
"Please run 'scripts/fetch-zcash-params.sh' and then restart."),
|
||||
ZC_GetParamsDir()),
|
||||
"", CClientUIInterface::MSG_ERROR);
|
||||
StartShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
LogPrintf("Loading verifying key from %s\n", vk_path.string().c_str());
|
||||
gettimeofday(&tv_start, 0);
|
||||
|
||||
pzcashParams = std::unique_ptr<ZCJoinSplit>(ZCJoinSplit::Prepared(vk_path.string(), pk_path.string()));
|
||||
|
||||
gettimeofday(&tv_end, 0);
|
||||
elapsed = float(tv_end.tv_sec-tv_start.tv_sec) + (tv_end.tv_usec-tv_start.tv_usec)/float(1000000);
|
||||
LogPrintf("Loaded verifying key in %fs seconds.\n", elapsed);
|
||||
}
|
||||
|
||||
/** Sanity checks
|
||||
* Ensure that Bitcoin is running in a usable environment with all
|
||||
* necessary library support.
|
||||
|
@ -1267,6 +1301,14 @@ bool AppInitMain()
|
|||
threadGroup.create_thread(&ThreadScriptCheck);
|
||||
}
|
||||
|
||||
// These must be disabled for now, they are buggy and we probably don't
|
||||
// want any of libsnark's profiling in production anyway.
|
||||
libsnark::inhibit_profiling_info = true;
|
||||
libsnark::inhibit_profiling_counters = true;
|
||||
|
||||
// Initialize Zcash circuit parameters
|
||||
ZC_LoadParams();
|
||||
|
||||
// Start the lightweight task scheduler thread
|
||||
CScheduler::Function serviceLoop = boost::bind(&CScheduler::serviceQueue, &scheduler);
|
||||
threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <string>
|
||||
#include <util.h>
|
||||
|
||||
#include <zcash/JoinSplit.hpp>
|
||||
|
||||
class CScheduler;
|
||||
class CWallet;
|
||||
|
||||
|
@ -21,6 +23,8 @@ namespace boost
|
|||
class thread_group;
|
||||
} // namespace boost
|
||||
|
||||
extern std::unique_ptr<ZCJoinSplit> pzcashParams;
|
||||
|
||||
void StartShutdown();
|
||||
bool ShutdownRequested();
|
||||
/** Interrupt threads */
|
||||
|
|
|
@ -121,6 +121,8 @@ const CLogCategoryDesc LogCategories[] =
|
|||
{BCLog::LEVELDB, "leveldb"},
|
||||
{BCLog::EQUIHASH, "equihash"},
|
||||
{BCLog::PAYMENTDISCLOSURE, "paymentdisclosure"},
|
||||
{BCLog::ZRPC, "zrpc"},
|
||||
{BCLog::ZRPCUNSAFE, "zrpcunsafe"},
|
||||
{BCLog::ALL, "1"},
|
||||
{BCLog::ALL, "all"},
|
||||
};
|
||||
|
|
|
@ -55,6 +55,8 @@ namespace BCLog {
|
|||
LEVELDB = (1 << 20),
|
||||
EQUIHASH = (1 << 21),
|
||||
PAYMENTDISCLOSURE = (1 << 22),
|
||||
ZRPC = (1 << 23),
|
||||
ZRPCUNSAFE = (1 << 24),
|
||||
ALL = ~(uint32_t)0,
|
||||
};
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ struct PaymentDisclosurePayload {
|
|||
uint8_t version; // 0 = experimental, 1 = first production version, etc.
|
||||
uint256 esk; // zcash/NoteEncryption.cpp
|
||||
uint256 txid; // primitives/transaction.h
|
||||
size_t js; // Index into CTransaction.vjoinsplit
|
||||
uint64_t js; // Index into CTransaction.vjoinsplit
|
||||
uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
|
||||
libzcash::PaymentAddress zaddr; // zcash/Address.hpp
|
||||
std::string message; // parameter to RPC call
|
||||
|
|
|
@ -48,8 +48,8 @@ JSDescription JSDescription::Randomized(
|
|||
const uint256& anchor,
|
||||
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
||||
std::array<size_t, ZC_NUM_JS_INPUTS>& inputMap,
|
||||
std::array<size_t, ZC_NUM_JS_OUTPUTS>& outputMap,
|
||||
std::array<uint64_t, ZC_NUM_JS_INPUTS>& inputMap,
|
||||
std::array<uint64_t, ZC_NUM_JS_OUTPUTS>& outputMap,
|
||||
CAmount vpub_old,
|
||||
CAmount vpub_new,
|
||||
bool computeProof,
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <zcash/JoinSplit.hpp>
|
||||
#include <zcash/Proof.hpp>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <array>
|
||||
|
||||
class JSDescription
|
||||
{
|
||||
|
@ -88,8 +88,8 @@ public:
|
|||
const uint256& rt,
|
||||
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
||||
std::array<size_t, ZC_NUM_JS_INPUTS>& inputMap,
|
||||
std::array<size_t, ZC_NUM_JS_OUTPUTS>& outputMap,
|
||||
std::array<uint64_t, ZC_NUM_JS_INPUTS>& inputMap,
|
||||
std::array<uint64_t, ZC_NUM_JS_OUTPUTS>& outputMap,
|
||||
CAmount vpub_old,
|
||||
CAmount vpub_new,
|
||||
bool computeProof = true, // Set to false in some tests
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
#include <miner.h>
|
||||
#include <net.h>
|
||||
#include <netbase.h>
|
||||
#include <paymentdisclosuredb.h>
|
||||
#include <rpc/protocol.h>
|
||||
#include <rpc/server.h>
|
||||
#include <rpc/rawtransaction.cpp>
|
||||
#include <script/interpreter.h>
|
||||
#include <sodium.h>
|
||||
#include <timedata.h>
|
||||
|
@ -23,14 +25,13 @@
|
|||
#include <wallet/wallet.h>
|
||||
#include <wallet/walletdb.h>
|
||||
#include <zcash/IncrementalMerkleTree.hpp>
|
||||
#include <key_io.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <wallet/paymentdisclosuredb.h>
|
||||
|
||||
using namespace libzcash;
|
||||
|
||||
int mta_find_output(UniValue obj, int n)
|
||||
|
@ -73,8 +74,8 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Recipient parameter missing");
|
||||
}
|
||||
|
||||
toTaddr_ = CBitcoinAddress(std::get<0>(recipient));
|
||||
isToTaddr_ = toTaddr_.IsValid();
|
||||
toTaddr_ = DecodeDestination(std::get<0>(recipient));
|
||||
isToTaddr_ = IsValidDestination(toTaddr_);
|
||||
isToZaddr_ = false;
|
||||
|
||||
if (!isToTaddr_) {
|
||||
|
@ -90,10 +91,10 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
|||
}
|
||||
|
||||
// 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());
|
||||
if (LogAcceptCategory(BCLog::ZRPCUNSAFE)) {
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: z_mergetoaddress initialized (params=%s)\n", getId(), contextInfo.write());
|
||||
} else {
|
||||
LogPrint("zrpc", "%s: z_mergetoaddress initialized\n", getId());
|
||||
LogPrint(BCLog::ZRPC, "%s: z_mergetoaddress initialized\n", getId());
|
||||
}
|
||||
|
||||
// Lock UTXOs
|
||||
|
@ -101,7 +102,7 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
|||
lock_notes();
|
||||
|
||||
// Enable payment disclosure if requested
|
||||
paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false);
|
||||
paymentDisclosureMode = fExperimentalMode && gArgs.GetBoolArg("-paymentdisclosure", false);
|
||||
}
|
||||
|
||||
AsyncRPCOperation_mergetoaddress::~AsyncRPCOperation_mergetoaddress()
|
||||
|
@ -121,14 +122,6 @@ void AsyncRPCOperation_mergetoaddress::main()
|
|||
|
||||
bool success = false;
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
#ifdef ENABLE_WALLET
|
||||
GenerateBitcoins(false, NULL, 0);
|
||||
#else
|
||||
GenerateBitcoins(false, 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
try {
|
||||
success = main_impl();
|
||||
} catch (const UniValue& objError) {
|
||||
|
@ -150,14 +143,6 @@ void AsyncRPCOperation_mergetoaddress::main()
|
|||
set_error_message("unknown error");
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
#ifdef ENABLE_WALLET
|
||||
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
|
||||
#else
|
||||
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
stop_execution_clock();
|
||||
|
||||
if (success) {
|
||||
|
@ -184,9 +169,9 @@ void AsyncRPCOperation_mergetoaddress::main()
|
|||
for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) {
|
||||
p.first.hash = txidhash;
|
||||
if (!db->Put(p.first, p.second)) {
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString());
|
||||
LogPrint(BCLog::PAYMENTDISCLOSURE, "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString());
|
||||
} else {
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString());
|
||||
LogPrint(BCLog::PAYMENTDISCLOSURE, "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +191,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
|||
size_t numInputs = utxoInputs_.size();
|
||||
|
||||
// Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
|
||||
size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0);
|
||||
size_t limit = (size_t)gArgs.GetArg("-mempooltxinputlimit", 0);
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
||||
|
@ -246,22 +231,22 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
|||
rawTx.vin.push_back(in);
|
||||
}
|
||||
if (isToTaddr_) {
|
||||
CScript scriptPubKey = GetScriptForDestination(toTaddr_.Get());
|
||||
CScript scriptPubKey = GetScriptForDestination(toTaddr_);
|
||||
CTxOut out(sendAmount, scriptPubKey);
|
||||
rawTx.vout.push_back(out);
|
||||
}
|
||||
tx_ = CTransaction(rawTx);
|
||||
|
||||
LogPrint(isPureTaddrOnlyTx ? "zrpc" : "zrpcunsafe", "%s: spending %s to send %s with fee %s\n",
|
||||
LogPrint(isPureTaddrOnlyTx ? BCLog::ZRPC : BCLog::ZRPCUNSAFE, "%s: spending %s to send %s with fee %s\n",
|
||||
getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee));
|
||||
LogPrint("zrpc", "%s: transparent input: %s\n", getId(), FormatMoney(t_inputs_total));
|
||||
LogPrint("zrpcunsafe", "%s: private input: %s\n", getId(), FormatMoney(z_inputs_total));
|
||||
LogPrint(BCLog::ZRPC, "%s: transparent input: %s\n", getId(), FormatMoney(t_inputs_total));
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: private input: %s\n", getId(), FormatMoney(z_inputs_total));
|
||||
if (isToTaddr_) {
|
||||
LogPrint("zrpc", "%s: transparent output: %s\n", getId(), FormatMoney(sendAmount));
|
||||
LogPrint(BCLog::ZRPC, "%s: transparent output: %s\n", getId(), FormatMoney(sendAmount));
|
||||
} else {
|
||||
LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(sendAmount));
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: private output: %s\n", getId(), FormatMoney(sendAmount));
|
||||
}
|
||||
LogPrint("zrpc", "%s: fee: %s\n", getId(), FormatMoney(minersFee));
|
||||
LogPrint(BCLog::ZRPC, "%s: fee: %s\n", getId(), FormatMoney(minersFee));
|
||||
|
||||
// Grab the current consensus branch ID
|
||||
{
|
||||
|
@ -453,7 +438,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
|||
|
||||
// Decrypt the change note's ciphertext to retrieve some data we need
|
||||
ZCNoteDecryption decryptor(changeKey.receiving_key());
|
||||
auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey);
|
||||
auto hSig = prevJoinSplit.h_sig(pzcashParams.get(), tx_.joinSplitPubKey);
|
||||
try {
|
||||
NotePlaintext plaintext = NotePlaintext::decrypt(
|
||||
decryptor,
|
||||
|
@ -468,7 +453,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
|||
|
||||
jsInputValue += plaintext.value;
|
||||
|
||||
LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n",
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: spending change (amount=%s)\n",
|
||||
getId(),
|
||||
FormatMoney(plaintext.value));
|
||||
|
||||
|
@ -521,7 +506,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
|||
wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight;
|
||||
wtxDepth = wtx.GetDepthInMainChain();
|
||||
}
|
||||
LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n",
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n",
|
||||
getId(),
|
||||
jso.hash.ToString().substr(0, 10),
|
||||
jso.js,
|
||||
|
@ -598,7 +583,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
|||
}
|
||||
info.vjsout.push_back(jso);
|
||||
|
||||
LogPrint("zrpcunsafe", "%s: generating note for %s (amount=%s)\n",
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: generating note for %s (amount=%s)\n",
|
||||
getId(),
|
||||
outputType,
|
||||
FormatMoney(jsChange));
|
||||
|
@ -635,7 +620,9 @@ void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj)
|
|||
|
||||
UniValue params = UniValue(UniValue::VARR);
|
||||
params.push_back(rawtxn);
|
||||
UniValue signResultValue = signrawtransaction(params, false);
|
||||
JSONRPCRequest jsonRequest;
|
||||
jsonRequest.params = params;
|
||||
UniValue signResultValue = signrawtransaction(jsonRequest);
|
||||
UniValue signResultObject = signResultValue.get_obj();
|
||||
UniValue completeValue = find_value(signResultObject, "complete");
|
||||
bool complete = completeValue.get_bool();
|
||||
|
@ -655,7 +642,9 @@ void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj)
|
|||
params.clear();
|
||||
params.setArray();
|
||||
params.push_back(signedtxn);
|
||||
UniValue sendResultValue = sendrawtransaction(params, false);
|
||||
JSONRPCRequest jsonRequest;
|
||||
jsonRequest.params = params;
|
||||
UniValue sendResultValue = sendrawtransaction(jsonRequest);
|
||||
if (sendResultValue.isNull()) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid.");
|
||||
}
|
||||
|
@ -749,7 +738,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
|
||||
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",
|
||||
LogPrint(BCLog::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),
|
||||
|
@ -759,13 +748,13 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
// 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;
|
||||
std::array<uint64_t, ZC_NUM_JS_INPUTS> inputMap;
|
||||
std::array<uint64_t, ZC_NUM_JS_OUTPUTS> outputMap;
|
||||
|
||||
uint256 esk; // payment disclosure - secret
|
||||
|
||||
JSDescription jsdesc = JSDescription::Randomized(
|
||||
*pzcashParams,
|
||||
pzcashParams.get(),
|
||||
joinSplitPubKey_,
|
||||
anchor,
|
||||
inputs,
|
||||
|
@ -778,7 +767,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
&esk); // parameter expects pointer to esk, so pass in address
|
||||
{
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) {
|
||||
if (!(jsdesc.Verify(pzcashParams.get(), verifier, joinSplitPubKey_))) {
|
||||
throw std::runtime_error("error verifying joinsplit");
|
||||
}
|
||||
}
|
||||
|
@ -817,7 +806,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
ss2 << ((unsigned char)0x00);
|
||||
ss2 << jsdesc.ephemeralKey;
|
||||
ss2 << jsdesc.ciphertexts[0];
|
||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
||||
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||
|
||||
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
|
@ -826,7 +815,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
ss2 << ((unsigned char)0x01);
|
||||
ss2 << jsdesc.ephemeralKey;
|
||||
ss2 << jsdesc.ciphertexts[1];
|
||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
||||
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||
|
||||
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
|
@ -858,7 +847,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||
|
||||
CZCPaymentAddress address(zaddr);
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString());
|
||||
LogPrint(BCLog::PAYMENTDISCLOSURE, "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString());
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ private:
|
|||
MergeToAddressRecipient recipient_;
|
||||
bool isToTaddr_;
|
||||
bool isToZaddr_;
|
||||
CBitcoinAddress toTaddr_;
|
||||
CTxDestination toTaddr_;
|
||||
PaymentAddress toPaymentAddress_;
|
||||
|
||||
uint256 joinSplitPubKey_;
|
||||
|
|
|
@ -2,24 +2,25 @@
|
|||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <asyncrpcoperation_sendmany.h>
|
||||
#include <wallet/asyncrpcoperation_sendmany.h>
|
||||
#include <asyncrpcqueue.h>
|
||||
#include <amount.h>
|
||||
#include <consensus/upgrades.h>
|
||||
#include <core_io.h>
|
||||
#include <init.h>
|
||||
#include <net.h>
|
||||
#include <netbase.h>
|
||||
#include <rpcserver.h>
|
||||
#include <paymentdisclosure.h>
|
||||
#include <paymentdisclosuredb.h>
|
||||
#include <rpc/protocol.h>
|
||||
#include <rpc/server.h>
|
||||
#include <timedata.h>
|
||||
#include <util.h>
|
||||
#include <utilmoneystr.h>
|
||||
#include <wallet.h>
|
||||
#include <walletdb.h>
|
||||
#include <wallet/wallet.h>
|
||||
#include <wallet/walletdb.h>
|
||||
#include <script/interpreter.h>
|
||||
#include <utiltime.h>
|
||||
#include <validation.h>
|
||||
#include <rpcprotocol.h>
|
||||
#include <zcash/IncrementalMerkleTree.hpp>
|
||||
#include <sodium.h>
|
||||
#include <miner.h>
|
||||
|
@ -29,8 +30,6 @@
|
|||
#include <thread>
|
||||
#include <string>
|
||||
|
||||
#include <wallet/paymentdisclosuredb.h>
|
||||
|
||||
using namespace libzcash;
|
||||
|
||||
int find_output(UniValue obj, int n) {
|
||||
|
@ -74,7 +73,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, "No recipients");
|
||||
}
|
||||
|
||||
fromtaddr_ = CBitcoinAddress(fromAddress);
|
||||
fromtaddr_ = DecodeDestination(fromAddress);
|
||||
isfromtaddr_ = fromtaddr_.IsValid();
|
||||
isfromzaddr_ = false;
|
||||
|
||||
|
@ -102,10 +101,10 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
|||
}
|
||||
|
||||
// Log the context info i.e. the call parameters to z_sendmany
|
||||
if (LogAcceptCategory("zrpcunsafe")) {
|
||||
LogPrint("zrpcunsafe", "%s: z_sendmany initialized (params=%s)\n", getId(), contextInfo.write());
|
||||
if (LogAcceptCategory(BCLog::ZRPCUNSAFE)) {
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: z_sendmany initialized (params=%s)\n", getId(), contextInfo.write());
|
||||
} else {
|
||||
LogPrint("zrpc", "%s: z_sendmany initialized\n", getId());
|
||||
LogPrint(BCLog::ZRPC, "%s: z_sendmany initialized\n", getId());
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,14 +124,6 @@ void AsyncRPCOperation_sendmany::main() {
|
|||
|
||||
bool success = false;
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
#ifdef ENABLE_WALLET
|
||||
GenerateBitcoins(false, NULL, 0);
|
||||
#else
|
||||
GenerateBitcoins(false, 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
try {
|
||||
success = main_impl();
|
||||
} catch (const UniValue& objError) {
|
||||
|
@ -154,14 +145,6 @@ void AsyncRPCOperation_sendmany::main() {
|
|||
set_error_message("unknown error");
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
#ifdef ENABLE_WALLET
|
||||
GenerateBitcoins(GetBoolArg("-gen",false), pwalletMain, GetArg("-genproclimit", 1));
|
||||
#else
|
||||
GenerateBitcoins(GetBoolArg("-gen",false), GetArg("-genproclimit", 1));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
stop_execution_clock();
|
||||
|
||||
if (success) {
|
||||
|
@ -185,9 +168,9 @@ void AsyncRPCOperation_sendmany::main() {
|
|||
for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) {
|
||||
p.first.hash = txidhash;
|
||||
if (!db->Put(p.first, p.second)) {
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString());
|
||||
LogPrint(BCLog::PAYMENTDISCLOSURE, "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString());
|
||||
} else {
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString());
|
||||
LogPrint(BCLog::PAYMENTDISCLOSURE, "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +292,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
t_inputs_total = selectedUTXOAmount;
|
||||
|
||||
// Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
|
||||
size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0);
|
||||
size_t limit = (size_t)gArgs.GetArg("-mempooltxinputlimit", 0);
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
||||
|
@ -335,13 +318,13 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
tx_ = CTransaction(rawTx);
|
||||
}
|
||||
|
||||
LogPrint((isfromtaddr_) ? "zrpc" : "zrpcunsafe", "%s: spending %s to send %s with fee %s\n",
|
||||
LogPrint((isfromtaddr_) ? BCLog::ZRPC : BCLog::ZRPCUNSAFE, "%s: spending %s to send %s with fee %s\n",
|
||||
getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee));
|
||||
LogPrint("zrpc", "%s: transparent input: %s (to choose from)\n", getId(), FormatMoney(t_inputs_total));
|
||||
LogPrint("zrpcunsafe", "%s: private input: %s (to choose from)\n", getId(), FormatMoney(z_inputs_total));
|
||||
LogPrint("zrpc", "%s: transparent output: %s\n", getId(), FormatMoney(t_outputs_total));
|
||||
LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(z_outputs_total));
|
||||
LogPrint("zrpc", "%s: fee: %s\n", getId(), FormatMoney(minersFee));
|
||||
LogPrint(BCLog::ZRPC, "%s: transparent input: %s (to choose from)\n", getId(), FormatMoney(t_inputs_total));
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: private input: %s (to choose from)\n", getId(), FormatMoney(z_inputs_total));
|
||||
LogPrint(BCLog::ZRPC, "%s: transparent output: %s\n", getId(), FormatMoney(t_outputs_total));
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: private output: %s\n", getId(), FormatMoney(z_outputs_total));
|
||||
LogPrint(BCLog::ZRPC, "%s: fee: %s\n", getId(), FormatMoney(minersFee));
|
||||
|
||||
// Grab the current consensus branch ID
|
||||
{
|
||||
|
@ -366,7 +349,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
if (change > 0) {
|
||||
add_taddr_change_output_to_tx(change);
|
||||
|
||||
LogPrint("zrpc", "%s: transparent change in transaction output (amount=%s)\n",
|
||||
LogPrint(BCLog::ZRPC, "%s: transparent change in transaction output (amount=%s)\n",
|
||||
getId(),
|
||||
FormatMoney(change)
|
||||
);
|
||||
|
@ -446,7 +429,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
"in z_sendmany.", FormatMoney(change)));
|
||||
} else {
|
||||
add_taddr_change_output_to_tx(change);
|
||||
LogPrint("zrpc", "%s: transparent change in transaction output (amount=%s)\n",
|
||||
LogPrint(BCLog::ZRPC, "%s: transparent change in transaction output (amount=%s)\n",
|
||||
getId(),
|
||||
FormatMoney(change)
|
||||
);
|
||||
|
@ -569,7 +552,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
|
||||
// Decrypt the change note's ciphertext to retrieve some data we need
|
||||
ZCNoteDecryption decryptor(spendingkey_.receiving_key());
|
||||
auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey);
|
||||
auto hSig = prevJoinSplit.h_sig(pzcashParams.get(), tx_.joinSplitPubKey);
|
||||
try {
|
||||
NotePlaintext plaintext = NotePlaintext::decrypt(
|
||||
decryptor,
|
||||
|
@ -583,7 +566,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
|
||||
jsInputValue += plaintext.value;
|
||||
|
||||
LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n",
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: spending change (amount=%s)\n",
|
||||
getId(),
|
||||
FormatMoney(plaintext.value)
|
||||
);
|
||||
|
@ -634,7 +617,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight;
|
||||
wtxDepth = wtx.GetDepthInMainChain();
|
||||
}
|
||||
LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n",
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n",
|
||||
getId(),
|
||||
jso.hash.ToString().substr(0, 10),
|
||||
jso.js,
|
||||
|
@ -738,7 +721,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
if (jsChange>0) {
|
||||
info.vjsout.push_back(JSOutput(frompaymentaddress_, jsChange));
|
||||
|
||||
LogPrint("zrpcunsafe", "%s: generating note for change (amount=%s)\n",
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: generating note for change (amount=%s)\n",
|
||||
getId(),
|
||||
FormatMoney(jsChange)
|
||||
);
|
||||
|
@ -829,7 +812,7 @@ void AsyncRPCOperation_sendmany::sign_send_raw_transaction(UniValue obj)
|
|||
|
||||
|
||||
bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) {
|
||||
set<CBitcoinAddress> setAddress = {fromtaddr_};
|
||||
set<CTxDestination> setAddress = {fromtaddr_};
|
||||
vector<COutput> vecOutputs;
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
@ -886,7 +869,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() {
|
|||
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("zrpcunsafe", "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n",
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n",
|
||||
getId(),
|
||||
entry.jsop.hash.ToString().substr(0, 10),
|
||||
entry.jsop.js,
|
||||
|
@ -902,7 +885,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() {
|
|||
|
||||
// sort in descending order, so big notes appear first
|
||||
std::sort(z_inputs_.begin(), z_inputs_.end(), [](SendManyInputJSOP i, SendManyInputJSOP j) -> bool {
|
||||
return ( std::get<2>(i) > std::get<2>(j));
|
||||
return (std::get<2>(i) > std::get<2>(j));
|
||||
});
|
||||
|
||||
return true;
|
||||
|
@ -964,7 +947,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
|
||||
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",
|
||||
LogPrint(BCLog::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),
|
||||
|
@ -983,7 +966,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
uint256 esk; // payment disclosure - secret
|
||||
|
||||
JSDescription jsdesc = JSDescription::Randomized(
|
||||
*pzcashParams,
|
||||
pzcashParams.get(),
|
||||
joinSplitPubKey_,
|
||||
anchor,
|
||||
inputs,
|
||||
|
@ -996,7 +979,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
&esk); // parameter expects pointer to esk, so pass in address
|
||||
{
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) {
|
||||
if (!(jsdesc.Verify(pzcashParams.get(), verifier, joinSplitPubKey_))) {
|
||||
throw std::runtime_error("error verifying joinsplit");
|
||||
}
|
||||
}
|
||||
|
@ -1039,7 +1022,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
ss2 << ((unsigned char) 0x00);
|
||||
ss2 << jsdesc.ephemeralKey;
|
||||
ss2 << jsdesc.ciphertexts[0];
|
||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
||||
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||
|
||||
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
|
@ -1048,7 +1031,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
ss2 << ((unsigned char) 0x01);
|
||||
ss2 << jsdesc.ephemeralKey;
|
||||
ss2 << jsdesc.ciphertexts[1];
|
||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
||||
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||
|
||||
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
|
@ -1080,7 +1063,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||
|
||||
CZCPaymentAddress address(zaddr);
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString());
|
||||
LogPrint(BCLog::PAYMENTDISCLOSURE, "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString());
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
|
||||
|
@ -1101,12 +1084,12 @@ void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() {
|
|||
std::string outputAddress = std::get<0>(r);
|
||||
CAmount nAmount = std::get<1>(r);
|
||||
|
||||
CBitcoinAddress address(outputAddress);
|
||||
if (!address.IsValid()) {
|
||||
CTxDestination address = DecodeDestination(outputAddress);
|
||||
if (!IsValidDestination(address)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid output address, not a valid taddr.");
|
||||
}
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(address.Get());
|
||||
CScript scriptPubKey = GetScriptForDestination(address);
|
||||
|
||||
CTxOut out(nAmount, scriptPubKey);
|
||||
rawTx.vout.push_back(out);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <primitives/transaction.h>
|
||||
#include <zcash/JoinSplit.hpp>
|
||||
#include <zcash/Address.hpp>
|
||||
#include <wallet.h>
|
||||
#include <wallet/wallet.h>
|
||||
#include <paymentdisclosure.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
@ -79,7 +79,7 @@ private:
|
|||
std::string fromaddress_;
|
||||
bool isfromtaddr_;
|
||||
bool isfromzaddr_;
|
||||
CBitcoinAddress fromtaddr_;
|
||||
CTxDestination fromtaddr_;
|
||||
PaymentAddress frompaymentaddress_;
|
||||
SpendingKey spendingkey_;
|
||||
|
||||
|
|
|
@ -4,21 +4,21 @@
|
|||
|
||||
#include <asyncrpcqueue.h>
|
||||
#include <amount.h>
|
||||
#include <consensus/upgrades.h>
|
||||
#include <core_io.h>
|
||||
#include <init.h>
|
||||
#include <main.h>
|
||||
#include <net.h>
|
||||
#include <netbase.h>
|
||||
#include <rpcserver.h>
|
||||
#include <paymentdisclosure.h>
|
||||
#include <paymentdisclosuredb.h>
|
||||
#include <rpc/protocol.h>
|
||||
#include <rpc/server.h>
|
||||
#include <timedata.h>
|
||||
#include <util.h>
|
||||
#include <utilmoneystr.h>
|
||||
#include <wallet.h>
|
||||
#include <walletdb.h>
|
||||
#include <wallet/wallet.h>
|
||||
#include <wallet/walletdb.h>
|
||||
#include <script/interpreter.h>
|
||||
#include <utiltime.h>
|
||||
#include <rpcprotocol.h>
|
||||
#include <zcash/IncrementalMerkleTree.hpp>
|
||||
#include <sodium.h>
|
||||
#include <miner.h>
|
||||
|
@ -30,8 +30,6 @@
|
|||
|
||||
#include <wallet/asyncrpcoperation_shieldcoinbase.h>
|
||||
|
||||
#include <wallet/paymentdisclosure.h>
|
||||
#include <wallet/paymentdisclosuredb.h>
|
||||
|
||||
using namespace libzcash;
|
||||
|
||||
|
@ -79,10 +77,10 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
|
|||
}
|
||||
|
||||
// Log the context info
|
||||
if (LogAcceptCategory("zrpcunsafe")) {
|
||||
LogPrint("zrpcunsafe", "%s: z_shieldcoinbase initialized (context=%s)\n", getId(), contextInfo.write());
|
||||
if (LogAcceptCategory(BCLog::ZRPCUNSAFE)) {
|
||||
LogPrint(BCLog::ZRPCUNSAFE, "%s: z_shieldcoinbase initialized (context=%s)\n", getId(), contextInfo.write());
|
||||
} else {
|
||||
LogPrint("zrpc", "%s: z_shieldcoinbase initialized\n", getId());
|
||||
LogPrint(BCLog::ZRPC, "%s: z_shieldcoinbase initialized\n", getId());
|
||||
}
|
||||
|
||||
// Lock UTXOs
|
||||
|
@ -106,14 +104,6 @@ void AsyncRPCOperation_shieldcoinbase::main() {
|
|||
|
||||
bool success = false;
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
#ifdef ENABLE_WALLET
|
||||
GenerateBitcoins(false, NULL, 0);
|
||||
#else
|
||||
GenerateBitcoins(false, 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
try {
|
||||
success = main_impl();
|
||||
} catch (const UniValue& objError) {
|
||||
|
@ -135,14 +125,6 @@ void AsyncRPCOperation_shieldcoinbase::main() {
|
|||
set_error_message("unknown error");
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
#ifdef ENABLE_WALLET
|
||||
GenerateBitcoins(GetBoolArg("-gen",false), pwalletMain, GetArg("-genproclimit", 1));
|
||||
#else
|
||||
GenerateBitcoins(GetBoolArg("-gen",false), GetArg("-genproclimit", 1));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
stop_execution_clock();
|
||||
|
||||
if (success) {
|
||||
|
@ -168,9 +150,9 @@ void AsyncRPCOperation_shieldcoinbase::main() {
|
|||
for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) {
|
||||
p.first.hash = txidhash;
|
||||
if (!db->Put(p.first, p.second)) {
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString());
|
||||
LogPrint(BCLog::PAYMENTDISCLOSURE, "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString());
|
||||
} else {
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString());
|
||||
LogPrint(BCLog::PAYMENTDISCLOSURE, "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +167,7 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() {
|
|||
size_t numInputs = inputs_.size();
|
||||
|
||||
// Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
|
||||
size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0);
|
||||
size_t limit = (size_t)gArgs.GetArg("-mempooltxinputlimit", 0);
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
||||
|
@ -210,7 +192,7 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() {
|
|||
}
|
||||
|
||||
CAmount sendAmount = targetAmount - minersFee;
|
||||
LogPrint("zrpc", "%s: spending %s to shield %s with fee %s\n",
|
||||
LogPrint(BCLog::ZRPC, "%s: spending %s to shield %s with fee %s\n",
|
||||
getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee));
|
||||
|
||||
// update the transaction with these inputs
|
||||
|
@ -337,7 +319,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
|
||||
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",
|
||||
LogPrint(BCLog::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),
|
||||
|
@ -356,7 +338,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
uint256 esk; // payment disclosure - secret
|
||||
|
||||
JSDescription jsdesc = JSDescription::Randomized(
|
||||
*pzcashParams,
|
||||
pzcashParams.get(),
|
||||
joinSplitPubKey_,
|
||||
anchor,
|
||||
inputs,
|
||||
|
@ -369,7 +351,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
&esk); // parameter expects pointer to esk, so pass in address
|
||||
{
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) {
|
||||
if (!(jsdesc.Verify(pzcashParams.get(), verifier, joinSplitPubKey_))) {
|
||||
throw std::runtime_error("error verifying joinsplit");
|
||||
}
|
||||
}
|
||||
|
@ -412,7 +394,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
ss2 << ((unsigned char) 0x00);
|
||||
ss2 << jsdesc.ephemeralKey;
|
||||
ss2 << jsdesc.ciphertexts[0];
|
||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
||||
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||
|
||||
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
|
@ -421,7 +403,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
ss2 << ((unsigned char) 0x01);
|
||||
ss2 << jsdesc.ephemeralKey;
|
||||
ss2 << jsdesc.ciphertexts[1];
|
||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
||||
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||
|
||||
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
|
@ -452,7 +434,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||
|
||||
CZCPaymentAddress address(zaddr);
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString());
|
||||
LogPrint(BCLog::PAYMENTDISCLOSURE, "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString());
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
#include <primitives/transaction.h>
|
||||
#include <zcash/JoinSplit.hpp>
|
||||
#include <zcash/Address.hpp>
|
||||
#include <wallet.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <tuple>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
#include <wallet/paymentdisclosure.h>
|
||||
#include <paymentdisclosure.h>
|
||||
|
||||
// Default transaction fee if caller does not specify one.
|
||||
#define SHIELD_COINBASE_DEFAULT_MINERS_FEE 10000
|
||||
|
|
|
@ -16,12 +16,12 @@ public:
|
|||
// Transaction hash
|
||||
uint256 hash;
|
||||
// Index into CTransaction.vjoinsplit
|
||||
size_t js;
|
||||
uint64_t js;
|
||||
// Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
|
||||
uint8_t n;
|
||||
|
||||
JSOutPoint() { SetNull(); }
|
||||
JSOutPoint(uint256 h, size_t js, uint8_t n) : hash {h}, js {js}, n {n} { }
|
||||
JSOutPoint(uint256 h, uint64_t js, uint8_t n) : hash {h}, js {js}, n {n} { }
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "uint256.h"
|
||||
#include "uint252.h"
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace libzcash {
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Zcash.h"
|
||||
#include "Address.hpp"
|
||||
#include "NoteEncryption.hpp"
|
||||
#include <array>
|
||||
|
||||
namespace libzcash {
|
||||
|
||||
|
|
Loading…
Reference in New Issue