Merge branch 'FSM' of https://github.com/jl777/komodo into jl777-FSM
merge
This commit is contained in:
255
src/Makefile.am
255
src/Makefile.am
@@ -3,6 +3,7 @@ DIST_SUBDIRS = secp256k1 univalue cryptoconditions
|
||||
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(SAN_LDFLAGS) $(HARDENED_LDFLAGS)
|
||||
AM_CXXFLAGS = $(SAN_CXXFLAGS) $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS)
|
||||
AM_CPPFLAGS = $(HARDENED_CPPFLAGS)
|
||||
EXTRA_LIBRARIES =
|
||||
|
||||
if EMBEDDED_LEVELDB
|
||||
LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include
|
||||
@@ -20,10 +21,12 @@ $(LIBLEVELDB) $(LIBMEMENV):
|
||||
endif
|
||||
|
||||
BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
|
||||
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
|
||||
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
|
||||
|
||||
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
|
||||
@@ -34,7 +37,7 @@ endif
|
||||
if TARGET_DARWIN
|
||||
LIBBITCOIN_SERVER=libbitcoin_server.a -lcurl
|
||||
else
|
||||
LIBBITCOIN_SERVER=libbitcoin_server.a
|
||||
LIBBITCOIN_SERVER=libbitcoin_server.a -lcurl
|
||||
endif
|
||||
|
||||
LIBBITCOIN_WALLET=libbitcoin_wallet.a
|
||||
@@ -42,59 +45,74 @@ LIBBITCOIN_COMMON=libbitcoin_common.a
|
||||
LIBBITCOIN_CLI=libbitcoin_cli.a
|
||||
LIBBITCOIN_UTIL=libbitcoin_util.a
|
||||
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
|
||||
LIBVERUS_CRYPTO=crypto/libverus_crypto.a
|
||||
LIBVERUS_PORTABLE_CRYPTO=crypto/libverus_portable_crypto.a
|
||||
LIBSECP256K1=secp256k1/libsecp256k1.la
|
||||
LIBCRYPTOCONDITIONS=cryptoconditions/libcryptoconditions_core.la
|
||||
LIBSNARK=snark/libsnark.a
|
||||
LIBUNIVALUE=univalue/libunivalue.la
|
||||
LIBZCASH=libzcash.a -lcurl
|
||||
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
|
||||
if ENABLE_WALLET
|
||||
LIBBITCOIN_WALLET=libbitcoin_wallet.a
|
||||
endif
|
||||
|
||||
$(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g "
|
||||
|
||||
LIBSNARK_CXXFLAGS = -fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1 -fstack-protector-all
|
||||
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) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64"
|
||||
$(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) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ check DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64"
|
||||
$(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"
|
||||
|
||||
$(LIBUNIVALUE): $(wildcard univalue/lib/*)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue/
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g "
|
||||
|
||||
$(LIBCRYPTOCONDITIONS): $(wildcard cryptoconditions/src/*) $(wildcard cryptoconditions/include/*)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -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:
|
||||
EXTRA_LIBRARIES = \
|
||||
crypto/libbitcoin_crypto.a \
|
||||
libbitcoin_util.a \
|
||||
libbitcoin_common.a \
|
||||
libbitcoin_server.a \
|
||||
libbitcoin_cli.a \
|
||||
libzcash.a
|
||||
EXTRA_LIBRARIES += \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBVERUS_CRYPTO) \
|
||||
$(LIBVERUS_PORTABLE_CRYPTO) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBBITCOIN_SERVER) \
|
||||
$(LIBBITCOIN_CLI) \
|
||||
libzcash.a
|
||||
if ENABLE_WALLET
|
||||
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
|
||||
EXTRA_LIBRARIES += libbitcoin_wallet.a
|
||||
EXTRA_LIBRARIES += $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
if ENABLE_ZMQ
|
||||
EXTRA_LIBRARIES += libbitcoin_zmq.a
|
||||
EXTRA_LIBRARIES += $(LIBBITCOIN_ZMQ)
|
||||
endif
|
||||
if ENABLE_PROTON
|
||||
EXTRA_LIBRARIES += libbitcoin_proton.a
|
||||
EXTRA_LIBRARIES += $(LIBBITCOIN_PROTON)
|
||||
endif
|
||||
|
||||
if BUILD_BITCOIN_LIBS
|
||||
lib_LTLIBRARIES = libzcashconsensus.la
|
||||
LIBZCASH_CONSENSUS=libzcashconsensus.la
|
||||
else
|
||||
LIBZCASH_CONSENSUS=
|
||||
endif
|
||||
lib_LTLIBRARIES = $(LIBZCASH_CONSENSUS)
|
||||
|
||||
bin_PROGRAMS =
|
||||
noinst_PROGRAMS =
|
||||
@@ -121,7 +139,8 @@ LIBZCASH_H = \
|
||||
zcash/prf.h \
|
||||
zcash/Proof.hpp \
|
||||
zcash/util.h \
|
||||
zcash/Zcash.h
|
||||
zcash/Zcash.h \
|
||||
zcash/zip32.h
|
||||
|
||||
.PHONY: FORCE collate-libsnark check-symbols check-security
|
||||
# bitcoin core #
|
||||
@@ -140,6 +159,7 @@ BITCOIN_CORE_H = \
|
||||
asyncrpcoperation.h \
|
||||
asyncrpcqueue.h \
|
||||
base58.h \
|
||||
bech32.h \
|
||||
bloom.h \
|
||||
cc/eval.h \
|
||||
chain.h \
|
||||
@@ -162,14 +182,18 @@ BITCOIN_CORE_H = \
|
||||
consensus/validation.h \
|
||||
core_io.h \
|
||||
core_memusage.h \
|
||||
crypto/haraka.h \
|
||||
crypto/haraka_portable.h \
|
||||
crypto/verus_hash.h \
|
||||
deprecation.h \
|
||||
hash.h \
|
||||
httprpc.h \
|
||||
httpserver.h \
|
||||
init.h \
|
||||
key.h \
|
||||
key_io.h \
|
||||
keystore.h \
|
||||
leveldbwrapper.h \
|
||||
dbwrapper.h \
|
||||
limitedmap.h \
|
||||
main.h \
|
||||
memusage.h \
|
||||
@@ -185,15 +209,18 @@ BITCOIN_CORE_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 \
|
||||
reverselock.h \
|
||||
rpcclient.h \
|
||||
rpcprotocol.h \
|
||||
rpcserver.h \
|
||||
rpc/client.h \
|
||||
rpc/protocol.h \
|
||||
rpc/server.h \
|
||||
rpc/register.h \
|
||||
scheduler.h \
|
||||
script/interpreter.h \
|
||||
script/script.h \
|
||||
@@ -213,6 +240,7 @@ BITCOIN_CORE_H = \
|
||||
timedata.h \
|
||||
tinyformat.h \
|
||||
torcontrol.h \
|
||||
transaction_builder.h \
|
||||
txdb.h \
|
||||
txmempool.h \
|
||||
ui_interface.h \
|
||||
@@ -230,9 +258,11 @@ BITCOIN_CORE_H = \
|
||||
wallet/asyncrpcoperation_shieldcoinbase.h \
|
||||
wallet/crypter.h \
|
||||
wallet/db.h \
|
||||
wallet/rpcwallet.h \
|
||||
wallet/wallet.h \
|
||||
wallet/wallet_ismine.h \
|
||||
wallet/walletdb.h \
|
||||
veruslaunch.h \
|
||||
zmq/zmqabstractnotifier.h \
|
||||
zmq/zmqconfig.h\
|
||||
zmq/zmqnotificationinterface.h \
|
||||
@@ -281,15 +311,19 @@ libbitcoin_server_a_SOURCES = \
|
||||
chain.cpp \
|
||||
checkpoints.cpp \
|
||||
crosschain.cpp \
|
||||
crosschain_authority.cpp \
|
||||
crosschain_authority.cpp \
|
||||
crypto/haraka.h \
|
||||
crypto/haraka_portable.h \
|
||||
crypto/verus_hash.h \
|
||||
crypto/verus_hash.cpp \
|
||||
deprecation.cpp \
|
||||
httprpc.cpp \
|
||||
httpserver.cpp \
|
||||
init.cpp \
|
||||
leveldbwrapper.cpp \
|
||||
dbwrapper.cpp \
|
||||
main.cpp \
|
||||
merkleblock.cpp \
|
||||
metrics.cpp \
|
||||
metrics.h \
|
||||
miner.cpp \
|
||||
net.cpp \
|
||||
notaries_staked.cpp \
|
||||
@@ -300,14 +334,15 @@ libbitcoin_server_a_SOURCES = \
|
||||
policy/fees.cpp \
|
||||
pow.cpp \
|
||||
rest.cpp \
|
||||
rpcblockchain.cpp \
|
||||
rpccrosschain.cpp \
|
||||
rpcmining.cpp \
|
||||
rpcmisc.cpp \
|
||||
rpcnet.cpp \
|
||||
rpcrawtransaction.cpp \
|
||||
rpcserver.cpp \
|
||||
rpc/blockchain.cpp \
|
||||
rpc/crosschain.cpp \
|
||||
rpc/mining.cpp \
|
||||
rpc/misc.cpp \
|
||||
rpc/net.cpp \
|
||||
rpc/rawtransaction.cpp \
|
||||
rpc/server.cpp \
|
||||
script/serverchecker.cpp \
|
||||
script/sigcache.cpp \
|
||||
timedata.cpp \
|
||||
torcontrol.cpp \
|
||||
txdb.cpp \
|
||||
@@ -317,8 +352,6 @@ libbitcoin_server_a_SOURCES = \
|
||||
$(LIBZCASH_H)
|
||||
|
||||
if ENABLE_ZMQ
|
||||
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
|
||||
|
||||
libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
|
||||
libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_zmq_a_SOURCES = \
|
||||
@@ -328,8 +361,6 @@ libbitcoin_zmq_a_SOURCES = \
|
||||
endif
|
||||
|
||||
if ENABLE_PROTON
|
||||
LIBBITCOIN_PROTON=libbitcoin_proton.a
|
||||
|
||||
libbitcoin_proton_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||
libbitcoin_proton_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_proton_a_SOURCES = \
|
||||
@@ -353,6 +384,7 @@ libbitcoin_wallet_a_SOURCES = \
|
||||
wallet/db.cpp \
|
||||
paymentdisclosure.cpp \
|
||||
paymentdisclosuredb.cpp \
|
||||
transaction_builder.cpp \
|
||||
wallet/rpcdisclosure.cpp \
|
||||
wallet/rpcdump.cpp \
|
||||
cc/CCassetstx.cpp \
|
||||
@@ -361,6 +393,7 @@ libbitcoin_wallet_a_SOURCES = \
|
||||
wallet/wallet.cpp \
|
||||
wallet/wallet_ismine.cpp \
|
||||
wallet/walletdb.cpp \
|
||||
zcash/zip32.cpp \
|
||||
$(BITCOIN_CORE_H) \
|
||||
$(LIBZCASH_H)
|
||||
|
||||
@@ -368,22 +401,26 @@ libbitcoin_wallet_a_SOURCES = \
|
||||
crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_CONFIG_INCLUDES)
|
||||
crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
crypto_libbitcoin_crypto_a_SOURCES = \
|
||||
crypto/common.h \
|
||||
crypto/equihash.cpp \
|
||||
crypto/equihash.h \
|
||||
crypto/equihash.tcc \
|
||||
crypto/hmac_sha256.cpp \
|
||||
crypto/hmac_sha256.h \
|
||||
crypto/hmac_sha512.cpp \
|
||||
crypto/hmac_sha512.h \
|
||||
crypto/ripemd160.cpp \
|
||||
crypto/ripemd160.h \
|
||||
crypto/sha1.cpp \
|
||||
crypto/sha1.h \
|
||||
crypto/sha256.cpp \
|
||||
crypto/sha256.h \
|
||||
crypto/sha512.cpp \
|
||||
crypto/sha512.h
|
||||
crypto/common.h \
|
||||
crypto/equihash.cpp \
|
||||
crypto/equihash.h \
|
||||
crypto/equihash.tcc \
|
||||
crypto/hmac_sha256.cpp \
|
||||
crypto/hmac_sha256.h \
|
||||
crypto/hmac_sha512.cpp \
|
||||
crypto/hmac_sha512.h \
|
||||
crypto/ripemd160.cpp \
|
||||
crypto/ripemd160.h \
|
||||
crypto/sha1.cpp \
|
||||
crypto/sha1.h \
|
||||
crypto/sha256.cpp \
|
||||
crypto/sha256.h \
|
||||
crypto/sha512.cpp \
|
||||
crypto/sha512.h \
|
||||
crypto/haraka.h \
|
||||
crypto/haraka_portable.h \
|
||||
crypto/verus_hash.h \
|
||||
crypto/verus_hash.cpp
|
||||
|
||||
if ENABLE_MINING
|
||||
EQUIHASH_TROMP_SOURCES = \
|
||||
@@ -397,35 +434,60 @@ crypto_libbitcoin_crypto_a_SOURCES += \
|
||||
${EQUIHASH_TROMP_SOURCES}
|
||||
endif
|
||||
|
||||
# Verus hash specific library - optimized
|
||||
crypto_libverus_crypto_a_CPPFLAGS = -O3 -Wint-conversion -march=x86-64 -msse4 -msse4.1 -msse4.2 -mssse3 -mavx -maes -g -funroll-loops -fomit-frame-pointer -fPIC $(AM_CPPFLAGS)
|
||||
crypto_libverus_crypto_a_CXXFLAGS = -O3 -Wint-conversion -march=x86-64 -msse4 -msse4.1 -msse4.2 -mssse3 -mavx -maes -g -funroll-loops -fomit-frame-pointer -fPIC $(AM_CXXFLAGS)
|
||||
crypto_libverus_crypto_a_SOURCES = \
|
||||
crypto/haraka.h \
|
||||
crypto/haraka.c
|
||||
|
||||
# Verus hash specific library - portable
|
||||
crypto_libverus_portable_crypto_a_CPPFLAGS = -O3 -Wint-conversion -march=x86-64 -g -funroll-loops -fomit-frame-pointer -fPIC $(AM_CPPFLAGS)
|
||||
crypto_libverus_portable_crypto_a_CXXFLAGS = -O3 -Wint-conversion -march=x86-64 -g -funroll-loops -fomit-frame-pointer -fPIC $(AM_CXXFLAGS)
|
||||
crypto_libverus_portable_crypto_a_SOURCES = \
|
||||
crypto/haraka_portable.h \
|
||||
crypto/haraka_portable.c
|
||||
|
||||
# common: shared between zcashd and non-server tools
|
||||
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_common_a_CPPFLAGS = -fPIC $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_common_a_CXXFLAGS = -fPIC $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_common_a_SOURCES = \
|
||||
amount.cpp \
|
||||
arith_uint256.cpp \
|
||||
base58.cpp \
|
||||
bech32.cpp \
|
||||
chainparams.cpp \
|
||||
coins.cpp \
|
||||
compressor.cpp \
|
||||
consensus/upgrades.cpp \
|
||||
core_read.cpp \
|
||||
core_write.cpp \
|
||||
crypto/haraka.h \
|
||||
crypto/haraka_portable.h \
|
||||
crypto/verus_hash.h \
|
||||
crypto/verus_hash.cpp \
|
||||
hash.cpp \
|
||||
importcoin.cpp \
|
||||
key.cpp \
|
||||
key_io.cpp \
|
||||
keystore.cpp \
|
||||
netbase.cpp \
|
||||
metrics.cpp \
|
||||
primitives/block.cpp \
|
||||
primitives/transaction.cpp \
|
||||
primitives/nonce.cpp \
|
||||
protocol.cpp \
|
||||
pubkey.cpp \
|
||||
scheduler.cpp \
|
||||
script/cc.cpp \
|
||||
script/interpreter.cpp \
|
||||
script/script.cpp \
|
||||
script/script_ext.cpp \
|
||||
script/script_error.cpp \
|
||||
script/sign.cpp \
|
||||
script/standard.cpp \
|
||||
veruslaunch.cpp \
|
||||
transaction_builder.cpp \
|
||||
$(BITCOIN_CORE_H) \
|
||||
$(LIBZCASH_H)
|
||||
|
||||
@@ -435,23 +497,23 @@ libbitcoin_common_a_SOURCES = \
|
||||
libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_util_a_SOURCES = \
|
||||
support/pagelocker.cpp \
|
||||
chainparamsbase.cpp \
|
||||
clientversion.cpp \
|
||||
compat/glibc_sanity.cpp \
|
||||
compat/glibcxx_sanity.cpp \
|
||||
compat/strnlen.cpp \
|
||||
random.cpp \
|
||||
rpcprotocol.cpp \
|
||||
support/cleanse.cpp \
|
||||
sync.cpp \
|
||||
uint256.cpp \
|
||||
util.cpp \
|
||||
utilmoneystr.cpp \
|
||||
utilstrencodings.cpp \
|
||||
utiltime.cpp \
|
||||
$(BITCOIN_CORE_H) \
|
||||
$(LIBZCASH_H)
|
||||
support/pagelocker.cpp \
|
||||
chainparamsbase.cpp \
|
||||
clientversion.cpp \
|
||||
compat/glibc_sanity.cpp \
|
||||
compat/glibcxx_sanity.cpp \
|
||||
compat/strnlen.cpp \
|
||||
random.cpp \
|
||||
rpc/protocol.cpp \
|
||||
support/cleanse.cpp \
|
||||
sync.cpp \
|
||||
uint256.cpp \
|
||||
util.cpp \
|
||||
utilmoneystr.cpp \
|
||||
utilstrencodings.cpp \
|
||||
utiltime.cpp \
|
||||
$(BITCOIN_CORE_H) \
|
||||
$(LIBZCASH_H)
|
||||
|
||||
if GLIBC_BACK_COMPAT
|
||||
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
|
||||
@@ -461,9 +523,9 @@ endif
|
||||
libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_cli_a_SOURCES = \
|
||||
rpcclient.cpp \
|
||||
$(BITCOIN_CORE_H) \
|
||||
$(LIBZCASH_H)
|
||||
rpc/client.cpp \
|
||||
$(BITCOIN_CORE_H) \
|
||||
$(LIBZCASH_H)
|
||||
|
||||
nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
|
||||
#
|
||||
@@ -483,7 +545,11 @@ komodod_LDADD = \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBUNIVALUE) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_ZMQ) \
|
||||
$(LIBBITCOIN_PROTON) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBVERUS_CRYPTO) \
|
||||
$(LIBVERUS_PORTABLE_CRYPTO) \
|
||||
$(LIBZCASH) \
|
||||
$(LIBSNARK) \
|
||||
$(LIBLEVELDB) \
|
||||
@@ -491,12 +557,8 @@ komodod_LDADD = \
|
||||
$(LIBSECP256K1) \
|
||||
$(LIBCRYPTOCONDITIONS)
|
||||
|
||||
if ENABLE_ZMQ
|
||||
komodod_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||
endif
|
||||
|
||||
if ENABLE_WALLET
|
||||
komodod_LDADD += libbitcoin_wallet.a
|
||||
komodod_LDADD += $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
|
||||
komodod_LDADD += \
|
||||
@@ -506,7 +568,11 @@ komodod_LDADD += \
|
||||
$(CRYPTO_LIBS) \
|
||||
$(EVENT_PTHREADS_LIBS) \
|
||||
$(EVENT_LIBS) \
|
||||
$(ZMQ_LIBS) \
|
||||
$(PROTON_LIBS) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBVERUS_CRYPTO) \
|
||||
$(LIBVERUS_PORTABLE_CRYPTO) \
|
||||
$(LIBZCASH_LIBS)
|
||||
|
||||
if ENABLE_PROTON
|
||||
@@ -541,6 +607,8 @@ komodo_cli_LDADD = \
|
||||
$(EVENT_LIBS) \
|
||||
$(LIBZCASH) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBVERUS_CRYPTO) \
|
||||
$(LIBVERUS_PORTABLE_CRYPTO) \
|
||||
$(LIBZCASH_LIBS)
|
||||
|
||||
if ENABLE_WALLET
|
||||
@@ -548,6 +616,8 @@ wallet_utility_LDADD = \
|
||||
libbitcoin_wallet.a \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBVERUS_CRYPTO) \
|
||||
$(LIBVERUS_PORTABLE_CRYPTO) \
|
||||
$(LIBSECP256K1) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(BOOST_LIBS) \
|
||||
@@ -578,6 +648,8 @@ komodo_tx_LDADD = \
|
||||
$(LIBZCASH) \
|
||||
$(LIBSNARK) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBVERUS_CRYPTO) \
|
||||
$(LIBVERUS_PORTABLE_CRYPTO) \
|
||||
$(LIBZCASH_LIBS) \
|
||||
$(LIBCRYPTOCONDITIONS)
|
||||
|
||||
@@ -594,6 +666,7 @@ 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 \
|
||||
@@ -603,6 +676,10 @@ libzcash_a_SOURCES = \
|
||||
|
||||
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_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
#libzcash_a_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
#libzcash_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DMONTGOMERY_OUTPUT
|
||||
|
||||
libzcash_a_CXXFLAGS = $(SAN_CXXFLAGS) $(HARDENED_CXXFLAGS) -fwrapv -fno-strict-aliasing
|
||||
libzcash_a_LDFLAGS = $(SAN_LDFLAGS) $(HARDENED_LDFLAGS)
|
||||
libzcash_a_CPPFLAGS += -DMONTGOMERY_OUTPUT
|
||||
@@ -619,6 +696,7 @@ libzcashconsensus_la_SOURCES = \
|
||||
crypto/sha512.cpp \
|
||||
hash.cpp \
|
||||
primitives/transaction.cpp \
|
||||
primitives/nonce.cpp \
|
||||
pubkey.cpp \
|
||||
script/zcashconsensus.cpp \
|
||||
script/interpreter.cpp \
|
||||
@@ -648,6 +726,7 @@ 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
|
||||
|
||||
@@ -680,5 +759,3 @@ include Makefile.ktest.include
|
||||
#include Makefile.test.include
|
||||
#include Makefile.gtest.include
|
||||
endif
|
||||
|
||||
include Makefile.zcash.include
|
||||
|
||||
@@ -23,6 +23,7 @@ zcash_gtest_SOURCES += \
|
||||
gtest/test_equihash.cpp \
|
||||
gtest/test_httprpc.cpp \
|
||||
gtest/test_joinsplit.cpp \
|
||||
gtest/test_keys.cpp \
|
||||
gtest/test_keystore.cpp \
|
||||
gtest/test_noteencryption.cpp \
|
||||
gtest/test_mempool.cpp \
|
||||
@@ -32,7 +33,9 @@ zcash_gtest_SOURCES += \
|
||||
gtest/test_pow.cpp \
|
||||
gtest/test_random.cpp \
|
||||
gtest/test_rpc.cpp \
|
||||
gtest/test_sapling_note.cpp \
|
||||
gtest/test_transaction.cpp \
|
||||
gtest/test_transaction_builder.cpp \
|
||||
gtest/test_upgrades.cpp \
|
||||
gtest/test_validation.cpp \
|
||||
gtest/test_circuit.cpp \
|
||||
@@ -40,7 +43,9 @@ zcash_gtest_SOURCES += \
|
||||
gtest/test_libzcash_utils.cpp \
|
||||
gtest/test_proofs.cpp \
|
||||
gtest/test_paymentdisclosure.cpp \
|
||||
gtest/test_checkblock.cpp
|
||||
gtest/test_pedersen_hash.cpp \
|
||||
gtest/test_checkblock.cpp \
|
||||
gtest/test_zip32.cpp
|
||||
if ENABLE_WALLET
|
||||
zcash_gtest_SOURCES += \
|
||||
wallet/gtest/test_wallet.cpp
|
||||
@@ -49,7 +54,7 @@ endif
|
||||
komodo_gtest_CPPFLAGS = $(AM_CPPFLAGS) -DMULTICORE -fopenmp -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DSTATIC $(BITCOIN_INCLUDES)
|
||||
komodo_gtest_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
|
||||
komodo_gtest_LDADD = -lgtest -lgmock $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||
komodo_gtest_LDADD = -lgtest -lgmock $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBVERUS_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1)
|
||||
if ENABLE_ZMQ
|
||||
zcash_gtest_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||
|
||||
@@ -361,7 +361,7 @@ qt_komodo_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
|
||||
if ENABLE_WALLET
|
||||
qt_komodo_qt_LDADD += $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
qt_komodo_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||
qt_komodo_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBVERUS_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) $(LIBZCASH_LIBS)
|
||||
qt_komodo_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
qt_komodo_qt_LIBTOOLFLAGS = --tag CXX
|
||||
|
||||
@@ -30,7 +30,7 @@ qt_test_test_komodo_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER)
|
||||
if ENABLE_WALLET
|
||||
qt_test_test_komodo_qt_LDADD += $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
qt_test_test_komodo_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \
|
||||
qt_test_test_komodo_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBVERUS_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \
|
||||
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
|
||||
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) $(LIBZCASH_LIBS)
|
||||
qt_test_test_komodo_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
||||
@@ -20,78 +20,89 @@ EXTRA_DIST += \
|
||||
test/data/wallet.dat
|
||||
|
||||
JSON_TEST_FILES = \
|
||||
test/data/script_valid.json \
|
||||
test/data/base58_keys_valid.json \
|
||||
test/data/base58_encode_decode.json \
|
||||
test/data/base58_keys_invalid.json \
|
||||
test/data/script_invalid.json \
|
||||
test/data/tx_invalid.json \
|
||||
test/data/tx_valid.json \
|
||||
test/data/sighash.json \
|
||||
test/data/merkle_roots.json \
|
||||
test/data/merkle_roots_empty.json \
|
||||
test/data/merkle_serialization.json \
|
||||
test/data/merkle_witness_serialization.json \
|
||||
test/data/merkle_path.json \
|
||||
test/data/merkle_commitments.json \
|
||||
test/data/g1_compressed.json \
|
||||
test/data/g2_compressed.json
|
||||
test/data/script_valid.json \
|
||||
test/data/base58_keys_valid.json \
|
||||
test/data/base58_encode_decode.json \
|
||||
test/data/base58_keys_invalid.json \
|
||||
test/data/script_invalid.json \
|
||||
test/data/tx_invalid.json \
|
||||
test/data/tx_valid.json \
|
||||
test/data/sighash.json \
|
||||
test/data/merkle_roots.json \
|
||||
test/data/merkle_roots_empty.json \
|
||||
test/data/merkle_serialization.json \
|
||||
test/data/merkle_witness_serialization.json \
|
||||
test/data/merkle_path.json \
|
||||
test/data/merkle_commitments.json \
|
||||
test/data/merkle_roots_sapling.json \
|
||||
test/data/merkle_roots_empty_sapling.json \
|
||||
test/data/merkle_serialization_sapling.json \
|
||||
test/data/merkle_witness_serialization_sapling.json \
|
||||
test/data/merkle_path_sapling.json \
|
||||
test/data/merkle_commitments_sapling.json \
|
||||
test/data/g1_compressed.json \
|
||||
test/data/g2_compressed.json \
|
||||
test/data/sapling_key_components.json
|
||||
|
||||
RAW_TEST_FILES = test/data/alertTests.raw
|
||||
|
||||
GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
|
||||
|
||||
BITCOIN_TESTS =\
|
||||
test/arith_uint256_tests.cpp \
|
||||
test/bignum.h \
|
||||
test/addrman_tests.cpp \
|
||||
test/allocator_tests.cpp \
|
||||
test/base32_tests.cpp \
|
||||
test/base58_tests.cpp \
|
||||
test/base64_tests.cpp \
|
||||
test/bip32_tests.cpp \
|
||||
test/bloom_tests.cpp \
|
||||
test/checkblock_tests.cpp \
|
||||
test/Checkpoints_tests.cpp \
|
||||
test/coins_tests.cpp \
|
||||
test/compress_tests.cpp \
|
||||
test/crypto_tests.cpp \
|
||||
test/DoS_tests.cpp \
|
||||
test/equihash_tests.cpp \
|
||||
test/getarg_tests.cpp \
|
||||
test/hash_tests.cpp \
|
||||
test/key_tests.cpp \
|
||||
test/main_tests.cpp \
|
||||
test/mempool_tests.cpp \
|
||||
test/miner_tests.cpp \
|
||||
test/mruset_tests.cpp \
|
||||
test/multisig_tests.cpp \
|
||||
test/netbase_tests.cpp \
|
||||
test/pmt_tests.cpp \
|
||||
test/policyestimator_tests.cpp \
|
||||
test/pow_tests.cpp \
|
||||
test/raii_event_tests.cpp \
|
||||
test/reverselock_tests.cpp \
|
||||
test/rpc_tests.cpp \
|
||||
test/sanity_tests.cpp \
|
||||
test/scheduler_tests.cpp \
|
||||
test/script_P2SH_tests.cpp \
|
||||
test/script_P2PKH_tests.cpp \
|
||||
test/script_tests.cpp \
|
||||
test/scriptnum_tests.cpp \
|
||||
test/serialize_tests.cpp \
|
||||
test/sighash_tests.cpp \
|
||||
test/sigopcount_tests.cpp \
|
||||
test/skiplist_tests.cpp \
|
||||
test/test_bitcoin.cpp \
|
||||
test/test_bitcoin.h \
|
||||
test/timedata_tests.cpp \
|
||||
test/torcontrol_tests.cpp \
|
||||
test/transaction_tests.cpp \
|
||||
test/uint256_tests.cpp \
|
||||
test/univalue_tests.cpp \
|
||||
test/util_tests.cpp \
|
||||
test/sha256compress_tests.cpp
|
||||
test/arith_uint256_tests.cpp \
|
||||
test/bignum.h \
|
||||
test/addrman_tests.cpp \
|
||||
test/alert_tests.cpp \
|
||||
test/allocator_tests.cpp \
|
||||
test/base32_tests.cpp \
|
||||
test/base58_tests.cpp \
|
||||
test/base64_tests.cpp \
|
||||
test/bech32_tests.cpp \
|
||||
test/bip32_tests.cpp \
|
||||
test/bloom_tests.cpp \
|
||||
test/checkblock_tests.cpp \
|
||||
test/Checkpoints_tests.cpp \
|
||||
test/coins_tests.cpp \
|
||||
test/compress_tests.cpp \
|
||||
test/convertbits_tests.cpp \
|
||||
test/crypto_tests.cpp \
|
||||
test/DoS_tests.cpp \
|
||||
test/equihash_tests.cpp \
|
||||
test/getarg_tests.cpp \
|
||||
test/hash_tests.cpp \
|
||||
test/key_tests.cpp \
|
||||
test/dbwrapper_tests.cpp \
|
||||
test/main_tests.cpp \
|
||||
test/mempool_tests.cpp \
|
||||
test/miner_tests.cpp \
|
||||
test/mruset_tests.cpp \
|
||||
test/multisig_tests.cpp \
|
||||
test/netbase_tests.cpp \
|
||||
test/pmt_tests.cpp \
|
||||
test/policyestimator_tests.cpp \
|
||||
test/pow_tests.cpp \
|
||||
test/prevector_tests.cpp \
|
||||
test/raii_event_tests.cpp \
|
||||
test/reverselock_tests.cpp \
|
||||
test/rpc_tests.cpp \
|
||||
test/sanity_tests.cpp \
|
||||
test/scheduler_tests.cpp \
|
||||
test/script_P2SH_tests.cpp \
|
||||
test/script_tests.cpp \
|
||||
test/scriptnum_tests.cpp \
|
||||
test/serialize_tests.cpp \
|
||||
test/sighash_tests.cpp \
|
||||
test/sigopcount_tests.cpp \
|
||||
test/skiplist_tests.cpp \
|
||||
test/test_bitcoin.cpp \
|
||||
test/test_bitcoin.h \
|
||||
test/timedata_tests.cpp \
|
||||
test/torcontrol_tests.cpp \
|
||||
test/transaction_tests.cpp \
|
||||
test/uint256_tests.cpp \
|
||||
test/univalue_tests.cpp \
|
||||
test/util_tests.cpp \
|
||||
test/sha256compress_tests.cpp
|
||||
|
||||
if ENABLE_WALLET
|
||||
BITCOIN_TESTS += \
|
||||
@@ -102,12 +113,15 @@ endif
|
||||
|
||||
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
||||
test_test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) -fopenmp $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_CFLAGS)
|
||||
test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||
test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBVERUS_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
if ENABLE_WALLET
|
||||
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
|
||||
$(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_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
|
||||
|
||||
@@ -24,6 +24,7 @@ zcash_CreateJoinSplit_LDADD = \
|
||||
$(LIBSNARK) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBVERUS_CRYPTO) \
|
||||
$(BOOST_LIBS) \
|
||||
$(LIBZCASH_LIBS) \
|
||||
$(LIBCRYPTOCONDITIONS) \
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(*(CAddress*)this);
|
||||
READWRITE(source);
|
||||
READWRITE(nLastSuccess);
|
||||
@@ -279,7 +279,7 @@ public:
|
||||
* very little in common.
|
||||
*/
|
||||
template<typename Stream>
|
||||
void Serialize(Stream &s, int nType, int nVersionDummy) const
|
||||
void Serialize(Stream &s) const
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
@@ -329,7 +329,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s, int nType, int nVersionDummy)
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
@@ -434,11 +434,6 @@ public:
|
||||
Check();
|
||||
}
|
||||
|
||||
unsigned int GetSerializeSize(int nType, int nVersion) const
|
||||
{
|
||||
return (CSizeComputer(nType, nVersion) << *this).size();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
std::vector<int>().swap(vRandom);
|
||||
|
||||
@@ -49,9 +49,8 @@ public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(this->nVersion);
|
||||
nVersion = this->nVersion;
|
||||
READWRITE(nRelayUntil);
|
||||
READWRITE(nExpiration);
|
||||
READWRITE(nID);
|
||||
@@ -87,7 +86,7 @@ public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(vchMsg);
|
||||
READWRITE(vchSig);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(nSatoshisPerK);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -66,18 +66,6 @@
|
||||
"190.114.254.104"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ac_name": "KMDICE",
|
||||
"ac_supply": "10500000",
|
||||
"ac_reward": "2500000000",
|
||||
"ac_halving": "210000",
|
||||
"ac_cc": "2",
|
||||
"addressindex": "1",
|
||||
"spentindex": "1",
|
||||
"addnode": [
|
||||
"144.76.217.232"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ac_name": "DION",
|
||||
"ac_supply": "3900000000",
|
||||
|
||||
@@ -16,7 +16,7 @@ using namespace std;
|
||||
|
||||
static boost::uuids::random_generator uuidgen;
|
||||
|
||||
std::map<OperationStatus, std::string> OperationStatusMap = {
|
||||
static std::map<OperationStatus, std::string> OperationStatusMap = {
|
||||
{OperationStatus::READY, "queued"},
|
||||
{OperationStatus::EXECUTING, "executing"},
|
||||
{OperationStatus::CANCELLED, "cancelled"},
|
||||
|
||||
@@ -4,15 +4,12 @@
|
||||
|
||||
#include "base58.h"
|
||||
|
||||
#include "hash.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include "version.h"
|
||||
#include "streams.h"
|
||||
#include <hash.h>
|
||||
#include <uint256.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
@@ -104,7 +101,7 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
|
||||
|
||||
std::string EncodeBase58(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
return EncodeBase58(&vch[0], &vch[0] + vch.size());
|
||||
return EncodeBase58(vch.data(), vch.data() + vch.size());
|
||||
}
|
||||
|
||||
bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
|
||||
@@ -143,6 +140,7 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe
|
||||
return DecodeBase58Check(str.c_str(), vchRet);
|
||||
}
|
||||
|
||||
|
||||
CBase58Data::CBase58Data()
|
||||
{
|
||||
vchVersion.clear();
|
||||
@@ -215,6 +213,7 @@ public:
|
||||
CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {}
|
||||
|
||||
bool operator()(const CKeyID& id) const { return addr->Set(id); }
|
||||
bool operator()(const CPubKey& key) const { return addr->Set(key); }
|
||||
bool operator()(const CScriptID& id) const { return addr->Set(id); }
|
||||
bool operator()(const CNoDestination& no) const { return false; }
|
||||
};
|
||||
@@ -227,6 +226,13 @@ bool CBitcoinAddress::Set(const CKeyID& id)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::Set(const CPubKey& key)
|
||||
{
|
||||
CKeyID id = key.GetID();
|
||||
SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::Set(const CScriptID& id)
|
||||
{
|
||||
SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
|
||||
@@ -302,6 +308,14 @@ bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::GetKeyID_NoCheck(CKeyID& keyID) const
|
||||
{
|
||||
uint160 id;
|
||||
memcpy(&id, &vchData[0], 20);
|
||||
keyID = CKeyID(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBitcoinAddress::IsScript() const
|
||||
{
|
||||
return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
|
||||
@@ -373,27 +387,3 @@ DATA_TYPE CZCEncoding<DATA_TYPE, PREFIX, SER_SIZE>::Get() const
|
||||
ss >> ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Explicit instantiations for libzcash::PaymentAddress
|
||||
template bool CZCEncoding<libzcash::PaymentAddress,
|
||||
CChainParams::ZCPAYMENT_ADDRRESS,
|
||||
libzcash::SerializedPaymentAddressSize>::Set(const libzcash::PaymentAddress& addr);
|
||||
template libzcash::PaymentAddress CZCEncoding<libzcash::PaymentAddress,
|
||||
CChainParams::ZCPAYMENT_ADDRRESS,
|
||||
libzcash::SerializedPaymentAddressSize>::Get() const;
|
||||
|
||||
// Explicit instantiations for libzcash::ViewingKey
|
||||
template bool CZCEncoding<libzcash::ViewingKey,
|
||||
CChainParams::ZCVIEWING_KEY,
|
||||
libzcash::SerializedViewingKeySize>::Set(const libzcash::ViewingKey& vk);
|
||||
template libzcash::ViewingKey CZCEncoding<libzcash::ViewingKey,
|
||||
CChainParams::ZCVIEWING_KEY,
|
||||
libzcash::SerializedViewingKeySize>::Get() const;
|
||||
|
||||
// Explicit instantiations for libzcash::SpendingKey
|
||||
template bool CZCEncoding<libzcash::SpendingKey,
|
||||
CChainParams::ZCSPENDING_KEY,
|
||||
libzcash::SerializedSpendingKeySize>::Set(const libzcash::SpendingKey& sk);
|
||||
template libzcash::SpendingKey CZCEncoding<libzcash::SpendingKey,
|
||||
CChainParams::ZCSPENDING_KEY,
|
||||
libzcash::SerializedSpendingKeySize>::Get() const;
|
||||
|
||||
39
src/base58.h
39
src/base58.h
@@ -58,13 +58,13 @@ std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn);
|
||||
* Decode a base58-encoded string (psz) that includes a checksum into a byte
|
||||
* vector (vchRet), return true if decoding is successful
|
||||
*/
|
||||
inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet);
|
||||
bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet);
|
||||
|
||||
/**
|
||||
* Decode a base58-encoded string (str) that includes a checksum into a byte
|
||||
* vector (vchRet), return true if decoding is successful
|
||||
*/
|
||||
inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet);
|
||||
bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet);
|
||||
|
||||
/**
|
||||
* Base class for all base58-encoded data
|
||||
@@ -107,39 +107,6 @@ public:
|
||||
DATA_TYPE Get() const;
|
||||
};
|
||||
|
||||
class CZCPaymentAddress : public CZCEncoding<libzcash::PaymentAddress, CChainParams::ZCPAYMENT_ADDRRESS, libzcash::SerializedPaymentAddressSize> {
|
||||
protected:
|
||||
std::string PrependName(const std::string& s) const { return "payment address" + s; }
|
||||
|
||||
public:
|
||||
CZCPaymentAddress() {}
|
||||
|
||||
CZCPaymentAddress(const std::string& strAddress) { SetString(strAddress.c_str(), 2); }
|
||||
CZCPaymentAddress(const libzcash::PaymentAddress& addr) { Set(addr); }
|
||||
};
|
||||
|
||||
class CZCViewingKey : public CZCEncoding<libzcash::ViewingKey, CChainParams::ZCVIEWING_KEY, libzcash::SerializedViewingKeySize> {
|
||||
protected:
|
||||
std::string PrependName(const std::string& s) const { return "viewing key" + s; }
|
||||
|
||||
public:
|
||||
CZCViewingKey() {}
|
||||
|
||||
CZCViewingKey(const std::string& strViewingKey) { SetString(strViewingKey.c_str(), 3); }
|
||||
CZCViewingKey(const libzcash::ViewingKey& vk) { Set(vk); }
|
||||
};
|
||||
|
||||
class CZCSpendingKey : public CZCEncoding<libzcash::SpendingKey, CChainParams::ZCSPENDING_KEY, libzcash::SerializedSpendingKeySize> {
|
||||
protected:
|
||||
std::string PrependName(const std::string& s) const { return "spending key" + s; }
|
||||
|
||||
public:
|
||||
CZCSpendingKey() {}
|
||||
|
||||
CZCSpendingKey(const std::string& strAddress) { SetString(strAddress.c_str(), 2); }
|
||||
CZCSpendingKey(const libzcash::SpendingKey& addr) { Set(addr); }
|
||||
};
|
||||
|
||||
/** base58-encoded Bitcoin addresses.
|
||||
* Public-key-hash-addresses have version 0 (or 111 testnet).
|
||||
* The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
|
||||
@@ -149,6 +116,7 @@ public:
|
||||
class CBitcoinAddress : public CBase58Data {
|
||||
public:
|
||||
bool Set(const CKeyID &id);
|
||||
bool Set(const CPubKey &key);
|
||||
bool Set(const CScriptID &id);
|
||||
bool Set(const CTxDestination &dest);
|
||||
bool IsValid() const;
|
||||
@@ -163,6 +131,7 @@ public:
|
||||
|
||||
CTxDestination Get() const;
|
||||
bool GetKeyID(CKeyID &keyID) const;
|
||||
bool GetKeyID_NoCheck(CKeyID& keyID) const;
|
||||
bool GetIndexKey(uint160& hashBytes, int& type) const;
|
||||
bool IsScript() const;
|
||||
};
|
||||
|
||||
194
src/bech32.cpp
Normal file
194
src/bech32.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
// Copyright (c) 2017 Pieter Wuille
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "bech32.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
typedef std::vector<uint8_t> data;
|
||||
|
||||
/** The Bech32 character set for encoding. */
|
||||
const char* CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
||||
|
||||
/** The Bech32 character set for decoding. */
|
||||
const int8_t CHARSET_REV[128] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
|
||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
|
||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
/** Concatenate two byte arrays. */
|
||||
data Cat(data x, const data& y)
|
||||
{
|
||||
x.insert(x.end(), y.begin(), y.end());
|
||||
return x;
|
||||
}
|
||||
|
||||
/** This function will compute what 6 5-bit values to XOR into the last 6 input values, in order to
|
||||
* make the checksum 0. These 6 values are packed together in a single 30-bit integer. The higher
|
||||
* bits correspond to earlier values. */
|
||||
uint32_t PolyMod(const data& v)
|
||||
{
|
||||
// The input is interpreted as a list of coefficients of a polynomial over F = GF(32), with an
|
||||
// implicit 1 in front. If the input is [v0,v1,v2,v3,v4], that polynomial is v(x) =
|
||||
// 1*x^5 + v0*x^4 + v1*x^3 + v2*x^2 + v3*x + v4. The implicit 1 guarantees that
|
||||
// [v0,v1,v2,...] has a distinct checksum from [0,v0,v1,v2,...].
|
||||
|
||||
// The output is a 30-bit integer whose 5-bit groups are the coefficients of the remainder of
|
||||
// v(x) mod g(x), where g(x) is the Bech32 generator,
|
||||
// x^6 + {29}x^5 + {22}x^4 + {20}x^3 + {21}x^2 + {29}x + {18}. g(x) is chosen in such a way
|
||||
// that the resulting code is a BCH code, guaranteeing detection of up to 3 errors within a
|
||||
// window of 1023 characters. Among the various possible BCH codes, one was selected to in
|
||||
// fact guarantee detection of up to 4 errors within a window of 89 characters.
|
||||
|
||||
// Note that the coefficients are elements of GF(32), here represented as decimal numbers
|
||||
// between {}. In this finite field, addition is just XOR of the corresponding numbers. For
|
||||
// example, {27} + {13} = {27 ^ 13} = {22}. Multiplication is more complicated, and requires
|
||||
// treating the bits of values themselves as coefficients of a polynomial over a smaller field,
|
||||
// GF(2), and multiplying those polynomials mod a^5 + a^3 + 1. For example, {5} * {26} =
|
||||
// (a^2 + 1) * (a^4 + a^3 + a) = (a^4 + a^3 + a) * a^2 + (a^4 + a^3 + a) = a^6 + a^5 + a^4 + a
|
||||
// = a^3 + 1 (mod a^5 + a^3 + 1) = {9}.
|
||||
|
||||
// During the course of the loop below, `c` contains the bitpacked coefficients of the
|
||||
// polynomial constructed from just the values of v that were processed so far, mod g(x). In
|
||||
// the above example, `c` initially corresponds to 1 mod (x), and after processing 2 inputs of
|
||||
// v, it corresponds to x^2 + v0*x + v1 mod g(x). As 1 mod g(x) = 1, that is the starting value
|
||||
// for `c`.
|
||||
uint32_t c = 1;
|
||||
for (auto v_i : v) {
|
||||
// We want to update `c` to correspond to a polynomial with one extra term. If the initial
|
||||
// value of `c` consists of the coefficients of c(x) = f(x) mod g(x), we modify it to
|
||||
// correspond to c'(x) = (f(x) * x + v_i) mod g(x), where v_i is the next input to
|
||||
// process. Simplifying:
|
||||
// c'(x) = (f(x) * x + v_i) mod g(x)
|
||||
// ((f(x) mod g(x)) * x + v_i) mod g(x)
|
||||
// (c(x) * x + v_i) mod g(x)
|
||||
// If c(x) = c0*x^5 + c1*x^4 + c2*x^3 + c3*x^2 + c4*x + c5, we want to compute
|
||||
// c'(x) = (c0*x^5 + c1*x^4 + c2*x^3 + c3*x^2 + c4*x + c5) * x + v_i mod g(x)
|
||||
// = c0*x^6 + c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i mod g(x)
|
||||
// = c0*(x^6 mod g(x)) + c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i
|
||||
// If we call (x^6 mod g(x)) = k(x), this can be written as
|
||||
// c'(x) = (c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i) + c0*k(x)
|
||||
|
||||
// First, determine the value of c0:
|
||||
uint8_t c0 = c >> 25;
|
||||
|
||||
// Then compute c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i:
|
||||
c = ((c & 0x1ffffff) << 5) ^ v_i;
|
||||
|
||||
// Finally, for each set bit n in c0, conditionally add {2^n}k(x):
|
||||
if (c0 & 1) c ^= 0x3b6a57b2; // k(x) = {29}x^5 + {22}x^4 + {20}x^3 + {21}x^2 + {29}x + {18}
|
||||
if (c0 & 2) c ^= 0x26508e6d; // {2}k(x) = {19}x^5 + {5}x^4 + x^3 + {3}x^2 + {19}x + {13}
|
||||
if (c0 & 4) c ^= 0x1ea119fa; // {4}k(x) = {15}x^5 + {10}x^4 + {2}x^3 + {6}x^2 + {15}x + {26}
|
||||
if (c0 & 8) c ^= 0x3d4233dd; // {8}k(x) = {30}x^5 + {20}x^4 + {4}x^3 + {12}x^2 + {30}x + {29}
|
||||
if (c0 & 16) c ^= 0x2a1462b3; // {16}k(x) = {21}x^5 + x^4 + {8}x^3 + {24}x^2 + {21}x + {19}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/** Convert to lower case. */
|
||||
inline unsigned char LowerCase(unsigned char c)
|
||||
{
|
||||
return (c >= 'A' && c <= 'Z') ? (c - 'A') + 'a' : c;
|
||||
}
|
||||
|
||||
/** Expand a HRP for use in checksum computation. */
|
||||
data ExpandHRP(const std::string& hrp)
|
||||
{
|
||||
data ret;
|
||||
ret.reserve(hrp.size() + 90);
|
||||
ret.resize(hrp.size() * 2 + 1);
|
||||
for (size_t i = 0; i < hrp.size(); ++i) {
|
||||
unsigned char c = hrp[i];
|
||||
ret[i] = c >> 5;
|
||||
ret[i + hrp.size() + 1] = c & 0x1f;
|
||||
}
|
||||
ret[hrp.size()] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Verify a checksum. */
|
||||
bool VerifyChecksum(const std::string& hrp, const data& values)
|
||||
{
|
||||
// PolyMod computes what value to xor into the final values to make the checksum 0. However,
|
||||
// if we required that the checksum was 0, it would be the case that appending a 0 to a valid
|
||||
// list of values would result in a new valid list. For that reason, Bech32 requires the
|
||||
// resulting checksum to be 1 instead.
|
||||
return PolyMod(Cat(ExpandHRP(hrp), values)) == 1;
|
||||
}
|
||||
|
||||
/** Create a checksum. */
|
||||
data CreateChecksum(const std::string& hrp, const data& values)
|
||||
{
|
||||
data enc = Cat(ExpandHRP(hrp), values);
|
||||
enc.resize(enc.size() + 6); // Append 6 zeroes
|
||||
uint32_t mod = PolyMod(enc) ^ 1; // Determine what to XOR into those 6 zeroes.
|
||||
data ret(6);
|
||||
for (size_t i = 0; i < 6; ++i) {
|
||||
// Convert the 5-bit groups in mod to checksum values.
|
||||
ret[i] = (mod >> (5 * (5 - i))) & 31;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace bech32
|
||||
{
|
||||
|
||||
/** Encode a Bech32 string. */
|
||||
std::string Encode(const std::string& hrp, const data& values) {
|
||||
data checksum = CreateChecksum(hrp, values);
|
||||
data combined = Cat(values, checksum);
|
||||
std::string ret = hrp + '1';
|
||||
ret.reserve(ret.size() + combined.size());
|
||||
for (auto c : combined) {
|
||||
if (c >= 32) {
|
||||
return "";
|
||||
}
|
||||
ret += CHARSET[c];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Decode a Bech32 string. */
|
||||
std::pair<std::string, data> Decode(const std::string& str) {
|
||||
bool lower = false, upper = false;
|
||||
for (size_t i = 0; i < str.size(); ++i) {
|
||||
unsigned char c = str[i];
|
||||
if (c < 33 || c > 126) return {};
|
||||
if (c >= 'a' && c <= 'z') lower = true;
|
||||
if (c >= 'A' && c <= 'Z') upper = true;
|
||||
}
|
||||
if (lower && upper) return {};
|
||||
size_t pos = str.rfind('1');
|
||||
if (str.size() > 1023 || pos == str.npos || pos == 0 || pos + 7 > str.size()) {
|
||||
return {};
|
||||
}
|
||||
data values(str.size() - 1 - pos);
|
||||
for (size_t i = 0; i < str.size() - 1 - pos; ++i) {
|
||||
unsigned char c = str[i + pos + 1];
|
||||
int8_t rev = (c < 33 || c > 126) ? -1 : CHARSET_REV[c];
|
||||
if (rev == -1) {
|
||||
return {};
|
||||
}
|
||||
values[i] = rev;
|
||||
}
|
||||
std::string hrp;
|
||||
for (size_t i = 0; i < pos; ++i) {
|
||||
hrp += LowerCase(str[i]);
|
||||
}
|
||||
if (!VerifyChecksum(hrp, values)) {
|
||||
return {};
|
||||
}
|
||||
return {hrp, data(values.begin(), values.end() - 6)};
|
||||
}
|
||||
|
||||
} // namespace bech32
|
||||
30
src/bech32.h
Normal file
30
src/bech32.h
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2017 Pieter Wuille
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
// Bech32 is a string encoding format used in newer address types.
|
||||
// The output consists of a human-readable part (alphanumeric), a
|
||||
// separator character (1), and a base32 data section, the last
|
||||
// 6 characters of which are a checksum.
|
||||
//
|
||||
// For more information, see BIP 173.
|
||||
|
||||
#ifndef BITCOIN_BECH32_H
|
||||
#define BITCOIN_BECH32_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace bech32
|
||||
{
|
||||
|
||||
/** Encode a Bech32 string. Returns the empty string in case of failure. */
|
||||
std::string Encode(const std::string& hrp, const std::vector<uint8_t>& values);
|
||||
|
||||
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */
|
||||
std::pair<std::string, std::vector<uint8_t>> Decode(const std::string& str);
|
||||
|
||||
} // namespace bech32
|
||||
|
||||
#endif // BITCOIN_BECH32_H
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
#include "chainparamsbase.h"
|
||||
#include "clientversion.h"
|
||||
#include "rpcclient.h"
|
||||
#include "rpcprotocol.h"
|
||||
#include "rpc/client.h"
|
||||
#include "rpc/protocol.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
@@ -22,14 +22,12 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
int64_t MAX_MONEY = 200000000 * 100000000LL;
|
||||
uint64_t komodo_maxallowed(int32_t baseid) { return(100000000LL * 1000000); } // stub
|
||||
|
||||
static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
|
||||
static const int CONTINUE_EXECUTION=-1;
|
||||
|
||||
std::string HelpMessageCli()
|
||||
{
|
||||
string strUsage;
|
||||
std::string strUsage;
|
||||
strUsage += HelpMessageGroup(_("Options:"));
|
||||
strUsage += HelpMessageOpt("-?", _("This help message"));
|
||||
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "komodo.conf"));
|
||||
@@ -43,6 +41,7 @@ std::string HelpMessageCli()
|
||||
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
|
||||
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
|
||||
strUsage += HelpMessageOpt("-rpcclienttimeout=<n>", strprintf(_("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT));
|
||||
strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases)"));
|
||||
|
||||
return strUsage;
|
||||
}
|
||||
@@ -90,8 +89,16 @@ uint32_t komodo_heightstamp(int32_t height)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static bool AppInitRPC(int argc, char* argv[])
|
||||
//
|
||||
// This function returns either one of EXIT_ codes when it's expected to stop the process or
|
||||
// CONTINUE_EXECUTION when it's expected to continue further.
|
||||
//
|
||||
static int AppInitRPC(int argc, char* argv[])
|
||||
{
|
||||
static_assert(CONTINUE_EXECUTION != EXIT_FAILURE,
|
||||
"CONTINUE_EXECUTION should be different from EXIT_FAILURE");
|
||||
static_assert(CONTINUE_EXECUTION != EXIT_SUCCESS,
|
||||
"CONTINUE_EXECUTION should be different from EXIT_SUCCESS");
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
@@ -111,29 +118,33 @@ static bool AppInitRPC(int argc, char* argv[])
|
||||
}
|
||||
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
return false;
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Error: too few parameters\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (!boost::filesystem::is_directory(GetDataDir(false))) {
|
||||
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
|
||||
return false;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
try {
|
||||
ReadConfigFile(mapArgs, mapMultiArgs);
|
||||
} catch (const std::exception& e) {
|
||||
fprintf(stderr,"Error reading configuration file: %s\n", e.what());
|
||||
return false;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
|
||||
if (!SelectBaseParamsFromCommandLine()) {
|
||||
fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
|
||||
return false;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (GetBoolArg("-rpcssl", false))
|
||||
{
|
||||
fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n");
|
||||
return false;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return true;
|
||||
return CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +213,7 @@ static void http_error_cb(enum evhttp_request_error err, void *ctx)
|
||||
}
|
||||
#endif
|
||||
|
||||
UniValue CallRPC(const string& strMethod, const UniValue& params)
|
||||
UniValue CallRPC(const std::string& strMethod, const UniValue& params)
|
||||
{
|
||||
std::string host = GetArg("-rpcconnect", "127.0.0.1");
|
||||
int port = GetArg("-rpcport", BaseParams().RPCPort());
|
||||
@@ -217,7 +228,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
|
||||
HTTPReply response;
|
||||
raii_evhttp_request req = obtain_evhttp_request(http_request_done, (void*)&response);
|
||||
if (req == NULL)
|
||||
throw runtime_error("create http request failed");
|
||||
throw std::runtime_error("create http request failed");
|
||||
#if LIBEVENT_VERSION_NUMBER >= 0x02010300
|
||||
evhttp_request_set_error_cb(req.get(), http_error_cb);
|
||||
#endif
|
||||
@@ -227,7 +238,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
|
||||
if (mapArgs["-rpcpassword"] == "") {
|
||||
// Try fall back to cookie-based authentication if no password is provided
|
||||
if (!GetAuthCookie(&strRPCUserColonPass)) {
|
||||
throw runtime_error(strprintf(
|
||||
throw std::runtime_error(strprintf(
|
||||
_("Could not locate RPC credentials. No authentication cookie could be found,\n"
|
||||
"and no rpcpassword is set in the configuration file (%s)."),
|
||||
GetConfigFile().string().c_str()));
|
||||
@@ -260,26 +271,26 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
|
||||
if (response.status == 0)
|
||||
throw CConnectionFailed(strprintf("couldn't connect to server: %s (code %d)\n(make sure server is running and you are connecting to the correct RPC port)", http_errorstring(response.error), response.error));
|
||||
else if (response.status == HTTP_UNAUTHORIZED)
|
||||
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
||||
throw std::runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
||||
else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
|
||||
throw runtime_error(strprintf("server returned HTTP error %d", response.status));
|
||||
throw std::runtime_error(strprintf("server returned HTTP error %d", response.status));
|
||||
else if (response.body.empty())
|
||||
throw runtime_error("no response from server");
|
||||
throw std::runtime_error("no response from server");
|
||||
|
||||
// Parse reply
|
||||
UniValue valReply(UniValue::VSTR);
|
||||
if (!valReply.read(response.body))
|
||||
throw runtime_error("couldn't parse reply from server");
|
||||
throw std::runtime_error("couldn't parse reply from server");
|
||||
const UniValue& reply = valReply.get_obj();
|
||||
if (reply.empty())
|
||||
throw runtime_error("expected reply to have result, error and id properties");
|
||||
throw std::runtime_error("expected reply to have result, error and id properties");
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
int CommandLineRPC(int argc, char *argv[])
|
||||
{
|
||||
string strPrint;
|
||||
std::string strPrint;
|
||||
int nRet = 0;
|
||||
try {
|
||||
// Skip switches
|
||||
@@ -287,15 +298,17 @@ int CommandLineRPC(int argc, char *argv[])
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
// Method
|
||||
if (argc < 2)
|
||||
throw runtime_error("too few parameters");
|
||||
string strMethod = argv[1];
|
||||
|
||||
// Parameters default to strings
|
||||
std::vector<std::string> strParams(&argv[2], &argv[argc]);
|
||||
UniValue params = RPCConvertValues(strMethod, strParams);
|
||||
std::vector<std::string> args = std::vector<std::string>(&argv[1], &argv[argc]);
|
||||
if (GetBoolArg("-stdin", false)) {
|
||||
// Read one arg per line from stdin and append
|
||||
std::string line;
|
||||
while (std::getline(std::cin,line))
|
||||
args.push_back(line);
|
||||
}
|
||||
if (args.size() < 1)
|
||||
throw std::runtime_error("too few parameters (need at least command)");
|
||||
std::string strMethod = args[0];
|
||||
UniValue params = RPCConvertValues(strMethod, std::vector<std::string>(args.begin()+1, args.end()));
|
||||
|
||||
// Execute and handle connection failures with -rpcwait
|
||||
const bool fWait = GetBoolArg("-rpcwait", false);
|
||||
@@ -347,7 +360,7 @@ int CommandLineRPC(int argc, char *argv[])
|
||||
throw;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
strPrint = string("error: ") + e.what();
|
||||
strPrint = std::string("error: ") + e.what();
|
||||
nRet = EXIT_FAILURE;
|
||||
}
|
||||
catch (...) {
|
||||
@@ -366,12 +379,13 @@ int main(int argc, char* argv[])
|
||||
SetupEnvironment();
|
||||
if (!SetupNetworking()) {
|
||||
fprintf(stderr, "Error: Initializing networking failed\n");
|
||||
exit(1);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
try {
|
||||
if(!AppInitRPC(argc, argv))
|
||||
return EXIT_FAILURE;
|
||||
int ret = AppInitRPC(argc, argv);
|
||||
if (ret != CONTINUE_EXECUTION)
|
||||
return ret;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
PrintExceptionContinue(&e, "AppInitRPC()");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "clientversion.h"
|
||||
#include "rpcserver.h"
|
||||
#include "rpc/server.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
#include "noui.h"
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "util.h"
|
||||
#include "httpserver.h"
|
||||
#include "httprpc.h"
|
||||
#include "rpcserver.h"
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
@@ -42,6 +41,7 @@
|
||||
*/
|
||||
|
||||
static bool fDaemon;
|
||||
#include "komodo_defs.h"
|
||||
#define KOMODO_ASSETCHAIN_MAXLEN 65
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
void komodo_passport_iteration();
|
||||
@@ -115,7 +115,7 @@ bool AppInit(int argc, char* argv[])
|
||||
}
|
||||
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -179,7 +179,7 @@ bool AppInit(int argc, char* argv[])
|
||||
if (fCommandLine)
|
||||
{
|
||||
fprintf(stderr, "Error: There is no RPC client functionality in komodod. Use the komodo-cli utility instead.\n");
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -236,5 +236,5 @@ int main(int argc, char* argv[])
|
||||
// Connect bitcoind signal handlers
|
||||
noui_connect();
|
||||
|
||||
return (AppInit(argc, argv) ? 0 : 1);
|
||||
return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(vData);
|
||||
READWRITE(nHashFuncs);
|
||||
READWRITE(nTweak);
|
||||
|
||||
@@ -20,15 +20,18 @@
|
||||
#include "CCinclude.h"
|
||||
#include "../merkleblock.h"
|
||||
|
||||
bool GatewaysValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool GatewaysValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector<CPubKey> pubkeys);
|
||||
std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::string refcoin,uint256 cointxid,int32_t claimvout,std::string deposithex,std::vector<uint8_t>proof,CPubKey destpub,int64_t amount);
|
||||
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount);
|
||||
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount);
|
||||
std::string GatewaysPartialSign(uint64_t txfee,uint256 txidaddr,std::string refcoin,std::string hex);
|
||||
std::string GatewaysCompleteSigning(uint64_t txfee,uint256 txidaddr,std::string refcoin,std::string hex);
|
||||
std::string GatewaysMarkDone(uint64_t txfee,uint256 withdrawtxid,std::string refcoin);
|
||||
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin);
|
||||
std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string refcoin,uint256 cointxid);
|
||||
UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin);
|
||||
UniValue GatewaysMultisig(char *txidaddr);
|
||||
std::string GatewaysPartialSign(uint64_t txfee,uint256 txidaddr,std::string refcoin, std::string hex);
|
||||
|
||||
|
||||
// CCcustom
|
||||
UniValue GatewaysInfo(uint256 bindtxid);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#define EVAL_HEIR 0xea
|
||||
|
||||
bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
UniValue HeirInfo();
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "CCinclude.h"
|
||||
|
||||
bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
std::string OracleCreate(int64_t txfee,std::string name,std::string description,std::string format);
|
||||
std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee);
|
||||
std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "CCinclude.h"
|
||||
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
UniValue PaymentsInfo();
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "CCinclude.h"
|
||||
|
||||
bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
UniValue PegsInfo();
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "CCinclude.h"
|
||||
|
||||
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
UniValue PricesList();
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "CCinclude.h"
|
||||
|
||||
bool TriggersValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool TriggersValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
UniValue TriggersInfo();
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "CCinclude.h"
|
||||
|
||||
// CCcustom
|
||||
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCassetsCore
|
||||
//CTxOut MakeAssetsVout(CAmount nValue,CPubKey pk);
|
||||
|
||||
@@ -56,7 +56,8 @@ int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
||||
|
||||
int64_t GetAssetBalance(CPubKey pk,uint256 tokenid)
|
||||
{
|
||||
CMutableTransaction mtx; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
return(AddAssetInputs(cp,mtx,pk,tokenid,0,0));
|
||||
}
|
||||
@@ -186,7 +187,8 @@ UniValue AssetOrders(uint256 refassetid)
|
||||
|
||||
std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
if ( assetsupply < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply);
|
||||
@@ -212,7 +214,8 @@ std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::
|
||||
|
||||
std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
|
||||
if ( total < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative total %lld\n",(long long)total);
|
||||
@@ -222,7 +225,7 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> des
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
{
|
||||
/*n = outputs.size();
|
||||
if ( n == amounts.size() )
|
||||
@@ -247,7 +250,8 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> des
|
||||
|
||||
std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total,int32_t evalcode)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
|
||||
if ( total < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative total %lld\n",(long long)total);
|
||||
@@ -257,7 +261,7 @@ std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector<uint8_t> dest
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
{
|
||||
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 )
|
||||
{
|
||||
@@ -273,7 +277,8 @@ std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector<uint8_t> dest
|
||||
|
||||
std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description;
|
||||
if ( bidamount < 0 || pricetotal < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n",(long long)bidamount,(long long)pricetotal);
|
||||
@@ -303,7 +308,8 @@ std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64
|
||||
|
||||
std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||
if ( askamount < 0 || pricetotal < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
||||
@@ -313,7 +319,7 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
{
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,askamount,60)) > 0 )
|
||||
@@ -335,7 +341,8 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
|
||||
std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||
fprintf(stderr,"asset swaps disabled\n");
|
||||
return("");
|
||||
if ( askamount < 0 || pricetotal < 0 )
|
||||
@@ -347,7 +354,7 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
{
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,askamount,60)) > 0 )
|
||||
@@ -374,12 +381,13 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a
|
||||
|
||||
std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t bidamount; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t bidamount; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
{
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if ( GetTransaction(bidtxid,vintx,hashBlock,false) != 0 )
|
||||
@@ -395,12 +403,13 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
||||
|
||||
std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t askamount; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t askamount; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
{
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if ( GetTransaction(asktxid,vintx,hashBlock,false) != 0 )
|
||||
@@ -416,7 +425,8 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
||||
|
||||
std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount)
|
||||
{
|
||||
CTransaction vintx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; int32_t bidvout=0; uint64_t mask; int64_t origprice,bidamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction vintx; uint256 hashBlock; CPubKey mypk; std::vector<uint8_t> origpubkey; int32_t bidvout=0; uint64_t mask; int64_t origprice,bidamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
if ( fillamount < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative fillamount %lld\n",(long long)fillamount);
|
||||
@@ -426,7 +436,7 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
{
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if ( GetTransaction(bidtxid,vintx,hashBlock,false) != 0 )
|
||||
@@ -456,7 +466,8 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
|
||||
|
||||
std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 asktxid,int64_t fillunits)
|
||||
{
|
||||
CTransaction vintx,filltx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction vintx,filltx; uint256 hashBlock; CPubKey mypk; std::vector<uint8_t> origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
if ( fillunits < 0 )
|
||||
{
|
||||
CCerror = strprintf("negative fillunits %lld\n",(long long)fillunits);
|
||||
@@ -474,7 +485,7 @@ std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 askt
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
{
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if ( GetTransaction(asktxid,vintx,hashBlock,false) != 0 )
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#define EVAL_AUCTION 0xe8
|
||||
|
||||
bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
std::string AuctionPost(uint64_t txfee,uint256 itemhash,int64_t minbid,char *title,char *description);
|
||||
std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "CCinclude.h"
|
||||
#define CHANNELS_MAXPAYMENTS 1000
|
||||
|
||||
bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment);
|
||||
std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret);
|
||||
std::string ChannelClose(uint64_t txfee,uint256 opentxid);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#include "key_io.h"
|
||||
#include "CCinclude.h"
|
||||
#include "CCassets.h"
|
||||
#include "CCfaucet.h"
|
||||
@@ -221,7 +222,7 @@ uint8_t GatewaysCCpriv[32] = { 0xf7, 0x4b, 0x5b, 0xa2, 0x7a, 0x5e, 0x9c, 0xda, 0
|
||||
#undef FUNCNAME
|
||||
#undef EVALCODE
|
||||
|
||||
struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode)
|
||||
struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
|
||||
{
|
||||
cp->evalcode = evalcode;
|
||||
switch ( evalcode )
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#define EVAL_DICE 0xe6
|
||||
|
||||
bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds);
|
||||
std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyvout,int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout,uint256 vin0txid,int32_t vin0vout);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define EVAL_FAUCET 0xe4
|
||||
#define FAUCETSIZE (COIN / 10)
|
||||
|
||||
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
std::string FaucetFund(uint64_t txfee,int64_t funds);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#define EVAL_FSM 0xe7
|
||||
|
||||
bool FSMValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool FSMValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
std::string FSMList();
|
||||
std::string FSMInfo(uint256 fsmtxid);
|
||||
|
||||
@@ -57,12 +57,13 @@ extern char ASSETCHAINS_SYMBOL[];
|
||||
extern std::string CCerror;
|
||||
|
||||
#define SMALLVAL 0.000000000000001
|
||||
#define MIN_NOTARIZATION_CONFIRMS 2
|
||||
#ifndef _BITS256
|
||||
#define _BITS256
|
||||
union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; };
|
||||
typedef union _bits256 bits256;
|
||||
union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; };
|
||||
typedef union _bits256 bits256;
|
||||
#endif
|
||||
|
||||
|
||||
struct CC_utxo
|
||||
{
|
||||
uint256 txid;
|
||||
@@ -70,13 +71,23 @@ struct CC_utxo
|
||||
int32_t vout;
|
||||
};
|
||||
|
||||
// these are the parameters stored after Verus crypto-condition vouts. new versions may change
|
||||
// the format
|
||||
struct CC_meta
|
||||
{
|
||||
std::vector<unsigned char> version;
|
||||
uint8_t evalCode;
|
||||
bool is1of2;
|
||||
uint8_t numDestinations;
|
||||
// followed by address destinations
|
||||
};
|
||||
|
||||
struct CCcontract_info
|
||||
{
|
||||
uint256 prevtxid;
|
||||
char unspendableCCaddr[64],CChexstr[72],normaladdr[64],unspendableaddr2[64],unspendableaddr3[64];
|
||||
uint8_t CCpriv[32],unspendablepriv2[32],unspendablepriv3[32];
|
||||
CPubKey unspendablepk2,unspendablepk3;
|
||||
bool (*validate)(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool (*validate)(struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint32_t nIn);
|
||||
bool (*ismyvin)(CScript const& scriptSig);
|
||||
uint8_t evalcode,evalcode2,evalcode3,didinit;
|
||||
};
|
||||
@@ -93,11 +104,13 @@ struct oracleprice_info
|
||||
extern CWallet* pwalletMain;
|
||||
#endif
|
||||
bool GetAddressUnspent(uint160 addressHash, int type,std::vector<std::pair<CAddressUnspentKey,CAddressUnspentValue> > &unspentOutputs);
|
||||
CBlockIndex *komodo_getblockindex(uint256 hash);
|
||||
int32_t komodo_nextheight();
|
||||
|
||||
static const uint256 zeroid;
|
||||
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock);
|
||||
int32_t is_hexstr(char *str,int32_t n);
|
||||
bool myAddtomempool(CTransaction &tx);
|
||||
bool myAddtomempool(CTransaction &tx, CValidationState *pstate = NULL);
|
||||
//uint64_t myGettxout(uint256 hash,int32_t n);
|
||||
bool myIsutxo_spentinmempool(uint256 txid,int32_t vout);
|
||||
bool mytxid_inmempool(uint256 txid);
|
||||
@@ -108,6 +121,8 @@ int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *
|
||||
CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys);
|
||||
int64_t CCaddress_balance(char *coinaddr);
|
||||
CPubKey CCtxidaddr(char *txidaddr,uint256 txid);
|
||||
bool GetCCParams(Eval* eval, const CTransaction &tx, uint32_t nIn,
|
||||
CTransaction &txOut, std::vector<std::vector<unsigned char>> &preConditions, std::vector<std::vector<unsigned char>> ¶ms);
|
||||
|
||||
int64_t OraclePrice(int32_t height,uint256 reforacletxid,char *markeraddr,char *format);
|
||||
uint8_t DecodeOraclesCreateOpRet(const CScript &scriptPubKey,std::string &name,std::string &description,std::string &format);
|
||||
@@ -156,8 +171,9 @@ bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
|
||||
std::vector<uint8_t> Mypubkey();
|
||||
bool Myprivkey(uint8_t myprivkey[]);
|
||||
int64_t CCduration(int32_t &numblocks,uint256 txid);
|
||||
bool isCCTxNotarizedConfirmed(uint256 txid);
|
||||
bool komodo_txnotarizedconfirmed(uint256 txid);
|
||||
// CCtx
|
||||
bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey);
|
||||
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret);
|
||||
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr);
|
||||
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#define EVAL_LOTTO 0xe9
|
||||
|
||||
bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
UniValue LottoInfo(uint256 lottoid);
|
||||
UniValue LottoList();
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define EVAL_REWARDS 0xe5
|
||||
#define REWARDSCC_MAXAPR (COIN * 25)
|
||||
|
||||
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
UniValue RewardsInfo(uint256 rewardid);
|
||||
UniValue RewardsList();
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "CCinclude.h"
|
||||
#include "key_io.h"
|
||||
|
||||
/*
|
||||
FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and the opreturn.
|
||||
@@ -348,7 +349,7 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
|
||||
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));
|
||||
threshold = total/maxinputs;
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > maxutxos )
|
||||
maxutxos = maxinputs;
|
||||
sum = 0;
|
||||
|
||||
@@ -13,11 +13,20 @@
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#include "CCinclude.h"
|
||||
|
||||
/*
|
||||
CCutils has low level functions that are universally useful for all contracts.
|
||||
*/
|
||||
#include "CCinclude.h"
|
||||
#include "komodo_structs.h"
|
||||
|
||||
#ifdef TESTMODE
|
||||
#define MIN_NON_NOTARIZED_CONFIRMS 2
|
||||
#else
|
||||
#define MIN_NON_NOTARIZED_CONFIRMS 101
|
||||
#endif // TESTMODE
|
||||
int32_t komodo_dpowconfs(int32_t height,int32_t numconfs);
|
||||
struct komodo_state *komodo_stateptr(char *symbol,char *dest);
|
||||
extern uint32_t KOMODO_DPOWCONFS;
|
||||
|
||||
void endiancpy(uint8_t *dest,uint8_t *src,int32_t len)
|
||||
{
|
||||
@@ -198,6 +207,48 @@ bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool GetCCParams(Eval* eval, const CTransaction &tx, uint32_t nIn,
|
||||
CTransaction &txOut, std::vector<std::vector<unsigned char>> &preConditions, std::vector<std::vector<unsigned char>> ¶ms)
|
||||
{
|
||||
uint256 blockHash;
|
||||
|
||||
if (myGetTransaction(tx.vin[nIn].prevout.hash, txOut, blockHash) && txOut.vout.size() > tx.vin[nIn].prevout.n)
|
||||
{
|
||||
CBlockIndex index;
|
||||
if (eval->GetBlock(blockHash, index))
|
||||
{
|
||||
// read preconditions
|
||||
CScript subScript = CScript();
|
||||
preConditions.clear();
|
||||
if (txOut.vout[tx.vin[nIn].prevout.n].scriptPubKey.IsPayToCryptoCondition(&subScript, preConditions))
|
||||
{
|
||||
// read any available parameters in the output transaction
|
||||
params.clear();
|
||||
if (tx.vout.size() > 0 && tx.vout[tx.vout.size() - 1].scriptPubKey.IsOpReturn())
|
||||
{
|
||||
if (tx.vout[tx.vout.size() - 1].scriptPubKey.GetOpretData(params) && params.size() == 1)
|
||||
{
|
||||
CScript scr = CScript(params[0].begin(), params[0].end());
|
||||
|
||||
// printf("Script decoding inner:\n%s\nouter:\n%s\n", scr.ToString().c_str(), tx.vout[tx.vout.size() - 1].scriptPubKey.ToString().c_str());
|
||||
|
||||
if (!scr.GetPushedData(scr.begin(), params))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
//fprintf(stderr,"ExtractDestination failed\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool pubkey2addr(char *destaddr,uint8_t *pubkey33)
|
||||
{
|
||||
std::vector<uint8_t>pk; int32_t i;
|
||||
@@ -368,9 +419,9 @@ bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> param
|
||||
cp->unspendableaddr2[0] = cp->unspendableaddr3[0] = 0;
|
||||
if ( paramsNull.size() != 0 ) // Don't expect params
|
||||
return eval->Invalid("Cannot have params");
|
||||
else if ( ctx.vout.size() == 0 )
|
||||
return eval->Invalid("no-vouts");
|
||||
else if ( (*cp->validate)(cp,eval,ctx) != 0 )
|
||||
//else if ( ctx.vout.size() == 0 ) // spend can go to z-addresses
|
||||
// return eval->Invalid("no-vouts");
|
||||
else if ( (*cp->validate)(cp,eval,ctx,nIn) != 0 )
|
||||
{
|
||||
//fprintf(stderr,"done CC %02x\n",cp->evalcode);
|
||||
//cp->prevtxid = txid;
|
||||
@@ -394,29 +445,60 @@ int64_t CCduration(int32_t &numblocks,uint256 txid)
|
||||
//fprintf(stderr,"CCduration no hashBlock for txid %s\n",uint256_str(str,txid));
|
||||
return(0);
|
||||
}
|
||||
else if ( (pindex= mapBlockIndex[hashBlock]) == 0 || (txtime= pindex->nTime) == 0 || (txheight= pindex->nHeight) <= 0 )
|
||||
else if ( (pindex= komodo_getblockindex(hashBlock)) == 0 || (txtime= pindex->nTime) == 0 || (txheight= pindex->GetHeight()) <= 0 )
|
||||
{
|
||||
fprintf(stderr,"CCduration no txtime %u or txheight.%d %p for txid %s\n",txtime,txheight,pindex,uint256_str(str,txid));
|
||||
return(0);
|
||||
}
|
||||
else if ( (pindex= chainActive.LastTip()) == 0 || pindex->nTime < txtime || pindex->nHeight <= txheight )
|
||||
else if ( (pindex= chainActive.LastTip()) == 0 || pindex->nTime < txtime || pindex->GetHeight() <= txheight )
|
||||
{
|
||||
if ( pindex->nTime < txtime )
|
||||
fprintf(stderr,"CCduration backwards timestamps %u %u for txid %s hts.(%d %d)\n",(uint32_t)pindex->nTime,txtime,uint256_str(str,txid),txheight,(int32_t)pindex->nHeight);
|
||||
fprintf(stderr,"CCduration backwards timestamps %u %u for txid %s hts.(%d %d)\n",(uint32_t)pindex->nTime,txtime,uint256_str(str,txid),txheight,(int32_t)pindex->GetHeight());
|
||||
return(0);
|
||||
}
|
||||
numblocks = (pindex->nHeight - txheight);
|
||||
numblocks = (pindex->GetHeight() - txheight);
|
||||
duration = (pindex->nTime - txtime);
|
||||
//fprintf(stderr,"duration %d (%u - %u) numblocks %d (%d - %d)\n",(int32_t)duration,(uint32_t)pindex->nTime,txtime,numblocks,pindex->nHeight,txheight);
|
||||
//fprintf(stderr,"duration %d (%u - %u) numblocks %d (%d - %d)\n",(int32_t)duration,(uint32_t)pindex->nTime,txtime,numblocks,pindex->GetHeight(),txheight);
|
||||
return(duration);
|
||||
}
|
||||
|
||||
bool isCCTxNotarizedConfirmed(uint256 txid)
|
||||
bool komodo_txnotarizedconfirmed(uint256 txid)
|
||||
{
|
||||
int32_t confirms;
|
||||
char str[65];
|
||||
uint32_t confirms,notarized=0,txheight;
|
||||
CTransaction tx;
|
||||
uint256 hashBlock;
|
||||
CBlockIndex *pindex;
|
||||
char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp;
|
||||
|
||||
CCduration(confirms,txid);
|
||||
if (confirms >= MIN_NOTARIZATION_CONFIRMS)
|
||||
if ( myGetTransaction(txid,tx,hashBlock) == 0 )
|
||||
{
|
||||
fprintf(stderr,"komodo_txnotarizedconfirmed cant find txid %s\n",txid.ToString().c_str());
|
||||
return(0);
|
||||
}
|
||||
else if ( hashBlock == zeroid )
|
||||
{
|
||||
fprintf(stderr,"komodo_txnotarizedconfirmed no hashBlock for txid %s\n",txid.ToString().c_str());
|
||||
return(0);
|
||||
}
|
||||
else if ( (pindex= mapBlockIndex[hashBlock]) == 0 || (txheight= pindex->GetHeight()) <= 0 )
|
||||
{
|
||||
fprintf(stderr,"komodo_txnotarizedconfirmed no txheight.%d %p for txid %s\n",txheight,pindex,txid.ToString().c_str());
|
||||
return(0);
|
||||
}
|
||||
else if ( (pindex= chainActive.LastTip()) == 0 || pindex->GetHeight() < txheight )
|
||||
{
|
||||
fprintf(stderr,"komodo_txnotarizedconfirmed backwards heights for txid %s hts.(%d %d)\n",txid.ToString().c_str(),txheight,(int32_t)pindex->GetHeight());
|
||||
return(0);
|
||||
}
|
||||
confirms=1 + pindex->GetHeight() - txheight;
|
||||
if ((sp= komodo_stateptr(symbol,dest)) != 0 && (notarized=sp->NOTARIZED_HEIGHT) > 0 && txheight > sp->NOTARIZED_HEIGHT) notarized=0;
|
||||
#ifdef TESTMODE
|
||||
notarized=0;
|
||||
#endif //TESTMODE
|
||||
if (notarized>0 && confirms > 1)
|
||||
return (true);
|
||||
else if (notarized==0 && confirms >= MIN_NON_NOTARIZED_CONFIRMS)
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey]
|
||||
*/
|
||||
|
||||
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
static uint256 zero;
|
||||
CTxDestination address; CTransaction vinTx,createTx; uint256 hashBlock,assetid,assetid2; int32_t i,starti,numvins,numvouts,preventCCvins,preventCCvouts; int64_t remaining_price,nValue,assetoshis,outputs,inputs,tmpprice,totalunits,ignore; std::vector<uint8_t> origpubkey,tmporigpubkey,ignorepubkey; uint8_t funcid; char destaddr[64],origaddr[64],CCaddr[64];
|
||||
|
||||
@@ -70,7 +70,7 @@ bool AuctionExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransactio
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval;
|
||||
return(false); // reject any auction CC for now
|
||||
@@ -150,7 +150,8 @@ int64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu
|
||||
|
||||
std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_AUCTION);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -170,7 +171,8 @@ std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount)
|
||||
|
||||
std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_AUCTION);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -190,7 +192,8 @@ std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid)
|
||||
|
||||
std::string AuctionPost(uint64_t txfee,uint256 itemhash,int64_t minbid,char *title,char *description)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Auctionpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Auctionpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_AUCTION);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "cc/utils.h"
|
||||
#include "primitives/transaction.h"
|
||||
|
||||
int32_t komodo_nextheight();
|
||||
|
||||
std::vector<CC*> BetProtocol::PlayerConditions()
|
||||
{
|
||||
@@ -53,7 +54,7 @@ CC* BetProtocol::MakeDisputeCond()
|
||||
*/
|
||||
CMutableTransaction BetProtocol::MakeSessionTx(CAmount spendFee)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
CC *disputeCond = MakeDisputeCond();
|
||||
mtx.vout.push_back(CTxOut(spendFee, CCPubKey(disputeCond)));
|
||||
@@ -70,7 +71,7 @@ CMutableTransaction BetProtocol::MakeSessionTx(CAmount spendFee)
|
||||
|
||||
CMutableTransaction BetProtocol::MakeDisputeTx(uint256 signedSessionTxHash, uint256 vmResultHash)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
CC *disputeCond = MakeDisputeCond();
|
||||
mtx.vin.push_back(CTxIn(signedSessionTxHash, 0, CScript()));
|
||||
@@ -84,7 +85,7 @@ CMutableTransaction BetProtocol::MakeDisputeTx(uint256 signedSessionTxHash, uint
|
||||
CMutableTransaction BetProtocol::MakePostEvidenceTx(uint256 signedSessionTxHash,
|
||||
int playerIdx, std::vector<unsigned char> state)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
mtx.vin.push_back(CTxIn(signedSessionTxHash, playerIdx+1, CScript()));
|
||||
mtx.vout.push_back(CTxOut(0, CScript() << OP_RETURN << state));
|
||||
@@ -115,7 +116,7 @@ CC* BetProtocol::MakePayoutCond(uint256 signedSessionTxHash)
|
||||
|
||||
CMutableTransaction BetProtocol::MakeStakeTx(CAmount totalPayout, uint256 signedSessionTxHash)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
CC *payoutCond = MakePayoutCond(signedSessionTxHash);
|
||||
mtx.vout.push_back(CTxOut(totalPayout, CCPubKey(payoutCond)));
|
||||
@@ -128,7 +129,7 @@ CMutableTransaction BetProtocol::MakeStakeTx(CAmount totalPayout, uint256 signed
|
||||
CMutableTransaction BetProtocol::MakeAgreePayoutTx(std::vector<CTxOut> payouts,
|
||||
uint256 signedStakeTxHash)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
mtx.vin.push_back(CTxIn(signedStakeTxHash, 0, CScript()));
|
||||
mtx.vout = payouts;
|
||||
return mtx;
|
||||
@@ -138,7 +139,7 @@ CMutableTransaction BetProtocol::MakeAgreePayoutTx(std::vector<CTxOut> payouts,
|
||||
CMutableTransaction BetProtocol::MakeImportPayoutTx(std::vector<CTxOut> payouts,
|
||||
CTransaction signedDisputeTx, uint256 signedStakeTxHash, MoMProof momProof)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
mtx.vin.push_back(CTxIn(signedStakeTxHash, 0, CScript()));
|
||||
mtx.vout = payouts;
|
||||
CScript proofData;
|
||||
@@ -263,7 +264,7 @@ bool Eval::DisputePayout(AppVM &vm, std::vector<uint8_t> params, const CTransact
|
||||
if (!GetTxConfirmed(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlock))
|
||||
return Error("couldnt-get-parent");
|
||||
|
||||
if (GetCurrentHeight() < sessionBlock.nHeight + waitBlocks)
|
||||
if (GetCurrentHeight() < sessionBlock.GetHeight() + waitBlocks)
|
||||
return Invalid("dispute-too-soon"); // Not yet
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
uint256 notarisationHash;
|
||||
ADD_SERIALIZE_METHODS;
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(branch);
|
||||
READWRITE(notarisationHash);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ bool ChannelsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransacti
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numpayments,p1,param1; bool retval;
|
||||
uint256 txid,hashblock,p3,param3,opentxid,tmp_txid,genhashchain,hashchain;
|
||||
@@ -199,7 +199,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
//vout.3: normal output of payment amount to receiver pubkey
|
||||
//vout.n-2: normal change
|
||||
//vout.n-1: opreturn - 'P' opentxid senderspubkey receiverspubkey depth numpayments secret
|
||||
if (isCCTxNotarizedConfirmed(opentxid) == 0)
|
||||
if (komodo_txnotarizedconfirmed(opentxid) == 0)
|
||||
return eval->Invalid("channelOpen is not yet confirmed(notarised)!");
|
||||
else if ( IsCCInput(tx.vin[0].scriptSig) != 0 )
|
||||
return eval->Invalid("vin.0 is normal for channelPayment!");
|
||||
@@ -261,7 +261,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
//vout.2: CC vout marker to receiver pubkey
|
||||
//vout.n-2: normal change
|
||||
//vout.n-1: opreturn - 'C' opentxid senderspubkey receiverspubkey 0 0 0
|
||||
if (isCCTxNotarizedConfirmed(opentxid) == 0)
|
||||
if (komodo_txnotarizedconfirmed(opentxid) == 0)
|
||||
return eval->Invalid("channelOpen is not yet confirmed(notarised)!");
|
||||
else if ( IsCCInput(tx.vin[0].scriptSig) != 0 )
|
||||
return eval->Invalid("vin.0 is normal for channelClose!");
|
||||
@@ -304,9 +304,9 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
//vout.2: normal output of CC input to senders pubkey
|
||||
//vout.n-2: normal change
|
||||
//vout.n-1: opreturn - 'R' opentxid senderspubkey receiverspubkey numpayments payment closetxid
|
||||
if (isCCTxNotarizedConfirmed(opentxid) == 0)
|
||||
if (komodo_txnotarizedconfirmed(opentxid) == 0)
|
||||
return eval->Invalid("channelOpen is not yet confirmed(notarised)!");
|
||||
else if (isCCTxNotarizedConfirmed(param3) == 0)
|
||||
else if (komodo_txnotarizedconfirmed(param3) == 0)
|
||||
return eval->Invalid("channelClose is not yet confirmed(notarised)!");
|
||||
else if ( IsCCInput(tx.vin[0].scriptSig) != 0 )
|
||||
return eval->Invalid("vin.0 is normal for channelRefund!");
|
||||
@@ -430,7 +430,8 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
|
||||
|
||||
std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment)
|
||||
{
|
||||
CMutableTransaction mtx; uint8_t hash[32],hashdest[32]; uint64_t funds; int32_t i; uint256 hashchain,entropy,hentropy;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
uint8_t hash[32],hashdest[32]; uint64_t funds; int32_t i; uint256 hashchain,entropy,hentropy;
|
||||
CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
|
||||
if ( numpayments <= 0 || payment <= 0 || numpayments > CHANNELS_MAXPAYMENTS )
|
||||
@@ -464,7 +465,8 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64
|
||||
|
||||
std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,srcpub,destpub; uint256 txid,hashchain,gensecret,hashblock,entropy,hentropy,prevtxid,param3;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,srcpub,destpub; uint256 txid,hashchain,gensecret,hashblock,entropy,hentropy,prevtxid,param3;
|
||||
struct CCcontract_info *cp,C; int32_t i,funcid,prevdepth,numvouts,numpayments,totalnumpayments;
|
||||
int64_t payment,change,funds,param2;
|
||||
uint8_t hash[32],hashdest[32];
|
||||
@@ -479,7 +481,7 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
|
||||
fprintf(stderr, "invalid channel open txid\n");
|
||||
return ("");
|
||||
}
|
||||
if (AddNormalinputs(mtx,mypk,2*txfee,1) > 0)
|
||||
if (AddNormalinputs(mtx,mypk,2*txfee,3) > 0)
|
||||
{
|
||||
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && (change=funds-amount-txfee)>=0)
|
||||
{
|
||||
@@ -569,7 +571,8 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
|
||||
|
||||
std::string ChannelClose(uint64_t txfee,uint256 opentxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,srcpub,destpub; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,srcpub,destpub; struct CCcontract_info *cp,C;
|
||||
CTransaction channelOpenTx;
|
||||
uint256 hashblock,tmp_txid,prevtxid,hashchain;
|
||||
int32_t numvouts,numpayments;
|
||||
@@ -595,7 +598,7 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid)
|
||||
fprintf(stderr,"cannot close, you are not channel owner\n");
|
||||
return("");
|
||||
}
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
|
||||
{
|
||||
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && funds-txfee>0)
|
||||
{
|
||||
@@ -616,7 +619,8 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid)
|
||||
|
||||
std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; int64_t funds,payment,param2;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; struct CCcontract_info *cp,C; int64_t funds,payment,param2;
|
||||
int32_t i,numpayments,numvouts,param1;
|
||||
uint256 hashchain,hashblock,txid,prevtxid,param3,entropy,hentropy,secret;
|
||||
CTransaction channelOpenTx,channelCloseTx,prevTx;
|
||||
@@ -658,7 +662,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
|
||||
fprintf(stderr,"cannot refund, you are not the channel owenr\n");
|
||||
return("");
|
||||
}
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
|
||||
{
|
||||
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && funds-txfee>0)
|
||||
{
|
||||
|
||||
2
src/cc/dapps/makedapps
Executable file
2
src/cc/dapps/makedapps
Executable file
@@ -0,0 +1,2 @@
|
||||
gcc -o oraclefeed cc/dapps/oraclefeed.c -lm
|
||||
gcc -o zmigrate cc/dapps/zmigrate.c -lm
|
||||
@@ -328,13 +328,18 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char
|
||||
{
|
||||
sprintf(cmdstr,"%s %s %s %s %s %s > %s\n",REFCOIN_CLI,method,arg0,arg1,arg2,arg3,fname);
|
||||
printf("ref.(%s) REFCOIN_CLI (%s)\n",refcoin,cmdstr);
|
||||
}
|
||||
}
|
||||
#ifdef TESTMODE
|
||||
fprintf(stderr,"cmd: %s\n",cmdstr);
|
||||
#endif // TESTMODE
|
||||
system(cmdstr);
|
||||
*retstrp = 0;
|
||||
if ( (jsonstr= filestr(&fsize,fname)) != 0 )
|
||||
{
|
||||
jsonstr[strlen(jsonstr)-1]='\0';
|
||||
//fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr);
|
||||
#ifdef TESTMODE
|
||||
fprintf(stderr,"jsonstr.(%s)\n",jsonstr);
|
||||
#endif // TESTMODE
|
||||
if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 )
|
||||
*retstrp = jsonstr;
|
||||
else free(jsonstr);
|
||||
@@ -483,6 +488,22 @@ cJSON *get_gatewayspending(char *refcoin,char *acname,char *bindtxidstr)
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *get_gatewaysprocessed(char *refcoin,char *acname,char *bindtxidstr)
|
||||
{
|
||||
cJSON *retjson; char *retstr;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysprocessed",bindtxidstr,refcoin,"","")) != 0 )
|
||||
{
|
||||
//printf("pending.(%s)\n",jprint(retjson,0));
|
||||
return(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"%s get_gatewaysprocessed.(%s) error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *get_rawmempool(char *refcoin,char *acname)
|
||||
{
|
||||
cJSON *retjson; char *retstr;
|
||||
@@ -550,10 +571,12 @@ int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* comp
|
||||
return (res);
|
||||
}
|
||||
|
||||
void importaddress(char *refcoin,char *acname,char *depositaddr)
|
||||
void importaddress(char *refcoin,char *acname,char *depositaddr, char *label,int rescan)
|
||||
{
|
||||
cJSON *retjson; char *retstr;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"importaddress",depositaddr,"","true","")) != 0 )
|
||||
cJSON *retjson; char *retstr; char rescanstr[10];
|
||||
if (rescan) strcpy(rescanstr,"true");
|
||||
else strcpy(rescanstr,"false");
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"importaddress",depositaddr,label,rescanstr,"")) != 0 )
|
||||
{
|
||||
printf("importaddress.(%s)\n",jprint(retjson,0));
|
||||
free_json(retjson);
|
||||
@@ -610,7 +633,7 @@ cJSON *getinputarray(int64_t *totalp,cJSON *unspents,int64_t required)
|
||||
return(vins);
|
||||
}
|
||||
|
||||
char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signeraddr,char *withdrawaddr,int64_t satoshis)
|
||||
char *createrawtx(char *refcoin,char *acname,char *depositaddr,char *withdrawaddr,char *txidaddr,int64_t satoshis)
|
||||
{
|
||||
char *retstr,*retstr2,array[128],*txstr = 0; cJSON *retjson2,*retjson,*vins,*vouts; int64_t txfee,total,change = 0;
|
||||
if ( strcmp(refcoin,"BTC") == 0 )
|
||||
@@ -618,7 +641,7 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
|
||||
else txfee = 10000;
|
||||
if ( satoshis < txfee )
|
||||
{
|
||||
printf("createmultisig satoshis %.8f < txfee %.8f\n",(double)satoshis/SATOSHIDEN,(double)txfee/SATOSHIDEN);
|
||||
printf("createrawtx satoshis %.8f < txfee %.8f\n",(double)satoshis/SATOSHIDEN,(double)txfee/SATOSHIDEN);
|
||||
return(0);
|
||||
}
|
||||
satoshis -= txfee;
|
||||
@@ -631,8 +654,9 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
|
||||
if ( total >= satoshis )
|
||||
{
|
||||
vouts = cJSON_CreateObject();
|
||||
jaddnum(vouts,withdrawaddr,(double)satoshis/SATOSHIDEN);
|
||||
if ( total > satoshis+txfee )
|
||||
jaddnum(vouts,withdrawaddr,(double)(satoshis-2*txfee)/SATOSHIDEN);
|
||||
jaddnum(vouts,txidaddr,(double)txfee/SATOSHIDEN);
|
||||
if ( total > satoshis)
|
||||
{
|
||||
change = (total - satoshis);
|
||||
jaddnum(vouts,depositaddr,(double)change/SATOSHIDEN);
|
||||
@@ -645,29 +669,30 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
|
||||
sprintf(argB,"\'%s\'",tmpB);
|
||||
if ( (retjson2= get_komodocli(refcoin,&txstr,acname,"createrawtransaction",argA,argB,"","")) != 0 )
|
||||
{
|
||||
printf("createmultisig: unexpected JSON2.(%s)\n",jprint(retjson2,0));
|
||||
printf("createrawtx: unexpected JSON2.(%s)\n",jprint(retjson2,0));
|
||||
free_json(retjson2);
|
||||
}
|
||||
else if ( txstr == 0 )
|
||||
printf("createmultisig: null txstr and JSON2\n");
|
||||
printf("createrawtx: null txstr and JSON2\n");
|
||||
free(tmpA);
|
||||
free(tmpB);
|
||||
free(argA);
|
||||
free(argB);
|
||||
}
|
||||
else printf("not enough funds to create withdraw tx\n");
|
||||
}
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
printf("createmultisig: unexpected null JSON, retstr.(%s)\n",retstr);
|
||||
printf("createrawtx: unexpected null JSON, retstr.(%s)\n",retstr);
|
||||
free(retstr);
|
||||
}
|
||||
else printf("createmultisig: null retstr and JSON\n");
|
||||
else printf("createrawtx: null retstr and JSON\n");
|
||||
return(txstr);
|
||||
}
|
||||
|
||||
cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx)
|
||||
cJSON *addsignature(char *refcoin,char *acname,char *rawtx)
|
||||
{
|
||||
char *retstr,*hexstr; cJSON *retjson;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"signrawtransaction",rawtx,"","","")) != 0 )
|
||||
@@ -681,6 +706,11 @@ cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx
|
||||
}
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
printf("error parsing signrawtransaction.(%s)\n",retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -696,6 +726,11 @@ char *get_gatewaysmultisig(char *refcoin,char *acname,char *txidaddr,int32_t *K)
|
||||
*K=jint(retjson,"number_of_signs");
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
printf("error parsing gatewaysmultisig.(%s)\n",retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(hex);
|
||||
}
|
||||
|
||||
@@ -714,11 +749,27 @@ bits256 gatewayspartialsign(char *refcoin,char *acname,bits256 txid,char *hex)
|
||||
return (zeroid);
|
||||
}
|
||||
|
||||
void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bits256 cointxid)
|
||||
void gatewayscompletesigning(char *refcoin,char *acname,bits256 withtxid,char *coin,char *hex)
|
||||
{
|
||||
char str[65],str2[65],*retstr; cJSON *retjson;
|
||||
printf("spend %s %s/v2 as marker\n",acname,bits256_str(str,withtxid));
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysmarkdone",bits256_str(str,withtxid),coin,bits256_str(str2,cointxid),"")) != 0 )
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayscompletesigning",bits256_str(str,withtxid),coin,hex,"")) != 0 )
|
||||
{
|
||||
komodobroadcast(refcoin,acname,retjson);
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
printf("error parsing gatewayscompletesigning.(%s)\n",retstr);
|
||||
free(retstr);
|
||||
}
|
||||
}
|
||||
|
||||
void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin)
|
||||
{
|
||||
char str[65],str2[65],*retstr; cJSON *retjson;
|
||||
printf("spend %s %s/v2 as marker\n",acname,bits256_str(str,withtxid));
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysmarkdone",bits256_str(str,withtxid),coin,"","")) != 0 )
|
||||
{
|
||||
komodobroadcast(refcoin,acname,retjson);
|
||||
free_json(retjson);
|
||||
@@ -771,6 +822,22 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M
|
||||
else return(0);
|
||||
}
|
||||
|
||||
int32_t tx_notarizedconfirmed(char *refcoin,char *acname,bits256 txid)
|
||||
{
|
||||
char *retstr,str[65]; cJSON *retjson; int32_t result;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"txnotarizedconfirmed",bits256_str(str,txid),"","","")) != 0 )
|
||||
{
|
||||
if (is_cJSON_True(jobj(retjson,"result")) != 0 ) result=1;
|
||||
else result=0;
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
printf("error parsing txnotarizedconfirmed.(%s)\n",retstr);
|
||||
free(retstr);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinaddr)
|
||||
{
|
||||
cJSON *txobj,*vouts,*vout,*vins,*vin,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numarray,retval = 0, hasvout=0;
|
||||
@@ -788,8 +855,7 @@ int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinadd
|
||||
{
|
||||
addr = jstri(addresses,j);
|
||||
if ( strcmp(addr,coinaddr) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"found %s in %s v%d\n",coinaddr,bits256_str(str,txid),i);
|
||||
{
|
||||
hasvout = 1;
|
||||
break;
|
||||
}
|
||||
@@ -798,23 +864,44 @@ int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinadd
|
||||
}
|
||||
if (hasvout==1) break;
|
||||
}
|
||||
}
|
||||
// if (hasvout==1 && (vins=jarray(&numarray,txobj,"vin"))!=0)
|
||||
// {
|
||||
// for (int i=0;i<numarray;i++)
|
||||
// {
|
||||
// if ((vin=jitem(vins,i))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
|
||||
// {
|
||||
// retval=1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
free_json(txobj);
|
||||
}
|
||||
return(hasvout);
|
||||
}
|
||||
|
||||
|
||||
int32_t markerexists(char *refcoin,char *acname,char *coinaddr)
|
||||
{
|
||||
cJSON *array; int32_t i,n,num=0; bits256 txid;
|
||||
if ( (array= get_addressutxos(refcoin,acname,coinaddr)) != 0 )
|
||||
{
|
||||
num=cJSON_GetArraySize(array);
|
||||
free_json(array);
|
||||
}
|
||||
if ( num == 0 )
|
||||
{
|
||||
if ( (array= get_rawmempool(refcoin,acname)) != 0 )
|
||||
{
|
||||
if ( (n= cJSON_GetArraySize(array)) != 0 )
|
||||
{
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
txid = jbits256i(array,i);
|
||||
if ( tx_has_voutaddress(refcoin,acname,txid,coinaddr) > 0 )
|
||||
{
|
||||
num = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free_json(array);
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"Num=%d\n",num);
|
||||
return(num);
|
||||
|
||||
}
|
||||
int32_t markerfromthisnodeorunconfirmed(char *refcoin,char *acname,char *coinaddr)
|
||||
{
|
||||
cJSON *array,*item,*rawtx,*vins,*vin; bits256 txid,tmptxid; int32_t i,n,m,num=0; char *retstr;
|
||||
@@ -887,54 +974,42 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
|
||||
//process item.0 {"txid":"10ec8f4dad6903df6b249b361b879ac77b0617caad7629b97e10f29fa7e99a9b","txidaddr":"RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz","withdrawaddr":"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc","amount":"1.00000000","depositaddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","signeraddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj"}
|
||||
if ( (txidaddr= jstr(item,"txidaddr")) != 0 && (withdrawaddr= jstr(item,"withdrawaddr")) != 0 && (depositaddr= jstr(item,"depositaddr")) != 0 && (signeraddr= jstr(item,"signeraddr")) != 0 )
|
||||
{
|
||||
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && markerfromthisnodeorunconfirmed("KMD",acname,txidaddr) == 0)
|
||||
{
|
||||
// the actual withdraw
|
||||
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && is_cJSON_True(jobj(item,"confirmed_or_notarized")) != 0 && markerfromthisnodeorunconfirmed("KMD",acname,txidaddr) == 0)
|
||||
{
|
||||
if ( strcmp(depositaddr,signeraddr) == 0 )
|
||||
{
|
||||
txid= sendtoaddress("KMD",acname,txidaddr,10000);
|
||||
if (bits256_nonz(txid) != 0)
|
||||
{
|
||||
rawtx = createrawtx(refcoin,"",depositaddr,withdrawaddr,txidaddr,satoshis);
|
||||
if ( rawtx != 0 )
|
||||
{
|
||||
cointxid = sendtoaddress(refcoin,"",withdrawaddr,satoshis);
|
||||
if ( bits256_nonz(cointxid) != 0)
|
||||
{
|
||||
fprintf(stderr,"withdraw %s %s %s %.8f processed\n",refcoin,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
|
||||
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
|
||||
processed++;
|
||||
if ( (clijson= addsignature(refcoin,"",rawtx)) != 0 && is_cJSON_True(jobj(clijson,"complete")) != 0)
|
||||
{
|
||||
gatewayscompletesigning("KMD",acname,origtxid,refcoin,jstr(clijson,"hex"));
|
||||
fprintf(stderr,"withdraw %.8f %s to %s processed\n",(double)satoshis/SATOSHIDEN,refcoin,withdrawaddr);
|
||||
free_json(clijson);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"ERROR withdraw %s %s %s %.8f processed\n",refcoin,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"ERROR sending withdraw marker %s %s to %s %.8f processed\n",refcoin,bits256_str(str,cointxid),txidaddr,(double)10000/SATOSHIDEN);
|
||||
}
|
||||
processed++;
|
||||
free(rawtx);
|
||||
} else fprintf(stderr,"couldnt create rawtx\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (rawtx= get_gatewaysmultisig(refcoin,acname,txidaddr,&K)) == 0)
|
||||
{
|
||||
rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis);
|
||||
rawtx = createrawtx(refcoin,"",depositaddr,withdrawaddr,txidaddr,satoshis);
|
||||
}
|
||||
if ( rawtx != 0 )
|
||||
{
|
||||
if ( (clijson= addmultisignature(refcoin,"",signeraddr,rawtx)) != 0 )
|
||||
if ( (clijson= addsignature(refcoin,"",rawtx)) != 0 )
|
||||
{
|
||||
if ( is_cJSON_True(jobj(clijson,"complete")) != 0 )
|
||||
{
|
||||
cointxid = komodobroadcast(refcoin,"",clijson);
|
||||
if ( bits256_nonz(cointxid) != 0 )
|
||||
{
|
||||
fprintf(stderr,"withdraw %s M.%d N.%d %s %s %.8f processed\n",refcoin,M,N,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
|
||||
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
|
||||
}
|
||||
{
|
||||
gatewayscompletesigning("KMD",acname,origtxid,refcoin,jstr(clijson,"hex"));
|
||||
fprintf(stderr,"withdraw %.8f %s M.%d N.%d to %s processed\n",(double)satoshis/SATOSHIDEN,refcoin,M,N,withdrawaddr);
|
||||
}
|
||||
else if ( jint(clijson,"partialtx") != 0 )
|
||||
{
|
||||
txid=gatewayspartialsign(refcoin,acname,origtxid,jstr(clijson,"hex"));
|
||||
fprintf(stderr,"%d of %d partialtx %s sent\n",K+1,N,bits256_str(str,txid));
|
||||
fprintf(stderr,"%d sign(s) %dof%d partialtx %s sent\n",K+1,M,N,bits256_str(str,txid));
|
||||
}
|
||||
free_json(clijson);
|
||||
}
|
||||
@@ -949,6 +1024,33 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
|
||||
}
|
||||
free_json(retjson);
|
||||
}
|
||||
if ( (retjson= get_gatewaysprocessed("KMD",acname,bindtxidstr)) != 0 )
|
||||
{
|
||||
if ( jint(retjson,"queueflag") != 0 && (coinstr= jstr(retjson,"coin")) != 0 && strcmp(coinstr,refcoin) == 0 )
|
||||
{
|
||||
if ( (pending=jarray(&n,retjson,"processed")) != 0 )
|
||||
{
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
item = jitem(pending,i);
|
||||
origtxid = jbits256(item,"txid");
|
||||
txidaddr = jstr(item,"withdrawtxidaddr");
|
||||
if (validateaddress(refcoin,"",txidaddr,"iswatchonly")==0 && validateaddress(refcoin,"",txidaddr,"ismine")==0)
|
||||
importaddress(refcoin,"",txidaddr,jstr(item,"txid"),0);
|
||||
if ( txidaddr != 0 && markerexists(refcoin,"",txidaddr)==0)
|
||||
{
|
||||
cointxid = komodobroadcast(refcoin,"",item);
|
||||
if ( bits256_nonz(cointxid) != 0 )
|
||||
{
|
||||
withdrawaddr = jstr(item,"withdrawaddr");
|
||||
fprintf(stderr,"withdraw %.8f %s to %s - %s broadcasted on %s\n",(double)satoshis/SATOSHIDEN,refcoin,withdrawaddr,bits256_str(str,cointxid),refcoin);
|
||||
gatewaysmarkdone("KMD",acname,origtxid,refcoin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t get_oracledata(char *refcoin,char *acname,int32_t prevheight,char *hexstr,int32_t maxsize,char *format)
|
||||
@@ -1050,9 +1152,9 @@ int32_t main(int32_t argc,char **argv)
|
||||
printf("cant find bindtxid.(%s)\n",bindtxidstr);
|
||||
exit(0);
|
||||
}
|
||||
if (validateaddress(refcoin,"",depositaddr,"iswatchonly")==0)
|
||||
if (validateaddress(refcoin,"",depositaddr,"iswatchonly")==0 && validateaddress(refcoin,"",depositaddr,"ismine")==0)
|
||||
{
|
||||
if (M==N==1) importaddress(refcoin,"",depositaddr);
|
||||
if (M==N==1) importaddress(refcoin,"",depositaddr,bindtxidstr,0);
|
||||
else addmultisigaddress(refcoin,"",M,pubkeys,bindtxidstr);
|
||||
}
|
||||
if (pubkeys!=0) free(pubkeys);
|
||||
@@ -1075,9 +1177,9 @@ int32_t main(int32_t argc,char **argv)
|
||||
{
|
||||
prevheight = height;
|
||||
acheight = get_coinheight(refcoin,"");
|
||||
printf("%s ht.%d <- %s\n",refcoin,height,hexstr);
|
||||
update_gatewayspending(refcoin,acname,bindtxidstr,M,N);
|
||||
}
|
||||
printf("%s ht.%d <- %s\n",refcoin,height,hexstr);
|
||||
update_gatewayspending(refcoin,acname,bindtxidstr,M,N);
|
||||
}
|
||||
free_json(clijson2);
|
||||
}
|
||||
else if ( retstr2 != 0 )
|
||||
@@ -1085,7 +1187,7 @@ int32_t main(int32_t argc,char **argv)
|
||||
printf("error parsing oraclesdata.(%s)\n",retstr2);
|
||||
free(retstr2);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
956
src/cc/dapps/zmigrate.c
Normal file
956
src/cc/dapps/zmigrate.c
Normal file
@@ -0,0 +1,956 @@
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2018 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <memory.h>
|
||||
#include "cJSON.c"
|
||||
|
||||
/*
|
||||
z_migrate: the purpose of z_migrate is to make converting of all sprout outputs into sapling. the usage would be for the user to specify a sapling address and call z_migrate zsaddr, until it returns that there is nothing left to be done.
|
||||
|
||||
its main functionality is quite similar to a z_mergetoaddress ANY_ZADDR -> onetime_taddr followed by a z_sendmany onetime_taddr -> zsaddr
|
||||
|
||||
since the z_mergetoaddress will take time, it would just queue up an async operation. When it starts, it should see if there are any onetime_taddr with 10000.0001 funds in it, that is a signal for it to do the sapling tx and it can just do that without async as it is fast enough, especially with a taddr input. Maybe it limits itself to one, or it does all possible taddr -> sapling as fast as it can. either is fine as it will be called over and over anyway.
|
||||
|
||||
It might be that there is nothing to do, but some operations are pending. in that case it would return such a status. as soon as the operation finishes, there would be more work to do.
|
||||
|
||||
the amount sent to the taddr, should be 10000.0001
|
||||
|
||||
The GUI or user would be expected to generate a sapling address and then call z_migrate saplingaddr in a loop, until it returns that it is all done. this loop should pause for 10 seconds or so, if z_migrate is just waiting for opid to complete.
|
||||
*/
|
||||
|
||||
bits256 zeroid;
|
||||
|
||||
char hexbyte(int32_t c)
|
||||
{
|
||||
c &= 0xf;
|
||||
if ( c < 10 )
|
||||
return('0'+c);
|
||||
else if ( c < 16 )
|
||||
return('a'+c-10);
|
||||
else return(0);
|
||||
}
|
||||
|
||||
int32_t _unhex(char c)
|
||||
{
|
||||
if ( c >= '0' && c <= '9' )
|
||||
return(c - '0');
|
||||
else if ( c >= 'a' && c <= 'f' )
|
||||
return(c - 'a' + 10);
|
||||
else if ( c >= 'A' && c <= 'F' )
|
||||
return(c - 'A' + 10);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int32_t is_hexstr(char *str,int32_t n)
|
||||
{
|
||||
int32_t i;
|
||||
if ( str == 0 || str[0] == 0 )
|
||||
return(0);
|
||||
for (i=0; str[i]!=0; i++)
|
||||
{
|
||||
if ( n > 0 && i >= n )
|
||||
break;
|
||||
if ( _unhex(str[i]) < 0 )
|
||||
break;
|
||||
}
|
||||
if ( n == 0 )
|
||||
return(i);
|
||||
return(i == n);
|
||||
}
|
||||
|
||||
int32_t unhex(char c)
|
||||
{
|
||||
int32_t hex;
|
||||
if ( (hex= _unhex(c)) < 0 )
|
||||
{
|
||||
//printf("unhex: illegal hexchar.(%c)\n",c);
|
||||
}
|
||||
return(hex);
|
||||
}
|
||||
|
||||
unsigned char _decode_hex(char *hex) { return((unhex(hex[0])<<4) | unhex(hex[1])); }
|
||||
|
||||
int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex)
|
||||
{
|
||||
int32_t adjust,i = 0;
|
||||
//printf("decode.(%s)\n",hex);
|
||||
if ( is_hexstr(hex,n) <= 0 )
|
||||
{
|
||||
memset(bytes,0,n);
|
||||
return(n);
|
||||
}
|
||||
if ( hex[n-1] == '\n' || hex[n-1] == '\r' )
|
||||
hex[--n] = 0;
|
||||
if ( hex[n-1] == '\n' || hex[n-1] == '\r' )
|
||||
hex[--n] = 0;
|
||||
if ( n == 0 || (hex[n*2+1] == 0 && hex[n*2] != 0) )
|
||||
{
|
||||
if ( n > 0 )
|
||||
{
|
||||
bytes[0] = unhex(hex[0]);
|
||||
printf("decode_hex n.%d hex[0] (%c) -> %d hex.(%s) [n*2+1: %d] [n*2: %d %c] len.%ld\n",n,hex[0],bytes[0],hex,hex[n*2+1],hex[n*2],hex[n*2],(long)strlen(hex));
|
||||
}
|
||||
bytes++;
|
||||
hex++;
|
||||
adjust = 1;
|
||||
} else adjust = 0;
|
||||
if ( n > 0 )
|
||||
{
|
||||
for (i=0; i<n; i++)
|
||||
bytes[i] = _decode_hex(&hex[i*2]);
|
||||
}
|
||||
//bytes[i] = 0;
|
||||
return(n + adjust);
|
||||
}
|
||||
|
||||
int32_t init_hexbytes_noT(char *hexbytes,unsigned char *message,long len)
|
||||
{
|
||||
int32_t i;
|
||||
if ( len <= 0 )
|
||||
{
|
||||
hexbytes[0] = 0;
|
||||
return(1);
|
||||
}
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
hexbytes[i*2] = hexbyte((message[i]>>4) & 0xf);
|
||||
hexbytes[i*2 + 1] = hexbyte(message[i] & 0xf);
|
||||
//printf("i.%d (%02x) [%c%c]\n",i,message[i],hexbytes[i*2],hexbytes[i*2+1]);
|
||||
}
|
||||
hexbytes[len*2] = 0;
|
||||
//printf("len.%ld\n",len*2+1);
|
||||
return((int32_t)len*2+1);
|
||||
}
|
||||
|
||||
long _stripwhite(char *buf,int accept)
|
||||
{
|
||||
int32_t i,j,c;
|
||||
if ( buf == 0 || buf[0] == 0 )
|
||||
return(0);
|
||||
for (i=j=0; buf[i]!=0; i++)
|
||||
{
|
||||
buf[j] = c = buf[i];
|
||||
if ( c == accept || (c != ' ' && c != '\n' && c != '\r' && c != '\t' && c != '\b') )
|
||||
j++;
|
||||
}
|
||||
buf[j] = 0;
|
||||
return(j);
|
||||
}
|
||||
|
||||
char *clonestr(char *str)
|
||||
{
|
||||
char *clone;
|
||||
if ( str == 0 || str[0]==0)
|
||||
{
|
||||
printf("warning cloning nullstr.%p\n",str);
|
||||
//#ifdef __APPLE__
|
||||
// while ( 1 ) sleep(1);
|
||||
//#endif
|
||||
str = (char *)"<nullstr>";
|
||||
}
|
||||
clone = (char *)malloc(strlen(str)+16);
|
||||
strcpy(clone,str);
|
||||
return(clone);
|
||||
}
|
||||
|
||||
int32_t safecopy(char *dest,char *src,long len)
|
||||
{
|
||||
int32_t i = -1;
|
||||
if ( src != 0 && dest != 0 && src != dest )
|
||||
{
|
||||
if ( dest != 0 )
|
||||
memset(dest,0,len);
|
||||
for (i=0; i<len&&src[i]!=0; i++)
|
||||
dest[i] = src[i];
|
||||
if ( i == len )
|
||||
{
|
||||
printf("safecopy: %s too long %ld\n",src,len);
|
||||
//printf("divide by zero! %d\n",1/zeroval());
|
||||
#ifdef __APPLE__
|
||||
//getchar();
|
||||
#endif
|
||||
return(-1);
|
||||
}
|
||||
dest[i] = 0;
|
||||
}
|
||||
return(i);
|
||||
}
|
||||
|
||||
char *bits256_str(char hexstr[65],bits256 x)
|
||||
{
|
||||
init_hexbytes_noT(hexstr,x.bytes,sizeof(x));
|
||||
return(hexstr);
|
||||
}
|
||||
|
||||
int64_t conv_floatstr(char *numstr)
|
||||
{
|
||||
double val,corr;
|
||||
val = atof(numstr);
|
||||
corr = (val < 0.) ? -0.50000000001 : 0.50000000001;
|
||||
return((int64_t)(val * SATOSHIDEN + corr));
|
||||
}
|
||||
|
||||
char *nonportable_path(char *str)
|
||||
{
|
||||
int32_t i;
|
||||
for (i=0; str[i]!=0; i++)
|
||||
if ( str[i] == '/' )
|
||||
str[i] = '\\';
|
||||
return(str);
|
||||
}
|
||||
|
||||
char *portable_path(char *str)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return(nonportable_path(str));
|
||||
#else
|
||||
#ifdef __PNACL
|
||||
/*int32_t i,n;
|
||||
if ( str[0] == '/' )
|
||||
return(str);
|
||||
else
|
||||
{
|
||||
n = (int32_t)strlen(str);
|
||||
for (i=n; i>0; i--)
|
||||
str[i] = str[i-1];
|
||||
str[0] = '/';
|
||||
str[n+1] = 0;
|
||||
}*/
|
||||
#endif
|
||||
return(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep)
|
||||
{
|
||||
FILE *fp;
|
||||
long filesize,buflen = *allocsizep;
|
||||
uint8_t *buf = *bufp;
|
||||
*lenp = 0;
|
||||
if ( (fp= fopen(portable_path(fname),"rb")) != 0 )
|
||||
{
|
||||
fseek(fp,0,SEEK_END);
|
||||
filesize = ftell(fp);
|
||||
if ( filesize == 0 )
|
||||
{
|
||||
fclose(fp);
|
||||
*lenp = 0;
|
||||
printf("loadfile null size.(%s)\n",fname);
|
||||
return(0);
|
||||
}
|
||||
if ( filesize > buflen )
|
||||
{
|
||||
*allocsizep = filesize;
|
||||
*bufp = buf = (uint8_t *)realloc(buf,(long)*allocsizep+64);
|
||||
}
|
||||
rewind(fp);
|
||||
if ( buf == 0 )
|
||||
printf("Null buf ???\n");
|
||||
else
|
||||
{
|
||||
if ( fread(buf,1,(long)filesize,fp) != (unsigned long)filesize )
|
||||
printf("error reading filesize.%ld\n",(long)filesize);
|
||||
buf[filesize] = 0;
|
||||
}
|
||||
fclose(fp);
|
||||
*lenp = filesize;
|
||||
//printf("loaded.(%s)\n",buf);
|
||||
} //else printf("OS_loadfile couldnt load.(%s)\n",fname);
|
||||
return(buf);
|
||||
}
|
||||
|
||||
void *filestr(long *allocsizep,char *_fname)
|
||||
{
|
||||
long filesize = 0; char *fname,*buf = 0; void *retptr;
|
||||
*allocsizep = 0;
|
||||
fname = malloc(strlen(_fname)+1);
|
||||
strcpy(fname,_fname);
|
||||
retptr = loadfile(fname,(uint8_t **)&buf,&filesize,allocsizep);
|
||||
free(fname);
|
||||
return(retptr);
|
||||
}
|
||||
|
||||
char *send_curl(char *url,char *fname)
|
||||
{
|
||||
long fsize; char curlstr[1024];
|
||||
sprintf(curlstr,"curl --url \"%s\" > %s",url,fname);
|
||||
system(curlstr);
|
||||
return(filestr(&fsize,fname));
|
||||
}
|
||||
|
||||
cJSON *get_urljson(char *url,char *fname)
|
||||
{
|
||||
char *jsonstr; cJSON *json = 0;
|
||||
if ( (jsonstr= send_curl(url,fname)) != 0 )
|
||||
{
|
||||
//printf("(%s) -> (%s)\n",url,jsonstr);
|
||||
json = cJSON_Parse(jsonstr);
|
||||
free(jsonstr);
|
||||
}
|
||||
return(json);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// start of dapp
|
||||
//////////////////////////////////////////////
|
||||
|
||||
char *REFCOIN_CLI;
|
||||
|
||||
cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char *arg0,char *arg1,char *arg2,char *arg3)
|
||||
{
|
||||
long fsize; cJSON *retjson = 0; char cmdstr[32768],*jsonstr,fname[256];
|
||||
sprintf(fname,"/tmp/zmigrate.%s",method);
|
||||
if ( acname[0] != 0 )
|
||||
{
|
||||
if ( refcoin[0] != 0 && strcmp(refcoin,"KMD") != 0 )
|
||||
printf("unexpected: refcoin.(%s) acname.(%s)\n",refcoin,acname);
|
||||
sprintf(cmdstr,"./komodo-cli -ac_name=%s %s %s %s %s %s > %s\n",acname,method,arg0,arg1,arg2,arg3,fname);
|
||||
}
|
||||
else if ( strcmp(refcoin,"KMD") == 0 )
|
||||
sprintf(cmdstr,"./komodo-cli %s %s %s %s %s > %s\n",method,arg0,arg1,arg2,arg3,fname);
|
||||
else if ( REFCOIN_CLI != 0 && REFCOIN_CLI[0] != 0 )
|
||||
{
|
||||
sprintf(cmdstr,"%s %s %s %s %s %s > %s\n",REFCOIN_CLI,method,arg0,arg1,arg2,arg3,fname);
|
||||
//printf("ref.(%s) REFCOIN_CLI (%s)\n",refcoin,cmdstr);
|
||||
}
|
||||
system(cmdstr);
|
||||
*retstrp = 0;
|
||||
if ( (jsonstr= filestr(&fsize,fname)) != 0 )
|
||||
{
|
||||
jsonstr[strlen(jsonstr)-1]='\0';
|
||||
//fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr);
|
||||
if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 )
|
||||
*retstrp = jsonstr;
|
||||
else free(jsonstr);
|
||||
}
|
||||
return(retjson);
|
||||
}
|
||||
|
||||
bits256 komodobroadcast(char *refcoin,char *acname,cJSON *hexjson)
|
||||
{
|
||||
char *hexstr,*retstr,str[65]; cJSON *retjson; bits256 txid;
|
||||
memset(txid.bytes,0,sizeof(txid));
|
||||
if ( (hexstr= jstr(hexjson,"hex")) != 0 )
|
||||
{
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"sendrawtransaction",hexstr,"","","")) != 0 )
|
||||
{
|
||||
//fprintf(stderr,"broadcast.(%s)\n",jprint(retjson,0));
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
if ( strlen(retstr) >= 64 )
|
||||
{
|
||||
retstr[64] = 0;
|
||||
decode_hex(txid.bytes,32,retstr);
|
||||
}
|
||||
fprintf(stderr,"broadcast %s txid.(%s)\n",strlen(acname)>0?acname:refcoin,bits256_str(str,txid));
|
||||
free(retstr);
|
||||
}
|
||||
}
|
||||
return(txid);
|
||||
}
|
||||
|
||||
bits256 sendtoaddress(char *refcoin,char *acname,char *destaddr,int64_t satoshis)
|
||||
{
|
||||
char numstr[32],*retstr,str[65]; cJSON *retjson; bits256 txid;
|
||||
memset(txid.bytes,0,sizeof(txid));
|
||||
sprintf(numstr,"%.8f",(double)satoshis/SATOSHIDEN);
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"sendtoaddress",destaddr,numstr,"","")) != 0 )
|
||||
{
|
||||
fprintf(stderr,"unexpected sendrawtransaction json.(%s)\n",jprint(retjson,0));
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
if ( strlen(retstr) >= 64 )
|
||||
{
|
||||
retstr[64] = 0;
|
||||
decode_hex(txid.bytes,32,retstr);
|
||||
}
|
||||
fprintf(stderr,"sendtoaddress %s %.8f txid.(%s)\n",destaddr,(double)satoshis/SATOSHIDEN,bits256_str(str,txid));
|
||||
free(retstr);
|
||||
}
|
||||
return(txid);
|
||||
}
|
||||
|
||||
int32_t get_coinheight(char *refcoin,char *acname)
|
||||
{
|
||||
cJSON *retjson; char *retstr; int32_t height=0;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockchaininfo","","","","")) != 0 )
|
||||
{
|
||||
height = jint(retjson,"blocks");
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"%s get_coinheight.(%s) error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(height);
|
||||
}
|
||||
|
||||
bits256 get_coinblockhash(char *refcoin,char *acname,int32_t height)
|
||||
{
|
||||
cJSON *retjson; char *retstr,heightstr[32]; bits256 hash;
|
||||
memset(hash.bytes,0,sizeof(hash));
|
||||
sprintf(heightstr,"%d",height);
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockhash",heightstr,"","","")) != 0 )
|
||||
{
|
||||
fprintf(stderr,"unexpected blockhash json.(%s)\n",jprint(retjson,0));
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
if ( strlen(retstr) >= 64 )
|
||||
{
|
||||
retstr[64] = 0;
|
||||
decode_hex(hash.bytes,32,retstr);
|
||||
}
|
||||
free(retstr);
|
||||
}
|
||||
return(hash);
|
||||
}
|
||||
|
||||
bits256 get_coinmerkleroot(char *refcoin,char *acname,bits256 blockhash)
|
||||
{
|
||||
cJSON *retjson; char *retstr,str[65]; bits256 merkleroot;
|
||||
memset(merkleroot.bytes,0,sizeof(merkleroot));
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockheader",bits256_str(str,blockhash),"","","")) != 0 )
|
||||
{
|
||||
merkleroot = jbits256(retjson,"merkleroot");
|
||||
//fprintf(stderr,"got merkleroot.(%s)\n",bits256_str(str,merkleroot));
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"%s %s get_coinmerkleroot error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(merkleroot);
|
||||
}
|
||||
|
||||
int32_t get_coinheader(char *refcoin,char *acname,bits256 *blockhashp,bits256 *merklerootp,int32_t prevheight)
|
||||
{
|
||||
int32_t height = 0; char str[65];
|
||||
if ( prevheight == 0 )
|
||||
height = get_coinheight(refcoin,acname) - 20;
|
||||
else height = prevheight + 1;
|
||||
if ( height > 0 )
|
||||
{
|
||||
*blockhashp = get_coinblockhash(refcoin,acname,height);
|
||||
if ( bits256_nonz(*blockhashp) != 0 )
|
||||
{
|
||||
*merklerootp = get_coinmerkleroot(refcoin,acname,*blockhashp);
|
||||
if ( bits256_nonz(*merklerootp) != 0 )
|
||||
return(height);
|
||||
}
|
||||
}
|
||||
memset(blockhashp,0,sizeof(*blockhashp));
|
||||
memset(merklerootp,0,sizeof(*merklerootp));
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *get_rawmempool(char *refcoin,char *acname)
|
||||
{
|
||||
cJSON *retjson; char *retstr;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getrawmempool","","","","")) != 0 )
|
||||
{
|
||||
//printf("mempool.(%s)\n",jprint(retjson,0));
|
||||
return(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"get_rawmempool.(%s) error.(%s)\n",acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *get_addressutxos(char *refcoin,char *acname,char *coinaddr)
|
||||
{
|
||||
cJSON *retjson; char *retstr,jsonbuf[256];
|
||||
if ( refcoin[0] != 0 && strcmp(refcoin,"KMD") != 0 )
|
||||
printf("warning: assumes %s has addressindex enabled\n",refcoin);
|
||||
sprintf(jsonbuf,"{\\\"addresses\\\":[\\\"%s\\\"]}",coinaddr);
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getaddressutxos",jsonbuf,"","","")) != 0 )
|
||||
{
|
||||
//printf("addressutxos.(%s)\n",jprint(retjson,0));
|
||||
return(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"get_addressutxos.(%s) error.(%s)\n",acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid)
|
||||
{
|
||||
cJSON *retjson; char *retstr,str[65];
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getrawtransaction",bits256_str(str,txid),"1","","")) != 0 )
|
||||
{
|
||||
return(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"get_rawtransaction.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *get_listunspent(char *refcoin,char *acname)
|
||||
{
|
||||
cJSON *retjson; char *retstr,str[65];
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent","","","","")) != 0 )
|
||||
{
|
||||
return(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"get_listunspent.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *z_listunspent(char *refcoin,char *acname)
|
||||
{
|
||||
cJSON *retjson; char *retstr,str[65];
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_listunspent","","","","")) != 0 )
|
||||
{
|
||||
return(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"z_listunspent.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *z_listoperationids(char *refcoin,char *acname)
|
||||
{
|
||||
cJSON *retjson; char *retstr,str[65];
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_listoperationids","","","","")) != 0 )
|
||||
{
|
||||
return(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"z_listoperationids.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *z_getoperationstatus(char *refcoin,char *acname,char *opid)
|
||||
{
|
||||
cJSON *retjson; char *retstr,str[65],params[512];
|
||||
sprintf(params,"'[\"%s\"]'",opid);
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getoperationstatus",params,"","","")) != 0 )
|
||||
{
|
||||
//printf("got status (%s)\n",jprint(retjson,0));
|
||||
return(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"z_getoperationstatus.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
cJSON *z_getoperationresult(char *refcoin,char *acname,char *opid)
|
||||
{
|
||||
cJSON *retjson; char *retstr,str[65],params[512];
|
||||
sprintf(params,"'[\"%s\"]'",opid);
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getoperationresult",params,"","","")) != 0 )
|
||||
{
|
||||
return(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"z_getoperationresult.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* compare)
|
||||
{
|
||||
cJSON *retjson; char *retstr; int32_t res=0;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 )
|
||||
{
|
||||
if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1;
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"validateaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
int32_t z_validateaddress(char *refcoin,char *acname,char *depositaddr, char *compare)
|
||||
{
|
||||
cJSON *retjson; char *retstr; int32_t res=0;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_validateaddress",depositaddr,"","","")) != 0 )
|
||||
{
|
||||
if (is_cJSON_True(jobj(retjson,compare)) != 0 )
|
||||
res=1;
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"z_validateaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
int64_t z_getbalance(char *refcoin,char *acname,char *coinaddr)
|
||||
{
|
||||
cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getbalance",coinaddr,"","","")) != 0 )
|
||||
{
|
||||
fprintf(stderr,"z_getbalance.(%s) %s returned json!\n",refcoin,acname);
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
amount = atof(retstr) * SATOSHIDEN;
|
||||
sprintf(cmpstr,"%.8f",dstr(amount));
|
||||
if ( strcmp(retstr,cmpstr) != 0 )
|
||||
amount++;
|
||||
//printf("retstr %s -> %.8f\n",retstr,dstr(amount));
|
||||
free(retstr);
|
||||
}
|
||||
return (amount);
|
||||
}
|
||||
|
||||
int32_t getnewaddress(char *coinaddr,char *refcoin,char *acname)
|
||||
{
|
||||
cJSON *retjson; char *retstr; int64_t amount=0;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getnewaddress","","","","")) != 0 )
|
||||
{
|
||||
fprintf(stderr,"getnewaddress.(%s) %s returned json!\n",refcoin,acname);
|
||||
free_json(retjson);
|
||||
return(-1);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
strcpy(coinaddr,retstr);
|
||||
free(retstr);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
int64_t find_onetime_amount(char *coinstr,char *coinaddr)
|
||||
{
|
||||
cJSON *array,*item; int32_t i,n; char *addr; int64_t amount = 0;
|
||||
coinaddr[0] = 0;
|
||||
if ( (array= get_listunspent(coinstr,"")) != 0 )
|
||||
{
|
||||
if ( (n= cJSON_GetArraySize(array)) > 0 )
|
||||
{
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
item = jitem(array,i);
|
||||
if ( (addr= jstr(item,"address")) != 0 )
|
||||
{
|
||||
strcpy(coinaddr,addr);
|
||||
amount = z_getbalance(coinstr,"",coinaddr);
|
||||
printf("found address.(%s) with amount %.8f\n",coinaddr,dstr(amount));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free_json(array);
|
||||
}
|
||||
return(amount);
|
||||
}
|
||||
|
||||
int64_t find_sprout_amount(char *coinstr,char *zcaddr)
|
||||
{
|
||||
cJSON *array,*item; int32_t i,n; char *addr; int64_t amount = 0;
|
||||
zcaddr[0] = 0;
|
||||
if ( (array= z_listunspent(coinstr,"")) != 0 )
|
||||
{
|
||||
if ( (n= cJSON_GetArraySize(array)) > 0 )
|
||||
{
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
item = jitem(array,i);
|
||||
if ( (addr= jstr(item,"address")) != 0 && addr[0] == 'z' && addr[1] == 'c' )
|
||||
{
|
||||
strcpy(zcaddr,addr);
|
||||
amount = z_getbalance(coinstr,"",zcaddr);
|
||||
printf("found address.(%s) with amount %.8f\n",zcaddr,dstr(amount));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free_json(array);
|
||||
}
|
||||
return(amount);
|
||||
}
|
||||
|
||||
void importaddress(char *refcoin,char *acname,char *depositaddr)
|
||||
{
|
||||
cJSON *retjson; char *retstr;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"importaddress",depositaddr,"","true","")) != 0 )
|
||||
{
|
||||
printf("importaddress.(%s)\n",jprint(retjson,0));
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"importaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t z_sendmany(char *opidstr,char *coinstr,char *acname,char *srcaddr,char *destaddr,int64_t amount)
|
||||
{
|
||||
cJSON *retjson; char *retstr,params[1024],addr[128];
|
||||
sprintf(params,"'[{\"address\":\"%s\",\"amount\":%.8f}]'",destaddr,dstr(amount));
|
||||
sprintf(addr,"\"%s\"",srcaddr);
|
||||
if ( (retjson= get_komodocli(coinstr,&retstr,acname,"z_sendmany",addr,params,"","")) != 0 )
|
||||
{
|
||||
printf("unexpected json z_sendmany.(%s)\n",jprint(retjson,0));
|
||||
free_json(retjson);
|
||||
return(-1);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"z_sendmany.(%s) -> opid.(%s)\n",coinstr,retstr);
|
||||
strcpy(opidstr,retstr);
|
||||
free(retstr);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t empty_mempool(char *coinstr,char *acname)
|
||||
{
|
||||
cJSON *array; int32_t n;
|
||||
if ( (array= get_rawmempool(coinstr,acname)) != 0 )
|
||||
{
|
||||
if ( (n= cJSON_GetArraySize(array)) > 0 )
|
||||
return(0);
|
||||
free_json(array);
|
||||
return(1);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
cJSON *getinputarray(int64_t *totalp,cJSON *unspents,int64_t required)
|
||||
{
|
||||
cJSON *vin,*item,*vins = cJSON_CreateArray(); int32_t i,n,v; int64_t satoshis; bits256 txid;
|
||||
*totalp = 0;
|
||||
if ( (n= cJSON_GetArraySize(unspents)) > 0 )
|
||||
{
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
item = jitem(unspents,i);
|
||||
satoshis = jdouble(item,"amount") * SATOSHIDEN;
|
||||
txid = jbits256(item,"txid");
|
||||
v = jint(item,"vout");
|
||||
if ( bits256_nonz(txid) != 0 )
|
||||
{
|
||||
vin = cJSON_CreateObject();
|
||||
jaddbits256(vin,"txid",txid);
|
||||
jaddnum(vin,"vout",v);
|
||||
jaddi(vins,vin);
|
||||
*totalp += satoshis;
|
||||
if ( (*totalp) >= required )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(vins);
|
||||
}
|
||||
|
||||
int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinaddr)
|
||||
{
|
||||
cJSON *txobj,*vouts,*vout,*vins,*vin,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numarray,retval = 0, hasvout=0;
|
||||
if ( (txobj= get_rawtransaction(refcoin,acname,txid)) != 0 )
|
||||
{
|
||||
if ( (vouts= jarray(&numarray,txobj,"vout")) != 0 )
|
||||
{
|
||||
for (i=0; i<numarray; i++)
|
||||
{
|
||||
if ((vout = jitem(vouts,i)) !=0 && (sobj= jobj(vout,"scriptPubKey")) != 0 )
|
||||
{
|
||||
if ( (addresses= jarray(&n,sobj,"addresses")) != 0 )
|
||||
{
|
||||
for (j=0; j<n; j++)
|
||||
{
|
||||
addr = jstri(addresses,j);
|
||||
if ( strcmp(addr,coinaddr) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"found %s in %s v%d\n",coinaddr,bits256_str(str,txid),i);
|
||||
hasvout = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasvout==1) break;
|
||||
}
|
||||
}
|
||||
// if (hasvout==1 && (vins=jarray(&numarray,txobj,"vin"))!=0)
|
||||
// {
|
||||
// for (int i=0;i<numarray;i++)
|
||||
// {
|
||||
// if ((vin=jitem(vins,i))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
|
||||
// {
|
||||
// retval=1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
free_json(txobj);
|
||||
}
|
||||
return(hasvout);
|
||||
}
|
||||
|
||||
int32_t have_pending_opid(char *coinstr,int32_t clearresults)
|
||||
{
|
||||
cJSON *array,*status,*result; int32_t i,n,j,m,pending = 0; char *statusstr;
|
||||
if ( (array= z_listoperationids(coinstr,"")) != 0 )
|
||||
{
|
||||
if ( (n= cJSON_GetArraySize(array)) > 0 )
|
||||
{
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
if ( (status= z_getoperationstatus(coinstr,"",jstri(array,i))) != 0 )
|
||||
{
|
||||
if ( (m= cJSON_GetArraySize(status)) > 0 )
|
||||
{
|
||||
for (j=0; j<m; j++)
|
||||
{
|
||||
if ( (statusstr= jstr(jitem(status,j),"status")) != 0 )
|
||||
{
|
||||
if ( strcmp(statusstr,"executing") == 0 )
|
||||
{
|
||||
pending++;
|
||||
//printf("pending.%d\n",pending);
|
||||
}
|
||||
else if ( clearresults != 0 )
|
||||
{
|
||||
if ( (result= z_getoperationresult(coinstr,"",jstri(array,i))) != 0 )
|
||||
{
|
||||
free_json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free_json(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
free_json(array);
|
||||
}
|
||||
return(pending);
|
||||
}
|
||||
|
||||
int32_t main(int32_t argc,char **argv)
|
||||
{
|
||||
char buf[1024],*zsaddr,*coinstr;
|
||||
if ( argc != 3 )
|
||||
{
|
||||
printf("argc needs to be 3\n");
|
||||
return(-1);
|
||||
}
|
||||
if ( strcmp(argv[1],"KMD") == 0 )
|
||||
{
|
||||
REFCOIN_CLI = "./komodo-cli";
|
||||
coinstr = clonestr("KMD");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf,"./komodo-cli -ac_name=%s",argv[1]);
|
||||
REFCOIN_CLI = clonestr(buf);
|
||||
coinstr = clonestr(argv[1]);
|
||||
}
|
||||
if ( argv[2][0] != 'z' || argv[2][1] != 's' )
|
||||
{
|
||||
printf("invalid sapling address (%s)\n",argv[2]);
|
||||
return(-2);
|
||||
}
|
||||
if ( z_validateaddress(coinstr,"",argv[2],"ismine") == 0 )
|
||||
{
|
||||
printf("invalid sapling address (%s)\n",argv[2]);
|
||||
return(-3);
|
||||
}
|
||||
zsaddr = clonestr(argv[2]);
|
||||
printf("%s: %s %s\n",REFCOIN_CLI,coinstr,zsaddr);
|
||||
uint32_t lastopid; char coinaddr[64],zcaddr[128],opidstr[128]; int32_t finished; int64_t amount,stdamount,txfee;
|
||||
stdamount = 10000 * SATOSHIDEN;
|
||||
txfee = 10000;
|
||||
again:
|
||||
printf("start processing zmigrate\n");
|
||||
lastopid = (uint32_t)time(NULL);
|
||||
finished = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( have_pending_opid(coinstr,0) != 0 )
|
||||
{
|
||||
sleep(60);
|
||||
continue;
|
||||
}
|
||||
if ( (amount= find_onetime_amount(coinstr,coinaddr)) > txfee )
|
||||
{
|
||||
// find taddr with funds and send all to zsaddr
|
||||
z_sendmany(opidstr,coinstr,"",coinaddr,zsaddr,amount-txfee);
|
||||
lastopid = (uint32_t)time(NULL);
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
if ( (amount= find_sprout_amount(coinstr,zcaddr)) > txfee )
|
||||
{
|
||||
// generate taddr, send max of 10000.0001
|
||||
if ( amount > stdamount+txfee )
|
||||
amount = stdamount + txfee;
|
||||
if ( getnewaddress(coinaddr,coinstr,"") == 0 )
|
||||
{
|
||||
z_sendmany(opidstr,coinstr,"",zcaddr,coinaddr,amount-txfee);
|
||||
lastopid = (uint32_t)time(NULL);
|
||||
} else printf("couldnt getnewaddress!\n");
|
||||
sleep(30);
|
||||
continue;
|
||||
}
|
||||
if ( time(NULL) > lastopid+600 )
|
||||
break;
|
||||
}
|
||||
sleep(3);
|
||||
printf("%s %s ALLDONE! taddr %.8f sprout %.8f mempool empty.%d\n",coinstr,zsaddr,dstr(find_onetime_amount(coinstr,coinaddr)),dstr(find_sprout_amount(coinstr,zcaddr)),empty_mempool(coinstr,""));
|
||||
sleep(3);
|
||||
if ( find_onetime_amount(coinstr,coinaddr) == 0 && find_sprout_amount(coinstr,zcaddr) == 0 )
|
||||
{
|
||||
printf("about to purge all opid results!. ctrl-C to abort, <enter> to proceed\n");
|
||||
getchar();
|
||||
have_pending_opid(coinstr,1);
|
||||
} else goto again;
|
||||
return(0);
|
||||
}
|
||||
@@ -245,9 +245,12 @@ bool mySenddicetransaction(std::string res,uint256 entropyused,int32_t entropyvo
|
||||
{
|
||||
RelayTransaction(tx);
|
||||
fprintf(stderr,"rebroadcast.%c and clear [%d] and broadcast entropyused.%s bettxid.%s -> %s\n",funcid,i,entropyused.GetHex().c_str(),bettxid.GetHex().c_str(),tx.GetHash().GetHex().c_str());
|
||||
if ( ptr->rawtx.empty() == 0 )
|
||||
ptr->rawtx.clear();
|
||||
ptr->txid = zeroid;
|
||||
if ( ptr != 0 )
|
||||
{
|
||||
if ( ptr->rawtx.empty() == 0 )
|
||||
ptr->rawtx.clear();
|
||||
ptr->txid = zeroid;
|
||||
}
|
||||
//fprintf(stderr,"error adding funcid.%c E.%s bet.%s -> %s to mempool, probably Disable replacement feature size.%d\n",funcid,entropyused.GetHex().c_str(),bettxid.GetHex().c_str(),tx.GetHash().GetHex().c_str(),(int32_t)ptr->rawtx.size());
|
||||
}
|
||||
} else fprintf(stderr,"error duplicate entropyused different bettxid\n");
|
||||
@@ -540,10 +543,9 @@ CPubKey DiceFundingPk(CScript scriptPubKey)
|
||||
CPubKey pk; uint8_t *ptr,*dest; int32_t i;
|
||||
if ( scriptPubKey.size() == 35 )
|
||||
{
|
||||
ptr = (uint8_t *)scriptPubKey.data();
|
||||
dest = (uint8_t *)pk.begin();
|
||||
for (i=0; i<33; i++)
|
||||
dest[i] = ptr[i+1];
|
||||
dest[i] = scriptPubKey[i+1];
|
||||
} else fprintf(stderr,"DiceFundingPk invalid size.%d\n",(int32_t)scriptPubKey.size());
|
||||
return(pk);
|
||||
}
|
||||
@@ -831,7 +833,7 @@ bool DiceVerifyTimeout(CTransaction &betTx,int32_t timeoutblocks)
|
||||
return(numblocks >= timeoutblocks);
|
||||
}
|
||||
|
||||
bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
uint256 txid,fundingtxid,vinfundingtxid,vinhentropy,vinproof,hashBlock,hash,proof,entropy; int64_t minbet,maxbet,maxodds,timeoutblocks,odds,winnings; uint64_t vinsbits,refsbits=0,sbits,amount,inputs,outputs,txfee=10000; int32_t numvins,entropyvout,numvouts,preventCCvins,preventCCvouts,i,iswin; uint8_t funcid; CScript fundingPubKey; CTransaction fundingTx,vinTx,vinofvinTx; char CCaddr[64];
|
||||
numvins = tx.vin.size();
|
||||
@@ -917,8 +919,8 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
fprintf(stderr,"%s != %s betTx.%s\n",addr0,addr1,uint256_str(str,txid));
|
||||
fprintf(stderr,"entropyTx.%s v%d\n",uint256_str(str,tx.vin[0].prevout.hash),(int32_t)tx.vin[0].prevout.n);
|
||||
fprintf(stderr,"entropyTx vin0 %s v%d\n",uint256_str(str,vinTx.vin[0].prevout.hash),(int32_t)vinTx.vin[0].prevout.n);
|
||||
ptr0 = (uint8_t *)vinofvinTx.vout[vinTx.vin[0].prevout.n].scriptPubKey.data();
|
||||
ptr1 = (uint8_t *)fundingPubKey.data();
|
||||
ptr0 = (uint8_t *)&vinofvinTx.vout[vinTx.vin[0].prevout.n].scriptPubKey[0];
|
||||
ptr1 = (uint8_t *)&fundingPubKey[0];
|
||||
for (i=0; i<vinofvinTx.vout[vinTx.vin[0].prevout.n].scriptPubKey.size(); i++)
|
||||
fprintf(stderr,"%02x",ptr0[i]);
|
||||
fprintf(stderr," script vs ");
|
||||
@@ -972,7 +974,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
return eval->Invalid("vout[0] != inputs-txfee for loss");
|
||||
else if ( tx.vout[2].scriptPubKey != fundingPubKey )
|
||||
{
|
||||
if ( tx.vout[2].scriptPubKey.size() == 0 || ((uint8_t *)tx.vout[2].scriptPubKey.data())[0] != 0x6a )
|
||||
if ( tx.vout[2].scriptPubKey.size() == 0 || tx.vout[2].scriptPubKey[0] != 0x6a )
|
||||
return eval->Invalid("vout[2] not send to fundingPubKey for loss");
|
||||
}
|
||||
iswin = -1;
|
||||
@@ -996,7 +998,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
}
|
||||
else if ( tx.vout[3].scriptPubKey != fundingPubKey )
|
||||
{
|
||||
if ( tx.vout[3].scriptPubKey.size() == 0 || ((uint8_t *)tx.vout[3].scriptPubKey.data())[0] != 0x6a )
|
||||
if ( tx.vout[3].scriptPubKey.size() == 0 || tx.vout[3].scriptPubKey[0] != 0x6a )
|
||||
return eval->Invalid("vout[3] not send to fundingPubKey for win/timeout");
|
||||
}
|
||||
iswin = (funcid == 'W');
|
||||
@@ -1162,8 +1164,8 @@ int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbit
|
||||
Getscriptaddress(addr1,fundingPubKey);
|
||||
if ( strcmp(addr0,addr1) != 0 )
|
||||
{
|
||||
ptr0 = (uint8_t *)vinTx.vout[1].scriptPubKey.data();
|
||||
ptr1 = (uint8_t *)fundingPubKey.data();
|
||||
ptr0 = (uint8_t *)&vinTx.vout[1].scriptPubKey[0];
|
||||
ptr1 = (uint8_t *)&fundingPubKey[0];
|
||||
for (i=0; i<vinTx.vout[1].scriptPubKey.size(); i++)
|
||||
fprintf(stderr,"%02x",ptr0[i]);
|
||||
fprintf(stderr," script vs ");
|
||||
@@ -1187,13 +1189,12 @@ int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbit
|
||||
else
|
||||
{
|
||||
uint8_t *ptr0,*ptr1; int32_t i; char str[65];
|
||||
ptr0 = (uint8_t *)tx.vout[1].scriptPubKey.data();
|
||||
ptr1 = (uint8_t *)fundingPubKey.data();
|
||||
const CScript &s0 = tx.vout[1].scriptPubKey;
|
||||
for (i=0; i<tx.vout[1].scriptPubKey.size(); i++)
|
||||
fprintf(stderr,"%02x",ptr0[i]);
|
||||
fprintf(stderr,"%02x",s0[i]);
|
||||
fprintf(stderr," script vs ");
|
||||
for (i=0; i<fundingPubKey.size(); i++)
|
||||
fprintf(stderr,"%02x",ptr1[i]);
|
||||
fprintf(stderr,"%02x",fundingPubKey[i]);
|
||||
fprintf(stderr," (%c) tx vin.%d fundingPubKey mismatch %s\n",funcid,tx.vin[0].prevout.n,uint256_str(str,tx.vin[0].prevout.hash));
|
||||
}
|
||||
}
|
||||
@@ -1334,7 +1335,8 @@ UniValue DiceList()
|
||||
|
||||
std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks)
|
||||
{
|
||||
CMutableTransaction mtx; uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C;
|
||||
if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || maxodds > 9999 || timeoutblocks < 0 || timeoutblocks > 1440 )
|
||||
{
|
||||
CCerror = "invalid parameter error";
|
||||
@@ -1368,7 +1370,8 @@ std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t
|
||||
|
||||
std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks;
|
||||
if ( amount < 0 )
|
||||
{
|
||||
CCerror = "amount must be positive";
|
||||
@@ -1383,13 +1386,11 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6
|
||||
if ( 0 )
|
||||
{
|
||||
uint8_t *ptr0,*ptr1; int32_t i;
|
||||
ptr0 = (uint8_t *)scriptPubKey.data();
|
||||
ptr1 = (uint8_t *)fundingPubKey.data();
|
||||
for (i=0; i<35; i++)
|
||||
fprintf(stderr,"%02x",ptr0[i]);
|
||||
fprintf(stderr,"%02x",scriptPubKey[i]);
|
||||
fprintf(stderr," script vs ");
|
||||
for (i=0; i<35; i++)
|
||||
fprintf(stderr,"%02x",ptr1[i]);
|
||||
fprintf(stderr,"%02x",fundingPubKey[i]);
|
||||
fprintf(stderr," funding\n");
|
||||
}
|
||||
if ( scriptPubKey == fundingPubKey )
|
||||
@@ -1413,7 +1414,8 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6
|
||||
|
||||
std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds)
|
||||
{
|
||||
CMutableTransaction mtx; CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval,entropyval2; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropytxid2,entropy,hentropy; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval,entropyval2; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropytxid2,entropy,hentropy; struct CCcontract_info *cp,C;
|
||||
if ( bet < 0 )
|
||||
{
|
||||
CCerror = "bet must be positive";
|
||||
@@ -1472,7 +1474,8 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet
|
||||
|
||||
std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyvout,int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout,uint256 vin0txid,int32_t vin0vout)
|
||||
{
|
||||
CMutableTransaction mtx; CScript scriptPubKey,fundingPubKey; CTransaction oldbetTx,betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy,oldbettxid; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs=0,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; int32_t oldentropyvout,retval=0,iswin=0; uint64_t entropyval,sbits;
|
||||
CMutableTransaction savemtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript scriptPubKey,fundingPubKey; CTransaction oldbetTx,betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy,oldbettxid; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs=0,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; int32_t oldentropyvout,retval=0,iswin=0; uint64_t entropyval,sbits;
|
||||
entropyused = zeroid;
|
||||
*resultp = 0;
|
||||
funcid = 0;
|
||||
@@ -1483,9 +1486,9 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
return("");
|
||||
}
|
||||
fundingpk = DiceFundingPk(fundingPubKey);
|
||||
scriptPubKey = CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG;
|
||||
if ( winlosetimeout != 0 ) // must be dealernode
|
||||
{
|
||||
scriptPubKey = CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG;
|
||||
if ( scriptPubKey != fundingPubKey )
|
||||
{
|
||||
//fprintf(stderr,"only dice fund creator can submit winner or loser\n");
|
||||
@@ -1506,7 +1509,7 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
{
|
||||
if ( vin0txid == zeroid || vin0vout < 0 )
|
||||
{
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,1) == 0 ) // must be a single vin!!
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,3) == 0 ) // must be a single vin!!
|
||||
{
|
||||
CCerror = "no txfee inputs for win/lose";
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
@@ -1587,6 +1590,7 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
}
|
||||
CCchange = betTx.vout[0].nValue + betTx.vout[1].nValue;
|
||||
fundsneeded = txfee + (odds+1)*betTx.vout[1].nValue;
|
||||
savemtx = mtx;
|
||||
if ( CCchange >= fundsneeded )
|
||||
CCchange -= fundsneeded;
|
||||
else if ( (inputs= AddDiceInputs(cp,mtx,dicepk,fundsneeded,1,sbits,fundingtxid)) >= fundsneeded )
|
||||
@@ -1596,6 +1600,7 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx = savemtx;
|
||||
if ( (inputs= AddDiceInputs(cp,mtx,dicepk,fundsneeded,60,sbits,fundingtxid)) > 0 )
|
||||
{
|
||||
if ( inputs > fundsneeded )
|
||||
@@ -1621,6 +1626,15 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
//fprintf(stderr,"make tx.%c\n",funcid);
|
||||
if ( funcid == 'L' || funcid == 'W' ) // dealernode only
|
||||
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1);
|
||||
else
|
||||
{
|
||||
if ( scriptPubKey != betTx.vout[2].scriptPubKey )
|
||||
{
|
||||
CCerror = strprintf("can only finish your own bettxid\n");
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
return("");
|
||||
}
|
||||
}
|
||||
*resultp = 1;
|
||||
//char str[65],str2[65];
|
||||
//fprintf(stderr,"iswin.%d house entropy %s vs bettor %s\n",iswin,uint256_str(str,hentropyproof),uint256_str(str2,bettorentropy));
|
||||
@@ -1715,6 +1729,12 @@ double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettx
|
||||
GetCCaddress(cp,coinaddr,dicepk);
|
||||
if ( bettxid == zeroid ) // scan
|
||||
{
|
||||
if ( fundingpk != mypk )
|
||||
{
|
||||
CCerror = "Diceinit error in status, non-dealer must provide bettxid";
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
return(0.);
|
||||
}
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
|
||||
@@ -46,7 +46,7 @@ bool Eval::DisputePayout(AppVM &vm, std::vector<uint8_t> params, const CTransact
|
||||
if (!GetTxConfirmed(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlock))
|
||||
return Error("couldnt-get-parent");
|
||||
|
||||
if (GetCurrentHeight() < sessionBlock.nHeight + waitBlocks)
|
||||
if (GetCurrentHeight() < sessionBlock.GetHeight() + waitBlocks)
|
||||
return Invalid("dispute-too-soon"); // Not yet
|
||||
}
|
||||
|
||||
|
||||
@@ -74,11 +74,11 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
|
||||
switch ( ecode )
|
||||
{
|
||||
case EVAL_IMPORTPAYOUT:
|
||||
return ImportPayout(vparams, txTo, nIn);
|
||||
//return ImportPayout(vparams, txTo, nIn);
|
||||
break;
|
||||
|
||||
case EVAL_IMPORTCOIN:
|
||||
return ImportCoin(vparams, txTo, nIn);
|
||||
//return ImportCoin(vparams, txTo, nIn);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -98,9 +98,10 @@ bool Eval::GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) c
|
||||
|
||||
bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const
|
||||
{
|
||||
if (!myGetTransaction(hash, txOut,hashBlock)) {
|
||||
return(myGetTransaction(hash, txOut,hashBlock));
|
||||
/*if (!myGetTransaction(hash, txOut,hashBlock)) {
|
||||
return(GetTransaction(hash, txOut,hashBlock));
|
||||
} else return(true);
|
||||
} else return(true);*/
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +158,7 @@ bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data)
|
||||
CTransaction notarisationTx;
|
||||
CBlockIndex block;
|
||||
if (!GetTxConfirmed(notaryHash, notarisationTx, block)) return false;
|
||||
if (!CheckNotaryInputs(notarisationTx, block.nHeight, block.nTime)) return false;
|
||||
if (!CheckNotaryInputs(notarisationTx, block.GetHeight(), block.nTime)) return false;
|
||||
if (!ParseNotarisationOpReturn(notarisationTx, data)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
* there should be a code identifying it. For example,
|
||||
* a possible code is EVAL_BITCOIN_SCRIPT, where the entire binary
|
||||
* after the code is interpreted as a bitcoin script.
|
||||
* Verus EVAL_STAKEGUARD is 0x01
|
||||
*/
|
||||
#define FOREACH_EVAL(EVAL) \
|
||||
EVAL(EVAL_IMPORTPAYOUT, 0xe1) \
|
||||
@@ -173,7 +174,7 @@ public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
|
||||
bool IsBack = IsBackNotarisation;
|
||||
if (2 == IsBackNotarisation) IsBack = DetectBackNotarisation(s, ser_action);
|
||||
@@ -269,7 +270,7 @@ public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(VARINT(nIndex));
|
||||
READWRITE(branch);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
|
||||
@@ -146,7 +146,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/maxinputs;
|
||||
threshold = total/(maxinputs+1);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
@@ -174,7 +174,8 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
|
||||
|
||||
std::string FaucetGet(uint64_t txfee)
|
||||
{
|
||||
CMutableTransaction mtx,tmpmtx; CPubKey mypk,faucetpk; int64_t inputs,CCchange=0,nValue=FAUCETSIZE; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,faucetpk; int64_t inputs,CCchange=0,nValue=FAUCETSIZE; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
cp = CCinit(&C,EVAL_FAUCET);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -214,7 +215,8 @@ std::string FaucetGet(uint64_t txfee)
|
||||
|
||||
std::string FaucetFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_FAUCET);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -231,7 +233,8 @@ std::string FaucetFund(uint64_t txfee,int64_t funds)
|
||||
UniValue FaucetInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Faucet"));
|
||||
cp = CCinit(&C,EVAL_FAUCET);
|
||||
|
||||
@@ -72,7 +72,7 @@ bool FSMExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool FSMValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool FSMValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval;
|
||||
return(false); // reject any FSM CC for now
|
||||
@@ -157,7 +157,8 @@ std::string FSMList()
|
||||
|
||||
std::string FSMCreate(uint64_t txfee,std::string name,std::string states)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,fsmpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,fsmpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_FSM);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -177,7 +178,8 @@ std::string FSMCreate(uint64_t txfee,std::string name,std::string states)
|
||||
|
||||
std::string FSMInfo(uint256 fsmtxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,fsmpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,fsmpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_FSM);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
fsmpk = GetUnspendable(cp,0);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -71,7 +71,7 @@ bool HeirExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||
return(false);
|
||||
@@ -143,7 +143,8 @@ int64_t AddHeirInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
|
||||
|
||||
std::string HeirGet(uint64_t txfee,int64_t nValue)
|
||||
{
|
||||
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Heirpk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Heirpk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
cp = CCinit(&C,EVAL_HEIR);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -183,7 +184,8 @@ std::string HeirGet(uint64_t txfee,int64_t nValue)
|
||||
|
||||
std::string HeirFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Heirpk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Heirpk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_HEIR);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -199,8 +201,9 @@ std::string HeirFund(uint64_t txfee,int64_t funds)
|
||||
|
||||
UniValue HeirInfo()
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey Heirpk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CPubKey Heirpk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Heir"));
|
||||
cp = CCinit(&C,EVAL_HEIR);
|
||||
|
||||
@@ -112,7 +112,7 @@ bool LottoExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval;
|
||||
return(false); // reject any lotto CC for now
|
||||
@@ -283,7 +283,8 @@ UniValue LottoList()
|
||||
|
||||
std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t ticketsize,int32_t odds,int32_t firstheight,int32_t period)
|
||||
{
|
||||
CMutableTransaction mtx; uint256 entropy,hentropy; CPubKey mypk,lottopk; uint64_t sbits; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
uint256 entropy,hentropy; CPubKey mypk,lottopk; uint64_t sbits; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_LOTTO);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -301,7 +302,8 @@ std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t tic
|
||||
|
||||
std::string LottoTicket(uint64_t txfee,uint256 lottoid,int64_t numtickets)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,lottopk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,lottopk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_LOTTO);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -321,7 +323,8 @@ std::string LottoTicket(uint64_t txfee,uint256 lottoid,int64_t numtickets)
|
||||
|
||||
std::string LottoWinner(uint64_t txfee)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,lottopk; int64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,lottopk; int64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_LOTTO);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
|
||||
@@ -233,6 +233,10 @@ int64_t OracleDatafee(CScript &scriptPubKey,uint256 oracletxid,CPubKey publisher
|
||||
CCtxidaddr(markeraddr,oracletxid);
|
||||
datafee = OracleCurrentDatafee(oracletxid,markeraddr,publisher);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Could not decode op_ret from transaction %s\nscriptPubKey: %s\n", oracletxid.GetHex().c_str(), oracletx.vout[numvouts-1].scriptPubKey.ToString().c_str());
|
||||
}
|
||||
}
|
||||
return(datafee);
|
||||
}
|
||||
@@ -593,7 +597,7 @@ bool OraclesDataValidate(struct CCcontract_info *cp,Eval* eval,const CTransactio
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
uint256 txid,oracletxid,batontxid; uint64_t txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts; uint8_t *script; std::vector<uint8_t> vopret,data; CScript scriptPubKey; CPubKey publisher;
|
||||
numvins = tx.vin.size();
|
||||
@@ -724,7 +728,8 @@ int64_t LifetimeOraclesFunds(struct CCcontract_info *cp,uint256 oracletxid,CPubK
|
||||
|
||||
std::string OracleCreate(int64_t txfee,std::string name,std::string description,std::string format)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
if ( name.size() > 32 || description.size() > 4096 || format.size() > 4096 )
|
||||
{
|
||||
@@ -735,7 +740,7 @@ std::string OracleCreate(int64_t txfee,std::string name,std::string description,
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Oraclespk = GetUnspendable(cp,0);
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(Oraclespk)) << OP_CHECKSIG));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesCreateOpRet('C',name,description,format)));
|
||||
@@ -745,7 +750,8 @@ std::string OracleCreate(int64_t txfee,std::string name,std::string description,
|
||||
|
||||
std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,markerpubkey,batonpk; struct CCcontract_info *cp,C; char markeraddr[64],batonaddr[64];
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,markerpubkey,batonpk; struct CCcontract_info *cp,C; char markeraddr[64],batonaddr[64];
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -768,13 +774,14 @@ std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee)
|
||||
|
||||
std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; char markeraddr[64];
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; char markeraddr[64];
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
markerpubkey = CCtxidaddr(markeraddr,oracletxid);
|
||||
if ( AddNormalinputs(mtx,mypk,amount + 2*txfee,1) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,amount + 2*txfee,64) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,publisher));
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG));
|
||||
@@ -785,17 +792,20 @@ std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,i
|
||||
|
||||
std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> data)
|
||||
{
|
||||
CMutableTransaction mtx; CScript pubKey; CPubKey mypk,batonpk; int64_t datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid; char coinaddr[64],batonaddr[64]; std::vector <uint8_t> prevdata;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript pubKey; CPubKey mypk,batonpk; int64_t datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid; char coinaddr[64],batonaddr[64]; std::vector <uint8_t> prevdata;
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( data.size() > 8192 )
|
||||
{
|
||||
fprintf(stderr,"datasize %d is too big\n",(int32_t)data.size());
|
||||
CCerror = strprintf("datasize %d is too big",(int32_t)data.size());
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
return("");
|
||||
}
|
||||
if ( (datafee= OracleDatafee(pubKey,oracletxid,mypk)) <= 0 )
|
||||
{
|
||||
fprintf(stderr,"datafee %.8f is illegal\n",(double)datafee/COIN);
|
||||
CCerror = strprintf("datafee %.8f is illegal",(double)datafee/COIN);
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
return("");
|
||||
}
|
||||
if ( txfee == 0 )
|
||||
@@ -816,8 +826,14 @@ std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> da
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,batonpk));
|
||||
mtx.vout.push_back(CTxOut(datafee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesData('D',oracletxid,batontxid,mypk,data)));
|
||||
} else fprintf(stderr,"couldnt find enough oracle inputs %s, limit 1 per utxo\n",coinaddr);
|
||||
} else fprintf(stderr,"couldnt add normal inputs\n");
|
||||
} else {
|
||||
CCerror = strprintf("couldnt find enough oracle inputs %s, limit 1 per utxo\n",coinaddr);
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
}
|
||||
} else {
|
||||
CCerror = strprintf("couldnt add normal inputs\n");
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
}
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -867,7 +883,8 @@ UniValue OracleInfo(uint256 origtxid)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR);
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
CMutableTransaction mtx; CTransaction regtx,tx; std::string name,description,format; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey pk; struct CCcontract_info *cp,C; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64],batonaddr[64]; std::vector <uint8_t> data;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction regtx,tx; std::string name,description,format; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey pk; struct CCcontract_info *cp,C; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64],batonaddr[64]; std::vector <uint8_t> data;
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
CCtxidaddr(markeraddr,origtxid);
|
||||
if ( GetTransaction(origtxid,tx,hashBlock,false) == 0 )
|
||||
|
||||
@@ -72,7 +72,7 @@ bool PaymentsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransacti
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||
return(false);
|
||||
@@ -144,7 +144,8 @@ int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
|
||||
|
||||
std::string PaymentsGet(uint64_t txfee,int64_t nValue)
|
||||
{
|
||||
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Paymentspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Paymentspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -184,7 +185,8 @@ std::string PaymentsGet(uint64_t txfee,int64_t nValue)
|
||||
|
||||
std::string PaymentsFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Paymentspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Paymentspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -201,7 +203,8 @@ std::string PaymentsFund(uint64_t txfee,int64_t funds)
|
||||
UniValue PaymentsInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey Paymentspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey Paymentspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Payments"));
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
|
||||
@@ -79,7 +79,7 @@ bool PegsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||
return(false);
|
||||
@@ -151,7 +151,8 @@ int64_t AddPegsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
|
||||
|
||||
std::string PegsGet(uint64_t txfee,int64_t nValue)
|
||||
{
|
||||
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Pegspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Pegspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
cp = CCinit(&C,EVAL_PEGS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -191,7 +192,8 @@ std::string PegsGet(uint64_t txfee,int64_t nValue)
|
||||
|
||||
std::string PegsFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Pegspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Pegspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_PEGS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -208,7 +210,8 @@ std::string PegsFund(uint64_t txfee,int64_t funds)
|
||||
UniValue PegsInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey Pegspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey Pegspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Pegs"));
|
||||
cp = CCinit(&C,EVAL_PEGS);
|
||||
|
||||
@@ -86,7 +86,7 @@ uint8_t DecodePricesFundingOpRet(CScript scriptPubKey,CPubKey &planpk,uint256 &o
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||
return(false);
|
||||
@@ -182,7 +182,8 @@ UniValue PricesList()
|
||||
// bettoken
|
||||
std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletxid,uint64_t margin,uint64_t mode,uint256 longtoken,uint256 shorttoken,int32_t maxleverage,int64_t funding,std::vector<CPubKey> pubkeys)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction oracletx; int64_t fullsupply,inputs,CCchange=0; uint256 hashBlock; char str[65],coinaddr[64],houseaddr[64]; CPubKey mypk,pricespk; int32_t i,N,numvouts; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction oracletx; int64_t fullsupply,inputs,CCchange=0; uint256 hashBlock; char str[65],coinaddr[64],houseaddr[64]; CPubKey mypk,pricespk; int32_t i,N,numvouts; struct CCcontract_info *cp,C;
|
||||
if ( funding < 100*COIN || maxleverage <= 0 || maxleverage > 10000 )
|
||||
{
|
||||
CCerror = "invalid parameter error";
|
||||
@@ -229,7 +230,7 @@ std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletx
|
||||
return("");
|
||||
}
|
||||
fprintf(stderr,"error check bettoken\n");
|
||||
if ( AddNormalinputs(mtx,mypk,3*txfee,3) > 0 )
|
||||
if ( AddNormalinputs(mtx,mypk,3*txfee,4) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG));
|
||||
@@ -293,7 +294,8 @@ UniValue PricesInfo(uint256 fundingtxid)
|
||||
|
||||
std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,CCchange = 0; uint64_t funding,mode; int32_t margin,maxleverage; char houseaddr[64],myaddr[64]; std::vector<CPubKey>pubkeys;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,CCchange = 0; uint64_t funding,mode; int32_t margin,maxleverage; char houseaddr[64],myaddr[64]; std::vector<CPubKey>pubkeys;
|
||||
if ( amount < 10000 )
|
||||
{
|
||||
CCerror = "amount must be positive";
|
||||
@@ -343,7 +345,8 @@ std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingt
|
||||
|
||||
std::string PricesBet(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount,int32_t leverage)
|
||||
{
|
||||
CMutableTransaction mtx; struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,tokenid,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,inputs2,longexposure,netexposure,shortexposure,CCchange = 0,CCchange2 = 0; uint64_t funding,mode; int32_t dir,margin,maxleverage; char houseaddr[64],myaddr[64],exposureaddr[64]; std::vector<CPubKey>pubkeys;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,tokenid,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,inputs2,longexposure,netexposure,shortexposure,CCchange = 0,CCchange2 = 0; uint64_t funding,mode; int32_t dir,margin,maxleverage; char houseaddr[64],myaddr[64],exposureaddr[64]; std::vector<CPubKey>pubkeys;
|
||||
if ( amount < 0 )
|
||||
{
|
||||
amount = -amount;
|
||||
|
||||
@@ -192,7 +192,7 @@ bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransactio
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
uint256 txid,fundingtxid,hashBlock,vinfundingtxid; uint64_t vinsbits,sbits,APR,minseconds,maxseconds,mindeposit,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx;
|
||||
numvins = tx.vin.size();
|
||||
@@ -333,7 +333,7 @@ int64_t AddRewardsInputs(CScript &scriptPubKey,uint64_t maxseconds,struct CCcont
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/maxinputs;
|
||||
threshold = total/(maxinputs+1);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
@@ -500,7 +500,8 @@ UniValue RewardsList()
|
||||
|
||||
std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
||||
if ( funds < COIN || mindeposit < 0 || minseconds < 0 || maxseconds < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative parameter error\n");
|
||||
@@ -534,7 +535,8 @@ std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int6
|
||||
|
||||
std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
||||
if ( amount < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative parameter error\n");
|
||||
@@ -568,7 +570,8 @@ std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,i
|
||||
|
||||
std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t deposit)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t lockedfunds,sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,rewardspk; CScript opret; uint64_t lockedfunds,sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
|
||||
if ( deposit < txfee )
|
||||
{
|
||||
CCerror = "deposit amount less than txfee";
|
||||
@@ -611,7 +614,8 @@ std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t
|
||||
|
||||
std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid)
|
||||
{
|
||||
CMutableTransaction mtx,firstmtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript scriptPubKey,ignore; uint256 hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; int64_t funding,reward=0,amount=0,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction firstmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript scriptPubKey,ignore; uint256 hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; int64_t funding,reward=0,amount=0,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_REWARDS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
|
||||
@@ -71,7 +71,7 @@ bool TriggersExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransacti
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool TriggersValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||
bool TriggersValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||
return(false);
|
||||
@@ -143,7 +143,8 @@ int64_t AddTriggersInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
|
||||
|
||||
std::string TriggersGet(uint64_t txfee,int64_t nValue)
|
||||
{
|
||||
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Triggerspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Triggerspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
cp = CCinit(&C,EVAL_TRIGGERS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -183,7 +184,8 @@ std::string TriggersGet(uint64_t txfee,int64_t nValue)
|
||||
|
||||
std::string TriggersFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Triggerspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Triggerspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_TRIGGERS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -200,7 +202,8 @@ std::string TriggersFund(uint64_t txfee,int64_t funds)
|
||||
UniValue TriggersInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey Triggerspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey Triggerspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Triggers"));
|
||||
cp = CCinit(&C,EVAL_TRIGGERS);
|
||||
|
||||
@@ -16,9 +16,9 @@ void CChain::SetTip(CBlockIndex *pindex) {
|
||||
vChain.clear();
|
||||
return;
|
||||
}
|
||||
vChain.resize(pindex->nHeight + 1);
|
||||
while (pindex && vChain[pindex->nHeight] != pindex) {
|
||||
vChain[pindex->nHeight] = pindex;
|
||||
vChain.resize(pindex->GetHeight() + 1);
|
||||
while (pindex && vChain[pindex->GetHeight()] != pindex) {
|
||||
vChain[pindex->GetHeight()] = pindex;
|
||||
pindex = pindex->pprev;
|
||||
}
|
||||
}
|
||||
@@ -33,10 +33,10 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
|
||||
while (pindex) {
|
||||
vHave.push_back(pindex->GetBlockHash());
|
||||
// Stop when we have added the genesis block.
|
||||
if (pindex->nHeight == 0)
|
||||
if (pindex->GetHeight() == 0)
|
||||
break;
|
||||
// Exponentially larger steps back, plus the genesis block.
|
||||
int nHeight = std::max(pindex->nHeight - nStep, 0);
|
||||
int nHeight = std::max(pindex->GetHeight() - nStep, 0);
|
||||
if (Contains(pindex)) {
|
||||
// Use O(1) CChain index if possible.
|
||||
pindex = (*this)[nHeight];
|
||||
@@ -54,13 +54,63 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
|
||||
const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
|
||||
if ( pindex == 0 )
|
||||
return(0);
|
||||
if (pindex->nHeight > Height())
|
||||
if (pindex->GetHeight() > Height())
|
||||
pindex = pindex->GetAncestor(Height());
|
||||
while (pindex && !Contains(pindex))
|
||||
pindex = pindex->pprev;
|
||||
return pindex;
|
||||
}
|
||||
|
||||
CChainPower::CChainPower(CBlockIndex *pblockIndex)
|
||||
{
|
||||
nHeight = pblockIndex->GetHeight();
|
||||
chainStake = arith_uint256(0);
|
||||
chainWork = arith_uint256(0);
|
||||
}
|
||||
|
||||
CChainPower::CChainPower(CBlockIndex *pblockIndex, const arith_uint256 &stake, const arith_uint256 &work)
|
||||
{
|
||||
nHeight = pblockIndex->GetHeight();
|
||||
chainStake = stake;
|
||||
chainWork = work;
|
||||
}
|
||||
|
||||
bool operator==(const CChainPower &p1, const CChainPower &p2)
|
||||
{
|
||||
arith_uint256 bigZero = arith_uint256(0);
|
||||
arith_uint256 workDivisor = p1.chainWork > p2.chainWork ? p1.chainWork : (p2.chainWork != bigZero ? p2.chainWork : 1);
|
||||
arith_uint256 stakeDivisor = p1.chainStake > p2.chainStake ? p1.chainStake : (p2.chainStake != bigZero ? p2.chainStake : 1);
|
||||
|
||||
// use up 16 bits for precision
|
||||
return ((p1.chainWork << 16) / workDivisor + (p1.chainStake << 16) / stakeDivisor) ==
|
||||
((p2.chainWork << 16) / workDivisor + (p2.chainStake << 16) / stakeDivisor);
|
||||
}
|
||||
|
||||
bool operator<(const CChainPower &p1, const CChainPower &p2)
|
||||
{
|
||||
arith_uint256 bigZero = arith_uint256(0);
|
||||
arith_uint256 workDivisor = p1.chainWork > p2.chainWork ? p1.chainWork : (p2.chainWork != bigZero ? p2.chainWork : 1);
|
||||
arith_uint256 stakeDivisor = p1.chainStake > p2.chainStake ? p1.chainStake : (p2.chainStake != bigZero ? p2.chainStake : 1);
|
||||
|
||||
// use up 16 bits for precision
|
||||
return ((p1.chainWork << 16) / workDivisor + (p1.chainStake << 16) / stakeDivisor) <
|
||||
((p2.chainWork << 16) / workDivisor + (p2.chainStake << 16) / stakeDivisor);
|
||||
}
|
||||
|
||||
bool operator<=(const CChainPower &p1, const CChainPower &p2)
|
||||
{
|
||||
arith_uint256 bigZero = arith_uint256(0);
|
||||
arith_uint256 workDivisor = p1.chainWork > p2.chainWork ? p1.chainWork : (p2.chainWork != bigZero ? p2.chainWork : 1);
|
||||
arith_uint256 stakeDivisor = p1.chainStake > p2.chainStake ? p1.chainStake : (p2.chainStake != bigZero ? p2.chainStake : 1);
|
||||
|
||||
// use up 16 bits for precision
|
||||
return ((p1.chainWork << 16) / workDivisor + (p1.chainStake << 16) / stakeDivisor) <=
|
||||
((p2.chainWork << 16) / workDivisor + (p2.chainStake << 16) / stakeDivisor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */
|
||||
int static inline InvertLowestOne(int n) { return n & (n - 1); }
|
||||
|
||||
@@ -77,11 +127,11 @@ int static inline GetSkipHeight(int height) {
|
||||
|
||||
CBlockIndex* CBlockIndex::GetAncestor(int height)
|
||||
{
|
||||
if (height > nHeight || height < 0)
|
||||
if (height > GetHeight() || height < 0)
|
||||
return NULL;
|
||||
|
||||
CBlockIndex* pindexWalk = this;
|
||||
int heightWalk = nHeight;
|
||||
int heightWalk = GetHeight();
|
||||
while ( heightWalk > height && pindexWalk != 0 )
|
||||
{
|
||||
int heightSkip = GetSkipHeight(heightWalk);
|
||||
@@ -94,6 +144,7 @@ CBlockIndex* CBlockIndex::GetAncestor(int height)
|
||||
pindexWalk = pindexWalk->pskip;
|
||||
heightWalk = heightSkip;
|
||||
} else {
|
||||
assert(pindexWalk->pprev);
|
||||
pindexWalk = pindexWalk->pprev;
|
||||
heightWalk--;
|
||||
}
|
||||
@@ -109,5 +160,5 @@ const CBlockIndex* CBlockIndex::GetAncestor(int height) const
|
||||
void CBlockIndex::BuildSkip()
|
||||
{
|
||||
if (pprev)
|
||||
pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
|
||||
pskip = pprev->GetAncestor(GetSkipHeight(GetHeight()));
|
||||
}
|
||||
|
||||
189
src/chain.h
189
src/chain.h
@@ -6,6 +6,8 @@
|
||||
#ifndef BITCOIN_CHAIN_H
|
||||
#define BITCOIN_CHAIN_H
|
||||
|
||||
class CChainPower;
|
||||
|
||||
#include "arith_uint256.h"
|
||||
#include "primitives/block.h"
|
||||
#include "pow.h"
|
||||
@@ -17,6 +19,8 @@
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
static const int SPROUT_VALUE_VERSION = 1001400;
|
||||
static const int SAPLING_VALUE_VERSION = 1010100;
|
||||
extern int32_t ASSETCHAINS_LWMAPOS;
|
||||
|
||||
struct CDiskBlockPos
|
||||
{
|
||||
@@ -26,7 +30,7 @@ struct CDiskBlockPos
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(VARINT(nFile));
|
||||
READWRITE(VARINT(nPos));
|
||||
}
|
||||
@@ -102,6 +106,101 @@ enum BlockStatus: uint32_t {
|
||||
//! Blocks with this validity are assumed to satisfy all consensus rules.
|
||||
static const BlockStatus BLOCK_VALID_CONSENSUS = BLOCK_VALID_SCRIPTS;
|
||||
|
||||
class CBlockIndex;
|
||||
|
||||
// This class provides an accumulator for both the chainwork and the chainPOS value
|
||||
// CChainPower's can be compared, and the comparison ensures that work and proof of stake power
|
||||
// are both used equally to determine which chain has the most work. This makes an attack
|
||||
// that involves mining in secret completely ineffective, even before dPOW, unless a large part
|
||||
// of the staking supply is also controlled. It also enables a faster deterministic convergence,
|
||||
// aided by both POS and POW.
|
||||
class CChainPower
|
||||
{
|
||||
public:
|
||||
arith_uint256 chainWork;
|
||||
arith_uint256 chainStake;
|
||||
int32_t nHeight;
|
||||
|
||||
CChainPower() : nHeight(0), chainStake(0), chainWork(0) {}
|
||||
CChainPower(CBlockIndex *pblockIndex);
|
||||
CChainPower(CBlockIndex *pblockIndex, const arith_uint256 &stake, const arith_uint256 &work);
|
||||
CChainPower(int32_t height) : nHeight(height), chainStake(0), chainWork(0) {}
|
||||
CChainPower(int32_t height, const arith_uint256 &stake, const arith_uint256 &work) :
|
||||
nHeight(height), chainStake(stake), chainWork(work) {}
|
||||
|
||||
CChainPower &operator=(const CChainPower &chainPower)
|
||||
{
|
||||
chainWork = chainPower.chainWork;
|
||||
chainStake = chainPower.chainStake;
|
||||
nHeight = chainPower.nHeight;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CChainPower &operator+=(const CChainPower &chainPower)
|
||||
{
|
||||
this->chainWork += chainPower.chainWork;
|
||||
this->chainStake += chainPower.chainStake;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend CChainPower operator+(const CChainPower &chainPowerA, const CChainPower &chainPowerB)
|
||||
{
|
||||
CChainPower result = CChainPower(chainPowerA);
|
||||
result.chainWork += chainPowerB.chainWork;
|
||||
result.chainStake += chainPowerB.chainStake;
|
||||
return result;
|
||||
}
|
||||
|
||||
friend CChainPower operator-(const CChainPower &chainPowerA, const CChainPower &chainPowerB)
|
||||
{
|
||||
CChainPower result = CChainPower(chainPowerA);
|
||||
result.chainWork -= chainPowerB.chainWork;
|
||||
result.chainStake -= chainPowerB.chainStake;
|
||||
return result;
|
||||
}
|
||||
|
||||
friend CChainPower operator*(const CChainPower &chainPower, int32_t x)
|
||||
{
|
||||
CChainPower result = CChainPower(chainPower);
|
||||
result.chainWork *= x;
|
||||
result.chainStake *= x;
|
||||
return result;
|
||||
}
|
||||
|
||||
CChainPower &addStake(const arith_uint256 &nChainStake)
|
||||
{
|
||||
chainStake += nChainStake;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CChainPower &addWork(const arith_uint256 &nChainWork)
|
||||
{
|
||||
chainWork += nChainWork;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend bool operator==(const CChainPower &p1, const CChainPower &p2);
|
||||
|
||||
friend bool operator!=(const CChainPower &p1, const CChainPower &p2)
|
||||
{
|
||||
return !(p1 == p2);
|
||||
}
|
||||
|
||||
friend bool operator<(const CChainPower &p1, const CChainPower &p2);
|
||||
|
||||
friend bool operator<=(const CChainPower &p1, const CChainPower &p2);
|
||||
|
||||
friend bool operator>(const CChainPower &p1, const CChainPower &p2)
|
||||
{
|
||||
return !(p1 <= p2);
|
||||
}
|
||||
|
||||
friend bool operator>=(const CChainPower &p1, const CChainPower &p2)
|
||||
{
|
||||
return !(p1 < p2);
|
||||
}
|
||||
};
|
||||
|
||||
/** The block chain is a tree shaped structure starting with the
|
||||
* genesis block at the root, with each block potentially having multiple
|
||||
* candidates to be the next block. A blockindex may have multiple pprev pointing
|
||||
@@ -120,7 +219,6 @@ public:
|
||||
CBlockIndex* pskip;
|
||||
|
||||
//! height of the entry in the chain. The genesis block has height 0
|
||||
int nHeight;
|
||||
int64_t newcoins,zfunds; int8_t segid; // jl777 fields
|
||||
//! Which # file this block is stored in (blk?????.dat)
|
||||
int nFile;
|
||||
@@ -132,7 +230,7 @@ public:
|
||||
unsigned int nUndoPos;
|
||||
|
||||
//! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
|
||||
arith_uint256 nChainWork;
|
||||
CChainPower chainPower;
|
||||
|
||||
//! Number of transactions in this block.
|
||||
//! Note: in a potential headers-first mode, this number cannot be relied upon
|
||||
@@ -152,10 +250,10 @@ public:
|
||||
boost::optional<uint32_t> nCachedBranchId;
|
||||
|
||||
//! The anchor for the tree state up to the start of this block
|
||||
uint256 hashAnchor;
|
||||
uint256 hashSproutAnchor;
|
||||
|
||||
//! (memory only) The anchor for the tree state up to the end of this block
|
||||
uint256 hashAnchorEnd;
|
||||
uint256 hashFinalSproutRoot;
|
||||
|
||||
//! Change in value held by the Sprout circuit over this block.
|
||||
//! Will be boost::none for older blocks on old nodes until a reindex has taken place.
|
||||
@@ -166,10 +264,19 @@ public:
|
||||
//! Will be boost::none if nChainTx is zero.
|
||||
boost::optional<CAmount> nChainSproutValue;
|
||||
|
||||
//! Change in value held by the Sapling circuit over this block.
|
||||
//! Not a boost::optional because this was added before Sapling activated, so we can
|
||||
//! rely on the invariant that every block before this was added had nSaplingValue = 0.
|
||||
CAmount nSaplingValue;
|
||||
|
||||
//! (memory only) Total value held by the Sapling circuit up to and including this block.
|
||||
//! Will be boost::none if nChainTx is zero.
|
||||
boost::optional<CAmount> nChainSaplingValue;
|
||||
|
||||
//! block header
|
||||
int nVersion;
|
||||
uint256 hashMerkleRoot;
|
||||
uint256 hashReserved;
|
||||
uint256 hashFinalSaplingRoot;
|
||||
unsigned int nTime;
|
||||
unsigned int nBits;
|
||||
uint256 nNonce;
|
||||
@@ -185,24 +292,25 @@ public:
|
||||
segid = -2;
|
||||
pprev = NULL;
|
||||
pskip = NULL;
|
||||
nHeight = 0;
|
||||
nFile = 0;
|
||||
nDataPos = 0;
|
||||
nUndoPos = 0;
|
||||
nChainWork = arith_uint256();
|
||||
chainPower = CChainPower();
|
||||
nTx = 0;
|
||||
nChainTx = 0;
|
||||
nStatus = 0;
|
||||
nCachedBranchId = boost::none;
|
||||
hashAnchor = uint256();
|
||||
hashAnchorEnd = uint256();
|
||||
hashSproutAnchor = uint256();
|
||||
hashFinalSproutRoot = uint256();
|
||||
nSequenceId = 0;
|
||||
nSproutValue = boost::none;
|
||||
nChainSproutValue = boost::none;
|
||||
nSaplingValue = 0;
|
||||
nChainSaplingValue = boost::none;
|
||||
|
||||
nVersion = 0;
|
||||
hashMerkleRoot = uint256();
|
||||
hashReserved = uint256();
|
||||
hashFinalSaplingRoot = uint256();
|
||||
nTime = 0;
|
||||
nBits = 0;
|
||||
nNonce = uint256();
|
||||
@@ -220,13 +328,23 @@ public:
|
||||
|
||||
nVersion = block.nVersion;
|
||||
hashMerkleRoot = block.hashMerkleRoot;
|
||||
hashReserved = block.hashReserved;
|
||||
hashFinalSaplingRoot = block.hashFinalSaplingRoot;
|
||||
nTime = block.nTime;
|
||||
nBits = block.nBits;
|
||||
nNonce = block.nNonce;
|
||||
nSolution = block.nSolution;
|
||||
}
|
||||
|
||||
int32_t SetHeight(int32_t height)
|
||||
{
|
||||
this->chainPower.nHeight = height;
|
||||
}
|
||||
|
||||
inline int32_t GetHeight() const
|
||||
{
|
||||
return this->chainPower.nHeight;
|
||||
}
|
||||
|
||||
CDiskBlockPos GetBlockPos() const {
|
||||
CDiskBlockPos ret;
|
||||
if (nStatus & BLOCK_HAVE_DATA) {
|
||||
@@ -252,7 +370,7 @@ public:
|
||||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.hashReserved = hashReserved;
|
||||
block.hashFinalSaplingRoot = hashFinalSaplingRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
@@ -289,7 +407,7 @@ public:
|
||||
std::string ToString() const
|
||||
{
|
||||
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
|
||||
pprev, nHeight,
|
||||
pprev, this->chainPower.nHeight,
|
||||
hashMerkleRoot.ToString(),
|
||||
GetBlockHash().ToString());
|
||||
}
|
||||
@@ -324,6 +442,17 @@ public:
|
||||
CBlockIndex* GetAncestor(int height);
|
||||
const CBlockIndex* GetAncestor(int height) const;
|
||||
|
||||
int32_t GetVerusPOSTarget() const
|
||||
{
|
||||
return GetBlockHeader().GetVerusPOSTarget();
|
||||
}
|
||||
|
||||
bool IsVerusPOSBlock() const
|
||||
{
|
||||
if ( ASSETCHAINS_LWMAPOS != 0 )
|
||||
return GetBlockHeader().IsVerusPOSBlock();
|
||||
else return(0);
|
||||
}
|
||||
};
|
||||
|
||||
/** Used to marshal pointers into hashes for db storage. */
|
||||
@@ -332,7 +461,7 @@ class CDiskBlockIndex : public CBlockIndex
|
||||
public:
|
||||
uint256 hashPrev;
|
||||
|
||||
CDiskBlockIndex() {
|
||||
CDiskBlockIndex() : CBlockIndex() {
|
||||
hashPrev = uint256();
|
||||
}
|
||||
|
||||
@@ -343,11 +472,15 @@ public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
if (!(nType & SER_GETHASH))
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
int nVersion = s.GetVersion();
|
||||
if (!(s.GetType() & SER_GETHASH))
|
||||
READWRITE(VARINT(nVersion));
|
||||
|
||||
READWRITE(VARINT(nHeight));
|
||||
if (ser_action.ForRead()) {
|
||||
chainPower = CChainPower();
|
||||
}
|
||||
READWRITE(VARINT(chainPower.nHeight));
|
||||
READWRITE(VARINT(nStatus));
|
||||
READWRITE(VARINT(nTx));
|
||||
if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
|
||||
@@ -368,13 +501,13 @@ public:
|
||||
READWRITE(branchId);
|
||||
}
|
||||
}
|
||||
READWRITE(hashAnchor);
|
||||
READWRITE(hashSproutAnchor);
|
||||
|
||||
// block header
|
||||
READWRITE(this->nVersion);
|
||||
READWRITE(hashPrev);
|
||||
READWRITE(hashMerkleRoot);
|
||||
READWRITE(hashReserved);
|
||||
READWRITE(hashFinalSaplingRoot);
|
||||
READWRITE(nTime);
|
||||
READWRITE(nBits);
|
||||
READWRITE(nNonce);
|
||||
@@ -382,9 +515,15 @@ public:
|
||||
|
||||
// Only read/write nSproutValue if the client version used to create
|
||||
// this index was storing them.
|
||||
if ((nType & SER_DISK) && (nVersion >= SPROUT_VALUE_VERSION)) {
|
||||
if ((s.GetType() & SER_DISK) && (nVersion >= SPROUT_VALUE_VERSION)) {
|
||||
READWRITE(nSproutValue);
|
||||
}
|
||||
|
||||
// Only read/write nSaplingValue if the client version used to create
|
||||
// this index was storing them.
|
||||
if ((s.GetType() & SER_DISK) && (nVersion >= SAPLING_VALUE_VERSION)) {
|
||||
READWRITE(nSaplingValue);
|
||||
}
|
||||
}
|
||||
|
||||
uint256 GetBlockHash() const
|
||||
@@ -393,7 +532,7 @@ public:
|
||||
block.nVersion = nVersion;
|
||||
block.hashPrevBlock = hashPrev;
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.hashReserved = hashReserved;
|
||||
block.hashFinalSaplingRoot = hashFinalSaplingRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
@@ -450,18 +589,18 @@ public:
|
||||
|
||||
/** Efficiently check whether a block is present in this chain. */
|
||||
bool Contains(const CBlockIndex *pindex) const {
|
||||
return (*this)[pindex->nHeight] == pindex;
|
||||
return (*this)[pindex->GetHeight()] == pindex;
|
||||
}
|
||||
|
||||
/** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */
|
||||
CBlockIndex *Next(const CBlockIndex *pindex) const {
|
||||
if (Contains(pindex))
|
||||
return (*this)[pindex->nHeight + 1];
|
||||
return (*this)[pindex->GetHeight() + 1];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */
|
||||
/** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->GetHeight() : -1. */
|
||||
int Height() const {
|
||||
return vChain.size() - 1;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "crypto/equihash.h"
|
||||
|
||||
@@ -13,14 +14,12 @@
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
#include "base58.h"
|
||||
|
||||
#include "chainparamsseeds.h"
|
||||
|
||||
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, const uint256& nNonce, const std::vector<unsigned char>& nSolution, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
|
||||
{
|
||||
// To create a genesis block for a new chain which is Overwintered:
|
||||
// txNew.nVersion = 3
|
||||
// txNew.nVersion = OVERWINTER_TX_VERSION
|
||||
// txNew.fOverwintered = true
|
||||
// txNew.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID
|
||||
// txNew.nExpiryHeight = <default value>
|
||||
@@ -80,9 +79,9 @@ void *chainparams_commandline(void *ptr);
|
||||
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
|
||||
extern uint32_t ASSETCHAIN_INIT;
|
||||
extern uint32_t ASSETCHAINS_MAGIC;
|
||||
extern uint64_t ASSETCHAINS_SUPPLY;
|
||||
extern uint32_t ASSETCHAIN_INIT, ASSETCHAINS_MAGIC;
|
||||
extern int32_t VERUS_BLOCK_POSUNITS, ASSETCHAINS_LWMAPOS, ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER;
|
||||
extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_VERUSHASH;
|
||||
|
||||
const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
|
||||
|
||||
@@ -90,30 +89,39 @@ class CMainParams : public CChainParams {
|
||||
public:
|
||||
CMainParams()
|
||||
{
|
||||
|
||||
strNetworkID = "main";
|
||||
strCurrencyUnits = "KMD";
|
||||
consensus.fCoinbaseMustBeProtected = false;//true;
|
||||
bip44CoinType = 133; // As registered in https://github.com/satoshilabs/slips/blob/master/slip-0044.md (ZCASH, should be VRSC)
|
||||
consensus.fCoinbaseMustBeProtected = false; // true this is only true wuth Verus and enforced after block 12800
|
||||
consensus.nSubsidySlowStartInterval = 20000;
|
||||
consensus.nSubsidyHalvingInterval = 840000;
|
||||
consensus.nMajorityEnforceBlockUpgrade = 750;
|
||||
consensus.nMajorityRejectBlockOutdated = 950;
|
||||
consensus.nMajorityWindow = 4000;
|
||||
consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
consensus.powAlternate = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
consensus.nPowAveragingWindow = 17;
|
||||
consensus.nMaxFutureBlockTime = 7 * 60; // 7 mins
|
||||
|
||||
assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow);
|
||||
consensus.nPowMaxAdjustDown = 32; // 32% adjustment down
|
||||
consensus.nPowMaxAdjustUp = 16; // 16% adjustment up
|
||||
consensus.nPowTargetSpacing = 1 * 60;
|
||||
consensus.fPowAllowMinDifficultyBlocks = true; //false;
|
||||
consensus.nPowAllowMinDifficultyBlocksAfterHeight = boost::none;
|
||||
consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002;
|
||||
consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight =
|
||||
Consensus::NetworkUpgrade::ALWAYS_ACTIVE;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nProtocolVersion = 170002;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight =
|
||||
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170004;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight =
|
||||
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170005;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170007;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
|
||||
|
||||
// The best chain should have at least this much work.
|
||||
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000281b32ff3198a1");
|
||||
|
||||
/**
|
||||
* The message start string is designed to be unlikely to occur in normal data.
|
||||
@@ -125,6 +133,7 @@ public:
|
||||
pchMessageStart[2] = 0xe4;
|
||||
pchMessageStart[3] = 0x8d;
|
||||
vAlertPubKey = ParseHex("020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9");
|
||||
// (Zcash) vAlertPubKey = ParseHex("04b7ecf0baa90495ceb4e4090f6b2fd37eec1e9c85fac68a487f3ce11589692e4a317479316ee814e066638e1db54e37a10689b70286e6315b1087b6615d179264");
|
||||
nDefaultPort = 7770;
|
||||
nMinerThreads = 0;
|
||||
nMaxTipAge = 24 * 60 * 60;
|
||||
@@ -162,6 +171,7 @@ public:
|
||||
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
|
||||
vFixedSeeds.clear();
|
||||
vSeeds.clear();
|
||||
vSeeds.push_back(CDNSSeedData("veruscoin.io", "seeds.veruscoin.io")); // @kolo - old static dns seeds
|
||||
vSeeds.push_back(CDNSSeedData("komodoplatform.com", "seeds.komodoplatform.com")); // @kolo - old static dns seeds
|
||||
vSeeds.push_back(CDNSSeedData("kolo.supernet.org", "static.kolo.supernet.org")); // @kolo - new static dns seeds ToDo
|
||||
vSeeds.push_back(CDNSSeedData("kolo.supernet.org", "dynamic.kolo.supernet.org")); // @kolo - crawler seeds ToDo
|
||||
@@ -178,6 +188,11 @@ public:
|
||||
// guarantees the first two characters, when base58 encoded, are "SK"
|
||||
base58Prefixes[ZCSPENDING_KEY] = {171,54};
|
||||
|
||||
bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "zs";
|
||||
bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviews";
|
||||
bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivks";
|
||||
bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-main";
|
||||
|
||||
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
|
||||
|
||||
fMiningRequiresPeers = true;
|
||||
@@ -186,21 +201,13 @@ public:
|
||||
fMineBlocksOnDemand = false;
|
||||
fTestnetToBeDeprecatedFieldRPC = false;
|
||||
|
||||
// LogPrintf(">>>>>>>> ac_name = %u\n",GetArg("-ac_name","").c_str());
|
||||
|
||||
// if ( GetArg("-ac_name","").c_str()[0] != 0 )
|
||||
// {
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// }
|
||||
|
||||
if ( pthread_create((pthread_t *)malloc(sizeof(pthread_t)),NULL,chainparams_commandline,(void *)&consensus) != 0 )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static CMainParams mainParams;
|
||||
|
||||
void CChainParams::SetCheckpointData(CChainParams::CCheckpointData checkpointData)
|
||||
@@ -208,6 +215,22 @@ void CChainParams::SetCheckpointData(CChainParams::CCheckpointData checkpointDat
|
||||
CChainParams::checkpointData = checkpointData;
|
||||
}
|
||||
|
||||
int32_t MAX_BLOCK_SIZE(int32_t height)
|
||||
{
|
||||
//fprintf(stderr,"MAX_BLOCK_SIZE %d vs. %d\n",height,mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight);
|
||||
if ( height <= 0 || (mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight > 0 && height >= mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight) )
|
||||
return(4096 * 1024);
|
||||
else return(2000000);
|
||||
}
|
||||
|
||||
void komodo_setactivation(int32_t height)
|
||||
{
|
||||
mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = height;
|
||||
mainParams.consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = height;
|
||||
ASSETCHAINS_SAPLING = height;
|
||||
fprintf(stderr,"SET SAPLING ACTIVATION height.%d\n",height);
|
||||
}
|
||||
|
||||
void *chainparams_commandline(void *ptr)
|
||||
{
|
||||
CChainParams::CCheckpointData checkpointData;
|
||||
@@ -231,20 +254,69 @@ void *chainparams_commandline(void *ptr)
|
||||
mainParams.pchMessageStart[3] = (ASSETCHAINS_MAGIC >> 24) & 0xff;
|
||||
fprintf(stderr,">>>>>>>>>> %s: p2p.%u rpc.%u magic.%08x %u %u coins\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_MAGIC,ASSETCHAINS_MAGIC,(uint32_t)ASSETCHAINS_SUPPLY);
|
||||
|
||||
checkpointData = //(Checkpoints::CCheckpointData)
|
||||
{
|
||||
boost::assign::map_list_of
|
||||
(0, mainParams.consensus.hashGenesisBlock),
|
||||
//(2500, uint256S("0x0e6a3d5a46eba97c4e7618d66a39f115729e1176433c98481124c2bf733aa54e"))
|
||||
//(15000, uint256S("0x00f0bd236790e903321a2d22f85bd6bf8a505f6ef4eddb20458a65d37e14d142")),
|
||||
//(100000, uint256S("0x0f02eb1f3a4b89df9909fec81a4bd7d023e32e24e1f5262d9fc2cc36a715be6f")),
|
||||
(int64_t)1481120910, // * UNIX timestamp of last checkpoint block
|
||||
(int64_t)110415, // * total number of transactions between genesis and last checkpoint
|
||||
// (the tx=... number in the SetBestChain debug.log lines)
|
||||
(double)2777 // * estimated number of transactions per day after checkpoint
|
||||
// total number of tx / (checkpoint block height / (24 * 24))
|
||||
};
|
||||
if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH)
|
||||
{
|
||||
// this is only good for 60 second blocks with an averaging window of 45. for other parameters, use:
|
||||
// nLwmaAjustedWeight = (N+1)/2 * (0.9989^(500/nPowAveragingWindow)) * nPowTargetSpacing
|
||||
mainParams.consensus.nLwmaAjustedWeight = 1350;
|
||||
mainParams.consensus.nPowAveragingWindow = 45;
|
||||
mainParams.consensus.powAlternate = uint256S("00000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
}
|
||||
|
||||
if (ASSETCHAINS_LWMAPOS != 0)
|
||||
{
|
||||
mainParams.consensus.posLimit = uint256S("000000000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
mainParams.consensus.nPOSAveragingWindow = 45;
|
||||
// spacing is 1000 units per block to get better resolution, POS is 50% hard coded for now, we can vary it later
|
||||
// when we get reliable integer math on nLwmaPOSAjustedWeight
|
||||
mainParams.consensus.nPOSTargetSpacing = VERUS_BLOCK_POSUNITS * 2;
|
||||
// nLwmaPOSAjustedWeight = (N+1)/2 * (0.9989^(500/nPOSAveragingWindow)) * nPOSTargetSpacing
|
||||
// this needs to be recalculated if VERUS_BLOCK_POSUNITS is changed
|
||||
mainParams.consensus.nLwmaPOSAjustedWeight = 46531;
|
||||
}
|
||||
|
||||
// only require coinbase protection on Verus from the Komodo family of coins
|
||||
if (strcmp(ASSETCHAINS_SYMBOL,"VRSC") == 0)
|
||||
{
|
||||
mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = 227520;
|
||||
mainParams.consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = 227520;
|
||||
mainParams.consensus.fCoinbaseMustBeProtected = true;
|
||||
checkpointData = //(Checkpoints::CCheckpointData)
|
||||
{
|
||||
boost::assign::map_list_of
|
||||
(0, mainParams.consensus.hashGenesisBlock)
|
||||
(10000, uint256S("0xac2cd7d37177140ea4991cf630c0b9c7f94d707b84fb0351bf3a44856d2ae5dc"))
|
||||
(20000, uint256S("0xb0e8cb9f77aaa7ff5bd90d6c08d06f4c4bf03e00c2b8a35a042e760845590c8a"))
|
||||
(30000, uint256S("0xf2112ca577338ad7104bf905fa6a63d36b17a86f914c97b73cd31d43fcd7557c"))
|
||||
(40000, uint256S("0x00000000008f83378dab727864b763ce91a4ea5f75d55939c0c1390cfb8c38f1"))
|
||||
(49170, uint256S("0x2add646c0089871ec2379f02f7cd60b3af6efd9c152a6f16fc10925458c270cc")),
|
||||
(int64_t)1529910234, // * UNIX timestamp of last checkpoint block
|
||||
(int64_t)63661, // * total number of transactions between genesis and last checkpoint
|
||||
// (the tx=... number in the SetBestChain debug.log lines)
|
||||
(double)2777 // * estimated number of transactions per day after checkpoint
|
||||
// total number of tx / (checkpoint block height / (24 * 24))
|
||||
};
|
||||
|
||||
mainParams.consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000001a8f4f23f8b2d1f7e");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(ASSETCHAINS_SYMBOL,"VRSCTEST") == 0 || strcmp(ASSETCHAINS_SYMBOL,"VERUSTEST") == 0)
|
||||
{
|
||||
mainParams.consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000000000001f7e");
|
||||
}
|
||||
mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = ASSETCHAINS_SAPLING;
|
||||
mainParams.consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = ASSETCHAINS_OVERWINTER;
|
||||
checkpointData = //(Checkpoints::CCheckpointData)
|
||||
{
|
||||
boost::assign::map_list_of
|
||||
(0, mainParams.consensus.hashGenesisBlock),
|
||||
(int64_t)1231006505,
|
||||
(int64_t)1,
|
||||
(double)2777 // * estimated number of transactions per day after checkpoint
|
||||
// total number of tx / (checkpoint block height / (24 * 24))
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -412,6 +484,7 @@ public:
|
||||
CTestNetParams() {
|
||||
strNetworkID = "test";
|
||||
strCurrencyUnits = "TAZ";
|
||||
bip44CoinType = 1;
|
||||
consensus.fCoinbaseMustBeProtected = true;
|
||||
consensus.nSubsidySlowStartInterval = 20000;
|
||||
consensus.nSubsidyHalvingInterval = 840000;
|
||||
@@ -419,8 +492,10 @@ public:
|
||||
consensus.nMajorityRejectBlockOutdated = 75;
|
||||
consensus.nMajorityWindow = 400;
|
||||
consensus.powLimit = uint256S("07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
consensus.powAlternate = uint256S("07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
consensus.nPowAveragingWindow = 17;
|
||||
assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow);
|
||||
consensus.nMaxFutureBlockTime = 7 * 60;
|
||||
|
||||
vAlertPubKey = ParseHex("00");
|
||||
nDefaultPort = 17770;
|
||||
@@ -428,6 +503,7 @@ public:
|
||||
consensus.nPowMaxAdjustDown = 32; // 32% adjustment down
|
||||
consensus.nPowMaxAdjustUp = 16; // 16% adjustment up
|
||||
consensus.nPowTargetSpacing = 2.5 * 60;
|
||||
consensus.nPowAllowMinDifficultyBlocksAfterHeight = 299187;
|
||||
consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002;
|
||||
consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight =
|
||||
Consensus::NetworkUpgrade::ALWAYS_ACTIVE;
|
||||
@@ -436,8 +512,12 @@ public:
|
||||
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170003;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = 207500;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170007;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = 280000;
|
||||
|
||||
// The best chain should have at least this much work.
|
||||
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000000001d0c4d9cd");
|
||||
|
||||
consensus.fPowAllowMinDifficultyBlocks = true;
|
||||
pchMessageStart[0] = 0x5A;
|
||||
pchMessageStart[1] = 0x1F;
|
||||
pchMessageStart[2] = 0x7E;
|
||||
@@ -473,6 +553,11 @@ public:
|
||||
base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C};
|
||||
base58Prefixes[ZCSPENDING_KEY] = {177,235};
|
||||
|
||||
bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "ztestsapling";
|
||||
bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviewtestsapling";
|
||||
bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivktestsapling";
|
||||
bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-test";
|
||||
|
||||
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
|
||||
|
||||
//fRequireRPCPassword = true;
|
||||
@@ -482,6 +567,7 @@ public:
|
||||
fMineBlocksOnDemand = false;
|
||||
fTestnetToBeDeprecatedFieldRPC = true;
|
||||
|
||||
|
||||
checkpointData = (CCheckpointData) {
|
||||
boost::assign::map_list_of
|
||||
(0, consensus.hashGenesisBlock)
|
||||
@@ -503,6 +589,7 @@ public:
|
||||
CRegTestParams() {
|
||||
strNetworkID = "regtest";
|
||||
strCurrencyUnits = "REG";
|
||||
bip44CoinType = 1;
|
||||
consensus.fCoinbaseMustBeProtected = false;
|
||||
consensus.nSubsidySlowStartInterval = 0;
|
||||
consensus.nSubsidyHalvingInterval = 150;
|
||||
@@ -510,11 +597,14 @@ public:
|
||||
consensus.nMajorityRejectBlockOutdated = 950;
|
||||
consensus.nMajorityWindow = 1000;
|
||||
consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
consensus.powAlternate = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
consensus.nPowAveragingWindow = 17;
|
||||
consensus.nMaxFutureBlockTime = 7 * 60; // 7 mins
|
||||
assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow);
|
||||
consensus.nPowMaxAdjustDown = 0; // Turn off adjustment down
|
||||
consensus.nPowMaxAdjustUp = 0; // Turn off adjustment up
|
||||
consensus.nPowTargetSpacing = 2.5 * 60;
|
||||
consensus.nPowAllowMinDifficultyBlocksAfterHeight = 0;
|
||||
consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002;
|
||||
consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight =
|
||||
Consensus::NetworkUpgrade::ALWAYS_ACTIVE;
|
||||
@@ -524,6 +614,12 @@ public:
|
||||
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170003;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight =
|
||||
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170006;
|
||||
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight =
|
||||
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
|
||||
|
||||
// The best chain should have at least this much work.
|
||||
consensus.nMinimumChainWork = uint256S("0x00");
|
||||
|
||||
pchMessageStart[0] = 0xaa;
|
||||
pchMessageStart[1] = 0x8e;
|
||||
@@ -581,6 +677,11 @@ public:
|
||||
base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C};
|
||||
base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08};
|
||||
|
||||
bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "zregtestsapling";
|
||||
bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviewregtestsapling";
|
||||
bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivkregtestsapling";
|
||||
bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-regtest";
|
||||
|
||||
// Founders reward script expects a vector of 2-of-3 multisig addresses
|
||||
vFoundersRewardAddress = { "t2FwcEhFdNXuFMv1tcYwaBJtYVtMj8b1uTg" };
|
||||
assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight());
|
||||
@@ -632,6 +733,7 @@ bool SelectParamsFromCommandLine()
|
||||
return false;
|
||||
|
||||
SelectParams(network);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -652,10 +754,10 @@ std::string CChainParams::GetFoundersRewardAddressAtHeight(int nHeight) const {
|
||||
CScript CChainParams::GetFoundersRewardScriptAtHeight(int nHeight) const {
|
||||
assert(nHeight > 0 && nHeight <= consensus.GetLastFoundersRewardBlockHeight());
|
||||
|
||||
CBitcoinAddress address(GetFoundersRewardAddressAtHeight(nHeight).c_str());
|
||||
assert(address.IsValid());
|
||||
assert(address.IsScript());
|
||||
CScriptID scriptID = boost::get<CScriptID>(address.Get()); // Get() returns a boost variant
|
||||
CTxDestination address = DecodeDestination(GetFoundersRewardAddressAtHeight(nHeight).c_str());
|
||||
assert(IsValidDestination(address));
|
||||
assert(boost::get<CScriptID>(&address) != nullptr);
|
||||
CScriptID scriptID = boost::get<CScriptID>(address); // address is a boost variant
|
||||
CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
|
||||
return script;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,15 @@ public:
|
||||
double fTransactionsPerDay;
|
||||
};
|
||||
|
||||
enum Bech32Type {
|
||||
SAPLING_PAYMENT_ADDRESS,
|
||||
SAPLING_FULL_VIEWING_KEY,
|
||||
SAPLING_INCOMING_VIEWING_KEY,
|
||||
SAPLING_EXTENDED_SPEND_KEY,
|
||||
|
||||
MAX_BECH32_TYPES
|
||||
};
|
||||
|
||||
const Consensus::Params& GetConsensus() const { return consensus; }
|
||||
const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
|
||||
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
|
||||
@@ -70,11 +79,11 @@ public:
|
||||
bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; }
|
||||
/** Policy: Filter transactions that do not match well-defined patterns */
|
||||
bool RequireStandard() const { return fRequireStandard; }
|
||||
int64_t MaxTipAge() const { return nMaxTipAge; }
|
||||
int64_t PruneAfterHeight() const { return nPruneAfterHeight; }
|
||||
unsigned int EquihashN() const { return nEquihashN; }
|
||||
unsigned int EquihashK() const { return nEquihashK; }
|
||||
std::string CurrencyUnits() const { return strCurrencyUnits; }
|
||||
uint32_t BIP44CoinType() const { return bip44CoinType; }
|
||||
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
|
||||
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
|
||||
/** In the future use NetworkIDString() for RPC fields */
|
||||
@@ -83,6 +92,7 @@ public:
|
||||
std::string NetworkIDString() const { return strNetworkID; }
|
||||
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
|
||||
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
|
||||
const std::string& Bech32HRP(Bech32Type type) const { return bech32HRPs[type]; }
|
||||
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
|
||||
const CCheckpointData& Checkpoints() const { return checkpointData; }
|
||||
/** Return the founder's reward address and script for a given block height */
|
||||
@@ -99,7 +109,6 @@ public:
|
||||
//void settimestamp(uint32_t timestamp) { genesis.nTime = timestamp; }
|
||||
//void setgenesis(CBlock &block) { genesis = block; }
|
||||
//void recalc_genesis(uint32_t nonce) { genesis = CreateGenesisBlock(ASSETCHAINS_TIMESTAMP, nonce, GENESIS_NBITS, 1, COIN); };
|
||||
int nDefaultPort = 0;
|
||||
CMessageHeader::MessageStartChars pchMessageStart; // jl777 moved
|
||||
Consensus::Params consensus;
|
||||
|
||||
@@ -110,13 +119,16 @@ protected:
|
||||
std::vector<unsigned char> vAlertPubKey;
|
||||
int nMinerThreads = 0;
|
||||
long nMaxTipAge = 0;
|
||||
int nDefaultPort = 0;
|
||||
uint64_t nPruneAfterHeight = 0;
|
||||
unsigned int nEquihashN = 0;
|
||||
unsigned int nEquihashK = 0;
|
||||
std::vector<CDNSSeedData> vSeeds;
|
||||
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
|
||||
std::string bech32HRPs[MAX_BECH32_TYPES];
|
||||
std::string strNetworkID;
|
||||
std::string strCurrencyUnits;
|
||||
uint32_t bip44CoinType;
|
||||
CBlock genesis;
|
||||
std::vector<SeedSpec6> vFixedSeeds;
|
||||
bool fMiningRequiresPeers = false;
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
* IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.
|
||||
*/
|
||||
static SeedSpec6 pnSeed6_main[] = {
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0xec}, 27485},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0xec}, 27487},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x40,0x69,0x6f}, 27485},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x40,0x69,0x6f}, 27487},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0x48}, 27485},
|
||||
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x30,0x48}, 27487}
|
||||
};
|
||||
|
||||
static SeedSpec6 pnSeed6_test[] = {
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
|
||||
//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
|
||||
#define CLIENT_VERSION_MAJOR 1
|
||||
#define CLIENT_VERSION_MAJOR 2
|
||||
#define CLIENT_VERSION_MINOR 0
|
||||
#define CLIENT_VERSION_REVISION 15
|
||||
#define CLIENT_VERSION_BUILD 52
|
||||
#define CLIENT_VERSION_BUILD 26
|
||||
|
||||
//! Set to true for release, false for prerelease or test build
|
||||
#define CLIENT_VERSION_IS_RELEASE true
|
||||
@@ -27,7 +27,7 @@
|
||||
* Copyright year (2009-this)
|
||||
* Todo: update this when changing our copyright comments in the source
|
||||
*/
|
||||
#define COPYRIGHT_YEAR 2017
|
||||
#define COPYRIGHT_YEAR 2018
|
||||
|
||||
#endif //HAVE_CONFIG_H
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#define DO_STRINGIZE(X) #X
|
||||
|
||||
//! Copyright string used in Windows .rc files
|
||||
#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers and The Zcash developers"
|
||||
#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers, The Zcash developers, Komodo developers, and Verus developers"
|
||||
|
||||
/**
|
||||
* bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
|
||||
|
||||
427
src/coins.cpp
427
src/coins.cpp
@@ -44,34 +44,42 @@ bool CCoins::Spend(uint32_t nPos)
|
||||
Cleanup();
|
||||
return true;
|
||||
}
|
||||
bool CCoinsView::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return false; }
|
||||
bool CCoinsView::GetNullifier(const uint256 &nullifier) const { return false; }
|
||||
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; }
|
||||
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
|
||||
uint256 CCoinsView::GetBestBlock() const { return uint256(); }
|
||||
uint256 CCoinsView::GetBestAnchor() const { return uint256(); };
|
||||
uint256 CCoinsView::GetBestAnchor(ShieldedType type) const { return uint256(); };
|
||||
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins,
|
||||
const uint256 &hashBlock,
|
||||
const uint256 &hashAnchor,
|
||||
CAnchorsMap &mapAnchors,
|
||||
CNullifiersMap &mapNullifiers) { return false; }
|
||||
const uint256 &hashSproutAnchor,
|
||||
const uint256 &hashSaplingAnchor,
|
||||
CAnchorsSproutMap &mapSproutAnchors,
|
||||
CAnchorsSaplingMap &mapSaplingAnchors,
|
||||
CNullifiersMap &mapSproutNullifiers,
|
||||
CNullifiersMap &mapSaplingNullifiers) { return false; }
|
||||
bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; }
|
||||
|
||||
|
||||
CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
|
||||
|
||||
bool CCoinsViewBacked::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return base->GetAnchorAt(rt, tree); }
|
||||
bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier) const { return base->GetNullifier(nullifier); }
|
||||
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); }
|
||||
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
|
||||
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
|
||||
uint256 CCoinsViewBacked::GetBestAnchor() const { return base->GetBestAnchor(); }
|
||||
uint256 CCoinsViewBacked::GetBestAnchor(ShieldedType type) const { return base->GetBestAnchor(type); }
|
||||
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
|
||||
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins,
|
||||
const uint256 &hashBlock,
|
||||
const uint256 &hashAnchor,
|
||||
CAnchorsMap &mapAnchors,
|
||||
CNullifiersMap &mapNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashAnchor, mapAnchors, mapNullifiers); }
|
||||
const uint256 &hashSproutAnchor,
|
||||
const uint256 &hashSaplingAnchor,
|
||||
CAnchorsSproutMap &mapSproutAnchors,
|
||||
CAnchorsSaplingMap &mapSaplingAnchors,
|
||||
CNullifiersMap &mapSproutNullifiers,
|
||||
CNullifiersMap &mapSaplingNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, mapSproutAnchors, mapSaplingAnchors, mapSproutNullifiers, mapSaplingNullifiers); }
|
||||
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); }
|
||||
|
||||
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
|
||||
@@ -85,8 +93,10 @@ CCoinsViewCache::~CCoinsViewCache()
|
||||
|
||||
size_t CCoinsViewCache::DynamicMemoryUsage() const {
|
||||
return memusage::DynamicUsage(cacheCoins) +
|
||||
memusage::DynamicUsage(cacheAnchors) +
|
||||
memusage::DynamicUsage(cacheNullifiers) +
|
||||
memusage::DynamicUsage(cacheSproutAnchors) +
|
||||
memusage::DynamicUsage(cacheSaplingAnchors) +
|
||||
memusage::DynamicUsage(cacheSproutNullifiers) +
|
||||
memusage::DynamicUsage(cacheSaplingNullifiers) +
|
||||
cachedCoinsUsage;
|
||||
}
|
||||
|
||||
@@ -109,9 +119,9 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const
|
||||
}
|
||||
|
||||
|
||||
bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const {
|
||||
CAnchorsMap::const_iterator it = cacheAnchors.find(rt);
|
||||
if (it != cacheAnchors.end()) {
|
||||
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;
|
||||
@@ -120,11 +130,11 @@ bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tr
|
||||
}
|
||||
}
|
||||
|
||||
if (!base->GetAnchorAt(rt, tree)) {
|
||||
if (!base->GetSproutAnchorAt(rt, tree)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CAnchorsMap::iterator ret = cacheAnchors.insert(std::make_pair(rt, CAnchorsCacheEntry())).first;
|
||||
CAnchorsSproutMap::iterator ret = cacheSproutAnchors.insert(std::make_pair(rt, CAnchorsSproutCacheEntry())).first;
|
||||
ret->second.entered = true;
|
||||
ret->second.tree = tree;
|
||||
cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage();
|
||||
@@ -132,24 +142,65 @@ bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tr
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::GetNullifier(const uint256 &nullifier) const {
|
||||
CNullifiersMap::iterator it = cacheNullifiers.find(nullifier);
|
||||
if (it != cacheNullifiers.end())
|
||||
bool CCoinsViewCache::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const {
|
||||
CAnchorsSaplingMap::const_iterator it = cacheSaplingAnchors.find(rt);
|
||||
if (it != cacheSaplingAnchors.end()) {
|
||||
if (it->second.entered) {
|
||||
tree = it->second.tree;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!base->GetSaplingAnchorAt(rt, tree)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CAnchorsSaplingMap::iterator ret = cacheSaplingAnchors.insert(std::make_pair(rt, CAnchorsSaplingCacheEntry())).first;
|
||||
ret->second.entered = true;
|
||||
ret->second.tree = tree;
|
||||
cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::GetNullifier(const uint256 &nullifier, ShieldedType type) const {
|
||||
CNullifiersMap* cacheToUse;
|
||||
switch (type) {
|
||||
case SPROUT:
|
||||
cacheToUse = &cacheSproutNullifiers;
|
||||
break;
|
||||
case SAPLING:
|
||||
cacheToUse = &cacheSaplingNullifiers;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown shielded type");
|
||||
}
|
||||
CNullifiersMap::iterator it = cacheToUse->find(nullifier);
|
||||
if (it != cacheToUse->end())
|
||||
return it->second.entered;
|
||||
|
||||
CNullifiersCacheEntry entry;
|
||||
bool tmp = base->GetNullifier(nullifier);
|
||||
bool tmp = base->GetNullifier(nullifier, type);
|
||||
entry.entered = tmp;
|
||||
|
||||
cacheNullifiers.insert(std::make_pair(nullifier, entry));
|
||||
cacheToUse->insert(std::make_pair(nullifier, entry));
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void CCoinsViewCache::PushAnchor(const ZCIncrementalMerkleTree &tree) {
|
||||
template<typename Tree, typename Cache, typename CacheIterator, typename CacheEntry>
|
||||
void CCoinsViewCache::AbstractPushAnchor(
|
||||
const Tree &tree,
|
||||
ShieldedType type,
|
||||
Cache &cacheAnchors,
|
||||
uint256 &hash
|
||||
)
|
||||
{
|
||||
uint256 newrt = tree.root();
|
||||
|
||||
auto currentRoot = GetBestAnchor();
|
||||
auto currentRoot = GetBestAnchor(type);
|
||||
|
||||
// We don't want to overwrite an anchor we already have.
|
||||
// This occurs when a block doesn't modify mapAnchors at all,
|
||||
@@ -157,24 +208,69 @@ void CCoinsViewCache::PushAnchor(const ZCIncrementalMerkleTree &tree) {
|
||||
// different way (make all blocks modify mapAnchors somehow)
|
||||
// but this is simpler to reason about.
|
||||
if (currentRoot != newrt) {
|
||||
auto insertRet = cacheAnchors.insert(std::make_pair(newrt, CAnchorsCacheEntry()));
|
||||
CAnchorsMap::iterator ret = insertRet.first;
|
||||
auto insertRet = cacheAnchors.insert(std::make_pair(newrt, CacheEntry()));
|
||||
CacheIterator ret = insertRet.first;
|
||||
|
||||
ret->second.entered = true;
|
||||
ret->second.tree = tree;
|
||||
ret->second.flags = CAnchorsCacheEntry::DIRTY;
|
||||
ret->second.flags = CacheEntry::DIRTY;
|
||||
|
||||
if (insertRet.second) {
|
||||
// An insert took place
|
||||
cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage();
|
||||
}
|
||||
|
||||
hashAnchor = newrt;
|
||||
hash = newrt;
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinsViewCache::PopAnchor(const uint256 &newrt) {
|
||||
auto currentRoot = GetBestAnchor();
|
||||
template<> void CCoinsViewCache::PushAnchor(const SproutMerkleTree &tree)
|
||||
{
|
||||
AbstractPushAnchor<SproutMerkleTree, CAnchorsSproutMap, CAnchorsSproutMap::iterator, CAnchorsSproutCacheEntry>(
|
||||
tree,
|
||||
SPROUT,
|
||||
cacheSproutAnchors,
|
||||
hashSproutAnchor
|
||||
);
|
||||
}
|
||||
|
||||
template<> void CCoinsViewCache::PushAnchor(const SaplingMerkleTree &tree)
|
||||
{
|
||||
AbstractPushAnchor<SaplingMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry>(
|
||||
tree,
|
||||
SAPLING,
|
||||
cacheSaplingAnchors,
|
||||
hashSaplingAnchor
|
||||
);
|
||||
}
|
||||
|
||||
template<>
|
||||
void CCoinsViewCache::BringBestAnchorIntoCache(
|
||||
const uint256 ¤tRoot,
|
||||
SproutMerkleTree &tree
|
||||
)
|
||||
{
|
||||
assert(GetSproutAnchorAt(currentRoot, tree));
|
||||
}
|
||||
|
||||
template<>
|
||||
void CCoinsViewCache::BringBestAnchorIntoCache(
|
||||
const uint256 ¤tRoot,
|
||||
SaplingMerkleTree &tree
|
||||
)
|
||||
{
|
||||
assert(GetSaplingAnchorAt(currentRoot, tree));
|
||||
}
|
||||
|
||||
template<typename Tree, typename Cache, typename CacheEntry>
|
||||
void CCoinsViewCache::AbstractPopAnchor(
|
||||
const uint256 &newrt,
|
||||
ShieldedType type,
|
||||
Cache &cacheAnchors,
|
||||
uint256 &hash
|
||||
)
|
||||
{
|
||||
auto currentRoot = GetBestAnchor(type);
|
||||
|
||||
// Blocks might not change the commitment tree, in which
|
||||
// case restoring the "old" anchor during a reorg must
|
||||
@@ -183,25 +279,57 @@ void CCoinsViewCache::PopAnchor(const uint256 &newrt) {
|
||||
// Bring the current best anchor into our local cache
|
||||
// so that its tree exists in memory.
|
||||
{
|
||||
ZCIncrementalMerkleTree tree;
|
||||
assert(GetAnchorAt(currentRoot, tree));
|
||||
Tree tree;
|
||||
BringBestAnchorIntoCache(currentRoot, tree);
|
||||
}
|
||||
|
||||
// Mark the anchor as unentered, removing it from view
|
||||
cacheAnchors[currentRoot].entered = false;
|
||||
|
||||
// Mark the cache entry as dirty so it's propagated
|
||||
cacheAnchors[currentRoot].flags = CAnchorsCacheEntry::DIRTY;
|
||||
cacheAnchors[currentRoot].flags = CacheEntry::DIRTY;
|
||||
|
||||
// Mark the new root as the best anchor
|
||||
hashAnchor = newrt;
|
||||
hash = newrt;
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinsViewCache::SetNullifier(const uint256 &nullifier, bool spent) {
|
||||
std::pair<CNullifiersMap::iterator, bool> ret = cacheNullifiers.insert(std::make_pair(nullifier, CNullifiersCacheEntry()));
|
||||
ret.first->second.entered = spent;
|
||||
ret.first->second.flags |= CNullifiersCacheEntry::DIRTY;
|
||||
void CCoinsViewCache::PopAnchor(const uint256 &newrt, ShieldedType type) {
|
||||
switch (type) {
|
||||
case SPROUT:
|
||||
AbstractPopAnchor<SproutMerkleTree, CAnchorsSproutMap, CAnchorsSproutCacheEntry>(
|
||||
newrt,
|
||||
SPROUT,
|
||||
cacheSproutAnchors,
|
||||
hashSproutAnchor
|
||||
);
|
||||
break;
|
||||
case SAPLING:
|
||||
AbstractPopAnchor<SaplingMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingCacheEntry>(
|
||||
newrt,
|
||||
SAPLING,
|
||||
cacheSaplingAnchors,
|
||||
hashSaplingAnchor
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown shielded type");
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinsViewCache::SetNullifiers(const CTransaction& tx, bool spent) {
|
||||
for (const JSDescription &joinsplit : tx.vjoinsplit) {
|
||||
for (const uint256 &nullifier : joinsplit.nullifiers) {
|
||||
std::pair<CNullifiersMap::iterator, bool> ret = cacheSproutNullifiers.insert(std::make_pair(nullifier, CNullifiersCacheEntry()));
|
||||
ret.first->second.entered = spent;
|
||||
ret.first->second.flags |= CNullifiersCacheEntry::DIRTY;
|
||||
}
|
||||
}
|
||||
for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
|
||||
std::pair<CNullifiersMap::iterator, bool> ret = cacheSaplingNullifiers.insert(std::make_pair(spendDescription.nullifier, CNullifiersCacheEntry()));
|
||||
ret.first->second.entered = spent;
|
||||
ret.first->second.flags |= CNullifiersCacheEntry::DIRTY;
|
||||
}
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
|
||||
@@ -254,26 +382,104 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
|
||||
|
||||
uint256 CCoinsViewCache::GetBestBlock() const {
|
||||
if (hashBlock.IsNull())
|
||||
hashBlock = base->GetBestBlock();
|
||||
{
|
||||
if (base)
|
||||
{
|
||||
hashBlock = base->GetBestBlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
hashBlock = uint256();
|
||||
}
|
||||
}
|
||||
return hashBlock;
|
||||
}
|
||||
|
||||
|
||||
uint256 CCoinsViewCache::GetBestAnchor() const {
|
||||
if (hashAnchor.IsNull())
|
||||
hashAnchor = base->GetBestAnchor();
|
||||
return hashAnchor;
|
||||
uint256 CCoinsViewCache::GetBestAnchor(ShieldedType type) const {
|
||||
switch (type) {
|
||||
case SPROUT:
|
||||
if (hashSproutAnchor.IsNull())
|
||||
hashSproutAnchor = base->GetBestAnchor(type);
|
||||
return hashSproutAnchor;
|
||||
break;
|
||||
case SAPLING:
|
||||
if (hashSaplingAnchor.IsNull())
|
||||
hashSaplingAnchor = base->GetBestAnchor(type);
|
||||
return hashSaplingAnchor;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown shielded type");
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
|
||||
hashBlock = hashBlockIn;
|
||||
}
|
||||
|
||||
void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNullifiers)
|
||||
{
|
||||
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);
|
||||
|
||||
if (parent_it == cacheNullifiers.end()) {
|
||||
CNullifiersCacheEntry& entry = cacheNullifiers[child_it->first];
|
||||
entry.entered = child_it->second.entered;
|
||||
entry.flags = CNullifiersCacheEntry::DIRTY;
|
||||
} else {
|
||||
if (parent_it->second.entered != child_it->second.entered) {
|
||||
parent_it->second.entered = child_it->second.entered;
|
||||
parent_it->second.flags |= CNullifiersCacheEntry::DIRTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
CNullifiersMap::iterator itOld = child_it++;
|
||||
mapNullifiers.erase(itOld);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Map, typename MapIterator, typename MapEntry>
|
||||
void BatchWriteAnchors(
|
||||
Map &mapAnchors,
|
||||
Map &cacheAnchors,
|
||||
size_t &cachedCoinsUsage
|
||||
)
|
||||
{
|
||||
for (MapIterator child_it = mapAnchors.begin(); child_it != mapAnchors.end();)
|
||||
{
|
||||
if (child_it->second.flags & MapEntry::DIRTY) {
|
||||
MapIterator parent_it = cacheAnchors.find(child_it->first);
|
||||
|
||||
if (parent_it == cacheAnchors.end()) {
|
||||
MapEntry& entry = cacheAnchors[child_it->first];
|
||||
entry.entered = child_it->second.entered;
|
||||
entry.tree = child_it->second.tree;
|
||||
entry.flags = MapEntry::DIRTY;
|
||||
|
||||
cachedCoinsUsage += entry.tree.DynamicMemoryUsage();
|
||||
} else {
|
||||
if (parent_it->second.entered != child_it->second.entered) {
|
||||
// The parent may have removed the entry.
|
||||
parent_it->second.entered = child_it->second.entered;
|
||||
parent_it->second.flags |= MapEntry::DIRTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MapIterator itOld = child_it++;
|
||||
mapAnchors.erase(itOld);
|
||||
}
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins,
|
||||
const uint256 &hashBlockIn,
|
||||
const uint256 &hashAnchorIn,
|
||||
CAnchorsMap &mapAnchors,
|
||||
CNullifiersMap &mapNullifiers) {
|
||||
const uint256 &hashSproutAnchorIn,
|
||||
const uint256 &hashSaplingAnchorIn,
|
||||
CAnchorsSproutMap &mapSproutAnchors,
|
||||
CAnchorsSaplingMap &mapSaplingAnchors,
|
||||
CNullifiersMap &mapSproutNullifiers,
|
||||
CNullifiersMap &mapSaplingNullifiers) {
|
||||
assert(!hasModifier);
|
||||
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
|
||||
if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
|
||||
@@ -310,61 +516,25 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins,
|
||||
mapCoins.erase(itOld);
|
||||
}
|
||||
|
||||
for (CAnchorsMap::iterator child_it = mapAnchors.begin(); child_it != mapAnchors.end();)
|
||||
{
|
||||
if (child_it->second.flags & CAnchorsCacheEntry::DIRTY) {
|
||||
CAnchorsMap::iterator parent_it = cacheAnchors.find(child_it->first);
|
||||
::BatchWriteAnchors<CAnchorsSproutMap, CAnchorsSproutMap::iterator, CAnchorsSproutCacheEntry>(mapSproutAnchors, cacheSproutAnchors, cachedCoinsUsage);
|
||||
::BatchWriteAnchors<CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry>(mapSaplingAnchors, cacheSaplingAnchors, cachedCoinsUsage);
|
||||
|
||||
if (parent_it == cacheAnchors.end()) {
|
||||
CAnchorsCacheEntry& entry = cacheAnchors[child_it->first];
|
||||
entry.entered = child_it->second.entered;
|
||||
entry.tree = child_it->second.tree;
|
||||
entry.flags = CAnchorsCacheEntry::DIRTY;
|
||||
::BatchWriteNullifiers(mapSproutNullifiers, cacheSproutNullifiers);
|
||||
::BatchWriteNullifiers(mapSaplingNullifiers, cacheSaplingNullifiers);
|
||||
|
||||
cachedCoinsUsage += entry.tree.DynamicMemoryUsage();
|
||||
} else {
|
||||
if (parent_it->second.entered != child_it->second.entered) {
|
||||
// The parent may have removed the entry.
|
||||
parent_it->second.entered = child_it->second.entered;
|
||||
parent_it->second.flags |= CAnchorsCacheEntry::DIRTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CAnchorsMap::iterator itOld = child_it++;
|
||||
mapAnchors.erase(itOld);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (parent_it == cacheNullifiers.end()) {
|
||||
CNullifiersCacheEntry& entry = cacheNullifiers[child_it->first];
|
||||
entry.entered = child_it->second.entered;
|
||||
entry.flags = CNullifiersCacheEntry::DIRTY;
|
||||
} else {
|
||||
if (parent_it->second.entered != child_it->second.entered) {
|
||||
parent_it->second.entered = child_it->second.entered;
|
||||
parent_it->second.flags |= CNullifiersCacheEntry::DIRTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
CNullifiersMap::iterator itOld = child_it++;
|
||||
mapNullifiers.erase(itOld);
|
||||
}
|
||||
|
||||
hashAnchor = hashAnchorIn;
|
||||
hashSproutAnchor = hashSproutAnchorIn;
|
||||
hashSaplingAnchor = hashSaplingAnchorIn;
|
||||
hashBlock = hashBlockIn;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoinsViewCache::Flush() {
|
||||
bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashAnchor, cacheAnchors, cacheNullifiers);
|
||||
bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, cacheSproutAnchors, cacheSaplingAnchors, cacheSproutNullifiers, cacheSaplingNullifiers);
|
||||
cacheCoins.clear();
|
||||
cacheAnchors.clear();
|
||||
cacheNullifiers.clear();
|
||||
cacheSproutAnchors.clear();
|
||||
cacheSaplingAnchors.clear();
|
||||
cacheSproutNullifiers.clear();
|
||||
cacheSaplingNullifiers.clear();
|
||||
cachedCoinsUsage = 0;
|
||||
return fOk;
|
||||
}
|
||||
@@ -380,17 +550,34 @@ const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const
|
||||
return coins->vout[input.prevout.n];
|
||||
}
|
||||
|
||||
const CScript &CCoinsViewCache::GetSpendFor(const CTxIn& input) const
|
||||
{
|
||||
const CCoins* coins = AccessCoins(input.prevout.hash);
|
||||
assert(coins);
|
||||
return coins->vout[input.prevout.n].scriptPubKey;
|
||||
}
|
||||
|
||||
//uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
|
||||
uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight);
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
|
||||
const CScript &CCoinsViewCache::GetSpendFor(const CCoins *coins, const CTxIn& input)
|
||||
{
|
||||
assert(coins);
|
||||
if (coins->nHeight < 6400 && !strcmp(ASSETCHAINS_SYMBOL, "VRSC"))
|
||||
{
|
||||
std::string hc = input.prevout.hash.ToString();
|
||||
if (LaunchMap().lmap.count(hc))
|
||||
{
|
||||
CTransactionExceptionData &txData = LaunchMap().lmap[hc];
|
||||
if ((txData.voutMask & (((uint64_t)1) << (uint64_t)input.prevout.n)) != 0)
|
||||
{
|
||||
return txData.scriptPubKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
return coins->vout[input.prevout.n].scriptPubKey;
|
||||
}
|
||||
|
||||
const CScript &CCoinsViewCache::GetSpendFor(const CTxIn& input) const
|
||||
{
|
||||
const CCoins* coins = AccessCoins(input.prevout.hash);
|
||||
return GetSpendFor(coins, input);
|
||||
}
|
||||
|
||||
CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTransaction& tx,uint32_t tiptime) const
|
||||
{
|
||||
CAmount value,nResult = 0;
|
||||
@@ -419,7 +606,7 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr
|
||||
}
|
||||
#endif
|
||||
}
|
||||
nResult += tx.GetJoinSplitValueIn();
|
||||
nResult += tx.GetShieldedValueIn();
|
||||
|
||||
return nResult;
|
||||
}
|
||||
@@ -427,24 +614,24 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr
|
||||
|
||||
bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const
|
||||
{
|
||||
boost::unordered_map<uint256, ZCIncrementalMerkleTree, CCoinsKeyHasher> intermediates;
|
||||
boost::unordered_map<uint256, SproutMerkleTree, CCoinsKeyHasher> intermediates;
|
||||
|
||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit)
|
||||
{
|
||||
BOOST_FOREACH(const uint256& nullifier, joinsplit.nullifiers)
|
||||
{
|
||||
if (GetNullifier(nullifier)) {
|
||||
if (GetNullifier(nullifier, SPROUT)) {
|
||||
// If the nullifier is set, this transaction
|
||||
// double-spends!
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ZCIncrementalMerkleTree tree;
|
||||
SproutMerkleTree tree;
|
||||
auto it = intermediates.find(joinsplit.anchor);
|
||||
if (it != intermediates.end()) {
|
||||
tree = it->second;
|
||||
} else if (!GetAnchorAt(joinsplit.anchor, tree)) {
|
||||
} else if (!GetSproutAnchorAt(joinsplit.anchor, tree)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -456,6 +643,16 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const
|
||||
intermediates.insert(std::make_pair(tree.root(), tree));
|
||||
}
|
||||
|
||||
for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
|
||||
if (GetNullifier(spendDescription.nullifier, SAPLING)) // Prevent double spends
|
||||
return false;
|
||||
|
||||
SaplingMerkleTree tree;
|
||||
if (!GetSaplingAnchorAt(spendDescription.anchor, tree)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -478,19 +675,17 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
|
||||
{
|
||||
if (tx.IsCoinBase())
|
||||
return 0.0;
|
||||
// Joinsplits do not reveal any information about the value or age of a note, so we
|
||||
|
||||
// Shielded transfers do not reveal any information about the value or age of a note, so we
|
||||
// cannot apply the priority algorithm used for transparent utxos. Instead, we just
|
||||
// use the maximum priority whenever a transaction contains any JoinSplits.
|
||||
// (Note that coinbase transactions cannot contain JoinSplits.)
|
||||
// FIXME: this logic is partially duplicated between here and CreateNewBlock in miner.cpp.
|
||||
|
||||
if (tx.vjoinsplit.size() > 0) {
|
||||
return MAX_PRIORITY;
|
||||
}
|
||||
if (tx.IsCoinImport()) {
|
||||
// use the maximum priority for all (partially or fully) shielded transactions.
|
||||
// (Note that coinbase transactions cannot contain JoinSplits, or Sapling shielded Spends or Outputs.)
|
||||
|
||||
if (tx.vjoinsplit.size() > 0 || tx.vShieldedSpend.size() > 0 || tx.vShieldedOutput.size() > 0 || tx.IsCoinImport()) {
|
||||
return MAX_PRIORITY;
|
||||
}
|
||||
|
||||
// FIXME: this logic is partially duplicated between here and CreateNewBlock in miner.cpp.
|
||||
double dResult = 0.0;
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
{
|
||||
|
||||
222
src/coins.h
222
src/coins.h
@@ -13,13 +13,18 @@
|
||||
#include "memusage.h"
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
#include "base58.h"
|
||||
#include "pubkey.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "zcash/IncrementalMerkleTree.hpp"
|
||||
#include "veruslaunch.h"
|
||||
|
||||
/**
|
||||
* Pruned version of CTransaction: only retains metadata and unspent transaction outputs
|
||||
@@ -157,31 +162,8 @@ public:
|
||||
return fCoinBase;
|
||||
}
|
||||
|
||||
unsigned int GetSerializeSize(int nType, int nVersion) const {
|
||||
unsigned int nSize = 0;
|
||||
unsigned int nMaskSize = 0, nMaskCode = 0;
|
||||
CalcMaskSize(nMaskSize, nMaskCode);
|
||||
bool fFirst = vout.size() > 0 && !vout[0].IsNull();
|
||||
bool fSecond = vout.size() > 1 && !vout[1].IsNull();
|
||||
assert(fFirst || fSecond || nMaskCode);
|
||||
unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
|
||||
// version
|
||||
nSize += ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion);
|
||||
// size of header code
|
||||
nSize += ::GetSerializeSize(VARINT(nCode), nType, nVersion);
|
||||
// spentness bitmask
|
||||
nSize += nMaskSize;
|
||||
// txouts
|
||||
for (unsigned int i = 0; i < vout.size(); i++)
|
||||
if (!vout[i].IsNull())
|
||||
nSize += ::GetSerializeSize(CTxOutCompressor(REF(vout[i])), nType, nVersion);
|
||||
// height
|
||||
nSize += ::GetSerializeSize(VARINT(nHeight), nType, nVersion);
|
||||
return nSize;
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream &s, int nType, int nVersion) const {
|
||||
void Serialize(Stream &s) const {
|
||||
unsigned int nMaskSize = 0, nMaskCode = 0;
|
||||
CalcMaskSize(nMaskSize, nMaskCode);
|
||||
bool fFirst = vout.size() > 0 && !vout[0].IsNull();
|
||||
@@ -189,33 +171,33 @@ public:
|
||||
assert(fFirst || fSecond || nMaskCode);
|
||||
unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
|
||||
// version
|
||||
::Serialize(s, VARINT(this->nVersion), nType, nVersion);
|
||||
::Serialize(s, VARINT(this->nVersion));
|
||||
// header code
|
||||
::Serialize(s, VARINT(nCode), nType, nVersion);
|
||||
::Serialize(s, VARINT(nCode));
|
||||
// spentness bitmask
|
||||
for (unsigned int b = 0; b<nMaskSize; b++) {
|
||||
unsigned char chAvail = 0;
|
||||
for (unsigned int i = 0; i < 8 && 2+b*8+i < vout.size(); i++)
|
||||
if (!vout[2+b*8+i].IsNull())
|
||||
chAvail |= (1 << i);
|
||||
::Serialize(s, chAvail, nType, nVersion);
|
||||
::Serialize(s, chAvail);
|
||||
}
|
||||
// txouts themself
|
||||
for (unsigned int i = 0; i < vout.size(); i++) {
|
||||
if (!vout[i].IsNull())
|
||||
::Serialize(s, CTxOutCompressor(REF(vout[i])), nType, nVersion);
|
||||
::Serialize(s, CTxOutCompressor(REF(vout[i])));
|
||||
}
|
||||
// coinbase height
|
||||
::Serialize(s, VARINT(nHeight), nType, nVersion);
|
||||
::Serialize(s, VARINT(nHeight));
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream &s, int nType, int nVersion) {
|
||||
void Unserialize(Stream &s) {
|
||||
unsigned int nCode = 0;
|
||||
// version
|
||||
::Unserialize(s, VARINT(this->nVersion), nType, nVersion);
|
||||
::Unserialize(s, VARINT(this->nVersion));
|
||||
// header code
|
||||
::Unserialize(s, VARINT(nCode), nType, nVersion);
|
||||
::Unserialize(s, VARINT(nCode));
|
||||
fCoinBase = nCode & 1;
|
||||
std::vector<bool> vAvail(2, false);
|
||||
vAvail[0] = (nCode & 2) != 0;
|
||||
@@ -224,7 +206,7 @@ public:
|
||||
// spentness bitmask
|
||||
while (nMaskCode > 0) {
|
||||
unsigned char chAvail = 0;
|
||||
::Unserialize(s, chAvail, nType, nVersion);
|
||||
::Unserialize(s, chAvail);
|
||||
for (unsigned int p = 0; p < 8; p++) {
|
||||
bool f = (chAvail & (1 << p)) != 0;
|
||||
vAvail.push_back(f);
|
||||
@@ -236,10 +218,10 @@ public:
|
||||
vout.assign(vAvail.size(), CTxOut());
|
||||
for (unsigned int i = 0; i < vAvail.size(); i++) {
|
||||
if (vAvail[i])
|
||||
::Unserialize(s, REF(CTxOutCompressor(vout[i])), nType, nVersion);
|
||||
::Unserialize(s, REF(CTxOutCompressor(vout[i])));
|
||||
}
|
||||
// coinbase height
|
||||
::Unserialize(s, VARINT(nHeight), nType, nVersion);
|
||||
::Unserialize(s, VARINT(nHeight));
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
@@ -267,6 +249,14 @@ public:
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t TotalTxValue() const {
|
||||
int64_t total = 0;
|
||||
BOOST_FOREACH(const CTxOut &out, vout) {
|
||||
total += out.nValue;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
};
|
||||
|
||||
class CCoinsKeyHasher
|
||||
@@ -300,17 +290,30 @@ struct CCoinsCacheEntry
|
||||
CCoinsCacheEntry() : coins(), flags(0) {}
|
||||
};
|
||||
|
||||
struct CAnchorsCacheEntry
|
||||
struct CAnchorsSproutCacheEntry
|
||||
{
|
||||
bool entered; // This will be false if the anchor is removed from the cache
|
||||
ZCIncrementalMerkleTree tree; // The tree itself
|
||||
SproutMerkleTree tree; // The tree itself
|
||||
unsigned char flags;
|
||||
|
||||
enum Flags {
|
||||
DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
|
||||
};
|
||||
|
||||
CAnchorsCacheEntry() : entered(false), flags(0) {}
|
||||
CAnchorsSproutCacheEntry() : entered(false), flags(0) {}
|
||||
};
|
||||
|
||||
struct CAnchorsSaplingCacheEntry
|
||||
{
|
||||
bool entered; // This will be false if the anchor is removed from the cache
|
||||
SaplingMerkleTree tree; // The tree itself
|
||||
unsigned char flags;
|
||||
|
||||
enum Flags {
|
||||
DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
|
||||
};
|
||||
|
||||
CAnchorsSaplingCacheEntry() : entered(false), flags(0) {}
|
||||
};
|
||||
|
||||
struct CNullifiersCacheEntry
|
||||
@@ -325,8 +328,15 @@ struct CNullifiersCacheEntry
|
||||
CNullifiersCacheEntry() : entered(false), flags(0) {}
|
||||
};
|
||||
|
||||
enum ShieldedType
|
||||
{
|
||||
SPROUT,
|
||||
SAPLING,
|
||||
};
|
||||
|
||||
typedef boost::unordered_map<uint256, CCoinsCacheEntry, CCoinsKeyHasher> CCoinsMap;
|
||||
typedef boost::unordered_map<uint256, CAnchorsCacheEntry, CCoinsKeyHasher> CAnchorsMap;
|
||||
typedef boost::unordered_map<uint256, CAnchorsSproutCacheEntry, CCoinsKeyHasher> CAnchorsSproutMap;
|
||||
typedef boost::unordered_map<uint256, CAnchorsSaplingCacheEntry, CCoinsKeyHasher> CAnchorsSaplingMap;
|
||||
typedef boost::unordered_map<uint256, CNullifiersCacheEntry, CCoinsKeyHasher> CNullifiersMap;
|
||||
|
||||
struct CCoinsStats
|
||||
@@ -347,11 +357,14 @@ struct CCoinsStats
|
||||
class CCoinsView
|
||||
{
|
||||
public:
|
||||
//! Retrieve the tree at a particular anchored root in the chain
|
||||
virtual bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const;
|
||||
//! 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;
|
||||
|
||||
//! Determine whether a nullifier is spent or not
|
||||
virtual bool GetNullifier(const uint256 &nullifier) const;
|
||||
virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||
|
||||
//! Retrieve the CCoins (unspent transaction outputs) for a given txid
|
||||
virtual bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
||||
@@ -364,15 +377,18 @@ public:
|
||||
virtual uint256 GetBestBlock() const;
|
||||
|
||||
//! Get the current "tip" or the latest anchored tree root in the chain
|
||||
virtual uint256 GetBestAnchor() const;
|
||||
virtual uint256 GetBestAnchor(ShieldedType type) const;
|
||||
|
||||
//! Do a bulk modification (multiple CCoins changes + BestBlock change).
|
||||
//! The passed mapCoins can be modified.
|
||||
virtual bool BatchWrite(CCoinsMap &mapCoins,
|
||||
const uint256 &hashBlock,
|
||||
const uint256 &hashAnchor,
|
||||
CAnchorsMap &mapAnchors,
|
||||
CNullifiersMap &mapNullifiers);
|
||||
const uint256 &hashSproutAnchor,
|
||||
const uint256 &hashSaplingAnchor,
|
||||
CAnchorsSproutMap &mapSproutAnchors,
|
||||
CAnchorsSaplingMap &mapSaplingAnchors,
|
||||
CNullifiersMap &mapSproutNullifiers,
|
||||
CNullifiersMap &mapSaplingNullifiers);
|
||||
|
||||
//! Calculate statistics about the unspent transaction output set
|
||||
virtual bool GetStats(CCoinsStats &stats) const;
|
||||
@@ -390,18 +406,22 @@ protected:
|
||||
|
||||
public:
|
||||
CCoinsViewBacked(CCoinsView *viewIn);
|
||||
bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const;
|
||||
bool GetNullifier(const uint256 &nullifier) const;
|
||||
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;
|
||||
bool HaveCoins(const uint256 &txid) const;
|
||||
uint256 GetBestBlock() const;
|
||||
uint256 GetBestAnchor() const;
|
||||
uint256 GetBestAnchor(ShieldedType type) const;
|
||||
void SetBackend(CCoinsView &viewIn);
|
||||
bool BatchWrite(CCoinsMap &mapCoins,
|
||||
const uint256 &hashBlock,
|
||||
const uint256 &hashAnchor,
|
||||
CAnchorsMap &mapAnchors,
|
||||
CNullifiersMap &mapNullifiers);
|
||||
const uint256 &hashSproutAnchor,
|
||||
const uint256 &hashSaplingAnchor,
|
||||
CAnchorsSproutMap &mapSproutAnchors,
|
||||
CAnchorsSaplingMap &mapSaplingAnchors,
|
||||
CNullifiersMap &mapSproutNullifiers,
|
||||
CNullifiersMap &mapSaplingNullifiers);
|
||||
bool GetStats(CCoinsStats &stats) const;
|
||||
};
|
||||
|
||||
@@ -428,6 +448,37 @@ public:
|
||||
friend class CCoinsViewCache;
|
||||
};
|
||||
|
||||
class CTransactionExceptionData
|
||||
{
|
||||
public:
|
||||
CScript scriptPubKey;
|
||||
uint64_t voutMask;
|
||||
CTransactionExceptionData() : scriptPubKey(), voutMask() {}
|
||||
};
|
||||
|
||||
class CLaunchMap
|
||||
{
|
||||
public:
|
||||
std::unordered_map<std::string, CTransactionExceptionData> lmap;
|
||||
CLaunchMap() : lmap()
|
||||
{
|
||||
//printf("txid: %s -> addr: %s\n", whitelist_ids[i], whitelist_addrs[i]);
|
||||
CBitcoinAddress bcaddr(whitelist_address);
|
||||
CKeyID key;
|
||||
if (bcaddr.GetKeyID_NoCheck(key))
|
||||
{
|
||||
std::vector<unsigned char> address = std::vector<unsigned char>(key.begin(), key.end());
|
||||
for (int i = 0; i < WHITELIST_COUNT; i++)
|
||||
{
|
||||
std::string hash = uint256S(whitelist_ids[i]).ToString();
|
||||
lmap[hash].scriptPubKey << OP_DUP << OP_HASH160 << address << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||
lmap[hash].voutMask = whitelist_masks[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static CLaunchMap launchMap = CLaunchMap();
|
||||
|
||||
/** CCoinsView that adds a memory cache for transactions to another CCoinsView */
|
||||
class CCoinsViewCache : public CCoinsViewBacked
|
||||
{
|
||||
@@ -435,16 +486,18 @@ protected:
|
||||
/* Whether this cache has an active modifier. */
|
||||
bool hasModifier;
|
||||
|
||||
|
||||
/**
|
||||
* Make mutable so that we can "fill the cache" even from Get-methods
|
||||
* declared as "const".
|
||||
*/
|
||||
mutable uint256 hashBlock;
|
||||
mutable CCoinsMap cacheCoins;
|
||||
mutable uint256 hashAnchor;
|
||||
mutable CAnchorsMap cacheAnchors;
|
||||
mutable CNullifiersMap cacheNullifiers;
|
||||
mutable uint256 hashSproutAnchor;
|
||||
mutable uint256 hashSaplingAnchor;
|
||||
mutable CAnchorsSproutMap cacheSproutAnchors;
|
||||
mutable CAnchorsSaplingMap cacheSaplingAnchors;
|
||||
mutable CNullifiersMap cacheSproutNullifiers;
|
||||
mutable CNullifiersMap cacheSaplingNullifiers;
|
||||
|
||||
/* Cached dynamic memory usage for the inner CCoins objects. */
|
||||
mutable size_t cachedCoinsUsage;
|
||||
@@ -454,30 +507,35 @@ public:
|
||||
~CCoinsViewCache();
|
||||
|
||||
// Standard CCoinsView methods
|
||||
bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const;
|
||||
bool GetNullifier(const uint256 &nullifier) const;
|
||||
static CLaunchMap &LaunchMap() { return launchMap; }
|
||||
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;
|
||||
bool HaveCoins(const uint256 &txid) const;
|
||||
uint256 GetBestBlock() const;
|
||||
uint256 GetBestAnchor() const;
|
||||
uint256 GetBestAnchor(ShieldedType type) const;
|
||||
void SetBestBlock(const uint256 &hashBlock);
|
||||
bool BatchWrite(CCoinsMap &mapCoins,
|
||||
const uint256 &hashBlock,
|
||||
const uint256 &hashAnchor,
|
||||
CAnchorsMap &mapAnchors,
|
||||
CNullifiersMap &mapNullifiers);
|
||||
const uint256 &hashSproutAnchor,
|
||||
const uint256 &hashSaplingAnchor,
|
||||
CAnchorsSproutMap &mapSproutAnchors,
|
||||
CAnchorsSaplingMap &mapSaplingAnchors,
|
||||
CNullifiersMap &mapSproutNullifiers,
|
||||
CNullifiersMap &mapSaplingNullifiers);
|
||||
|
||||
|
||||
// Adds the tree to mapAnchors and sets the current commitment
|
||||
// root to this root.
|
||||
void PushAnchor(const ZCIncrementalMerkleTree &tree);
|
||||
// Adds the tree to mapSproutAnchors (or mapSaplingAnchors based on the type of tree)
|
||||
// and sets the current commitment root to this root.
|
||||
template<typename Tree> void PushAnchor(const Tree &tree);
|
||||
|
||||
// Removes the current commitment root from mapAnchors and sets
|
||||
// the new current root.
|
||||
void PopAnchor(const uint256 &rt);
|
||||
void PopAnchor(const uint256 &rt, ShieldedType type);
|
||||
|
||||
// Marks a nullifier as spent or not.
|
||||
void SetNullifier(const uint256 &nullifier, bool spent);
|
||||
// Marks nullifiers for a given transaction as spent or not.
|
||||
void SetNullifiers(const CTransaction& tx, bool spent);
|
||||
|
||||
/**
|
||||
* Return a pointer to CCoins in the cache, or NULL if not found. This is
|
||||
@@ -512,7 +570,7 @@ public:
|
||||
* so may not be able to calculate this.
|
||||
*
|
||||
* @param[in] tx transaction for which we are checking input total
|
||||
* @return Sum of value of all inputs (scriptSigs)
|
||||
* @return Sum of value of all inputs (scriptSigs), (positive valueBalance or zero) and JoinSplit vpub_new
|
||||
*/
|
||||
CAmount GetValueIn(int32_t nHeight,int64_t *interestp,const CTransaction& tx,uint32_t prevblocktime) const;
|
||||
|
||||
@@ -527,6 +585,7 @@ public:
|
||||
|
||||
const CTxOut &GetOutputFor(const CTxIn& input) const;
|
||||
const CScript &GetSpendFor(const CTxIn& input) const;
|
||||
static const CScript &GetSpendFor(const CCoins *coins, const CTxIn& input);
|
||||
|
||||
friend class CCoinsModifier;
|
||||
|
||||
@@ -538,6 +597,31 @@ private:
|
||||
* By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache.
|
||||
*/
|
||||
CCoinsViewCache(const CCoinsViewCache &);
|
||||
|
||||
//! Generalized interface for popping anchors
|
||||
template<typename Tree, typename Cache, typename CacheEntry>
|
||||
void AbstractPopAnchor(
|
||||
const uint256 &newrt,
|
||||
ShieldedType type,
|
||||
Cache &cacheAnchors,
|
||||
uint256 &hash
|
||||
);
|
||||
|
||||
//! Generalized interface for pushing anchors
|
||||
template<typename Tree, typename Cache, typename CacheIterator, typename CacheEntry>
|
||||
void AbstractPushAnchor(
|
||||
const Tree &tree,
|
||||
ShieldedType type,
|
||||
Cache &cacheAnchors,
|
||||
uint256 &hash
|
||||
);
|
||||
|
||||
//! Interface for bringing an anchor into the cache.
|
||||
template<typename Tree>
|
||||
void BringBestAnchorIntoCache(
|
||||
const uint256 ¤tRoot,
|
||||
Tree &tree
|
||||
);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_COINS_H
|
||||
|
||||
@@ -55,16 +55,8 @@ protected:
|
||||
public:
|
||||
CScriptCompressor(CScript &scriptIn) : script(scriptIn) { }
|
||||
|
||||
unsigned int GetSerializeSize(int nType, int nVersion) const {
|
||||
std::vector<unsigned char> compr;
|
||||
if (Compress(compr))
|
||||
return compr.size();
|
||||
unsigned int nSize = script.size() + nSpecialScripts;
|
||||
return script.size() + VARINT(nSize).GetSerializeSize(nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream &s, int nType, int nVersion) const {
|
||||
void Serialize(Stream &s) const {
|
||||
std::vector<unsigned char> compr;
|
||||
if (Compress(compr)) {
|
||||
s << CFlatData(compr);
|
||||
@@ -76,7 +68,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream &s, int nType, int nVersion) {
|
||||
void Unserialize(Stream &s) {
|
||||
unsigned int nSize = 0;
|
||||
s >> VARINT(nSize);
|
||||
if (nSize < nSpecialScripts) {
|
||||
@@ -112,7 +104,7 @@ public:
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
if (!ser_action.ForRead()) {
|
||||
uint64_t nVal = CompressAmount(txout.nValue);
|
||||
READWRITE(VARINT(nVal));
|
||||
|
||||
@@ -10,16 +10,21 @@
|
||||
static const int32_t MIN_BLOCK_VERSION = 4;
|
||||
/** The minimum allowed transaction version (network rule) */
|
||||
static const int32_t SPROUT_MIN_TX_VERSION = 1;
|
||||
/** The minimum allowed transaction version (network rule) */
|
||||
/** The minimum allowed Overwinter transaction version (network rule) */
|
||||
static const int32_t OVERWINTER_MIN_TX_VERSION = 3;
|
||||
/** The maximum allowed transaction version (network rule) */
|
||||
/** The maximum allowed Overwinter transaction version (network rule) */
|
||||
static const int32_t OVERWINTER_MAX_TX_VERSION = 3;
|
||||
/** The minimum allowed Sapling transaction version (network rule) */
|
||||
static const int32_t SAPLING_MIN_TX_VERSION = 4;
|
||||
/** The maximum allowed Sapling transaction version (network rule) */
|
||||
static const int32_t SAPLING_MAX_TX_VERSION = 4;
|
||||
/** The maximum allowed size for a serialized block, in bytes (network rule) */
|
||||
static const unsigned int MAX_BLOCK_SIZE = 2000000;
|
||||
//static const unsigned int MAX_BLOCK_SIZE = 2000000;
|
||||
/** The maximum allowed number of signature check operations in a block (network rule) */
|
||||
extern unsigned int MAX_BLOCK_SIGOPS;
|
||||
/** The maximum size of a transaction (network rule) */
|
||||
static const unsigned int MAX_TX_SIZE = 100000;
|
||||
static const unsigned int MAX_TX_SIZE_BEFORE_SAPLING = 100000;
|
||||
static const unsigned int MAX_TX_SIZE_AFTER_SAPLING = (2 * MAX_TX_SIZE_BEFORE_SAPLING); //MAX_BLOCK_SIZE;
|
||||
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
|
||||
extern int COINBASE_MATURITY;
|
||||
/** The minimum value which is invalid for expiry height, used by CTransaction and CMutableTransaction */
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
|
||||
#include "uint256.h"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
int32_t MAX_BLOCK_SIZE(int32_t height);
|
||||
|
||||
namespace Consensus {
|
||||
|
||||
/**
|
||||
@@ -23,6 +27,7 @@ enum UpgradeIndex {
|
||||
BASE_SPROUT,
|
||||
UPGRADE_TESTDUMMY,
|
||||
UPGRADE_OVERWINTER,
|
||||
UPGRADE_SAPLING,
|
||||
// NOTE: Also add new upgrades to NetworkUpgradeInfo in upgrades.cpp
|
||||
MAX_NETWORK_UPGRADES
|
||||
};
|
||||
@@ -37,7 +42,6 @@ struct NetworkUpgrade {
|
||||
* Height of the first block for which the new consensus rules will be active
|
||||
*/
|
||||
int nActivationHeight;
|
||||
|
||||
/**
|
||||
* Special value for nActivationHeight indicating that the upgrade is always active.
|
||||
* This is useful for testing, as it means tests don't need to deal with the activation
|
||||
@@ -87,17 +91,33 @@ struct Params {
|
||||
int nMajorityEnforceBlockUpgrade;
|
||||
int nMajorityRejectBlockOutdated;
|
||||
int nMajorityWindow;
|
||||
int fPowAllowMinDifficultyBlocks;
|
||||
NetworkUpgrade vUpgrades[MAX_NETWORK_UPGRADES];
|
||||
|
||||
/** Proof of work parameters */
|
||||
uint256 powLimit;
|
||||
uint256 powAlternate;
|
||||
boost::optional<uint32_t> nPowAllowMinDifficultyBlocksAfterHeight;
|
||||
int64_t nPowAveragingWindow;
|
||||
int64_t nPowMaxAdjustDown;
|
||||
int64_t nPowMaxAdjustUp;
|
||||
int64_t nPowTargetSpacing;
|
||||
int64_t nLwmaAjustedWeight;
|
||||
|
||||
/* Proof of stake parameters */
|
||||
uint256 posLimit;
|
||||
int64_t nPOSAveragingWindow; // can be completely different than POW and initially trying a relatively large number, like 100
|
||||
int64_t nPOSTargetSpacing; // spacing is 1000 units per block to get better resolution, (100 % = 1000, 50% = 2000, 10% = 10000)
|
||||
int64_t nLwmaPOSAjustedWeight;
|
||||
|
||||
/* applied to all block times */
|
||||
int64_t nMaxFutureBlockTime;
|
||||
|
||||
int64_t AveragingWindowTimespan() const { return nPowAveragingWindow * nPowTargetSpacing; }
|
||||
int64_t MinActualTimespan() const { return (AveragingWindowTimespan() * (100 - nPowMaxAdjustUp )) / 100; }
|
||||
int64_t MaxActualTimespan() const { return (AveragingWindowTimespan() * (100 + nPowMaxAdjustDown)) / 100; }
|
||||
int32_t SetSaplingHeight(int32_t height) { vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = height; }
|
||||
int32_t SetOverwinterHeight(int32_t height) { vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = height; }
|
||||
uint256 nMinimumChainWork;
|
||||
};
|
||||
} // namespace Consensus
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@ const struct NUInfo NetworkUpgradeInfo[Consensus::MAX_NETWORK_UPGRADES] = {
|
||||
/*.nBranchId =*/ 0x5ba81b19,
|
||||
/*.strName =*/ "Overwinter",
|
||||
/*.strInfo =*/ "See https://z.cash/upgrade/overwinter.html for details.",
|
||||
},
|
||||
{
|
||||
/*.nBranchId =*/ 0x76b809bb,
|
||||
/*.strName =*/ "Sapling",
|
||||
/*.strInfo =*/ "See https://z.cash/upgrade/sapling.html for details.",
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,6 +38,10 @@ UpgradeState NetworkUpgradeState(
|
||||
const Consensus::Params& params,
|
||||
Consensus::UpgradeIndex idx)
|
||||
{
|
||||
if (nHeight < 0)
|
||||
{
|
||||
printf("height: %d", nHeight);
|
||||
}
|
||||
assert(nHeight >= 0);
|
||||
assert(idx >= Consensus::BASE_SPROUT && idx < Consensus::MAX_NETWORK_UPGRADES);
|
||||
auto nActivationHeight = params.vUpgrades[idx].nActivationHeight;
|
||||
@@ -69,13 +78,23 @@ int CurrentEpoch(int nHeight, const Consensus::Params& params) {
|
||||
return idxInt;
|
||||
}
|
||||
}
|
||||
return(0); // jl777 seems the right value to return
|
||||
// Base case
|
||||
return Consensus::BASE_SPROUT;
|
||||
}
|
||||
|
||||
uint32_t CurrentEpochBranchId(int nHeight, const Consensus::Params& params) {
|
||||
return NetworkUpgradeInfo[CurrentEpoch(nHeight, params)].nBranchId;
|
||||
}
|
||||
|
||||
bool IsConsensusBranchId(int branchId) {
|
||||
for (int idx = Consensus::BASE_SPROUT; idx < Consensus::MAX_NETWORK_UPGRADES; idx++) {
|
||||
if (branchId == NetworkUpgradeInfo[idx].nBranchId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsActivationHeight(
|
||||
int nHeight,
|
||||
const Consensus::Params& params,
|
||||
@@ -108,20 +127,28 @@ bool IsActivationHeightForAnyUpgrade(
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::optional<int> NextActivationHeight(
|
||||
int nHeight,
|
||||
const Consensus::Params& params)
|
||||
{
|
||||
boost::optional<int> NextEpoch(int nHeight, const Consensus::Params& params) {
|
||||
if (nHeight < 0) {
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
// Don't count Sprout as an activation height
|
||||
// Sprout is never pending
|
||||
for (auto idx = Consensus::BASE_SPROUT + 1; idx < Consensus::MAX_NETWORK_UPGRADES; idx++) {
|
||||
if (NetworkUpgradeState(nHeight, params, Consensus::UpgradeIndex(idx)) == UPGRADE_PENDING) {
|
||||
return params.vUpgrades[idx].nActivationHeight;
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
boost::optional<int> NextActivationHeight(
|
||||
int nHeight,
|
||||
const Consensus::Params& params)
|
||||
{
|
||||
auto idx = NextEpoch(nHeight, params);
|
||||
if (idx) {
|
||||
return params.vUpgrades[idx.get()].nActivationHeight;
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,12 @@ int CurrentEpoch(int nHeight, const Consensus::Params& params);
|
||||
*/
|
||||
uint32_t CurrentEpochBranchId(int nHeight, const Consensus::Params& params);
|
||||
|
||||
/**
|
||||
* Returns true if a given branch id is a valid nBranchId for one of the network
|
||||
* upgrades contained in NetworkUpgradeInfo.
|
||||
*/
|
||||
bool IsConsensusBranchId(int branchId);
|
||||
|
||||
/**
|
||||
* Returns true if the given block height is the activation height for the given
|
||||
* upgrade.
|
||||
@@ -79,6 +85,12 @@ bool IsActivationHeightForAnyUpgrade(
|
||||
int nHeight,
|
||||
const Consensus::Params& params);
|
||||
|
||||
/**
|
||||
* Returns the index of the next upgrade after the given block height, or
|
||||
* boost::none if there are no more known upgrades.
|
||||
*/
|
||||
boost::optional<int> NextEpoch(int nHeight, const Consensus::Params& params);
|
||||
|
||||
/**
|
||||
* Returns the activation height for the next upgrade after the given block height,
|
||||
* or boost::none if there are no more known upgrades.
|
||||
|
||||
@@ -16,6 +16,7 @@ class UniValue;
|
||||
|
||||
// core_read.cpp
|
||||
extern CScript ParseScript(const std::string& s);
|
||||
extern std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false);
|
||||
extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
|
||||
extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
|
||||
extern uint256 ParseHashUV(const UniValue& v, const std::string& strName);
|
||||
@@ -25,8 +26,7 @@ extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::strin
|
||||
// core_write.cpp
|
||||
extern std::string FormatScript(const CScript& script);
|
||||
extern std::string EncodeHexTx(const CTransaction& tx);
|
||||
extern void ScriptPubKeyToUniv(const CScript& scriptPubKey,
|
||||
UniValue& out, bool fIncludeHex);
|
||||
extern void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
|
||||
extern void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry);
|
||||
|
||||
#endif // BITCOIN_CORE_IO_H
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "memusage.h"
|
||||
|
||||
static inline size_t RecursiveDynamicUsage(const CScript& script) {
|
||||
return memusage::DynamicUsage(*static_cast<const std::vector<unsigned char>*>(&script));
|
||||
return memusage::DynamicUsage(*static_cast<const CScriptBase*>(&script));
|
||||
}
|
||||
|
||||
static inline size_t RecursiveDynamicUsage(const COutPoint& out) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "core_io.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "key_io.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
#include "script/standard.h"
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "utilmoneystr.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace std;
|
||||
@@ -54,6 +55,67 @@ string FormatScript(const CScript& script)
|
||||
return ret.substr(0, ret.size() - 1);
|
||||
}
|
||||
|
||||
const map<unsigned char, string> mapSigHashTypes =
|
||||
boost::assign::map_list_of
|
||||
(static_cast<unsigned char>(SIGHASH_ALL), string("ALL"))
|
||||
(static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_ANYONECANPAY), string("ALL|ANYONECANPAY"))
|
||||
(static_cast<unsigned char>(SIGHASH_NONE), string("NONE"))
|
||||
(static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_ANYONECANPAY), string("NONE|ANYONECANPAY"))
|
||||
(static_cast<unsigned char>(SIGHASH_SINGLE), string("SINGLE"))
|
||||
(static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY), string("SINGLE|ANYONECANPAY"))
|
||||
;
|
||||
|
||||
/**
|
||||
* Create the assembly string representation of a CScript object.
|
||||
* @param[in] script CScript object to convert into the asm string representation.
|
||||
* @param[in] fAttemptSighashDecode Whether to attempt to decode sighash types on data within the script that matches the format
|
||||
* of a signature. Only pass true for scripts you believe could contain signatures. For example,
|
||||
* pass false, or omit the this argument (defaults to false), for scriptPubKeys.
|
||||
*/
|
||||
string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode)
|
||||
{
|
||||
string str;
|
||||
opcodetype opcode;
|
||||
vector<unsigned char> vch;
|
||||
CScript::const_iterator pc = script.begin();
|
||||
while (pc < script.end()) {
|
||||
if (!str.empty()) {
|
||||
str += " ";
|
||||
}
|
||||
if (!script.GetOp(pc, opcode, vch)) {
|
||||
str += "[error]";
|
||||
return str;
|
||||
}
|
||||
if (0 <= opcode && opcode <= OP_PUSHDATA4) {
|
||||
if (vch.size() <= static_cast<vector<unsigned char>::size_type>(4)) {
|
||||
str += strprintf("%d", CScriptNum(vch, false).getint());
|
||||
} else {
|
||||
// the IsUnspendable check makes sure not to try to decode OP_RETURN data that may match the format of a signature
|
||||
if (fAttemptSighashDecode && !script.IsUnspendable()) {
|
||||
string strSigHashDecode;
|
||||
// goal: only attempt to decode a defined sighash type from data that looks like a signature within a scriptSig.
|
||||
// this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to
|
||||
// the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the
|
||||
// checks in CheckSignatureEncoding.
|
||||
if (CheckSignatureEncoding(vch, SCRIPT_VERIFY_STRICTENC, NULL)) {
|
||||
const unsigned char chSigHashType = vch.back();
|
||||
if (mapSigHashTypes.count(chSigHashType)) {
|
||||
strSigHashDecode = "[" + mapSigHashTypes.find(chSigHashType)->second + "]";
|
||||
vch.pop_back(); // remove the sighash type byte. it will be replaced by the decode.
|
||||
}
|
||||
}
|
||||
str += HexStr(vch) + strSigHashDecode;
|
||||
} else {
|
||||
str += HexStr(vch);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
str += GetOpName(opcode);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
string EncodeHexTx(const CTransaction& tx)
|
||||
{
|
||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||
@@ -68,7 +130,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
|
||||
vector<CTxDestination> addresses;
|
||||
int nRequired;
|
||||
|
||||
out.pushKV("asm", scriptPubKey.ToString());
|
||||
out.pushKV("asm", ScriptToAsmStr(scriptPubKey));
|
||||
if (fIncludeHex)
|
||||
out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
|
||||
|
||||
@@ -81,8 +143,9 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
|
||||
out.pushKV("type", GetTxnOutputType(type));
|
||||
|
||||
UniValue a(UniValue::VARR);
|
||||
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||
a.push_back(CBitcoinAddress(addr).ToString());
|
||||
for (const CTxDestination& addr : addresses) {
|
||||
a.push_back(EncodeDestination(addr));
|
||||
}
|
||||
out.pushKV("addresses", a);
|
||||
}
|
||||
|
||||
@@ -101,7 +164,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
|
||||
in.pushKV("txid", txin.prevout.hash.GetHex());
|
||||
in.pushKV("vout", (int64_t)txin.prevout.n);
|
||||
UniValue o(UniValue::VOBJ);
|
||||
o.pushKV("asm", txin.scriptSig.ToString());
|
||||
o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
|
||||
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
|
||||
in.pushKV("scriptSig", o);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
|
||||
int NOTARISATION_SCAN_LIMIT_BLOCKS = 1440;
|
||||
CBlockIndex *komodo_getblockindex(uint256 hash);
|
||||
|
||||
|
||||
/* On KMD */
|
||||
@@ -142,7 +143,7 @@ TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_
|
||||
CBlockIndex blockIdx;
|
||||
if (!eval->GetTxConfirmed(assetChainProof.first, sourceNotarisation, blockIdx))
|
||||
throw std::runtime_error("Notarisation not found");
|
||||
kmdHeight = blockIdx.nHeight;
|
||||
kmdHeight = blockIdx.GetHeight();
|
||||
}
|
||||
|
||||
// We now have a kmdHeight of the notarisation from chain A. So we know that a MoM exists
|
||||
@@ -252,7 +253,7 @@ bool GetNextBacknotarisation(uint256 kmdNotarisationTxid, Notarisation &out)
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) ScanNotarisationsFromHeight(block.nHeight+1, &IsSameAssetChain, out);
|
||||
return (bool) ScanNotarisationsFromHeight(block.GetHeight()+1, &IsSameAssetChain, out);
|
||||
}
|
||||
|
||||
|
||||
@@ -309,20 +310,20 @@ TxProof GetAssetchainProof(uint256 hash)
|
||||
if (blockHash.IsNull())
|
||||
throw std::runtime_error("tx still in mempool");
|
||||
|
||||
blockIndex = mapBlockIndex[blockHash];
|
||||
int h = blockIndex->nHeight;
|
||||
blockIndex = komodo_getblockindex(blockHash);
|
||||
int h = blockIndex->GetHeight();
|
||||
// The assumption here is that the first notarisation for a height GTE than
|
||||
// the transaction block height will contain the corresponding MoM. If there
|
||||
// are sequence issues with the notarisations this may fail.
|
||||
auto isTarget = [&](Notarisation ¬a) {
|
||||
if (!IsSameAssetChain(nota)) return false;
|
||||
return nota.second.height >= blockIndex->nHeight;
|
||||
return nota.second.height >= blockIndex->GetHeight();
|
||||
};
|
||||
if (!ScanNotarisationsFromHeight(blockIndex->nHeight, isTarget, nota))
|
||||
if (!ScanNotarisationsFromHeight(blockIndex->GetHeight(), isTarget, nota))
|
||||
throw std::runtime_error("backnotarisation not yet confirmed");
|
||||
|
||||
// index of block in MoM leaves
|
||||
nIndex = nota.second.height - blockIndex->nHeight;
|
||||
nIndex = nota.second.height - blockIndex->GetHeight();
|
||||
}
|
||||
|
||||
// build merkle chain from blocks to MoM
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sodium.h"
|
||||
#include "compat/endian.h"
|
||||
@@ -21,52 +22,67 @@
|
||||
|
||||
uint16_t static inline ReadLE16(const unsigned char* ptr)
|
||||
{
|
||||
return le16toh(*((uint16_t*)ptr));
|
||||
uint16_t x;
|
||||
memcpy((char*)&x, ptr, 2);
|
||||
return le16toh(x);
|
||||
}
|
||||
|
||||
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
||||
{
|
||||
return le32toh(*((uint32_t*)ptr));
|
||||
uint32_t x;
|
||||
memcpy((char*)&x, ptr, 4);
|
||||
return le32toh(x);
|
||||
}
|
||||
|
||||
uint64_t static inline ReadLE64(const unsigned char* ptr)
|
||||
{
|
||||
return le64toh(*((uint64_t*)ptr));
|
||||
uint64_t x;
|
||||
memcpy((char*)&x, ptr, 8);
|
||||
return le64toh(x);
|
||||
}
|
||||
|
||||
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
|
||||
{
|
||||
*((uint16_t*)ptr) = htole16(x);
|
||||
uint16_t v = htole16(x);
|
||||
memcpy(ptr, (char*)&v, 2);
|
||||
}
|
||||
|
||||
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
*((uint32_t*)ptr) = htole32(x);
|
||||
uint32_t v = htole32(x);
|
||||
memcpy(ptr, (char*)&v, 4);
|
||||
}
|
||||
|
||||
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
*((uint64_t*)ptr) = htole64(x);
|
||||
uint64_t v = htole64(x);
|
||||
memcpy(ptr, (char*)&v, 8);
|
||||
}
|
||||
|
||||
uint32_t static inline ReadBE32(const unsigned char* ptr)
|
||||
{
|
||||
return be32toh(*((uint32_t*)ptr));
|
||||
uint32_t x;
|
||||
memcpy((char*)&x, ptr, 4);
|
||||
return be32toh(x);
|
||||
}
|
||||
|
||||
uint64_t static inline ReadBE64(const unsigned char* ptr)
|
||||
{
|
||||
return be64toh(*((uint64_t*)ptr));
|
||||
uint64_t x;
|
||||
memcpy((char*)&x, ptr, 8);
|
||||
return be64toh(x);
|
||||
}
|
||||
|
||||
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
*((uint32_t*)ptr) = htobe32(x);
|
||||
uint32_t v = htobe32(x);
|
||||
memcpy(ptr, (char*)&v, 4);
|
||||
}
|
||||
|
||||
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
*((uint64_t*)ptr) = htobe64(x);
|
||||
uint64_t v = htobe64(x);
|
||||
memcpy(ptr, (char*)&v, 8);
|
||||
}
|
||||
|
||||
int inline init_and_check_sodium()
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#define __BYTE_ORDER BYTE_ORDER
|
||||
#endif
|
||||
*/
|
||||
EhSolverCancelledException solver_cancelled;
|
||||
static EhSolverCancelledException solver_cancelled;
|
||||
|
||||
template<unsigned int N, unsigned int K>
|
||||
int Equihash<N,K>::InitialiseState(eh_HashState& base_state)
|
||||
|
||||
606
src/crypto/haraka.c
Normal file
606
src/crypto/haraka.c
Normal file
@@ -0,0 +1,606 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 kste
|
||||
|
||||
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.
|
||||
|
||||
Optimized Implementations for Haraka256 and Haraka512
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "crypto/haraka.h"
|
||||
|
||||
u128 rc[40];
|
||||
u128 rc0[40] = {0};
|
||||
|
||||
void load_constants() {
|
||||
rc[0] = _mm_set_epi32(0x0684704c,0xe620c00a,0xb2c5fef0,0x75817b9d);
|
||||
rc[1] = _mm_set_epi32(0x8b66b4e1,0x88f3a06b,0x640f6ba4,0x2f08f717);
|
||||
rc[2] = _mm_set_epi32(0x3402de2d,0x53f28498,0xcf029d60,0x9f029114);
|
||||
rc[3] = _mm_set_epi32(0x0ed6eae6,0x2e7b4f08,0xbbf3bcaf,0xfd5b4f79);
|
||||
rc[4] = _mm_set_epi32(0xcbcfb0cb,0x4872448b,0x79eecd1c,0xbe397044);
|
||||
rc[5] = _mm_set_epi32(0x7eeacdee,0x6e9032b7,0x8d5335ed,0x2b8a057b);
|
||||
rc[6] = _mm_set_epi32(0x67c28f43,0x5e2e7cd0,0xe2412761,0xda4fef1b);
|
||||
rc[7] = _mm_set_epi32(0x2924d9b0,0xafcacc07,0x675ffde2,0x1fc70b3b);
|
||||
rc[8] = _mm_set_epi32(0xab4d63f1,0xe6867fe9,0xecdb8fca,0xb9d465ee);
|
||||
rc[9] = _mm_set_epi32(0x1c30bf84,0xd4b7cd64,0x5b2a404f,0xad037e33);
|
||||
rc[10] = _mm_set_epi32(0xb2cc0bb9,0x941723bf,0x69028b2e,0x8df69800);
|
||||
rc[11] = _mm_set_epi32(0xfa0478a6,0xde6f5572,0x4aaa9ec8,0x5c9d2d8a);
|
||||
rc[12] = _mm_set_epi32(0xdfb49f2b,0x6b772a12,0x0efa4f2e,0x29129fd4);
|
||||
rc[13] = _mm_set_epi32(0x1ea10344,0xf449a236,0x32d611ae,0xbb6a12ee);
|
||||
rc[14] = _mm_set_epi32(0xaf044988,0x4b050084,0x5f9600c9,0x9ca8eca6);
|
||||
rc[15] = _mm_set_epi32(0x21025ed8,0x9d199c4f,0x78a2c7e3,0x27e593ec);
|
||||
rc[16] = _mm_set_epi32(0xbf3aaaf8,0xa759c9b7,0xb9282ecd,0x82d40173);
|
||||
rc[17] = _mm_set_epi32(0x6260700d,0x6186b017,0x37f2efd9,0x10307d6b);
|
||||
rc[18] = _mm_set_epi32(0x5aca45c2,0x21300443,0x81c29153,0xf6fc9ac6);
|
||||
rc[19] = _mm_set_epi32(0x9223973c,0x226b68bb,0x2caf92e8,0x36d1943a);
|
||||
rc[20] = _mm_set_epi32(0xd3bf9238,0x225886eb,0x6cbab958,0xe51071b4);
|
||||
rc[21] = _mm_set_epi32(0xdb863ce5,0xaef0c677,0x933dfddd,0x24e1128d);
|
||||
rc[22] = _mm_set_epi32(0xbb606268,0xffeba09c,0x83e48de3,0xcb2212b1);
|
||||
rc[23] = _mm_set_epi32(0x734bd3dc,0xe2e4d19c,0x2db91a4e,0xc72bf77d);
|
||||
rc[24] = _mm_set_epi32(0x43bb47c3,0x61301b43,0x4b1415c4,0x2cb3924e);
|
||||
rc[25] = _mm_set_epi32(0xdba775a8,0xe707eff6,0x03b231dd,0x16eb6899);
|
||||
rc[26] = _mm_set_epi32(0x6df3614b,0x3c755977,0x8e5e2302,0x7eca472c);
|
||||
rc[27] = _mm_set_epi32(0xcda75a17,0xd6de7d77,0x6d1be5b9,0xb88617f9);
|
||||
rc[28] = _mm_set_epi32(0xec6b43f0,0x6ba8e9aa,0x9d6c069d,0xa946ee5d);
|
||||
rc[29] = _mm_set_epi32(0xcb1e6950,0xf957332b,0xa2531159,0x3bf327c1);
|
||||
rc[30] = _mm_set_epi32(0x2cee0c75,0x00da619c,0xe4ed0353,0x600ed0d9);
|
||||
rc[31] = _mm_set_epi32(0xf0b1a5a1,0x96e90cab,0x80bbbabc,0x63a4a350);
|
||||
rc[32] = _mm_set_epi32(0xae3db102,0x5e962988,0xab0dde30,0x938dca39);
|
||||
rc[33] = _mm_set_epi32(0x17bb8f38,0xd554a40b,0x8814f3a8,0x2e75b442);
|
||||
rc[34] = _mm_set_epi32(0x34bb8a5b,0x5f427fd7,0xaeb6b779,0x360a16f6);
|
||||
rc[35] = _mm_set_epi32(0x26f65241,0xcbe55438,0x43ce5918,0xffbaafde);
|
||||
rc[36] = _mm_set_epi32(0x4ce99a54,0xb9f3026a,0xa2ca9cf7,0x839ec978);
|
||||
rc[37] = _mm_set_epi32(0xae51a51a,0x1bdff7be,0x40c06e28,0x22901235);
|
||||
rc[38] = _mm_set_epi32(0xa0c1613c,0xba7ed22b,0xc173bc0f,0x48a659cf);
|
||||
rc[39] = _mm_set_epi32(0x756acc03,0x02288288,0x4ad6bdfd,0xe9c59da1);
|
||||
}
|
||||
|
||||
void test_implementations() {
|
||||
unsigned char *in = (unsigned char *)calloc(64*8, sizeof(unsigned char));
|
||||
unsigned char *out256 = (unsigned char *)calloc(32*8, sizeof(unsigned char));
|
||||
unsigned char *out512 = (unsigned char *)calloc(32*8, sizeof(unsigned char));
|
||||
unsigned char testvector256[32] = {0x80, 0x27, 0xcc, 0xb8, 0x79, 0x49, 0x77, 0x4b,
|
||||
0x78, 0xd0, 0x54, 0x5f, 0xb7, 0x2b, 0xf7, 0x0c,
|
||||
0x69, 0x5c, 0x2a, 0x09, 0x23, 0xcb, 0xd4, 0x7b,
|
||||
0xba, 0x11, 0x59, 0xef, 0xbf, 0x2b, 0x2c, 0x1c};
|
||||
|
||||
unsigned char testvector512[32] = {0xbe, 0x7f, 0x72, 0x3b, 0x4e, 0x80, 0xa9, 0x98,
|
||||
0x13, 0xb2, 0x92, 0x28, 0x7f, 0x30, 0x6f, 0x62,
|
||||
0x5a, 0x6d, 0x57, 0x33, 0x1c, 0xae, 0x5f, 0x34,
|
||||
0xdd, 0x92, 0x77, 0xb0, 0x94, 0x5b, 0xe2, 0xaa};
|
||||
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
// Input for testvector
|
||||
for(i = 0; i < 512; i++) {
|
||||
in[i] = i % 64;
|
||||
}
|
||||
|
||||
load_constants();
|
||||
haraka512_8x(out512, in);
|
||||
|
||||
// Verify output
|
||||
for(i = 0; i < 32; i++) {
|
||||
if (out512[i % 32] != testvector512[i]) {
|
||||
printf("Error: testvector incorrect.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
free(in);
|
||||
free(out256);
|
||||
free(out512);
|
||||
}
|
||||
|
||||
void haraka256(unsigned char *out, const unsigned char *in) {
|
||||
__m128i s[2], tmp;
|
||||
|
||||
s[0] = LOAD(in);
|
||||
s[1] = LOAD(in + 16);
|
||||
|
||||
AES2(s[0], s[1], 0);
|
||||
MIX2(s[0], s[1]);
|
||||
|
||||
AES2(s[0], s[1], 4);
|
||||
MIX2(s[0], s[1]);
|
||||
|
||||
AES2(s[0], s[1], 8);
|
||||
MIX2(s[0], s[1]);
|
||||
|
||||
AES2(s[0], s[1], 12);
|
||||
MIX2(s[0], s[1]);
|
||||
|
||||
AES2(s[0], s[1], 16);
|
||||
MIX2(s[0], s[1]);
|
||||
|
||||
s[0] = _mm_xor_si128(s[0], LOAD(in));
|
||||
s[1] = _mm_xor_si128(s[1], LOAD(in + 16));
|
||||
|
||||
STORE(out, s[0]);
|
||||
STORE(out + 16, s[1]);
|
||||
}
|
||||
|
||||
void haraka256_4x(unsigned char *out, const unsigned char *in) {
|
||||
__m128i s[4][2], tmp;
|
||||
|
||||
s[0][0] = LOAD(in);
|
||||
s[0][1] = LOAD(in + 16);
|
||||
s[1][0] = LOAD(in + 32);
|
||||
s[1][1] = LOAD(in + 48);
|
||||
s[2][0] = LOAD(in + 64);
|
||||
s[2][1] = LOAD(in + 80);
|
||||
s[3][0] = LOAD(in + 96);
|
||||
s[3][1] = LOAD(in + 112);
|
||||
|
||||
// Round 1
|
||||
AES2_4x(s[0], s[1], s[2], s[3], 0);
|
||||
|
||||
MIX2(s[0][0], s[0][1]);
|
||||
MIX2(s[1][0], s[1][1]);
|
||||
MIX2(s[2][0], s[2][1]);
|
||||
MIX2(s[3][0], s[3][1]);
|
||||
|
||||
// Round 2
|
||||
AES2_4x(s[0], s[1], s[2], s[3], 4);
|
||||
|
||||
MIX2(s[0][0], s[0][1]);
|
||||
MIX2(s[1][0], s[1][1]);
|
||||
MIX2(s[2][0], s[2][1]);
|
||||
MIX2(s[3][0], s[3][1]);
|
||||
|
||||
// Round 3
|
||||
AES2_4x(s[0], s[1], s[2], s[3], 8);
|
||||
|
||||
MIX2(s[0][0], s[0][1]);
|
||||
MIX2(s[1][0], s[1][1]);
|
||||
MIX2(s[2][0], s[2][1]);
|
||||
MIX2(s[3][0], s[3][1]);
|
||||
|
||||
// Round 4
|
||||
AES2_4x(s[0], s[1], s[2], s[3], 12);
|
||||
|
||||
MIX2(s[0][0], s[0][1]);
|
||||
MIX2(s[1][0], s[1][1]);
|
||||
MIX2(s[2][0], s[2][1]);
|
||||
MIX2(s[3][0], s[3][1]);
|
||||
|
||||
// Round 5
|
||||
AES2_4x(s[0], s[1], s[2], s[3], 16);
|
||||
|
||||
MIX2(s[0][0], s[0][1]);
|
||||
MIX2(s[1][0], s[1][1]);
|
||||
MIX2(s[2][0], s[2][1]);
|
||||
MIX2(s[3][0], s[3][1]);
|
||||
|
||||
// Feed Forward
|
||||
s[0][0] = _mm_xor_si128(s[0][0], LOAD(in));
|
||||
s[0][1] = _mm_xor_si128(s[0][1], LOAD(in + 16));
|
||||
s[1][0] = _mm_xor_si128(s[1][0], LOAD(in + 32));
|
||||
s[1][1] = _mm_xor_si128(s[1][1], LOAD(in + 48));
|
||||
s[2][0] = _mm_xor_si128(s[2][0], LOAD(in + 64));
|
||||
s[2][1] = _mm_xor_si128(s[2][1], LOAD(in + 80));
|
||||
s[3][0] = _mm_xor_si128(s[3][0], LOAD(in + 96));
|
||||
s[3][1] = _mm_xor_si128(s[3][1], LOAD(in + 112));
|
||||
|
||||
STORE(out, s[0][0]);
|
||||
STORE(out + 16, s[0][1]);
|
||||
STORE(out + 32, s[1][0]);
|
||||
STORE(out + 48, s[1][1]);
|
||||
STORE(out + 64, s[2][0]);
|
||||
STORE(out + 80, s[2][1]);
|
||||
STORE(out + 96, s[3][0]);
|
||||
STORE(out + 112, s[3][1]);
|
||||
}
|
||||
|
||||
void haraka256_8x(unsigned char *out, const unsigned char *in) {
|
||||
// This is faster on Skylake, the code below is faster on Haswell.
|
||||
haraka256_4x(out, in);
|
||||
haraka256_4x(out + 128, in + 128);
|
||||
return;
|
||||
// __m128i s[8][2], tmp;
|
||||
//
|
||||
// int i;
|
||||
//
|
||||
// s[0][0] = LOAD(in);
|
||||
// s[0][1] = LOAD(in + 16);
|
||||
// s[1][0] = LOAD(in + 32);
|
||||
// s[1][1] = LOAD(in + 48);
|
||||
// s[2][0] = LOAD(in + 64);
|
||||
// s[2][1] = LOAD(in + 80);
|
||||
// s[3][0] = LOAD(in + 96);
|
||||
// s[3][1] = LOAD(in + 112);
|
||||
// s[4][0] = LOAD(in + 128);
|
||||
// s[4][1] = LOAD(in + 144);
|
||||
// s[5][0] = LOAD(in + 160);
|
||||
// s[5][1] = LOAD(in + 176);
|
||||
// s[6][0] = LOAD(in + 192);
|
||||
// s[6][1] = LOAD(in + 208);
|
||||
// s[7][0] = LOAD(in + 224);
|
||||
// s[7][1] = LOAD(in + 240);
|
||||
//
|
||||
// // Round 1
|
||||
// AES2_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 0);
|
||||
//
|
||||
// MIX2(s[0][0], s[0][1]);
|
||||
// MIX2(s[1][0], s[1][1]);
|
||||
// MIX2(s[2][0], s[2][1]);
|
||||
// MIX2(s[3][0], s[3][1]);
|
||||
// MIX2(s[4][0], s[4][1]);
|
||||
// MIX2(s[5][0], s[5][1]);
|
||||
// MIX2(s[6][0], s[6][1]);
|
||||
// MIX2(s[7][0], s[7][1]);
|
||||
//
|
||||
//
|
||||
// // Round 2
|
||||
// AES2_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 4);
|
||||
//
|
||||
// MIX2(s[0][0], s[0][1]);
|
||||
// MIX2(s[1][0], s[1][1]);
|
||||
// MIX2(s[2][0], s[2][1]);
|
||||
// MIX2(s[3][0], s[3][1]);
|
||||
// MIX2(s[4][0], s[4][1]);
|
||||
// MIX2(s[5][0], s[5][1]);
|
||||
// MIX2(s[6][0], s[6][1]);
|
||||
// MIX2(s[7][0], s[7][1]);
|
||||
//
|
||||
// // Round 3
|
||||
// AES2_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 8);
|
||||
//
|
||||
// MIX2(s[0][0], s[0][1]);
|
||||
// MIX2(s[1][0], s[1][1]);
|
||||
// MIX2(s[2][0], s[2][1]);
|
||||
// MIX2(s[3][0], s[3][1]);
|
||||
// MIX2(s[4][0], s[4][1]);
|
||||
// MIX2(s[5][0], s[5][1]);
|
||||
// MIX2(s[6][0], s[6][1]);
|
||||
// MIX2(s[7][0], s[7][1]);
|
||||
//
|
||||
// // Round 4
|
||||
// AES2_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 12);
|
||||
//
|
||||
// MIX2(s[0][0], s[0][1]);
|
||||
// MIX2(s[1][0], s[1][1]);
|
||||
// MIX2(s[2][0], s[2][1]);
|
||||
// MIX2(s[3][0], s[3][1]);
|
||||
// MIX2(s[4][0], s[4][1]);
|
||||
// MIX2(s[5][0], s[5][1]);
|
||||
// MIX2(s[6][0], s[6][1]);
|
||||
// MIX2(s[7][0], s[7][1]);
|
||||
//
|
||||
// // Round 5
|
||||
// AES2_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 16);
|
||||
//
|
||||
// MIX2(s[0][0], s[0][1]);
|
||||
// MIX2(s[1][0], s[1][1]);
|
||||
// MIX2(s[2][0], s[2][1]);
|
||||
// MIX2(s[3][0], s[3][1]);
|
||||
// MIX2(s[4][0], s[4][1]);
|
||||
// MIX2(s[5][0], s[5][1]);
|
||||
// MIX2(s[6][0], s[6][1]);
|
||||
// MIX2(s[7][0], s[7][1]);
|
||||
//
|
||||
// // Feed Forward
|
||||
// s[0][0] = _mm_xor_si128(s[0][0], LOAD(in));
|
||||
// s[0][1] = _mm_xor_si128(s[0][1], LOAD(in + 16));
|
||||
// s[1][0] = _mm_xor_si128(s[1][0], LOAD(in + 32));
|
||||
// s[1][1] = _mm_xor_si128(s[1][1], LOAD(in + 48));
|
||||
// s[2][0] = _mm_xor_si128(s[2][0], LOAD(in + 64));
|
||||
// s[2][1] = _mm_xor_si128(s[2][1], LOAD(in + 80));
|
||||
// s[3][0] = _mm_xor_si128(s[3][0], LOAD(in + 96));
|
||||
// s[3][1] = _mm_xor_si128(s[3][1], LOAD(in + 112));
|
||||
// s[4][0] = _mm_xor_si128(s[4][0], LOAD(in + 128));
|
||||
// s[4][1] = _mm_xor_si128(s[4][1], LOAD(in + 144));
|
||||
// s[5][0] = _mm_xor_si128(s[5][0], LOAD(in + 160));
|
||||
// s[5][1] = _mm_xor_si128(s[5][1], LOAD(in + 176));
|
||||
// s[6][0] = _mm_xor_si128(s[6][0], LOAD(in + 192));
|
||||
// s[6][1] = _mm_xor_si128(s[6][1], LOAD(in + 208));
|
||||
// s[7][0] = _mm_xor_si128(s[7][0], LOAD(in + 224));
|
||||
// s[7][1] = _mm_xor_si128(s[7][1], LOAD(in + 240));
|
||||
//
|
||||
// STORE(out, s[0][0]);
|
||||
// STORE(out + 16, s[0][1]);
|
||||
// STORE(out + 32, s[1][0]);
|
||||
// STORE(out + 48, s[1][1]);
|
||||
// STORE(out + 64, s[2][0]);
|
||||
// STORE(out + 80, s[2][1]);
|
||||
// STORE(out + 96, s[3][0]);
|
||||
// STORE(out + 112, s[3][1]);
|
||||
// STORE(out + 128, s[4][0]);
|
||||
// STORE(out + 144, s[4][1]);
|
||||
// STORE(out + 160, s[5][0]);
|
||||
// STORE(out + 176, s[5][1]);
|
||||
// STORE(out + 192, s[6][0]);
|
||||
// STORE(out + 208, s[6][1]);
|
||||
// STORE(out + 224, s[7][0]);
|
||||
// STORE(out + 240, s[7][1]);
|
||||
}
|
||||
|
||||
void haraka512(unsigned char *out, const unsigned char *in) {
|
||||
u128 s[4], tmp;
|
||||
|
||||
s[0] = LOAD(in);
|
||||
s[1] = LOAD(in + 16);
|
||||
s[2] = LOAD(in + 32);
|
||||
s[3] = LOAD(in + 48);
|
||||
|
||||
AES4(s[0], s[1], s[2], s[3], 0);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
AES4(s[0], s[1], s[2], s[3], 8);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
AES4(s[0], s[1], s[2], s[3], 16);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
AES4(s[0], s[1], s[2], s[3], 24);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
AES4(s[0], s[1], s[2], s[3], 32);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
s[0] = _mm_xor_si128(s[0], LOAD(in));
|
||||
s[1] = _mm_xor_si128(s[1], LOAD(in + 16));
|
||||
s[2] = _mm_xor_si128(s[2], LOAD(in + 32));
|
||||
s[3] = _mm_xor_si128(s[3], LOAD(in + 48));
|
||||
|
||||
TRUNCSTORE(out, s[0], s[1], s[2], s[3]);
|
||||
}
|
||||
|
||||
void haraka512_zero(unsigned char *out, const unsigned char *in) {
|
||||
u128 s[4], tmp;
|
||||
|
||||
s[0] = LOAD(in);
|
||||
s[1] = LOAD(in + 16);
|
||||
s[2] = LOAD(in + 32);
|
||||
s[3] = LOAD(in + 48);
|
||||
|
||||
AES4_zero(s[0], s[1], s[2], s[3], 0);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
AES4_zero(s[0], s[1], s[2], s[3], 8);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
AES4_zero(s[0], s[1], s[2], s[3], 16);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
AES4_zero(s[0], s[1], s[2], s[3], 24);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
AES4_zero(s[0], s[1], s[2], s[3], 32);
|
||||
MIX4(s[0], s[1], s[2], s[3]);
|
||||
|
||||
s[0] = _mm_xor_si128(s[0], LOAD(in));
|
||||
s[1] = _mm_xor_si128(s[1], LOAD(in + 16));
|
||||
s[2] = _mm_xor_si128(s[2], LOAD(in + 32));
|
||||
s[3] = _mm_xor_si128(s[3], LOAD(in + 48));
|
||||
|
||||
TRUNCSTORE(out, s[0], s[1], s[2], s[3]);
|
||||
}
|
||||
|
||||
void haraka512_4x(unsigned char *out, const unsigned char *in) {
|
||||
u128 s[4][4], tmp;
|
||||
|
||||
s[0][0] = LOAD(in);
|
||||
s[0][1] = LOAD(in + 16);
|
||||
s[0][2] = LOAD(in + 32);
|
||||
s[0][3] = LOAD(in + 48);
|
||||
s[1][0] = LOAD(in + 64);
|
||||
s[1][1] = LOAD(in + 80);
|
||||
s[1][2] = LOAD(in + 96);
|
||||
s[1][3] = LOAD(in + 112);
|
||||
s[2][0] = LOAD(in + 128);
|
||||
s[2][1] = LOAD(in + 144);
|
||||
s[2][2] = LOAD(in + 160);
|
||||
s[2][3] = LOAD(in + 176);
|
||||
s[3][0] = LOAD(in + 192);
|
||||
s[3][1] = LOAD(in + 208);
|
||||
s[3][2] = LOAD(in + 224);
|
||||
s[3][3] = LOAD(in + 240);
|
||||
|
||||
AES4_4x(s[0], s[1], s[2], s[3], 0);
|
||||
MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
|
||||
AES4_4x(s[0], s[1], s[2], s[3], 8);
|
||||
MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
|
||||
AES4_4x(s[0], s[1], s[2], s[3], 16);
|
||||
MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
|
||||
AES4_4x(s[0], s[1], s[2], s[3], 24);
|
||||
MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
|
||||
AES4_4x(s[0], s[1], s[2], s[3], 32);
|
||||
MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
|
||||
|
||||
s[0][0] = _mm_xor_si128(s[0][0], LOAD(in));
|
||||
s[0][1] = _mm_xor_si128(s[0][1], LOAD(in + 16));
|
||||
s[0][2] = _mm_xor_si128(s[0][2], LOAD(in + 32));
|
||||
s[0][3] = _mm_xor_si128(s[0][3], LOAD(in + 48));
|
||||
s[1][0] = _mm_xor_si128(s[1][0], LOAD(in + 64));
|
||||
s[1][1] = _mm_xor_si128(s[1][1], LOAD(in + 80));
|
||||
s[1][2] = _mm_xor_si128(s[1][2], LOAD(in + 96));
|
||||
s[1][3] = _mm_xor_si128(s[1][3], LOAD(in + 112));
|
||||
s[2][0] = _mm_xor_si128(s[2][0], LOAD(in + 128));
|
||||
s[2][1] = _mm_xor_si128(s[2][1], LOAD(in + 144));
|
||||
s[2][2] = _mm_xor_si128(s[2][2], LOAD(in + 160));
|
||||
s[2][3] = _mm_xor_si128(s[2][3], LOAD(in + 176));
|
||||
s[3][0] = _mm_xor_si128(s[3][0], LOAD(in + 192));
|
||||
s[3][1] = _mm_xor_si128(s[3][1], LOAD(in + 208));
|
||||
s[3][2] = _mm_xor_si128(s[3][2], LOAD(in + 224));
|
||||
s[3][3] = _mm_xor_si128(s[3][3], LOAD(in + 240));
|
||||
|
||||
TRUNCSTORE(out, s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
TRUNCSTORE(out + 32, s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
TRUNCSTORE(out + 64, s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
TRUNCSTORE(out + 96, s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
}
|
||||
|
||||
void haraka512_8x(unsigned char *out, const unsigned char *in) {
|
||||
// This is faster on Skylake, the code below is faster on Haswell.
|
||||
haraka512_4x(out, in);
|
||||
haraka512_4x(out + 128, in + 256);
|
||||
|
||||
// u128 s[8][4], tmp;
|
||||
//
|
||||
// s[0][0] = LOAD(in);
|
||||
// s[0][1] = LOAD(in + 16);
|
||||
// s[0][2] = LOAD(in + 32);
|
||||
// s[0][3] = LOAD(in + 48);
|
||||
// s[1][0] = LOAD(in + 64);
|
||||
// s[1][1] = LOAD(in + 80);
|
||||
// s[1][2] = LOAD(in + 96);
|
||||
// s[1][3] = LOAD(in + 112);
|
||||
// s[2][0] = LOAD(in + 128);
|
||||
// s[2][1] = LOAD(in + 144);
|
||||
// s[2][2] = LOAD(in + 160);
|
||||
// s[2][3] = LOAD(in + 176);
|
||||
// s[3][0] = LOAD(in + 192);
|
||||
// s[3][1] = LOAD(in + 208);
|
||||
// s[3][2] = LOAD(in + 224);
|
||||
// s[3][3] = LOAD(in + 240);
|
||||
// s[4][0] = LOAD(in + 256);
|
||||
// s[4][1] = LOAD(in + 272);
|
||||
// s[4][2] = LOAD(in + 288);
|
||||
// s[4][3] = LOAD(in + 304);
|
||||
// s[5][0] = LOAD(in + 320);
|
||||
// s[5][1] = LOAD(in + 336);
|
||||
// s[5][2] = LOAD(in + 352);
|
||||
// s[5][3] = LOAD(in + 368);
|
||||
// s[6][0] = LOAD(in + 384);
|
||||
// s[6][1] = LOAD(in + 400);
|
||||
// s[6][2] = LOAD(in + 416);
|
||||
// s[6][3] = LOAD(in + 432);
|
||||
// s[7][0] = LOAD(in + 448);
|
||||
// s[7][1] = LOAD(in + 464);
|
||||
// s[7][2] = LOAD(in + 480);
|
||||
// s[7][3] = LOAD(in + 496);
|
||||
//
|
||||
// AES4_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 0);
|
||||
// MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
// MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
// MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
// MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
// MIX4(s[4][0], s[4][1], s[4][2], s[4][3]);
|
||||
// MIX4(s[5][0], s[5][1], s[5][2], s[5][3]);
|
||||
// MIX4(s[6][0], s[6][1], s[6][2], s[6][3]);
|
||||
// MIX4(s[7][0], s[7][1], s[7][2], s[7][3]);
|
||||
//
|
||||
// AES4_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 8);
|
||||
// MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
// MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
// MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
// MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
// MIX4(s[4][0], s[4][1], s[4][2], s[4][3]);
|
||||
// MIX4(s[5][0], s[5][1], s[5][2], s[5][3]);
|
||||
// MIX4(s[6][0], s[6][1], s[6][2], s[6][3]);
|
||||
// MIX4(s[7][0], s[7][1], s[7][2], s[7][3]);
|
||||
//
|
||||
// AES4_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 16);
|
||||
// MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
// MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
// MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
// MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
// MIX4(s[4][0], s[4][1], s[4][2], s[4][3]);
|
||||
// MIX4(s[5][0], s[5][1], s[5][2], s[5][3]);
|
||||
// MIX4(s[6][0], s[6][1], s[6][2], s[6][3]);
|
||||
// MIX4(s[7][0], s[7][1], s[7][2], s[7][3]);
|
||||
//
|
||||
// AES4_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 24);
|
||||
// MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
// MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
// MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
// MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
// MIX4(s[4][0], s[4][1], s[4][2], s[4][3]);
|
||||
// MIX4(s[5][0], s[5][1], s[5][2], s[5][3]);
|
||||
// MIX4(s[6][0], s[6][1], s[6][2], s[6][3]);
|
||||
// MIX4(s[7][0], s[7][1], s[7][2], s[7][3]);
|
||||
//
|
||||
// AES4_8x(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], 32);
|
||||
// MIX4(s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
// MIX4(s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
// MIX4(s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
// MIX4(s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
// MIX4(s[4][0], s[4][1], s[4][2], s[4][3]);
|
||||
// MIX4(s[5][0], s[5][1], s[5][2], s[5][3]);
|
||||
// MIX4(s[6][0], s[6][1], s[6][2], s[6][3]);
|
||||
// MIX4(s[7][0], s[7][1], s[7][2], s[7][3]);
|
||||
//
|
||||
//
|
||||
// s[0][0] = _mm_xor_si128(s[0][0], LOAD(in));
|
||||
// s[0][1] = _mm_xor_si128(s[0][1], LOAD(in + 16));
|
||||
// s[0][2] = _mm_xor_si128(s[0][2], LOAD(in + 32));
|
||||
// s[0][3] = _mm_xor_si128(s[0][3], LOAD(in + 48));
|
||||
// s[1][0] = _mm_xor_si128(s[1][0], LOAD(in + 64));
|
||||
// s[1][1] = _mm_xor_si128(s[1][1], LOAD(in + 80));
|
||||
// s[1][2] = _mm_xor_si128(s[1][2], LOAD(in + 96));
|
||||
// s[1][3] = _mm_xor_si128(s[1][3], LOAD(in + 112));
|
||||
// s[2][0] = _mm_xor_si128(s[2][0], LOAD(in + 128));
|
||||
// s[2][1] = _mm_xor_si128(s[2][1], LOAD(in + 144));
|
||||
// s[2][2] = _mm_xor_si128(s[2][2], LOAD(in + 160));
|
||||
// s[2][3] = _mm_xor_si128(s[2][3], LOAD(in + 176));
|
||||
// s[3][0] = _mm_xor_si128(s[3][0], LOAD(in + 192));
|
||||
// s[3][1] = _mm_xor_si128(s[3][1], LOAD(in + 208));
|
||||
// s[3][2] = _mm_xor_si128(s[3][2], LOAD(in + 224));
|
||||
// s[3][3] = _mm_xor_si128(s[3][3], LOAD(in + 240));
|
||||
// s[4][0] = _mm_xor_si128(s[4][0], LOAD(in + 256));
|
||||
// s[4][1] = _mm_xor_si128(s[4][1], LOAD(in + 272));
|
||||
// s[4][2] = _mm_xor_si128(s[4][2], LOAD(in + 288));
|
||||
// s[4][3] = _mm_xor_si128(s[4][3], LOAD(in + 304));
|
||||
// s[5][0] = _mm_xor_si128(s[5][0], LOAD(in + 320));
|
||||
// s[5][1] = _mm_xor_si128(s[5][1], LOAD(in + 336));
|
||||
// s[5][2] = _mm_xor_si128(s[5][2], LOAD(in + 352));
|
||||
// s[5][3] = _mm_xor_si128(s[5][3], LOAD(in + 368));
|
||||
// s[6][0] = _mm_xor_si128(s[6][0], LOAD(in + 384));
|
||||
// s[6][1] = _mm_xor_si128(s[6][1], LOAD(in + 400));
|
||||
// s[6][2] = _mm_xor_si128(s[6][2], LOAD(in + 416));
|
||||
// s[6][3] = _mm_xor_si128(s[6][3], LOAD(in + 432));
|
||||
// s[7][0] = _mm_xor_si128(s[7][0], LOAD(in + 448));
|
||||
// s[7][1] = _mm_xor_si128(s[7][1], LOAD(in + 464));
|
||||
// s[7][2] = _mm_xor_si128(s[7][2], LOAD(in + 480));
|
||||
// s[7][3] = _mm_xor_si128(s[7][3], LOAD(in + 496));
|
||||
//
|
||||
// TRUNCSTORE(out, s[0][0], s[0][1], s[0][2], s[0][3]);
|
||||
// TRUNCSTORE(out + 32, s[1][0], s[1][1], s[1][2], s[1][3]);
|
||||
// TRUNCSTORE(out + 64, s[2][0], s[2][1], s[2][2], s[2][3]);
|
||||
// TRUNCSTORE(out + 96, s[3][0], s[3][1], s[3][2], s[3][3]);
|
||||
// TRUNCSTORE(out + 128, s[4][0], s[4][1], s[4][2], s[4][3]);
|
||||
// TRUNCSTORE(out + 160, s[5][0], s[5][1], s[5][2], s[5][3]);
|
||||
// TRUNCSTORE(out + 192, s[6][0], s[6][1], s[6][2], s[6][3]);
|
||||
// TRUNCSTORE(out + 224, s[7][0], s[7][1], s[7][2], s[7][3]);
|
||||
}
|
||||
126
src/crypto/haraka.h
Normal file
126
src/crypto/haraka.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 kste
|
||||
|
||||
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.
|
||||
|
||||
Optimized Implementations for Haraka256 and Haraka512
|
||||
*/
|
||||
#ifndef HARAKA_H_
|
||||
#define HARAKA_H_
|
||||
|
||||
#include "immintrin.h"
|
||||
|
||||
#define NUMROUNDS 5
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef unsigned long long u64;
|
||||
#else
|
||||
typedef unsigned long u64;
|
||||
#endif
|
||||
typedef __m128i u128;
|
||||
|
||||
extern u128 rc[40];
|
||||
|
||||
#define LOAD(src) _mm_load_si128((u128 *)(src))
|
||||
#define STORE(dest,src) _mm_storeu_si128((u128 *)(dest),src)
|
||||
|
||||
#define AES2(s0, s1, rci) \
|
||||
s0 = _mm_aesenc_si128(s0, rc[rci]); \
|
||||
s1 = _mm_aesenc_si128(s1, rc[rci + 1]); \
|
||||
s0 = _mm_aesenc_si128(s0, rc[rci + 2]); \
|
||||
s1 = _mm_aesenc_si128(s1, rc[rci + 3]);
|
||||
|
||||
#define AES2_4x(s0, s1, s2, s3, rci) \
|
||||
AES2(s0[0], s0[1], rci); \
|
||||
AES2(s1[0], s1[1], rci); \
|
||||
AES2(s2[0], s2[1], rci); \
|
||||
AES2(s3[0], s3[1], rci);
|
||||
|
||||
#define AES2_8x(s0, s1, s2, s3, s4, s5, s6, s7, rci) \
|
||||
AES2_4x(s0, s1, s2, s3, rci); \
|
||||
AES2_4x(s4, s5, s6, s7, rci);
|
||||
|
||||
#define AES4(s0, s1, s2, s3, rci) \
|
||||
s0 = _mm_aesenc_si128(s0, rc[rci]); \
|
||||
s1 = _mm_aesenc_si128(s1, rc[rci + 1]); \
|
||||
s2 = _mm_aesenc_si128(s2, rc[rci + 2]); \
|
||||
s3 = _mm_aesenc_si128(s3, rc[rci + 3]); \
|
||||
s0 = _mm_aesenc_si128(s0, rc[rci + 4]); \
|
||||
s1 = _mm_aesenc_si128(s1, rc[rci + 5]); \
|
||||
s2 = _mm_aesenc_si128(s2, rc[rci + 6]); \
|
||||
s3 = _mm_aesenc_si128(s3, rc[rci + 7]); \
|
||||
|
||||
#define AES4_zero(s0, s1, s2, s3, rci) \
|
||||
s0 = _mm_aesenc_si128(s0, rc0[rci]); \
|
||||
s1 = _mm_aesenc_si128(s1, rc0[rci + 1]); \
|
||||
s2 = _mm_aesenc_si128(s2, rc0[rci + 2]); \
|
||||
s3 = _mm_aesenc_si128(s3, rc0[rci + 3]); \
|
||||
s0 = _mm_aesenc_si128(s0, rc0[rci + 4]); \
|
||||
s1 = _mm_aesenc_si128(s1, rc0[rci + 5]); \
|
||||
s2 = _mm_aesenc_si128(s2, rc0[rci + 6]); \
|
||||
s3 = _mm_aesenc_si128(s3, rc0[rci + 7]); \
|
||||
|
||||
#define AES4_4x(s0, s1, s2, s3, rci) \
|
||||
AES4(s0[0], s0[1], s0[2], s0[3], rci); \
|
||||
AES4(s1[0], s1[1], s1[2], s1[3], rci); \
|
||||
AES4(s2[0], s2[1], s2[2], s2[3], rci); \
|
||||
AES4(s3[0], s3[1], s3[2], s3[3], rci);
|
||||
|
||||
#define AES4_8x(s0, s1, s2, s3, s4, s5, s6, s7, rci) \
|
||||
AES4_4x(s0, s1, s2, s3, rci); \
|
||||
AES4_4x(s4, s5, s6, s7, rci);
|
||||
|
||||
#define MIX2(s0, s1) \
|
||||
tmp = _mm_unpacklo_epi32(s0, s1); \
|
||||
s1 = _mm_unpackhi_epi32(s0, s1); \
|
||||
s0 = tmp;
|
||||
|
||||
#define MIX4(s0, s1, s2, s3) \
|
||||
tmp = _mm_unpacklo_epi32(s0, s1); \
|
||||
s0 = _mm_unpackhi_epi32(s0, s1); \
|
||||
s1 = _mm_unpacklo_epi32(s2, s3); \
|
||||
s2 = _mm_unpackhi_epi32(s2, s3); \
|
||||
s3 = _mm_unpacklo_epi32(s0, s2); \
|
||||
s0 = _mm_unpackhi_epi32(s0, s2); \
|
||||
s2 = _mm_unpackhi_epi32(s1, tmp); \
|
||||
s1 = _mm_unpacklo_epi32(s1, tmp);
|
||||
|
||||
#define TRUNCSTORE(out, s0, s1, s2, s3) \
|
||||
*(u64*)(out) = (u64*)(s0)[1]; \
|
||||
*(u64*)(out + 8) = (u64*)(s1)[1]; \
|
||||
*(u64*)(out + 16) = (u64*)(s2)[0]; \
|
||||
*(u64*)(out + 24) = (u64*)(s3)[0];
|
||||
|
||||
void load_constants();
|
||||
void test_implementations();
|
||||
|
||||
void load_constants();
|
||||
|
||||
void haraka256(unsigned char *out, const unsigned char *in);
|
||||
void haraka256_4x(unsigned char *out, const unsigned char *in);
|
||||
void haraka256_8x(unsigned char *out, const unsigned char *in);
|
||||
|
||||
void haraka512(unsigned char *out, const unsigned char *in);
|
||||
void haraka512_zero(unsigned char *out, const unsigned char *in);
|
||||
void haraka512_4x(unsigned char *out, const unsigned char *in);
|
||||
void haraka512_8x(unsigned char *out, const unsigned char *in);
|
||||
|
||||
#endif
|
||||
375
src/crypto/haraka_portable.c
Normal file
375
src/crypto/haraka_portable.c
Normal file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
Plain C implementation of the Haraka256 and Haraka512 permutations.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "haraka_portable.h"
|
||||
|
||||
#define HARAKAS_RATE 32
|
||||
|
||||
static const unsigned char haraka_rc[40][16] = {
|
||||
{0x9d, 0x7b, 0x81, 0x75, 0xf0, 0xfe, 0xc5, 0xb2, 0x0a, 0xc0, 0x20, 0xe6, 0x4c, 0x70, 0x84, 0x06},
|
||||
{0x17, 0xf7, 0x08, 0x2f, 0xa4, 0x6b, 0x0f, 0x64, 0x6b, 0xa0, 0xf3, 0x88, 0xe1, 0xb4, 0x66, 0x8b},
|
||||
{0x14, 0x91, 0x02, 0x9f, 0x60, 0x9d, 0x02, 0xcf, 0x98, 0x84, 0xf2, 0x53, 0x2d, 0xde, 0x02, 0x34},
|
||||
{0x79, 0x4f, 0x5b, 0xfd, 0xaf, 0xbc, 0xf3, 0xbb, 0x08, 0x4f, 0x7b, 0x2e, 0xe6, 0xea, 0xd6, 0x0e},
|
||||
{0x44, 0x70, 0x39, 0xbe, 0x1c, 0xcd, 0xee, 0x79, 0x8b, 0x44, 0x72, 0x48, 0xcb, 0xb0, 0xcf, 0xcb},
|
||||
{0x7b, 0x05, 0x8a, 0x2b, 0xed, 0x35, 0x53, 0x8d, 0xb7, 0x32, 0x90, 0x6e, 0xee, 0xcd, 0xea, 0x7e},
|
||||
{0x1b, 0xef, 0x4f, 0xda, 0x61, 0x27, 0x41, 0xe2, 0xd0, 0x7c, 0x2e, 0x5e, 0x43, 0x8f, 0xc2, 0x67},
|
||||
{0x3b, 0x0b, 0xc7, 0x1f, 0xe2, 0xfd, 0x5f, 0x67, 0x07, 0xcc, 0xca, 0xaf, 0xb0, 0xd9, 0x24, 0x29},
|
||||
{0xee, 0x65, 0xd4, 0xb9, 0xca, 0x8f, 0xdb, 0xec, 0xe9, 0x7f, 0x86, 0xe6, 0xf1, 0x63, 0x4d, 0xab},
|
||||
{0x33, 0x7e, 0x03, 0xad, 0x4f, 0x40, 0x2a, 0x5b, 0x64, 0xcd, 0xb7, 0xd4, 0x84, 0xbf, 0x30, 0x1c},
|
||||
{0x00, 0x98, 0xf6, 0x8d, 0x2e, 0x8b, 0x02, 0x69, 0xbf, 0x23, 0x17, 0x94, 0xb9, 0x0b, 0xcc, 0xb2},
|
||||
{0x8a, 0x2d, 0x9d, 0x5c, 0xc8, 0x9e, 0xaa, 0x4a, 0x72, 0x55, 0x6f, 0xde, 0xa6, 0x78, 0x04, 0xfa},
|
||||
{0xd4, 0x9f, 0x12, 0x29, 0x2e, 0x4f, 0xfa, 0x0e, 0x12, 0x2a, 0x77, 0x6b, 0x2b, 0x9f, 0xb4, 0xdf},
|
||||
{0xee, 0x12, 0x6a, 0xbb, 0xae, 0x11, 0xd6, 0x32, 0x36, 0xa2, 0x49, 0xf4, 0x44, 0x03, 0xa1, 0x1e},
|
||||
{0xa6, 0xec, 0xa8, 0x9c, 0xc9, 0x00, 0x96, 0x5f, 0x84, 0x00, 0x05, 0x4b, 0x88, 0x49, 0x04, 0xaf},
|
||||
{0xec, 0x93, 0xe5, 0x27, 0xe3, 0xc7, 0xa2, 0x78, 0x4f, 0x9c, 0x19, 0x9d, 0xd8, 0x5e, 0x02, 0x21},
|
||||
{0x73, 0x01, 0xd4, 0x82, 0xcd, 0x2e, 0x28, 0xb9, 0xb7, 0xc9, 0x59, 0xa7, 0xf8, 0xaa, 0x3a, 0xbf},
|
||||
{0x6b, 0x7d, 0x30, 0x10, 0xd9, 0xef, 0xf2, 0x37, 0x17, 0xb0, 0x86, 0x61, 0x0d, 0x70, 0x60, 0x62},
|
||||
{0xc6, 0x9a, 0xfc, 0xf6, 0x53, 0x91, 0xc2, 0x81, 0x43, 0x04, 0x30, 0x21, 0xc2, 0x45, 0xca, 0x5a},
|
||||
{0x3a, 0x94, 0xd1, 0x36, 0xe8, 0x92, 0xaf, 0x2c, 0xbb, 0x68, 0x6b, 0x22, 0x3c, 0x97, 0x23, 0x92},
|
||||
{0xb4, 0x71, 0x10, 0xe5, 0x58, 0xb9, 0xba, 0x6c, 0xeb, 0x86, 0x58, 0x22, 0x38, 0x92, 0xbf, 0xd3},
|
||||
{0x8d, 0x12, 0xe1, 0x24, 0xdd, 0xfd, 0x3d, 0x93, 0x77, 0xc6, 0xf0, 0xae, 0xe5, 0x3c, 0x86, 0xdb},
|
||||
{0xb1, 0x12, 0x22, 0xcb, 0xe3, 0x8d, 0xe4, 0x83, 0x9c, 0xa0, 0xeb, 0xff, 0x68, 0x62, 0x60, 0xbb},
|
||||
{0x7d, 0xf7, 0x2b, 0xc7, 0x4e, 0x1a, 0xb9, 0x2d, 0x9c, 0xd1, 0xe4, 0xe2, 0xdc, 0xd3, 0x4b, 0x73},
|
||||
{0x4e, 0x92, 0xb3, 0x2c, 0xc4, 0x15, 0x14, 0x4b, 0x43, 0x1b, 0x30, 0x61, 0xc3, 0x47, 0xbb, 0x43},
|
||||
{0x99, 0x68, 0xeb, 0x16, 0xdd, 0x31, 0xb2, 0x03, 0xf6, 0xef, 0x07, 0xe7, 0xa8, 0x75, 0xa7, 0xdb},
|
||||
{0x2c, 0x47, 0xca, 0x7e, 0x02, 0x23, 0x5e, 0x8e, 0x77, 0x59, 0x75, 0x3c, 0x4b, 0x61, 0xf3, 0x6d},
|
||||
{0xf9, 0x17, 0x86, 0xb8, 0xb9, 0xe5, 0x1b, 0x6d, 0x77, 0x7d, 0xde, 0xd6, 0x17, 0x5a, 0xa7, 0xcd},
|
||||
{0x5d, 0xee, 0x46, 0xa9, 0x9d, 0x06, 0x6c, 0x9d, 0xaa, 0xe9, 0xa8, 0x6b, 0xf0, 0x43, 0x6b, 0xec},
|
||||
{0xc1, 0x27, 0xf3, 0x3b, 0x59, 0x11, 0x53, 0xa2, 0x2b, 0x33, 0x57, 0xf9, 0x50, 0x69, 0x1e, 0xcb},
|
||||
{0xd9, 0xd0, 0x0e, 0x60, 0x53, 0x03, 0xed, 0xe4, 0x9c, 0x61, 0xda, 0x00, 0x75, 0x0c, 0xee, 0x2c},
|
||||
{0x50, 0xa3, 0xa4, 0x63, 0xbc, 0xba, 0xbb, 0x80, 0xab, 0x0c, 0xe9, 0x96, 0xa1, 0xa5, 0xb1, 0xf0},
|
||||
{0x39, 0xca, 0x8d, 0x93, 0x30, 0xde, 0x0d, 0xab, 0x88, 0x29, 0x96, 0x5e, 0x02, 0xb1, 0x3d, 0xae},
|
||||
{0x42, 0xb4, 0x75, 0x2e, 0xa8, 0xf3, 0x14, 0x88, 0x0b, 0xa4, 0x54, 0xd5, 0x38, 0x8f, 0xbb, 0x17},
|
||||
{0xf6, 0x16, 0x0a, 0x36, 0x79, 0xb7, 0xb6, 0xae, 0xd7, 0x7f, 0x42, 0x5f, 0x5b, 0x8a, 0xbb, 0x34},
|
||||
{0xde, 0xaf, 0xba, 0xff, 0x18, 0x59, 0xce, 0x43, 0x38, 0x54, 0xe5, 0xcb, 0x41, 0x52, 0xf6, 0x26},
|
||||
{0x78, 0xc9, 0x9e, 0x83, 0xf7, 0x9c, 0xca, 0xa2, 0x6a, 0x02, 0xf3, 0xb9, 0x54, 0x9a, 0xe9, 0x4c},
|
||||
{0x35, 0x12, 0x90, 0x22, 0x28, 0x6e, 0xc0, 0x40, 0xbe, 0xf7, 0xdf, 0x1b, 0x1a, 0xa5, 0x51, 0xae},
|
||||
{0xcf, 0x59, 0xa6, 0x48, 0x0f, 0xbc, 0x73, 0xc1, 0x2b, 0xd2, 0x7e, 0xba, 0x3c, 0x61, 0xc1, 0xa0},
|
||||
{0xa1, 0x9d, 0xc5, 0xe9, 0xfd, 0xbd, 0xd6, 0x4a, 0x88, 0x82, 0x28, 0x02, 0x03, 0xcc, 0x6a, 0x75}
|
||||
};
|
||||
|
||||
static unsigned char rc[40][16];
|
||||
static unsigned char rc0[40][16];
|
||||
static unsigned char rc_sseed[40][16];
|
||||
|
||||
static const unsigned char sbox[256] =
|
||||
{ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe,
|
||||
0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4,
|
||||
0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7,
|
||||
0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3,
|
||||
0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09,
|
||||
0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3,
|
||||
0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe,
|
||||
0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
|
||||
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92,
|
||||
0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c,
|
||||
0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19,
|
||||
0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
|
||||
0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2,
|
||||
0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5,
|
||||
0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25,
|
||||
0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86,
|
||||
0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e,
|
||||
0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42,
|
||||
0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
|
||||
|
||||
#define XT(x) (((x) << 1) ^ ((((x) >> 7) & 1) * 0x1b))
|
||||
|
||||
// Simulate _mm_aesenc_si128 instructions from AESNI
|
||||
void aesenc(unsigned char *s, const unsigned char *rk)
|
||||
{
|
||||
unsigned char i, t, u, v[4][4];
|
||||
for (i = 0; i < 16; ++i) {
|
||||
v[((i / 4) + 4 - (i%4) ) % 4][i % 4] = sbox[s[i]];
|
||||
}
|
||||
for (i = 0; i < 4; ++i) {
|
||||
t = v[i][0];
|
||||
u = v[i][0] ^ v[i][1] ^ v[i][2] ^ v[i][3];
|
||||
v[i][0] ^= u ^ XT(v[i][0] ^ v[i][1]);
|
||||
v[i][1] ^= u ^ XT(v[i][1] ^ v[i][2]);
|
||||
v[i][2] ^= u ^ XT(v[i][2] ^ v[i][3]);
|
||||
v[i][3] ^= u ^ XT(v[i][3] ^ t);
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
s[i] = v[i / 4][i % 4] ^ rk[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Simulate _mm_unpacklo_epi32
|
||||
void unpacklo32(unsigned char *t, unsigned char *a, unsigned char *b)
|
||||
{
|
||||
unsigned char tmp[16];
|
||||
memcpy(tmp, a, 4);
|
||||
memcpy(tmp + 4, b, 4);
|
||||
memcpy(tmp + 8, a + 4, 4);
|
||||
memcpy(tmp + 12, b + 4, 4);
|
||||
memcpy(t, tmp, 16);
|
||||
}
|
||||
|
||||
// Simulate _mm_unpackhi_epi32
|
||||
void unpackhi32(unsigned char *t, unsigned char *a, unsigned char *b)
|
||||
{
|
||||
unsigned char tmp[16];
|
||||
memcpy(tmp, a + 8, 4);
|
||||
memcpy(tmp + 4, b + 8, 4);
|
||||
memcpy(tmp + 8, a + 12, 4);
|
||||
memcpy(tmp + 12, b + 12, 4);
|
||||
memcpy(t, tmp, 16);
|
||||
}
|
||||
|
||||
void load_constants_port()
|
||||
{
|
||||
/* Use the standard constants to generate tweaked ones. */
|
||||
memcpy(rc, haraka_rc, 40*16);
|
||||
}
|
||||
|
||||
void tweak_constants(const unsigned char *pk_seed, const unsigned char *sk_seed,
|
||||
unsigned long long seed_length)
|
||||
{
|
||||
unsigned char buf[40*16];
|
||||
|
||||
/* Use the standard constants to generate tweaked ones. */
|
||||
memcpy(rc, haraka_rc, 40*16);
|
||||
|
||||
/* Constants for sk.seed */
|
||||
if (sk_seed != NULL) {
|
||||
haraka_S(buf, 40*16, sk_seed, seed_length);
|
||||
memcpy(rc_sseed, buf, 40*16);
|
||||
}
|
||||
|
||||
/* Constants for pk.seed */
|
||||
haraka_S(buf, 40*16, pk_seed, seed_length);
|
||||
memcpy(rc, buf, 40*16);
|
||||
}
|
||||
|
||||
static void haraka_S_absorb(unsigned char *s, unsigned int r,
|
||||
const unsigned char *m, unsigned long long mlen,
|
||||
unsigned char p)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned char t[r];
|
||||
|
||||
while (mlen >= r) {
|
||||
// XOR block to state
|
||||
for (i = 0; i < r; ++i) {
|
||||
s[i] ^= m[i];
|
||||
}
|
||||
haraka512_perm(s, s);
|
||||
mlen -= r;
|
||||
m += r;
|
||||
}
|
||||
|
||||
for (i = 0; i < r; ++i) {
|
||||
t[i] = 0;
|
||||
}
|
||||
for (i = 0; i < mlen; ++i) {
|
||||
t[i] = m[i];
|
||||
}
|
||||
t[i] = p;
|
||||
t[r - 1] |= 128;
|
||||
for (i = 0; i < r; ++i) {
|
||||
s[i] ^= t[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void haraka_S_squeezeblocks(unsigned char *h, unsigned long long nblocks,
|
||||
unsigned char *s, unsigned int r)
|
||||
{
|
||||
while (nblocks > 0) {
|
||||
haraka512_perm(s, s);
|
||||
memcpy(h, s, HARAKAS_RATE);
|
||||
h += r;
|
||||
nblocks--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void haraka_S(unsigned char *out, unsigned long long outlen,
|
||||
const unsigned char *in, unsigned long long inlen)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned char s[64];
|
||||
unsigned char d[32];
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
s[i] = 0;
|
||||
}
|
||||
haraka_S_absorb(s, 32, in, inlen, 0x1F);
|
||||
|
||||
haraka_S_squeezeblocks(out, outlen / 32, s, 32);
|
||||
out += (outlen / 32) * 32;
|
||||
|
||||
if (outlen % 32) {
|
||||
haraka_S_squeezeblocks(d, 1, s, 32);
|
||||
for (i = 0; i < outlen % 32; i++) {
|
||||
out[i] = d[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void haraka512_perm(unsigned char *out, const unsigned char *in)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
unsigned char s[64], tmp[16];
|
||||
|
||||
memcpy(s, in, 16);
|
||||
memcpy(s + 16, in + 16, 16);
|
||||
memcpy(s + 32, in + 32, 16);
|
||||
memcpy(s + 48, in + 48, 16);
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
// aes round(s)
|
||||
for (j = 0; j < 2; ++j) {
|
||||
aesenc(s, rc[4*2*i + 4*j]);
|
||||
aesenc(s + 16, rc[4*2*i + 4*j + 1]);
|
||||
aesenc(s + 32, rc[4*2*i + 4*j + 2]);
|
||||
aesenc(s + 48, rc[4*2*i + 4*j + 3]);
|
||||
}
|
||||
|
||||
// mixing
|
||||
unpacklo32(tmp, s, s + 16);
|
||||
unpackhi32(s, s, s + 16);
|
||||
unpacklo32(s + 16, s + 32, s + 48);
|
||||
unpackhi32(s + 32, s + 32, s + 48);
|
||||
unpacklo32(s + 48, s, s + 32);
|
||||
unpackhi32(s, s, s + 32);
|
||||
unpackhi32(s + 32, s + 16, tmp);
|
||||
unpacklo32(s + 16, s + 16, tmp);
|
||||
}
|
||||
|
||||
memcpy(out, s, 64);
|
||||
}
|
||||
|
||||
void haraka512_port(unsigned char *out, const unsigned char *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
unsigned char buf[64];
|
||||
|
||||
haraka512_perm(buf, in);
|
||||
/* Feed-forward */
|
||||
for (i = 0; i < 64; i++) {
|
||||
buf[i] = buf[i] ^ in[i];
|
||||
}
|
||||
|
||||
/* Truncated */
|
||||
memcpy(out, buf + 8, 8);
|
||||
memcpy(out + 8, buf + 24, 8);
|
||||
memcpy(out + 16, buf + 32, 8);
|
||||
memcpy(out + 24, buf + 48, 8);
|
||||
}
|
||||
|
||||
void haraka512_perm_zero(unsigned char *out, const unsigned char *in)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
unsigned char s[64], tmp[16];
|
||||
|
||||
memcpy(s, in, 16);
|
||||
memcpy(s + 16, in + 16, 16);
|
||||
memcpy(s + 32, in + 32, 16);
|
||||
memcpy(s + 48, in + 48, 16);
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
// aes round(s)
|
||||
for (j = 0; j < 2; ++j) {
|
||||
aesenc(s, rc0[4*2*i + 4*j]);
|
||||
aesenc(s + 16, rc0[4*2*i + 4*j + 1]);
|
||||
aesenc(s + 32, rc0[4*2*i + 4*j + 2]);
|
||||
aesenc(s + 48, rc0[4*2*i + 4*j + 3]);
|
||||
}
|
||||
|
||||
// mixing
|
||||
unpacklo32(tmp, s, s + 16);
|
||||
unpackhi32(s, s, s + 16);
|
||||
unpacklo32(s + 16, s + 32, s + 48);
|
||||
unpackhi32(s + 32, s + 32, s + 48);
|
||||
unpacklo32(s + 48, s, s + 32);
|
||||
unpackhi32(s, s, s + 32);
|
||||
unpackhi32(s + 32, s + 16, tmp);
|
||||
unpacklo32(s + 16, s + 16, tmp);
|
||||
}
|
||||
|
||||
memcpy(out, s, 64);
|
||||
}
|
||||
|
||||
void haraka512_port_zero(unsigned char *out, const unsigned char *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
unsigned char buf[64];
|
||||
|
||||
haraka512_perm_zero(buf, in);
|
||||
/* Feed-forward */
|
||||
for (i = 0; i < 64; i++) {
|
||||
buf[i] = buf[i] ^ in[i];
|
||||
}
|
||||
|
||||
/* Truncated */
|
||||
memcpy(out, buf + 8, 8);
|
||||
memcpy(out + 8, buf + 24, 8);
|
||||
memcpy(out + 16, buf + 32, 8);
|
||||
memcpy(out + 24, buf + 48, 8);
|
||||
}
|
||||
|
||||
void haraka256_port(unsigned char *out, const unsigned char *in)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
unsigned char s[32], tmp[16];
|
||||
|
||||
memcpy(s, in, 16);
|
||||
memcpy(s + 16, in + 16, 16);
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
// aes round(s)
|
||||
for (j = 0; j < 2; ++j) {
|
||||
aesenc(s, rc[2*2*i + 2*j]);
|
||||
aesenc(s + 16, rc[2*2*i + 2*j + 1]);
|
||||
}
|
||||
|
||||
// mixing
|
||||
unpacklo32(tmp, s, s + 16);
|
||||
unpackhi32(s + 16, s, s + 16);
|
||||
memcpy(s, tmp, 16);
|
||||
}
|
||||
|
||||
/* Feed-forward */
|
||||
for (i = 0; i < 32; i++) {
|
||||
out[i] = in[i] ^ s[i];
|
||||
}
|
||||
}
|
||||
|
||||
void haraka256_sk(unsigned char *out, const unsigned char *in)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
unsigned char s[32], tmp[16];
|
||||
|
||||
memcpy(s, in, 16);
|
||||
memcpy(s + 16, in + 16, 16);
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
// aes round(s)
|
||||
for (j = 0; j < 2; ++j) {
|
||||
aesenc(s, rc_sseed[2*2*i + 2*j]);
|
||||
aesenc(s + 16, rc_sseed[2*2*i + 2*j + 1]);
|
||||
}
|
||||
|
||||
// mixing
|
||||
unpacklo32(tmp, s, s + 16);
|
||||
unpackhi32(s + 16, s, s + 16);
|
||||
memcpy(s, tmp, 16);
|
||||
}
|
||||
|
||||
/* Feed-forward */
|
||||
for (i = 0; i < 32; i++) {
|
||||
out[i] = in[i] ^ s[i];
|
||||
}
|
||||
}
|
||||
33
src/crypto/haraka_portable.h
Normal file
33
src/crypto/haraka_portable.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef SPX_HARAKA_H
|
||||
#define SPX_HARAKA_H
|
||||
|
||||
/* load constants */
|
||||
void load_constants_port();
|
||||
|
||||
/* Tweak constants with seed */
|
||||
void tweak_constants(const unsigned char *pk_seed, const unsigned char *sk_seed,
|
||||
unsigned long long seed_length);
|
||||
|
||||
/* Haraka Sponge */
|
||||
void haraka_S(unsigned char *out, unsigned long long outlen,
|
||||
const unsigned char *in, unsigned long long inlen);
|
||||
|
||||
/* Applies the 512-bit Haraka permutation to in. */
|
||||
void haraka512_perm(unsigned char *out, const unsigned char *in);
|
||||
|
||||
/* Implementation of Haraka-512 */
|
||||
void haraka512_port(unsigned char *out, const unsigned char *in);
|
||||
|
||||
/* Applies the 512-bit Haraka permutation to in, using zero key. */
|
||||
void haraka512_perm_zero(unsigned char *out, const unsigned char *in);
|
||||
|
||||
/* Implementation of Haraka-512, using zero key */
|
||||
void haraka512_port_zero(unsigned char *out, const unsigned char *in);
|
||||
|
||||
/* Implementation of Haraka-256 */
|
||||
void haraka256_port(unsigned char *out, const unsigned char *in);
|
||||
|
||||
/* Implementation of Haraka-256 using sk.seed constants */
|
||||
void haraka256_sk(unsigned char *out, const unsigned char *in);
|
||||
|
||||
#endif
|
||||
180
src/crypto/verus_hash.cpp
Normal file
180
src/crypto/verus_hash.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
// (C) 2018 The Verus Developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/*
|
||||
This provides the PoW hash function for Verus, a CPU-optimized hash
|
||||
function with a Haraka V2 core. Unlike Haraka, which is made for short
|
||||
inputs only, Verus Hash takes any length of input and produces a 256
|
||||
bit output.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "crypto/common.h"
|
||||
#include "crypto/verus_hash.h"
|
||||
|
||||
void (*CVerusHash::haraka512Function)(unsigned char *out, const unsigned char *in);
|
||||
|
||||
void CVerusHash::Hash(void *result, const void *data, size_t _len)
|
||||
{
|
||||
unsigned char buf[128];
|
||||
unsigned char *bufPtr = buf;
|
||||
int nextOffset = 64;
|
||||
uint32_t pos = 0, len = _len;
|
||||
unsigned char *bufPtr2 = bufPtr + nextOffset;
|
||||
unsigned char *ptr = (unsigned char *)data;
|
||||
|
||||
// put our last result or zero at beginning of buffer each time
|
||||
memset(bufPtr, 0, 32);
|
||||
|
||||
// digest up to 32 bytes at a time
|
||||
for ( ; pos < len; pos += 32)
|
||||
{
|
||||
if (len - pos >= 32)
|
||||
{
|
||||
memcpy(bufPtr + 32, ptr + pos, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = (int)(len - pos);
|
||||
memcpy(bufPtr + 32, ptr + pos, i);
|
||||
memset(bufPtr + 32 + i, 0, 32 - i);
|
||||
}
|
||||
(*haraka512Function)(bufPtr2, bufPtr);
|
||||
bufPtr2 = bufPtr;
|
||||
bufPtr += nextOffset;
|
||||
nextOffset *= -1;
|
||||
}
|
||||
memcpy(result, bufPtr, 32);
|
||||
};
|
||||
|
||||
void CVerusHash::init()
|
||||
{
|
||||
if (IsCPUVerusOptimized())
|
||||
{
|
||||
haraka512Function = &haraka512_zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
haraka512Function = &haraka512_port_zero;
|
||||
}
|
||||
}
|
||||
|
||||
CVerusHash &CVerusHash::Write(const unsigned char *data, size_t _len)
|
||||
{
|
||||
unsigned char *tmp;
|
||||
uint32_t pos, len = _len;
|
||||
|
||||
// digest up to 32 bytes at a time
|
||||
for ( pos = 0; pos < len; )
|
||||
{
|
||||
uint32_t room = 32 - curPos;
|
||||
|
||||
if (len - pos >= room)
|
||||
{
|
||||
memcpy(curBuf + 32 + curPos, data + pos, room);
|
||||
(*haraka512Function)(result, curBuf);
|
||||
tmp = curBuf;
|
||||
curBuf = result;
|
||||
result = tmp;
|
||||
pos += room;
|
||||
curPos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(curBuf + 32 + curPos, data + pos, len - pos);
|
||||
curPos += len - pos;
|
||||
pos = len;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// to be declared and accessed from C
|
||||
void verus_hash(void *result, const void *data, size_t len)
|
||||
{
|
||||
return CVerusHash::Hash(result, data, len);
|
||||
}
|
||||
|
||||
void (*CVerusHashV2::haraka512Function)(unsigned char *out, const unsigned char *in);
|
||||
|
||||
void CVerusHashV2::init()
|
||||
{
|
||||
if (IsCPUVerusOptimized())
|
||||
{
|
||||
load_constants();
|
||||
haraka512Function = &haraka512;
|
||||
}
|
||||
else
|
||||
{
|
||||
// load and tweak the haraka constants
|
||||
load_constants_port();
|
||||
haraka512Function = &haraka512_port;
|
||||
}
|
||||
}
|
||||
|
||||
void CVerusHashV2::Hash(void *result, const void *data, size_t len)
|
||||
{
|
||||
unsigned char buf[128];
|
||||
unsigned char *bufPtr = buf;
|
||||
int pos = 0, nextOffset = 64;
|
||||
unsigned char *bufPtr2 = bufPtr + nextOffset;
|
||||
unsigned char *ptr = (unsigned char *)data;
|
||||
|
||||
// put our last result or zero at beginning of buffer each time
|
||||
memset(bufPtr, 0, 32);
|
||||
|
||||
// digest up to 32 bytes at a time
|
||||
for ( ; pos < len; pos += 32)
|
||||
{
|
||||
if (len - pos >= 32)
|
||||
{
|
||||
memcpy(bufPtr + 32, ptr + pos, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = (int)(len - pos);
|
||||
memcpy(bufPtr + 32, ptr + pos, i);
|
||||
memset(bufPtr + 32 + i, 0, 32 - i);
|
||||
}
|
||||
(*haraka512Function)(bufPtr2, bufPtr);
|
||||
bufPtr2 = bufPtr;
|
||||
bufPtr += nextOffset;
|
||||
nextOffset *= -1;
|
||||
}
|
||||
memcpy(result, bufPtr, 32);
|
||||
};
|
||||
|
||||
CVerusHashV2 &CVerusHashV2::Write(const unsigned char *data, size_t len)
|
||||
{
|
||||
unsigned char *tmp;
|
||||
|
||||
// digest up to 32 bytes at a time
|
||||
for ( int pos = 0; pos < len; )
|
||||
{
|
||||
int room = 32 - curPos;
|
||||
|
||||
if (len - pos >= room)
|
||||
{
|
||||
memcpy(curBuf + 32 + curPos, data + pos, room);
|
||||
(*haraka512Function)(result, curBuf);
|
||||
tmp = curBuf;
|
||||
curBuf = result;
|
||||
result = tmp;
|
||||
pos += room;
|
||||
curPos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(curBuf + 32 + curPos, data + pos, len - pos);
|
||||
curPos += len - pos;
|
||||
pos = len;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// to be declared and accessed from C
|
||||
void verus_hash_v2(void *result, const void *data, size_t len)
|
||||
{
|
||||
return CVerusHashV2::Hash(result, data, len);
|
||||
}
|
||||
133
src/crypto/verus_hash.h
Normal file
133
src/crypto/verus_hash.h
Normal file
@@ -0,0 +1,133 @@
|
||||
// (C) 2018 Michael Toutonghi
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/*
|
||||
This provides the PoW hash function for Verus, enabling CPU mining.
|
||||
*/
|
||||
#ifndef VERUS_HASH_H_
|
||||
#define VERUS_HASH_H_
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "crypto/haraka.h"
|
||||
#include "crypto/haraka_portable.h"
|
||||
}
|
||||
|
||||
class CVerusHash
|
||||
{
|
||||
public:
|
||||
static void Hash(void *result, const void *data, size_t len);
|
||||
static void (*haraka512Function)(unsigned char *out, const unsigned char *in);
|
||||
|
||||
static void init();
|
||||
|
||||
CVerusHash() { }
|
||||
|
||||
CVerusHash &Write(const unsigned char *data, size_t len);
|
||||
|
||||
CVerusHash &Reset()
|
||||
{
|
||||
curBuf = buf1;
|
||||
result = buf2;
|
||||
curPos = 0;
|
||||
std::fill(buf1, buf1 + sizeof(buf1), 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int64_t *ExtraI64Ptr() { return (int64_t *)(curBuf + 32); }
|
||||
void ClearExtra()
|
||||
{
|
||||
if (curPos)
|
||||
{
|
||||
std::fill(curBuf + 32 + curPos, curBuf + 64, 0);
|
||||
}
|
||||
}
|
||||
void ExtraHash(unsigned char hash[32]) { (*haraka512Function)(hash, curBuf); }
|
||||
|
||||
void Finalize(unsigned char hash[32])
|
||||
{
|
||||
if (curPos)
|
||||
{
|
||||
std::fill(curBuf + 32 + curPos, curBuf + 64, 0);
|
||||
(*haraka512Function)(hash, curBuf);
|
||||
}
|
||||
else
|
||||
std::memcpy(hash, curBuf, 32);
|
||||
}
|
||||
|
||||
private:
|
||||
// only buf1, the first source, needs to be zero initialized
|
||||
unsigned char buf1[64] = {0}, buf2[64];
|
||||
unsigned char *curBuf = buf1, *result = buf2;
|
||||
size_t curPos = 0;
|
||||
};
|
||||
|
||||
class CVerusHashV2
|
||||
{
|
||||
public:
|
||||
static void Hash(void *result, const void *data, size_t len);
|
||||
static void (*haraka512Function)(unsigned char *out, const unsigned char *in);
|
||||
|
||||
static void init();
|
||||
|
||||
CVerusHashV2() {}
|
||||
|
||||
CVerusHashV2 &Write(const unsigned char *data, size_t len);
|
||||
|
||||
CVerusHashV2 &Reset()
|
||||
{
|
||||
curBuf = buf1;
|
||||
result = buf2;
|
||||
curPos = 0;
|
||||
std::fill(buf1, buf1 + sizeof(buf1), 0);
|
||||
}
|
||||
|
||||
int64_t *ExtraI64Ptr() { return (int64_t *)(curBuf + 32); }
|
||||
void ClearExtra()
|
||||
{
|
||||
if (curPos)
|
||||
{
|
||||
std::fill(curBuf + 32 + curPos, curBuf + 64, 0);
|
||||
}
|
||||
}
|
||||
void ExtraHash(unsigned char hash[32]) { (*haraka512Function)(hash, curBuf); }
|
||||
|
||||
void Finalize(unsigned char hash[32])
|
||||
{
|
||||
if (curPos)
|
||||
{
|
||||
std::fill(curBuf + 32 + curPos, curBuf + 64, 0);
|
||||
(*haraka512Function)(hash, curBuf);
|
||||
}
|
||||
else
|
||||
std::memcpy(hash, curBuf, 32);
|
||||
}
|
||||
|
||||
private:
|
||||
// only buf1, the first source, needs to be zero initialized
|
||||
unsigned char buf1[64] = {0}, buf2[64];
|
||||
unsigned char *curBuf = buf1, *result = buf2;
|
||||
size_t curPos = 0;
|
||||
};
|
||||
|
||||
extern void verus_hash(void *result, const void *data, size_t len);
|
||||
extern void verus_hash_v2(void *result, const void *data, size_t len);
|
||||
|
||||
inline bool IsCPUVerusOptimized()
|
||||
{
|
||||
unsigned int eax,ebx,ecx,edx;
|
||||
|
||||
if (!__get_cpuid(1,&eax,&ebx,&ecx,&edx))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return ((ecx & (bit_AVX | bit_AES)) == (bit_AVX | bit_AES));
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -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)
|
||||
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) -march:x86-64 -g
|
||||
|
||||
CRYPTOCONDITIONS_CORE=libcryptoconditions_core.la
|
||||
|
||||
|
||||
@@ -56,8 +56,6 @@ typedef struct CC {
|
||||
};
|
||||
} CC;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Crypto Condition Visitor
|
||||
*/
|
||||
@@ -87,6 +85,7 @@ struct CC* cc_conditionFromJSON(cJSON *params, char *err);
|
||||
struct CC* cc_conditionFromJSONString(const char *json, char *err);
|
||||
struct CC* cc_readConditionBinary(const uint8_t *cond_bin, size_t cond_bin_len);
|
||||
struct CC* cc_readFulfillmentBinary(const uint8_t *ffill_bin, size_t ffill_bin_len);
|
||||
int cc_readFulfillmentBinaryExt(const unsigned char *ffill_bin, size_t ffill_bin_len, CC **ppcc);
|
||||
struct CC* cc_new(int typeId);
|
||||
struct cJSON* cc_conditionToJSON(const CC *cond);
|
||||
char* cc_conditionToJSONString(const CC *cond);
|
||||
|
||||
@@ -55,7 +55,7 @@ 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);
|
||||
//fprintf(stderr,"anon fingerprint %p %p\n",out,cond->fingerprint);
|
||||
memcpy(out, cond->fingerprint, 32);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define _CompoundSha256Condition_H_
|
||||
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
|
||||
/* Including external dependencies */
|
||||
#include <OCTET_STRING.h>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define _Condition_H_
|
||||
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
|
||||
/* Including external dependencies */
|
||||
#include "SimpleSha256Condition.h"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define _ConditionTypes_H_
|
||||
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
|
||||
/* Including external dependencies */
|
||||
#include <BIT_STRING.h>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define _Ed25519FingerprintContents_H_
|
||||
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
|
||||
/* Including external dependencies */
|
||||
#include <OCTET_STRING.h>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define _Ed25519Sha512Fulfillment_H_
|
||||
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
|
||||
/* Including external dependencies */
|
||||
#include <OCTET_STRING.h>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define _EvalFulfillment_H_
|
||||
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
|
||||
/* Including external dependencies */
|
||||
#include <OCTET_STRING.h>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define _Fulfillment_H_
|
||||
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
|
||||
/* Including external dependencies */
|
||||
#include "PreimageFulfillment.h"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#ifndef _INTEGER_H_
|
||||
#define _INTEGER_H_
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
#include <asn_codecs_prim.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#ifndef _NativeInteger_H_
|
||||
#define _NativeInteger_H_
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
#include <INTEGER.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#ifndef _OCTET_STRING_H_
|
||||
#define _OCTET_STRING_H_
|
||||
|
||||
#include <asn_application.h>
|
||||
#include "asn_application.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user