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
|
endif
|
||||||
|
|
||||||
dist_bin_SCRIPTS = #zcutil/fetch-params.sh
|
dist_bin_SCRIPTS = scripts/fetch-zcash-params.sh
|
||||||
dist_noinst_SCRIPTS = autogen.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)
|
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
|
test/util/rpcauth-test.py
|
||||||
|
|
||||||
CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER)
|
CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER)
|
||||||
install-exec-hook:
|
|
||||||
mv $(DESTDIR)$(bindir)/fetch-params.sh $(DESTDIR)$(bindir)/zcash-fetch-params
|
|
||||||
|
|
||||||
.INTERMEDIATE: $(COVERAGE_INFO)
|
.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([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"])
|
||||||
AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]])
|
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)
|
BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
|
||||||
|
|
||||||
|
|
|
@ -103,5 +103,5 @@ ld -v
|
||||||
|
|
||||||
HOST="$HOST" BUILD="$BUILD" "$MAKE" "$@" -C ./depends/ V=1
|
HOST="$HOST" BUILD="$BUILD" "$MAKE" "$@" -C ./depends/ V=1
|
||||||
./autogen.sh
|
./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
|
"$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 \
|
validationinterface.h \
|
||||||
versionbits.h \
|
versionbits.h \
|
||||||
walletinitinterface.h \
|
walletinitinterface.h \
|
||||||
wallet/asyncrpcoperation_mergetoaddress.h \
|
|
||||||
wallet/asyncrpcoperation_sendmany.h \
|
|
||||||
wallet/asyncrpcoperation_shieldcoinbase.h \
|
|
||||||
wallet/coincontrol.h \
|
wallet/coincontrol.h \
|
||||||
wallet/crypter.h \
|
wallet/crypter.h \
|
||||||
wallet/db.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_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
libbitcoin_wallet_a_SOURCES = \
|
libbitcoin_wallet_a_SOURCES = \
|
||||||
interfaces/wallet.cpp \
|
interfaces/wallet.cpp \
|
||||||
wallet/asyncrpcoperation_mergetoaddress.cpp \
|
|
||||||
wallet/asyncrpcoperation_sendmany.cpp \
|
|
||||||
wallet/asyncrpcoperation_shieldcoinbase.cpp \
|
|
||||||
wallet/crypter.cpp \
|
wallet/crypter.cpp \
|
||||||
wallet/db.cpp \
|
wallet/db.cpp \
|
||||||
wallet/feebumper.cpp \
|
wallet/feebumper.cpp \
|
||||||
|
@ -303,7 +297,6 @@ libbitcoin_wallet_a_SOURCES = \
|
||||||
wallet/init.cpp \
|
wallet/init.cpp \
|
||||||
paymentdisclosure.cpp \
|
paymentdisclosure.cpp \
|
||||||
paymentdisclosuredb.cpp \
|
paymentdisclosuredb.cpp \
|
||||||
wallet/rpcdisclosure.cpp \
|
|
||||||
wallet/rpcdump.cpp \
|
wallet/rpcdump.cpp \
|
||||||
wallet/rpcwallet.cpp \
|
wallet/rpcwallet.cpp \
|
||||||
wallet/wallet.cpp \
|
wallet/wallet.cpp \
|
||||||
|
|
|
@ -355,19 +355,19 @@ public:
|
||||||
|
|
||||||
nPruneAfterHeight = 1000;
|
nPruneAfterHeight = 1000;
|
||||||
|
|
||||||
nEquihashN = 48;
|
nEquihashN = 200;
|
||||||
nEquihashK = 5;
|
nEquihashK = 9;
|
||||||
|
|
||||||
uint256 nNonce = uint256S("0000000000000000000000000000000000000000000000000000000000000009");
|
uint256 nNonce = uint256S("0000000000000000000000000000000000000000000000000000000000000009");
|
||||||
genesis = CreateGenesisBlock(1482971059, nNonce, 0x200f0f0f, 4, 0, GenesisSolutions::REGTEST);
|
genesis = CreateGenesisBlock(1482971059, nNonce, 0x200f0f0f, 4, 0, GenesisSolutions::REGTEST);
|
||||||
consensus.hashGenesisBlock = genesis.GetHash();
|
consensus.hashGenesisBlock = genesis.GetHash();
|
||||||
assert(consensus.hashGenesisBlock == uint256S("0x0575f78ee8dc057deee78ef691876e3be29833aaee5e189bb0459c087451305a"));
|
assert(consensus.hashGenesisBlock == uint256S("0x0575f78ee8dc057deee78ef691876e3be29833aaee5e189bb0459c087451305a"));
|
||||||
|
|
||||||
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
|
base58Prefixes[PUBKEY_ADDRESS] = {0x19,0x57};
|
||||||
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
|
base58Prefixes[SCRIPT_ADDRESS] = {0x19,0xE0};
|
||||||
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
|
base58Prefixes[SECRET_KEY] = {0xEF};
|
||||||
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
|
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
|
||||||
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
|
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
|
||||||
base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xC0};
|
base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xC0};
|
||||||
base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08};
|
base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08};
|
||||||
bech32_hrp = "regbtcp";
|
bech32_hrp = "regbtcp";
|
||||||
|
|
|
@ -32,7 +32,7 @@ bool CheckTransactionJoinsplits(const CTransaction& tx, CValidationState &state)
|
||||||
// Ensure that zk-SNARKs verify
|
// Ensure that zk-SNARKs verify
|
||||||
auto verifier = libzcash::ProofVerifier::Strict();
|
auto verifier = libzcash::ProofVerifier::Strict();
|
||||||
for(const JSDescription &joinsplit : tx.vjoinsplit) {
|
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"),
|
return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
|
||||||
REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
|
REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
|
||||||
}
|
}
|
||||||
|
|
42
src/init.cpp
42
src/init.cpp
|
@ -60,6 +60,8 @@
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
|
|
||||||
|
#include <libsnark/common/profiling.hpp>
|
||||||
|
|
||||||
#if ENABLE_ZMQ
|
#if ENABLE_ZMQ
|
||||||
#include <zmq/zmqnotificationinterface.h>
|
#include <zmq/zmqnotificationinterface.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -72,6 +74,8 @@ static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
|
||||||
std::unique_ptr<CConnman> g_connman;
|
std::unique_ptr<CConnman> g_connman;
|
||||||
std::unique_ptr<PeerLogicValidation> peerLogic;
|
std::unique_ptr<PeerLogicValidation> peerLogic;
|
||||||
|
|
||||||
|
std::unique_ptr<ZCJoinSplit> pzcashParams;
|
||||||
|
|
||||||
#if !(ENABLE_WALLET)
|
#if !(ENABLE_WALLET)
|
||||||
class DummyWalletInit : public WalletInitInterface {
|
class DummyWalletInit : public WalletInitInterface {
|
||||||
public:
|
public:
|
||||||
|
@ -289,6 +293,7 @@ void Shutdown()
|
||||||
GetMainSignals().UnregisterWithMempoolSignals(mempool);
|
GetMainSignals().UnregisterWithMempoolSignals(mempool);
|
||||||
g_wallet_init_interface.Close();
|
g_wallet_init_interface.Close();
|
||||||
globalVerifyHandle.reset();
|
globalVerifyHandle.reset();
|
||||||
|
|
||||||
ECC_Stop();
|
ECC_Stop();
|
||||||
LogPrintf("%s: done\n", __func__);
|
LogPrintf("%s: done\n", __func__);
|
||||||
}
|
}
|
||||||
|
@ -698,6 +703,35 @@ static void ThreadImport(std::vector<fs::path> vImportFiles)
|
||||||
g_is_mempool_loaded = !fRequestShutdown;
|
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
|
/** Sanity checks
|
||||||
* Ensure that Bitcoin is running in a usable environment with all
|
* Ensure that Bitcoin is running in a usable environment with all
|
||||||
* necessary library support.
|
* necessary library support.
|
||||||
|
@ -1267,6 +1301,14 @@ bool AppInitMain()
|
||||||
threadGroup.create_thread(&ThreadScriptCheck);
|
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
|
// Start the lightweight task scheduler thread
|
||||||
CScheduler::Function serviceLoop = boost::bind(&CScheduler::serviceQueue, &scheduler);
|
CScheduler::Function serviceLoop = boost::bind(&CScheduler::serviceQueue, &scheduler);
|
||||||
threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
|
threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
|
#include <zcash/JoinSplit.hpp>
|
||||||
|
|
||||||
class CScheduler;
|
class CScheduler;
|
||||||
class CWallet;
|
class CWallet;
|
||||||
|
|
||||||
|
@ -21,6 +23,8 @@ namespace boost
|
||||||
class thread_group;
|
class thread_group;
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
extern std::unique_ptr<ZCJoinSplit> pzcashParams;
|
||||||
|
|
||||||
void StartShutdown();
|
void StartShutdown();
|
||||||
bool ShutdownRequested();
|
bool ShutdownRequested();
|
||||||
/** Interrupt threads */
|
/** Interrupt threads */
|
||||||
|
|
|
@ -121,6 +121,8 @@ const CLogCategoryDesc LogCategories[] =
|
||||||
{BCLog::LEVELDB, "leveldb"},
|
{BCLog::LEVELDB, "leveldb"},
|
||||||
{BCLog::EQUIHASH, "equihash"},
|
{BCLog::EQUIHASH, "equihash"},
|
||||||
{BCLog::PAYMENTDISCLOSURE, "paymentdisclosure"},
|
{BCLog::PAYMENTDISCLOSURE, "paymentdisclosure"},
|
||||||
|
{BCLog::ZRPC, "zrpc"},
|
||||||
|
{BCLog::ZRPCUNSAFE, "zrpcunsafe"},
|
||||||
{BCLog::ALL, "1"},
|
{BCLog::ALL, "1"},
|
||||||
{BCLog::ALL, "all"},
|
{BCLog::ALL, "all"},
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,6 +55,8 @@ namespace BCLog {
|
||||||
LEVELDB = (1 << 20),
|
LEVELDB = (1 << 20),
|
||||||
EQUIHASH = (1 << 21),
|
EQUIHASH = (1 << 21),
|
||||||
PAYMENTDISCLOSURE = (1 << 22),
|
PAYMENTDISCLOSURE = (1 << 22),
|
||||||
|
ZRPC = (1 << 23),
|
||||||
|
ZRPCUNSAFE = (1 << 24),
|
||||||
ALL = ~(uint32_t)0,
|
ALL = ~(uint32_t)0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ struct PaymentDisclosurePayload {
|
||||||
uint8_t version; // 0 = experimental, 1 = first production version, etc.
|
uint8_t version; // 0 = experimental, 1 = first production version, etc.
|
||||||
uint256 esk; // zcash/NoteEncryption.cpp
|
uint256 esk; // zcash/NoteEncryption.cpp
|
||||||
uint256 txid; // primitives/transaction.h
|
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
|
uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
|
||||||
libzcash::PaymentAddress zaddr; // zcash/Address.hpp
|
libzcash::PaymentAddress zaddr; // zcash/Address.hpp
|
||||||
std::string message; // parameter to RPC call
|
std::string message; // parameter to RPC call
|
||||||
|
|
|
@ -48,8 +48,8 @@ JSDescription JSDescription::Randomized(
|
||||||
const uint256& anchor,
|
const uint256& anchor,
|
||||||
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||||
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
||||||
std::array<size_t, ZC_NUM_JS_INPUTS>& inputMap,
|
std::array<uint64_t, ZC_NUM_JS_INPUTS>& inputMap,
|
||||||
std::array<size_t, ZC_NUM_JS_OUTPUTS>& outputMap,
|
std::array<uint64_t, ZC_NUM_JS_OUTPUTS>& outputMap,
|
||||||
CAmount vpub_old,
|
CAmount vpub_old,
|
||||||
CAmount vpub_new,
|
CAmount vpub_new,
|
||||||
bool computeProof,
|
bool computeProof,
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include <zcash/JoinSplit.hpp>
|
#include <zcash/JoinSplit.hpp>
|
||||||
#include <zcash/Proof.hpp>
|
#include <zcash/Proof.hpp>
|
||||||
|
|
||||||
#include <boost/array.hpp>
|
#include <array>
|
||||||
|
|
||||||
class JSDescription
|
class JSDescription
|
||||||
{
|
{
|
||||||
|
@ -88,8 +88,8 @@ public:
|
||||||
const uint256& rt,
|
const uint256& rt,
|
||||||
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||||
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
||||||
std::array<size_t, ZC_NUM_JS_INPUTS>& inputMap,
|
std::array<uint64_t, ZC_NUM_JS_INPUTS>& inputMap,
|
||||||
std::array<size_t, ZC_NUM_JS_OUTPUTS>& outputMap,
|
std::array<uint64_t, ZC_NUM_JS_OUTPUTS>& outputMap,
|
||||||
CAmount vpub_old,
|
CAmount vpub_old,
|
||||||
CAmount vpub_new,
|
CAmount vpub_new,
|
||||||
bool computeProof = true, // Set to false in some tests
|
bool computeProof = true, // Set to false in some tests
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
#include <miner.h>
|
#include <miner.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <netbase.h>
|
#include <netbase.h>
|
||||||
|
#include <paymentdisclosuredb.h>
|
||||||
#include <rpc/protocol.h>
|
#include <rpc/protocol.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
|
#include <rpc/rawtransaction.cpp>
|
||||||
#include <script/interpreter.h>
|
#include <script/interpreter.h>
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
#include <timedata.h>
|
#include <timedata.h>
|
||||||
|
@ -23,14 +25,13 @@
|
||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
#include <wallet/walletdb.h>
|
#include <wallet/walletdb.h>
|
||||||
#include <zcash/IncrementalMerkleTree.hpp>
|
#include <zcash/IncrementalMerkleTree.hpp>
|
||||||
|
#include <key_io.h>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include <wallet/paymentdisclosuredb.h>
|
|
||||||
|
|
||||||
using namespace libzcash;
|
using namespace libzcash;
|
||||||
|
|
||||||
int mta_find_output(UniValue obj, int n)
|
int mta_find_output(UniValue obj, int n)
|
||||||
|
@ -73,8 +74,8 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Recipient parameter missing");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Recipient parameter missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
toTaddr_ = CBitcoinAddress(std::get<0>(recipient));
|
toTaddr_ = DecodeDestination(std::get<0>(recipient));
|
||||||
isToTaddr_ = toTaddr_.IsValid();
|
isToTaddr_ = IsValidDestination(toTaddr_);
|
||||||
isToZaddr_ = false;
|
isToZaddr_ = false;
|
||||||
|
|
||||||
if (!isToTaddr_) {
|
if (!isToTaddr_) {
|
||||||
|
@ -90,10 +91,10 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the context info i.e. the call parameters to z_mergetoaddress
|
// Log the context info i.e. the call parameters to z_mergetoaddress
|
||||||
if (LogAcceptCategory("zrpcunsafe")) {
|
if (LogAcceptCategory(BCLog::ZRPCUNSAFE)) {
|
||||||
LogPrint("zrpcunsafe", "%s: z_mergetoaddress initialized (params=%s)\n", getId(), contextInfo.write());
|
LogPrint(BCLog::ZRPCUNSAFE, "%s: z_mergetoaddress initialized (params=%s)\n", getId(), contextInfo.write());
|
||||||
} else {
|
} else {
|
||||||
LogPrint("zrpc", "%s: z_mergetoaddress initialized\n", getId());
|
LogPrint(BCLog::ZRPC, "%s: z_mergetoaddress initialized\n", getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock UTXOs
|
// Lock UTXOs
|
||||||
|
@ -101,7 +102,7 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
||||||
lock_notes();
|
lock_notes();
|
||||||
|
|
||||||
// Enable payment disclosure if requested
|
// Enable payment disclosure if requested
|
||||||
paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false);
|
paymentDisclosureMode = fExperimentalMode && gArgs.GetBoolArg("-paymentdisclosure", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncRPCOperation_mergetoaddress::~AsyncRPCOperation_mergetoaddress()
|
AsyncRPCOperation_mergetoaddress::~AsyncRPCOperation_mergetoaddress()
|
||||||
|
@ -121,14 +122,6 @@ void AsyncRPCOperation_mergetoaddress::main()
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
#ifdef ENABLE_MINING
|
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
GenerateBitcoins(false, NULL, 0);
|
|
||||||
#else
|
|
||||||
GenerateBitcoins(false, 0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
success = main_impl();
|
success = main_impl();
|
||||||
} catch (const UniValue& objError) {
|
} catch (const UniValue& objError) {
|
||||||
|
@ -150,14 +143,6 @@ void AsyncRPCOperation_mergetoaddress::main()
|
||||||
set_error_message("unknown error");
|
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();
|
stop_execution_clock();
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
@ -184,9 +169,9 @@ void AsyncRPCOperation_mergetoaddress::main()
|
||||||
for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) {
|
for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) {
|
||||||
p.first.hash = txidhash;
|
p.first.hash = txidhash;
|
||||||
if (!db->Put(p.first, p.second)) {
|
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 {
|
} 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();
|
size_t numInputs = utxoInputs_.size();
|
||||||
|
|
||||||
// Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
|
// 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);
|
LOCK(cs_main);
|
||||||
if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
||||||
|
@ -246,22 +231,22 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
rawTx.vin.push_back(in);
|
rawTx.vin.push_back(in);
|
||||||
}
|
}
|
||||||
if (isToTaddr_) {
|
if (isToTaddr_) {
|
||||||
CScript scriptPubKey = GetScriptForDestination(toTaddr_.Get());
|
CScript scriptPubKey = GetScriptForDestination(toTaddr_);
|
||||||
CTxOut out(sendAmount, scriptPubKey);
|
CTxOut out(sendAmount, scriptPubKey);
|
||||||
rawTx.vout.push_back(out);
|
rawTx.vout.push_back(out);
|
||||||
}
|
}
|
||||||
tx_ = CTransaction(rawTx);
|
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));
|
getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee));
|
||||||
LogPrint("zrpc", "%s: transparent input: %s\n", getId(), FormatMoney(t_inputs_total));
|
LogPrint(BCLog::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::ZRPCUNSAFE, "%s: private input: %s\n", getId(), FormatMoney(z_inputs_total));
|
||||||
if (isToTaddr_) {
|
if (isToTaddr_) {
|
||||||
LogPrint("zrpc", "%s: transparent output: %s\n", getId(), FormatMoney(sendAmount));
|
LogPrint(BCLog::ZRPC, "%s: transparent output: %s\n", getId(), FormatMoney(sendAmount));
|
||||||
} else {
|
} 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
|
// 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
|
// Decrypt the change note's ciphertext to retrieve some data we need
|
||||||
ZCNoteDecryption decryptor(changeKey.receiving_key());
|
ZCNoteDecryption decryptor(changeKey.receiving_key());
|
||||||
auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey);
|
auto hSig = prevJoinSplit.h_sig(pzcashParams.get(), tx_.joinSplitPubKey);
|
||||||
try {
|
try {
|
||||||
NotePlaintext plaintext = NotePlaintext::decrypt(
|
NotePlaintext plaintext = NotePlaintext::decrypt(
|
||||||
decryptor,
|
decryptor,
|
||||||
|
@ -468,7 +453,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
|
|
||||||
jsInputValue += plaintext.value;
|
jsInputValue += plaintext.value;
|
||||||
|
|
||||||
LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n",
|
LogPrint(BCLog::ZRPCUNSAFE, "%s: spending change (amount=%s)\n",
|
||||||
getId(),
|
getId(),
|
||||||
FormatMoney(plaintext.value));
|
FormatMoney(plaintext.value));
|
||||||
|
|
||||||
|
@ -521,7 +506,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight;
|
wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight;
|
||||||
wtxDepth = wtx.GetDepthInMainChain();
|
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(),
|
getId(),
|
||||||
jso.hash.ToString().substr(0, 10),
|
jso.hash.ToString().substr(0, 10),
|
||||||
jso.js,
|
jso.js,
|
||||||
|
@ -598,7 +583,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
}
|
}
|
||||||
info.vjsout.push_back(jso);
|
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(),
|
getId(),
|
||||||
outputType,
|
outputType,
|
||||||
FormatMoney(jsChange));
|
FormatMoney(jsChange));
|
||||||
|
@ -635,7 +620,9 @@ void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj)
|
||||||
|
|
||||||
UniValue params = UniValue(UniValue::VARR);
|
UniValue params = UniValue(UniValue::VARR);
|
||||||
params.push_back(rawtxn);
|
params.push_back(rawtxn);
|
||||||
UniValue signResultValue = signrawtransaction(params, false);
|
JSONRPCRequest jsonRequest;
|
||||||
|
jsonRequest.params = params;
|
||||||
|
UniValue signResultValue = signrawtransaction(jsonRequest);
|
||||||
UniValue signResultObject = signResultValue.get_obj();
|
UniValue signResultObject = signResultValue.get_obj();
|
||||||
UniValue completeValue = find_value(signResultObject, "complete");
|
UniValue completeValue = find_value(signResultObject, "complete");
|
||||||
bool complete = completeValue.get_bool();
|
bool complete = completeValue.get_bool();
|
||||||
|
@ -655,7 +642,9 @@ void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj)
|
||||||
params.clear();
|
params.clear();
|
||||||
params.setArray();
|
params.setArray();
|
||||||
params.push_back(signedtxn);
|
params.push_back(signedtxn);
|
||||||
UniValue sendResultValue = sendrawtransaction(params, false);
|
JSONRPCRequest jsonRequest;
|
||||||
|
jsonRequest.params = params;
|
||||||
|
UniValue sendResultValue = sendrawtransaction(jsonRequest);
|
||||||
if (sendResultValue.isNull()) {
|
if (sendResultValue.isNull()) {
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid.");
|
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_);
|
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(),
|
getId(),
|
||||||
tx_.vjoinsplit.size(),
|
tx_.vjoinsplit.size(),
|
||||||
FormatMoney(info.vpub_old), FormatMoney(info.vpub_new),
|
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.
|
// 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::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<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs{info.vjsout[0], info.vjsout[1]};
|
||||||
std::array<size_t, ZC_NUM_JS_INPUTS> inputMap;
|
std::array<uint64_t, ZC_NUM_JS_INPUTS> inputMap;
|
||||||
std::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap;
|
std::array<uint64_t, ZC_NUM_JS_OUTPUTS> outputMap;
|
||||||
|
|
||||||
uint256 esk; // payment disclosure - secret
|
uint256 esk; // payment disclosure - secret
|
||||||
|
|
||||||
JSDescription jsdesc = JSDescription::Randomized(
|
JSDescription jsdesc = JSDescription::Randomized(
|
||||||
*pzcashParams,
|
pzcashParams.get(),
|
||||||
joinSplitPubKey_,
|
joinSplitPubKey_,
|
||||||
anchor,
|
anchor,
|
||||||
inputs,
|
inputs,
|
||||||
|
@ -778,7 +767,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
||||||
&esk); // parameter expects pointer to esk, so pass in address
|
&esk); // parameter expects pointer to esk, so pass in address
|
||||||
{
|
{
|
||||||
auto verifier = libzcash::ProofVerifier::Strict();
|
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");
|
throw std::runtime_error("error verifying joinsplit");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -817,7 +806,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
||||||
ss2 << ((unsigned char)0x00);
|
ss2 << ((unsigned char)0x00);
|
||||||
ss2 << jsdesc.ephemeralKey;
|
ss2 << jsdesc.ephemeralKey;
|
||||||
ss2 << jsdesc.ciphertexts[0];
|
ss2 << jsdesc.ciphertexts[0];
|
||||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||||
|
|
||||||
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
|
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
|
||||||
}
|
}
|
||||||
|
@ -826,7 +815,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
||||||
ss2 << ((unsigned char)0x01);
|
ss2 << ((unsigned char)0x01);
|
||||||
ss2 << jsdesc.ephemeralKey;
|
ss2 << jsdesc.ephemeralKey;
|
||||||
ss2 << jsdesc.ciphertexts[1];
|
ss2 << jsdesc.ciphertexts[1];
|
||||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||||
|
|
||||||
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
||||||
}
|
}
|
||||||
|
@ -858,7 +847,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
||||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||||
|
|
||||||
CZCPaymentAddress address(zaddr);
|
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
|
// !!! Payment disclosure END
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ private:
|
||||||
MergeToAddressRecipient recipient_;
|
MergeToAddressRecipient recipient_;
|
||||||
bool isToTaddr_;
|
bool isToTaddr_;
|
||||||
bool isToZaddr_;
|
bool isToZaddr_;
|
||||||
CBitcoinAddress toTaddr_;
|
CTxDestination toTaddr_;
|
||||||
PaymentAddress toPaymentAddress_;
|
PaymentAddress toPaymentAddress_;
|
||||||
|
|
||||||
uint256 joinSplitPubKey_;
|
uint256 joinSplitPubKey_;
|
||||||
|
|
|
@ -2,24 +2,25 @@
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <asyncrpcoperation_sendmany.h>
|
#include <wallet/asyncrpcoperation_sendmany.h>
|
||||||
#include <asyncrpcqueue.h>
|
#include <asyncrpcqueue.h>
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
#include <consensus/upgrades.h>
|
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <netbase.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 <timedata.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <utilmoneystr.h>
|
#include <utilmoneystr.h>
|
||||||
#include <wallet.h>
|
#include <wallet/wallet.h>
|
||||||
#include <walletdb.h>
|
#include <wallet/walletdb.h>
|
||||||
#include <script/interpreter.h>
|
#include <script/interpreter.h>
|
||||||
#include <utiltime.h>
|
#include <utiltime.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
#include <rpcprotocol.h>
|
|
||||||
#include <zcash/IncrementalMerkleTree.hpp>
|
#include <zcash/IncrementalMerkleTree.hpp>
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
#include <miner.h>
|
#include <miner.h>
|
||||||
|
@ -29,8 +30,6 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <wallet/paymentdisclosuredb.h>
|
|
||||||
|
|
||||||
using namespace libzcash;
|
using namespace libzcash;
|
||||||
|
|
||||||
int find_output(UniValue obj, int n) {
|
int find_output(UniValue obj, int n) {
|
||||||
|
@ -74,7 +73,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "No recipients");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "No recipients");
|
||||||
}
|
}
|
||||||
|
|
||||||
fromtaddr_ = CBitcoinAddress(fromAddress);
|
fromtaddr_ = DecodeDestination(fromAddress);
|
||||||
isfromtaddr_ = fromtaddr_.IsValid();
|
isfromtaddr_ = fromtaddr_.IsValid();
|
||||||
isfromzaddr_ = false;
|
isfromzaddr_ = false;
|
||||||
|
|
||||||
|
@ -102,10 +101,10 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the context info i.e. the call parameters to z_sendmany
|
// Log the context info i.e. the call parameters to z_sendmany
|
||||||
if (LogAcceptCategory("zrpcunsafe")) {
|
if (LogAcceptCategory(BCLog::ZRPCUNSAFE)) {
|
||||||
LogPrint("zrpcunsafe", "%s: z_sendmany initialized (params=%s)\n", getId(), contextInfo.write());
|
LogPrint(BCLog::ZRPCUNSAFE, "%s: z_sendmany initialized (params=%s)\n", getId(), contextInfo.write());
|
||||||
} else {
|
} 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;
|
bool success = false;
|
||||||
|
|
||||||
#ifdef ENABLE_MINING
|
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
GenerateBitcoins(false, NULL, 0);
|
|
||||||
#else
|
|
||||||
GenerateBitcoins(false, 0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
success = main_impl();
|
success = main_impl();
|
||||||
} catch (const UniValue& objError) {
|
} catch (const UniValue& objError) {
|
||||||
|
@ -154,14 +145,6 @@ void AsyncRPCOperation_sendmany::main() {
|
||||||
set_error_message("unknown error");
|
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();
|
stop_execution_clock();
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
@ -185,9 +168,9 @@ void AsyncRPCOperation_sendmany::main() {
|
||||||
for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) {
|
for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) {
|
||||||
p.first.hash = txidhash;
|
p.first.hash = txidhash;
|
||||||
if (!db->Put(p.first, p.second)) {
|
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 {
|
} 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;
|
t_inputs_total = selectedUTXOAmount;
|
||||||
|
|
||||||
// Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
|
// 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);
|
LOCK(cs_main);
|
||||||
if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
||||||
|
@ -335,13 +318,13 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
tx_ = CTransaction(rawTx);
|
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));
|
getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee));
|
||||||
LogPrint("zrpc", "%s: transparent input: %s (to choose from)\n", getId(), FormatMoney(t_inputs_total));
|
LogPrint(BCLog::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(BCLog::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(BCLog::ZRPC, "%s: transparent output: %s\n", getId(), FormatMoney(t_outputs_total));
|
||||||
LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(z_outputs_total));
|
LogPrint(BCLog::ZRPCUNSAFE, "%s: private output: %s\n", getId(), FormatMoney(z_outputs_total));
|
||||||
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
|
// Grab the current consensus branch ID
|
||||||
{
|
{
|
||||||
|
@ -366,7 +349,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
if (change > 0) {
|
if (change > 0) {
|
||||||
add_taddr_change_output_to_tx(change);
|
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(),
|
getId(),
|
||||||
FormatMoney(change)
|
FormatMoney(change)
|
||||||
);
|
);
|
||||||
|
@ -446,7 +429,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
"in z_sendmany.", FormatMoney(change)));
|
"in z_sendmany.", FormatMoney(change)));
|
||||||
} else {
|
} else {
|
||||||
add_taddr_change_output_to_tx(change);
|
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(),
|
getId(),
|
||||||
FormatMoney(change)
|
FormatMoney(change)
|
||||||
);
|
);
|
||||||
|
@ -569,7 +552,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
|
|
||||||
// Decrypt the change note's ciphertext to retrieve some data we need
|
// Decrypt the change note's ciphertext to retrieve some data we need
|
||||||
ZCNoteDecryption decryptor(spendingkey_.receiving_key());
|
ZCNoteDecryption decryptor(spendingkey_.receiving_key());
|
||||||
auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey);
|
auto hSig = prevJoinSplit.h_sig(pzcashParams.get(), tx_.joinSplitPubKey);
|
||||||
try {
|
try {
|
||||||
NotePlaintext plaintext = NotePlaintext::decrypt(
|
NotePlaintext plaintext = NotePlaintext::decrypt(
|
||||||
decryptor,
|
decryptor,
|
||||||
|
@ -583,7 +566,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
|
|
||||||
jsInputValue += plaintext.value;
|
jsInputValue += plaintext.value;
|
||||||
|
|
||||||
LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n",
|
LogPrint(BCLog::ZRPCUNSAFE, "%s: spending change (amount=%s)\n",
|
||||||
getId(),
|
getId(),
|
||||||
FormatMoney(plaintext.value)
|
FormatMoney(plaintext.value)
|
||||||
);
|
);
|
||||||
|
@ -634,7 +617,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight;
|
wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight;
|
||||||
wtxDepth = wtx.GetDepthInMainChain();
|
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(),
|
getId(),
|
||||||
jso.hash.ToString().substr(0, 10),
|
jso.hash.ToString().substr(0, 10),
|
||||||
jso.js,
|
jso.js,
|
||||||
|
@ -738,7 +721,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
if (jsChange>0) {
|
if (jsChange>0) {
|
||||||
info.vjsout.push_back(JSOutput(frompaymentaddress_, jsChange));
|
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(),
|
getId(),
|
||||||
FormatMoney(jsChange)
|
FormatMoney(jsChange)
|
||||||
);
|
);
|
||||||
|
@ -829,7 +812,7 @@ void AsyncRPCOperation_sendmany::sign_send_raw_transaction(UniValue obj)
|
||||||
|
|
||||||
|
|
||||||
bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) {
|
bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) {
|
||||||
set<CBitcoinAddress> setAddress = {fromtaddr_};
|
set<CTxDestination> setAddress = {fromtaddr_};
|
||||||
vector<COutput> vecOutputs;
|
vector<COutput> vecOutputs;
|
||||||
|
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
|
@ -886,7 +869,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() {
|
||||||
for (CNotePlaintextEntry & entry : entries) {
|
for (CNotePlaintextEntry & entry : entries) {
|
||||||
z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(frompaymentaddress_), CAmount(entry.plaintext.value)));
|
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());
|
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(),
|
getId(),
|
||||||
entry.jsop.hash.ToString().substr(0, 10),
|
entry.jsop.hash.ToString().substr(0, 10),
|
||||||
entry.jsop.js,
|
entry.jsop.js,
|
||||||
|
@ -902,7 +885,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() {
|
||||||
|
|
||||||
// sort in descending order, so big notes appear first
|
// sort in descending order, so big notes appear first
|
||||||
std::sort(z_inputs_.begin(), z_inputs_.end(), [](SendManyInputJSOP i, SendManyInputJSOP j) -> bool {
|
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;
|
return true;
|
||||||
|
@ -964,7 +947,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||||
|
|
||||||
CMutableTransaction mtx(tx_);
|
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(),
|
getId(),
|
||||||
tx_.vjoinsplit.size(),
|
tx_.vjoinsplit.size(),
|
||||||
FormatMoney(info.vpub_old), FormatMoney(info.vpub_new),
|
FormatMoney(info.vpub_old), FormatMoney(info.vpub_new),
|
||||||
|
@ -983,7 +966,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||||
uint256 esk; // payment disclosure - secret
|
uint256 esk; // payment disclosure - secret
|
||||||
|
|
||||||
JSDescription jsdesc = JSDescription::Randomized(
|
JSDescription jsdesc = JSDescription::Randomized(
|
||||||
*pzcashParams,
|
pzcashParams.get(),
|
||||||
joinSplitPubKey_,
|
joinSplitPubKey_,
|
||||||
anchor,
|
anchor,
|
||||||
inputs,
|
inputs,
|
||||||
|
@ -996,7 +979,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||||
&esk); // parameter expects pointer to esk, so pass in address
|
&esk); // parameter expects pointer to esk, so pass in address
|
||||||
{
|
{
|
||||||
auto verifier = libzcash::ProofVerifier::Strict();
|
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");
|
throw std::runtime_error("error verifying joinsplit");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1039,7 +1022,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||||
ss2 << ((unsigned char) 0x00);
|
ss2 << ((unsigned char) 0x00);
|
||||||
ss2 << jsdesc.ephemeralKey;
|
ss2 << jsdesc.ephemeralKey;
|
||||||
ss2 << jsdesc.ciphertexts[0];
|
ss2 << jsdesc.ciphertexts[0];
|
||||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||||
|
|
||||||
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
|
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
|
||||||
}
|
}
|
||||||
|
@ -1048,7 +1031,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||||
ss2 << ((unsigned char) 0x01);
|
ss2 << ((unsigned char) 0x01);
|
||||||
ss2 << jsdesc.ephemeralKey;
|
ss2 << jsdesc.ephemeralKey;
|
||||||
ss2 << jsdesc.ciphertexts[1];
|
ss2 << jsdesc.ciphertexts[1];
|
||||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||||
|
|
||||||
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
||||||
}
|
}
|
||||||
|
@ -1080,7 +1063,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||||
|
|
||||||
CZCPaymentAddress address(zaddr);
|
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
|
// !!! Payment disclosure END
|
||||||
|
|
||||||
|
@ -1101,12 +1084,12 @@ void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() {
|
||||||
std::string outputAddress = std::get<0>(r);
|
std::string outputAddress = std::get<0>(r);
|
||||||
CAmount nAmount = std::get<1>(r);
|
CAmount nAmount = std::get<1>(r);
|
||||||
|
|
||||||
CBitcoinAddress address(outputAddress);
|
CTxDestination address = DecodeDestination(outputAddress);
|
||||||
if (!address.IsValid()) {
|
if (!IsValidDestination(address)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid output address, not a valid taddr.");
|
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);
|
CTxOut out(nAmount, scriptPubKey);
|
||||||
rawTx.vout.push_back(out);
|
rawTx.vout.push_back(out);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <zcash/JoinSplit.hpp>
|
#include <zcash/JoinSplit.hpp>
|
||||||
#include <zcash/Address.hpp>
|
#include <zcash/Address.hpp>
|
||||||
#include <wallet.h>
|
#include <wallet/wallet.h>
|
||||||
#include <paymentdisclosure.h>
|
#include <paymentdisclosure.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -79,7 +79,7 @@ private:
|
||||||
std::string fromaddress_;
|
std::string fromaddress_;
|
||||||
bool isfromtaddr_;
|
bool isfromtaddr_;
|
||||||
bool isfromzaddr_;
|
bool isfromzaddr_;
|
||||||
CBitcoinAddress fromtaddr_;
|
CTxDestination fromtaddr_;
|
||||||
PaymentAddress frompaymentaddress_;
|
PaymentAddress frompaymentaddress_;
|
||||||
SpendingKey spendingkey_;
|
SpendingKey spendingkey_;
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,21 @@
|
||||||
|
|
||||||
#include <asyncrpcqueue.h>
|
#include <asyncrpcqueue.h>
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
#include <consensus/upgrades.h>
|
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <main.h>
|
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <netbase.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 <timedata.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <utilmoneystr.h>
|
#include <utilmoneystr.h>
|
||||||
#include <wallet.h>
|
#include <wallet/wallet.h>
|
||||||
#include <walletdb.h>
|
#include <wallet/walletdb.h>
|
||||||
#include <script/interpreter.h>
|
#include <script/interpreter.h>
|
||||||
#include <utiltime.h>
|
#include <utiltime.h>
|
||||||
#include <rpcprotocol.h>
|
|
||||||
#include <zcash/IncrementalMerkleTree.hpp>
|
#include <zcash/IncrementalMerkleTree.hpp>
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
#include <miner.h>
|
#include <miner.h>
|
||||||
|
@ -30,8 +30,6 @@
|
||||||
|
|
||||||
#include <wallet/asyncrpcoperation_shieldcoinbase.h>
|
#include <wallet/asyncrpcoperation_shieldcoinbase.h>
|
||||||
|
|
||||||
#include <wallet/paymentdisclosure.h>
|
|
||||||
#include <wallet/paymentdisclosuredb.h>
|
|
||||||
|
|
||||||
using namespace libzcash;
|
using namespace libzcash;
|
||||||
|
|
||||||
|
@ -79,10 +77,10 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the context info
|
// Log the context info
|
||||||
if (LogAcceptCategory("zrpcunsafe")) {
|
if (LogAcceptCategory(BCLog::ZRPCUNSAFE)) {
|
||||||
LogPrint("zrpcunsafe", "%s: z_shieldcoinbase initialized (context=%s)\n", getId(), contextInfo.write());
|
LogPrint(BCLog::ZRPCUNSAFE, "%s: z_shieldcoinbase initialized (context=%s)\n", getId(), contextInfo.write());
|
||||||
} else {
|
} else {
|
||||||
LogPrint("zrpc", "%s: z_shieldcoinbase initialized\n", getId());
|
LogPrint(BCLog::ZRPC, "%s: z_shieldcoinbase initialized\n", getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock UTXOs
|
// Lock UTXOs
|
||||||
|
@ -106,14 +104,6 @@ void AsyncRPCOperation_shieldcoinbase::main() {
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
#ifdef ENABLE_MINING
|
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
GenerateBitcoins(false, NULL, 0);
|
|
||||||
#else
|
|
||||||
GenerateBitcoins(false, 0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
success = main_impl();
|
success = main_impl();
|
||||||
} catch (const UniValue& objError) {
|
} catch (const UniValue& objError) {
|
||||||
|
@ -135,14 +125,6 @@ void AsyncRPCOperation_shieldcoinbase::main() {
|
||||||
set_error_message("unknown error");
|
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();
|
stop_execution_clock();
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
@ -168,9 +150,9 @@ void AsyncRPCOperation_shieldcoinbase::main() {
|
||||||
for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) {
|
for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) {
|
||||||
p.first.hash = txidhash;
|
p.first.hash = txidhash;
|
||||||
if (!db->Put(p.first, p.second)) {
|
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 {
|
} 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();
|
size_t numInputs = inputs_.size();
|
||||||
|
|
||||||
// Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
|
// 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);
|
LOCK(cs_main);
|
||||||
if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
||||||
|
@ -210,7 +192,7 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
CAmount sendAmount = targetAmount - minersFee;
|
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));
|
getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee));
|
||||||
|
|
||||||
// update the transaction with these inputs
|
// update the transaction with these inputs
|
||||||
|
@ -337,7 +319,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
||||||
|
|
||||||
CMutableTransaction mtx(tx_);
|
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(),
|
getId(),
|
||||||
tx_.vjoinsplit.size(),
|
tx_.vjoinsplit.size(),
|
||||||
FormatMoney(info.vpub_old), FormatMoney(info.vpub_new),
|
FormatMoney(info.vpub_old), FormatMoney(info.vpub_new),
|
||||||
|
@ -356,7 +338,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
||||||
uint256 esk; // payment disclosure - secret
|
uint256 esk; // payment disclosure - secret
|
||||||
|
|
||||||
JSDescription jsdesc = JSDescription::Randomized(
|
JSDescription jsdesc = JSDescription::Randomized(
|
||||||
*pzcashParams,
|
pzcashParams.get(),
|
||||||
joinSplitPubKey_,
|
joinSplitPubKey_,
|
||||||
anchor,
|
anchor,
|
||||||
inputs,
|
inputs,
|
||||||
|
@ -369,7 +351,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
||||||
&esk); // parameter expects pointer to esk, so pass in address
|
&esk); // parameter expects pointer to esk, so pass in address
|
||||||
{
|
{
|
||||||
auto verifier = libzcash::ProofVerifier::Strict();
|
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");
|
throw std::runtime_error("error verifying joinsplit");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,7 +394,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
||||||
ss2 << ((unsigned char) 0x00);
|
ss2 << ((unsigned char) 0x00);
|
||||||
ss2 << jsdesc.ephemeralKey;
|
ss2 << jsdesc.ephemeralKey;
|
||||||
ss2 << jsdesc.ciphertexts[0];
|
ss2 << jsdesc.ciphertexts[0];
|
||||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||||
|
|
||||||
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
|
encryptedNote1 = HexStr(ss2.begin(), ss2.end());
|
||||||
}
|
}
|
||||||
|
@ -421,7 +403,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
||||||
ss2 << ((unsigned char) 0x01);
|
ss2 << ((unsigned char) 0x01);
|
||||||
ss2 << jsdesc.ephemeralKey;
|
ss2 << jsdesc.ephemeralKey;
|
||||||
ss2 << jsdesc.ciphertexts[1];
|
ss2 << jsdesc.ciphertexts[1];
|
||||||
ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_);
|
ss2 << jsdesc.h_sig(pzcashParams.get(), joinSplitPubKey_);
|
||||||
|
|
||||||
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
||||||
}
|
}
|
||||||
|
@ -452,7 +434,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
||||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||||
|
|
||||||
CZCPaymentAddress address(zaddr);
|
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
|
// !!! Payment disclosure END
|
||||||
|
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <zcash/JoinSplit.hpp>
|
#include <zcash/JoinSplit.hpp>
|
||||||
#include <zcash/Address.hpp>
|
#include <zcash/Address.hpp>
|
||||||
#include <wallet.h>
|
#include <wallet/wallet.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
|
|
||||||
#include <wallet/paymentdisclosure.h>
|
#include <paymentdisclosure.h>
|
||||||
|
|
||||||
// Default transaction fee if caller does not specify one.
|
// Default transaction fee if caller does not specify one.
|
||||||
#define SHIELD_COINBASE_DEFAULT_MINERS_FEE 10000
|
#define SHIELD_COINBASE_DEFAULT_MINERS_FEE 10000
|
||||||
|
|
|
@ -16,12 +16,12 @@ public:
|
||||||
// Transaction hash
|
// Transaction hash
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
// Index into CTransaction.vjoinsplit
|
// Index into CTransaction.vjoinsplit
|
||||||
size_t js;
|
uint64_t js;
|
||||||
// Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
|
// Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
|
||||||
uint8_t n;
|
uint8_t n;
|
||||||
|
|
||||||
JSOutPoint() { SetNull(); }
|
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;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "uint252.h"
|
#include "uint252.h"
|
||||||
|
|
||||||
#include <boost/array.hpp>
|
#include <array>
|
||||||
|
|
||||||
namespace libzcash {
|
namespace libzcash {
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Zcash.h"
|
#include "Zcash.h"
|
||||||
#include "Address.hpp"
|
#include "Address.hpp"
|
||||||
#include "NoteEncryption.hpp"
|
#include "NoteEncryption.hpp"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace libzcash {
|
namespace libzcash {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue