Merge branch 'danger' into sietch_dynamic
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
# Copyright 2019-2020 The Hush developers
|
||||
|
||||
DIST_SUBDIRS = secp256k1 univalue cryptoconditions
|
||||
|
||||
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(SAN_LDFLAGS) $(HARDENED_LDFLAGS)
|
||||
@@ -27,8 +29,6 @@ BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
|
||||
BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/include
|
||||
BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/src
|
||||
BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/src/asn
|
||||
BITCOIN_INCLUDES += -I$(srcdir)/snark
|
||||
BITCOIN_INCLUDES += -I$(srcdir)/snark/libsnark
|
||||
BITCOIN_INCLUDES += -I$(srcdir)/univalue/include
|
||||
|
||||
if TARGET_WINDOWS
|
||||
@@ -48,16 +48,12 @@ LIBBITCOIN_UTIL=libbitcoin_util.a
|
||||
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
|
||||
LIBSECP256K1=secp256k1/libsecp256k1.la
|
||||
LIBCRYPTOCONDITIONS=cryptoconditions/libcryptoconditions_core.la
|
||||
LIBSNARK=snark/libsnark.a
|
||||
LIBUNIVALUE=univalue/libunivalue.la
|
||||
LIBZCASH=libzcash.a
|
||||
|
||||
if ENABLE_ZMQ
|
||||
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
|
||||
endif
|
||||
if ENABLE_PROTON
|
||||
LIBBITCOIN_PROTON=libbitcoin_proton.a
|
||||
endif
|
||||
if BUILD_BITCOIN_LIBS
|
||||
LIBZCASH_CONSENSUS=libzcashconsensus.la
|
||||
endif
|
||||
@@ -66,28 +62,13 @@ LIBBITCOIN_WALLET=libbitcoin_wallet.a
|
||||
endif
|
||||
|
||||
$(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g "
|
||||
|
||||
LIBSNARK_CXXFLAGS = $(AM_CXXFLAGS) $(PIC_FLAGS) -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1 -fstack-protector-all
|
||||
LIBSNARK_CONFIG_FLAGS = CURVE=ALT_BN128 NO_PROCPS=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT NO_COPY_DEPINST=1 NO_COMPILE_LIBGTEST=1
|
||||
if HAVE_OPENMP
|
||||
LIBSNARK_CONFIG_FLAGS += MULTICORE=1
|
||||
endif
|
||||
if TARGET_DARWIN
|
||||
LIBSNARK_CONFIG_FLAGS += PLATFORM=darwin
|
||||
endif
|
||||
|
||||
$(LIBSNARK): $(wildcard snark/src/*)
|
||||
$(AM_V_at) CC="$(CC)" CXX="$(CXX)" AR="$(AR)" CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64"
|
||||
|
||||
libsnark-tests: $(wildcard snark/src/*)
|
||||
$(AM_V_at) CC="$(CC)" CXX="$(CXX)" AR="$(AR)" CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ check DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64"
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -g "
|
||||
|
||||
$(LIBUNIVALUE): $(wildcard univalue/lib/*)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g "
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -g "
|
||||
|
||||
$(LIBCRYPTOCONDITIONS): $(wildcard cryptoconditions/src/*) $(wildcard cryptoconditions/include/*)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g "
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -g "
|
||||
|
||||
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
|
||||
# But to build the less dependent modules first, we manually select their order here:
|
||||
@@ -105,9 +86,6 @@ endif
|
||||
if ENABLE_ZMQ
|
||||
EXTRA_LIBRARIES += $(LIBBITCOIN_ZMQ)
|
||||
endif
|
||||
if ENABLE_PROTON
|
||||
EXTRA_LIBRARIES += $(LIBBITCOIN_PROTON)
|
||||
endif
|
||||
|
||||
lib_LTLIBRARIES = $(LIBZCASH_CONSENSUS)
|
||||
|
||||
@@ -139,7 +117,7 @@ LIBZCASH_H = \
|
||||
zcash/Zcash.h \
|
||||
zcash/zip32.h
|
||||
|
||||
.PHONY: FORCE collate-libsnark check-symbols check-security
|
||||
.PHONY: FORCE check-symbols check-security
|
||||
# bitcoin core #
|
||||
BITCOIN_CORE_H = \
|
||||
addressindex.h \
|
||||
@@ -199,14 +177,11 @@ BITCOIN_CORE_H = \
|
||||
netbase.h \
|
||||
notaries_staked.h \
|
||||
noui.h \
|
||||
paymentdisclosure.h \
|
||||
paymentdisclosuredb.h \
|
||||
policy/fees.h \
|
||||
pow.h \
|
||||
prevector.h \
|
||||
primitives/block.h \
|
||||
primitives/transaction.h \
|
||||
primitives/nonce.h \
|
||||
protocol.h \
|
||||
pubkey.h \
|
||||
random.h \
|
||||
@@ -248,11 +223,13 @@ BITCOIN_CORE_H = \
|
||||
validationinterface.h \
|
||||
version.h \
|
||||
wallet/asyncrpcoperation_mergetoaddress.h \
|
||||
wallet/asyncrpcoperation_saplingconsolidation.h \
|
||||
wallet/asyncrpcoperation_sendmany.h \
|
||||
wallet/asyncrpcoperation_shieldcoinbase.h \
|
||||
wallet/crypter.h \
|
||||
wallet/db.h \
|
||||
wallet/rpcwallet.h \
|
||||
wallet/rpchushwallet.h \
|
||||
wallet/wallet.h \
|
||||
wallet/wallet_ismine.h \
|
||||
wallet/walletdb.h \
|
||||
@@ -319,8 +296,6 @@ libbitcoin_server_a_SOURCES = \
|
||||
notaries_staked.cpp \
|
||||
noui.cpp \
|
||||
notarisationdb.cpp \
|
||||
paymentdisclosure.cpp \
|
||||
paymentdisclosuredb.cpp \
|
||||
policy/fees.cpp \
|
||||
pow.cpp \
|
||||
rest.cpp \
|
||||
@@ -350,38 +325,27 @@ libbitcoin_zmq_a_SOURCES = \
|
||||
zmq/zmqpublishnotifier.cpp
|
||||
endif
|
||||
|
||||
if ENABLE_PROTON
|
||||
libbitcoin_proton_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||
libbitcoin_proton_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_proton_a_SOURCES = \
|
||||
amqp/amqpabstractnotifier.cpp \
|
||||
amqp/amqpnotificationinterface.cpp \
|
||||
amqp/amqppublishnotifier.cpp
|
||||
endif
|
||||
|
||||
# wallet: zcashd, but only linked when wallet enabled
|
||||
# wallet: komodod, but only linked when wallet enabled
|
||||
libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_wallet_a_SOURCES = \
|
||||
utiltest.cpp \
|
||||
utiltest.h \
|
||||
zcbenchmarks.cpp \
|
||||
zcbenchmarks.h \
|
||||
wallet/asyncrpcoperation_mergetoaddress.cpp \
|
||||
wallet/asyncrpcoperation_saplingconsolidation.cpp \
|
||||
wallet/asyncrpcoperation_sendmany.cpp \
|
||||
wallet/asyncrpcoperation_shieldcoinbase.cpp \
|
||||
wallet/crypter.cpp \
|
||||
wallet/db.cpp \
|
||||
paymentdisclosure.cpp \
|
||||
paymentdisclosuredb.cpp \
|
||||
zcash/Note.cpp \
|
||||
transaction_builder.cpp \
|
||||
wallet/rpcdisclosure.cpp \
|
||||
wallet/rpcdump.cpp \
|
||||
cc/CCtokens.cpp \
|
||||
cc/CCassetsCore.cpp \
|
||||
cc/CCassetstx.cpp \
|
||||
cc/CCtx.cpp \
|
||||
wallet/rpcwallet.cpp \
|
||||
wallet/rpchushwallet.cpp \
|
||||
wallet/wallet.cpp \
|
||||
wallet/wallet_ismine.cpp \
|
||||
wallet/walletdb.cpp \
|
||||
@@ -450,7 +414,6 @@ libbitcoin_common_a_SOURCES = \
|
||||
metrics.cpp \
|
||||
primitives/block.cpp \
|
||||
primitives/transaction.cpp \
|
||||
primitives/nonce.cpp \
|
||||
protocol.cpp \
|
||||
pubkey.cpp \
|
||||
scheduler.cpp \
|
||||
@@ -510,7 +473,7 @@ libbitcoin_cli_a_SOURCES = \
|
||||
nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
|
||||
#
|
||||
|
||||
# bitcoind binary #
|
||||
# komodod binary #
|
||||
komodod_SOURCES = bitcoind.cpp
|
||||
komodod_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
komodod_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
@@ -526,10 +489,8 @@ komodod_LDADD = \
|
||||
$(LIBUNIVALUE) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_ZMQ) \
|
||||
$(LIBBITCOIN_PROTON) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBZCASH) \
|
||||
$(LIBSNARK) \
|
||||
$(LIBLEVELDB) \
|
||||
$(LIBMEMENV) \
|
||||
$(LIBSECP256K1) \
|
||||
@@ -547,7 +508,6 @@ komodod_LDADD += \
|
||||
$(EVENT_PTHREADS_LIBS) \
|
||||
$(EVENT_LIBS) \
|
||||
$(ZMQ_LIBS) \
|
||||
$(PROTON_LIBS) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBZCASH_LIBS)
|
||||
|
||||
@@ -561,16 +521,12 @@ if TARGET_LINUX
|
||||
komodod_LDADD += libcc.so $(LIBSECP256K1)
|
||||
endif
|
||||
|
||||
if ENABLE_PROTON
|
||||
komodod_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS)
|
||||
endif
|
||||
|
||||
# [+] Decker: use static linking for libstdc++.6.dylib, libgomp.1.dylib, libgcc_s.1.dylib
|
||||
if TARGET_DARWIN
|
||||
komodod_LDFLAGS += -static-libgcc
|
||||
endif
|
||||
|
||||
# bitcoin-cli binary #
|
||||
# komodo-cli binary #
|
||||
komodo_cli_SOURCES = bitcoin-cli.cpp
|
||||
komodo_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS)
|
||||
komodo_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
@@ -614,12 +570,11 @@ wallet_utility_LDADD = \
|
||||
$(BDB_LIBS) \
|
||||
$(CRYPTO_LIBS) \
|
||||
$(LIBZCASH) \
|
||||
$(LIBSNARK) \
|
||||
$(LIBZCASH_LIBS)\
|
||||
$(LIBCRYPTOCONDITIONS)
|
||||
endif
|
||||
|
||||
# zcash-tx binary #
|
||||
# komodo-tx binary #
|
||||
komodo_tx_SOURCES = komodo-tx.cpp
|
||||
komodo_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
komodo_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
@@ -629,20 +584,17 @@ if TARGET_WINDOWS
|
||||
komodo_tx_SOURCES += bitcoin-tx-res.rc
|
||||
endif
|
||||
|
||||
# FIXME: Is libzcash needed for hush-tx ?
|
||||
komodo_tx_LDADD = \
|
||||
$(LIBUNIVALUE) \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBSECP256K1) \
|
||||
$(LIBZCASH) \
|
||||
$(LIBSNARK) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBZCASH_LIBS) \
|
||||
$(LIBCRYPTOCONDITIONS)
|
||||
|
||||
komodo_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
|
||||
#
|
||||
|
||||
# zcash protocol primitives #
|
||||
libzcash_a_SOURCES = \
|
||||
@@ -654,15 +606,9 @@ libzcash_a_SOURCES = \
|
||||
zcash/Note.cpp \
|
||||
zcash/prf.cpp \
|
||||
zcash/util.cpp \
|
||||
zcash/zip32.cpp \
|
||||
zcash/circuit/commitment.tcc \
|
||||
zcash/circuit/gadget.tcc \
|
||||
zcash/circuit/merkle.tcc \
|
||||
zcash/circuit/note.tcc \
|
||||
zcash/circuit/prfs.tcc \
|
||||
zcash/circuit/utils.tcc
|
||||
zcash/zip32.cpp
|
||||
|
||||
libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) $(HARDENED_CXXFLAGS) $(HARDENED_LDFLAGS) -pipe $(SAN_LDFLAGS) -O1 -g -Wstack-protector $(SAN_CXXFLAGS) -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES)
|
||||
libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) $(HARDENED_CXXFLAGS) $(HARDENED_LDFLAGS) -pipe $(SAN_LDFLAGS) -O1 -g -Wstack-protector $(SAN_CXXFLAGS) -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES)
|
||||
|
||||
#libzcash_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
#libzcash_a_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
@@ -684,7 +630,6 @@ libzcashconsensus_la_SOURCES = \
|
||||
crypto/sha512.cpp \
|
||||
hash.cpp \
|
||||
primitives/transaction.cpp \
|
||||
primitives/nonce.cpp \
|
||||
pubkey.cpp \
|
||||
script/zcashconsensus.cpp \
|
||||
script/interpreter.cpp \
|
||||
@@ -708,12 +653,11 @@ CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno */*.gcno wal
|
||||
|
||||
DISTCLEANFILES = obj/build.h
|
||||
|
||||
EXTRA_DIST = leveldb snark
|
||||
EXTRA_DIST = leveldb
|
||||
|
||||
clean-local:
|
||||
-$(MAKE) -C leveldb clean
|
||||
-$(MAKE) -C secp256k1 clean
|
||||
-$(MAKE) -C snark clean
|
||||
-$(MAKE) -C univalue clean
|
||||
rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno
|
||||
-rm -f config.h
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
|
||||
# Copyright (c) 2019-2020 Hush developers
|
||||
# Released under the GPLv3
|
||||
TESTS += komodo-gtest
|
||||
bin_PROGRAMS += komodo-gtest
|
||||
|
||||
@@ -9,7 +10,6 @@ komodo_gtest_SOURCES = \
|
||||
gtest/test_checktransaction.cpp \
|
||||
gtest/json_test_vectors.cpp \
|
||||
gtest/json_test_vectors.h \
|
||||
# gtest/test_foundersreward.cpp \
|
||||
gtest/test_wallet_zkeys.cpp \
|
||||
# These tests are order-dependent, because they
|
||||
# depend on global state (see #1539)
|
||||
@@ -63,12 +63,7 @@ if ENABLE_WALLET
|
||||
komodo_gtest_LDADD += $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
|
||||
komodo_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBSNARK) $(LIBZCASH_LIBS)
|
||||
|
||||
if ENABLE_PROTON
|
||||
komodo_gtest_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS)
|
||||
endif
|
||||
|
||||
komodo_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS)
|
||||
|
||||
komodo_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
|
||||
|
||||
|
||||
@@ -123,17 +123,13 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C
|
||||
$(LIBLEVELDB) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
|
||||
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
|
||||
test_test_bitcoin_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(LIBZCASH) $(LIBSNARK) $(LIBZCASH_LIBS)
|
||||
test_test_bitcoin_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS)
|
||||
test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
|
||||
|
||||
if ENABLE_ZMQ
|
||||
test_test_bitcoin_LDADD += $(ZMQ_LIBS)
|
||||
endif
|
||||
|
||||
if ENABLE_PROTON
|
||||
test_test_bitcoin_LDADD += $(PROTON_LIBS)
|
||||
endif
|
||||
|
||||
nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)
|
||||
|
||||
$(BITCOIN_TESTS): $(GENERATED_TEST_FILES)
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
noinst_PROGRAMS += \
|
||||
zcash/GenerateParams \
|
||||
zcash/CreateJoinSplit
|
||||
|
||||
# tool for generating our public parameters
|
||||
zcash_GenerateParams_SOURCES = zcash/GenerateParams.cpp
|
||||
zcash_GenerateParams_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
zcash_GenerateParams_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
zcash_GenerateParams_LDADD = \
|
||||
$(BOOST_LIBS) \
|
||||
$(LIBZCASH) \
|
||||
$(LIBSNARK) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBZCASH_LIBS)
|
||||
|
||||
# tool for profiling the creation of joinsplits
|
||||
zcash_CreateJoinSplit_SOURCES = zcash/CreateJoinSplit.cpp
|
||||
zcash_CreateJoinSplit_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
zcash_CreateJoinSplit_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
zcash_CreateJoinSplit_LDADD = \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBZCASH) \
|
||||
$(LIBSNARK) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(BOOST_LIBS) \
|
||||
$(LIBZCASH_LIBS) \
|
||||
$(LIBCRYPTOCONDITIONS) \
|
||||
$(LIBSECP256K1)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright (c) 2012 Pieter Wuille
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -268,7 +269,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
|
||||
|
||||
if (pinfo) {
|
||||
// periodically update nTime
|
||||
bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
|
||||
bool fCurrentlyOnline = (GetTime() - addr.nTime < 24 * 60 * 60);
|
||||
int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
|
||||
if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty))
|
||||
pinfo->nTime = std::max((int64_t)0, addr.nTime - nTimePenalty);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012 Pieter Wuille
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
@@ -112,10 +113,10 @@ public:
|
||||
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
|
||||
|
||||
//! Determine whether the statistics about this entry are bad enough so that it can just be deleted
|
||||
bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
|
||||
bool IsTerrible(int64_t nNow = GetTime()) const;
|
||||
|
||||
//! Calculate the relative chance this entry should be given when selecting nodes to connect to
|
||||
double GetChance(int64_t nNow = GetAdjustedTime()) const;
|
||||
double GetChance(int64_t nNow = GetTime()) const;
|
||||
|
||||
};
|
||||
|
||||
@@ -530,7 +531,7 @@ public:
|
||||
}
|
||||
|
||||
//! Mark an entry as accessible.
|
||||
void Good(const CService &addr, int64_t nTime = GetAdjustedTime())
|
||||
void Good(const CService &addr, int64_t nTime = GetTime())
|
||||
{
|
||||
{
|
||||
LOCK(cs);
|
||||
@@ -541,7 +542,7 @@ public:
|
||||
}
|
||||
|
||||
//! Mark an entry as connection attempted to.
|
||||
void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime())
|
||||
void Attempt(const CService &addr, int64_t nTime = GetTime())
|
||||
{
|
||||
{
|
||||
LOCK(cs);
|
||||
@@ -580,7 +581,7 @@ public:
|
||||
}
|
||||
|
||||
//! Mark an entry as currently-connected-to.
|
||||
void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
|
||||
void Connected(const CService &addr, int64_t nTime = GetTime())
|
||||
{
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
@@ -117,7 +118,7 @@ uint256 CAlert::GetHash() const
|
||||
|
||||
bool CAlert::IsInEffect() const
|
||||
{
|
||||
return (GetAdjustedTime() < nExpiration);
|
||||
return (GetTime() < nExpiration);
|
||||
}
|
||||
|
||||
bool CAlert::Cancels(const CAlert& alert) const
|
||||
@@ -152,7 +153,7 @@ bool CAlert::RelayTo(CNode* pnode) const
|
||||
{
|
||||
if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
|
||||
AppliesToMe() ||
|
||||
GetAdjustedTime() < nRelayUntil)
|
||||
GetTime() < nRelayUntil)
|
||||
{
|
||||
pnode->PushMessage("alert", *this);
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "amqpabstractnotifier.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
AMQPAbstractNotifier::~AMQPAbstractNotifier()
|
||||
{
|
||||
}
|
||||
|
||||
bool AMQPAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AMQPAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H
|
||||
#define ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H
|
||||
|
||||
#include "amqpconfig.h"
|
||||
|
||||
class CBlockIndex;
|
||||
class AMQPAbstractNotifier;
|
||||
|
||||
typedef AMQPAbstractNotifier* (*AMQPNotifierFactory)();
|
||||
|
||||
class AMQPAbstractNotifier
|
||||
{
|
||||
public:
|
||||
AMQPAbstractNotifier() { }
|
||||
virtual ~AMQPAbstractNotifier();
|
||||
|
||||
template <typename T>
|
||||
static AMQPAbstractNotifier* Create()
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
|
||||
std::string GetType() const { return type; }
|
||||
void SetType(const std::string &t) { type = t; }
|
||||
std::string GetAddress() const { return address; }
|
||||
void SetAddress(const std::string &a) { address = a; }
|
||||
|
||||
virtual bool Initialize() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual bool NotifyBlock(const CBlockIndex *pindex);
|
||||
virtual bool NotifyTransaction(const CTransaction &transaction);
|
||||
|
||||
protected:
|
||||
std::string type;
|
||||
std::string address;
|
||||
};
|
||||
|
||||
#endif // ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef ZCASH_AMQP_AMQPCONFIG_H
|
||||
#define ZCASH_AMQP_AMQPCONFIG_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/bitcoin-config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
|
||||
#if ENABLE_PROTON
|
||||
#include <proton/connection.hpp>
|
||||
#include <proton/connection_options.hpp>
|
||||
#include <proton/container.hpp>
|
||||
#include <proton/default_container.hpp>
|
||||
#include <proton/message.hpp>
|
||||
#include <proton/message_id.hpp>
|
||||
#include <proton/messaging_handler.hpp>
|
||||
#include <proton/thread_safe.hpp>
|
||||
#include <proton/tracker.hpp>
|
||||
#include <proton/transport.hpp>
|
||||
#include <proton/types.hpp>
|
||||
#include <proton/url.hpp>
|
||||
#endif
|
||||
|
||||
#include "primitives/block.h"
|
||||
#include "primitives/transaction.h"
|
||||
|
||||
#endif // ZCASH_AMQP_AMQPCONFIG_H
|
||||
@@ -1,136 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "amqpnotificationinterface.h"
|
||||
#include "amqppublishnotifier.h"
|
||||
|
||||
#include "version.h"
|
||||
#include "main.h"
|
||||
#include "streams.h"
|
||||
#include "util.h"
|
||||
|
||||
// AMQP 1.0 Support
|
||||
//
|
||||
// The boost::signals2 signals and slot system is thread safe, so CValidationInterface listeners
|
||||
// can be invoked from any thread.
|
||||
//
|
||||
// Currently signals are fired from main.cpp so the callbacks should be invoked on the same thread.
|
||||
// It should be safe to share objects responsible for sending, as they should not be run concurrently
|
||||
// across different threads.
|
||||
//
|
||||
// Developers should be mindful of where notifications are fired to avoid potential race conditions.
|
||||
// For example, different signals targeting the same address could be fired from different threads
|
||||
// in different parts of the system around the same time.
|
||||
//
|
||||
// Like the ZMQ notification interface, if a notifier fails to send a message, the notifier is shut down.
|
||||
//
|
||||
|
||||
AMQPNotificationInterface::AMQPNotificationInterface()
|
||||
{
|
||||
}
|
||||
|
||||
AMQPNotificationInterface::~AMQPNotificationInterface()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
for (std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
AMQPNotificationInterface* AMQPNotificationInterface::CreateWithArguments(const std::map<std::string, std::string> &args)
|
||||
{
|
||||
AMQPNotificationInterface* notificationInterface = nullptr;
|
||||
std::map<std::string, AMQPNotifierFactory> factories;
|
||||
std::list<AMQPAbstractNotifier*> notifiers;
|
||||
|
||||
factories["pubhashblock"] = AMQPAbstractNotifier::Create<AMQPPublishHashBlockNotifier>;
|
||||
factories["pubhashtx"] = AMQPAbstractNotifier::Create<AMQPPublishHashTransactionNotifier>;
|
||||
factories["pubrawblock"] = AMQPAbstractNotifier::Create<AMQPPublishRawBlockNotifier>;
|
||||
factories["pubrawtx"] = AMQPAbstractNotifier::Create<AMQPPublishRawTransactionNotifier>;
|
||||
|
||||
for (std::map<std::string, AMQPNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i) {
|
||||
std::map<std::string, std::string>::const_iterator j = args.find("-amqp" + i->first);
|
||||
if (j!=args.end()) {
|
||||
AMQPNotifierFactory factory = i->second;
|
||||
std::string address = j->second;
|
||||
AMQPAbstractNotifier *notifier = factory();
|
||||
notifier->SetType(i->first);
|
||||
notifier->SetAddress(address);
|
||||
notifiers.push_back(notifier);
|
||||
}
|
||||
}
|
||||
|
||||
if (!notifiers.empty()) {
|
||||
notificationInterface = new AMQPNotificationInterface();
|
||||
notificationInterface->notifiers = notifiers;
|
||||
|
||||
if (!notificationInterface->Initialize()) {
|
||||
delete notificationInterface;
|
||||
notificationInterface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return notificationInterface;
|
||||
}
|
||||
|
||||
// Called at startup to conditionally set up
|
||||
bool AMQPNotificationInterface::Initialize()
|
||||
{
|
||||
LogPrint("amqp", "amqp: Initialize notification interface\n");
|
||||
|
||||
std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin();
|
||||
for (; i != notifiers.end(); ++i) {
|
||||
AMQPAbstractNotifier *notifier = *i;
|
||||
if (notifier->Initialize()) {
|
||||
LogPrint("amqp", "amqp: Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress());
|
||||
} else {
|
||||
LogPrint("amqp", "amqp: Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i != notifiers.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called during shutdown sequence
|
||||
void AMQPNotificationInterface::Shutdown()
|
||||
{
|
||||
LogPrint("amqp", "amqp: Shutdown notification interface\n");
|
||||
|
||||
for (std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); ++i) {
|
||||
AMQPAbstractNotifier *notifier = *i;
|
||||
notifier->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void AMQPNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex)
|
||||
{
|
||||
for (std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); ) {
|
||||
AMQPAbstractNotifier *notifier = *i;
|
||||
if (notifier->NotifyBlock(pindex)) {
|
||||
i++;
|
||||
} else {
|
||||
notifier->Shutdown();
|
||||
i = notifiers.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMQPNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock)
|
||||
{
|
||||
for (std::list<AMQPAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); ) {
|
||||
AMQPAbstractNotifier *notifier = *i;
|
||||
if (notifier->NotifyTransaction(tx)) {
|
||||
i++;
|
||||
} else {
|
||||
notifier->Shutdown();
|
||||
i = notifiers.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H
|
||||
#define ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H
|
||||
|
||||
#include "validationinterface.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class CBlockIndex;
|
||||
class AMQPAbstractNotifier;
|
||||
|
||||
class AMQPNotificationInterface : public CValidationInterface
|
||||
{
|
||||
public:
|
||||
virtual ~AMQPNotificationInterface();
|
||||
|
||||
static AMQPNotificationInterface* CreateWithArguments(const std::map<std::string, std::string> &args);
|
||||
|
||||
protected:
|
||||
bool Initialize();
|
||||
void Shutdown();
|
||||
|
||||
// CValidationInterface
|
||||
void SyncTransaction(const CTransaction &tx, const CBlock *pblock);
|
||||
void UpdatedBlockTip(const CBlockIndex *pindex);
|
||||
|
||||
private:
|
||||
AMQPNotificationInterface();
|
||||
|
||||
std::list<AMQPAbstractNotifier*> notifiers;
|
||||
};
|
||||
|
||||
#endif // ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H
|
||||
@@ -1,177 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "amqppublishnotifier.h"
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "amqpsender.h"
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
static std::multimap<std::string, AMQPAbstractPublishNotifier*> mapPublishNotifiers;
|
||||
|
||||
static const char *MSG_HASHBLOCK = "hashblock";
|
||||
static const char *MSG_HASHTX = "hashtx";
|
||||
static const char *MSG_RAWBLOCK = "rawblock";
|
||||
static const char *MSG_RAWTX = "rawtx";
|
||||
|
||||
// Invoke this method from a new thread to run the proton container event loop.
|
||||
void AMQPAbstractPublishNotifier::SpawnProtonContainer()
|
||||
{
|
||||
try {
|
||||
proton::default_container(*handler_).run();
|
||||
}
|
||||
catch (const proton::error_condition &e) {
|
||||
LogPrint("amqp", "amqp: container error: %s\n", e.what());
|
||||
}
|
||||
catch (const std::runtime_error &e) {
|
||||
LogPrint("amqp", "amqp: runtime error: %s\n", e.what());
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
LogPrint("amqp", "amqp: exception: %s\n", e.what());
|
||||
}
|
||||
catch (...) {
|
||||
LogPrint("amqp", "amqp: unknown error\n");
|
||||
}
|
||||
handler_->terminate();
|
||||
}
|
||||
|
||||
bool AMQPAbstractPublishNotifier::Initialize()
|
||||
{
|
||||
std::multimap<std::string, AMQPAbstractPublishNotifier*>::iterator i = mapPublishNotifiers.find(address);
|
||||
|
||||
if (i == mapPublishNotifiers.end()) {
|
||||
try {
|
||||
handler_ = std::make_shared<AMQPSender>(address);
|
||||
thread_ = std::make_shared<std::thread>(&AMQPAbstractPublishNotifier::SpawnProtonContainer, this);
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
LogPrint("amqp", "amqp: initialization error: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
mapPublishNotifiers.insert(std::make_pair(address, this));
|
||||
} else {
|
||||
// copy the shared ptrs to the message handler and the thread where the proton container is running
|
||||
handler_ = i->second->handler_;
|
||||
thread_ = i->second->thread_;
|
||||
mapPublishNotifiers.insert(std::make_pair(address, this));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void AMQPAbstractPublishNotifier::Shutdown()
|
||||
{
|
||||
LogPrint("amqp", "amqp: Shutdown notifier %s at %s\n", GetType(), GetAddress());
|
||||
|
||||
int count = mapPublishNotifiers.count(address);
|
||||
|
||||
// remove this notifier from the list of publishers using this address
|
||||
typedef std::multimap<std::string, AMQPAbstractPublishNotifier*>::iterator iterator;
|
||||
std::pair<iterator, iterator> iterpair = mapPublishNotifiers.equal_range(address);
|
||||
|
||||
for (iterator it = iterpair.first; it != iterpair.second; ++it) {
|
||||
if (it->second == this) {
|
||||
mapPublishNotifiers.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// terminate the connection if this is the last publisher using this address
|
||||
if (count == 1) {
|
||||
handler_->terminate();
|
||||
if (thread_.get() != nullptr) {
|
||||
if (thread_->joinable()) {
|
||||
thread_->join();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool AMQPAbstractPublishNotifier::SendMessage(const char *command, const void* data, size_t size)
|
||||
{
|
||||
try {
|
||||
proton::binary content;
|
||||
const char *p = (const char *)data;
|
||||
content.assign(p, p + size);
|
||||
|
||||
proton::message message(content);
|
||||
message.subject(std::string(command));
|
||||
proton::message::property_map & props = message.properties();
|
||||
props.put("x-opt-sequence-number", sequence_);
|
||||
handler_->publish(message);
|
||||
|
||||
} catch (proton::error_condition &e) {
|
||||
LogPrint("amqp", "amqp: error : %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
catch (const std::runtime_error &e) {
|
||||
LogPrint("amqp", "amqp: runtime error: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
LogPrint("amqp", "amqp: exception: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
catch (...) {
|
||||
LogPrint("amqp", "amqp: unknown error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
sequence_++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AMQPPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
|
||||
{
|
||||
uint256 hash = pindex->GetBlockHash();
|
||||
LogPrint("amqp", "amqp: Publish hashblock %s\n", hash.GetHex());
|
||||
char data[32];
|
||||
for (unsigned int i = 0; i < 32; i++)
|
||||
data[31 - i] = hash.begin()[i];
|
||||
return SendMessage(MSG_HASHBLOCK, data, 32);
|
||||
}
|
||||
|
||||
bool AMQPPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
|
||||
{
|
||||
uint256 hash = transaction.GetHash();
|
||||
LogPrint("amqp", "amqp: Publish hashtx %s\n", hash.GetHex());
|
||||
char data[32];
|
||||
for (unsigned int i = 0; i < 32; i++)
|
||||
data[31 - i] = hash.begin()[i];
|
||||
return SendMessage(MSG_HASHTX, data, 32);
|
||||
}
|
||||
|
||||
bool AMQPPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
|
||||
{
|
||||
LogPrint("amqp", "amqp: Publish rawblock %s\n", pindex->GetBlockHash().GetHex());
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
{
|
||||
LOCK(cs_main);
|
||||
CBlock block;
|
||||
if(!ReadBlockFromDisk(block, pindex)) {
|
||||
LogPrint("amqp", "amqp: Can't read block from disk");
|
||||
return false;
|
||||
}
|
||||
|
||||
ss << block;
|
||||
}
|
||||
|
||||
return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size());
|
||||
}
|
||||
|
||||
bool AMQPPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
|
||||
{
|
||||
uint256 hash = transaction.GetHash();
|
||||
LogPrint("amqp", "amqp: Publish rawtx %s\n", hash.GetHex());
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << transaction;
|
||||
return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size());
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H
|
||||
#define ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H
|
||||
|
||||
#include "amqpabstractnotifier.h"
|
||||
#include "amqpconfig.h"
|
||||
#include "amqpsender.h"
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
class CBlockIndex;
|
||||
|
||||
class AMQPAbstractPublishNotifier : public AMQPAbstractNotifier
|
||||
{
|
||||
private:
|
||||
uint64_t sequence_; // memory only, per notifier instance: upcounting message sequence number
|
||||
|
||||
std::shared_ptr<std::thread> thread_; // proton container thread, may be shared between notifiers
|
||||
std::shared_ptr<AMQPSender> handler_; // proton container message handler, may be shared between notifiers
|
||||
|
||||
public:
|
||||
bool SendMessage(const char *command, const void* data, size_t size);
|
||||
bool Initialize();
|
||||
void Shutdown();
|
||||
void SpawnProtonContainer();
|
||||
};
|
||||
|
||||
class AMQPPublishHashBlockNotifier : public AMQPAbstractPublishNotifier
|
||||
{
|
||||
public:
|
||||
bool NotifyBlock(const CBlockIndex *pindex);
|
||||
};
|
||||
|
||||
class AMQPPublishHashTransactionNotifier : public AMQPAbstractPublishNotifier
|
||||
{
|
||||
public:
|
||||
bool NotifyTransaction(const CTransaction &transaction);
|
||||
};
|
||||
|
||||
class AMQPPublishRawBlockNotifier : public AMQPAbstractPublishNotifier
|
||||
{
|
||||
public:
|
||||
bool NotifyBlock(const CBlockIndex *pindex);
|
||||
};
|
||||
|
||||
class AMQPPublishRawTransactionNotifier : public AMQPAbstractPublishNotifier
|
||||
{
|
||||
public:
|
||||
bool NotifyTransaction(const CTransaction &transaction);
|
||||
};
|
||||
|
||||
#endif // ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H
|
||||
@@ -1,115 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef ZCASH_AMQP_AMQPSENDER_H
|
||||
#define ZCASH_AMQP_AMQPSENDER_H
|
||||
|
||||
#include "amqpconfig.h"
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
|
||||
class AMQPSender : public proton::messaging_handler {
|
||||
private:
|
||||
std::deque<proton::message> messages_;
|
||||
proton::url url_;
|
||||
proton::connection conn_;
|
||||
proton::sender sender_;
|
||||
std::mutex lock_;
|
||||
std::atomic<bool> terminated_ = {false};
|
||||
|
||||
public:
|
||||
|
||||
AMQPSender(const std::string& url) : url_(url) {}
|
||||
|
||||
// Callback to initialize the container when run() is invoked
|
||||
void on_container_start(proton::container& c) override {
|
||||
proton::duration t(10000); // milliseconds
|
||||
proton::connection_options opts = proton::connection_options().idle_timeout(t);
|
||||
conn_ = c.connect(url_, opts);
|
||||
sender_ = conn_.open_sender(url_.path());
|
||||
}
|
||||
|
||||
// Remote end signals when the local end can send (i.e. has credit)
|
||||
void on_sendable(proton::sender &s) override {
|
||||
dispatch();
|
||||
}
|
||||
|
||||
// Publish message by adding to queue and trying to dispatch it
|
||||
void publish(const proton::message &m) {
|
||||
add_message(m);
|
||||
dispatch();
|
||||
}
|
||||
|
||||
// Add message to queue
|
||||
void add_message(const proton::message &m) {
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
messages_.push_back(m);
|
||||
}
|
||||
|
||||
// Send messages in queue
|
||||
void dispatch() {
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
|
||||
if (isTerminated()) {
|
||||
throw std::runtime_error("amqp connection was terminated");
|
||||
}
|
||||
|
||||
if (!conn_.active()) {
|
||||
throw std::runtime_error("amqp connection is not active");
|
||||
}
|
||||
|
||||
while (messages_.size() > 0) {
|
||||
if (sender_.credit()) {
|
||||
const proton::message& m = messages_.front();
|
||||
sender_.send(m);
|
||||
messages_.pop_front();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close connection to remote end. Container event-loop, by default, will auto-stop.
|
||||
void terminate() {
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
conn_.close();
|
||||
terminated_.store(true);
|
||||
}
|
||||
|
||||
bool isTerminated() const {
|
||||
return terminated_.load();
|
||||
}
|
||||
|
||||
void on_transport_error(proton::transport &t) override {
|
||||
t.connection().close();
|
||||
throw t.error();
|
||||
}
|
||||
|
||||
void on_connection_error(proton::connection &c) override {
|
||||
c.close();
|
||||
throw c.error();
|
||||
}
|
||||
|
||||
void on_session_error(proton::session &s) override {
|
||||
s.connection().close();
|
||||
throw s.error();
|
||||
}
|
||||
|
||||
void on_receiver_error(proton::receiver &r) override {
|
||||
r.connection().close();
|
||||
throw r.error();
|
||||
}
|
||||
|
||||
void on_sender_error(proton::sender &s) override {
|
||||
s.connection().close();
|
||||
throw s.error();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //ZCASH_AMQP_AMQPSENDER_H
|
||||
@@ -193,9 +193,10 @@ unsigned int base_uint<BITS>::bits() const
|
||||
{
|
||||
for (int pos = WIDTH - 1; pos >= 0; pos--) {
|
||||
if (pn[pos]) {
|
||||
for (int bits = 31; bits > 0; bits--) {
|
||||
if (pn[pos] & 1 << bits)
|
||||
for (size_t bits = 31; bits > 0; bits--) {
|
||||
if (pn[pos] & (1U << bits)) {
|
||||
return 32 * pos + bits + 1;
|
||||
}
|
||||
}
|
||||
return 32 * pos + 1;
|
||||
}
|
||||
|
||||
5
src/cc/Makefile_custom
Executable file → Normal file
5
src/cc/Makefile_custom
Executable file → Normal file
@@ -2,6 +2,7 @@ SHELL = /bin/sh
|
||||
CC = gcc
|
||||
CC_DARWIN = g++-8
|
||||
CC_WIN = x86_64-w64-mingw32-gcc-posix
|
||||
CC_AARCH64 = aarch64-linux-gnu-g++
|
||||
CFLAGS_DARWIN = -DBUILD_CUSTOMCC -std=c++11 -arch x86_64 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -Wl,-undefined -Wl,dynamic_lookup -Wno-write-strings -shared -dynamiclib
|
||||
CFLAGS = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared
|
||||
CFLAGS_WIN = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/x86_64-w64-mingw32/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared
|
||||
@@ -28,6 +29,10 @@ else ifeq ($(HOST),x86_64-w64-mingw32)
|
||||
$(CC_WIN) $(CFLAGS_WIN) $(DEBUGFLAGS) -o $(TARGET_WIN) -c $(SOURCES)
|
||||
cp $(TARGET_WIN) ../libcc.dll
|
||||
#else ifeq ($(WIN_HOST),True) - todo: pass ENV var from build.sh if WIN host
|
||||
else ifeq ($(HOST),aarch64-linux-gnu)
|
||||
$(info LINUX ARM 64bit )
|
||||
$(CC_AARCH64) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) -c $(SOURCES)
|
||||
cp $(TARGET) ../libcc.so
|
||||
else
|
||||
$(info LINUX)
|
||||
$(CC) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) -c $(SOURCES)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright © 2019-2020 The Hush Developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# Copyright 2020 The Hush Developers
|
||||
# just type make to compile all dapps
|
||||
all: zmigrate oraclefeed
|
||||
|
||||
subatomic:
|
||||
$(CC) subatomic.c -o subatomic -lm
|
||||
|
||||
zmigrate:
|
||||
$(CC) zmigrate.c -o zmigrate -lm
|
||||
|
||||
@@ -9,3 +13,4 @@ oraclefeed:
|
||||
|
||||
clean:
|
||||
rm zmigrate oraclefeed
|
||||
|
||||
|
||||
1599
src/cc/dapps/dappinc.h
Normal file
1599
src/cc/dapps/dappinc.h
Normal file
File diff suppressed because it is too large
Load Diff
1429
src/cc/dapps/subatomic.c
Normal file
1429
src/cc/dapps/subatomic.c
Normal file
File diff suppressed because it is too large
Load Diff
27
src/cc/dapps/subatomic.json
Normal file
27
src/cc/dapps/subatomic.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"authorized": [
|
||||
{"chmex":"030754bffcf6dfcb34a20c486ff5a5be5546b9cc16fba9692165272b3f8e98c4af" },
|
||||
{"SHossain":"03c8657bd57b6ceb14514a10e99fe8a0cec5a9bc24592df7f66f050e670e4f6bac" },
|
||||
{"satinder":"03732f8ef851ff234c74d0df575c2c5b159e2bab3faca4ec52b3f217d5cda5361d" },
|
||||
{"ml777":"02453d028c74cb9551e1aaf35113383b6ecbd9f06ff23a4ab1a953429b9763e345" },
|
||||
{"tonylhub":"0218e0f435d4544404c25a7759b7f7174d821215085ef936218c5569d975af468b" },
|
||||
{"gthub":"036c7de9a5090fbad78b9eea41549ccacc07bd0e9e7f8d290c88f470f3569e1a35" },
|
||||
{"zkTrader":"026c6b0b35ec0adc2f8a5c648da1fce634f798c69d5e9fe518400447e88398b830" },
|
||||
{"nutellalicka":"03aee08860e0340f0f490a3ef3718d6676882f2d63d4f536dfebb1d348b82c79ee" },
|
||||
{"gcharang":"02d3431950c2f0f9654217b6ce3d44468d3a9ca7255741767fdeee7c5ec6b47567" },
|
||||
{"jl777":"02b27de3ee5335518b06f69f4fbabb029cfc737613b100996841d5532b324a5a61" }
|
||||
],
|
||||
"tokens":[
|
||||
{"RICK.demo":"2b1feef719ecb526b07416dd432bce603ac6dc8bfe794cddf105cb52f6aae3cd"}
|
||||
],
|
||||
"files":[
|
||||
{"filename":"hushd","prices":[{"HUSH":0.1}, {"PIRATE":1}]}
|
||||
],
|
||||
"externalcoins":[
|
||||
{ "BTC":"bitcoin-cli" },
|
||||
{ "KMD":"komodod-cli" },
|
||||
{ "CHIPS":"chips-cli" },
|
||||
{ "PIRATE":"pirate-cli" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
if make -f Makefile_custom "$@"; then
|
||||
if HOST="$HOST" make -B -f Makefile_custom "$@"; then
|
||||
echo CUSTOMCC BUILD SUCCESSFUL
|
||||
else
|
||||
echo CUSTOMCC BUILD FAILED
|
||||
|
||||
15
src/chain.h
15
src/chain.h
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -276,9 +276,12 @@ public:
|
||||
//! inputs and outputs.
|
||||
int64_t nShieldedTx;
|
||||
|
||||
//! (memory only) Number of shielded outputs in the block up to and including this block.
|
||||
//! (memory only) Number of shielded outputs
|
||||
int64_t nShieldedOutputs;
|
||||
|
||||
//! (memory only) Number of shielded spends
|
||||
int64_t nShieldedSpends;
|
||||
|
||||
//! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined
|
||||
//! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent
|
||||
// inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc...
|
||||
@@ -332,6 +335,9 @@ public:
|
||||
//! (memory only) Number of shielded outputs in the chain up to and including this block.
|
||||
int64_t nChainShieldedOutputs;
|
||||
|
||||
//! (memory only) Number of shielded spends in the chain up to and including this block.
|
||||
int64_t nChainShieldedSpends;
|
||||
|
||||
//! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined
|
||||
//! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent
|
||||
// inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc...
|
||||
@@ -429,18 +435,20 @@ public:
|
||||
nChainNotarizations = 0;
|
||||
nChainFullyShieldedTx = 0;
|
||||
nChainShieldedOutputs = 0;
|
||||
nChainShieldedSpends = 0;
|
||||
nChainShieldedPayments = 0;
|
||||
nChainShieldingPayments = 0;
|
||||
nChainDeshieldingPayments = 0;
|
||||
nChainFullyShieldedPayments = 0;
|
||||
|
||||
// Shieldex Index stats
|
||||
// Shielded Index stats
|
||||
nPayments = 0;
|
||||
nShieldedTx = 0;
|
||||
nShieldingTx = 0;
|
||||
nNotarizations = 0;
|
||||
nDeshieldingTx = 0;
|
||||
nShieldedOutputs = 0;
|
||||
nShieldedSpends = 0;
|
||||
nFullyShieldedTx = 0;
|
||||
nShieldedPayments = 0;
|
||||
nShieldingPayments = 0;
|
||||
@@ -679,6 +687,7 @@ public:
|
||||
READWRITE(nDeshieldingPayments);
|
||||
READWRITE(nFullyShieldedPayments);
|
||||
READWRITE(nShieldedOutputs);
|
||||
READWRITE(nShieldedSpends);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -544,6 +544,14 @@ int32_t MAX_BLOCK_SIZE(int32_t height)
|
||||
else return(2000000);
|
||||
}
|
||||
|
||||
// Change the Hush blocktime at run-time(!)
|
||||
void hush_changeblocktime()
|
||||
{
|
||||
pCurrentParams->consensus.nMaxFutureBlockTime = 7 * ASSETCHAINS_BLOCKTIME;
|
||||
pCurrentParams->consensus.nPowTargetSpacing = ASSETCHAINS_BLOCKTIME;
|
||||
fprintf(stderr,"HUSH blocktime changing to %d seconds\n",ASSETCHAINS_BLOCKTIME);
|
||||
}
|
||||
|
||||
void komodo_setactivation(int32_t height)
|
||||
{
|
||||
pCurrentParams->consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = height;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Checkpoints {
|
||||
fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
|
||||
}
|
||||
|
||||
return fWorkBefore / (fWorkBefore + fWorkAfter);
|
||||
return std::min(fWorkBefore / (fWorkBefore + fWorkAfter), 1.0);
|
||||
}
|
||||
|
||||
int GetTotalBlocksEstimate(const CChainParams::CCheckpointData& data)
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
|
||||
// Must be kept in sync with configure.ac !
|
||||
#define CLIENT_VERSION_MAJOR 3
|
||||
#define CLIENT_VERSION_MINOR 3
|
||||
#define CLIENT_VERSION_REVISION 1
|
||||
#define CLIENT_VERSION_MINOR 4
|
||||
#define CLIENT_VERSION_REVISION 0
|
||||
#define CLIENT_VERSION_BUILD 50
|
||||
|
||||
//! Set to true for release, false for prerelease or test build
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2012-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -65,7 +65,6 @@ bool CCoins::Spend(uint32_t nPos)
|
||||
Cleanup();
|
||||
return true;
|
||||
}
|
||||
bool CCoinsView::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return false; }
|
||||
bool CCoinsView::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return false; }
|
||||
bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return false; }
|
||||
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
|
||||
@@ -85,7 +84,6 @@ bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; }
|
||||
|
||||
CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
|
||||
|
||||
bool CCoinsViewBacked::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return base->GetSproutAnchorAt(rt, tree); }
|
||||
bool CCoinsViewBacked::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return base->GetSaplingAnchorAt(rt, tree); }
|
||||
bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return base->GetNullifier(nullifier, type); }
|
||||
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
|
||||
@@ -139,30 +137,6 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool CCoinsViewCache::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const {
|
||||
CAnchorsSproutMap::const_iterator it = cacheSproutAnchors.find(rt);
|
||||
if (it != cacheSproutAnchors.end()) {
|
||||
if (it->second.entered) {
|
||||
tree = it->second.tree;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!base->GetSproutAnchorAt(rt, tree)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CAnchorsSproutMap::iterator ret = cacheSproutAnchors.insert(std::make_pair(rt, CAnchorsSproutCacheEntry())).first;
|
||||
ret->second.entered = true;
|
||||
ret->second.tree = tree;
|
||||
cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const {
|
||||
CAnchorsSaplingMap::const_iterator it = cacheSaplingAnchors.find(rt);
|
||||
if (it != cacheSaplingAnchors.end()) {
|
||||
@@ -271,7 +245,6 @@ void CCoinsViewCache::BringBestAnchorIntoCache(
|
||||
SproutMerkleTree &tree
|
||||
)
|
||||
{
|
||||
assert(GetSproutAnchorAt(currentRoot, tree));
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -436,8 +409,8 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
|
||||
|
||||
void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNullifiers)
|
||||
{
|
||||
if(fZdebug)
|
||||
LogPrintf("%s\n", __FUNCTION__);
|
||||
//if(fZdebug)
|
||||
// LogPrintf("%s\n", __FUNCTION__);
|
||||
for (CNullifiersMap::iterator child_it = mapNullifiers.begin(); child_it != mapNullifiers.end();) {
|
||||
if (child_it->second.flags & CNullifiersCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
|
||||
CNullifiersMap::iterator parent_it = cacheNullifiers.find(child_it->first);
|
||||
@@ -550,9 +523,9 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins,
|
||||
bool CCoinsViewCache::Flush() {
|
||||
bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, cacheSproutAnchors, cacheSaplingAnchors, cacheSproutNullifiers, cacheSaplingNullifiers);
|
||||
cacheCoins.clear();
|
||||
cacheSproutAnchors.clear();
|
||||
//cacheSproutAnchors.clear();
|
||||
cacheSaplingAnchors.clear();
|
||||
cacheSproutNullifiers.clear();
|
||||
//cacheSproutNullifiers.clear();
|
||||
cacheSaplingNullifiers.clear();
|
||||
cachedCoinsUsage = 0;
|
||||
return fOk;
|
||||
@@ -624,37 +597,8 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr
|
||||
}
|
||||
|
||||
|
||||
bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const
|
||||
bool CCoinsViewCache::HaveShieldedRequirements(const CTransaction& tx) const
|
||||
{
|
||||
boost::unordered_map<uint256, SproutMerkleTree, CCoinsKeyHasher> intermediates;
|
||||
|
||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit)
|
||||
{
|
||||
BOOST_FOREACH(const uint256& nullifier, joinsplit.nullifiers)
|
||||
{
|
||||
if (GetNullifier(nullifier, SPROUT)) {
|
||||
// If the nullifier is set, this transaction
|
||||
// double-spends!
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SproutMerkleTree tree;
|
||||
auto it = intermediates.find(joinsplit.anchor);
|
||||
if (it != intermediates.end()) {
|
||||
tree = it->second;
|
||||
} else if (!GetSproutAnchorAt(joinsplit.anchor, tree)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const uint256& commitment, joinsplit.commitments)
|
||||
{
|
||||
tree.append(commitment);
|
||||
}
|
||||
|
||||
intermediates.insert(std::make_pair(tree.root(), tree));
|
||||
}
|
||||
|
||||
for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
|
||||
if (GetNullifier(spendDescription.nullifier, SAPLING)) { // Prevent double spends
|
||||
LogPrintf("%s: sapling nullifier %s exists, preventing double spend\n", __FUNCTION__, spendDescription.nullifier.GetHex().c_str());
|
||||
|
||||
11
src/coins.h
11
src/coins.h
@@ -372,9 +372,6 @@ struct CCoinsStats
|
||||
class CCoinsView
|
||||
{
|
||||
public:
|
||||
//! Retrieve the tree (Sprout) at a particular anchored root in the chain
|
||||
virtual bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||
|
||||
//! Retrieve the tree (Sapling) at a particular anchored root in the chain
|
||||
virtual bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||
|
||||
@@ -421,7 +418,6 @@ protected:
|
||||
|
||||
public:
|
||||
CCoinsViewBacked(CCoinsView *viewIn);
|
||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||
@@ -493,7 +489,6 @@ public:
|
||||
CNullifiersMap getNullifiers();
|
||||
|
||||
// Standard CCoinsView methods
|
||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||
@@ -550,7 +545,7 @@ public:
|
||||
size_t DynamicMemoryUsage() const;
|
||||
|
||||
/**
|
||||
* Amount of bitcoins coming in to a transaction
|
||||
* Amount of HUSH coming in to a transaction
|
||||
* Note that lightweight clients may not know anything besides the hash of previous transactions,
|
||||
* so may not be able to calculate this.
|
||||
*
|
||||
@@ -562,8 +557,8 @@ public:
|
||||
//! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
|
||||
bool HaveInputs(const CTransaction& tx) const;
|
||||
|
||||
//! Check whether all joinsplit requirements (anchors/nullifiers) are satisfied
|
||||
bool HaveJoinSplitRequirements(const CTransaction& tx) const;
|
||||
//! Check whether all shielded requirements (anchors/nullifiers) are satisfied
|
||||
bool HaveShieldedRequirements(const CTransaction& tx) const;
|
||||
|
||||
//! Return priority of tx at height nHeight
|
||||
double GetPriority(const CTransaction &tx, int nHeight) const;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Copyright (c) 2018 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -15,7 +15,7 @@ AM_CFLAGS = -I$(top_srcdir)/src/asn -I$(top_srcdir)/include -I$(top_srcdir)/src/
|
||||
LIBSECP256K1=src/include/secp256k1/libsecp256k1.la
|
||||
|
||||
$(LIBSECP256K1): $(wildcard src/secp256k1/*)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) -march:x86-64 -g
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) -g
|
||||
|
||||
CRYPTOCONDITIONS_CORE=libcryptoconditions_core.la
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -53,11 +54,8 @@ static void anonToJSON(const CC *cond, cJSON *params) {
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *anonFingerprint(const CC *cond) {
|
||||
unsigned char *out = calloc(1, 32);
|
||||
//fprintf(stderr,"anon fingerprint %p %p\n",out,cond->fingerprint);
|
||||
static void anonFingerprint(const CC *cond, uint8_t *out) {
|
||||
memcpy(out, cond->fingerprint, 32);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1714,7 +1714,9 @@ OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
||||
OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
|
||||
asn_OCTET_STRING_specifics_t *specs;
|
||||
asn_struct_ctx_t *ctx;
|
||||
#if !defined(__aarch64__)
|
||||
struct _stack *stck;
|
||||
#endif
|
||||
|
||||
if(!td || !st)
|
||||
return;
|
||||
@@ -1731,6 +1733,15 @@ OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
||||
st->buf = 0;
|
||||
}
|
||||
|
||||
/* Attention !!!
|
||||
* this is quick & dirty workaround for memory corruption bug on aarch64-linux-gnu
|
||||
* - downside: allows memory leakage
|
||||
* - issue description: On Raspberry Pi 4 @ 64bit linux, daemon crashes with "free(): invalid pointer" error
|
||||
* - probable cause: misaligned memory access to nested structs containing pointers
|
||||
* - TODO: use the latest asn1c compiler on CryptoConditions.asn, maybe generate cpp instead of c code... investigation in progress
|
||||
*/
|
||||
|
||||
#if !defined(__aarch64__)
|
||||
/*
|
||||
* Remove decode-time stack.
|
||||
*/
|
||||
@@ -1747,6 +1758,7 @@ OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
||||
if(!contents_only) {
|
||||
FREEMEM(st);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -65,8 +66,8 @@ void appendUriSubtypes(uint32_t mask, unsigned char *buf) {
|
||||
|
||||
|
||||
char *cc_conditionUri(const CC *cond) {
|
||||
unsigned char *fp = cond->type->fingerprint(cond);
|
||||
if (!fp) return NULL;
|
||||
unsigned char *fp = calloc(1, 32);
|
||||
cond->type->fingerprint(cond, fp);
|
||||
|
||||
unsigned char *encoded = base64_encode(fp, 32);
|
||||
|
||||
@@ -118,13 +119,13 @@ uint32_t fromAsnSubtypes(const ConditionTypes_t types) {
|
||||
size_t cc_conditionBinary(const CC *cond, unsigned char *buf) {
|
||||
Condition_t *asn = calloc(1, sizeof(Condition_t));
|
||||
asnCondition(cond, asn);
|
||||
size_t out = 0;
|
||||
asn_enc_rval_t rc = der_encode_to_buffer(&asn_DEF_Condition, asn, buf, 1000);
|
||||
if (rc.encoded == -1) {
|
||||
fprintf(stderr, "CONDITION NOT ENCODED\n");
|
||||
return 0;
|
||||
}
|
||||
if (rc.encoded == -1) goto end;
|
||||
out = rc.encoded;
|
||||
end:
|
||||
ASN_STRUCT_FREE(asn_DEF_Condition, asn);
|
||||
return rc.encoded;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -146,10 +147,12 @@ void asnCondition(const CC *cond, Condition_t *asn) {
|
||||
// This may look a little weird - we dont have a reference here to the correct
|
||||
// union choice for the condition type, so we just assign everything to the threshold
|
||||
// type. This works out nicely since the union choices have the same binary interface.
|
||||
|
||||
CompoundSha256Condition_t *choice = &asn->choice.thresholdSha256;
|
||||
choice->cost = cc_getCost(cond);
|
||||
choice->fingerprint.buf = cond->type->fingerprint(cond);
|
||||
choice->fingerprint.size = 32;
|
||||
choice->fingerprint.buf = calloc(1, 32);
|
||||
cond->type->fingerprint(cond, choice->fingerprint.buf);
|
||||
choice->subtypes = asnSubtypes(cond->type->getSubtypes(cond));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -25,11 +26,10 @@
|
||||
struct CCType CC_Ed25519Type;
|
||||
|
||||
|
||||
static unsigned char *ed25519Fingerprint(const CC *cond) {
|
||||
static void ed25519Fingerprint(const CC *cond, uint8_t *out) {
|
||||
Ed25519FingerprintContents_t *fp = calloc(1, sizeof(Ed25519FingerprintContents_t));
|
||||
//fprintf(stderr,"ed25519 fingerprint %p %p\n",fp,cond->publicKey);
|
||||
OCTET_STRING_fromBuf(&fp->publicKey, cond->publicKey, 32);
|
||||
return hashFingerprintContents(&asn_DEF_Ed25519FingerprintContents, fp);
|
||||
hashFingerprintContents(&asn_DEF_Ed25519FingerprintContents, fp, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -25,11 +26,8 @@
|
||||
struct CCType CC_EvalType;
|
||||
|
||||
|
||||
static unsigned char *evalFingerprint(const CC *cond) {
|
||||
unsigned char *hash = calloc(1, 32);
|
||||
//fprintf(stderr,"evalfingerprint %p %p\n",hash,cond->code);
|
||||
sha256(cond->code, cond->codeLength, hash);
|
||||
return hash;
|
||||
static void evalFingerprint(const CC *cond, uint8_t *out) {
|
||||
sha256(cond->code, cond->codeLength, out);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +103,7 @@ static uint32_t evalSubtypes(const CC *cond) {
|
||||
*/
|
||||
int jsonVerifyEval(CC *cond, void *context) {
|
||||
if (cond->codeLength == 5 && 0 == memcmp(cond->code, "TEST", 4)) {
|
||||
return cond->code[5];
|
||||
return cond->code[4];
|
||||
}
|
||||
fprintf(stderr, "Cannot verify eval; user function unknown\n");
|
||||
return 0;
|
||||
|
||||
@@ -71,7 +71,7 @@ endif
|
||||
endif
|
||||
|
||||
libsecp256k1_la_SOURCES = src/secp256k1.c
|
||||
libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) -march=x86-64 -g
|
||||
libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) -g
|
||||
libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB)
|
||||
|
||||
libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c
|
||||
|
||||
@@ -36,4 +36,4 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -41,7 +42,7 @@ typedef struct CCType {
|
||||
char name[100];
|
||||
Condition_PR asnType;
|
||||
int (*visitChildren)(CC *cond, CCVisitor visitor);
|
||||
unsigned char *(*fingerprint)(const CC *cond);
|
||||
void (*fingerprint)(const CC *cond, uint8_t *fp);
|
||||
unsigned long (*getCost)(const CC *cond);
|
||||
uint32_t (*getSubtypes)(const CC *cond);
|
||||
CC *(*fromJSON)(const cJSON *params, char *err);
|
||||
@@ -77,7 +78,7 @@ struct CCType *getTypeByAsnEnum(Condition_PR present);
|
||||
*/
|
||||
unsigned char *base64_encode(const unsigned char *data, size_t input_length);
|
||||
unsigned char *base64_decode(const unsigned char *data_, size_t *output_length);
|
||||
unsigned char *hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp);
|
||||
void hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp, uint8_t* out);
|
||||
void dumpStr(unsigned char *str, size_t len);
|
||||
int checkString(const cJSON *value, char *key, char *err);
|
||||
int checkDecodeBase64(const cJSON *value, char *key, char *err, unsigned char **data, size_t *size);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -37,13 +38,12 @@ static int prefixVisitChildren(CC *cond, CCVisitor visitor) {
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *prefixFingerprint(const CC *cond) {
|
||||
static void prefixFingerprint(const CC *cond, uint8_t *out) {
|
||||
PrefixFingerprintContents_t *fp = calloc(1, sizeof(PrefixFingerprintContents_t));
|
||||
//fprintf(stderr,"prefixfinger %p %p\n",fp,cond->prefix);
|
||||
asnCondition(cond->subcondition, &fp->subcondition); // TODO: check asnCondition for safety
|
||||
asnCondition(cond->subcondition, &fp->subcondition);
|
||||
fp->maxMessageLength = cond->maxMessageLength;
|
||||
OCTET_STRING_fromBuf(&fp->prefix, cond->prefix, cond->prefixLength);
|
||||
return hashFingerprintContents(&asn_DEF_PrefixFingerprintContents, fp);
|
||||
hashFingerprintContents(&asn_DEF_PrefixFingerprintContents, fp, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -44,11 +45,8 @@ static unsigned long preimageCost(const CC *cond) {
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *preimageFingerprint(const CC *cond) {
|
||||
unsigned char *hash = calloc(1, 32);
|
||||
//fprintf(stderr,"preimage %p %p\n",hash,cond->preimage);
|
||||
sha256(cond->preimage, cond->preimageLength, hash);
|
||||
return hash;
|
||||
static void preimageFingerprint(const CC *cond, uint8_t *out) {
|
||||
sha256(cond->preimage, cond->preimageLength, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -88,11 +89,10 @@ void initVerify() {
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *secp256k1Fingerprint(const CC *cond) {
|
||||
static void secp256k1Fingerprint(const CC *cond, uint8_t *out) {
|
||||
Secp256k1FingerprintContents_t *fp = calloc(1, sizeof(Secp256k1FingerprintContents_t));
|
||||
//fprintf(stderr,"secpfinger %p %p size %d vs %d\n",fp,cond->publicKey,(int32_t)sizeof(Secp256k1FingerprintContents_t),(int32_t)SECP256K1_PK_SIZE);
|
||||
OCTET_STRING_fromBuf(&fp->publicKey, cond->publicKey, SECP256K1_PK_SIZE);
|
||||
return hashFingerprintContents(&asn_DEF_Secp256k1FingerprintContents, fp);
|
||||
hashFingerprintContents(&asn_DEF_Secp256k1FingerprintContents, fp, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -94,17 +95,15 @@ static int cmpConditionBin(const void *a, const void *b) {
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *thresholdFingerprint(const CC *cond) {
|
||||
/* Create fingerprint */
|
||||
static void thresholdFingerprint(const CC *cond, uint8_t *out) {
|
||||
ThresholdFingerprintContents_t *fp = calloc(1, sizeof(ThresholdFingerprintContents_t));
|
||||
//fprintf(stderr,"thresholdfinger %p\n",fp);
|
||||
fp->threshold = cond->threshold;
|
||||
for (int i=0; i<cond->size; i++) {
|
||||
Condition_t *asnCond = asnConditionNew(cond->subconditions[i]);
|
||||
asn_set_add(&fp->subconditions2, asnCond);
|
||||
}
|
||||
qsort(fp->subconditions2.list.array, cond->size, sizeof(Condition_t*), cmpConditionBin);
|
||||
return hashFingerprintContents(&asn_DEF_ThresholdFingerprintContents, fp);
|
||||
hashFingerprintContents(&asn_DEF_ThresholdFingerprintContents, fp, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -210,17 +211,15 @@ void jsonAddBase64(cJSON *params, char *key, unsigned char *bin, size_t size) {
|
||||
}
|
||||
|
||||
|
||||
unsigned char *hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp) {
|
||||
void hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp, uint8_t *out) {
|
||||
unsigned char buf[BUF_SIZE];
|
||||
asn_enc_rval_t rc = der_encode_to_buffer(asnType, fp, buf, BUF_SIZE);
|
||||
ASN_STRUCT_FREE(*asnType, fp);
|
||||
if (rc.encoded < 1) {
|
||||
fprintf(stderr, "Encoding fingerprint failed\n");
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
unsigned char *hash = calloc(1,32);
|
||||
sha256(buf, rc.encoded, hash);
|
||||
return hash;
|
||||
sha256(buf, rc.encoded, out);
|
||||
}
|
||||
|
||||
|
||||
@@ -301,5 +300,3 @@ int jsonGetHexOptional(const cJSON *params, char *key, char *err, unsigned char
|
||||
}
|
||||
return checkDecodeHex(item, key, err, data, size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -82,4 +82,25 @@ def test_malleability_checked():
|
||||
assert not cc_rfb(b'\xa2\x13\xa0\x0f\xa0\x06\x80\x04abcd\xa0\x05\x80\x03abc\xa1\x00')
|
||||
|
||||
|
||||
def test_large_threshold():
|
||||
conds = [{
|
||||
'type': "secp256k1-sha-256",
|
||||
"publicKey": "02D5D969305535AC29A77079C11D4F0DD40661CF96E04E974A5E8D7E374EE225AA"
|
||||
}]
|
||||
|
||||
for i in range(250):
|
||||
conds.append({
|
||||
"type": "eval-sha-256",
|
||||
"code": "VEVTVAE"
|
||||
})
|
||||
|
||||
r = jsonRPC("encodeCondition", {
|
||||
"type": "threshold-sha-256",
|
||||
"subfulfillments": conds,
|
||||
"threshold": 251
|
||||
})
|
||||
assert 'error' not in r, r
|
||||
|
||||
|
||||
|
||||
so.cc_conditionUri.restype = ctypes.c_char_p
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
#include "util.h"
|
||||
|
||||
#include <libsnark/common/default_types/r1cs_ppzksnark_pp.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
|
||||
#include "librustzcash.h"
|
||||
|
||||
struct ECCryptoClosure
|
||||
@@ -23,12 +20,7 @@ int main(int argc, char **argv) {
|
||||
assert(init_and_check_sodium() != -1);
|
||||
ECC_Start();
|
||||
|
||||
libsnark::default_r1cs_ppzksnark_pp::init_public_params();
|
||||
libsnark::inhibit_profiling_info = true;
|
||||
libsnark::inhibit_profiling_counters = true;
|
||||
boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key";
|
||||
boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key";
|
||||
params = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string());
|
||||
params = ZCJoinSplit::Prepared();
|
||||
|
||||
boost::filesystem::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
|
||||
boost::filesystem::path sapling_output = ZC_GetParamsDir() / "sapling-output.params";
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "uint256.h"
|
||||
|
||||
#include "zcash/util.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <libsnark/common/default_types/r1cs_ppzksnark_pp.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
#include <libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp>
|
||||
#include <libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp>
|
||||
|
||||
#include "zcash/IncrementalMerkleTree.hpp"
|
||||
|
||||
using namespace libsnark;
|
||||
using namespace libzcash;
|
||||
|
||||
#include "zcash/circuit/utils.tcc"
|
||||
#include "zcash/circuit/merkle.tcc"
|
||||
|
||||
template<typename FieldT>
|
||||
void test_value_equals(uint64_t i) {
|
||||
protoboard<FieldT> pb;
|
||||
pb_variable_array<FieldT> num;
|
||||
num.allocate(pb, 64, "");
|
||||
num.fill_with_bits(pb, uint64_to_bool_vector(i));
|
||||
pb.add_r1cs_constraint(r1cs_constraint<FieldT>(
|
||||
packed_addition(num),
|
||||
FieldT::one(),
|
||||
FieldT::one() * i
|
||||
), "");
|
||||
ASSERT_TRUE(pb.is_satisfied());
|
||||
}
|
||||
|
||||
TEST(circuit, values)
|
||||
{
|
||||
typedef Fr<default_r1cs_ppzksnark_pp> FieldT;
|
||||
test_value_equals<FieldT>(0);
|
||||
test_value_equals<FieldT>(1);
|
||||
test_value_equals<FieldT>(3);
|
||||
test_value_equals<FieldT>(5391);
|
||||
test_value_equals<FieldT>(883128374);
|
||||
test_value_equals<FieldT>(173419028459);
|
||||
test_value_equals<FieldT>(2205843009213693953);
|
||||
}
|
||||
|
||||
TEST(circuit, endianness)
|
||||
{
|
||||
std::vector<unsigned char> before = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55,
|
||||
56, 57, 58, 59, 60, 61, 62, 63
|
||||
};
|
||||
auto result = swap_endianness_u64(before);
|
||||
|
||||
std::vector<unsigned char> after = {
|
||||
56, 57, 58, 59, 60, 61, 62, 63,
|
||||
48, 49, 50, 51, 52, 53, 54, 55,
|
||||
40, 41, 42, 43, 44, 45, 46, 47,
|
||||
32, 33, 34, 35, 36, 37, 38, 39,
|
||||
24, 25, 26, 27, 28, 29, 30, 31,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7
|
||||
};
|
||||
|
||||
EXPECT_EQ(after, result);
|
||||
|
||||
std::vector<unsigned char> bad = {0, 1, 2, 3};
|
||||
|
||||
ASSERT_THROW(swap_endianness_u64(bad), std::length_error);
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
bool test_merkle_gadget(
|
||||
bool enforce_a,
|
||||
bool enforce_b,
|
||||
bool write_root_first
|
||||
)
|
||||
{
|
||||
protoboard<FieldT> pb;
|
||||
digest_variable<FieldT> root(pb, 256, "root");
|
||||
pb.set_input_sizes(256);
|
||||
|
||||
digest_variable<FieldT> commitment1(pb, 256, "commitment1");
|
||||
digest_variable<FieldT> commitment2(pb, 256, "commitment2");
|
||||
|
||||
pb_variable<FieldT> commitment1_read;
|
||||
commitment1_read.allocate(pb);
|
||||
pb_variable<FieldT> commitment2_read;
|
||||
commitment2_read.allocate(pb);
|
||||
|
||||
merkle_tree_gadget<FieldT> mgadget1(pb, commitment1, root, commitment1_read);
|
||||
merkle_tree_gadget<FieldT> mgadget2(pb, commitment2, root, commitment2_read);
|
||||
|
||||
commitment1.generate_r1cs_constraints();
|
||||
commitment2.generate_r1cs_constraints();
|
||||
root.generate_r1cs_constraints();
|
||||
mgadget1.generate_r1cs_constraints();
|
||||
mgadget2.generate_r1cs_constraints();
|
||||
|
||||
SproutMerkleTree tree;
|
||||
uint256 commitment1_data = uint256S("54d626e08c1c802b305dad30b7e54a82f102390cc92c7d4db112048935236e9c");
|
||||
uint256 commitment2_data = uint256S("59d2cde5e65c1414c32ba54f0fe4bdb3d67618125286e6a191317917c812c6d7");
|
||||
tree.append(commitment1_data);
|
||||
auto wit1 = tree.witness();
|
||||
tree.append(commitment2_data);
|
||||
wit1.append(commitment2_data);
|
||||
auto wit2 = tree.witness();
|
||||
auto expected_root = tree.root();
|
||||
tree.append(uint256S("3e243c8798678570bb8d42616c23a536af44be15c4eef073490c2a44ae5f32c3"));
|
||||
auto unexpected_root = tree.root();
|
||||
tree.append(uint256S("26d9b20c7f1c3d2528bbcd43cd63344b0afd3b6a0a8ebd37ec51cba34907bec7"));
|
||||
auto badwit1 = tree.witness();
|
||||
tree.append(uint256S("02c2467c9cd15e0d150f74cd636505ed675b0b71b66a719f6f52fdb49a5937bb"));
|
||||
auto badwit2 = tree.witness();
|
||||
|
||||
// Perform the test
|
||||
|
||||
pb.val(commitment1_read) = enforce_a ? FieldT::one() : FieldT::zero();
|
||||
pb.val(commitment2_read) = enforce_b ? FieldT::one() : FieldT::zero();
|
||||
|
||||
commitment1.bits.fill_with_bits(pb, uint256_to_bool_vector(commitment1_data));
|
||||
commitment2.bits.fill_with_bits(pb, uint256_to_bool_vector(commitment2_data));
|
||||
|
||||
if (write_root_first) {
|
||||
root.bits.fill_with_bits(pb, uint256_to_bool_vector(expected_root));
|
||||
}
|
||||
|
||||
mgadget1.generate_r1cs_witness(wit1.path());
|
||||
mgadget2.generate_r1cs_witness(wit2.path());
|
||||
|
||||
// Overwrite with our expected root
|
||||
root.bits.fill_with_bits(pb, uint256_to_bool_vector(expected_root));
|
||||
|
||||
return pb.is_satisfied();
|
||||
}
|
||||
|
||||
TEST(circuit, merkle_tree_gadget_weirdness)
|
||||
{
|
||||
/*
|
||||
The merkle tree gadget takes a leaf in the merkle tree (the Note commitment),
|
||||
a merkle tree authentication path, and a root (anchor). It also takes a parameter
|
||||
called read_success, which is used to determine if the commitment actually needs to
|
||||
appear in the tree.
|
||||
|
||||
If two input notes use the same root (which our protocol does) then if `read_success`
|
||||
is disabled on the first note but enabled on the second note (i.e., the first note
|
||||
has value of zero and second note has nonzero value) then there is an edge case in
|
||||
the witnessing behavior. The first witness will accidentally constrain the root to
|
||||
equal null (the default value of the anchor) and the second witness will actually
|
||||
copy the bits, violating the constraint system.
|
||||
|
||||
Notice that this edge case is not in the constraint system but in the witnessing
|
||||
behavior.
|
||||
*/
|
||||
|
||||
typedef Fr<default_r1cs_ppzksnark_pp> FieldT;
|
||||
|
||||
// Test the normal case
|
||||
ASSERT_TRUE(test_merkle_gadget<FieldT>(true, true, false));
|
||||
ASSERT_TRUE(test_merkle_gadget<FieldT>(true, true, true));
|
||||
|
||||
// Test the case where the first commitment is enforced but the second isn't
|
||||
// Works because the first read is performed before the second one
|
||||
ASSERT_TRUE(test_merkle_gadget<FieldT>(true, false, false));
|
||||
ASSERT_TRUE(test_merkle_gadget<FieldT>(true, false, true));
|
||||
|
||||
// Test the case where the first commitment isn't enforced but the second is
|
||||
// Doesn't work because the first multipacker witnesses the existing root (which
|
||||
// is null)
|
||||
ASSERT_TRUE(!test_merkle_gadget<FieldT>(false, true, false));
|
||||
|
||||
// Test the last again, except this time write the root first.
|
||||
ASSERT_TRUE(test_merkle_gadget<FieldT>(false, true, true));
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "chainparams.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "zcash/Address.hpp"
|
||||
#include "wallet/wallet.h"
|
||||
#include "amount.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "util.h"
|
||||
|
||||
#ifndef disable_founders
|
||||
// To run tests:
|
||||
// ./zcash-gtest --gtest_filter="founders_reward_test.*"
|
||||
|
||||
//
|
||||
// Enable this test to generate and print 48 testnet 2-of-3 multisig addresses.
|
||||
// The output can be copied into chainparams.cpp.
|
||||
// The temporary wallet file can be renamed as wallet.dat and used for testing with zcashd.
|
||||
//
|
||||
#if 0
|
||||
TEST(founders_reward_test, create_testnet_2of3multisig) {
|
||||
SelectParams(CBaseChainParams::TESTNET);
|
||||
boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
|
||||
boost::filesystem::create_directories(pathTemp);
|
||||
mapArgs["-datadir"] = pathTemp.string();
|
||||
bool fFirstRun;
|
||||
auto pWallet = std::make_shared<CWallet>("wallet.dat");
|
||||
ASSERT_EQ(DB_LOAD_OK, pWallet->LoadWallet(fFirstRun));
|
||||
pWallet->TopUpKeyPool();
|
||||
std::cout << "Test wallet and logs saved in folder: " << pathTemp.native() << std::endl;
|
||||
|
||||
int numKeys = 48;
|
||||
std::vector<CPubKey> pubkeys;
|
||||
pubkeys.resize(3);
|
||||
CPubKey newKey;
|
||||
std::vector<std::string> addresses;
|
||||
for (int i = 0; i < numKeys; i++) {
|
||||
ASSERT_TRUE(pWallet->GetKeyFromPool(newKey));
|
||||
pubkeys[0] = newKey;
|
||||
pWallet->SetAddressBook(newKey.GetID(), "", "receive");
|
||||
|
||||
ASSERT_TRUE(pWallet->GetKeyFromPool(newKey));
|
||||
pubkeys[1] = newKey;
|
||||
pWallet->SetAddressBook(newKey.GetID(), "", "receive");
|
||||
|
||||
ASSERT_TRUE(pWallet->GetKeyFromPool(newKey));
|
||||
pubkeys[2] = newKey;
|
||||
pWallet->SetAddressBook(newKey.GetID(), "", "receive");
|
||||
|
||||
CScript result = GetScriptForMultisig(2, pubkeys);
|
||||
ASSERT_FALSE(result.size() > MAX_SCRIPT_ELEMENT_SIZE);
|
||||
CScriptID innerID(result);
|
||||
pWallet->AddCScript(result);
|
||||
pWallet->SetAddressBook(innerID, "", "receive");
|
||||
|
||||
std::string address = EncodeDestination(innerID);
|
||||
addresses.push_back(address);
|
||||
}
|
||||
|
||||
// Print out the addresses, 4 on each line.
|
||||
std::string s = "vFoundersRewardAddress = {\n";
|
||||
int i=0;
|
||||
int colsPerRow = 4;
|
||||
ASSERT_TRUE(numKeys % colsPerRow == 0);
|
||||
int numRows = numKeys/colsPerRow;
|
||||
for (int row=0; row<numRows; row++) {
|
||||
s += " ";
|
||||
for (int col=0; col<colsPerRow; col++) {
|
||||
s += "\"" + addresses[i++] + "\", ";
|
||||
}
|
||||
s += "\n";
|
||||
}
|
||||
s += " };";
|
||||
std::cout << s << std::endl;
|
||||
|
||||
pWallet->Flush(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Utility method to check the number of unique addresses from height 1 to maxHeight
|
||||
void checkNumberOfUniqueAddresses(int nUnique) {
|
||||
int maxHeight = Params().GetConsensus().GetLastFoundersRewardBlockHeight();
|
||||
std::set<std::string> addresses;
|
||||
for (int i = 1; i <= maxHeight; i++) {
|
||||
addresses.insert(Params().GetFoundersRewardAddressAtHeight(i));
|
||||
}
|
||||
ASSERT_TRUE(addresses.size() == nUnique);
|
||||
}
|
||||
|
||||
|
||||
TEST(founders_reward_test, general) {
|
||||
SelectParams(CBaseChainParams::TESTNET);
|
||||
|
||||
CChainParams params = Params();
|
||||
|
||||
// Fourth testnet reward:
|
||||
// address = t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy
|
||||
// script.ToString() = OP_HASH160 55d64928e69829d9376c776550b6cc710d427153 OP_EQUAL
|
||||
// HexStr(script) = a91455d64928e69829d9376c776550b6cc710d42715387
|
||||
EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(1)), "a914ef775f1f997f122a062fff1a2d7443abd1f9c64287");
|
||||
EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(1), "t2UNzUUx8mWBCRYPRezvA363EYXyEpHokyi");
|
||||
EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(53126)), "a914ac67f4c072668138d88a86ff21b27207b283212f87");
|
||||
EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53126), "t2NGQjYMQhFndDHguvUw4wZdNdsssA6K7x2");
|
||||
EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(53127)), "a91455d64928e69829d9376c776550b6cc710d42715387");
|
||||
EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53127), "t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy");
|
||||
|
||||
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
||||
|
||||
// If the block height parameter is out of bounds, there is an assert.
|
||||
EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(0), "nHeight");
|
||||
EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(maxHeight+1), "nHeight");
|
||||
EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(0), "nHeight");
|
||||
EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(maxHeight+1), "nHeight");
|
||||
}
|
||||
|
||||
|
||||
#define NUM_MAINNET_FOUNDER_ADDRESSES 48
|
||||
|
||||
TEST(founders_reward_test, mainnet) {
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
checkNumberOfUniqueAddresses(NUM_MAINNET_FOUNDER_ADDRESSES);
|
||||
}
|
||||
|
||||
|
||||
#define NUM_TESTNET_FOUNDER_ADDRESSES 48
|
||||
|
||||
TEST(founders_reward_test, testnet) {
|
||||
SelectParams(CBaseChainParams::TESTNET);
|
||||
checkNumberOfUniqueAddresses(NUM_TESTNET_FOUNDER_ADDRESSES);
|
||||
}
|
||||
|
||||
|
||||
#define NUM_REGTEST_FOUNDER_ADDRESSES 1
|
||||
|
||||
TEST(founders_reward_test, regtest) {
|
||||
SelectParams(CBaseChainParams::REGTEST);
|
||||
checkNumberOfUniqueAddresses(NUM_REGTEST_FOUNDER_ADDRESSES);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Test that 10% founders reward is fully rewarded after the first halving and slow start shift.
|
||||
// On Mainnet, this would be 2,100,000 ZEC after 850,000 blocks (840,000 + 10,000).
|
||||
TEST(founders_reward_test, slow_start_subsidy) {
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
CChainParams params = Params();
|
||||
|
||||
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
||||
CAmount totalSubsidy = 0;
|
||||
for (int nHeight = 1; nHeight <= maxHeight; nHeight++) {
|
||||
CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus()) / 5;
|
||||
totalSubsidy += nSubsidy;
|
||||
}
|
||||
|
||||
ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0);
|
||||
}
|
||||
|
||||
|
||||
// For use with mainnet and testnet which each have 48 addresses.
|
||||
// Verify the number of rewards each individual address receives.
|
||||
void verifyNumberOfRewards() {
|
||||
CChainParams params = Params();
|
||||
int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight();
|
||||
std::multiset<std::string> ms;
|
||||
for (int nHeight = 1; nHeight <= maxHeight; nHeight++) {
|
||||
ms.insert(params.GetFoundersRewardAddressAtHeight(nHeight));
|
||||
}
|
||||
|
||||
ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(0)) == 17708);
|
||||
for (int i = 1; i <= 46; i++) {
|
||||
ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(i)) == 17709);
|
||||
}
|
||||
ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(47)) == 17677);
|
||||
}
|
||||
|
||||
// Verify the number of rewards going to each mainnet address
|
||||
TEST(founders_reward_test, per_address_reward_mainnet) {
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
verifyNumberOfRewards();
|
||||
}
|
||||
|
||||
// Verify the number of rewards going to each testnet address
|
||||
TEST(founders_reward_test, per_address_reward_testnet) {
|
||||
SelectParams(CBaseChainParams::TESTNET);
|
||||
verifyNumberOfRewards();
|
||||
}
|
||||
#endif
|
||||
@@ -1,616 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/variant/get.hpp>
|
||||
|
||||
#include "zcash/prf.h"
|
||||
#include "util.h"
|
||||
#include "streams.h"
|
||||
#include "version.h"
|
||||
#include "serialize.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
#include "zcash/Note.hpp"
|
||||
#include "zcash/NoteEncryption.hpp"
|
||||
#include "zcash/IncrementalMerkleTree.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
using namespace libzcash;
|
||||
|
||||
extern ZCJoinSplit* params;
|
||||
|
||||
typedef std::array<JSDescription, 2> SproutProofs;
|
||||
// Make both the PHGR and Groth proof for a Sprout statement,
|
||||
// and store the results in JSDescription objects.
|
||||
SproutProofs makeSproutProofs(
|
||||
ZCJoinSplit& js,
|
||||
const std::array<JSInput, 2>& inputs,
|
||||
const std::array<JSOutput, 2>& outputs,
|
||||
const uint256& joinSplitPubKey,
|
||||
uint64_t vpub_old,
|
||||
uint64_t vpub_new,
|
||||
const uint256& rt
|
||||
){
|
||||
//Making the PHGR proof
|
||||
JSDescription phgr(false, js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new);
|
||||
//Making the Groth proof
|
||||
JSDescription groth(true, js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new);
|
||||
|
||||
return {phgr, groth};
|
||||
|
||||
}
|
||||
|
||||
bool verifySproutProofs(
|
||||
ZCJoinSplit& js,
|
||||
const SproutProofs& jsdescs,
|
||||
const uint256& joinSplitPubKey
|
||||
)
|
||||
{
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
bool phgrPassed = jsdescs[0].Verify(js, verifier, joinSplitPubKey);
|
||||
bool grothPassed = jsdescs[1].Verify(js, verifier, joinSplitPubKey);
|
||||
return phgrPassed && grothPassed;
|
||||
}
|
||||
|
||||
|
||||
void test_full_api(ZCJoinSplit* js)
|
||||
{
|
||||
// Create verification context.
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
|
||||
// The recipient's information.
|
||||
SproutSpendingKey recipient_key = SproutSpendingKey::random();
|
||||
SproutPaymentAddress recipient_addr = recipient_key.address();
|
||||
|
||||
// Create the commitment tree
|
||||
SproutMerkleTree tree;
|
||||
|
||||
// Set up a JoinSplit description
|
||||
uint64_t vpub_old = 10;
|
||||
uint64_t vpub_new = 0;
|
||||
uint256 joinSplitPubKey = random_uint256();
|
||||
uint256 rt = tree.root();
|
||||
SproutProofs jsdescs;
|
||||
|
||||
{
|
||||
std::array<JSInput, 2> inputs = {
|
||||
JSInput(), // dummy input
|
||||
JSInput() // dummy input
|
||||
};
|
||||
|
||||
std::array<JSOutput, 2> outputs = {
|
||||
JSOutput(recipient_addr, 10),
|
||||
JSOutput() // dummy output
|
||||
};
|
||||
|
||||
std::array<SproutNote, 2> output_notes;
|
||||
|
||||
// Perform the proofs
|
||||
jsdescs = makeSproutProofs(
|
||||
*js,
|
||||
inputs,
|
||||
outputs,
|
||||
joinSplitPubKey,
|
||||
vpub_old,
|
||||
vpub_new,
|
||||
rt
|
||||
);
|
||||
}
|
||||
|
||||
// Verify both PHGR and Groth Proof:
|
||||
ASSERT_TRUE(verifySproutProofs(*js, jsdescs, joinSplitPubKey));
|
||||
|
||||
// Run tests using both phgr and groth as basis for field values
|
||||
for (auto jsdesc : jsdescs)
|
||||
{
|
||||
SproutMerkleTree tree;
|
||||
SproutProofs jsdescs2;
|
||||
// Recipient should decrypt
|
||||
// Now the recipient should spend the money again
|
||||
auto h_sig = js->h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey);
|
||||
ZCNoteDecryption decryptor(recipient_key.receiving_key());
|
||||
|
||||
auto note_pt = SproutNotePlaintext::decrypt(
|
||||
decryptor,
|
||||
jsdesc.ciphertexts[0],
|
||||
jsdesc.ephemeralKey,
|
||||
h_sig,
|
||||
0
|
||||
);
|
||||
|
||||
auto decrypted_note = note_pt.note(recipient_addr);
|
||||
|
||||
ASSERT_TRUE(decrypted_note.value() == 10);
|
||||
|
||||
// Insert the commitments from the last tx into the tree
|
||||
tree.append(jsdesc.commitments[0]);
|
||||
auto witness_recipient = tree.witness();
|
||||
tree.append(jsdesc.commitments[1]);
|
||||
witness_recipient.append(jsdesc.commitments[1]);
|
||||
vpub_old = 0;
|
||||
vpub_new = 1;
|
||||
rt = tree.root();
|
||||
auto joinSplitPubKey2 = random_uint256();
|
||||
|
||||
{
|
||||
std::array<JSInput, 2> inputs = {
|
||||
JSInput(), // dummy input
|
||||
JSInput(witness_recipient, decrypted_note, recipient_key)
|
||||
};
|
||||
|
||||
SproutSpendingKey second_recipient = SproutSpendingKey::random();
|
||||
SproutPaymentAddress second_addr = second_recipient.address();
|
||||
|
||||
std::array<JSOutput, 2> outputs = {
|
||||
JSOutput(second_addr, 9),
|
||||
JSOutput() // dummy output
|
||||
};
|
||||
|
||||
std::array<SproutNote, 2> output_notes;
|
||||
|
||||
|
||||
// Perform the proofs
|
||||
jsdescs2 = makeSproutProofs(
|
||||
*js,
|
||||
inputs,
|
||||
outputs,
|
||||
joinSplitPubKey2,
|
||||
vpub_old,
|
||||
vpub_new,
|
||||
rt
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Verify both PHGR and Groth Proof:
|
||||
ASSERT_TRUE(verifySproutProofs(*js, jsdescs2, joinSplitPubKey2));
|
||||
}
|
||||
}
|
||||
|
||||
// Invokes the API (but does not compute a proof)
|
||||
// to test exceptions
|
||||
void invokeAPI(
|
||||
ZCJoinSplit* js,
|
||||
const std::array<JSInput, 2>& inputs,
|
||||
const std::array<JSOutput, 2>& outputs,
|
||||
uint64_t vpub_old,
|
||||
uint64_t vpub_new,
|
||||
const uint256& rt
|
||||
) {
|
||||
uint256 ephemeralKey;
|
||||
uint256 randomSeed;
|
||||
uint256 joinSplitPubKey = random_uint256();
|
||||
std::array<uint256, 2> macs;
|
||||
std::array<uint256, 2> nullifiers;
|
||||
std::array<uint256, 2> commitments;
|
||||
std::array<ZCNoteEncryption::Ciphertext, 2> ciphertexts;
|
||||
|
||||
std::array<SproutNote, 2> output_notes;
|
||||
|
||||
// PHGR
|
||||
SproutProof proof = js->prove(
|
||||
false,
|
||||
inputs,
|
||||
outputs,
|
||||
output_notes,
|
||||
ciphertexts,
|
||||
ephemeralKey,
|
||||
joinSplitPubKey,
|
||||
randomSeed,
|
||||
macs,
|
||||
nullifiers,
|
||||
commitments,
|
||||
vpub_old,
|
||||
vpub_new,
|
||||
rt,
|
||||
false
|
||||
);
|
||||
|
||||
// Groth
|
||||
proof = js->prove(
|
||||
true,
|
||||
inputs,
|
||||
outputs,
|
||||
output_notes,
|
||||
ciphertexts,
|
||||
ephemeralKey,
|
||||
joinSplitPubKey,
|
||||
randomSeed,
|
||||
macs,
|
||||
nullifiers,
|
||||
commitments,
|
||||
vpub_old,
|
||||
vpub_new,
|
||||
rt,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
void invokeAPIFailure(
|
||||
ZCJoinSplit* js,
|
||||
const std::array<JSInput, 2>& inputs,
|
||||
const std::array<JSOutput, 2>& outputs,
|
||||
uint64_t vpub_old,
|
||||
uint64_t vpub_new,
|
||||
const uint256& rt,
|
||||
std::string reason
|
||||
)
|
||||
{
|
||||
try {
|
||||
invokeAPI(js, inputs, outputs, vpub_old, vpub_new, rt);
|
||||
FAIL() << "It worked, when it shouldn't have!";
|
||||
} catch(std::invalid_argument const & err) {
|
||||
EXPECT_EQ(err.what(), reason);
|
||||
} catch(...) {
|
||||
FAIL() << "Expected invalid_argument exception.";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(joinsplit, h_sig)
|
||||
{
|
||||
/*
|
||||
// by Taylor Hornby
|
||||
|
||||
import pyblake2
|
||||
import binascii
|
||||
|
||||
def hSig(randomSeed, nf1, nf2, joinSplitPubKey):
|
||||
return pyblake2.blake2b(
|
||||
data=(randomSeed + nf1 + nf2 + joinSplitPubKey),
|
||||
digest_size=32,
|
||||
person=b"ZcashComputehSig"
|
||||
).digest()
|
||||
|
||||
INCREASING = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
|
||||
|
||||
TEST_VECTORS = [
|
||||
[b"a" * 32, b"b" * 32, b"c" * 32, b"d" * 32],
|
||||
[b"\x00" * 32, b"\x00" * 32, b"\x00" * 32, b"\x00" * 32],
|
||||
[b"\xFF" * 32, b"\xFF" * 32, b"\xFF" * 32, b"\xFF" * 32],
|
||||
[INCREASING, INCREASING, INCREASING, INCREASING]
|
||||
]
|
||||
|
||||
for test_input in TEST_VECTORS:
|
||||
print "---"
|
||||
print "\"" + binascii.hexlify(test_input[0][::-1]) + "\""
|
||||
print "\"" + binascii.hexlify(test_input[1][::-1]) + "\""
|
||||
print "\"" + binascii.hexlify(test_input[2][::-1]) + "\""
|
||||
print "\"" + binascii.hexlify(test_input[3][::-1]) + "\""
|
||||
print "\"" + binascii.hexlify(hSig(test_input[0], test_input[1], test_input[2], test_input[3])[::-1]) + "\""
|
||||
*/
|
||||
|
||||
std::vector<std::vector<std::string>> tests = {
|
||||
{
|
||||
"6161616161616161616161616161616161616161616161616161616161616161",
|
||||
"6262626262626262626262626262626262626262626262626262626262626262",
|
||||
"6363636363636363636363636363636363636363636363636363636363636363",
|
||||
"6464646464646464646464646464646464646464646464646464646464646464",
|
||||
"a8cba69f1fa329c055756b4af900f8a00b61e44f4cb8a1824ceb58b90a5b8113"
|
||||
},
|
||||
{
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"697322276b5dd93b12fb1fcbd2144b2960f24c73aac6c6a0811447be1e7f1e19"
|
||||
},
|
||||
{
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"4961048919f0ca79d49c9378c36a91a8767060001f4212fe6f7d426f3ccf9f32"
|
||||
},
|
||||
{
|
||||
"1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100",
|
||||
"1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100",
|
||||
"1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100",
|
||||
"1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100",
|
||||
"b61110ec162693bc3d9ca7fb0eec3afd2e278e2f41394b3ff11d7cb761ad4b27"
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_FOREACH(std::vector<std::string>& v, tests) {
|
||||
auto expected = ZCJoinSplit::h_sig(
|
||||
uint256S(v[0]),
|
||||
{uint256S(v[1]), uint256S(v[2])},
|
||||
uint256S(v[3])
|
||||
);
|
||||
|
||||
EXPECT_EQ(expected, uint256S(v[4]));
|
||||
}
|
||||
}
|
||||
|
||||
void increment_note_witnesses(
|
||||
const uint256& element,
|
||||
std::vector<SproutWitness>& witnesses,
|
||||
SproutMerkleTree& tree
|
||||
)
|
||||
{
|
||||
tree.append(element);
|
||||
for (SproutWitness& w : witnesses) {
|
||||
w.append(element);
|
||||
}
|
||||
witnesses.push_back(tree.witness());
|
||||
}
|
||||
|
||||
TEST(joinsplit, full_api_test)
|
||||
{
|
||||
{
|
||||
std::vector<SproutWitness> witnesses;
|
||||
SproutMerkleTree tree;
|
||||
increment_note_witnesses(uint256(), witnesses, tree);
|
||||
SproutSpendingKey sk = SproutSpendingKey::random();
|
||||
SproutPaymentAddress addr = sk.address();
|
||||
SproutNote note1(addr.a_pk, 100, random_uint256(), random_uint256());
|
||||
increment_note_witnesses(note1.cm(), witnesses, tree);
|
||||
SproutNote note2(addr.a_pk, 100, random_uint256(), random_uint256());
|
||||
increment_note_witnesses(note2.cm(), witnesses, tree);
|
||||
SproutNote note3(addr.a_pk, 2100000000000001, random_uint256(), random_uint256());
|
||||
increment_note_witnesses(note3.cm(), witnesses, tree);
|
||||
SproutNote note4(addr.a_pk, 1900000000000000, random_uint256(), random_uint256());
|
||||
increment_note_witnesses(note4.cm(), witnesses, tree);
|
||||
SproutNote note5(addr.a_pk, 1900000000000000, random_uint256(), random_uint256());
|
||||
increment_note_witnesses(note5.cm(), witnesses, tree);
|
||||
|
||||
// Should work
|
||||
invokeAPI(params,
|
||||
{
|
||||
JSInput(),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
0,
|
||||
tree.root());
|
||||
|
||||
// lhs > MAX_MONEY
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(),
|
||||
JSOutput()
|
||||
},
|
||||
2100000000000001,
|
||||
0,
|
||||
tree.root(),
|
||||
"nonsensical vpub_old value");
|
||||
|
||||
// rhs > MAX_MONEY
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
2100000000000001,
|
||||
tree.root(),
|
||||
"nonsensical vpub_new value");
|
||||
|
||||
// input witness for the wrong element
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(witnesses[0], note1, sk),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
100,
|
||||
tree.root(),
|
||||
"witness of wrong element for joinsplit input");
|
||||
|
||||
// input witness doesn't match up with
|
||||
// real root
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(witnesses[1], note1, sk),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
100,
|
||||
uint256(),
|
||||
"joinsplit not anchored to the correct root");
|
||||
|
||||
// input is in the tree now! this should work
|
||||
invokeAPI(params,
|
||||
{
|
||||
JSInput(witnesses[1], note1, sk),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
100,
|
||||
tree.root());
|
||||
|
||||
// Wrong secret key
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(witnesses[1], note1, SproutSpendingKey::random()),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
0,
|
||||
tree.root(),
|
||||
"input note not authorized to spend with given key");
|
||||
|
||||
// Absurd input value
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(witnesses[3], note3, sk),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
0,
|
||||
tree.root(),
|
||||
"nonsensical input note value");
|
||||
|
||||
// Absurd total input value
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(witnesses[4], note4, sk),
|
||||
JSInput(witnesses[5], note5, sk)
|
||||
},
|
||||
{
|
||||
JSOutput(),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
0,
|
||||
tree.root(),
|
||||
"nonsensical left hand size of joinsplit balance");
|
||||
|
||||
// Absurd output value
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(addr, 2100000000000001),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
0,
|
||||
tree.root(),
|
||||
"nonsensical output value");
|
||||
|
||||
// Absurd total output value
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(addr, 1900000000000000),
|
||||
JSOutput(addr, 1900000000000000)
|
||||
},
|
||||
0,
|
||||
0,
|
||||
tree.root(),
|
||||
"nonsensical right hand side of joinsplit balance");
|
||||
|
||||
// Absurd total output value
|
||||
invokeAPIFailure(params,
|
||||
{
|
||||
JSInput(),
|
||||
JSInput()
|
||||
},
|
||||
{
|
||||
JSOutput(addr, 1900000000000000),
|
||||
JSOutput()
|
||||
},
|
||||
0,
|
||||
0,
|
||||
tree.root(),
|
||||
"invalid joinsplit balance");
|
||||
}
|
||||
|
||||
test_full_api(params);
|
||||
}
|
||||
|
||||
TEST(joinsplit, note_plaintexts)
|
||||
{
|
||||
uint252 a_sk = uint252(uint256S("f6da8716682d600f74fc16bd0187faad6a26b4aa4c24d5c055b216d94516840e"));
|
||||
uint256 a_pk = PRF_addr_a_pk(a_sk);
|
||||
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
|
||||
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
|
||||
SproutPaymentAddress addr_pk(a_pk, pk_enc);
|
||||
|
||||
uint256 h_sig;
|
||||
|
||||
ZCNoteEncryption encryptor(h_sig);
|
||||
uint256 epk = encryptor.get_epk();
|
||||
|
||||
SproutNote note(a_pk,
|
||||
1945813,
|
||||
random_uint256(),
|
||||
random_uint256()
|
||||
);
|
||||
|
||||
std::array<unsigned char, ZC_MEMO_SIZE> memo;
|
||||
|
||||
SproutNotePlaintext note_pt(note, memo);
|
||||
|
||||
ZCNoteEncryption::Ciphertext ct = note_pt.encrypt(encryptor, pk_enc);
|
||||
|
||||
ZCNoteDecryption decryptor(sk_enc);
|
||||
|
||||
auto decrypted = SproutNotePlaintext::decrypt(decryptor, ct, epk, h_sig, 0);
|
||||
auto decrypted_note = decrypted.note(addr_pk);
|
||||
|
||||
ASSERT_TRUE(decrypted_note.a_pk == note.a_pk);
|
||||
ASSERT_TRUE(decrypted_note.rho == note.rho);
|
||||
ASSERT_TRUE(decrypted_note.r == note.r);
|
||||
ASSERT_TRUE(decrypted_note.value() == note.value());
|
||||
|
||||
ASSERT_TRUE(decrypted.memo() == note_pt.memo());
|
||||
|
||||
// Check memo() returns by reference, not return by value, for use cases such as:
|
||||
// std::string data(plaintext.memo().begin(), plaintext.memo().end());
|
||||
ASSERT_TRUE(decrypted.memo().data() == decrypted.memo().data());
|
||||
|
||||
// Check serialization of note plaintext
|
||||
CDataStream ss(SER_DISK, PROTOCOL_VERSION);
|
||||
ss << note_pt;
|
||||
SproutNotePlaintext note_pt2;
|
||||
ss >> note_pt2;
|
||||
ASSERT_EQ(note_pt.value(), note.value());
|
||||
ASSERT_EQ(note_pt.value(), note_pt2.value());
|
||||
ASSERT_EQ(note_pt.memo(), note_pt2.memo());
|
||||
ASSERT_EQ(note_pt.rho, note_pt2.rho);
|
||||
ASSERT_EQ(note_pt.r, note_pt2.r);
|
||||
}
|
||||
|
||||
TEST(joinsplit, note_class)
|
||||
{
|
||||
uint252 a_sk = uint252(uint256S("f6da8716682d600f74fc16bd0187faad6a26b4aa4c24d5c055b216d94516840e"));
|
||||
uint256 a_pk = PRF_addr_a_pk(a_sk);
|
||||
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
|
||||
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
|
||||
SproutPaymentAddress addr_pk(a_pk, pk_enc);
|
||||
|
||||
SproutNote note(a_pk,
|
||||
1945813,
|
||||
random_uint256(),
|
||||
random_uint256());
|
||||
|
||||
SproutNote clone = note;
|
||||
ASSERT_NE(¬e, &clone);
|
||||
ASSERT_EQ(note.value(), clone.value());
|
||||
ASSERT_EQ(note.cm(), clone.cm());
|
||||
ASSERT_EQ(note.rho, clone.rho);
|
||||
ASSERT_EQ(note.r, clone.r);
|
||||
ASSERT_EQ(note.a_pk, clone.a_pk);
|
||||
}
|
||||
@@ -95,101 +95,6 @@ TEST(keystore_tests, sapling_keys) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(keystore_tests, store_and_retrieve_spending_key) {
|
||||
CBasicKeyStore keyStore;
|
||||
libzcash::SproutSpendingKey skOut;
|
||||
|
||||
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||
keyStore.GetSproutPaymentAddresses(addrs);
|
||||
EXPECT_EQ(0, addrs.size());
|
||||
|
||||
auto sk = libzcash::SproutSpendingKey::random();
|
||||
auto addr = sk.address();
|
||||
|
||||
// Sanity-check: we can't get a key we haven't added
|
||||
EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr));
|
||||
EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut));
|
||||
|
||||
keyStore.AddSproutSpendingKey(sk);
|
||||
EXPECT_TRUE(keyStore.HaveSproutSpendingKey(addr));
|
||||
EXPECT_TRUE(keyStore.GetSproutSpendingKey(addr, skOut));
|
||||
EXPECT_EQ(sk, skOut);
|
||||
|
||||
keyStore.GetSproutPaymentAddresses(addrs);
|
||||
EXPECT_EQ(1, addrs.size());
|
||||
EXPECT_EQ(1, addrs.count(addr));
|
||||
}
|
||||
|
||||
TEST(keystore_tests, store_and_retrieve_note_decryptor) {
|
||||
CBasicKeyStore keyStore;
|
||||
ZCNoteDecryption decOut;
|
||||
|
||||
auto sk = libzcash::SproutSpendingKey::random();
|
||||
auto addr = sk.address();
|
||||
|
||||
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||
|
||||
keyStore.AddSproutSpendingKey(sk);
|
||||
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||
EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut);
|
||||
}
|
||||
|
||||
TEST(keystore_tests, StoreAndRetrieveViewingKey) {
|
||||
CBasicKeyStore keyStore;
|
||||
libzcash::SproutViewingKey vkOut;
|
||||
libzcash::SproutSpendingKey skOut;
|
||||
ZCNoteDecryption decOut;
|
||||
|
||||
auto sk = libzcash::SproutSpendingKey::random();
|
||||
auto vk = sk.viewing_key();
|
||||
auto addr = sk.address();
|
||||
|
||||
// Sanity-check: we can't get a viewing key we haven't added
|
||||
EXPECT_FALSE(keyStore.HaveSproutViewingKey(addr));
|
||||
EXPECT_FALSE(keyStore.GetSproutViewingKey(addr, vkOut));
|
||||
|
||||
// and we shouldn't have a spending key or decryptor either
|
||||
EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr));
|
||||
EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut));
|
||||
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||
|
||||
// and we can't find it in our list of addresses
|
||||
std::set<libzcash::SproutPaymentAddress> addresses;
|
||||
keyStore.GetSproutPaymentAddresses(addresses);
|
||||
EXPECT_FALSE(addresses.count(addr));
|
||||
|
||||
keyStore.AddSproutViewingKey(vk);
|
||||
EXPECT_TRUE(keyStore.HaveSproutViewingKey(addr));
|
||||
EXPECT_TRUE(keyStore.GetSproutViewingKey(addr, vkOut));
|
||||
EXPECT_EQ(vk, vkOut);
|
||||
|
||||
// We should still not have the spending key...
|
||||
EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr));
|
||||
EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut));
|
||||
|
||||
// ... but we should have a decryptor
|
||||
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||
EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut);
|
||||
|
||||
// ... and we should find it in our list of addresses
|
||||
addresses.clear();
|
||||
keyStore.GetSproutPaymentAddresses(addresses);
|
||||
EXPECT_TRUE(addresses.count(addr));
|
||||
|
||||
keyStore.RemoveSproutViewingKey(vk);
|
||||
EXPECT_FALSE(keyStore.HaveSproutViewingKey(addr));
|
||||
EXPECT_FALSE(keyStore.GetSproutViewingKey(addr, vkOut));
|
||||
EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr));
|
||||
EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut));
|
||||
addresses.clear();
|
||||
keyStore.GetSproutPaymentAddresses(addresses);
|
||||
EXPECT_FALSE(addresses.count(addr));
|
||||
|
||||
// We still have a decryptor because those are cached in memory
|
||||
// (and also we only remove viewing keys when adding a spending key)
|
||||
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||
EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut);
|
||||
}
|
||||
|
||||
// Sapling
|
||||
TEST(keystore_tests, StoreAndRetrieveSaplingSpendingKey) {
|
||||
@@ -280,9 +185,6 @@ TEST(keystore_tests, StoreAndRetrieveHDSeedInEncryptedStore) {
|
||||
// 3) Test adding a new seed to an already-encrypted key store
|
||||
TestCCryptoKeyStore keyStore2;
|
||||
|
||||
// Add a Sprout address so the wallet has something to test when decrypting
|
||||
ASSERT_TRUE(keyStore2.AddSproutSpendingKey(libzcash::SproutSpendingKey::random()));
|
||||
|
||||
ASSERT_TRUE(keyStore2.EncryptKeys(vMasterKey));
|
||||
ASSERT_TRUE(keyStore2.Unlock(vMasterKey));
|
||||
|
||||
@@ -296,78 +198,4 @@ TEST(keystore_tests, StoreAndRetrieveHDSeedInEncryptedStore) {
|
||||
EXPECT_EQ(seed3, seedOut);
|
||||
}
|
||||
|
||||
TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) {
|
||||
TestCCryptoKeyStore keyStore;
|
||||
uint256 r {GetRandHash()};
|
||||
CKeyingMaterial vMasterKey (r.begin(), r.end());
|
||||
libzcash::SproutSpendingKey keyOut;
|
||||
ZCNoteDecryption decOut;
|
||||
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||
|
||||
// 1) Test adding a key to an unencrypted key store, then encrypting it
|
||||
auto sk = libzcash::SproutSpendingKey::random();
|
||||
auto addr = sk.address();
|
||||
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||
|
||||
keyStore.AddSproutSpendingKey(sk);
|
||||
ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr));
|
||||
ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr, keyOut));
|
||||
ASSERT_EQ(sk, keyOut);
|
||||
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||
EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut);
|
||||
|
||||
ASSERT_TRUE(keyStore.EncryptKeys(vMasterKey));
|
||||
ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr));
|
||||
ASSERT_FALSE(keyStore.GetSproutSpendingKey(addr, keyOut));
|
||||
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||
EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut);
|
||||
|
||||
// Unlocking with a random key should fail
|
||||
uint256 r2 {GetRandHash()};
|
||||
CKeyingMaterial vRandomKey (r2.begin(), r2.end());
|
||||
EXPECT_FALSE(keyStore.Unlock(vRandomKey));
|
||||
|
||||
// Unlocking with a slightly-modified vMasterKey should fail
|
||||
CKeyingMaterial vModifiedKey (r.begin(), r.end());
|
||||
vModifiedKey[0] += 1;
|
||||
EXPECT_FALSE(keyStore.Unlock(vModifiedKey));
|
||||
|
||||
// Unlocking with vMasterKey should succeed
|
||||
ASSERT_TRUE(keyStore.Unlock(vMasterKey));
|
||||
ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr, keyOut));
|
||||
ASSERT_EQ(sk, keyOut);
|
||||
|
||||
keyStore.GetSproutPaymentAddresses(addrs);
|
||||
ASSERT_EQ(1, addrs.size());
|
||||
ASSERT_EQ(1, addrs.count(addr));
|
||||
|
||||
// 2) Test adding a spending key to an already-encrypted key store
|
||||
auto sk2 = libzcash::SproutSpendingKey::random();
|
||||
auto addr2 = sk2.address();
|
||||
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr2, decOut));
|
||||
|
||||
keyStore.AddSproutSpendingKey(sk2);
|
||||
ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr2));
|
||||
ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr2, keyOut));
|
||||
ASSERT_EQ(sk2, keyOut);
|
||||
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut));
|
||||
EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut);
|
||||
|
||||
ASSERT_TRUE(keyStore.Lock());
|
||||
ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr2));
|
||||
ASSERT_FALSE(keyStore.GetSproutSpendingKey(addr2, keyOut));
|
||||
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut));
|
||||
EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut);
|
||||
|
||||
ASSERT_TRUE(keyStore.Unlock(vMasterKey));
|
||||
ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr2, keyOut));
|
||||
ASSERT_EQ(sk2, keyOut);
|
||||
EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut));
|
||||
EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut);
|
||||
|
||||
keyStore.GetSproutPaymentAddresses(addrs);
|
||||
ASSERT_EQ(2, addrs.size());
|
||||
ASSERT_EQ(1, addrs.count(addr));
|
||||
ASSERT_EQ(1, addrs.count(addr2));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "test/data/merkle_roots.json.h"
|
||||
#include "test/data/merkle_roots_empty.json.h"
|
||||
#include "test/data/merkle_serialization.json.h"
|
||||
#include "test/data/merkle_witness_serialization.json.h"
|
||||
#include "test/data/merkle_path.json.h"
|
||||
#include "test/data/merkle_commitments.json.h"
|
||||
|
||||
#include "test/data/merkle_roots_sapling.json.h"
|
||||
#include "test/data/merkle_roots_empty_sapling.json.h"
|
||||
#include "test/data/merkle_serialization_sapling.json.h"
|
||||
#include "test/data/merkle_witness_serialization_sapling.json.h"
|
||||
#include "test/data/merkle_path_sapling.json.h"
|
||||
@@ -26,17 +24,11 @@
|
||||
#include "zcash/IncrementalMerkleTree.hpp"
|
||||
#include "zcash/util.h"
|
||||
|
||||
#include <libsnark/common/default_types/r1cs_ppzksnark_pp.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
#include <libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp>
|
||||
#include <libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "json_test_vectors.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace libsnark;
|
||||
|
||||
template<>
|
||||
void expect_deser_same(const SproutTestingWitness& expected)
|
||||
@@ -58,8 +50,7 @@ void test_tree(
|
||||
UniValue root_tests,
|
||||
UniValue ser_tests,
|
||||
UniValue witness_ser_tests,
|
||||
UniValue path_tests,
|
||||
bool libsnark_test
|
||||
UniValue path_tests
|
||||
)
|
||||
{
|
||||
size_t witness_ser_i = 0;
|
||||
@@ -115,55 +106,6 @@ void test_tree(
|
||||
} else {
|
||||
auto path = wit.path();
|
||||
expect_test_vector(path_tests[path_i++], path);
|
||||
|
||||
if (libsnark_test) {
|
||||
typedef Fr<default_r1cs_ppzksnark_pp> FieldT;
|
||||
|
||||
protoboard<FieldT> pb;
|
||||
pb_variable_array<FieldT> positions;
|
||||
digest_variable<FieldT> commitment(pb, 256, "commitment");
|
||||
digest_variable<FieldT> root(pb, 256, "root");
|
||||
positions.allocate(pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, "pos");
|
||||
merkle_authentication_path_variable<FieldT, sha256_two_to_one_hash_gadget<FieldT>> authvars(pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, "auth");
|
||||
merkle_tree_check_read_gadget<FieldT, sha256_two_to_one_hash_gadget<FieldT>> auth(
|
||||
pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, positions, commitment, root, authvars, ONE, "path"
|
||||
);
|
||||
commitment.generate_r1cs_constraints();
|
||||
root.generate_r1cs_constraints();
|
||||
authvars.generate_r1cs_constraints();
|
||||
auth.generate_r1cs_constraints();
|
||||
|
||||
std::vector<bool> commitment_bv;
|
||||
{
|
||||
uint256 witnessed_commitment = wit.element();
|
||||
std::vector<unsigned char> commitment_v(witnessed_commitment.begin(), witnessed_commitment.end());
|
||||
commitment_bv = convertBytesVectorToVector(commitment_v);
|
||||
}
|
||||
|
||||
size_t path_index = convertVectorToInt(path.index);
|
||||
|
||||
commitment.bits.fill_with_bits(pb, bit_vector(commitment_bv));
|
||||
positions.fill_with_bits_of_uint64(pb, path_index);
|
||||
|
||||
authvars.generate_r1cs_witness(path_index, path.authentication_path);
|
||||
auth.generate_r1cs_witness();
|
||||
|
||||
std::vector<bool> root_bv;
|
||||
{
|
||||
uint256 witroot = wit.root();
|
||||
std::vector<unsigned char> root_v(witroot.begin(), witroot.end());
|
||||
root_bv = convertBytesVectorToVector(root_v);
|
||||
}
|
||||
|
||||
root.bits.fill_with_bits(pb, bit_vector(root_bv));
|
||||
|
||||
ASSERT_TRUE(pb.is_satisfied());
|
||||
|
||||
root_bv[0] = !root_bv[0];
|
||||
root.bits.fill_with_bits(pb, bit_vector(root_bv));
|
||||
|
||||
ASSERT_TRUE(!pb.is_satisfied());
|
||||
}
|
||||
}
|
||||
|
||||
// Check witness serialization
|
||||
@@ -200,8 +142,7 @@ TEST(merkletree, vectors) {
|
||||
root_tests,
|
||||
ser_tests,
|
||||
witness_ser_tests,
|
||||
path_tests,
|
||||
true
|
||||
path_tests
|
||||
);
|
||||
}
|
||||
|
||||
@@ -217,18 +158,19 @@ TEST(merkletree, SaplingVectors) {
|
||||
root_tests,
|
||||
ser_tests,
|
||||
witness_ser_tests,
|
||||
path_tests,
|
||||
false
|
||||
path_tests
|
||||
);
|
||||
}
|
||||
|
||||
TEST(merkletree, emptyroots) {
|
||||
UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty));
|
||||
|
||||
libzcash::EmptyMerkleRoots<64, libzcash::SHA256Compress> emptyroots;
|
||||
std::array<libzcash::SHA256Compress, 65> computed;
|
||||
|
||||
for (size_t depth = 0; depth <= 64; depth++) {
|
||||
expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth));
|
||||
computed.at(0) = libzcash::SHA256Compress::uncommitted();
|
||||
ASSERT_TRUE(emptyroots.empty_root(0) == computed.at(0));
|
||||
for (size_t d = 1; d <= 64; d++) {
|
||||
computed.at(d) = libzcash::SHA256Compress::combine(computed.at(d-1), computed.at(d-1), d-1);
|
||||
ASSERT_TRUE(emptyroots.empty_root(d) == computed.at(d));
|
||||
}
|
||||
|
||||
// Double check that we're testing (at least) all the empty roots we'll use.
|
||||
@@ -236,12 +178,14 @@ TEST(merkletree, emptyroots) {
|
||||
}
|
||||
|
||||
TEST(merkletree, EmptyrootsSapling) {
|
||||
UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty_sapling));
|
||||
|
||||
libzcash::EmptyMerkleRoots<62, libzcash::PedersenHash> emptyroots;
|
||||
std::array<libzcash::PedersenHash, 63> computed;
|
||||
|
||||
for (size_t depth = 0; depth <= 62; depth++) {
|
||||
expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth));
|
||||
computed.at(0) = libzcash::PedersenHash::uncommitted();
|
||||
ASSERT_TRUE(emptyroots.empty_root(0) == computed.at(0));
|
||||
for (size_t d = 1; d <= 62; d++) {
|
||||
computed.at(d) = libzcash::PedersenHash::combine(computed.at(d-1), computed.at(d-1), d-1);
|
||||
ASSERT_TRUE(emptyroots.empty_root(d) == computed.at(d));
|
||||
}
|
||||
|
||||
// Double check that we're testing (at least) all the empty roots we'll use.
|
||||
@@ -249,7 +193,7 @@ TEST(merkletree, EmptyrootsSapling) {
|
||||
}
|
||||
|
||||
TEST(merkletree, emptyroot) {
|
||||
// This literal is the depth-20 empty tree root with the bytes reversed to
|
||||
// This literal is the depth-29 empty tree root with the bytes reversed to
|
||||
// account for the fact that uint256S() loads a big-endian representation of
|
||||
// an integer which converted to little-endian internally.
|
||||
uint256 expected = uint256S("59d2cde5e65c1414c32ba54f0fe4bdb3d67618125286e6a191317917c812c6d7");
|
||||
@@ -258,7 +202,7 @@ TEST(merkletree, emptyroot) {
|
||||
}
|
||||
|
||||
TEST(merkletree, EmptyrootSapling) {
|
||||
// This literal is the depth-20 empty tree root with the bytes reversed to
|
||||
// This literal is the depth-32 empty tree root with the bytes reversed to
|
||||
// account for the fact that uint256S() loads a big-endian representation of
|
||||
// an integer which converted to little-endian internally.
|
||||
uint256 expected = uint256S("3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb");
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "chainparams.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "zcash/Address.hpp"
|
||||
#include "wallet/wallet.h"
|
||||
#include "amount.h"
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <iostream>
|
||||
#include "util.h"
|
||||
|
||||
#include "paymentdisclosure.h"
|
||||
#include "paymentdisclosuredb.h"
|
||||
|
||||
#include "sodium.h"
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
To run tests:
|
||||
./zcash-gtest --gtest_filter="paymentdisclosure.*"
|
||||
|
||||
Note: As an experimental feature, writing your own tests may require option flags to be set.
|
||||
mapArgs["-experimentalfeatures"] = true;
|
||||
mapArgs["-paymentdisclosure"] = true;
|
||||
*/
|
||||
|
||||
#define NUM_TRIES 10000
|
||||
|
||||
#define DUMP_DATABASE_TO_STDOUT false
|
||||
|
||||
static boost::uuids::random_generator uuidgen;
|
||||
|
||||
static uint256 random_uint256()
|
||||
{
|
||||
uint256 ret;
|
||||
randombytes_buf(ret.begin(), 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Subclass of PaymentDisclosureDB to add debugging methods
|
||||
class PaymentDisclosureDBTest : public PaymentDisclosureDB {
|
||||
public:
|
||||
PaymentDisclosureDBTest(const boost::filesystem::path& dbPath) : PaymentDisclosureDB(dbPath) {}
|
||||
|
||||
void DebugDumpAllStdout() {
|
||||
ASSERT_NE(db, nullptr);
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
|
||||
// Iterate over each item in the database and print them
|
||||
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
|
||||
|
||||
for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
||||
cout << it->key().ToString() << " : ";
|
||||
// << it->value().ToString() << endl;
|
||||
try {
|
||||
std::string strValue = it->value().ToString();
|
||||
PaymentDisclosureInfo info;
|
||||
CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
|
||||
ssValue >> info;
|
||||
cout << info.ToString() << std::endl;
|
||||
} catch (const std::exception& e) {
|
||||
cout << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (false == it->status().ok()) {
|
||||
cerr << "An error was found iterating over the database" << endl;
|
||||
cerr << it->status().ToString() << endl;
|
||||
}
|
||||
|
||||
delete it;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// This test creates random payment disclosure blobs and checks that they can be
|
||||
// 1. inserted and retrieved from a database
|
||||
// 2. serialized and deserialized without corruption
|
||||
// Note that the zpd: prefix is not part of the payment disclosure blob itself. It is only
|
||||
// used as convention to improve the user experience when sharing payment disclosure blobs.
|
||||
TEST(paymentdisclosure, mainnet) {
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
|
||||
boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
|
||||
boost::filesystem::create_directories(pathTemp);
|
||||
mapArgs["-datadir"] = pathTemp.string();
|
||||
|
||||
std::cout << "Test payment disclosure database created in folder: " << pathTemp.string() << std::endl;
|
||||
|
||||
PaymentDisclosureDBTest mydb(pathTemp);
|
||||
|
||||
for (int i=0; i<NUM_TRIES; i++) {
|
||||
// Generate an ephemeral keypair for joinsplit sig.
|
||||
uint256 joinSplitPubKey;
|
||||
unsigned char buffer[crypto_sign_SECRETKEYBYTES] = {0};
|
||||
crypto_sign_keypair(joinSplitPubKey.begin(), &buffer[0]);
|
||||
|
||||
// First 32 bytes contain private key, second 32 bytes contain public key.
|
||||
ASSERT_EQ(0, memcmp(joinSplitPubKey.begin(), &buffer[0]+32, 32));
|
||||
std::vector<unsigned char> vch(&buffer[0], &buffer[0] + 32);
|
||||
uint256 joinSplitPrivKey = uint256(vch);
|
||||
|
||||
// Create payment disclosure key and info data to store in test database
|
||||
size_t js = random_uint256().GetCheapHash() % std::numeric_limits<size_t>::max();
|
||||
uint8_t n = random_uint256().GetCheapHash() % std::numeric_limits<uint8_t>::max();
|
||||
PaymentDisclosureKey key { random_uint256(), js, n};
|
||||
PaymentDisclosureInfo info;
|
||||
info.esk = random_uint256();
|
||||
info.joinSplitPrivKey = joinSplitPrivKey;
|
||||
info.zaddr = libzcash::SproutSpendingKey::random().address();
|
||||
ASSERT_TRUE(mydb.Put(key, info));
|
||||
|
||||
// Retrieve info from test database into new local variable and test it matches
|
||||
PaymentDisclosureInfo info2;
|
||||
ASSERT_TRUE(mydb.Get(key, info2));
|
||||
ASSERT_EQ(info, info2);
|
||||
|
||||
// Modify this local variable and confirm it no longer matches
|
||||
info2.esk = random_uint256();
|
||||
info2.joinSplitPrivKey = random_uint256();
|
||||
info2.zaddr = libzcash::SproutSpendingKey::random().address();
|
||||
ASSERT_NE(info, info2);
|
||||
|
||||
// Using the payment info object, let's create a dummy payload
|
||||
PaymentDisclosurePayload payload;
|
||||
payload.version = PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL;
|
||||
payload.esk = info.esk;
|
||||
payload.txid = key.hash;
|
||||
payload.js = key.js;
|
||||
payload.n = key.n;
|
||||
payload.message = "random-" + boost::uuids::to_string(uuidgen()); // random message
|
||||
payload.zaddr = info.zaddr;
|
||||
|
||||
// Serialize and hash the payload to generate a signature
|
||||
uint256 dataToBeSigned = SerializeHash(payload, SER_GETHASH, 0);
|
||||
|
||||
// Compute the payload signature
|
||||
unsigned char payloadSig[64];
|
||||
if (!(crypto_sign_detached(&payloadSig[0], NULL,
|
||||
dataToBeSigned.begin(), 32,
|
||||
&buffer[0] // buffer containing both private and public key required
|
||||
) == 0))
|
||||
{
|
||||
throw std::runtime_error("crypto_sign_detached failed");
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (!(crypto_sign_verify_detached(&payloadSig[0],
|
||||
dataToBeSigned.begin(), 32,
|
||||
joinSplitPubKey.begin()
|
||||
) == 0))
|
||||
{
|
||||
throw std::runtime_error("crypto_sign_verify_detached failed");
|
||||
}
|
||||
|
||||
// Convert signature buffer to boost array
|
||||
std::array<unsigned char, 64> arrayPayloadSig;
|
||||
memcpy(arrayPayloadSig.data(), &payloadSig[0], 64);
|
||||
|
||||
// Payment disclosure blob to pass around
|
||||
PaymentDisclosure pd = {payload, arrayPayloadSig};
|
||||
|
||||
// Test payment disclosure constructors
|
||||
PaymentDisclosure pd2(payload, arrayPayloadSig);
|
||||
ASSERT_EQ(pd, pd2);
|
||||
PaymentDisclosure pd3(joinSplitPubKey, key, info, payload.message);
|
||||
ASSERT_EQ(pd, pd3);
|
||||
|
||||
// Verify serialization and deserialization works
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << pd;
|
||||
std::string ssHexString = HexStr(ss.begin(), ss.end());
|
||||
|
||||
PaymentDisclosure pdTmp;
|
||||
CDataStream ssTmp(ParseHex(ssHexString), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ssTmp >> pdTmp;
|
||||
ASSERT_EQ(pd, pdTmp);
|
||||
|
||||
CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss2 << pdTmp;
|
||||
std::string ss2HexString = HexStr(ss2.begin(), ss2.end());
|
||||
ASSERT_EQ(ssHexString, ss2HexString);
|
||||
|
||||
// Verify marker
|
||||
ASSERT_EQ(pd.payload.marker, PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES);
|
||||
ASSERT_EQ(pdTmp.payload.marker, PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES);
|
||||
ASSERT_EQ(0, ssHexString.find("706462ff")); // Little endian encoding of PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES value
|
||||
|
||||
// Sanity check
|
||||
PaymentDisclosure pdDummy;
|
||||
ASSERT_NE(pd, pdDummy);
|
||||
}
|
||||
|
||||
#if DUMP_DATABASE_TO_STDOUT == true
|
||||
mydb.DebugDumpAllStdout();
|
||||
#endif
|
||||
}
|
||||
@@ -1,702 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "zcash/Proof.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <libsnark/common/default_types/r1cs_ppzksnark_pp.hpp>
|
||||
#include <libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
|
||||
using namespace libzcash;
|
||||
|
||||
typedef libsnark::default_r1cs_ppzksnark_pp curve_pp;
|
||||
typedef libsnark::default_r1cs_ppzksnark_pp::G1_type curve_G1;
|
||||
typedef libsnark::default_r1cs_ppzksnark_pp::G2_type curve_G2;
|
||||
typedef libsnark::default_r1cs_ppzksnark_pp::GT_type curve_GT;
|
||||
typedef libsnark::default_r1cs_ppzksnark_pp::Fp_type curve_Fr;
|
||||
typedef libsnark::default_r1cs_ppzksnark_pp::Fq_type curve_Fq;
|
||||
typedef libsnark::default_r1cs_ppzksnark_pp::Fqe_type curve_Fq2;
|
||||
|
||||
#include "streams.h"
|
||||
#include "version.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
TEST(proofs, g1_pairing_at_infinity)
|
||||
{
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
auto r1 = curve_G1::random_element();
|
||||
auto r2 = curve_G2::random_element();
|
||||
ASSERT_TRUE(
|
||||
curve_pp::reduced_pairing(curve_G1::zero(), r2) ==
|
||||
curve_GT::one()
|
||||
);
|
||||
ASSERT_TRUE(
|
||||
curve_pp::final_exponentiation(
|
||||
curve_pp::double_miller_loop(
|
||||
curve_pp::precompute_G1(curve_G1::zero()),
|
||||
curve_pp::precompute_G2(r2),
|
||||
curve_pp::precompute_G1(curve_G1::zero()),
|
||||
curve_pp::precompute_G2(r2)
|
||||
)
|
||||
) ==
|
||||
curve_GT::one()
|
||||
);
|
||||
ASSERT_TRUE(
|
||||
curve_pp::final_exponentiation(
|
||||
curve_pp::double_miller_loop(
|
||||
curve_pp::precompute_G1(r1),
|
||||
curve_pp::precompute_G2(r2),
|
||||
curve_pp::precompute_G1(curve_G1::zero()),
|
||||
curve_pp::precompute_G2(r2)
|
||||
)
|
||||
) ==
|
||||
curve_pp::reduced_pairing(r1, r2)
|
||||
);
|
||||
ASSERT_TRUE(
|
||||
curve_pp::final_exponentiation(
|
||||
curve_pp::double_miller_loop(
|
||||
curve_pp::precompute_G1(curve_G1::zero()),
|
||||
curve_pp::precompute_G2(r2),
|
||||
curve_pp::precompute_G1(r1),
|
||||
curve_pp::precompute_G2(r2)
|
||||
)
|
||||
) ==
|
||||
curve_pp::reduced_pairing(r1, r2)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(proofs, g2_subgroup_check)
|
||||
{
|
||||
// all G2 elements are order r
|
||||
ASSERT_TRUE(libsnark::alt_bn128_modulus_r * curve_G2::random_element() == curve_G2::zero());
|
||||
|
||||
// but that doesn't mean all elements that satisfy the curve equation are in G2...
|
||||
curve_G2 p = curve_G2::one();
|
||||
|
||||
while (1) {
|
||||
// This will construct an order r(2q-r) point with high probability
|
||||
p.X = curve_Fq2::random_element();
|
||||
try {
|
||||
p.Y = ((p.X.squared() * p.X) + libsnark::alt_bn128_twist_coeff_b).sqrt();
|
||||
break;
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
ASSERT_TRUE(p.is_well_formed()); // it's on the curve
|
||||
ASSERT_TRUE(libsnark::alt_bn128_modulus_r * p != curve_G2::zero()); // but not the order r subgroup..
|
||||
|
||||
{
|
||||
// libsnark unfortunately doesn't check, and the pairing will complete
|
||||
auto e = curve_Fr("149");
|
||||
auto a = curve_pp::reduced_pairing(curve_G1::one(), p);
|
||||
auto b = curve_pp::reduced_pairing(e * curve_G1::one(), p);
|
||||
|
||||
// though it will not preserve bilinearity
|
||||
ASSERT_TRUE((a^e) != b);
|
||||
}
|
||||
|
||||
{
|
||||
// so, our decompression API should not allow you to decompress G2 elements of that form!
|
||||
CompressedG2 badp(p);
|
||||
try {
|
||||
auto newp = badp.to_libsnark_g2<curve_G2>();
|
||||
FAIL() << "Expected std::runtime_error";
|
||||
} catch (std::runtime_error const & err) {
|
||||
EXPECT_EQ(err.what(), std::string("point is not in G2"));
|
||||
} catch(...) {
|
||||
FAIL() << "Expected std::runtime_error";
|
||||
}
|
||||
}
|
||||
|
||||
// educational purposes: showing that E'(Fp2) is of order r(2q-r),
|
||||
// by multiplying our random point in E' by (2q-r) = (q + q - r) to
|
||||
// get an element in G2
|
||||
{
|
||||
auto p1 = libsnark::alt_bn128_modulus_q * p;
|
||||
p1 = p1 + p1;
|
||||
p1 = p1 - (libsnark::alt_bn128_modulus_r * p);
|
||||
|
||||
ASSERT_TRUE(p1.is_well_formed());
|
||||
ASSERT_TRUE(libsnark::alt_bn128_modulus_r * p1 == curve_G2::zero());
|
||||
|
||||
CompressedG2 goodp(p1);
|
||||
auto newp = goodp.to_libsnark_g2<curve_G2>();
|
||||
|
||||
ASSERT_TRUE(newp == p1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(proofs, sqrt_zero)
|
||||
{
|
||||
ASSERT_TRUE(curve_Fq::zero() == curve_Fq::zero().sqrt());
|
||||
ASSERT_TRUE(curve_Fq2::zero() == curve_Fq2::zero().sqrt());
|
||||
}
|
||||
|
||||
TEST(proofs, sqrt_fq)
|
||||
{
|
||||
// Poor man's PRNG
|
||||
curve_Fq acc = curve_Fq("348957923485290374852379485") ^ 1000;
|
||||
|
||||
size_t quadratic_residues = 0;
|
||||
size_t quadratic_nonresidues = 0;
|
||||
|
||||
for (size_t i = 1; i < 1000; i++) {
|
||||
try {
|
||||
acc += curve_Fq("45634563456") ^ i;
|
||||
|
||||
curve_Fq x = acc.sqrt();
|
||||
ASSERT_TRUE((x*x) == acc);
|
||||
quadratic_residues += 1;
|
||||
} catch (std::runtime_error &e) {
|
||||
quadratic_nonresidues += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Half of all nonzero elements in Fp are quadratic residues
|
||||
ASSERT_TRUE(quadratic_residues == 511);
|
||||
ASSERT_TRUE(quadratic_nonresidues == 488);
|
||||
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
curve_Fq x = curve_Fq::random_element();
|
||||
curve_Fq x2 = x * x;
|
||||
|
||||
ASSERT_TRUE((x2.sqrt() == x) || (x2.sqrt() == -x));
|
||||
}
|
||||
|
||||
// Test vectors
|
||||
ASSERT_TRUE(
|
||||
curve_Fq("5204065062716160319596273903996315000119019512886596366359652578430118331601")
|
||||
==
|
||||
curve_Fq("348579348568").sqrt()
|
||||
);
|
||||
ASSERT_THROW(curve_Fq("348579348569").sqrt(), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST(proofs, sqrt_fq2)
|
||||
{
|
||||
curve_Fq2 acc = curve_Fq2(
|
||||
curve_Fq("3456293840592348059238409578239048769348760238476029347885092384059238459834") ^ 1000,
|
||||
curve_Fq("2394578084760439457823945729347502374590283479582739485723945729384759823745") ^ 1000
|
||||
);
|
||||
|
||||
size_t quadratic_residues = 0;
|
||||
size_t quadratic_nonresidues = 0;
|
||||
|
||||
for (size_t i = 1; i < 1000; i++) {
|
||||
try {
|
||||
acc = acc + curve_Fq2(
|
||||
curve_Fq("5204065062716160319596273903996315000119019512886596366359652578430118331601") ^ i,
|
||||
curve_Fq("348957923485290374852379485348957923485290374852379485348957923485290374852") ^ i
|
||||
);
|
||||
|
||||
curve_Fq2 x = acc.sqrt();
|
||||
ASSERT_TRUE((x*x) == acc);
|
||||
quadratic_residues += 1;
|
||||
} catch (std::runtime_error &e) {
|
||||
quadratic_nonresidues += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Half of all nonzero elements in Fp^k are quadratic residues as long
|
||||
// as p != 2
|
||||
ASSERT_TRUE(quadratic_residues == 505);
|
||||
ASSERT_TRUE(quadratic_nonresidues == 494);
|
||||
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
curve_Fq2 x = curve_Fq2::random_element();
|
||||
curve_Fq2 x2 = x * x;
|
||||
|
||||
ASSERT_TRUE((x2.sqrt() == x) || (x2.sqrt() == -x));
|
||||
}
|
||||
|
||||
// Test vectors
|
||||
ASSERT_THROW(curve_Fq2(
|
||||
curve_Fq("2"),
|
||||
curve_Fq("1")
|
||||
).sqrt(), std::runtime_error);
|
||||
|
||||
ASSERT_THROW(curve_Fq2(
|
||||
curve_Fq("3345897230485723946872934576923485762803457692345760237495682347502347589473"),
|
||||
curve_Fq("1234912378405347958234756902345768290345762348957605678245967234857634857676")
|
||||
).sqrt(), std::runtime_error);
|
||||
|
||||
curve_Fq2 x = curve_Fq2(
|
||||
curve_Fq("12844195307879678418043983815760255909500142247603239203345049921980497041944"),
|
||||
curve_Fq("7476417578426924565731404322659619974551724117137577781074613937423560117731")
|
||||
);
|
||||
|
||||
curve_Fq2 nx = -x;
|
||||
|
||||
curve_Fq2 x2 = curve_Fq2(
|
||||
curve_Fq("3345897230485723946872934576923485762803457692345760237495682347502347589474"),
|
||||
curve_Fq("1234912378405347958234756902345768290345762348957605678245967234857634857676")
|
||||
);
|
||||
|
||||
ASSERT_TRUE(x == x2.sqrt());
|
||||
ASSERT_TRUE(nx == -x2.sqrt());
|
||||
ASSERT_TRUE(x*x == x2);
|
||||
ASSERT_TRUE(nx*nx == x2);
|
||||
}
|
||||
|
||||
TEST(proofs, size_is_expected)
|
||||
{
|
||||
PHGRProof p;
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << p;
|
||||
|
||||
ASSERT_EQ(ss.size(), 296);
|
||||
}
|
||||
|
||||
TEST(proofs, fq_serializes_properly)
|
||||
{
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
curve_Fq e = curve_Fq::random_element();
|
||||
|
||||
Fq e2(e);
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << e2;
|
||||
|
||||
Fq e3;
|
||||
ss >> e3;
|
||||
|
||||
curve_Fq e4 = e3.to_libsnark_fq<curve_Fq>();
|
||||
|
||||
ASSERT_TRUE(e == e4);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(proofs, fq2_serializes_properly)
|
||||
{
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
curve_Fq2 e = curve_Fq2::random_element();
|
||||
|
||||
Fq2 e2(e);
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << e2;
|
||||
|
||||
Fq2 e3;
|
||||
ss >> e3;
|
||||
|
||||
curve_Fq2 e4 = e3.to_libsnark_fq2<curve_Fq2>();
|
||||
|
||||
ASSERT_TRUE(e == e4);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T deserialize_tv(std::string s)
|
||||
{
|
||||
T e;
|
||||
CDataStream ss(ParseHex(s), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss >> e;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
curve_Fq deserialize_fq(std::string s)
|
||||
{
|
||||
return deserialize_tv<Fq>(s).to_libsnark_fq<curve_Fq>();
|
||||
}
|
||||
|
||||
curve_Fq2 deserialize_fq2(std::string s)
|
||||
{
|
||||
return deserialize_tv<Fq2>(s).to_libsnark_fq2<curve_Fq2>();
|
||||
}
|
||||
|
||||
TEST(proofs, fq_valid)
|
||||
{
|
||||
curve_Fq e = deserialize_fq("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46");
|
||||
|
||||
ASSERT_TRUE(e == curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"));
|
||||
ASSERT_TRUE(e != curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208581"));
|
||||
|
||||
curve_Fq e2 = deserialize_fq("30644e72e131a029b75045b68181585d97816a916871ca8d3c208c16d87cfd46");
|
||||
|
||||
ASSERT_TRUE(e2 == curve_Fq("21888242871839275222221885816603420866962577604863418715751138068690288573766"));
|
||||
}
|
||||
|
||||
TEST(proofs, fq_invalid)
|
||||
{
|
||||
// Should not be able to deserialize the modulus
|
||||
ASSERT_THROW(
|
||||
deserialize_fq("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"),
|
||||
std::logic_error
|
||||
);
|
||||
|
||||
// Should not be able to deserialize the modulus plus one
|
||||
ASSERT_THROW(
|
||||
deserialize_fq("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd48"),
|
||||
std::logic_error
|
||||
);
|
||||
|
||||
// Should not be able to deserialize a ridiculously out of bound int
|
||||
ASSERT_THROW(
|
||||
deserialize_fq("ff644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"),
|
||||
std::logic_error
|
||||
);
|
||||
}
|
||||
|
||||
TEST(proofs, fq2_valid)
|
||||
{
|
||||
// (q - 1) * q + q
|
||||
curve_Fq2 e = deserialize_fq2("0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b0");
|
||||
ASSERT_TRUE(e.c0 == curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"));
|
||||
ASSERT_TRUE(e.c1 == curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"));
|
||||
|
||||
curve_Fq2 e2 = deserialize_fq2("000000000000000000000000000000000000000000000000010245be1c91e3186bbbe1c430a93fcfc5aada4ab10c3492f70eea97a91c7b29554db55acffa34d2");
|
||||
ASSERT_TRUE(e2.c0 == curve_Fq("238769481237490823"));
|
||||
ASSERT_TRUE(e2.c1 == curve_Fq("384579238459723485"));
|
||||
|
||||
curve_Fq2 e3 = deserialize_fq2("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
||||
ASSERT_TRUE(e3.c0 == curve_Fq("0"));
|
||||
ASSERT_TRUE(e3.c1 == curve_Fq("0"));
|
||||
|
||||
curve_Fq2 e4 = deserialize_fq2("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
|
||||
ASSERT_TRUE(e4.c0 == curve_Fq("1"));
|
||||
ASSERT_TRUE(e4.c1 == curve_Fq("0"));
|
||||
}
|
||||
|
||||
TEST(proofs, fq2_invalid)
|
||||
{
|
||||
// (q - 1) * q + q is invalid
|
||||
ASSERT_THROW(
|
||||
deserialize_fq2("0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b1"),
|
||||
std::logic_error
|
||||
);
|
||||
|
||||
// q * q + (q - 1) is invalid
|
||||
ASSERT_THROW(
|
||||
deserialize_fq2("0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d34cced085b43e2f202a05e52ef18233a3d8371be725c8b8e7774e4b8ffda66f7"),
|
||||
std::logic_error
|
||||
);
|
||||
|
||||
// Ridiculously out of bounds
|
||||
ASSERT_THROW(
|
||||
deserialize_fq2("0fffc4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b0"),
|
||||
std::logic_error
|
||||
);
|
||||
ASSERT_THROW(
|
||||
deserialize_fq2("ffffffff763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b0"),
|
||||
std::logic_error
|
||||
);
|
||||
}
|
||||
|
||||
TEST(proofs, g1_serializes_properly)
|
||||
{
|
||||
// Cannot serialize zero
|
||||
{
|
||||
ASSERT_THROW({CompressedG1 g = CompressedG1(curve_G1::zero());}, std::domain_error);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
curve_G1 e = curve_G1::random_element();
|
||||
|
||||
CompressedG1 e2(e);
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << e2;
|
||||
|
||||
CompressedG1 e3;
|
||||
ss >> e3;
|
||||
|
||||
ASSERT_TRUE(e2 == e3);
|
||||
|
||||
curve_G1 e4 = e3.to_libsnark_g1<curve_G1>();
|
||||
|
||||
ASSERT_TRUE(e == e4);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(proofs, g2_serializes_properly)
|
||||
{
|
||||
// Cannot serialize zero
|
||||
{
|
||||
ASSERT_THROW({CompressedG2 g = CompressedG2(curve_G2::zero());}, std::domain_error);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
curve_G2 e = curve_G2::random_element();
|
||||
|
||||
CompressedG2 e2(e);
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << e2;
|
||||
|
||||
CompressedG2 e3;
|
||||
ss >> e3;
|
||||
|
||||
ASSERT_TRUE(e2 == e3);
|
||||
|
||||
curve_G2 e4 = e3.to_libsnark_g2<curve_G2>();
|
||||
|
||||
ASSERT_TRUE(e == e4);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(proofs, zksnark_serializes_properly)
|
||||
{
|
||||
auto example = libsnark::generate_r1cs_example_with_field_input<curve_Fr>(250, 4);
|
||||
example.constraint_system.swap_AB_if_beneficial();
|
||||
auto kp = libsnark::r1cs_ppzksnark_generator<curve_pp>(example.constraint_system);
|
||||
auto vkprecomp = libsnark::r1cs_ppzksnark_verifier_process_vk(kp.vk);
|
||||
|
||||
for (size_t i = 0; i < 20; i++) {
|
||||
auto badproof = PHGRProof::random_invalid();
|
||||
auto proof = badproof.to_libsnark_proof<libsnark::r1cs_ppzksnark_proof<curve_pp>>();
|
||||
|
||||
auto verifierEnabled = ProofVerifier::Strict();
|
||||
auto verifierDisabled = ProofVerifier::Disabled();
|
||||
// This verifier should catch the bad proof
|
||||
ASSERT_FALSE(verifierEnabled.check(
|
||||
kp.vk,
|
||||
vkprecomp,
|
||||
example.primary_input,
|
||||
proof
|
||||
));
|
||||
// This verifier won't!
|
||||
ASSERT_TRUE(verifierDisabled.check(
|
||||
kp.vk,
|
||||
vkprecomp,
|
||||
example.primary_input,
|
||||
proof
|
||||
));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 20; i++) {
|
||||
auto proof = libsnark::r1cs_ppzksnark_prover<curve_pp>(
|
||||
kp.pk,
|
||||
example.primary_input,
|
||||
example.auxiliary_input,
|
||||
example.constraint_system
|
||||
);
|
||||
|
||||
{
|
||||
auto verifierEnabled = ProofVerifier::Strict();
|
||||
auto verifierDisabled = ProofVerifier::Disabled();
|
||||
ASSERT_TRUE(verifierEnabled.check(
|
||||
kp.vk,
|
||||
vkprecomp,
|
||||
example.primary_input,
|
||||
proof
|
||||
));
|
||||
ASSERT_TRUE(verifierDisabled.check(
|
||||
kp.vk,
|
||||
vkprecomp,
|
||||
example.primary_input,
|
||||
proof
|
||||
));
|
||||
}
|
||||
|
||||
ASSERT_TRUE(libsnark::r1cs_ppzksnark_verifier_strong_IC<curve_pp>(
|
||||
kp.vk,
|
||||
example.primary_input,
|
||||
proof
|
||||
));
|
||||
|
||||
PHGRProof compressed_proof_0(proof);
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << compressed_proof_0;
|
||||
|
||||
PHGRProof compressed_proof_1;
|
||||
ss >> compressed_proof_1;
|
||||
|
||||
ASSERT_TRUE(compressed_proof_0 == compressed_proof_1);
|
||||
|
||||
auto newproof = compressed_proof_1.to_libsnark_proof<libsnark::r1cs_ppzksnark_proof<curve_pp>>();
|
||||
|
||||
ASSERT_TRUE(proof == newproof);
|
||||
ASSERT_TRUE(libsnark::r1cs_ppzksnark_verifier_strong_IC<curve_pp>(
|
||||
kp.vk,
|
||||
example.primary_input,
|
||||
newproof
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(proofs, g1_deserialization)
|
||||
{
|
||||
CompressedG1 g;
|
||||
curve_G1 expected;
|
||||
|
||||
// Valid G1 element.
|
||||
{
|
||||
CDataStream ss(ParseHex("0230644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss >> g;
|
||||
|
||||
expected.X = curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582");
|
||||
expected.Y = curve_Fq("3969792565221544645472939191694882283483352126195956956354061729942568608776");
|
||||
expected.Z = curve_Fq::one();
|
||||
|
||||
ASSERT_TRUE(g.to_libsnark_g1<curve_G1>() == expected);
|
||||
}
|
||||
|
||||
// Its negation.
|
||||
{
|
||||
CDataStream ss(ParseHex("0330644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss >> g;
|
||||
|
||||
expected.X = curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582");
|
||||
expected.Y = curve_Fq("3969792565221544645472939191694882283483352126195956956354061729942568608776");
|
||||
expected.Z = curve_Fq::one();
|
||||
|
||||
ASSERT_TRUE(g.to_libsnark_g1<curve_G1>() == -expected);
|
||||
}
|
||||
|
||||
// Invalid leading bytes
|
||||
{
|
||||
CDataStream ss(ParseHex("ff30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
ASSERT_THROW(ss >> g, std::ios_base::failure);
|
||||
}
|
||||
|
||||
// Invalid point
|
||||
{
|
||||
CDataStream ss(ParseHex("0208c6d2adffacbc8438f09f321874ea66e2fcc29f8dcfec2caefa21ec8c96a77c"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss >> g;
|
||||
|
||||
ASSERT_THROW(g.to_libsnark_g1<curve_G1>(), std::runtime_error);
|
||||
}
|
||||
|
||||
// Point with out of bounds Fq
|
||||
{
|
||||
CDataStream ss(ParseHex("02ffc6d2adffacbc8438f09f321874ea66e2fcc29f8dcfec2caefa21ec8c96a77c"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss >> g;
|
||||
|
||||
ASSERT_THROW(g.to_libsnark_g1<curve_G1>(), std::logic_error);
|
||||
}
|
||||
|
||||
// Randomly produce valid G1 representations and fail/succeed to
|
||||
// turn them into G1 points based on whether they are valid.
|
||||
for (size_t i = 0; i < 5000; i++) {
|
||||
curve_Fq e = curve_Fq::random_element();
|
||||
CDataStream ss(ParseHex("02"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << Fq(e);
|
||||
CompressedG1 g;
|
||||
ss >> g;
|
||||
|
||||
try {
|
||||
curve_G1 g_real = g.to_libsnark_g1<curve_G1>();
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(proofs, g2_deserialization)
|
||||
{
|
||||
CompressedG2 g;
|
||||
curve_G2 expected = curve_G2::random_element();
|
||||
|
||||
// Valid G2 point
|
||||
{
|
||||
CDataStream ss(ParseHex("0a023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss >> g;
|
||||
|
||||
expected.X = curve_Fq2(
|
||||
curve_Fq("5923585509243758863255447226263146374209884951848029582715967108651637186684"),
|
||||
curve_Fq("5336385337059958111259504403491065820971993066694750945459110579338490853570")
|
||||
);
|
||||
expected.Y = curve_Fq2(
|
||||
curve_Fq("10374495865873200088116930399159835104695426846400310764827677226300185211748"),
|
||||
curve_Fq("5256529835065685814318509161957442385362539991735248614869838648137856366932")
|
||||
);
|
||||
expected.Z = curve_Fq2::one();
|
||||
|
||||
ASSERT_TRUE(g.to_libsnark_g2<curve_G2>() == expected);
|
||||
}
|
||||
|
||||
// Its negation
|
||||
{
|
||||
CDataStream ss(ParseHex("0b023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss >> g;
|
||||
|
||||
expected.X = curve_Fq2(
|
||||
curve_Fq("5923585509243758863255447226263146374209884951848029582715967108651637186684"),
|
||||
curve_Fq("5336385337059958111259504403491065820971993066694750945459110579338490853570")
|
||||
);
|
||||
expected.Y = curve_Fq2(
|
||||
curve_Fq("10374495865873200088116930399159835104695426846400310764827677226300185211748"),
|
||||
curve_Fq("5256529835065685814318509161957442385362539991735248614869838648137856366932")
|
||||
);
|
||||
expected.Z = curve_Fq2::one();
|
||||
|
||||
ASSERT_TRUE(g.to_libsnark_g2<curve_G2>() == -expected);
|
||||
}
|
||||
|
||||
// Invalid leading bytes
|
||||
{
|
||||
CDataStream ss(ParseHex("ff023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
ASSERT_THROW(ss >> g, std::ios_base::failure);
|
||||
}
|
||||
|
||||
|
||||
// Invalid point
|
||||
{
|
||||
CDataStream ss(ParseHex("0b023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984b"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss >> g;
|
||||
|
||||
ASSERT_THROW(g.to_libsnark_g2<curve_G2>(), std::runtime_error);
|
||||
}
|
||||
|
||||
// Point with out of bounds Fq2
|
||||
{
|
||||
CDataStream ss(ParseHex("0a0f3aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss >> g;
|
||||
|
||||
ASSERT_THROW(g.to_libsnark_g2<curve_G2>(), std::logic_error);
|
||||
}
|
||||
|
||||
// Randomly produce valid G2 representations and fail/succeed to
|
||||
// turn them into G2 points based on whether they are valid.
|
||||
for (size_t i = 0; i < 5000; i++) {
|
||||
curve_Fq2 e = curve_Fq2::random_element();
|
||||
CDataStream ss(ParseHex("0a"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << Fq2(e);
|
||||
CompressedG2 g;
|
||||
ss >> g;
|
||||
|
||||
try {
|
||||
curve_G2 g_real = g.to_libsnark_g2<curve_G2>();
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "json_test_vectors.h"
|
||||
#include "test/data/g1_compressed.json.h"
|
||||
|
||||
TEST(proofs, g1_test_vectors)
|
||||
{
|
||||
UniValue v = read_json(std::string(json_tests::g1_compressed, json_tests::g1_compressed + sizeof(json_tests::g1_compressed)));
|
||||
|
||||
curve_G1 e = curve_Fr("34958239045823") * curve_G1::one();
|
||||
for (size_t i = 0; i < 10000; i++) {
|
||||
e = (curve_Fr("34958239045823") ^ i) * e;
|
||||
auto expected = CompressedG1(e);
|
||||
|
||||
expect_test_vector(v[i], expected);
|
||||
ASSERT_TRUE(expected.to_libsnark_g1<curve_G1>() == e);
|
||||
}
|
||||
}
|
||||
|
||||
#include "test/data/g2_compressed.json.h"
|
||||
|
||||
TEST(proofs, g2_test_vectors)
|
||||
{
|
||||
UniValue v = read_json(std::string(json_tests::g2_compressed, json_tests::g2_compressed + sizeof(json_tests::g2_compressed)));
|
||||
|
||||
curve_G2 e = curve_Fr("34958239045823") * curve_G2::one();
|
||||
for (size_t i = 0; i < 10000; i++) {
|
||||
e = (curve_Fr("34958239045823") ^ i) * e;
|
||||
auto expected = CompressedG2(e);
|
||||
|
||||
expect_test_vector(v[i], expected);
|
||||
ASSERT_TRUE(expected.to_libsnark_g2<curve_G2>() == e);
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "primitives/transaction.h"
|
||||
#include "zcash/Note.hpp"
|
||||
#include "zcash/Address.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
extern ZCJoinSplit* params;
|
||||
extern int GenZero(int n);
|
||||
extern int GenMax(int n);
|
||||
|
||||
TEST(Transaction, JSDescriptionRandomized) {
|
||||
// construct a merkle tree
|
||||
SproutMerkleTree merkleTree;
|
||||
|
||||
libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random();
|
||||
libzcash::SproutPaymentAddress addr = k.address();
|
||||
|
||||
libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256());
|
||||
|
||||
// commitment from coin
|
||||
uint256 commitment = note.cm();
|
||||
|
||||
// insert commitment into the merkle tree
|
||||
merkleTree.append(commitment);
|
||||
|
||||
// compute the merkle root we will be working with
|
||||
uint256 rt = merkleTree.root();
|
||||
|
||||
auto witness = merkleTree.witness();
|
||||
|
||||
// create JSDescription
|
||||
uint256 joinSplitPubKey;
|
||||
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS> inputs = {
|
||||
libzcash::JSInput(witness, note, k),
|
||||
libzcash::JSInput() // dummy input of zero value
|
||||
};
|
||||
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs = {
|
||||
libzcash::JSOutput(addr, 50),
|
||||
libzcash::JSOutput(addr, 50)
|
||||
};
|
||||
std::array<size_t, ZC_NUM_JS_INPUTS> inputMap;
|
||||
std::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap;
|
||||
|
||||
{
|
||||
auto jsdesc = JSDescription::Randomized(
|
||||
false,
|
||||
*params, joinSplitPubKey, rt,
|
||||
inputs, outputs,
|
||||
inputMap, outputMap,
|
||||
0, 0, false);
|
||||
|
||||
std::set<size_t> inputSet(inputMap.begin(), inputMap.end());
|
||||
std::set<size_t> expectedInputSet {0, 1};
|
||||
EXPECT_EQ(expectedInputSet, inputSet);
|
||||
|
||||
std::set<size_t> outputSet(outputMap.begin(), outputMap.end());
|
||||
std::set<size_t> expectedOutputSet {0, 1};
|
||||
EXPECT_EQ(expectedOutputSet, outputSet);
|
||||
}
|
||||
|
||||
{
|
||||
auto jsdesc = JSDescription::Randomized(
|
||||
false,
|
||||
*params, joinSplitPubKey, rt,
|
||||
inputs, outputs,
|
||||
inputMap, outputMap,
|
||||
0, 0, false, nullptr, GenZero);
|
||||
|
||||
std::array<size_t, ZC_NUM_JS_INPUTS> expectedInputMap {1, 0};
|
||||
std::array<size_t, ZC_NUM_JS_OUTPUTS> expectedOutputMap {1, 0};
|
||||
EXPECT_EQ(expectedInputMap, inputMap);
|
||||
EXPECT_EQ(expectedOutputMap, outputMap);
|
||||
}
|
||||
|
||||
{
|
||||
auto jsdesc = JSDescription::Randomized(
|
||||
false,
|
||||
*params, joinSplitPubKey, rt,
|
||||
inputs, outputs,
|
||||
inputMap, outputMap,
|
||||
0, 0, false, nullptr, GenMax);
|
||||
|
||||
std::array<size_t, ZC_NUM_JS_INPUTS> expectedInputMap {0, 1};
|
||||
std::array<size_t, ZC_NUM_JS_OUTPUTS> expectedOutputMap {0, 1};
|
||||
EXPECT_EQ(expectedInputMap, inputMap);
|
||||
EXPECT_EQ(expectedOutputMap, outputMap);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "rpc/protocol.h" // For HTTP status codes
|
||||
#include "sync.h"
|
||||
#include "ui_interface.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -251,21 +252,25 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
|
||||
{
|
||||
std::unique_ptr<HTTPRequest> hreq(new HTTPRequest(req));
|
||||
|
||||
LogPrint("http", "Received a %s request for %s from %s\n",
|
||||
RequestMethodString(hreq->GetRequestMethod()), hreq->GetURI(), hreq->GetPeer().ToString());
|
||||
|
||||
// Early address-based allow check
|
||||
if (!ClientAllowed(hreq->GetPeer())) {
|
||||
LogPrint("http", "HTTP request from %s rejected: Client network is not allowed RPC access\n",
|
||||
hreq->GetPeer().ToString());
|
||||
hreq->WriteReply(HTTP_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
// Early reject unknown HTTP methods
|
||||
if (hreq->GetRequestMethod() == HTTPRequest::UNKNOWN) {
|
||||
LogPrint("http", "HTTP request from %s rejected: Unknown HTTP request method\n",
|
||||
hreq->GetPeer().ToString());
|
||||
hreq->WriteReply(HTTP_BADMETHOD);
|
||||
return;
|
||||
}
|
||||
|
||||
LogPrint("http", "Received a %s request for %s from %s\n",
|
||||
RequestMethodString(hreq->GetRequestMethod()), SanitizeString(hreq->GetURI(), SAFE_CHARS_URI).substr(0, 100), hreq->GetPeer().ToString());
|
||||
|
||||
// Find registered handler for prefix
|
||||
std::string strURI = hreq->GetURI();
|
||||
std::string path;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2019 Hush developers
|
||||
# Copyright (c) 2019-2020 Hush developers
|
||||
# Released under the GPLv3
|
||||
|
||||
# set working directory to the location of this script
|
||||
# readlink -f does not always exist
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2019 Hush developers
|
||||
# Copyright (c) 2019-2020 Hush developers
|
||||
# Released under the GPLv3
|
||||
|
||||
# set working directory to the location of this script
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
180
src/init.cpp
180
src/init.cpp
@@ -57,6 +57,7 @@
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet/wallet.h"
|
||||
#include "wallet/walletdb.h"
|
||||
#include "wallet/asyncrpcoperation_saplingconsolidation.h"
|
||||
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
@@ -79,16 +80,10 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include <thread>
|
||||
|
||||
#include <libsnark/common/profiling.hpp>
|
||||
|
||||
#if ENABLE_ZMQ
|
||||
#include "zmq/zmqnotificationinterface.h"
|
||||
#endif
|
||||
|
||||
#if ENABLE_PROTON
|
||||
#include "amqp/amqpnotificationinterface.h"
|
||||
#endif
|
||||
|
||||
#include "librustzcash.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -102,7 +97,7 @@ extern int32_t KOMODO_SNAPSHOT_INTERVAL;
|
||||
|
||||
extern void komodo_init(int32_t height);
|
||||
|
||||
ZCJoinSplit* pzcashParams = NULL;
|
||||
//ZCJoinSplit* pzcashParams = NULL;
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
CWallet* pwalletMain = NULL;
|
||||
@@ -113,10 +108,6 @@ bool fFeeEstimatesInitialized = false;
|
||||
static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
|
||||
#endif
|
||||
|
||||
#if ENABLE_PROTON
|
||||
static AMQPNotificationInterface* pAMQPNotificationInterface = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
// Win32 LevelDB doesn't use file descriptors, and the ones used for
|
||||
// accessing block files don't count towards the fd_set size limit
|
||||
@@ -286,14 +277,6 @@ void Shutdown()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_PROTON
|
||||
if (pAMQPNotificationInterface) {
|
||||
UnregisterValidationInterface(pAMQPNotificationInterface);
|
||||
delete pAMQPNotificationInterface;
|
||||
pAMQPNotificationInterface = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
try {
|
||||
boost::filesystem::remove(GetPidFile());
|
||||
@@ -306,8 +289,8 @@ void Shutdown()
|
||||
delete pwalletMain;
|
||||
pwalletMain = NULL;
|
||||
#endif
|
||||
delete pzcashParams;
|
||||
pzcashParams = NULL;
|
||||
//delete pzcashParams;
|
||||
//pzcashParams = NULL;
|
||||
globalVerifyHandle.reset();
|
||||
ECC_Stop();
|
||||
LogPrintf("%s: done\n", __func__);
|
||||
@@ -400,6 +383,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
#ifndef _WIN32
|
||||
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "komodod.pid"));
|
||||
#endif
|
||||
strUsage += HelpMessageOpt("-txexpirynotify=<cmd>", _("Execute command when transaction expires (%s in cmd is replaced by transaction id)"));
|
||||
strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. "
|
||||
"Warning: Reverting this setting requires re-downloading the entire blockchain. "
|
||||
"(default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
|
||||
@@ -449,11 +433,18 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += HelpMessageGroup(_("Wallet options:"));
|
||||
strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
|
||||
strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
|
||||
strUsage += HelpMessageOpt("-consolidation", _("Enable auto Sapling note consolidation (default: false)"));
|
||||
strUsage += HelpMessageOpt("-consolidatesaplingaddress=<zaddr>", _("Specify Sapling Address to Consolidate. (default: all)"));
|
||||
strUsage += HelpMessageOpt("-consolidationtxfee", strprintf(_("Fee amount in Puposhis used send consolidation transactions. (default %i)"), DEFAULT_CONSOLIDATION_FEE));
|
||||
strUsage += HelpMessageOpt("-deletetx", _("Enable Old Transaction Deletion"));
|
||||
strUsage += HelpMessageOpt("-deleteinterval", strprintf(_("Delete transaction every <n> blocks during inital block download (default: %i)"), DEFAULT_TX_DELETE_INTERVAL));
|
||||
strUsage += HelpMessageOpt("-keeptxnum", strprintf(_("Keep the last <n> transactions (default: %i)"), DEFAULT_TX_RETENTION_LASTTX));
|
||||
strUsage += HelpMessageOpt("-keeptxfornblocks", strprintf(_("Keep transactions for at least <n> blocks (default: %i)"), DEFAULT_TX_RETENTION_BLOCKS));
|
||||
if (showDebug)
|
||||
strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)",
|
||||
CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK())));
|
||||
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
|
||||
CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
|
||||
strUsage += HelpMessageOpt("-opretmintxfee=<amt>", strprintf(_("Minimum fee (in %s/kB) to allow for OP_RETURN transactions (default: %s)"), CURRENCY_UNIT, 400000 ));
|
||||
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
|
||||
strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
|
||||
strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup"));
|
||||
strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
|
||||
@@ -479,14 +470,6 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += HelpMessageOpt("-zmqpubrawtx=<address>", _("Enable publish raw transaction in <address>"));
|
||||
#endif
|
||||
|
||||
#if ENABLE_PROTON
|
||||
strUsage += HelpMessageGroup(_("AMQP 1.0 notification options:"));
|
||||
strUsage += HelpMessageOpt("-amqppubhashblock=<address>", _("Enable publish hash block in <address>"));
|
||||
strUsage += HelpMessageOpt("-amqppubhashtx=<address>", _("Enable publish hash transaction in <address>"));
|
||||
strUsage += HelpMessageOpt("-amqppubrawblock=<address>", _("Enable publish raw block in <address>"));
|
||||
strUsage += HelpMessageOpt("-amqppubrawtx=<address>", _("Enable publish raw transaction in <address>"));
|
||||
#endif
|
||||
|
||||
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
|
||||
if (showDebug)
|
||||
{
|
||||
@@ -500,7 +483,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0));
|
||||
strUsage += HelpMessageOpt("-nuparams=hexBranchId:activationHeight", "Use given activation height for specified network upgrade (regtest-only)");
|
||||
}
|
||||
string debugCategories = "addrman, alert, bench, coindb, db, estimatefee, http, libevent, lock, mempool, net, partitioncheck, pow, proxy, prune, "
|
||||
string debugCategories = "addrman, alert, bench, coindb, db, deletetx, estimatefee, http, libevent, lock, mempool, net, partitioncheck, pow, proxy, prune, "
|
||||
"rand, reindex, rpc, selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these
|
||||
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
|
||||
_("If <category> is not supplied or if <category> = 1, output all debugging information.") + " " + _("<category> can be:") + " " + debugCategories + ".");
|
||||
@@ -569,16 +552,13 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += HelpMessageOpt("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT));
|
||||
}
|
||||
|
||||
// Disabled until we can lock notes and also tune performance of libsnark which by default uses multiple threads
|
||||
//strUsage += HelpMessageOpt("-rpcasyncthreads=<n>", strprintf(_("Set the number of threads to service Async RPC calls (default: %d)"), 1));
|
||||
|
||||
if (mode == HMM_BITCOIND) {
|
||||
strUsage += HelpMessageGroup(_("Metrics Options (only if -daemon and -printtoconsole are not set):"));
|
||||
strUsage += HelpMessageOpt("-showmetrics", _("Show metrics on stdout (default: 1 if running in a console, 0 otherwise)"));
|
||||
strUsage += HelpMessageOpt("-metricsui", _("Set to 1 for a persistent metrics screen, 0 for sequential metrics output (default: 1 if running in a console, 0 otherwise)"));
|
||||
strUsage += HelpMessageOpt("-metricsrefreshtime", strprintf(_("Number of seconds between metrics refreshes (default: %u if running in a console, %u otherwise)"), 1, 600));
|
||||
}
|
||||
strUsage += HelpMessageGroup(_("Komodo Asset Chain options:"));
|
||||
strUsage += HelpMessageGroup(_("Hush Smart Chain options:"));
|
||||
strUsage += HelpMessageOpt("-ac_algo", _("Choose PoW mining algorithm, default is Equihash"));
|
||||
strUsage += HelpMessageOpt("-ac_blocktime", _("Block time in seconds, default is 60"));
|
||||
strUsage += HelpMessageOpt("-ac_cc", _("Cryptoconditions, default 0"));
|
||||
@@ -615,6 +595,14 @@ static void BlockNotifyCallback(const uint256& hashNewTip)
|
||||
boost::thread t(runCommand, strCmd); // thread runs free
|
||||
}
|
||||
|
||||
static void TxExpiryNotifyCallback(const uint256& txid)
|
||||
{
|
||||
std::string strCmd = GetArg("-txexpirynotify", "");
|
||||
|
||||
boost::replace_all(strCmd, "%s", txid.GetHex());
|
||||
boost::thread t(runCommand, strCmd); // thread runs free
|
||||
}
|
||||
|
||||
struct CImportingNow
|
||||
{
|
||||
CImportingNow() {
|
||||
@@ -733,22 +721,6 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadNotifyRecentlyAdded()
|
||||
{
|
||||
while (true) {
|
||||
// Run the notifier on an integer second in the steady clock.
|
||||
auto now = std::chrono::steady_clock::now().time_since_epoch();
|
||||
auto nextFire = std::chrono::duration_cast<std::chrono::seconds>(
|
||||
now + std::chrono::seconds(1));
|
||||
std::this_thread::sleep_until(
|
||||
std::chrono::time_point<std::chrono::steady_clock>(nextFire));
|
||||
|
||||
boost::this_thread::interruption_point();
|
||||
|
||||
mempool.NotifyRecentlyAdded();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sanity checks
|
||||
* Ensure that Hush is running in a usable environment with all
|
||||
* necessary library support.
|
||||
@@ -1046,10 +1018,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
if (mapArgs.count("-developerencryptwallet")) {
|
||||
fprintf(stderr,"%s wallet encryption error\n", __FUNCTION__);
|
||||
return InitError(_("Wallet encryption requires -experimentalfeatures."));
|
||||
}
|
||||
else if (mapArgs.count("-paymentdisclosure")) {
|
||||
fprintf(stderr,"%s payment disclosure error\n", __FUNCTION__);
|
||||
return InitError(_("Payment disclosure requires -experimentalfeatures."));
|
||||
//TODO: make this non experimental
|
||||
} else if (mapArgs.count("-zmergetoaddress")) {
|
||||
fprintf(stderr,"%s zmerge error\n", __FUNCTION__);
|
||||
return InitError(_("RPC method z_mergetoaddress requires -experimentalfeatures."));
|
||||
@@ -1456,10 +1425,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
}
|
||||
|
||||
//fprintf(stderr,"%s tik15\n", __FUNCTION__);
|
||||
// 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;
|
||||
|
||||
if ( KOMODO_NSPV_FULLNODE )
|
||||
{
|
||||
@@ -1635,21 +1600,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_PROTON
|
||||
pAMQPNotificationInterface = AMQPNotificationInterface::CreateWithArguments(mapArgs);
|
||||
|
||||
if (pAMQPNotificationInterface) {
|
||||
|
||||
// AMQP support is currently an experimental feature, so fail if user configured AMQP notifications
|
||||
// without enabling experimental features.
|
||||
if (!fExperimentalMode) {
|
||||
return InitError(_("AMQP support requires -experimentalfeatures."));
|
||||
}
|
||||
|
||||
RegisterValidationInterface(pAMQPNotificationInterface);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( KOMODO_NSPV_SUPERLITE )
|
||||
{
|
||||
std::vector<boost::filesystem::path> vImportFiles;
|
||||
@@ -1953,6 +1903,42 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
pwalletMain->GenerateNewSeed();
|
||||
}
|
||||
|
||||
//Set Sapling Consolidation
|
||||
pwalletMain->fSaplingConsolidationEnabled = GetBoolArg("-consolidation", false);
|
||||
fConsolidationTxFee = GetArg("-consolidationtxfee", DEFAULT_CONSOLIDATION_FEE);
|
||||
fConsolidationMapUsed = !mapMultiArgs["-consolidatesaplingaddress"].empty();
|
||||
|
||||
//Validate Sapling Addresses
|
||||
vector<string>& vaddresses = mapMultiArgs["-consolidatesaplingaddress"];
|
||||
for (int i = 0; i < vaddresses.size(); i++) {
|
||||
LogPrintf("Consolidating Sapling Address: %s\n", vaddresses[i]);
|
||||
auto zAddress = DecodePaymentAddress(vaddresses[i]);
|
||||
if (!IsValidPaymentAddress(zAddress)) {
|
||||
return InitError("Invalid consolidation address");
|
||||
}
|
||||
}
|
||||
|
||||
//Set Transaction Deletion Options
|
||||
fTxDeleteEnabled = GetBoolArg("-deletetx", false);
|
||||
fTxConflictDeleteEnabled = GetBoolArg("-deleteconflicttx", true);
|
||||
|
||||
fDeleteInterval = GetArg("-deleteinterval", DEFAULT_TX_DELETE_INTERVAL);
|
||||
if (fDeleteInterval < 1)
|
||||
return InitError("deleteinterval must be greater than 0");
|
||||
|
||||
fKeepLastNTransactions = GetArg("-keeptxnum", DEFAULT_TX_RETENTION_LASTTX);
|
||||
if (fKeepLastNTransactions < 1)
|
||||
return InitError("keeptxnum must be greater than 0");
|
||||
|
||||
fDeleteTransactionsAfterNBlocks = GetArg("-keeptxfornblocks", DEFAULT_TX_RETENTION_BLOCKS);
|
||||
if (fDeleteTransactionsAfterNBlocks < 1)
|
||||
return InitError("keeptxfornblocks must be greater than 0");
|
||||
|
||||
if (fDeleteTransactionsAfterNBlocks < MAX_REORG_LENGTH + 1 ) {
|
||||
LogPrintf("keeptxfornblock is less the MAX_REORG_LENGTH, Setting to %i\n", MAX_REORG_LENGTH + 1);
|
||||
fDeleteTransactionsAfterNBlocks = MAX_REORG_LENGTH + 1;
|
||||
}
|
||||
|
||||
if (fFirstRun)
|
||||
{
|
||||
// Create new keyUser and set as default key
|
||||
@@ -2053,6 +2039,24 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
}
|
||||
#endif // ENABLE_MINING
|
||||
|
||||
// Start the thread that notifies listeners of transactions that have been
|
||||
// recently added to the mempool, or have been added to or removed from the
|
||||
// chain. We perform this before step 10 (import blocks) so that the
|
||||
// original value of chainActive.Tip(), which corresponds with the wallet's
|
||||
// view of the chaintip, is passed to ThreadNotifyWallets before the chain
|
||||
// tip changes again.
|
||||
{
|
||||
CBlockIndex *pindexLastTip;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindexLastTip = chainActive.Tip();
|
||||
}
|
||||
boost::function<void()> threadnotifywallets = boost::bind(&ThreadNotifyWallets, pindexLastTip);
|
||||
threadGroup.create_thread(
|
||||
boost::bind(&TraceThread<boost::function<void()>>, "txnotify", threadnotifywallets)
|
||||
);
|
||||
}
|
||||
|
||||
// ********************************************************* Step 9: data directory maintenance
|
||||
|
||||
// if pruning, unset the service bit and perform the initial blockstore prune
|
||||
@@ -2077,6 +2081,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
|
||||
if (mapArgs.count("-blocknotify"))
|
||||
uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
|
||||
if (mapArgs.count("-txexpirynotify"))
|
||||
uiInterface.NotifyTxExpiration.connect(TxExpiryNotifyCallback);
|
||||
if ( KOMODO_REWIND >= 0 )
|
||||
{
|
||||
uiInterface.InitMessage(_("Activating best chain..."));
|
||||
@@ -2094,10 +2100,22 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
vImportFiles.push_back(strFile);
|
||||
}
|
||||
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
|
||||
if (chainActive.Tip() == NULL) {
|
||||
LogPrintf("Waiting for genesis block to be imported...\n");
|
||||
while (!fRequestShutdown && chainActive.Tip() == NULL)
|
||||
|
||||
// Wait for genesis block to be processed
|
||||
bool fHaveGenesis = false;
|
||||
while (!fHaveGenesis && !fRequestShutdown) {
|
||||
{
|
||||
LOCK(cs_main);
|
||||
fHaveGenesis = (chainActive.Tip() != NULL);
|
||||
MilliSleep(10);
|
||||
}
|
||||
|
||||
if (!fHaveGenesis) {
|
||||
MilliSleep(10);
|
||||
}
|
||||
}
|
||||
if (!fHaveGenesis) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ********************************************************* Step 11: start node
|
||||
@@ -2113,17 +2131,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
|
||||
LogPrintf("nBestHeight = %d\n", chainActive.Height());
|
||||
#ifdef ENABLE_WALLET
|
||||
RescanWallets();
|
||||
|
||||
LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0);
|
||||
LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0);
|
||||
LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
|
||||
#endif
|
||||
|
||||
// Start the thread that notifies listeners of transactions that have been
|
||||
// recently added to the mempool.
|
||||
threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "txnotify", &ThreadNotifyRecentlyAdded));
|
||||
|
||||
if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
|
||||
StartTorControl(threadGroup, scheduler);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
//#include "zcash/JoinSplit.hpp"
|
||||
|
||||
class CScheduler;
|
||||
class CWallet;
|
||||
@@ -34,7 +34,7 @@ class thread_group;
|
||||
} // namespace boost
|
||||
|
||||
extern CWallet* pwalletMain;
|
||||
extern ZCJoinSplit* pzcashParams;
|
||||
//extern ZCJoinSplit* pzcashParams;
|
||||
|
||||
void StartShutdown();
|
||||
bool ShutdownRequested();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2014-2016 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-2018 The Zcash developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -84,15 +85,6 @@ private:
|
||||
public:
|
||||
PaymentAddressEncoder(const CChainParams& params) : m_params(params) {}
|
||||
|
||||
std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << zaddr;
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
|
||||
data.insert(data.end(), ss.begin(), ss.end());
|
||||
return EncodeBase58Check(data);
|
||||
}
|
||||
|
||||
std::string operator()(const libzcash::SaplingPaymentAddress& zaddr) const
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
@@ -107,6 +99,7 @@ public:
|
||||
}
|
||||
|
||||
std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
|
||||
std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const { return {}; }
|
||||
};
|
||||
|
||||
class ViewingKeyEncoder : public boost::static_visitor<std::string>
|
||||
@@ -117,17 +110,6 @@ private:
|
||||
public:
|
||||
ViewingKeyEncoder(const CChainParams& params) : m_params(params) {}
|
||||
|
||||
std::string operator()(const libzcash::SproutViewingKey& vk) const
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << vk;
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCVIEWING_KEY);
|
||||
data.insert(data.end(), ss.begin(), ss.end());
|
||||
std::string ret = EncodeBase58Check(data);
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string operator()(const libzcash::SaplingIncomingViewingKey& vk) const
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
@@ -152,17 +134,6 @@ private:
|
||||
public:
|
||||
SpendingKeyEncoder(const CChainParams& params) : m_params(params) {}
|
||||
|
||||
std::string operator()(const libzcash::SproutSpendingKey& zkey) const
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << zkey;
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCSPENDING_KEY);
|
||||
data.insert(data.end(), ss.begin(), ss.end());
|
||||
std::string ret = EncodeBase58Check(data);
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string operator()(const libzcash::SaplingExtendedSpendingKey& zkey) const
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
@@ -324,18 +295,6 @@ std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
|
||||
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
|
||||
{
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
|
||||
if ((data.size() == libzcash::SerializedSproutPaymentAddressSize + zaddr_prefix.size()) &&
|
||||
std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) {
|
||||
CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end());
|
||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||
libzcash::SproutPaymentAddress ret;
|
||||
ss >> ret;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
data.clear();
|
||||
auto bech = bech32::Decode(str);
|
||||
if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS) &&
|
||||
bech.second.size() == ConvertedSaplingPaymentAddressSize) {
|
||||
@@ -363,20 +322,6 @@ std::string EncodeViewingKey(const libzcash::ViewingKey& vk)
|
||||
libzcash::ViewingKey DecodeViewingKey(const std::string& str)
|
||||
{
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& vk_prefix = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY);
|
||||
if ((data.size() == libzcash::SerializedSproutViewingKeySize + vk_prefix.size()) &&
|
||||
std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) {
|
||||
CSerializeData serialized(data.begin() + vk_prefix.size(), data.end());
|
||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||
libzcash::SproutViewingKey ret;
|
||||
ss >> ret;
|
||||
memory_cleanse(serialized.data(), serialized.size());
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
data.clear();
|
||||
auto bech = bech32::Decode(str);
|
||||
if(bech.first == Params().Bech32HRP(CChainParams::SAPLING_INCOMING_VIEWING_KEY) &&
|
||||
bech.second.size() == ConvertedSaplingIncomingViewingKeySize) {
|
||||
@@ -400,20 +345,6 @@ std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
|
||||
libzcash::SpendingKey DecodeSpendingKey(const std::string& str)
|
||||
{
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& zkey_prefix = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY);
|
||||
if ((data.size() == libzcash::SerializedSproutSpendingKeySize + zkey_prefix.size()) &&
|
||||
std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) {
|
||||
CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end());
|
||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||
libzcash::SproutSpendingKey ret;
|
||||
ss >> ret;
|
||||
memory_cleanse(serialized.data(), serialized.size());
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
data.clear();
|
||||
auto bech = bech32::Decode(str);
|
||||
if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_EXTENDED_SPEND_KEY) &&
|
||||
bech.second.size() == ConvertedSaplingExtendedSpendingKeySize) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-2018 The Zcash developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -128,15 +129,6 @@ bool CBasicKeyStore::HaveWatchOnly() const
|
||||
return (!setWatchOnly.empty());
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk)
|
||||
{
|
||||
LOCK(cs_SpendingKeyStore);
|
||||
auto address = sk.address();
|
||||
mapSproutSpendingKeys[address] = sk;
|
||||
mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(sk.receiving_key())));
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Sapling
|
||||
bool CBasicKeyStore::AddSaplingSpendingKey(
|
||||
const libzcash::SaplingExtendedSpendingKey &sk,
|
||||
@@ -155,14 +147,6 @@ bool CBasicKeyStore::AddSaplingSpendingKey(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::AddSproutViewingKey(const libzcash::SproutViewingKey &vk)
|
||||
{
|
||||
LOCK(cs_SpendingKeyStore);
|
||||
auto address = vk.address();
|
||||
mapSproutViewingKeys[address] = vk;
|
||||
mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(vk.sk_enc)));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::AddSaplingFullViewingKey(
|
||||
const libzcash::SaplingFullViewingKey &fvk,
|
||||
@@ -190,18 +174,7 @@ bool CBasicKeyStore::AddSaplingIncomingViewingKey(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk)
|
||||
{
|
||||
LOCK(cs_SpendingKeyStore);
|
||||
mapSproutViewingKeys.erase(vk.address());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const
|
||||
{
|
||||
LOCK(cs_SpendingKeyStore);
|
||||
return mapSproutViewingKeys.count(address) > 0;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const
|
||||
{
|
||||
@@ -215,19 +188,6 @@ bool CBasicKeyStore::HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymen
|
||||
return mapSaplingIncomingViewingKeys.count(addr) > 0;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::GetSproutViewingKey(
|
||||
const libzcash::SproutPaymentAddress &address,
|
||||
libzcash::SproutViewingKey &vkOut) const
|
||||
{
|
||||
LOCK(cs_SpendingKeyStore);
|
||||
SproutViewingKeyMap::const_iterator mi = mapSproutViewingKeys.find(address);
|
||||
if (mi != mapSproutViewingKeys.end()) {
|
||||
vkOut = mi->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::GetSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk,
|
||||
libzcash::SaplingFullViewingKey &fvkOut) const
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -70,14 +71,6 @@ public:
|
||||
virtual bool HaveWatchOnly(const CScript &dest) const =0;
|
||||
virtual bool HaveWatchOnly() const =0;
|
||||
|
||||
//! Add a spending key to the store.
|
||||
virtual bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk) =0;
|
||||
|
||||
//! Check whether a spending key corresponding to a given payment address is present in the store.
|
||||
virtual bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const =0;
|
||||
virtual bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0;
|
||||
virtual void GetSproutPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const =0;
|
||||
|
||||
//! Add a Sapling spending key to the store.
|
||||
virtual bool AddSaplingSpendingKey(
|
||||
const libzcash::SaplingExtendedSpendingKey &sk,
|
||||
@@ -106,21 +99,11 @@ public:
|
||||
libzcash::SaplingIncomingViewingKey& ivkOut) const =0;
|
||||
virtual void GetSaplingPaymentAddresses(std::set<libzcash::SaplingPaymentAddress> &setAddress) const =0;
|
||||
|
||||
//! Support for Sprout viewing keys
|
||||
virtual bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk) =0;
|
||||
virtual bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk) =0;
|
||||
virtual bool HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const =0;
|
||||
virtual bool GetSproutViewingKey(
|
||||
const libzcash::SproutPaymentAddress &address,
|
||||
libzcash::SproutViewingKey& vkOut) const =0;
|
||||
};
|
||||
|
||||
typedef std::map<CKeyID, CKey> KeyMap;
|
||||
typedef std::map<CScriptID, CScript > ScriptMap;
|
||||
typedef std::set<CScript> WatchOnlySet;
|
||||
typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutSpendingKey> SproutSpendingKeyMap;
|
||||
typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutViewingKey> SproutViewingKeyMap;
|
||||
typedef std::map<libzcash::SproutPaymentAddress, ZCNoteDecryption> NoteDecryptorMap;
|
||||
|
||||
// Full viewing key has equivalent functionality to a transparent address
|
||||
// When encrypting wallet, encrypt SaplingSpendingKeyMap, while leaving SaplingFullViewingKeyMap unencrypted
|
||||
@@ -137,10 +120,7 @@ protected:
|
||||
KeyMap mapKeys;
|
||||
ScriptMap mapScripts;
|
||||
WatchOnlySet setWatchOnly;
|
||||
SproutSpendingKeyMap mapSproutSpendingKeys;
|
||||
SproutViewingKeyMap mapSproutViewingKeys;
|
||||
NoteDecryptorMap mapNoteDecryptors;
|
||||
|
||||
|
||||
SaplingSpendingKeyMap mapSaplingSpendingKeys;
|
||||
SaplingFullViewingKeyMap mapSaplingFullViewingKeys;
|
||||
SaplingIncomingViewingKeyMap mapSaplingIncomingViewingKeys;
|
||||
@@ -195,62 +175,6 @@ public:
|
||||
virtual bool HaveWatchOnly(const CScript &dest) const;
|
||||
virtual bool HaveWatchOnly() const;
|
||||
|
||||
bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk);
|
||||
bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const
|
||||
{
|
||||
bool result;
|
||||
{
|
||||
LOCK(cs_SpendingKeyStore);
|
||||
result = (mapSproutSpendingKeys.count(address) > 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_SpendingKeyStore);
|
||||
SproutSpendingKeyMap::const_iterator mi = mapSproutSpendingKeys.find(address);
|
||||
if (mi != mapSproutSpendingKeys.end())
|
||||
{
|
||||
skOut = mi->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool GetNoteDecryptor(const libzcash::SproutPaymentAddress &address, ZCNoteDecryption &decOut) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_SpendingKeyStore);
|
||||
NoteDecryptorMap::const_iterator mi = mapNoteDecryptors.find(address);
|
||||
if (mi != mapNoteDecryptors.end())
|
||||
{
|
||||
decOut = mi->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void GetSproutPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const
|
||||
{
|
||||
setAddress.clear();
|
||||
{
|
||||
LOCK(cs_SpendingKeyStore);
|
||||
SproutSpendingKeyMap::const_iterator mi = mapSproutSpendingKeys.begin();
|
||||
while (mi != mapSproutSpendingKeys.end())
|
||||
{
|
||||
setAddress.insert((*mi).first);
|
||||
mi++;
|
||||
}
|
||||
SproutViewingKeyMap::const_iterator mvi = mapSproutViewingKeys.begin();
|
||||
while (mvi != mapSproutViewingKeys.end())
|
||||
{
|
||||
setAddress.insert((*mvi).first);
|
||||
mvi++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Sapling
|
||||
bool AddSaplingSpendingKey(
|
||||
const libzcash::SaplingExtendedSpendingKey &sk,
|
||||
@@ -313,17 +237,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk);
|
||||
virtual bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk);
|
||||
virtual bool HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const;
|
||||
virtual bool GetSproutViewingKey(
|
||||
const libzcash::SproutPaymentAddress &address,
|
||||
libzcash::SproutViewingKey& vkOut) const;
|
||||
};
|
||||
|
||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
||||
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
||||
typedef std::map<libzcash::SproutPaymentAddress, std::vector<unsigned char> > CryptedSproutSpendingKeyMap;
|
||||
|
||||
//! Sapling
|
||||
typedef std::map<libzcash::SaplingExtendedFullViewingKey, std::vector<unsigned char> > CryptedSaplingSpendingKeyMap;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
#include <curl/curl.h>
|
||||
#include <curl/easy.h>
|
||||
#include "consensus/params.h"
|
||||
#include "primitives/nonce.h"
|
||||
//#include "primitives/nonce.h"
|
||||
#include "komodo_defs.h"
|
||||
#include "script/standard.h"
|
||||
#include "cc/CCinclude.h"
|
||||
#include "sietch.h"
|
||||
|
||||
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
|
||||
int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp);
|
||||
@@ -70,6 +71,7 @@ int tx_height( const uint256 &hash ){
|
||||
uint256 hashBlock;
|
||||
if (!GetTransaction(hash, tx, hashBlock, true)) {
|
||||
fprintf(stderr,"tx hash %s does not exist!\n", hash.ToString().c_str() );
|
||||
return nHeight;
|
||||
}
|
||||
|
||||
BlockMap::const_iterator it = mapBlockIndex.find(hashBlock);
|
||||
@@ -78,6 +80,7 @@ int tx_height( const uint256 &hash ){
|
||||
//fprintf(stderr,"blockHash %s height %d\n",hashBlock.ToString().c_str(), nHeight);
|
||||
} else {
|
||||
// Unconfirmed xtns
|
||||
fprintf(stderr,"tx %s is unconfirmed\n", hash.ToString().c_str() );
|
||||
//fprintf(stderr,"block hash %s does not exist!\n", hashBlock.ToString().c_str() );
|
||||
}
|
||||
return nHeight;
|
||||
@@ -1532,8 +1535,8 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh
|
||||
//fprintf(stderr,"blocktime.%u -> ",blocktime);
|
||||
if ( blocktime < prevtime+3 )
|
||||
blocktime = prevtime+3;
|
||||
if ( blocktime < GetAdjustedTime()-60 )
|
||||
blocktime = GetAdjustedTime()+30;
|
||||
if ( blocktime < GetTime()-60 )
|
||||
blocktime = GetTime()+30;
|
||||
//fprintf(stderr,"blocktime.%u txtime.%u\n",blocktime,txtime);
|
||||
}
|
||||
if ( value == 0 || txtime == 0 || blocktime == 0 || prevtime == 0 )
|
||||
|
||||
@@ -81,7 +81,8 @@ bits320 fexpand(bits256 basepoint)
|
||||
return(out);
|
||||
}
|
||||
|
||||
#if __amd64__
|
||||
#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__) || defined(__amd64__) || defined(__amd64) || defined(_M_X64) || defined(_M_IA64)
|
||||
|
||||
// donna: special gcc mode for 128-bit integers. It's implemented on 64-bit platforms only as far as I know.
|
||||
typedef unsigned uint128_t __attribute__((mode(TI)));
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -34,33 +34,34 @@
|
||||
#define KOMODO_FIRSTFUNGIBLEID 100
|
||||
#define KOMODO_SAPLING_ACTIVATION 1544832000 // Dec 15th, 2018
|
||||
#define KOMODO_SAPLING_DEADLINE 1550188800 // Feb 15th, 2019
|
||||
#define ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX 57
|
||||
#define ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF 27
|
||||
#define ASSETCHAINS_STAKED_MIN_POW_DIFF 536900000 // 537000000 537300000
|
||||
#define _COINBASE_MATURITY 100
|
||||
|
||||
// KMD Notary Seasons
|
||||
// 1: May 1st 2018 1530921600
|
||||
// 2: July 15th 2019 1563148800 -> estimated height 1444000
|
||||
// 3: 3rd season ending isnt known, so use very far times in future.
|
||||
// 3: 3rd season
|
||||
// 1751328000 = dummy timestamp, 1 July 2025!
|
||||
// 7113400 = 5x current KMD blockheight.
|
||||
// to add 4th season, change NUM_KMD_SEASONS to 4, and add timestamp and height of activation to these arrays.
|
||||
// to add seasons, change NUM_KMD_SEASONS, and add timestamp and height of activation to these arrays.
|
||||
|
||||
#define NUM_KMD_SEASONS 4
|
||||
#define NUM_KMD_SEASONS 6
|
||||
#define NUM_KMD_NOTARIES 64
|
||||
|
||||
// $ ./contrib/block_time.pl 166250
|
||||
// Hush Block 166250 will happen at roughly:
|
||||
// Wed Jan 29 08:14:12 2020 Eastern # 1580303652
|
||||
// Wed Jan 29 13:14:12 2020 GMT # 1580303652
|
||||
const uint32_t nHushHardforkHeight = 166250;
|
||||
const uint32_t nHushHardforkHeight = 166250;
|
||||
// $ ./contrib/block_time.pl 245555
|
||||
// Hush Block 245555 will happen at roughly... now
|
||||
const uint32_t nHushHardforkHeight2 = 245055;
|
||||
|
||||
// No coins/code are currently using timestamp activated fork
|
||||
const uint32_t nHushHardforkTimestamp = 1580303652; // Jan 29nd 1pm GMT
|
||||
const uint32_t nHushHardforkTimestamp = 1580303652; // Jan 29nd 1pm GMT
|
||||
const uint32_t nHushHardforkTimestamp2 = 1594425600; // Jul 11th 12a GMT
|
||||
|
||||
static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, 1751328000};
|
||||
static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {1,2,nHushHardforkHeight, 5*nHushHardforkHeight};
|
||||
static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, nHushHardforkTimestamp2, nHushHardforkTimestamp2*5, nHushHardforkTimestamp2*6};
|
||||
static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {1,2,nHushHardforkHeight, nHushHardforkHeight2, (int)340000, 5*nHushHardforkHeight2};
|
||||
|
||||
// Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above.
|
||||
static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] =
|
||||
@@ -329,7 +330,74 @@ static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] =
|
||||
{"gt_AR", "0307c1cf89bd8ed4db1b09a0a98cf5f746fc77df3803ecc8611cf9455ec0ce6960" },
|
||||
{"patchkez_SH", "03d7c187689bf829ca076a30bbf36d2e67bb74e16a3290d8a55df21d6cb15c80c1" },
|
||||
{"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" }
|
||||
}
|
||||
},
|
||||
{
|
||||
// Season 4 https://github.com/KomodoPlatform/dPoW/blob/s4/iguana/3rd_party
|
||||
{"alien_AR", "024f20c096b085308e21893383f44b4faf1cdedea9ad53cc7d7e7fbfa0c30c1e71" },
|
||||
{"alien_EU", "022b85908191788f409506ebcf96a892f3274f352864c3ed566c5a16de63953236" },
|
||||
{"alien_NA", "022f62b56ddfd07c9860921c701285ac39bb3ac8f6f083d1b59c8f4943be3de162" },
|
||||
{"alright_DEV", "03b6f9493658bdd102503585a08ae642b49d6a68fb69ac3626f9737cd7581abdfa" },
|
||||
{"artemii235_DEV", "037a20916d2e9ea575300ac9d729507c23a606b9a200c8e913d7c9832f912a1fa7" },
|
||||
{"chainmakers_NA", "028803e07bcc521fde264b7191a944f9b3612e8ee4e24a99bcd903f6976240839a" },
|
||||
{"chainzilla_SH", "0311dde03c2dd654ce78323b718ed3ad73a464d1bde97820f3395f54788b5420dd" },
|
||||
{"chmex_AR", "030cd487e10fbf142e0e8d582e702ecb775f378569c3cb5acd0ff97b6b12803588" },
|
||||
{"chmex_EU", "030bf7bd7ad0515c33b5d5d9a91e0729baf801b9002f80495ae535ea1cebb352cb" },
|
||||
{"cipi_EU", "026f4f66385daaf8313ef30ffe4988e7db497132682dca185a70763d93e1417d9d" },
|
||||
{"cipi_NA", "03f4e69edcb4fa3b2095cb8cb1ca010f4ec4972eac5d8822397e5c8d87aa21a739" },
|
||||
{"daemonfox_NA", "023c7584b1006d4a62a4b4c9c1ede390a3789316547897d5ed49ff9385a3acb411" },
|
||||
{"dappvader_SH", "025199bc04bcb8a17976d9fe8bc87763a6150c2727321aa59bf34a2b49f2f3a0ce" },
|
||||
{"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" },
|
||||
{"decker_DEV", "02fca8ee50e49f480de275745618db7b0b3680b0bdcce7dcae7d2e0fd5c3345744" },
|
||||
{"decker_EU", "027777775b89ff548c3be54fb0c9455437d87f38bfce83bdef113899881b219c9e" },
|
||||
{"dragonhound_NA", "029912212d370ee0fb4d38eefd8bfcd8ab04e2c3b0354020789c29ddf2a35c72d6" },
|
||||
{"dudezmobi_AR", "033c121d3f8d450174674a73f3b7f140b2717a7d51ea19ee597e2e8e8f9d5ed87f" },
|
||||
{"etszombi_AR", "03bfcbca83f11e622fa4eed9a1fa25dba377981ea3b22e3d0a4015f9a932af9272" },
|
||||
{"etszombi_EU", "03a5c083c78ba397970f20b544a01c13e7ed36ca8a5ae26d5fe7bd38b92b6a0c94" },
|
||||
{"fullmoon_AR", "03639bc56d3fecf856f17759a441c5893668e7c2d460f3d216798a413cd6766bb2" },
|
||||
{"fullmoon_NA", "03e388bcc579ac2675f8fadfa921eec186dcea8d2b43de1eed6caba23d5a962b74" },
|
||||
{"fullmoon_SH", "03a5cfda2b097c808834ccdd805828c811b519611feabdfe6b3644312e53f6748f" },
|
||||
{"gcharang_SH", "02a654037d12cdd609f4fad48e15ec54538e03f61fdae1acb855f16ebacac6bd73" },
|
||||
{"greer_NA", "0262da6aaa0b295b8e2f120035924758a4a630f899316dc63ee15ef03e9b7b2b23" },
|
||||
{"indenodes_AR", "0242778789986d614f75bcf629081651b851a12ab1cc10c73995b27b90febb75a2" },
|
||||
{"indenodes_EU", "03a416533cace0814455a1bb1cd7861ce825a543c6f6284a432c4c8d8875b7ace9" },
|
||||
{"indenodes_NA", "02b3908eda4078f0e9b6704451cdc24d418e899c0f515fab338d7494da6f0a647b" },
|
||||
{"indenodes_SH", "031d1584cf0eb4a2d314465e49e2677226b1615c3718013b8d6b4854c15676a58c" },
|
||||
{"karasugoi_NA", "02f803e6f159824a181cc5d709f3d1e7ff65f19e1899920724aeb4e3d2d869f911" },
|
||||
{"madmax_AR", "027afddbcf690230dd8d435ec16a7bfb0083e6b77030f763437f291dfc40a579d0" },
|
||||
{"madmax_EU", "0397ec3a4ad84b3009566d260c89f1c4404e86e5d044964747c9371277e38f5995" },
|
||||
{"madmax_NA", "036d3afebe1eab09f4c38c3ee6a4659ad390f3df92787c11437a58c59a29e408e6" },
|
||||
{"marmarachain_AR", "028690ca1e3afdf8a38b421f6a41f5ff407afc96d5a7a6a488330aae26c8b086bb" },
|
||||
{"mcrypt_SH", "027a4ca7b11d3456ff558c08bb04483a89c7f383448461fd0b6b3b07424aabe9a4" },
|
||||
{"metaphilibert_AR", "0239e34ad22957bbf4c8df824401f237b2afe8d40f7a645ecd43e8f27dde1ab0da" },
|
||||
{"metaphilibert_SH", "03b21ff042bf1730b28bde43f44c064578b41996117ac7634b567c3773089e3be3" },
|
||||
{"mihailo_EU", "036494e7c9467c8c7ff3bf29e841907fb0fa24241866569944ea422479ec0e6252" },
|
||||
{"mrlynch_AR", "03e67440141f53a08684c329ebc852b018e41f905da88e52aa4a6dc5aa4b12447a" },
|
||||
{"mylo_SH", "026d5f29d09ff3f33e14db4811606249b2438c6bcf964876714f81d1f2d952acde" },
|
||||
{"node9_EU", "0392e4c9400e69f28c6b9e89d586da69d5a6af7702f1045eaa6ebc1996f0496e1f" },
|
||||
{"nodeone_NA", "0310a249c6c2dcc29f2135715138a9ddb8e01c0eab701cbd0b96d9cec660dbdc58" },
|
||||
{"nutellalicka_SH", "0284c4d3cb97dd8a32d10fb32b1855ae18cf845dad542e3b8937ca0e998fb54ecc" },
|
||||
{"oszy_EU", "03c53bd421de4a29ce68c8cc83f802e1181e77c08f8f16684490d61452ea8d023a" },
|
||||
{"patchkez_SH", "028c08db6e7242681f50db6c234fe3d6e12fb1a915350311be26373bac0d457d49" },
|
||||
{"pbca26_NA", "03c18431bb6bc95672f640f19998a196becd2851d5dcba4795fe8d85b7d77eab81" },
|
||||
{"peer2cloud_AR", "0243958faf9ae4d43b598b859ddc595c170c4cf50f8e4517d660ae5bc72aeb821b" },
|
||||
{"phba2061_EU", "03369187ce134bd7793ee34af7756fe1ab27202e09306491cdd5d8ad2c71697937" },
|
||||
{"phm87_SH", "03889a10f9df2caef57220628515693cf25316fe1b0693b0241419e75d0d0e66ed" },
|
||||
{"pirate_EU", "0240011b95cde819f298fe0f507b2260c9fecdab784924076d4d1e54c522103cb1" },
|
||||
{"pirate_NA", "02ad7ef25d2dd461e361120cd3efe7cbce5e9512c361e9185aac33dd303d758613" },
|
||||
{"pungocloud_SH", "02641c36ae6747b88150a463a1fe65cf7a9d1c00a64387c73f296f0b64e77c7d3f" },
|
||||
{"smdmitry_AR", "0397b7584cb29717b721c0c587d4462477efc1f36a56921f133c9d17b0cd7f278a" },
|
||||
{"starfleet_EU", "03c6e047218f34644ccba67e317b9da5d28e68bbbb6b9973aef1281d2bafa46496" },
|
||||
{"strob_NA", "02285bf2f9e96068ecac14bc6f770e394927b4da9f5ba833eaa9468b5d47f203a3" },
|
||||
{"strob_SH", "0213751a1c59d3489ca85b3d62a3d606dcef7f0428aa021c1978ea16fb38a2fad6" },
|
||||
{"swisscertifiers_EU", "02e7722ebba9f8b5ebfb4e87d4fa58cc75aef677535b9cfc060c7d9471aacd9c9e" },
|
||||
{"titomane_AR", "03958bd8d13fe6946b8d0d0fbbc3861c72542560d0276e80a4c6b5fe55bc758b81" },
|
||||
{"titomane_EU", "02276090e483db1a01a802456b10831b3b6e0a6ad3ece9b2a01f4aad0e480c8edc" },
|
||||
{"titomane_SH", "02abf206bafc8048dbdc042b8eb6b1e356ea5dbe149eae3532b4811d4905e5cf01" },
|
||||
{"tonyl_AR", "0229e499e3f2e065ced402ceb8aaf3d5ab8bd3793aa074305e9fa30772ce604908" },
|
||||
{"tonyl_DEV", "0258b77d7dcfc6c2628b0b6b438951a6e74201fb2cd180a795e4c37fcf8e78a678" },
|
||||
{"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" },
|
||||
{"zatjum_SH", "0241c5660ca540780be66603b1791127a1261d56abbcb7562c297eec8e4fc078fb" }
|
||||
}
|
||||
};
|
||||
|
||||
#define SETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] |= (1 << ((bitoffset) & 7)))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
|
||||
304
src/main.cpp
304
src/main.cpp
@@ -85,6 +85,7 @@ int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
|
||||
//void komodo_broadcast(CBlock *pblock,int32_t limit);
|
||||
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
|
||||
void komodo_setactivation(int32_t height);
|
||||
void hush_changeblocktime();
|
||||
void komodo_pricesupdate(int32_t height,CBlock *pblock);
|
||||
|
||||
BlockMap mapBlockIndex;
|
||||
@@ -114,6 +115,8 @@ bool fAlerts = DEFAULT_ALERTS;
|
||||
/* If the tip is older than this (in seconds), the node is considered to be in initial block download.
|
||||
*/
|
||||
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
|
||||
bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false;
|
||||
int32_t nFirstHalvingHeight = 340000;
|
||||
|
||||
unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
@@ -957,7 +960,7 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
|
||||
}
|
||||
else if (!txin.IsFinal())
|
||||
{
|
||||
LogPrintf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
|
||||
LogPrintf("non-final txin txid.%s seq.%x locktime.%u vs nTime.%u\n",tx.GetHash().ToString().c_str(),txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -998,7 +1001,7 @@ bool CheckFinalTx(const CTransaction &tx, int flags)
|
||||
// However this changes once median past time-locks are enforced:
|
||||
const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
|
||||
? chainActive.Tip()->GetMedianTimePast()
|
||||
: GetAdjustedTime();
|
||||
: GetTime();
|
||||
|
||||
return IsFinalTx(tx, nBlockHeight, nBlockTime);
|
||||
}
|
||||
@@ -1224,9 +1227,9 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde
|
||||
if (IsExpiredTx(tx, nHeight)) {
|
||||
// Don't increase banscore if the transaction only just expired
|
||||
int expiredDosLevel = IsExpiredTx(tx, nHeight - 1) ? (dosLevel > 10 ? dosLevel : 10) : 0;
|
||||
string strHex = EncodeHexTx(tx);
|
||||
//string strHex = EncodeHexTx(tx);
|
||||
//fprintf(stderr, "transaction exipred.%s\n",strHex.c_str());
|
||||
return state.DoS(expiredDosLevel, error("ContextualCheckTransaction(): transaction %s is expired, expiry block %i vs current block %i\n txhex.%s",tx.GetHash().ToString(),tx.nExpiryHeight,nHeight,strHex), REJECT_INVALID, "tx-overwinter-expired");
|
||||
return state.DoS(expiredDosLevel, error("ContextualCheckTransaction(): transaction %s is expired, expiry block %i vs current block %i\n",tx.GetHash().ToString(),tx.nExpiryHeight,nHeight), REJECT_INVALID, "tx-overwinter-expired");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1327,6 +1330,7 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde
|
||||
))
|
||||
{
|
||||
librustzcash_sapling_verification_ctx_free(ctx);
|
||||
fprintf(stderr,"%s: Invalid sapling binding sig! tx=%s valueBalance=%li, bindingSig.size=%li\n", __func__, tx.GetHash().ToString().c_str(), tx.valueBalance, tx.bindingSig.size() );
|
||||
return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"),
|
||||
REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid");
|
||||
}
|
||||
@@ -1366,16 +1370,8 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState
|
||||
|
||||
if (!CheckTransactionWithoutProofVerification(tiptime,tx, state)) {
|
||||
return false;
|
||||
} else {
|
||||
// Ensure that zk-SNARKs v|| y
|
||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
|
||||
if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
|
||||
return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
|
||||
REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime) // from ac_private chains only
|
||||
@@ -1584,17 +1580,18 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio
|
||||
else if ( joinsplit.vpub_new != 0 && joinsplit.vpub_old == 0 )
|
||||
z_t++;
|
||||
}
|
||||
|
||||
if ( ASSETCHAINS_PRIVATE != 0 && invalid_private_taddr != 0 )
|
||||
{
|
||||
static uint32_t counter;
|
||||
if ( counter++ < 10 )
|
||||
fprintf(stderr,"found taddr in private chain: z_z.%d z_t.%d t_z.%d vinsize.%d\n",z_z,z_t,t_z,(int32_t)tx.vin.size());
|
||||
if ( z_t == 0 || z_z != 0 || t_z != 0 || tx.vin.size() != 0 )
|
||||
return state.DoS(100, error("CheckTransaction(): this is a private chain, only sprout -> taddr allowed until deadline"),REJECT_INVALID, "bad-txns-acprivacy-chain");
|
||||
return state.DoS(100, error("CheckTransaction(): this is a private chain, sending to taddrs not allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain");
|
||||
}
|
||||
if ( ASSETCHAINS_TXPOW != 0 )
|
||||
{
|
||||
// genesis coinbase 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
||||
// BTC genesis coinbase 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
|
||||
uint256 txid = tx.GetHash();
|
||||
if ( ((ASSETCHAINS_TXPOW & 2) != 0 && iscoinbase != 0) || ((ASSETCHAINS_TXPOW & 1) != 0 && iscoinbase == 0) )
|
||||
{
|
||||
@@ -1740,6 +1737,23 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
|
||||
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, int dosLevel)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
const uint32_t z2zTransitionWindow = 10;
|
||||
const uint32_t z2zTransitionStart = 340000 - z2zTransitionWindow;
|
||||
const uint32_t nHeight = chainActive.Height();
|
||||
|
||||
// This only applies to HUSH3, other chains can start off z2z via ac_private=1
|
||||
if(ishush3) {
|
||||
if((nHeight >= z2zTransitionStart) || (nHeight <= 340000)) {
|
||||
// During the z2z transition window, only coinbase tx's as part of blocks are allowed
|
||||
// Theory: We want an empty mempool at our fork block height, and the only way to assure that
|
||||
// is to have an empty mempool for a few previous blocks, to take care of potential re-orgs
|
||||
// and edge cases. This empty mempool assures there will be no transactions involving taddrs
|
||||
// stuck in the mempool, when the z2z rule takes effect.
|
||||
// Thanks to jl777 for helping design this
|
||||
fprintf(stderr,"%s: rejecting all tx's during z2z transition window at height=%d\n", __func__,nHeight);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (pfMissingInputs)
|
||||
*pfMissingInputs = false;
|
||||
uint32_t tiptime;
|
||||
@@ -1893,10 +1907,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
}
|
||||
|
||||
// are the joinsplit's requirements met?
|
||||
if (!view.HaveJoinSplitRequirements(tx))
|
||||
if (!view.HaveShieldedRequirements(tx))
|
||||
{
|
||||
//fprintf(stderr,"accept failure.2\n");
|
||||
return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
|
||||
return state.Invalid(error("AcceptToMemoryPool: shielded requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
|
||||
}
|
||||
|
||||
// Bring the best block into scope
|
||||
@@ -2060,8 +2074,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
}
|
||||
}
|
||||
}
|
||||
// This should be here still?
|
||||
//SyncWithWallets(tx, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2719,9 +2731,9 @@ namespace Consensus {
|
||||
if (!inputs.HaveInputs(tx))
|
||||
return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
|
||||
|
||||
// are the JoinSplit's requirements met?
|
||||
if (!inputs.HaveJoinSplitRequirements(tx))
|
||||
return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString()));
|
||||
// are the shielded requirements met?
|
||||
if (!inputs.HaveShieldedRequirements(tx))
|
||||
return state.Invalid(error("CheckInputs(): %s shielded requirements not met", tx.GetHash().ToString()));
|
||||
|
||||
CAmount nValueIn = 0;
|
||||
CAmount nFees = 0;
|
||||
@@ -3217,6 +3229,16 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
||||
// move best block pointer to prevout block
|
||||
view.SetBestBlock(pindex->pprev->GetBlockHash());
|
||||
|
||||
// If disconnecting a block brings us back before our blocktime halving height, go back
|
||||
// to our original blocktime so our DAA has the correct target for that height
|
||||
int nHeight = pindex->pprev->GetHeight();
|
||||
if (ishush3 && (ASSETCHAINS_BLOCKTIME != 150) && (nHeight < nFirstHalvingHeight)) {
|
||||
LogPrintf("%s: Setting blocktime to 150s at height %d!\n",__func__,nHeight);
|
||||
ASSETCHAINS_BLOCKTIME = 150;
|
||||
hush_changeblocktime();
|
||||
}
|
||||
|
||||
|
||||
if (pfClean) {
|
||||
*pfClean = fClean;
|
||||
return true;
|
||||
@@ -3277,7 +3299,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const
|
||||
if (bestHeader == NULL || initialDownloadCheck()) return;
|
||||
|
||||
static int64_t lastAlertTime = 0;
|
||||
int64_t now = GetAdjustedTime();
|
||||
int64_t now = GetTime();
|
||||
if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
|
||||
|
||||
const int SPAN_HOURS=4;
|
||||
@@ -3287,7 +3309,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const
|
||||
boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
|
||||
|
||||
std::string strWarning;
|
||||
int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
|
||||
int64_t startTime = GetTime()-SPAN_SECONDS;
|
||||
|
||||
LOCK(cs);
|
||||
const CBlockIndex* i = bestHeader;
|
||||
@@ -3340,6 +3362,7 @@ static int64_t nTimeTotal = 0;
|
||||
bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false);
|
||||
bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos);
|
||||
|
||||
|
||||
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
|
||||
{
|
||||
CDiskBlockPos blockPos;
|
||||
@@ -3350,6 +3373,24 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
return(false);
|
||||
//fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->GetHeight());
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false;
|
||||
|
||||
// At startup, HUSH3 doesn't know a block height yet and so we must wait until
|
||||
// connecting a block to set our private/blocktime flags, which are height-dependent
|
||||
if(!ASSETCHAINS_PRIVATE && ishush3) {
|
||||
unsigned int nHeight = pindex->GetHeight();
|
||||
if(nHeight >= nFirstHalvingHeight) {
|
||||
fprintf(stderr, "%s: Going full z2z at height %d!\n",__func__,pindex->GetHeight());
|
||||
ASSETCHAINS_PRIVATE = 1;
|
||||
}
|
||||
}
|
||||
if (ishush3 && (ASSETCHAINS_BLOCKTIME != 75) && (chainActive.Height() >= nFirstHalvingHeight)) {
|
||||
LogPrintf("%s: Blocktime halving to 75s at height %d!\n",__func__,pindex->GetHeight());
|
||||
ASSETCHAINS_BLOCKTIME = 75;
|
||||
hush_changeblocktime();
|
||||
}
|
||||
|
||||
bool fExpensiveChecks = true;
|
||||
if (fCheckpointsEnabled) {
|
||||
CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
|
||||
@@ -3443,7 +3484,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
// Before the genesis block, there was an empty tree
|
||||
SproutMerkleTree tree;
|
||||
pindex->hashSproutAnchor = tree.root();
|
||||
// The genesis block contained no JoinSplits
|
||||
// The genesis block contained no JoinSplits, lulz
|
||||
pindex->hashFinalSproutRoot = pindex->hashSproutAnchor;
|
||||
}
|
||||
return true;
|
||||
@@ -3502,13 +3543,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
|
||||
// This should never fail: we should always be able to get the root
|
||||
// that is on the tip of our chain
|
||||
assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree));
|
||||
//assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree));
|
||||
|
||||
{
|
||||
//{
|
||||
// Consistency check: the root of the tree we're given should
|
||||
// match what we asked for.
|
||||
assert(sprout_tree.root() == old_sprout_tree_root);
|
||||
}
|
||||
//assert(sprout_tree.root() == old_sprout_tree_root);
|
||||
//}
|
||||
|
||||
SaplingMerkleTree sapling_tree;
|
||||
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
|
||||
@@ -3536,10 +3577,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
|
||||
REJECT_INVALID, "bad-txns-inputs-missingorspent");
|
||||
}
|
||||
// are the JoinSplit's requirements met?
|
||||
if (!view.HaveJoinSplitRequirements(tx))
|
||||
return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
|
||||
REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
|
||||
// are the shielded requirements met?
|
||||
if (!view.HaveShieldedRequirements(tx))
|
||||
return state.DoS(100, error("ConnectBlock(): shielded requirements not met"), REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
|
||||
|
||||
if (fAddressIndex || fSpentIndex)
|
||||
{
|
||||
@@ -3637,21 +3677,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
}
|
||||
}
|
||||
|
||||
//if ( ASSETCHAINS_SYMBOL[0] == 0 )
|
||||
// komodo_earned_interest(pindex->GetHeight(),sum);
|
||||
CTxUndo undoDummy;
|
||||
if (i > 0) {
|
||||
blockundo.vtxundo.push_back(CTxUndo());
|
||||
}
|
||||
UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->GetHeight());
|
||||
|
||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
|
||||
BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) {
|
||||
// Insert the note commitments into our temporary tree.
|
||||
|
||||
sprout_tree.append(note_commitment);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const OutputDescription &outputDescription, tx.vShieldedOutput) {
|
||||
sapling_tree.append(outputDescription.cm);
|
||||
@@ -3661,7 +3692,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
||||
}
|
||||
|
||||
view.PushAnchor(sprout_tree);
|
||||
//view.PushAnchor(sprout_tree);
|
||||
view.PushAnchor(sapling_tree);
|
||||
if (!fJustCheck) {
|
||||
pindex->hashFinalSproutRoot = sprout_tree.root();
|
||||
@@ -3952,8 +3983,16 @@ void static UpdateTip(CBlockIndex *pindexNew) {
|
||||
if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
|
||||
progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip());
|
||||
} else {
|
||||
int32_t longestchain = komodo_longestchain();
|
||||
progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
|
||||
int32_t longestchain = komodo_longestchain();
|
||||
progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
|
||||
}
|
||||
|
||||
if(ishush3) {
|
||||
if (ASSETCHAINS_BLOCKTIME != 75 && (chainActive.Height() >= nFirstHalvingHeight)) {
|
||||
LogPrintf("%s: Blocktime halving to 75s at height %d!\n",__func__,chainActive.Height());
|
||||
ASSETCHAINS_BLOCKTIME = 75;
|
||||
hush_changeblocktime();
|
||||
}
|
||||
}
|
||||
|
||||
LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
|
||||
@@ -3964,33 +4003,6 @@ void static UpdateTip(CBlockIndex *pindexNew) {
|
||||
pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
|
||||
|
||||
cvBlockChange.notify_all();
|
||||
|
||||
/*
|
||||
// https://github.com/zcash/zcash/issues/3992 -> https://github.com/zcash/zcash/commit/346d11d3eb2f8162df0cb00b1d1f49d542495198
|
||||
|
||||
// Check the version of the last 100 blocks to see if we need to upgrade:
|
||||
static bool fWarned = false;
|
||||
if (!IsInitialBlockDownload() && !fWarned)
|
||||
{
|
||||
int nUpgraded = 0;
|
||||
const CBlockIndex* pindex = chainActive.Tip();
|
||||
for (int i = 0; i < 100 && pindex != NULL; i++)
|
||||
{
|
||||
if (pindex->nVersion > CBlock::CURRENT_VERSION)
|
||||
++nUpgraded;
|
||||
pindex = pindex->pprev;
|
||||
}
|
||||
if (nUpgraded > 0)
|
||||
LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
|
||||
if (nUpgraded > 100/2)
|
||||
{
|
||||
// strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
|
||||
strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
|
||||
CAlert::Notify(strMiscWarning, true);
|
||||
fWarned = true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4068,21 +4080,8 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
|
||||
// Update chainActive and related variables.
|
||||
UpdateTip(pindexDelete->pprev);
|
||||
|
||||
// Get the current commitment tree
|
||||
SproutMerkleTree newSproutTree;
|
||||
SaplingMerkleTree newSaplingTree;
|
||||
assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newSproutTree));
|
||||
assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), newSaplingTree));
|
||||
// Let wallets know transactions went from 1-confirmed to
|
||||
// 0-confirmed or conflicted:
|
||||
std::vector<uint256> TxToRemove;
|
||||
for (int i = 0; i < block.vtx.size(); i++)
|
||||
{
|
||||
CTransaction &tx = block.vtx[i];
|
||||
SyncWithWallets(tx, NULL);
|
||||
}
|
||||
// Update cached incremental witnesses
|
||||
GetMainSignals().ChainTip(pindexDelete, &block, newSproutTree, newSaplingTree, false);
|
||||
// Updates to connected wallets are triggered by ThreadNotifyWallets
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4156,6 +4155,11 @@ static int64_t nTimeFlush = 0;
|
||||
static int64_t nTimeChainState = 0;
|
||||
static int64_t nTimePostConnect = 0;
|
||||
|
||||
// Protected by cs_main
|
||||
std::map<CBlockIndex*, std::list<CTransaction>> recentlyConflictedTxs;
|
||||
uint64_t nRecentlyConflictedSequence = 0;
|
||||
uint64_t nNotifiedSequence = 0;
|
||||
|
||||
/**
|
||||
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
|
||||
* corresponding to pindexNew, to bypass loading it again from disk.
|
||||
@@ -4175,14 +4179,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
||||
}
|
||||
KOMODO_CONNECTING = (int32_t)pindexNew->GetHeight();
|
||||
//fprintf(stderr,"%s connecting ht.%d maxsize.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pindexNew->GetHeight(),MAX_BLOCK_SIZE(pindexNew->GetHeight()),(int32_t)::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
|
||||
// Get the current commitment tree
|
||||
SproutMerkleTree oldSproutTree;
|
||||
SaplingMerkleTree oldSaplingTree;
|
||||
if ( KOMODO_NSPV_FULLNODE )
|
||||
{
|
||||
assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree));
|
||||
assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree));
|
||||
}
|
||||
|
||||
// Apply the block atomically to the chain state.
|
||||
int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
|
||||
int64_t nTime3;
|
||||
@@ -4220,29 +4217,25 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
||||
}
|
||||
int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
|
||||
LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
|
||||
|
||||
// Remove conflicting transactions from the mempool.
|
||||
list<CTransaction> txConflicted;
|
||||
std::list<CTransaction> txConflicted;
|
||||
mempool.removeForBlock(pblock->vtx, pindexNew->GetHeight(), txConflicted, !IsInitialBlockDownload());
|
||||
|
||||
// Remove transactions that expire at new block height from mempool
|
||||
mempool.removeExpired(pindexNew->GetHeight());
|
||||
auto ids = mempool.removeExpired(pindexNew->GetHeight());
|
||||
|
||||
for (auto id : ids) {
|
||||
uiInterface.NotifyTxExpiration(id);
|
||||
}
|
||||
|
||||
// Update chainActive & related variables.
|
||||
UpdateTip(pindexNew);
|
||||
if ( KOMODO_NSPV_FULLNODE )
|
||||
{
|
||||
// Tell wallet about transactions that went from mempool
|
||||
// to conflicted:
|
||||
BOOST_FOREACH(const CTransaction &tx, txConflicted) {
|
||||
SyncWithWallets(tx, NULL);
|
||||
}
|
||||
// ... and about transactions that got confirmed:
|
||||
BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
|
||||
SyncWithWallets(tx, pblock);
|
||||
}
|
||||
}
|
||||
// Update cached incremental witnesses
|
||||
GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true);
|
||||
|
||||
// Cache the conflicted transactions for subsequent notification.
|
||||
// Updates to connected wallets are triggered by ThreadNotifyWallets
|
||||
recentlyConflictedTxs.insert(std::make_pair(pindexNew, txConflicted));
|
||||
nRecentlyConflictedSequence += 1;
|
||||
|
||||
EnforceNodeDeprecation(pindexNew->GetHeight());
|
||||
|
||||
@@ -4278,6 +4271,30 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
||||
//fprintf(stderr,"%s: returning true\n", __FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
std::pair<std::map<CBlockIndex*, std::list<CTransaction>>, uint64_t> DrainRecentlyConflicted()
|
||||
{
|
||||
uint64_t recentlyConflictedSequence;
|
||||
std::map<CBlockIndex*, std::list<CTransaction>> txs;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
recentlyConflictedSequence = nRecentlyConflictedSequence;
|
||||
txs.swap(recentlyConflictedTxs);
|
||||
}
|
||||
|
||||
return std::make_pair(txs, recentlyConflictedSequence);
|
||||
}
|
||||
|
||||
void SetChainNotifiedSequence(uint64_t recentlyConflictedSequence) {
|
||||
assert(Params().NetworkIDString() == "regtest");
|
||||
LOCK(cs_main);
|
||||
nNotifiedSequence = recentlyConflictedSequence;
|
||||
}
|
||||
|
||||
bool ChainIsFullyNotified() {
|
||||
assert(Params().NetworkIDString() == "regtest");
|
||||
LOCK(cs_main);
|
||||
return nRecentlyConflictedSequence == nNotifiedSequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the tip of the chain with the most work in it, that isn't
|
||||
@@ -4717,7 +4734,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
CAmount sproutValue = 0;
|
||||
CAmount saplingValue = 0;
|
||||
bool isShieldedTx = false;
|
||||
unsigned int nShieldedSpends=0,nShieldedOutputs=0,nPayments=0, nShieldedOutputsInBlock=0;
|
||||
unsigned int nShieldedSpends=0,nShieldedSpendsInBlock=0,nShieldedOutputs=0,nPayments=0,nShieldedOutputsInBlock=0;
|
||||
unsigned int nShieldedTx=0,nFullyShieldedTx=0,nDeshieldingTx=0,nShieldingTx=0;
|
||||
unsigned int nShieldedPayments=0,nFullyShieldedPayments=0,nShieldingPayments=0,nDeshieldingPayments=0;
|
||||
unsigned int nNotarizations=0;
|
||||
@@ -4805,8 +4822,12 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
// No shielded payments, add transparent payments minus a change address
|
||||
nPayments += tx.vout.size() > 1 ? tx.vout.size()-1 : tx.vout.size();
|
||||
}
|
||||
// To calculate the anonset we must track the sum of zouts in every tx, in every block. -- Duke
|
||||
// To calculate the anonset we must track the sum of spends and zouts in every tx, in every block. -- Duke
|
||||
nShieldedOutputsInBlock += nShieldedOutputs;
|
||||
nShieldedSpendsInBlock += nShieldedSpends;
|
||||
if (fZdebug) {
|
||||
fprintf(stderr,"%s: tx=%s has zspends=%d zouts=%d\n", __FUNCTION__, tx.GetHash().ToString().c_str(), nShieldedSpendsInBlock, nShieldedOutputsInBlock );
|
||||
}
|
||||
}
|
||||
|
||||
pindexNew->nSproutValue = sproutValue;
|
||||
@@ -4823,6 +4844,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
pindexNew->nPayments = nPayments;
|
||||
pindexNew->nShieldedTx = nShieldedTx;
|
||||
pindexNew->nShieldedOutputs = nShieldedOutputsInBlock;
|
||||
pindexNew->nShieldedSpends = nShieldedSpendsInBlock;
|
||||
pindexNew->nFullyShieldedTx = nFullyShieldedTx;
|
||||
pindexNew->nDeshieldingTx = nDeshieldingTx;
|
||||
pindexNew->nShieldingTx = nShieldingTx;
|
||||
@@ -4845,12 +4867,15 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
queue.pop_front();
|
||||
pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
|
||||
|
||||
// Update -zindex stats
|
||||
if (fZindex) {
|
||||
if (fZdebug)
|
||||
fprintf(stderr,"%s: setting blockchain zstats with zouts=%d\n", __FUNCTION__, nShieldedOutputsInBlock );
|
||||
if (fZdebug) {
|
||||
fprintf(stderr,"%s: setting blockchain zstats with zspends=%d, zouts=%d\n", __FUNCTION__, nShieldedSpendsInBlock, nShieldedOutputsInBlock );
|
||||
}
|
||||
pindex->nChainNotarizations = (pindex->pprev ? pindex->pprev->nChainNotarizations : 0) + pindex->nNotarizations;
|
||||
pindex->nChainShieldedTx = (pindex->pprev ? pindex->pprev->nChainShieldedTx : 0) + pindex->nShieldedTx;
|
||||
pindex->nChainShieldedOutputs = (pindex->pprev ? pindex->pprev->nChainShieldedOutputs : 0) + pindex->nShieldedOutputs;
|
||||
pindex->nChainShieldedSpends = (pindex->pprev ? pindex->pprev->nChainShieldedSpends : 0) + pindex->nShieldedSpends;
|
||||
pindex->nChainFullyShieldedTx = (pindex->pprev ? pindex->pprev->nChainFullyShieldedTx : 0) + pindex->nFullyShieldedTx;
|
||||
pindex->nChainShieldingTx = (pindex->pprev ? pindex->pprev->nChainShieldingTx : 0) + pindex->nShieldingTx;
|
||||
pindex->nChainDeshieldingTx = (pindex->pprev ? pindex->pprev->nChainDeshieldingTx : 0) + pindex->nDeshieldingTx;
|
||||
@@ -5106,28 +5131,28 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,
|
||||
*futureblockp = 0;
|
||||
if ( ASSETCHAINS_ADAPTIVEPOW > 0 )
|
||||
{
|
||||
if (blockhdr.GetBlockTime() > GetAdjustedTime() + 4)
|
||||
if (blockhdr.GetBlockTime() > GetTime() + 4)
|
||||
{
|
||||
//LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
|
||||
//LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetTime());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
|
||||
else if (blockhdr.GetBlockTime() > GetTime() + 60)
|
||||
{
|
||||
/*CBlockIndex *tipindex;
|
||||
//fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
|
||||
if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
|
||||
//fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetTime());
|
||||
if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetTime() + 60 + 5 )
|
||||
{
|
||||
//fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
|
||||
while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
|
||||
//fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetTime() + 60 - blockhdr.GetBlockTime());
|
||||
while ( blockhdr.GetBlockTime() > GetTime() + 60 )
|
||||
sleep(1);
|
||||
//fprintf(stderr,"now its valid\n");
|
||||
}
|
||||
else*/
|
||||
{
|
||||
if (blockhdr.GetBlockTime() < GetAdjustedTime() + 300)
|
||||
if (blockhdr.GetBlockTime() < GetTime() + 300)
|
||||
*futureblockp = 1;
|
||||
//LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
|
||||
//LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetTime());
|
||||
return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
|
||||
}
|
||||
}
|
||||
@@ -5316,11 +5341,6 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (ptx)
|
||||
{
|
||||
SyncWithWallets(*ptx, &block);
|
||||
}
|
||||
|
||||
if ( ASSETCHAINS_CC != 0 )
|
||||
{
|
||||
LOCK2(cs_main,mempool.cs);
|
||||
@@ -5380,7 +5400,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
|
||||
}
|
||||
|
||||
// Check that timestamp is not too far in the future
|
||||
if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime)
|
||||
if (block.GetBlockTime() > GetTime() + consensusParams.nMaxFutureBlockTime)
|
||||
{
|
||||
return state.Invalid(error("%s: block timestamp too far in the future", __func__),
|
||||
REJECT_INVALID, "time-too-new");
|
||||
@@ -6094,7 +6114,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash)
|
||||
// Create new
|
||||
CBlockIndex* pindexNew = new CBlockIndex();
|
||||
if (!pindexNew)
|
||||
throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
|
||||
throw runtime_error("InsertBlockIndex(): new CBlockIndex failed");
|
||||
mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
|
||||
pindexNew->phashBlock = &((*mi).first);
|
||||
//fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
|
||||
@@ -6311,6 +6331,13 @@ bool static LoadBlockIndexDB()
|
||||
|
||||
chainActive.SetTip(it->second);
|
||||
|
||||
// Try to detect if we are z2z based on height of blocks on disk
|
||||
// This helps to set it correctly on startup before a new block is connected
|
||||
if(ishush3 && chainActive.Height() >= 340000) {
|
||||
LogPrintf("%s: enabled ac_private=1 at height=%d\n", __func__, chainActive.Height());
|
||||
ASSETCHAINS_PRIVATE = 1;
|
||||
}
|
||||
|
||||
// Set hashFinalSproutRoot for the end of best chain
|
||||
it->second->hashFinalSproutRoot = pcoinsTip->GetBestAnchor(SPROUT);
|
||||
|
||||
@@ -6373,7 +6400,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
|
||||
CBlockIndex* pindexFailure = NULL;
|
||||
int nGoodTransactions = 0;
|
||||
CValidationState state;
|
||||
// No need to verify JoinSplits twice
|
||||
// No need to verify shielded req's twice
|
||||
auto verifier = libzcash::ProofVerifier::Disabled();
|
||||
//fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
|
||||
for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
|
||||
@@ -7391,9 +7418,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
|
||||
remoteAddr);
|
||||
|
||||
int64_t nTimeOffset = nTime - GetTime();
|
||||
pfrom->nTimeOffset = nTimeOffset;
|
||||
AddTimeData(pfrom->addr, nTimeOffset);
|
||||
//int64_t nTimeOffset = nTime - GetTime();
|
||||
//pfrom->nTimeOffset = nTimeOffset;
|
||||
//AddTimeData(pfrom->addr, nTimeOffset);
|
||||
pfrom->nTimeOffset = timeWarning.AddTimeData(pfrom->addr, nTime, GetTime());
|
||||
}
|
||||
|
||||
|
||||
@@ -7469,7 +7497,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
|
||||
// Store the new addresses
|
||||
vector<CAddress> vAddrOk;
|
||||
int64_t nNow = GetAdjustedTime();
|
||||
int64_t nNow = GetTime();
|
||||
int64_t nSince = nNow - 10 * 60;
|
||||
BOOST_FOREACH(CAddress& addr, vAddr)
|
||||
{
|
||||
@@ -7679,7 +7707,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
// not a direct successor.
|
||||
pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
|
||||
CNodeState *nodestate = State(pfrom->GetId());
|
||||
if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
|
||||
if (chainActive.Tip()->GetBlockTime() > GetTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
|
||||
nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
vToFetch.push_back(inv);
|
||||
// Mark block as in flight already, even though the actual "getdata" message only goes out
|
||||
@@ -8442,7 +8470,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
|
||||
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex && pindexBestHeader!=0) {
|
||||
// Only actively request headers from a single peer, unless we're close to today.
|
||||
if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
|
||||
if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetTime() - 24 * 60 * 60) {
|
||||
state.fSyncStarted = true;
|
||||
nSyncStarted++;
|
||||
CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
|
||||
|
||||
@@ -949,4 +949,8 @@ uint64_t CalculateCurrentUsage();
|
||||
/** Return a CMutableTransaction with contextual default values based on set of consensus rules at height */
|
||||
CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight);
|
||||
|
||||
std::pair<std::map<CBlockIndex*, std::list<CTransaction>>, uint64_t> DrainRecentlyConflicted();
|
||||
void SetChainNotifiedSequence(uint64_t recentlyConflictedSequence);
|
||||
bool ChainIsFullyNotified();
|
||||
|
||||
#endif // BITCOIN_MAIN_H
|
||||
|
||||
@@ -288,7 +288,7 @@ int printMiningStatus(bool mining)
|
||||
} else if (IsInitialBlockDownload()) {
|
||||
std::cout << _("Mining is paused while downloading blocks.") << std::endl;
|
||||
} else {
|
||||
std::cout << _("Mining is paused (a JoinSplit may be in progress).") << std::endl;
|
||||
std::cout << _("Mining is paused, enhance your calm") << std::endl;
|
||||
}
|
||||
}
|
||||
lines++;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
@@ -126,8 +126,8 @@ extern int8_t ASSETCHAINS_ADAPTIVEPOW;
|
||||
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
|
||||
{
|
||||
if ( ASSETCHAINS_ADAPTIVEPOW <= 0 )
|
||||
pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
||||
else pblock->nTime = std::max((int64_t)(pindexPrev->nTime+1), GetAdjustedTime());
|
||||
pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetTime());
|
||||
else pblock->nTime = std::max((int64_t)(pindexPrev->nTime+1), GetTime());
|
||||
|
||||
// Updating time can change work required on testnet:
|
||||
if (ASSETCHAINS_ADAPTIVEPOW > 0 || consensusParams.nPowAllowMinDifficultyBlocksAfterHeight != boost::none)
|
||||
@@ -239,7 +239,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
bool sapling = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING);
|
||||
|
||||
const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
|
||||
uint32_t proposedTime = GetAdjustedTime();
|
||||
uint32_t proposedTime = GetTime();
|
||||
voutsum = GetBlockSubsidy(nHeight,consensusParams) + 10000*COIN; // approx fees
|
||||
|
||||
if (proposedTime == nMedianTimePast)
|
||||
@@ -248,12 +248,12 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
// forward as quickly as possible
|
||||
for (int i; i < 100; i++)
|
||||
{
|
||||
proposedTime = GetAdjustedTime();
|
||||
proposedTime = GetTime();
|
||||
if (proposedTime == nMedianTimePast)
|
||||
MilliSleep(10);
|
||||
}
|
||||
}
|
||||
pblock->nTime = GetAdjustedTime();
|
||||
pblock->nTime = GetTime();
|
||||
// Now we have the block time + height, we can get the active notaries.
|
||||
int8_t numSN = 0; uint8_t notarypubkeys[64][33] = {0};
|
||||
if ( ASSETCHAINS_NOTARY_PAY[0] != 0 )
|
||||
@@ -340,7 +340,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
if (!mempool.mapTx.count(txin.prevout.hash))
|
||||
{
|
||||
LogPrintf("ERROR: mempool transaction missing input\n");
|
||||
if (fDebug) assert("mempool transaction missing input" == 0);
|
||||
// if (fDebug) assert("mempool transaction missing input" == 0);
|
||||
fMissingInputs = true;
|
||||
if (porphan)
|
||||
vOrphan.pop_back();
|
||||
@@ -472,6 +472,40 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
|
||||
// Size limits
|
||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
// Opret spam limits
|
||||
if (mapArgs.count("-opretmintxfee"))
|
||||
{
|
||||
CAmount n = 0;
|
||||
CFeeRate opretMinFeeRate;
|
||||
if (ParseMoney(mapArgs["-opretmintxfee"], n) && n > 0)
|
||||
opretMinFeeRate = CFeeRate(n);
|
||||
else
|
||||
opretMinFeeRate = CFeeRate(400000); // default opretMinFeeRate (1 HUSH per 250 Kb = 0.004 per 1 Kb = 400000 puposhis per 1 Kb)
|
||||
|
||||
bool fSpamTx = false;
|
||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||
unsigned int nTxOpretSize = 0;
|
||||
|
||||
// calc total oprets size
|
||||
BOOST_FOREACH(const CTxOut& txout, tx.vout) {
|
||||
if (txout.scriptPubKey.IsOpReturn()) {
|
||||
CScript::const_iterator it = txout.scriptPubKey.begin() + 1;
|
||||
opcodetype op;
|
||||
std::vector<uint8_t> opretData;
|
||||
if (txout.scriptPubKey.GetOp(it, op, opretData)) {
|
||||
//std::cerr << HexStr(opretData.begin(), opretData.end()) << std::endl;
|
||||
nTxOpretSize += opretData.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((nTxOpretSize > 256) && (feeRate < opretMinFeeRate)) fSpamTx = true;
|
||||
// std::cerr << tx.GetHash().ToString() << " nTxSize." << nTxSize << " nTxOpretSize." << nTxOpretSize << " feeRate." << feeRate.ToString() << " opretMinFeeRate." << opretMinFeeRate.ToString() << " fSpamTx." << fSpamTx << std::endl;
|
||||
if (fSpamTx) continue;
|
||||
// std::cerr << tx.GetHash().ToString() << " vecPriority.size() = " << vecPriority.size() << std::endl;
|
||||
}
|
||||
|
||||
if (nBlockSize + nTxSize >= nBlockMaxSize-512) // room for extra autotx
|
||||
{
|
||||
//fprintf(stderr,"nBlockSize %d + %d nTxSize >= %d nBlockMaxSize\n",(int32_t)nBlockSize,(int32_t)nTxSize,(int32_t)nBlockMaxSize);
|
||||
@@ -569,8 +603,8 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
nLastBlockTx = nBlockTx;
|
||||
nLastBlockSize = nBlockSize;
|
||||
if ( ASSETCHAINS_ADAPTIVEPOW <= 0 )
|
||||
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
||||
else blocktime = 1 + std::max((int64_t)(pindexPrev->nTime+1), GetAdjustedTime());
|
||||
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetTime());
|
||||
else blocktime = 1 + std::max((int64_t)(pindexPrev->nTime+1), GetTime());
|
||||
//pblock->nTime = blocktime + 1;
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||
|
||||
@@ -590,8 +624,8 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
//fprintf(stderr,"mine ht.%d with %.8f\n",nHeight,(double)txNew.vout[0].nValue/COIN);
|
||||
txNew.nExpiryHeight = 0;
|
||||
if ( ASSETCHAINS_ADAPTIVEPOW <= 0 )
|
||||
txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
||||
else txNew.nLockTime = std::max((int64_t)(pindexPrev->nTime+1), GetAdjustedTime());
|
||||
txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetTime());
|
||||
else txNew.nLockTime = std::max((int64_t)(pindexPrev->nTime+1), GetTime());
|
||||
|
||||
|
||||
if ( ASSETCHAINS_SYMBOL[0] == 0 && IS_KOMODO_NOTARY != 0 && My_notaryid >= 0 )
|
||||
@@ -949,6 +983,9 @@ static bool ProcessBlockFound(CBlock* pblock)
|
||||
}
|
||||
}
|
||||
|
||||
// Inform about the new block
|
||||
GetMainSignals().BlockFound(pblock->GetHash());
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
// Remove key from key pool
|
||||
if ( IS_KOMODO_NOTARY == 0 )
|
||||
@@ -1331,10 +1368,10 @@ void static BitcoinMiner()
|
||||
// MilliSleep(30);
|
||||
return false;
|
||||
}
|
||||
if ( IS_KOMODO_NOTARY != 0 && B.nTime > GetAdjustedTime() )
|
||||
if ( IS_KOMODO_NOTARY != 0 && B.nTime > GetTime() )
|
||||
{
|
||||
//fprintf(stderr,"need to wait %d seconds to submit block\n",(int32_t)(B.nTime - GetAdjustedTime()));
|
||||
while ( GetAdjustedTime() < B.nTime-2 )
|
||||
//fprintf(stderr,"need to wait %d seconds to submit block\n",(int32_t)(B.nTime - GetTime()));
|
||||
while ( GetTime() < B.nTime-2 )
|
||||
{
|
||||
sleep(1);
|
||||
if ( chainActive.LastTip()->GetHeight() >= Mining_height )
|
||||
|
||||
10
src/net.cpp
10
src/net.cpp
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -193,7 +193,7 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer)
|
||||
ret = CAddress(addr);
|
||||
}
|
||||
ret.nServices = nLocalServices;
|
||||
ret.nTime = GetAdjustedTime();
|
||||
ret.nTime = GetTime();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
||||
/// debug print
|
||||
LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
|
||||
pszDest ? pszDest : addrConnect.ToString(),
|
||||
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
|
||||
pszDest ? 0.0 : (double)(GetTime() - addrConnect.nTime)/3600.0);
|
||||
|
||||
// Connect
|
||||
SOCKET hSocket;
|
||||
@@ -458,7 +458,7 @@ void CNode::PushVersion()
|
||||
{
|
||||
int nBestHeight = g_signals.GetHeight().get_value_or(0);
|
||||
|
||||
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
|
||||
int64_t nTime = (fInbound ? GetTime() : GetTime());
|
||||
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
|
||||
CAddress addrMe = GetLocalAddress(&addr);
|
||||
GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
|
||||
@@ -1429,7 +1429,7 @@ void ThreadOpenConnections()
|
||||
}
|
||||
}
|
||||
|
||||
int64_t nANow = GetAdjustedTime();
|
||||
int64_t nANow = GetTime();
|
||||
|
||||
int nTries = 0;
|
||||
while (true)
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "paymentdisclosure.h"
|
||||
|
||||
#include "key_io.h"
|
||||
#include "util.h"
|
||||
|
||||
std::string PaymentDisclosureInfo::ToString() const {
|
||||
return strprintf("PaymentDisclosureInfo(version=%d, esk=%s, joinSplitPrivKey=<omitted>, address=%s)",
|
||||
version, esk.ToString(), EncodePaymentAddress(zaddr));
|
||||
}
|
||||
|
||||
std::string PaymentDisclosure::ToString() const {
|
||||
std::string s = HexStr(payloadSig.begin(), payloadSig.end());
|
||||
return strprintf("PaymentDisclosure(payload=%s, payloadSig=%s)", payload.ToString(), s);
|
||||
}
|
||||
|
||||
std::string PaymentDisclosurePayload::ToString() const {
|
||||
return strprintf("PaymentDisclosurePayload(version=%d, esk=%s, txid=%s, js=%d, n=%d, address=%s, message=%s)",
|
||||
version, esk.ToString(), txid.ToString(), js, n, EncodePaymentAddress(zaddr), message);
|
||||
}
|
||||
|
||||
PaymentDisclosure::PaymentDisclosure(const uint256 &joinSplitPubKey, const PaymentDisclosureKey &key, const PaymentDisclosureInfo &info, const std::string &message)
|
||||
{
|
||||
// Populate payload member variable
|
||||
payload.version = info.version; // experimental = 0, production = 1 etc.
|
||||
payload.esk = info.esk;
|
||||
payload.txid = key.hash;
|
||||
payload.js = key.js;
|
||||
payload.n = key.n;
|
||||
payload.zaddr = info.zaddr;
|
||||
payload.message = message;
|
||||
|
||||
// Serialize and hash the payload to generate a signature
|
||||
uint256 dataToBeSigned = SerializeHash(payload, SER_GETHASH, 0);
|
||||
|
||||
LogPrint("paymentdisclosure", "Payment Disclosure: signing raw payload = %s\n", dataToBeSigned.ToString());
|
||||
|
||||
// Prepare buffer to store ed25519 key pair in libsodium-compatible format
|
||||
unsigned char bufferKeyPair[64];
|
||||
memcpy(&bufferKeyPair[0], info.joinSplitPrivKey.begin(), 32);
|
||||
memcpy(&bufferKeyPair[32], joinSplitPubKey.begin(), 32);
|
||||
|
||||
// Compute payload signature member variable
|
||||
if (!(crypto_sign_detached(payloadSig.data(), NULL,
|
||||
dataToBeSigned.begin(), 32,
|
||||
&bufferKeyPair[0]
|
||||
) == 0))
|
||||
{
|
||||
throw std::runtime_error("crypto_sign_detached failed");
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (!(crypto_sign_verify_detached(payloadSig.data(),
|
||||
dataToBeSigned.begin(), 32,
|
||||
joinSplitPubKey.begin()) == 0))
|
||||
{
|
||||
throw std::runtime_error("crypto_sign_verify_detached failed");
|
||||
}
|
||||
|
||||
std::string sigString = HexStr(payloadSig.data(), payloadSig.data() + payloadSig.size());
|
||||
LogPrint("paymentdisclosure", "Payment Disclosure: signature = %s\n", sigString);
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef ZCASH_PAYMENTDISCLOSURE_H
|
||||
#define ZCASH_PAYMENTDISCLOSURE_H
|
||||
|
||||
#include "uint256.h"
|
||||
#include "clientversion.h"
|
||||
#include "serialize.h"
|
||||
#include "streams.h"
|
||||
#include "version.h"
|
||||
|
||||
// For JSOutPoint
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
// Ensure that the two different protocol messages, payment disclosure blobs and transactions,
|
||||
// which are signed with the same key, joinSplitPrivKey, have disjoint encodings such that an
|
||||
// encoding from one context will be rejected in the other. We know that the set of valid
|
||||
// transaction versions is currently ({1..INT32_MAX}) so we will use a negative value for
|
||||
// payment disclosure of -10328976 which in hex is 0xFF626470. Serialization is in little endian
|
||||
// format, so a payment disclosure hex string begins 706462FF, which in ISO-8859-1 is "pdbÿ".
|
||||
#define PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES -10328976
|
||||
|
||||
#define PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL 0
|
||||
|
||||
#define PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX "zpd:"
|
||||
|
||||
typedef JSOutPoint PaymentDisclosureKey;
|
||||
|
||||
struct PaymentDisclosureInfo {
|
||||
uint8_t version; // 0 = experimental, 1 = first production version, etc.
|
||||
uint256 esk; // zcash/NoteEncryption.cpp
|
||||
uint256 joinSplitPrivKey; // primitives/transaction.h
|
||||
// ed25519 - not tied to implementation e.g. libsodium, see ed25519 rfc
|
||||
|
||||
libzcash::SproutPaymentAddress zaddr;
|
||||
|
||||
PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) {
|
||||
}
|
||||
|
||||
PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::SproutPaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { }
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(version);
|
||||
READWRITE(esk);
|
||||
READWRITE(joinSplitPrivKey);
|
||||
READWRITE(zaddr);
|
||||
}
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
friend bool operator==(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) {
|
||||
return (a.version == b.version && a.esk == b.esk && a.joinSplitPrivKey == b.joinSplitPrivKey && a.zaddr == b.zaddr);
|
||||
}
|
||||
|
||||
friend bool operator!=(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct PaymentDisclosurePayload {
|
||||
int32_t marker = PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES; // to be disjoint from transaction encoding
|
||||
uint8_t version; // 0 = experimental, 1 = first production version, etc.
|
||||
uint256 esk; // zcash/NoteEncryption.cpp
|
||||
uint256 txid; // primitives/transaction.h
|
||||
uint64_t js; // Index into CTransaction.vjoinsplit
|
||||
uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
|
||||
libzcash::SproutPaymentAddress zaddr; // zcash/Address.hpp
|
||||
std::string message; // parameter to RPC call
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(marker);
|
||||
READWRITE(version);
|
||||
READWRITE(esk);
|
||||
READWRITE(txid);
|
||||
READWRITE(js);
|
||||
READWRITE(n);
|
||||
READWRITE(zaddr);
|
||||
READWRITE(message);
|
||||
}
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
friend bool operator==(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) {
|
||||
return (
|
||||
a.version == b.version &&
|
||||
a.esk == b.esk &&
|
||||
a.txid == b.txid &&
|
||||
a.js == b.js &&
|
||||
a.n == b.n &&
|
||||
a.zaddr == b.zaddr &&
|
||||
a.message == b.message
|
||||
);
|
||||
}
|
||||
|
||||
friend bool operator!=(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
};
|
||||
|
||||
struct PaymentDisclosure {
|
||||
PaymentDisclosurePayload payload;
|
||||
std::array<unsigned char, 64> payloadSig;
|
||||
// We use boost array because serialize doesn't like char buffer, otherwise we could do: unsigned char payloadSig[64];
|
||||
|
||||
PaymentDisclosure() {};
|
||||
PaymentDisclosure(const PaymentDisclosurePayload payload, const std::array<unsigned char, 64> sig) : payload(payload), payloadSig(sig) {};
|
||||
PaymentDisclosure(const uint256& joinSplitPubKey, const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info, const std::string& message);
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(payload);
|
||||
READWRITE(payloadSig);
|
||||
}
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
friend bool operator==(const PaymentDisclosure& a, const PaymentDisclosure& b) {
|
||||
return (a.payload == b.payload && a.payloadSig == b.payloadSig);
|
||||
}
|
||||
|
||||
friend bool operator!=(const PaymentDisclosure& a, const PaymentDisclosure& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef std::pair<PaymentDisclosureKey, PaymentDisclosureInfo> PaymentDisclosureKeyInfo;
|
||||
|
||||
|
||||
#endif // ZCASH_PAYMENTDISCLOSURE_H
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "paymentdisclosuredb.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "dbwrapper.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static boost::filesystem::path emptyPath;
|
||||
|
||||
/**
|
||||
* Static method to return the shared/default payment disclosure database.
|
||||
*/
|
||||
shared_ptr<PaymentDisclosureDB> PaymentDisclosureDB::sharedInstance() {
|
||||
// Thread-safe in C++11 and gcc 4.3
|
||||
static shared_ptr<PaymentDisclosureDB> ptr = std::make_shared<PaymentDisclosureDB>();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// C++11 delegated constructor
|
||||
PaymentDisclosureDB::PaymentDisclosureDB() : PaymentDisclosureDB(emptyPath) {
|
||||
}
|
||||
|
||||
PaymentDisclosureDB::PaymentDisclosureDB(const boost::filesystem::path& dbPath) {
|
||||
boost::filesystem::path path(dbPath);
|
||||
if (path.empty()) {
|
||||
path = GetDataDir() / "paymentdisclosure";
|
||||
LogPrintf("PaymentDisclosure: using default path for database: %s\n", path.string());
|
||||
} else {
|
||||
LogPrintf("PaymentDisclosure: using custom path for database: %s\n", path.string());
|
||||
}
|
||||
|
||||
TryCreateDirectory(path);
|
||||
options.create_if_missing = true;
|
||||
leveldb::Status status = leveldb::DB::Open(options, path.string(), &db);
|
||||
dbwrapper_private::HandleError(status); // throws exception
|
||||
LogPrintf("PaymentDisclosure: Opened LevelDB successfully\n");
|
||||
}
|
||||
|
||||
PaymentDisclosureDB::~PaymentDisclosureDB() {
|
||||
if (db != nullptr) {
|
||||
delete db;
|
||||
}
|
||||
}
|
||||
|
||||
bool PaymentDisclosureDB::Put(const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info)
|
||||
{
|
||||
if (db == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
|
||||
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
||||
ssValue.reserve(GetSerializeSize(ssValue, info));
|
||||
ssValue << info;
|
||||
leveldb::Slice slice(&ssValue[0], ssValue.size());
|
||||
|
||||
leveldb::Status status = db->Put(writeOptions, key.ToString(), slice);
|
||||
dbwrapper_private::HandleError(status);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PaymentDisclosureDB::Get(const PaymentDisclosureKey& key, PaymentDisclosureInfo& info)
|
||||
{
|
||||
if (db == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
|
||||
std::string strValue;
|
||||
leveldb::Status status = db->Get(readOptions, key.ToString(), &strValue);
|
||||
if (!status.ok()) {
|
||||
if (status.IsNotFound())
|
||||
return false;
|
||||
LogPrintf("PaymentDisclosure: LevelDB read failure: %s\n", status.ToString());
|
||||
dbwrapper_private::HandleError(status);
|
||||
}
|
||||
|
||||
try {
|
||||
CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
|
||||
ssValue >> info;
|
||||
} catch (const std::exception&) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright (c) 2017 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef ZCASH_PAYMENTDISCLOSUREDB_H
|
||||
#define ZCASH_PAYMENTDISCLOSUREDB_H
|
||||
|
||||
#include "paymentdisclosure.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <future>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <leveldb/db.h>
|
||||
|
||||
|
||||
class PaymentDisclosureDB
|
||||
{
|
||||
protected:
|
||||
leveldb::DB* db = nullptr;
|
||||
leveldb::Options options;
|
||||
leveldb::ReadOptions readOptions;
|
||||
leveldb::WriteOptions writeOptions;
|
||||
mutable std::mutex lock_;
|
||||
|
||||
public:
|
||||
static std::shared_ptr<PaymentDisclosureDB> sharedInstance();
|
||||
|
||||
PaymentDisclosureDB();
|
||||
PaymentDisclosureDB(const boost::filesystem::path& dbPath);
|
||||
~PaymentDisclosureDB();
|
||||
|
||||
bool Put(const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info);
|
||||
bool Get(const PaymentDisclosureKey& key, PaymentDisclosureInfo& info);
|
||||
};
|
||||
|
||||
|
||||
#endif // ZCASH_PAYMENTDISCLOSUREDB_H
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -298,6 +298,9 @@ arith_uint256 zawy_TSA_EMA(int32_t height,int32_t tipdiff,arith_uint256 prevTarg
|
||||
|
||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||
{
|
||||
if (pindexLast->GetHeight() == 340000) {
|
||||
LogPrintf("%s: Using blocktime=%d\n",__func__,ASSETCHAINS_BLOCKTIME);
|
||||
}
|
||||
if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH && ASSETCHAINS_STAKED == 0)
|
||||
return lwmaGetNextWorkRequired(pindexLast, pblock, params);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define BITCOIN_PRIMITIVES_BLOCK_H
|
||||
|
||||
#include "primitives/transaction.h"
|
||||
#include "primitives/nonce.h"
|
||||
//#include "primitives/nonce.h"
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
#include "arith_uint256.h"
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright (c) 2019 The Hush Developers
|
||||
// Copyright (c) 2018 Michael Toutonghi
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
||||
* the top-level directory of this distribution for the individual copyright *
|
||||
* holder information and the developer policies on copyright and licensing. *
|
||||
* *
|
||||
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
||||
* SuperNET software, including this file may be copied, modified, propagated *
|
||||
* or distributed except according to the terms contained in the LICENSE file *
|
||||
* *
|
||||
* Removal or modification of this copyright notice is prohibited. *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#include "hash.h"
|
||||
#include "nonce.h"
|
||||
#include <cstring>
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright (c) 2019 Hush Developers
|
||||
// Copyright (c) 2018 Michael Toutonghi
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
||||
* the top-level directory of this distribution for the individual copyright *
|
||||
* holder information and the developer policies on copyright and licensing. *
|
||||
* *
|
||||
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
||||
* SuperNET software, including this file may be copied, modified, propagated *
|
||||
* or distributed except according to the terms contained in the LICENSE file *
|
||||
* *
|
||||
* Removal or modification of this copyright notice is prohibited. *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef BITCOIN_PRIMITIVES_NONCE_H
|
||||
#define BITCOIN_PRIMITIVES_NONCE_H
|
||||
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
#include "arith_uint256.h"
|
||||
|
||||
|
||||
#endif // BITCOIN_PRIMITIVES_NONCE_H
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -26,139 +27,6 @@
|
||||
|
||||
#include "librustzcash.h"
|
||||
|
||||
JSDescription::JSDescription(
|
||||
bool makeGrothProof,
|
||||
ZCJoinSplit& params,
|
||||
const uint256& joinSplitPubKey,
|
||||
const uint256& anchor,
|
||||
const std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||
const std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
||||
CAmount vpub_old,
|
||||
CAmount vpub_new,
|
||||
bool computeProof,
|
||||
uint256 *esk // payment disclosure
|
||||
) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor)
|
||||
{
|
||||
std::array<libzcash::SproutNote, ZC_NUM_JS_OUTPUTS> notes;
|
||||
|
||||
proof = params.prove(
|
||||
makeGrothProof,
|
||||
inputs,
|
||||
outputs,
|
||||
notes,
|
||||
ciphertexts,
|
||||
ephemeralKey,
|
||||
joinSplitPubKey,
|
||||
randomSeed,
|
||||
macs,
|
||||
nullifiers,
|
||||
commitments,
|
||||
vpub_old,
|
||||
vpub_new,
|
||||
anchor,
|
||||
computeProof,
|
||||
esk // payment disclosure
|
||||
);
|
||||
}
|
||||
|
||||
JSDescription JSDescription::Randomized(
|
||||
bool makeGrothProof,
|
||||
ZCJoinSplit& params,
|
||||
const uint256& joinSplitPubKey,
|
||||
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,
|
||||
CAmount vpub_old,
|
||||
CAmount vpub_new,
|
||||
bool computeProof,
|
||||
uint256 *esk, // payment disclosure
|
||||
std::function<int(int)> gen
|
||||
)
|
||||
{
|
||||
// Randomize the order of the inputs and outputs
|
||||
inputMap = {0, 1};
|
||||
outputMap = {0, 1};
|
||||
|
||||
assert(gen);
|
||||
|
||||
MappedShuffle(inputs.begin(), inputMap.begin(), ZC_NUM_JS_INPUTS, gen);
|
||||
MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen);
|
||||
|
||||
return JSDescription(
|
||||
makeGrothProof,
|
||||
params, joinSplitPubKey, anchor, inputs, outputs,
|
||||
vpub_old, vpub_new, computeProof,
|
||||
esk // payment disclosure
|
||||
);
|
||||
}
|
||||
|
||||
class SproutProofVerifier : public boost::static_visitor<bool>
|
||||
{
|
||||
ZCJoinSplit& params;
|
||||
libzcash::ProofVerifier& verifier;
|
||||
const uint256& joinSplitPubKey;
|
||||
const JSDescription& jsdesc;
|
||||
|
||||
public:
|
||||
SproutProofVerifier(
|
||||
ZCJoinSplit& params,
|
||||
libzcash::ProofVerifier& verifier,
|
||||
const uint256& joinSplitPubKey,
|
||||
const JSDescription& jsdesc
|
||||
) : params(params), jsdesc(jsdesc), verifier(verifier), joinSplitPubKey(joinSplitPubKey) {}
|
||||
|
||||
bool operator()(const libzcash::PHGRProof& proof) const
|
||||
{
|
||||
return params.verify(
|
||||
proof,
|
||||
verifier,
|
||||
joinSplitPubKey,
|
||||
jsdesc.randomSeed,
|
||||
jsdesc.macs,
|
||||
jsdesc.nullifiers,
|
||||
jsdesc.commitments,
|
||||
jsdesc.vpub_old,
|
||||
jsdesc.vpub_new,
|
||||
jsdesc.anchor
|
||||
);
|
||||
}
|
||||
|
||||
bool operator()(const libzcash::GrothProof& proof) const
|
||||
{
|
||||
uint256 h_sig = params.h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey);
|
||||
|
||||
return librustzcash_sprout_verify(
|
||||
proof.begin(),
|
||||
jsdesc.anchor.begin(),
|
||||
h_sig.begin(),
|
||||
jsdesc.macs[0].begin(),
|
||||
jsdesc.macs[1].begin(),
|
||||
jsdesc.nullifiers[0].begin(),
|
||||
jsdesc.nullifiers[1].begin(),
|
||||
jsdesc.commitments[0].begin(),
|
||||
jsdesc.commitments[1].begin(),
|
||||
jsdesc.vpub_old,
|
||||
jsdesc.vpub_new
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
bool JSDescription::Verify(
|
||||
ZCJoinSplit& params,
|
||||
libzcash::ProofVerifier& verifier,
|
||||
const uint256& joinSplitPubKey
|
||||
) const {
|
||||
auto pv = SproutProofVerifier(params, verifier, joinSplitPubKey, *this);
|
||||
return boost::apply_visitor(pv, proof);
|
||||
}
|
||||
|
||||
uint256 JSDescription::h_sig(ZCJoinSplit& params, const uint256& joinSplitPubKey) const
|
||||
{
|
||||
return params.h_sig(randomSeed, nullifiers, joinSplitPubKey);
|
||||
}
|
||||
|
||||
std::string COutPoint::ToString() const
|
||||
{
|
||||
return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -43,10 +44,16 @@
|
||||
#include "zcash/Zcash.h"
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
#include "zcash/Proof.hpp"
|
||||
#include "zcash/Note.hpp"
|
||||
|
||||
extern uint32_t ASSETCHAINS_MAGIC;
|
||||
extern std::string ASSETCHAINS_SELFIMPORT;
|
||||
|
||||
#define JOINSPLIT_SIZE GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION)
|
||||
#define OUTPUTDESCRIPTION_SIZE GetSerializeSize(OutputDescription(), SER_NETWORK, PROTOCOL_VERSION)
|
||||
#define SPENDDESCRIPTION_SIZE GetSerializeSize(SpendDescription(), SER_NETWORK, PROTOCOL_VERSION)
|
||||
|
||||
|
||||
// Overwinter transaction version
|
||||
static const int32_t OVERWINTER_TX_VERSION = 3;
|
||||
static_assert(OVERWINTER_TX_VERSION >= OVERWINTER_MIN_TX_VERSION,
|
||||
@@ -251,7 +258,6 @@ public:
|
||||
JSDescription(): vpub_old(0), vpub_new(0) { }
|
||||
|
||||
JSDescription(
|
||||
bool makeGrothProof,
|
||||
ZCJoinSplit& params,
|
||||
const uint256& joinSplitPubKey,
|
||||
const uint256& rt,
|
||||
@@ -264,7 +270,6 @@ public:
|
||||
);
|
||||
|
||||
static JSDescription Randomized(
|
||||
bool makeGrothProof,
|
||||
ZCJoinSplit& params,
|
||||
const uint256& joinSplitPubKey,
|
||||
const uint256& rt,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -1668,9 +1668,10 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp, const CPubKey& my
|
||||
obj.push_back(Pair("chainwork", chainActive.LastTip()->chainPower.chainWork.GetHex()));
|
||||
obj.push_back(Pair("pruned", fPruneMode));
|
||||
|
||||
SproutMerkleTree tree;
|
||||
pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), tree);
|
||||
obj.push_back(Pair("commitments", static_cast<uint64_t>(tree.size())));
|
||||
//SproutMerkleTree tree;
|
||||
//pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), tree);
|
||||
//obj.push_back(Pair("commitments", static_cast<uint64_t>(tree.size())));
|
||||
obj.push_back(Pair("commitments", 0));
|
||||
|
||||
CBlockIndex* tip = chainActive.LastTip();
|
||||
UniValue valuePools(UniValue::VARR);
|
||||
@@ -1875,9 +1876,11 @@ inline CBlockIndex* LookupBlockIndex(const uint256& hash)
|
||||
return it == mapBlockIndex.end() ? nullptr : it->second;
|
||||
}
|
||||
|
||||
// Every coin can have different number of coinbase due to Founders Reward addresses/etc
|
||||
#define COINBASE_PER_BLOCK 2
|
||||
// given a transaction count X, subtract out coinbase and dpow transactions
|
||||
// to give an "organic count". We return 0 instead of negative values
|
||||
#define ORG(X) ( (X - blockcount - nNotarizationsDiff) > 0 ? (X - blockcount - nNotarizationsDiff) : 0 )
|
||||
#define ORG(X) ( (X - COINBASE_PER_BLOCK*blockcount - nNotarizationsDiff) > 0 ? (X - COINBASE_PER_BLOCK*blockcount - nNotarizationsDiff) : 0 )
|
||||
|
||||
//TODO: Allow custom error message in this macro
|
||||
#define THROW_IF_SYNCING(INSYNC) if (INSYNC == 0) { throw runtime_error(strprintf("%s: Chain still syncing at height %d, aborting to prevent garbage data. Please wait until the chain is synced to run this RPC",__FUNCTION__,chainActive.Tip()->GetHeight())); }
|
||||
@@ -1901,6 +1904,7 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk
|
||||
" \"nullifiers\": xxxxx, (numeric) The total number of shielded nullifiers in the chain up to that point.\n"
|
||||
" \"shielded_txcount\": xxxxx, (numeric) The total number of shielded (containing a zaddr) transactions in the chain up to that point.\n"
|
||||
" \"shielded_outputs\": xxxxx, (numeric) The total number of shielded outputs in the chain up to that point.\n"
|
||||
" \"shielded_spends\": xxxxx, (numeric) The total number of shielded spends in the chain up to that point.\n"
|
||||
" \"shielded_pool_size\": xxxxx, (numeric) The total number of unspent shielded outputs, i.e. the Shielded Pool or Anonymity Set (anonset).\n"
|
||||
" \"shielding_txcount\": xxxxx, (numeric) The total number of shielding (containing a zaddr output) transactions in the chain up to that point.\n"
|
||||
" \"deshielding_txcount\": xxxxx, (numeric) The total number of deshielding (containing a zaddr input) transactions in the chain up to that point.\n"
|
||||
@@ -2000,9 +2004,11 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk
|
||||
ret.pushKV("shielding_payments", (int64_t)pindex->nChainShieldingPayments);
|
||||
|
||||
int64_t nullifierCount = pwalletMain->NullifierCount();
|
||||
//TODO: this is unreliable, is only a cache or subset of total nullifiers
|
||||
ret.pushKV("nullifiers", (int64_t)nullifierCount);
|
||||
ret.pushKV("shielded_pool_size", (int64_t)pindex->nChainShieldedOutputs - nullifierCount);
|
||||
ret.pushKV("shielded_pool_size", (int64_t)(pindex->nChainShieldedOutputs - pindex->nChainShieldedSpends));
|
||||
ret.pushKV("shielded_outputs", (int64_t)pindex->nChainShieldedOutputs);
|
||||
ret.pushKV("shielded_spends", (int64_t)pindex->nChainShieldedSpends);
|
||||
}
|
||||
|
||||
if (blockcount > 0) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -130,12 +131,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "getaddressdeltas", 0},
|
||||
{ "getaddressutxos", 0},
|
||||
{ "getaddressmempool", 0},
|
||||
{ "zcrawjoinsplit", 1 },
|
||||
{ "zcrawjoinsplit", 2 },
|
||||
{ "zcrawjoinsplit", 3 },
|
||||
{ "zcrawjoinsplit", 4 },
|
||||
{ "zcbenchmark", 1 },
|
||||
{ "zcbenchmark", 2 },
|
||||
{ "getblocksubsidy", 0},
|
||||
{ "z_listaddresses", 0},
|
||||
{ "z_listreceivedbyaddress", 1},
|
||||
@@ -144,6 +139,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "z_listunspent", 2 },
|
||||
{ "z_listunspent", 3 },
|
||||
{ "z_getbalance", 1},
|
||||
{ "z_getnotescount", 0},
|
||||
{ "z_gettotalbalance", 0},
|
||||
{ "z_gettotalbalance", 1},
|
||||
{ "z_gettotalbalance", 2},
|
||||
@@ -168,8 +164,17 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "kvupdate", 4 },
|
||||
{ "z_importkey", 2 },
|
||||
{ "z_importviewingkey", 2 },
|
||||
{ "z_getpaymentdisclosure", 1},
|
||||
{ "z_getpaymentdisclosure", 2},
|
||||
{ "z_listsentbyaddress", 1},
|
||||
{ "z_listsentbyaddress", 2},
|
||||
{ "z_listsentbyaddress", 3},
|
||||
{ "z_listsentbyaddress", 4},
|
||||
{ "z_listsentbyaddress", 5},
|
||||
{ "z_listreceivedbyaddress", 1},
|
||||
{ "z_listreceivedbyaddress", 2},
|
||||
{ "z_listreceivedbyaddress", 3},
|
||||
{ "z_listreceivedbyaddress", 4},
|
||||
{ "z_listreceivedbyaddress", 5},
|
||||
|
||||
// crosschain
|
||||
{ "assetchainproof", 1},
|
||||
{ "crosschainproof", 1},
|
||||
@@ -178,6 +183,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "height_MoM", 1},
|
||||
{ "calc_MoM", 2},
|
||||
{ "migrate_completeimporttransaction", 1},
|
||||
{ "getalldata", 0},
|
||||
{ "getalldata", 1},
|
||||
{ "getalldata", 2},
|
||||
{ "getalldata", 3}
|
||||
};
|
||||
|
||||
class CRPCConvertTable
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -203,9 +204,9 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
" \"version\": xxxxx, (numeric) the server version\n"
|
||||
" \"protocolversion\": xxxxx, (numeric) the protocol version\n"
|
||||
" \"walletversion\": xxxxx, (numeric) the wallet version\n"
|
||||
" \"balance\": xxxxxxx, (numeric) the total Komodo balance of the wallet\n"
|
||||
" \"balance\": xxxxxxx, (numeric) the total Hush balance of the wallet\n"
|
||||
" \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
|
||||
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
|
||||
" \"timeoffset\": xxxxx, (numeric) the time offset (deprecated, always 0)\n"
|
||||
" \"connections\": xxxxx, (numeric) the number of connections\n"
|
||||
" \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
|
||||
" \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
|
||||
@@ -285,7 +286,7 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
#endif
|
||||
obj.push_back(Pair("sapling", ASSETCHAINS_SAPLING));
|
||||
}
|
||||
obj.push_back(Pair("timeoffset", GetTimeOffset()));
|
||||
obj.push_back(Pair("timeoffset", 0));
|
||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||
obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
|
||||
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
|
||||
@@ -420,12 +421,12 @@ UniValue coinsupply(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"result\" : \"success\", (string) If the request was successful.\n"
|
||||
" \"coin\" : \"KMD\", (string) The currency symbol of the coin for asset chains, otherwise KMD.\n"
|
||||
" \"coin\" : \"HUSH3\", (string) The currency symbol of the coin for asset chains, otherwise HUSH3.\n"
|
||||
" \"height\" : 420, (integer) The height of this coin supply data\n"
|
||||
" \"supply\" : \"777.0\", (float) The transparent coin supply\n"
|
||||
" \"zfunds\" : \"0.777\", (float) The shielded coin supply (in zaddrs)\n"
|
||||
" \"sprout\" : \"0.077\", (float) The sprout coin supply (in zcaddrs)\n"
|
||||
" \"total\" : \"777.777\", (float) The total coin supply, i.e. sum of supply + zfunds\n"
|
||||
" \"supply\" : \"555.0\", (float) The transparent coin supply\n"
|
||||
" \"zfunds\" : \"0.55555\", (float) The shielded coin supply (in zaddrs)\n"
|
||||
" \"sprout\" : \"0.000\", (float) The sprout coin supply (in zcaddrs)\n"
|
||||
" \"total\" : \"555.55555\", (float) The total coin supply, i.e. sum of supply + zfunds\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("coinsupply", "420")
|
||||
@@ -536,14 +537,14 @@ UniValue validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
"validateaddress \"komodoaddress\"\n"
|
||||
"\nReturn information about the given Komodo address.\n"
|
||||
"validateaddress \"hushaddress\"\n"
|
||||
"\nReturn information about the given Hush address.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"komodoaddress\" (string, required) The Komodo address to validate\n"
|
||||
"1. \"hushaddress\" (string, required) The Hush address to validate\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
|
||||
" \"address\" : \"komodoaddress\", (string) The Komodo address validated\n"
|
||||
" \"address\" : \"hushaddress\", (string) The Hush address validated\n"
|
||||
" \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
|
||||
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
|
||||
" \"isscript\" : true|false, (boolean) If the key is a script\n"
|
||||
@@ -589,43 +590,6 @@ UniValue validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk
|
||||
}
|
||||
|
||||
|
||||
class DescribePaymentAddressVisitor : public boost::static_visitor<UniValue>
|
||||
{
|
||||
public:
|
||||
UniValue operator()(const libzcash::InvalidEncoding &zaddr) const { return UniValue(UniValue::VOBJ); }
|
||||
|
||||
UniValue operator()(const libzcash::SproutPaymentAddress &zaddr) const {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("type", "sprout"));
|
||||
obj.push_back(Pair("payingkey", zaddr.a_pk.GetHex()));
|
||||
obj.push_back(Pair("transmissionkey", zaddr.pk_enc.GetHex()));
|
||||
#ifdef ENABLE_WALLET
|
||||
if (pwalletMain) {
|
||||
obj.push_back(Pair("ismine", pwalletMain->HaveSproutSpendingKey(zaddr)));
|
||||
}
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const libzcash::SaplingPaymentAddress &zaddr) const {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("type", "sapling"));
|
||||
obj.push_back(Pair("diversifier", HexStr(zaddr.d)));
|
||||
obj.push_back(Pair("diversifiedtransmissionkey", zaddr.pk_d.GetHex()));
|
||||
#ifdef ENABLE_WALLET
|
||||
if (pwalletMain) {
|
||||
libzcash::SaplingIncomingViewingKey ivk;
|
||||
libzcash::SaplingFullViewingKey fvk;
|
||||
bool isMine = pwalletMain->GetSaplingIncomingViewingKey(zaddr, ivk) &&
|
||||
pwalletMain->GetSaplingFullViewingKey(ivk, fvk) &&
|
||||
pwalletMain->HaveSaplingSpendingKey(fvk);
|
||||
obj.push_back(Pair("ismine", isMine));
|
||||
}
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
@@ -638,17 +602,15 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& my
|
||||
"{\n"
|
||||
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
|
||||
" \"address\" : \"zaddr\", (string) The z address validated\n"
|
||||
" \"type\" : \"xxxx\", (string) \"sprout\" or \"sapling\"\n"
|
||||
" \"type\" : \"xxxx\", (string) \"sapling\"\n"
|
||||
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
|
||||
" \"payingkey\" : \"hex\", (string) [sprout] The hex value of the paying key, a_pk\n"
|
||||
" \"transmissionkey\" : \"hex\", (string) [sprout] The hex value of the transmission key, pk_enc\n"
|
||||
" \"diversifier\" : \"hex\", (string) [sapling] The hex value of the diversifier, d\n"
|
||||
" \"diversifiedtransmissionkey\" : \"hex\", (string) [sapling] The hex value of pk_d\n"
|
||||
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("z_validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"")
|
||||
+ HelpExampleRpc("z_validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"")
|
||||
+ HelpExampleCli("z_validateaddress", "\"zs1z7rejlpsa98s2rrrfkwmaxu53e4ue0ulcrw0h4x5g8jl04tak0d3mm47vdtahatqrlkngh9slya\"")
|
||||
+ HelpExampleRpc("z_validateaddress", "\"zs1z7rejlpsa98s2rrrfkwmaxu53e4ue0ulcrw0h4x5g8jl04tak0d3mm47vdtahatqrlkngh9slya\"")
|
||||
);
|
||||
|
||||
|
||||
@@ -664,11 +626,25 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& my
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.push_back(Pair("isvalid", isValid));
|
||||
if (isValid)
|
||||
auto zaddr = boost::get<libzcash::SaplingPaymentAddress>(&address);
|
||||
if (isValid && (zaddr != nullptr))
|
||||
{
|
||||
ret.push_back(Pair("address", strAddress));
|
||||
UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(), address);
|
||||
ret.pushKVs(detail);
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("type", "sapling"));
|
||||
obj.push_back(Pair("diversifier", HexStr(zaddr->d)));
|
||||
obj.push_back(Pair("diversifiedtransmissionkey", zaddr->pk_d.GetHex()));
|
||||
#ifdef ENABLE_WALLET
|
||||
if (pwalletMain) {
|
||||
libzcash::SaplingIncomingViewingKey ivk;
|
||||
libzcash::SaplingFullViewingKey fvk;
|
||||
bool isMine = pwalletMain->GetSaplingIncomingViewingKey(*zaddr, ivk) &&
|
||||
pwalletMain->GetSaplingFullViewingKey(ivk, fvk) &&
|
||||
pwalletMain->HaveSaplingSpendingKey(fvk);
|
||||
obj.push_back(Pair("ismine", isMine));
|
||||
}
|
||||
#endif
|
||||
ret.pushKVs(obj);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -747,9 +723,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
|
||||
"\nArguments:\n"
|
||||
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
|
||||
"2. \"keys\" (string, required) A json array of keys which are Komodo addresses or hex-encoded public keys\n"
|
||||
"2. \"keys\" (string, required) A json array of keys which are Hush addresses or hex-encoded public keys\n"
|
||||
" [\n"
|
||||
" \"key\" (string) Komodo address or hex-encoded public key\n"
|
||||
" \"key\" (string) Hush address or hex-encoded public key\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
|
||||
@@ -783,10 +759,10 @@ UniValue verifymessage(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
{
|
||||
if (fHelp || params.size() != 3)
|
||||
throw runtime_error(
|
||||
"verifymessage \"komodoaddress\" \"signature\" \"message\"\n"
|
||||
"verifymessage \"hushaddress\" \"signature\" \"message\"\n"
|
||||
"\nVerify a signed message\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"komodoaddress\" (string, required) The Komodo address to use for the signature.\n"
|
||||
"1. \"hushaddress\" (string, required) The Hush address to use for the signature.\n"
|
||||
"2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
|
||||
"3. \"message\" (string, required) The message that was signed.\n"
|
||||
"\nResult:\n"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
@@ -108,7 +109,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
" \"bytessent\": n, (numeric) The total bytes sent\n"
|
||||
" \"bytesrecv\": n, (numeric) The total bytes received\n"
|
||||
" \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
|
||||
" \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
|
||||
" \"timeoffset\": ttt, (numeric) The time offset in seconds (deprecated, always 0)\n"
|
||||
" \"pingtime\": n, (numeric) ping time\n"
|
||||
" \"pingwait\": n, (numeric) ping wait\n"
|
||||
" \"version\": v, (numeric) The peer version, such as 170002\n"
|
||||
@@ -151,7 +152,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
obj.push_back(Pair("bytessent", stats.nSendBytes));
|
||||
obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
|
||||
obj.push_back(Pair("conntime", stats.nTimeConnected));
|
||||
obj.push_back(Pair("timeoffset", stats.nTimeOffset));
|
||||
obj.push_back(Pair("timeoffset", 0));
|
||||
obj.push_back(Pair("pingtime", stats.dPingTime));
|
||||
if (stats.dPingWait > 0.0)
|
||||
obj.push_back(Pair("pingwait", stats.dPingWait));
|
||||
@@ -502,7 +503,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
" \"subversion\": \"/MagicBean:x.y.z[-v]/\", (string) the server subversion string\n"
|
||||
" \"protocolversion\": xxxxx, (numeric) the protocol version\n"
|
||||
" \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
|
||||
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
|
||||
" \"timeoffset\": xxxxx, (numeric) the time offset (deprecated, always 0)\n"
|
||||
" \"connections\": xxxxx, (numeric) the number of connections\n"
|
||||
" \"networks\": [ (array) information per network\n"
|
||||
" {\n"
|
||||
@@ -536,7 +537,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
obj.push_back(Pair("subversion", strSubVersion));
|
||||
obj.push_back(Pair("protocolversion",PROTOCOL_VERSION));
|
||||
obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
|
||||
obj.push_back(Pair("timeoffset", GetTimeOffset()));
|
||||
obj.push_back(Pair("timeoffset", 0));
|
||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||
obj.push_back(Pair("networks", GetNetworksInfo()));
|
||||
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019 The Hush developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -651,11 +651,6 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "wallet", "walletlock", &walletlock, true },
|
||||
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true },
|
||||
{ "wallet", "walletpassphrase", &walletpassphrase, true },
|
||||
{ "wallet", "zcbenchmark", &zc_benchmark, true },
|
||||
{ "wallet", "zcrawkeygen", &zc_raw_keygen, true },
|
||||
{ "wallet", "zcrawjoinsplit", &zc_raw_joinsplit, true },
|
||||
{ "wallet", "zcrawreceive", &zc_raw_receive, true },
|
||||
{ "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true },
|
||||
{ "wallet", "z_listreceivedbyaddress",&z_listreceivedbyaddress,false },
|
||||
{ "wallet", "z_getbalance", &z_getbalance, false },
|
||||
{ "wallet", "z_gettotalbalance", &z_gettotalbalance, false },
|
||||
@@ -674,11 +669,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "wallet", "z_importviewingkey", &z_importviewingkey, true },
|
||||
{ "wallet", "z_exportwallet", &z_exportwallet, true },
|
||||
{ "wallet", "z_importwallet", &z_importwallet, true },
|
||||
{ "wallet", "opreturn_burn", &opreturn_burn, true },
|
||||
|
||||
// TODO: rearrange into another category
|
||||
{ "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true },
|
||||
{ "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true }
|
||||
{ "wallet", "opreturn_burn", &opreturn_burn, true }
|
||||
#endif // ENABLE_WALLET
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2019 The Hush Developers
|
||||
// Copyright (c) 2019-2020 The Hush Developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -402,11 +402,6 @@ extern UniValue getnetworkinfo(const UniValue& params, bool fHelp, const CPubKey
|
||||
extern UniValue getdeprecationinfo(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
extern UniValue setmocktime(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
extern UniValue resendwallettransactions(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
extern UniValue zc_benchmark(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
extern UniValue zc_raw_keygen(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
extern UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
extern UniValue zc_raw_receive(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
extern UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
|
||||
extern UniValue jumblr_deposit(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
extern UniValue jumblr_secret(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||
@@ -494,6 +489,7 @@ extern UniValue z_getoperationstatus(const UniValue& params, bool fHelp, const C
|
||||
extern UniValue z_getoperationresult(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp
|
||||
extern UniValue z_listoperationids(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp
|
||||
extern UniValue opreturn_burn(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp
|
||||
extern UniValue rescan(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp
|
||||
extern UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcmisc.cpp
|
||||
extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdisclosure.cpp
|
||||
extern UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdisclosure.cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-2014 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
51
src/snark/.gitignore
vendored
51
src/snark/.gitignore
vendored
@@ -1,51 +0,0 @@
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.d
|
||||
libsnark/gtests
|
||||
depinst/
|
||||
depsrc/
|
||||
README.html
|
||||
doxygen/
|
||||
libsnark/gtests
|
||||
libsnark/gadgetlib2/examples/tutorial
|
||||
libsnark/gadgetlib2/tests/gadgetlib2_test
|
||||
|
||||
libsnark/algebra/curves/tests/test_bilinearity
|
||||
libsnark/algebra/curves/tests/test_groups
|
||||
libsnark/algebra/fields/tests/test_fields
|
||||
libsnark/common/routing_algorithms/profiling/profile_routing_algorithms
|
||||
libsnark/common/routing_algorithms/tests/test_routing_algorithms
|
||||
libsnark/gadgetlib1/gadgets/cpu_checkers/fooram/examples/test_fooram
|
||||
libsnark/gadgetlib1/gadgets/hashes/knapsack/tests/test_knapsack_gadget
|
||||
libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget
|
||||
libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets
|
||||
libsnark/gadgetlib1/gadgets/routing/profiling/profile_routing_gadgets
|
||||
libsnark/gadgetlib1/gadgets/set_commitment/tests/test_set_commitment_gadget
|
||||
libsnark/gadgetlib1/gadgets/verifiers/tests/test_r1cs_ppzksnark_verifier_gadget
|
||||
libsnark/reductions/ram_to_r1cs/examples/demo_arithmetization
|
||||
libsnark/relations/arithmetic_programs/qap/tests/test_qap
|
||||
libsnark/relations/arithmetic_programs/ssp/tests/test_ssp
|
||||
libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/profiling/profile_r1cs_mp_ppzkpcd
|
||||
libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/tests/test_r1cs_mp_ppzkpcd
|
||||
libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/profiling/profile_r1cs_sp_ppzkpcd
|
||||
libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/tests/test_r1cs_sp_ppzkpcd
|
||||
libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark
|
||||
libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/profiling/profile_bacs_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/tests/test_bacs_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/profiling/profile_r1cs_gg_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_generator
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_prover
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_verifier
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/profiling/profile_ram_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/tests/test_ram_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/profiling/profile_tbcs_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/tests/test_tbcs_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/profiling/profile_uscs_ppzksnark
|
||||
libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/tests/test_uscs_ppzksnark
|
||||
libsnark/zk_proof_systems/zksnark/ram_zksnark/profiling/profile_ram_zksnark
|
||||
libsnark/zk_proof_systems/zksnark/ram_zksnark/tests/test_ram_zksnark
|
||||
@@ -1,22 +0,0 @@
|
||||
SCIPR Lab:
|
||||
Eli Ben-Sasson
|
||||
Alessandro Chiesa
|
||||
Daniel Genkin
|
||||
Shaul Kfir
|
||||
Eran Tromer
|
||||
Madars Virza
|
||||
|
||||
External contributors:
|
||||
Michael Backes
|
||||
Manuel Barbosa
|
||||
Dario Fiore
|
||||
Jens Groth
|
||||
Joshua A. Kroll
|
||||
Shigeo MITSUNARI
|
||||
Raphael Reischuk
|
||||
Tadanori TERUYA
|
||||
Sean Bowe
|
||||
Daira Hopwood
|
||||
@mugatu on forum.z.cash
|
||||
David Mercer
|
||||
Joshua Yabut
|
||||
@@ -1,24 +0,0 @@
|
||||
The libsnark library is developed by SCIPR Lab (http://scipr-lab.org)
|
||||
and contributors.
|
||||
|
||||
Copyright (c) 2012-2014 SCIPR Lab and contributors (see AUTHORS file).
|
||||
|
||||
All files, with the exceptions below, are released under the MIT License:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,289 +0,0 @@
|
||||
#********************************************************************************
|
||||
# Makefile for the libsnark library.
|
||||
#********************************************************************************
|
||||
#* @author This file is part of libsnark, developed by SCIPR Lab
|
||||
#* and contributors (see AUTHORS).
|
||||
#* @copyright MIT license (see LICENSE file)
|
||||
#*******************************************************************************/
|
||||
|
||||
# Determine building operating system
|
||||
ifeq ($(OS),Windows_NT)
|
||||
uname_S := Windows
|
||||
else
|
||||
uname_S := $(shell uname -s)
|
||||
endif
|
||||
|
||||
# To override these, use "make OPTFLAGS=..." etc.
|
||||
CURVE = BN128
|
||||
OPTFLAGS = -O2 -march=x86-64 -g -mtune=x86-64
|
||||
|
||||
ifneq ($(PLATFORM),darwin)
|
||||
FEATUREFLAGS = -DUSE_ASM -DMONTGOMERY_OUTPUT
|
||||
else
|
||||
FEATUREFLAGS = -DUSE_ASM -DMONTGOMERY_OUTPUT -D__SIZE_TYPE__="unsigned long long"
|
||||
endif
|
||||
|
||||
# Initialize this using "CXXFLAGS=... make". The makefile appends to that.
|
||||
CXXFLAGS += -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wno-comment -Wfatal-errors $(OPTFLAGS) $(FEATUREFLAGS) -DCURVE_$(CURVE)
|
||||
|
||||
DEPSRC = depsrc
|
||||
DEPINST = depinst
|
||||
|
||||
CXXFLAGS += -I$(DEPINST)/include -Ilibsnark
|
||||
LDFLAGS += -L$(DEPINST)/lib -Wl,-rpath,$(DEPINST)/lib
|
||||
LDLIBS += -lgmpxx -lgmp -lboost_program_options -lsodium
|
||||
# List of .a files to include within libsnark.a and libsnark.so:
|
||||
AR_LIBS =
|
||||
# List of library files to install:
|
||||
INSTALL_LIBS = $(LIB_FILE)
|
||||
# Sentinel file to check existence of this directory (since directories don't work as a Make dependency):
|
||||
DEPINST_EXISTS = $(DEPINST)/.exists
|
||||
|
||||
ifneq ($(NO_GTEST),1)
|
||||
# Compile GTest from sourcecode if we can (e.g., Ubuntu). Otherwise use precompiled one (e.g., Fedora).
|
||||
# See https://github.com/google/googletest/blob/master/googletest/docs/FAQ.md#why-is-it-not-recommended-to-install-a-pre-compiled-copy-of-google-test-for-example-into-usrlocal
|
||||
ifneq ($(NO_COMPILE_LIBGTEST),1)
|
||||
GTESTDIR=/usr/src/gtest
|
||||
COMPILE_LIBGTEST = $(shell test -d $(GTESTDIR) && echo -n 1)
|
||||
endif
|
||||
GTEST_LDLIBS += -lgtest -lpthread
|
||||
endif
|
||||
|
||||
ifneq ($(NO_SUPERCOP),1)
|
||||
SUPERCOP_LDLIBS += -lsupercop
|
||||
INSTALL_LIBS += depinst/lib/libsupercop.a
|
||||
# Would have been nicer to roll supercop into libsnark.a ("AR_LIBS += $(DEPINST)/lib/libsupercop.a"), but it doesn't support position-independent code (libsnark issue #20).
|
||||
endif
|
||||
|
||||
LIB_SRCS = \
|
||||
libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp \
|
||||
libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp \
|
||||
libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp \
|
||||
libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp \
|
||||
libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp \
|
||||
libsnark/common/profiling.cpp \
|
||||
libsnark/common/utils.cpp \
|
||||
libsnark/gadgetlib1/constraint_profiling.cpp \
|
||||
|
||||
ifeq ($(CURVE),BN128)
|
||||
LIB_SRCS += \
|
||||
libsnark/algebra/curves/bn128/bn128_g1.cpp \
|
||||
libsnark/algebra/curves/bn128/bn128_g2.cpp \
|
||||
libsnark/algebra/curves/bn128/bn128_gt.cpp \
|
||||
libsnark/algebra/curves/bn128/bn128_init.cpp \
|
||||
libsnark/algebra/curves/bn128/bn128_pairing.cpp \
|
||||
libsnark/algebra/curves/bn128/bn128_pp.cpp
|
||||
|
||||
CXXFLAGS += -DBN_SUPPORT_SNARK
|
||||
AR_LIBS += $(DEPINST)/lib/libzm.a
|
||||
endif
|
||||
|
||||
# FIXME: most of these are broken due to removed code.
|
||||
DISABLED_EXECUTABLES = \
|
||||
libsnark/common/routing_algorithms/profiling/profile_routing_algorithms \
|
||||
libsnark/common/routing_algorithms/tests/test_routing_algorithms \
|
||||
libsnark/gadgetlib1/gadgets/cpu_checkers/fooram/examples/test_fooram \
|
||||
libsnark/gadgetlib1/gadgets/hashes/knapsack/tests/test_knapsack_gadget \
|
||||
libsnark/gadgetlib1/gadgets/routing/profiling/profile_routing_gadgets \
|
||||
libsnark/gadgetlib1/gadgets/set_commitment/tests/test_set_commitment_gadget \
|
||||
libsnark/gadgetlib1/gadgets/verifiers/tests/test_r1cs_ppzksnark_verifier_gadget \
|
||||
libsnark/reductions/ram_to_r1cs/examples/demo_arithmetization \
|
||||
libsnark/relations/arithmetic_programs/ssp/tests/test_ssp \
|
||||
libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/profiling/profile_r1cs_mp_ppzkpcd \
|
||||
libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/tests/test_r1cs_mp_ppzkpcd \
|
||||
libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/profiling/profile_r1cs_sp_ppzkpcd \
|
||||
libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/tests/test_r1cs_sp_ppzkpcd \
|
||||
libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/profiling/profile_bacs_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/tests/test_bacs_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/profiling/profile_r1cs_gg_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_generator \
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_prover \
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_verifier \
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/profiling/profile_ram_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/tests/test_ram_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/profiling/profile_tbcs_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/tests/test_tbcs_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/profiling/profile_uscs_ppzksnark \
|
||||
libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/tests/test_uscs_ppzksnark \
|
||||
libsnark/zk_proof_systems/zksnark/ram_zksnark/profiling/profile_ram_zksnark \
|
||||
libsnark/zk_proof_systems/zksnark/ram_zksnark/tests/test_ram_zksnark
|
||||
|
||||
EXECUTABLES =
|
||||
|
||||
EXECUTABLES_WITH_GTEST =
|
||||
|
||||
EXECUTABLES_WITH_SUPERCOP = \
|
||||
libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark
|
||||
|
||||
GTEST_TESTS =
|
||||
|
||||
GTEST_SRCS =
|
||||
|
||||
DOCS = README.html
|
||||
|
||||
LIBSNARK_A = libsnark.a
|
||||
|
||||
# For documentation of the following options, see README.md .
|
||||
|
||||
ifeq ($(NO_PROCPS),1)
|
||||
CXXFLAGS += -DNO_PROCPS
|
||||
else
|
||||
LDLIBS += -lprocps
|
||||
endif
|
||||
|
||||
ifeq ($(LOWMEM),1)
|
||||
CXXFLAGS += -DLOWMEM
|
||||
endif
|
||||
|
||||
ifeq ($(PROFILE_OP_COUNTS),1)
|
||||
STATIC = 1
|
||||
CXXFLAGS += -DPROFILE_OP_COUNTS
|
||||
endif
|
||||
|
||||
ifeq ($(STATIC),1)
|
||||
ifneq ($(PLATFORM),darwin)
|
||||
CXXFLAGS += -static
|
||||
endif
|
||||
CXXFLAGS += -DSTATIC
|
||||
else
|
||||
CXXFLAGS += -fPIC
|
||||
endif
|
||||
|
||||
ifeq ($(MULTICORE),1)
|
||||
CXXFLAGS += -DMULTICORE -fopenmp
|
||||
endif
|
||||
|
||||
ifeq ($(CPPDEBUG),1)
|
||||
CXXFLAGS += -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
|
||||
DEBUG = 1
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
CXXFLAGS += -DDEBUG -ggdb3
|
||||
endif
|
||||
|
||||
ifeq ($(PERFORMANCE),1)
|
||||
OPTFLAGS = -O3 -march=x86-64 -g -mtune=x86-64
|
||||
CXXFLAGS += -DNDEBUG
|
||||
# Enable link-time optimization:
|
||||
CXXFLAGS += -flto -fuse-linker-plugin
|
||||
LDFLAGS += -flto
|
||||
endif
|
||||
|
||||
LIB_OBJS =$(patsubst %.cpp,%.o,$(LIB_SRCS))
|
||||
EXEC_OBJS =$(patsubst %,%.o,$(EXECUTABLES) $(EXECUTABLES_WITH_GTEST) $(EXECUTABLES_WITH_SUPERCOP))
|
||||
GTEST_OBJS =$(patsubst %.cpp,%.o,$(GTEST_SRCS))
|
||||
|
||||
all: \
|
||||
$(if $(NO_GTEST),,$(EXECUTABLES_WITH_GTEST) $(GTEST_TESTS)) \
|
||||
$(if $(NO_SUPERCOP),,$(EXECUTABLES_WITH_SUPERCOP)) \
|
||||
$(EXECUTABLES) \
|
||||
$(LIBSNARK_A) \
|
||||
$(if $(NO_DOCS),,doc)
|
||||
|
||||
doc: $(DOCS)
|
||||
|
||||
$(DEPINST_EXISTS):
|
||||
# Create placeholder directories for installed dependencies. Some make settings (including the default) require actually running ./prepare-depends.sh to populate this directory.
|
||||
mkdir -p $(DEPINST)/lib $(DEPINST)/include
|
||||
touch $@
|
||||
|
||||
# In order to detect changes to #include dependencies. -MMD below generates a .d file for each .o file. Include the .d file.
|
||||
-include $(patsubst %.o,%.d, $(LIB_OBJS) $(GTEST_OBJS) $(EXEC_OBJS) )
|
||||
|
||||
$(LIB_OBJS) $(if $(NO_GTEST),,$(GTEST_OBJS)) $(EXEC_OBJS): %.o: %.cpp
|
||||
$(CXX) -o $@ $< -c -MMD $(CXXFLAGS)
|
||||
|
||||
LIBGTEST_A = $(DEPINST)/lib/libgtest.a
|
||||
|
||||
$(LIBGTEST_A): $(GTESTDIR)/libsnark/gtest-all.cc $(DEPINST_EXISTS)
|
||||
$(CXX) -o $(DEPINST)/lib/gtest-all.o -I $(GTESTDIR) -c -isystem $(GTESTDIR)/include $< $(CXXFLAGS)
|
||||
$(AR) -rv $(LIBGTEST_A) $(DEPINST)/lib/gtest-all.o
|
||||
|
||||
# libsnark.a will contains all of our relevant object files, and we also mash in the .a files of relevant dependencies built by ./prepare-depends.sh
|
||||
$(LIBSNARK_A): $(LIB_OBJS) $(AR_LIBS)
|
||||
$(AR) q $(LIBSNARK_A) $(LIB_OBJS)
|
||||
if [ -n "$(AR_LIBS)" ]; then mkdir -p tmp-ar; cd tmp-ar; for AR_LIB in $(AR_LIBS); do $(AR) x $$AR_LIB; done; $(AR) qc $(LIBSNARK_A) tmp-ar/*; cd ..; rm -r tmp-ar; fi;
|
||||
$(AR) s $(LIBSNARK_A)
|
||||
|
||||
libsnark.so: $(LIBSNARK_A) $(DEPINST_EXISTS)
|
||||
$(CXX) -o $@ --shared -Wl,--whole-archive $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) -Wl,--no-whole-archive $(LDLIBS)
|
||||
|
||||
libsnark/gadgetlib2/tests/gadgetlib2_test: \
|
||||
libsnark/gadgetlib2/tests/adapters_UTEST.cpp \
|
||||
libsnark/gadgetlib2/tests/constraint_UTEST.cpp \
|
||||
libsnark/gadgetlib2/tests/gadget_UTEST.cpp \
|
||||
libsnark/gadgetlib2/tests/integration_UTEST.cpp \
|
||||
libsnark/gadgetlib2/tests/protoboard_UTEST.cpp \
|
||||
libsnark/gadgetlib2/tests/variable_UTEST.cpp
|
||||
|
||||
$(EXECUTABLES): %: %.o $(LIBSNARK_A) $(DEPINST_EXISTS)
|
||||
$(CXX) -o $@ $@.o $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
$(EXECUTABLES_WITH_GTEST): %: %.o $(LIBSNARK_A) $(if $(COMPILE_LIBGTEST),$(LIBGTEST_A)) $(DEPINST_EXISTS)
|
||||
$(CXX) -o $@ $@.o $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(GTEST_LDLIBS) $(LDLIBS)
|
||||
|
||||
$(EXECUTABLES_WITH_SUPERCOP): %: %.o $(LIBSNARK_A) $(DEPINST_EXISTS)
|
||||
$(CXX) -o $@ $@.o $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(SUPERCOP_LDLIBS) $(LDLIBS)
|
||||
|
||||
$(GTEST_TESTS): %: $(GTEST_OBJS) $(LIBSNARK_A) $(if $(COMPILE_LIBGTEST),$(LIBGTEST_A)) $(DEPINST_EXISTS)
|
||||
$(CXX) -o $@ $(GTEST_OBJS) $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(GTEST_LDLIBS) $(LDLIBS)
|
||||
|
||||
|
||||
ifeq ($(STATIC),1)
|
||||
LIB_FILE = $(LIBSNARK_A)
|
||||
else
|
||||
LIB_FILE = libsnark.so
|
||||
endif
|
||||
|
||||
lib: $(LIB_FILE)
|
||||
|
||||
$(DOCS): %.html: %.md
|
||||
markdown_py -f $@ $^ -x toc -x extra --noisy
|
||||
# TODO: Would be nice to enable "-x smartypants" but Ubuntu 12.04 doesn't support that.
|
||||
# TODO: switch to redcarpet, to produce same output as GitHub's processing of README.md. But what about TOC?
|
||||
|
||||
ifeq ($(PREFIX),)
|
||||
install:
|
||||
$(error Please provide PREFIX. E.g. make install PREFIX=/usr)
|
||||
else
|
||||
HEADERS_SRC=$(shell find libsnark -name '*.hpp' -o -name '*.tcc')
|
||||
HEADERS_DEST=$(patsubst libsnark/%,$(PREFIX)/include/libsnark/%,$(HEADERS_SRC))
|
||||
|
||||
$(HEADERS_DEST): $(PREFIX)/include/libsnark/%: libsnark/%
|
||||
mkdir -p $(shell dirname $@)
|
||||
cp $< $@
|
||||
|
||||
install: $(INSTALL_LIBS) $(HEADERS_DEST) $(DEPINST_EXISTS)
|
||||
mkdir -p $(PREFIX)/lib
|
||||
cp -v $(INSTALL_LIBS) $(PREFIX)/lib/
|
||||
ifneq ($(NO_COPY_DEPINST),1)
|
||||
cp -rv $(DEPINST)/include $(PREFIX)
|
||||
endif
|
||||
endif
|
||||
|
||||
check: $(GTEST_TESTS)
|
||||
$(GTEST_TESTS)
|
||||
|
||||
doxy:
|
||||
doxygen doxygen.conf
|
||||
|
||||
# Clean generated files, except locally-compiled dependencies
|
||||
clean:
|
||||
$(RM) \
|
||||
$(LIB_OBJS) $(GTEST_OBJS) $(EXEC_OBJS) \
|
||||
$(EXECUTABLES) $(EXECUTABLES_WITH_GTEST) $(EXECUTABLES_WITH_SUPERCOP) $(GTEST_TESTS) \
|
||||
$(DOCS) \
|
||||
${patsubst %.o,%.d,${LIB_OBJS} ${GTEST_OBJS} ${EXEC_OBJS}} \
|
||||
libsnark.so $(LIBSNARK_A) \
|
||||
$(RM) -fr doxygen/ \
|
||||
$(RM) $(LIBGTEST_A) $(DEPINST)/lib/gtest-all.o
|
||||
|
||||
# Clean all, including locally-compiled dependencies
|
||||
clean-all: clean
|
||||
$(RM) -fr $(DEPSRC) $(DEPINST)
|
||||
|
||||
.PHONY: all clean clean-all doc doxy lib install
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user