Merge branch 'FSM' of https://github.com/jl777/komodo into jl777-FSM

merge
This commit is contained in:
blackjok3r
2018-11-29 23:22:32 +08:00
566 changed files with 42751 additions and 10240 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -24,6 +24,7 @@ zcash_CreateJoinSplit_LDADD = \
$(LIBSNARK) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
$(LIBVERUS_CRYPTO) \
$(BOOST_LIBS) \
$(LIBZCASH_LIBS) \
$(LIBCRYPTOCONDITIONS) \

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);
}
};

View File

@@ -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",

View File

@@ -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"},

View File

@@ -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;

View File

@@ -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
View 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
View 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

View File

@@ -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()");

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();

View File

@@ -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);

View File

@@ -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 )

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 )

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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>> &params);
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);

View File

@@ -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();

View File

@@ -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();

View File

@@ -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;

View File

@@ -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>> &params)
{
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);
}

View File

@@ -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];

View File

@@ -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;

View File

@@ -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
}

View File

@@ -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);
}

View File

@@ -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
View File

@@ -0,0 +1,2 @@
gcc -o oraclefeed cc/dapps/oraclefeed.c -lm
gcc -o zmigrate cc/dapps/zmigrate.c -lm

View File

@@ -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
View 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);
}

View File

@@ -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++)

View File

@@ -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
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 )

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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()));
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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[] = {

View File

@@ -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.

View File

@@ -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 &currentRoot,
SproutMerkleTree &tree
)
{
assert(GetSproutAnchorAt(currentRoot, tree));
}
template<>
void CCoinsViewCache::BringBestAnchorIntoCache(
const uint256 &currentRoot,
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)
{

View File

@@ -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 &currentRoot,
Tree &tree
);
};
#endif // BITCOIN_COINS_H

View File

@@ -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));

View File

@@ -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 */

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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 &nota) {
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

View File

@@ -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()

View File

@@ -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
View 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
View 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

View 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];
}
}

View 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
View 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
View 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

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -8,7 +8,7 @@
#define _CompoundSha256Condition_H_
#include <asn_application.h>
#include "asn_application.h"
/* Including external dependencies */
#include <OCTET_STRING.h>

View File

@@ -8,7 +8,7 @@
#define _Condition_H_
#include <asn_application.h>
#include "asn_application.h"
/* Including external dependencies */
#include "SimpleSha256Condition.h"

View File

@@ -8,7 +8,7 @@
#define _ConditionTypes_H_
#include <asn_application.h>
#include "asn_application.h"
/* Including external dependencies */
#include <BIT_STRING.h>

View File

@@ -8,7 +8,7 @@
#define _Ed25519FingerprintContents_H_
#include <asn_application.h>
#include "asn_application.h"
/* Including external dependencies */
#include <OCTET_STRING.h>

View File

@@ -8,7 +8,7 @@
#define _Ed25519Sha512Fulfillment_H_
#include <asn_application.h>
#include "asn_application.h"
/* Including external dependencies */
#include <OCTET_STRING.h>

View File

@@ -8,7 +8,7 @@
#define _EvalFulfillment_H_
#include <asn_application.h>
#include "asn_application.h"
/* Including external dependencies */
#include <OCTET_STRING.h>

View File

@@ -8,7 +8,7 @@
#define _Fulfillment_H_
#include <asn_application.h>
#include "asn_application.h"
/* Including external dependencies */
#include "PreimageFulfillment.h"

View File

@@ -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

View File

@@ -12,7 +12,7 @@
#ifndef _NativeInteger_H_
#define _NativeInteger_H_
#include <asn_application.h>
#include "asn_application.h"
#include <INTEGER.h>
#ifdef __cplusplus

View File

@@ -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