Merge branch 'duke' into dev

Conflicts:
	src/chainparams.cpp
    src/primitives/block.h
This commit is contained in:
Duke Leto
2019-12-26 20:50:50 -05:00
330 changed files with 6573 additions and 47633 deletions

View File

@@ -297,7 +297,6 @@ libbitcoin_server_a_SOURCES = \
cc/oracles.cpp \
cc/prices.cpp \
cc/pegs.cpp \
cc/marmara.cpp \
cc/payments.cpp \
cc/gateways.cpp \
cc/channels.cpp \
@@ -307,8 +306,6 @@ libbitcoin_server_a_SOURCES = \
checkpoints.cpp \
crosschain.cpp \
crosschain_authority.cpp \
crypto/haraka.h \
crypto/haraka_portable.h \
deprecation.cpp \
httprpc.cpp \
httpserver.cpp \
@@ -413,6 +410,11 @@ crypto_libbitcoin_crypto_a_SOURCES = \
crypto/sha512.cpp \
crypto/sha512.h
if EXPERIMENTAL_ASM
crypto_libbitcoin_crypto_a_SOURCES += crypto/sha256_sse4.cpp
endif
if ENABLE_MINING
EQUIHASH_TROMP_SOURCES = \
pow/tromp/equi_miner.h \
@@ -439,8 +441,6 @@ libbitcoin_common_a_SOURCES = \
consensus/upgrades.cpp \
core_read.cpp \
core_write.cpp \
crypto/haraka.h \
crypto/haraka_portable.h \
hash.cpp \
importcoin.cpp \
key.cpp \

View File

@@ -1,418 +0,0 @@
bin_PROGRAMS += qt/komodo-qt
EXTRA_LIBRARIES += qt/libbitcoinqt.a
# bitcoin qt core #
QT_TS = \
qt/locale/bitcoin_ach.ts \
qt/locale/bitcoin_af_ZA.ts \
qt/locale/bitcoin_ar.ts \
qt/locale/bitcoin_be_BY.ts \
qt/locale/bitcoin_bg.ts \
qt/locale/bitcoin_bs.ts \
qt/locale/bitcoin_ca_ES.ts \
qt/locale/bitcoin_ca.ts \
qt/locale/bitcoin_ca@valencia.ts \
qt/locale/bitcoin_cmn.ts \
qt/locale/bitcoin_cs.ts \
qt/locale/bitcoin_cy.ts \
qt/locale/bitcoin_da.ts \
qt/locale/bitcoin_de.ts \
qt/locale/bitcoin_el_GR.ts \
qt/locale/bitcoin_en.ts \
qt/locale/bitcoin_eo.ts \
qt/locale/bitcoin_es_CL.ts \
qt/locale/bitcoin_es_DO.ts \
qt/locale/bitcoin_es_MX.ts \
qt/locale/bitcoin_es.ts \
qt/locale/bitcoin_es_UY.ts \
qt/locale/bitcoin_et.ts \
qt/locale/bitcoin_eu_ES.ts \
qt/locale/bitcoin_fa_IR.ts \
qt/locale/bitcoin_fa.ts \
qt/locale/bitcoin_fi.ts \
qt/locale/bitcoin_fr_CA.ts \
qt/locale/bitcoin_fr.ts \
qt/locale/bitcoin_gl.ts \
qt/locale/bitcoin_gu_IN.ts \
qt/locale/bitcoin_he.ts \
qt/locale/bitcoin_hi_IN.ts \
qt/locale/bitcoin_hr.ts \
qt/locale/bitcoin_hu.ts \
qt/locale/bitcoin_id_ID.ts \
qt/locale/bitcoin_it.ts \
qt/locale/bitcoin_ja.ts \
qt/locale/bitcoin_ka.ts \
qt/locale/bitcoin_kk_KZ.ts \
qt/locale/bitcoin_ko_KR.ts \
qt/locale/bitcoin_ky.ts \
qt/locale/bitcoin_la.ts \
qt/locale/bitcoin_lt.ts \
qt/locale/bitcoin_lv_LV.ts \
qt/locale/bitcoin_mn.ts \
qt/locale/bitcoin_ms_MY.ts \
qt/locale/bitcoin_nb.ts \
qt/locale/bitcoin_nl.ts \
qt/locale/bitcoin_pam.ts \
qt/locale/bitcoin_pl.ts \
qt/locale/bitcoin_pt_BR.ts \
qt/locale/bitcoin_pt_PT.ts \
qt/locale/bitcoin_ro_RO.ts \
qt/locale/bitcoin_ru.ts \
qt/locale/bitcoin_sah.ts \
qt/locale/bitcoin_sk.ts \
qt/locale/bitcoin_sl_SI.ts \
qt/locale/bitcoin_sq.ts \
qt/locale/bitcoin_sr.ts \
qt/locale/bitcoin_sv.ts \
qt/locale/bitcoin_th_TH.ts \
qt/locale/bitcoin_tr.ts \
qt/locale/bitcoin_uk.ts \
qt/locale/bitcoin_ur_PK.ts \
qt/locale/bitcoin_uz@Cyrl.ts \
qt/locale/bitcoin_vi.ts \
qt/locale/bitcoin_vi_VN.ts \
qt/locale/bitcoin_zh_CN.ts \
qt/locale/bitcoin_zh_HK.ts \
qt/locale/bitcoin_zh_TW.ts
QT_FORMS_UI = \
qt/forms/addressbookpage.ui \
qt/forms/askpassphrasedialog.ui \
qt/forms/coincontroldialog.ui \
qt/forms/editaddressdialog.ui \
qt/forms/helpmessagedialog.ui \
qt/forms/intro.ui \
qt/forms/openuridialog.ui \
qt/forms/optionsdialog.ui \
qt/forms/overviewpage.ui \
qt/forms/receivecoinsdialog.ui \
qt/forms/receiverequestdialog.ui \
qt/forms/rpcconsole.ui \
qt/forms/sendcoinsdialog.ui \
qt/forms/sendcoinsentry.ui \
qt/forms/signverifymessagedialog.ui \
qt/forms/transactiondescdialog.ui
QT_MOC_CPP = \
qt/moc_addressbookpage.cpp \
qt/moc_addresstablemodel.cpp \
qt/moc_askpassphrasedialog.cpp \
qt/moc_bitcoinaddressvalidator.cpp \
qt/moc_bitcoinamountfield.cpp \
qt/moc_bitcoingui.cpp \
qt/moc_bitcoinunits.cpp \
qt/moc_clientmodel.cpp \
qt/moc_coincontroldialog.cpp \
qt/moc_coincontroltreewidget.cpp \
qt/moc_csvmodelwriter.cpp \
qt/moc_editaddressdialog.cpp \
qt/moc_guiutil.cpp \
qt/moc_intro.cpp \
qt/moc_macdockiconhandler.cpp \
qt/moc_macnotificationhandler.cpp \
qt/moc_notificator.cpp \
qt/moc_openuridialog.cpp \
qt/moc_optionsdialog.cpp \
qt/moc_optionsmodel.cpp \
qt/moc_overviewpage.cpp \
qt/moc_peertablemodel.cpp \
qt/moc_paymentserver.cpp \
qt/moc_qvalidatedlineedit.cpp \
qt/moc_qvaluecombobox.cpp \
qt/moc_receivecoinsdialog.cpp \
qt/moc_receiverequestdialog.cpp \
qt/moc_recentrequeststablemodel.cpp \
qt/moc_rpcconsole.cpp \
qt/moc_sendcoinsdialog.cpp \
qt/moc_sendcoinsentry.cpp \
qt/moc_signverifymessagedialog.cpp \
qt/moc_splashscreen.cpp \
qt/moc_trafficgraphwidget.cpp \
qt/moc_transactiondesc.cpp \
qt/moc_transactiondescdialog.cpp \
qt/moc_transactionfilterproxy.cpp \
qt/moc_transactiontablemodel.cpp \
qt/moc_transactionview.cpp \
qt/moc_utilitydialog.cpp \
qt/moc_walletframe.cpp \
qt/moc_walletmodel.cpp \
qt/moc_walletview.cpp
BITCOIN_MM = \
qt/macdockiconhandler.mm \
qt/macnotificationhandler.mm
QT_MOC = \
qt/bitcoin.moc \
qt/bitcoinamountfield.moc \
qt/intro.moc \
qt/overviewpage.moc \
qt/rpcconsole.moc
QT_QRC_CPP = qt/qrc_bitcoin.cpp
QT_QRC = qt/bitcoin.qrc
QT_QRC_LOCALE_CPP = qt/qrc_bitcoin_locale.cpp
QT_QRC_LOCALE = qt/bitcoin_locale.qrc
PROTOBUF_CC = qt/paymentrequest.pb.cc
PROTOBUF_H = qt/paymentrequest.pb.h
PROTOBUF_PROTO = qt/paymentrequest.proto
BITCOIN_QT_H = \
qt/addressbookpage.h \
qt/addresstablemodel.h \
qt/askpassphrasedialog.h \
qt/bitcoinaddressvalidator.h \
qt/bitcoinamountfield.h \
qt/bitcoingui.h \
qt/bitcoinunits.h \
qt/clientmodel.h \
qt/coincontroldialog.h \
qt/coincontroltreewidget.h \
qt/csvmodelwriter.h \
qt/editaddressdialog.h \
qt/guiconstants.h \
qt/guiutil.h \
qt/intro.h \
qt/macdockiconhandler.h \
qt/macnotificationhandler.h \
qt/networkstyle.h \
qt/notificator.h \
qt/openuridialog.h \
qt/optionsdialog.h \
qt/optionsmodel.h \
qt/overviewpage.h \
qt/paymentrequestplus.h \
qt/paymentserver.h \
qt/peertablemodel.h \
qt/qvalidatedlineedit.h \
qt/qvaluecombobox.h \
qt/receivecoinsdialog.h \
qt/receiverequestdialog.h \
qt/recentrequeststablemodel.h \
qt/rpcconsole.h \
qt/scicon.h \
qt/sendcoinsdialog.h \
qt/sendcoinsentry.h \
qt/signverifymessagedialog.h \
qt/splashscreen.h \
qt/trafficgraphwidget.h \
qt/transactiondesc.h \
qt/transactiondescdialog.h \
qt/transactionfilterproxy.h \
qt/transactionrecord.h \
qt/transactiontablemodel.h \
qt/transactionview.h \
qt/utilitydialog.h \
qt/walletframe.h \
qt/walletmodel.h \
qt/walletmodeltransaction.h \
qt/walletview.h \
qt/winshutdownmonitor.h
RES_ICONS = \
qt/res/icons/add.png \
qt/res/icons/address-book.png \
qt/res/icons/about.png \
qt/res/icons/about_qt.png \
qt/res/icons/bitcoin.ico \
qt/res/icons/bitcoin.png \
qt/res/icons/clock1.png \
qt/res/icons/clock2.png \
qt/res/icons/clock3.png \
qt/res/icons/clock4.png \
qt/res/icons/clock5.png \
qt/res/icons/configure.png \
qt/res/icons/connect0.png \
qt/res/icons/connect1.png \
qt/res/icons/connect2.png \
qt/res/icons/connect3.png \
qt/res/icons/connect4.png \
qt/res/icons/debugwindow.png \
qt/res/icons/edit.png \
qt/res/icons/editcopy.png \
qt/res/icons/editpaste.png \
qt/res/icons/export.png \
qt/res/icons/eye.png \
qt/res/icons/eye_minus.png \
qt/res/icons/eye_plus.png \
qt/res/icons/filesave.png \
qt/res/icons/history.png \
qt/res/icons/info.png \
qt/res/icons/key.png \
qt/res/icons/lock_closed.png \
qt/res/icons/lock_open.png \
qt/res/icons/open.png \
qt/res/icons/overview.png \
qt/res/icons/quit.png \
qt/res/icons/receive.png \
qt/res/icons/remove.png \
qt/res/icons/send.png \
qt/res/icons/synced.png \
qt/res/icons/transaction0.png \
qt/res/icons/transaction2.png \
qt/res/icons/transaction_conflicted.png \
qt/res/icons/tx_inout.png \
qt/res/icons/tx_input.png \
qt/res/icons/tx_output.png \
qt/res/icons/tx_mined.png \
qt/res/icons/warning.png \
qt/res/icons/verify.png
BITCOIN_QT_CPP = \
qt/bitcoinaddressvalidator.cpp \
qt/bitcoinamountfield.cpp \
qt/bitcoingui.cpp \
qt/bitcoinunits.cpp \
qt/clientmodel.cpp \
qt/csvmodelwriter.cpp \
qt/guiutil.cpp \
qt/intro.cpp \
qt/networkstyle.cpp \
qt/notificator.cpp \
qt/optionsdialog.cpp \
qt/optionsmodel.cpp \
qt/peertablemodel.cpp \
qt/qvalidatedlineedit.cpp \
qt/qvaluecombobox.cpp \
qt/rpcconsole.cpp \
qt/scicon.cpp \
qt/splashscreen.cpp \
qt/trafficgraphwidget.cpp \
qt/utilitydialog.cpp
if TARGET_WINDOWS
BITCOIN_QT_CPP += qt/winshutdownmonitor.cpp
endif
if ENABLE_WALLET
BITCOIN_QT_CPP += \
qt/addressbookpage.cpp \
qt/addresstablemodel.cpp \
qt/askpassphrasedialog.cpp \
qt/coincontroldialog.cpp \
qt/coincontroltreewidget.cpp \
qt/editaddressdialog.cpp \
qt/openuridialog.cpp \
qt/overviewpage.cpp \
qt/paymentrequestplus.cpp \
qt/paymentserver.cpp \
qt/receivecoinsdialog.cpp \
qt/receiverequestdialog.cpp \
qt/recentrequeststablemodel.cpp \
qt/sendcoinsdialog.cpp \
qt/sendcoinsentry.cpp \
qt/signverifymessagedialog.cpp \
qt/transactiondesc.cpp \
qt/transactiondescdialog.cpp \
qt/transactionfilterproxy.cpp \
qt/transactionrecord.cpp \
qt/transactiontablemodel.cpp \
qt/transactionview.cpp \
qt/walletframe.cpp \
qt/walletmodel.cpp \
qt/walletmodeltransaction.cpp \
qt/walletview.cpp
endif
RES_IMAGES =
RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png)
BITCOIN_RC = qt/res/komodo-qt-res.rc
BITCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \
-I$(builddir)/qt/forms -DQT_NO_KEYWORDS
qt_libbitcoinqt_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
qt_libbitcoinqt_a_SOURCES = $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(QT_FORMS_UI) \
$(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES)
nodist_qt_libbitcoinqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(PROTOBUF_CC) \
$(PROTOBUF_H) $(QT_QRC_CPP) $(QT_QRC_LOCALE_CPP)
# forms/foo.h -> forms/ui_foo.h
QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h))))
# Most files will depend on the forms and moc files as includes. Generate them
# before anything else.
$(QT_MOC): $(QT_FORMS_H)
$(qt_libbitcoinqt_a_OBJECTS) $(qt_komodo_qt_OBJECTS) : | $(QT_MOC)
#Generating these with a half-written protobuf header leads to wacky results.
#This makes sure it's done.
$(QT_MOC): $(PROTOBUF_H)
$(QT_MOC_CPP): $(PROTOBUF_H)
# bitcoin-qt binary #
qt_komodo_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
qt_komodo_qt_SOURCES = qt/bitcoin.cpp
if TARGET_DARWIN
qt_komodo_qt_SOURCES += $(BITCOIN_MM)
endif
if TARGET_WINDOWS
qt_komodo_qt_SOURCES += $(BITCOIN_RC)
endif
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) \
$(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
#locale/foo.ts -> locale/foo.qm
QT_QM=$(QT_TS:.ts=.qm)
SECONDARY: $(QT_QM)
qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES)
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
$(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) ../share/qt/extract_strings_qt.py $^
translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM)
@test -n $(LUPDATE) || echo "lupdate is required for updating translations"
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts qt/locale/bitcoin_en.ts
$(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM)
@test -f $(RCC)
@test -f $(@D)/$(<F) || cp -f $< $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin_locale $(@D)/$(<F) | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
$(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(PROTOBUF_H)
@test -f $(RCC)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin $< | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno
CLEANFILES += $(CLEAN_QT)
komodo_qt_clean: FORCE
rm -f $(CLEAN_QT) $(qt_libbitcoinqt_a_OBJECTS) $(qt_komodo_qt_OBJECTS) qt/bitcoin-qt$(EXEEXT) $(LIBBITCOINQT)
komodo_qt : qt/bitcoin-qt$(EXEEXT)
ui_%.h: %.ui
@test -f $(UIC)
@$(MKDIR_P) $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(UIC) -o $@ $< || (echo "Error creating $@"; false)
%.moc: %.cpp
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
moc_%.cpp: %.h
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
%.qm: %.ts
@test -f $(LRELEASE)
@$(MKDIR_P) $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LRELEASE) -silent $< -qm $@

View File

@@ -1,48 +0,0 @@
bin_PROGRAMS += qt/test/test_bitcoin-qt
TESTS += qt/test/test_bitcoin-qt
TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp
if ENABLE_WALLET
TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
endif
TEST_QT_H = \
qt/test/uritests.h \
qt/test/paymentrequestdata.h \
qt/test/paymentservertests.h
qt_test_test_komodo_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS)
qt_test_test_komodo_qt_SOURCES = \
qt/test/test_main.cpp \
qt/test/uritests.cpp \
$(TEST_QT_H)
if ENABLE_WALLET
qt_test_test_komodo_qt_SOURCES += \
qt/test/paymentservertests.cpp
endif
nodist_qt_test_test_komodo_qt_SOURCES = $(TEST_QT_MOC_CPP)
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) \
$(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)
CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno
CLEANFILES += $(CLEAN_BITCOIN_QT_TEST)
test_komodo_qt : qt/test/test_bitcoin-qt$(EXEEXT)
test_komodo_qt_check : qt/test/test_bitcoin-qt$(EXEEXT) FORCE
$(MAKE) check-TESTS TESTS=$^
test_komodo_qt_clean: FORCE
rm -f $(CLEAN_BITCOIN_QT_TEST) $(qt_test_test_komodo_qt_OBJECTS)

View File

@@ -1,323 +0,0 @@
# RG1QE6hTqu4dadL2XSNWS9VCHjd8xNVo58 KMD 16462.32091533, REVS 289.86606506
fiat/revs sendtoaddress RG1QE6hTqu4dadL2XSNWS9VCHjd8xNVo58 289.86606506
sleep 1
# RFVvyUAnQe5yon6wq7B73Z1BzfFeZKyAZA KMD 74417.52897713, REVS 500.77700000
fiat/revs sendtoaddress RFVvyUAnQe5yon6wq7B73Z1BzfFeZKyAZA 500.77700000
sleep 1
# RWfaj9ZNmHq5A4jV411xpt1FJoyvKfVJ6c KMD 616895.10028203, REVS 3685.61452692
fiat/revs sendtoaddress RWfaj9ZNmHq5A4jV411xpt1FJoyvKfVJ6c 3685.61452692
sleep 1
# R9dTcQWVDuaRdFqDzq4xPaFDjGbaLK6t8n KMD 1053.37494565, REVS 4.29070721
fiat/revs sendtoaddress R9dTcQWVDuaRdFqDzq4xPaFDjGbaLK6t8n 4.29070721
sleep 1
# REvJWEuwqmwTnanZ8bWt85wnjfrsAjnvgE KMD 3945.67461320, REVS 30.24757576
fiat/revs sendtoaddress REvJWEuwqmwTnanZ8bWt85wnjfrsAjnvgE 30.24757576
sleep 1
# RBpEnyzuQNj1hNdAG1pKLALpAWEUS67PBj KMD 2729058.03025689, REVS 54178.00103054
fiat/revs sendtoaddress RBpEnyzuQNj1hNdAG1pKLALpAWEUS67PBj 54178.00103054
sleep 1
# RHSZ1CWDNhkNbbQRDrqLHRAdCshueMrt2r KMD 8661.80183095, REVS 171.90929822
fiat/revs sendtoaddress RHSZ1CWDNhkNbbQRDrqLHRAdCshueMrt2r 171.90929822
sleep 1
# RTqh7gEJMJDpnBp62FZZAfXctj8X7sRRia KMD 18367.01200788, REVS 350.00000000
fiat/revs sendtoaddress RTqh7gEJMJDpnBp62FZZAfXctj8X7sRRia 350.00000000
sleep 1
# RNhyF9U3o4hTgWqnwQjHwrD1o4GqWiP1T6 KMD 7816.63087181, REVS 78.63808960
fiat/revs sendtoaddress RNhyF9U3o4hTgWqnwQjHwrD1o4GqWiP1T6 78.63808960
sleep 1
# RE3yR2mCeG15ARgvENMbb573VqoQJcM3po KMD 17738.87416605, REVS 18.61556549
fiat/revs sendtoaddress RE3yR2mCeG15ARgvENMbb573VqoQJcM3po 18.61556549
sleep 1
# RT7ENMvL46nwrFfNj1TLa5FEqJzTztHefH KMD 26696.69308472, REVS 529.99000000
fiat/revs sendtoaddress RT7ENMvL46nwrFfNj1TLa5FEqJzTztHefH 529.99000000
sleep 1
# RDTcqgh4MMHLtu9FBCcULqZmP761DFmk9b KMD 82906.87674571, REVS 1438.93600000
fiat/revs sendtoaddress RDTcqgh4MMHLtu9FBCcULqZmP761DFmk9b 1438.93600000
sleep 1
# RHSUmLRyJwpbdsRtytkGs9GmpZghQWHje3 KMD 2197.34858012, REVS 43.61040113
fiat/revs sendtoaddress RHSUmLRyJwpbdsRtytkGs9GmpZghQWHje3 43.61040113
sleep 1
# RJEQbNrMQUHELrYPVLPepR2Y3ruAag3hEP KMD 64966.39751162, REVS 1035.00000000
fiat/revs sendtoaddress RJEQbNrMQUHELrYPVLPepR2Y3ruAag3hEP 1035.00000000
sleep 1
# RJ1DUUySYib5LcwJKFJ78PD3so2GQ89jKJ KMD 377892.70160675, REVS 7501.00000000
fiat/revs sendtoaddress RJ1DUUySYib5LcwJKFJ78PD3so2GQ89jKJ 7501.00000000
sleep 1
# RC2nLGhFUc5Q9QFG1b38gAi9WgSgzQ9hJR KMD 41.38832712, REVS 0.82090537
fiat/revs sendtoaddress RC2nLGhFUc5Q9QFG1b38gAi9WgSgzQ9hJR 0.82090537
sleep 1
# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 1350076.86672091, REVS 100.00000000
fiat/revs sendtoaddress RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 100.00000000
sleep 1
# RJbudEMb7wEEN8QZ18fEkptxjE4QnMECUu KMD 50567.04202258, REVS 1003.32000000
fiat/revs sendtoaddress RJbudEMb7wEEN8QZ18fEkptxjE4QnMECUu 1003.32000000
sleep 1
# RSdVypRznJsboL6MaP1shkaLhrVFcNx2KL KMD 589187.66272894, REVS 11685.49743445
fiat/revs sendtoaddress RSdVypRznJsboL6MaP1shkaLhrVFcNx2KL 11685.49743445
sleep 1
# RWXwZyGf4q7cBakkY4tgupptBbCSvcBsBH KMD 1012.75625347, REVS 20.10000000
fiat/revs sendtoaddress RWXwZyGf4q7cBakkY4tgupptBbCSvcBsBH 20.10000000
sleep 1
# RA7UJPwPxqgPHn4YscYWRH5EPQVaFaaaPa KMD 45132.81116316, REVS 342.26137428
fiat/revs sendtoaddress RA7UJPwPxqgPHn4YscYWRH5EPQVaFaaaPa 342.26137428
sleep 1
# RRFFxsc6kkfahR7v4paTaUZrPFisuz9Nkq KMD 155.36852443, REVS 3.08314987
fiat/revs sendtoaddress RRFFxsc6kkfahR7v4paTaUZrPFisuz9Nkq 3.08314987
sleep 1
# RWFSbi9ECuZWVE37jpkbiKGw7DaFYdNtts KMD 23963.90703474, REVS 475.60756080
fiat/revs sendtoaddress RWFSbi9ECuZWVE37jpkbiKGw7DaFYdNtts 475.60756080
sleep 1
# RUVkn1F9g7TxoPbYtegiQoFnPTusP2gzDr KMD 43088.75849296, REVS 470.88002226
fiat/revs sendtoaddress RUVkn1F9g7TxoPbYtegiQoFnPTusP2gzDr 470.88002226
sleep 1
# R9vBYQw9tSBhu2c1g4SQhZdhuZeeQrEBoN KMD 111664.10821907, REVS 2023.42268720
fiat/revs sendtoaddress R9vBYQw9tSBhu2c1g4SQhZdhuZeeQrEBoN 2023.42268720
sleep 1
# RG8g7LjK7hdyKp3aoKBRdwzpLy31XMXMLk KMD 972.80557592, REVS 19.29916914
fiat/revs sendtoaddress RG8g7LjK7hdyKp3aoKBRdwzpLy31XMXMLk 19.29916914
sleep 1
# RJ7RfZfip4qL9uEJs7Wr9FYtGusQiryMqE KMD 43251.49599262, REVS 857.93461385
fiat/revs sendtoaddress RJ7RfZfip4qL9uEJs7Wr9FYtGusQiryMqE 857.93461385
sleep 1
# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 53585.08128315, REVS 731.01000000
fiat/revs sendtoaddress RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY 731.01000000
sleep 1
# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 57862.44847739, REVS 464.78017965
fiat/revs sendtoaddress RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 464.78017965
sleep 1
# RTkvmxME9rVZBY6ABNqkkbqKvn8WUqgQqr KMD 215743.93040290, REVS 4280.65926868
fiat/revs sendtoaddress RTkvmxME9rVZBY6ABNqkkbqKvn8WUqgQqr 4280.65926868
sleep 1
# RS9erX84xJG17efdZ66qHxhsUMG15fnCsH KMD 977546.42205511, REVS 19403.85638743
fiat/revs sendtoaddress RS9erX84xJG17efdZ66qHxhsUMG15fnCsH 19403.85638743
sleep 1
# RE1wsrDNwW2NnNWM5eE162yp6haLtm5uh7 KMD 14588.33036215, REVS 289.61149547
fiat/revs sendtoaddress RE1wsrDNwW2NnNWM5eE162yp6haLtm5uh7 289.61149547
sleep 1
# RK5BnRzCP52qsTE4xR3Qysn6m6KeTgpZA6 KMD 3170.70655908, REVS 37.96790925
fiat/revs sendtoaddress RK5BnRzCP52qsTE4xR3Qysn6m6KeTgpZA6 37.96790925
sleep 1
# RN6TfTEYHdvFAeosYrvDaMBb2yBco47Q5a KMD 7073.16782615, REVS 44.30216197
fiat/revs sendtoaddress RN6TfTEYHdvFAeosYrvDaMBb2yBco47Q5a 44.30216197
sleep 1
# RV4Hf22arBv4P4s5eFsUAnXC6N11T8x9tv KMD 117108.97863641, REVS 1631.49836519
fiat/revs sendtoaddress RV4Hf22arBv4P4s5eFsUAnXC6N11T8x9tv 1631.49836519
sleep 1
# RYBH6Ha8RJa3CcE91yxJP6z2E6mDFm3bBt KMD 163386.58575808, REVS 50.00000000
fiat/revs sendtoaddress RYBH6Ha8RJa3CcE91yxJP6z2E6mDFm3bBt 50.00000000
sleep 1
# RUY7YW1WmTD3hCvkXmUKLeRnNg5UsJoLbU KMD 6742.29255596, REVS 105.00000000
fiat/revs sendtoaddress RUY7YW1WmTD3hCvkXmUKLeRnNg5UsJoLbU 105.00000000
sleep 1
# RNVwzuZynZ7d4DE5CfT8CWkxsp9TtCY3BF KMD 1598.36899361, REVS 11.75449303
fiat/revs sendtoaddress RNVwzuZynZ7d4DE5CfT8CWkxsp9TtCY3BF 11.75449303
sleep 1
# RPriQZfzzgin7y2Ns6vxdrMAa4XgZqdY6y KMD 21671.70738465, REVS 170.69524117
fiat/revs sendtoaddress RPriQZfzzgin7y2Ns6vxdrMAa4XgZqdY6y 170.69524117
sleep 1
# RSCdeeWvzpBhg2tKnCWZWKw9iAMyYWiREG KMD 12075.12037906, REVS 239.62000000
fiat/revs sendtoaddress RSCdeeWvzpBhg2tKnCWZWKw9iAMyYWiREG 239.62000000
sleep 1
# RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj KMD 25710.06172178, REVS 510.00000000
fiat/revs sendtoaddress RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj 510.00000000
sleep 1
# RQuMEMn1TG7CCpbmYCVcDfPqesEvEkisjC KMD 34758.47429765, REVS 689.94006658
fiat/revs sendtoaddress RQuMEMn1TG7CCpbmYCVcDfPqesEvEkisjC 689.94006658
sleep 1
# RBNB5mKstG86jYRjrKFgJuFoUFvZKJb9Wq KMD 816561.67159376, REVS 16199.49755302
fiat/revs sendtoaddress RBNB5mKstG86jYRjrKFgJuFoUFvZKJb9Wq 16199.49755302
sleep 1
# RHoouCBBapEHE6uyX7CxHGFcRwUQFGMot5 KMD 88331.27512150, REVS 1398.88449696
fiat/revs sendtoaddress RHoouCBBapEHE6uyX7CxHGFcRwUQFGMot5 1398.88449696
sleep 1
# RLHEGDwXuXQwhYkrhwSRGSJMFuvv7EAT7i KMD 22366.16022678, REVS 443.95821128
fiat/revs sendtoaddress RLHEGDwXuXQwhYkrhwSRGSJMFuvv7EAT7i 443.95821128
sleep 1
# RAEtFUqe3jwVxLywCga2eKQxT2DiewsUuN KMD 25.54297774, REVS 0.50680815
fiat/revs sendtoaddress RAEtFUqe3jwVxLywCga2eKQxT2DiewsUuN 0.50680815
sleep 1
# RUcDMtu7fA3ATbHHsDTsZ8KThgd1ivawym KMD 21446.21749875, REVS 241.00000000
fiat/revs sendtoaddress RUcDMtu7fA3ATbHHsDTsZ8KThgd1ivawym 241.00000000
sleep 1
# RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 KMD 102137.83664315, REVS 2027.11216000
fiat/revs sendtoaddress RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 2027.11216000
sleep 1
# REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf KMD 130928.69826981, REVS 2597.54928401
fiat/revs sendtoaddress REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf 2597.54928401
sleep 1
# RXKZmFmmpfAV2DAdUUXhA88RqCoyPRXcnA KMD 28641.72782430, REVS 337.66808110
fiat/revs sendtoaddress RXKZmFmmpfAV2DAdUUXhA88RqCoyPRXcnA 337.66808110
sleep 1
# RCxnQhmYdpK9vTS7PLRtXBtDk2HaRNo1qk KMD 2171.04073365, REVS 43.05910000
fiat/revs sendtoaddress RCxnQhmYdpK9vTS7PLRtXBtDk2HaRNo1qk 43.05910000
sleep 1
# RPtwW4UejbAxs5PU6a1zMPcPqW7SVghMDS KMD 31741.86724191, REVS 514.45537037
fiat/revs sendtoaddress RPtwW4UejbAxs5PU6a1zMPcPqW7SVghMDS 514.45537037
sleep 1
# RYMzZx5nxKrMtTm3TNeheVn4RooTGvhsNd KMD 12756.16332851, REVS 253.10000000
fiat/revs sendtoaddress RYMzZx5nxKrMtTm3TNeheVn4RooTGvhsNd 253.10000000
sleep 1
# RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz KMD 3422.63549310, REVS 51.90683618
fiat/revs sendtoaddress RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz 51.90683618
sleep 1
# RVcGdBT2N6Fbqbptj3R4zhZYNB4WJQWEns KMD 77986.19708921, REVS 1548.20316000
fiat/revs sendtoaddress RVcGdBT2N6Fbqbptj3R4zhZYNB4WJQWEns 1548.20316000
sleep 1
# RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf KMD 11621.99031627, REVS 192.14192021
fiat/revs sendtoaddress RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf 192.14192021
sleep 1
# REtq1LtbLVo6bz68f9TGFduNmUTKqG7vnH KMD 25088.84725730, REVS 305.62849999
fiat/revs sendtoaddress REtq1LtbLVo6bz68f9TGFduNmUTKqG7vnH 305.62849999
sleep 1
# RS3rMPEGouBWbHKStyQg8TxVmtwFQ6ebh3 KMD 3546.25060143, REVS 39.99000000
fiat/revs sendtoaddress RS3rMPEGouBWbHKStyQg8TxVmtwFQ6ebh3 39.99000000
sleep 1
# RGzvr4JSHDLDQAGBwdyoUiUuaYn5sUwKNd KMD 69108.92543895, REVS 314.51750000
fiat/revs sendtoaddress RGzvr4JSHDLDQAGBwdyoUiUuaYn5sUwKNd 314.51750000
sleep 1
# RMD1wVnzMmKn8uMTHaP9pYfCWkxf3QVWWE KMD 2931.50081538, REVS 40.37145505
fiat/revs sendtoaddress RMD1wVnzMmKn8uMTHaP9pYfCWkxf3QVWWE 40.37145505
sleep 1
# RQCEEEprmqghZHN73iG1C2XvYTTQ6FB2wE KMD 5506.18026103, REVS 90.00054364
fiat/revs sendtoaddress RQCEEEprmqghZHN73iG1C2XvYTTQ6FB2wE 90.00054364
sleep 1
# RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx KMD 529.41438680, REVS 10.50000000
fiat/revs sendtoaddress RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx 10.50000000
sleep 1
# R9ULUWEvzmHPZ4rYL5FtwkMyTWvGDZX43J KMD 15051.18125683, REVS 298.60000000
fiat/revs sendtoaddress R9ULUWEvzmHPZ4rYL5FtwkMyTWvGDZX43J 298.60000000
sleep 1
# RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb KMD 166779.58408020, REVS 3310.49966000
fiat/revs sendtoaddress RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb 3310.49966000
sleep 1
# RALRwXaEN3yS5damdDwAkmEMKvdAkVs361 KMD 25746.96382302, REVS 510.64558668
fiat/revs sendtoaddress RALRwXaEN3yS5damdDwAkmEMKvdAkVs361 510.64558668
sleep 1
# RPVNUvVq4BgKrrB3E1uULja2hjPW6Hv6r9 KMD 16872.68860925, REVS 334.64000000
fiat/revs sendtoaddress RPVNUvVq4BgKrrB3E1uULja2hjPW6Hv6r9 334.64000000
sleep 1
# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 19616.45270312, REVS 389.05771834
fiat/revs sendtoaddress RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A 389.05771834
sleep 1
# RXFr5VB9gQYC5QYv7yVvkxtjDY3zwYuvDx KMD 327.74801651, REVS 6.50475878
fiat/revs sendtoaddress RXFr5VB9gQYC5QYv7yVvkxtjDY3zwYuvDx 6.50475878
sleep 1
# RHUpvFhHv1umX1JsV5S8smAKAsN5CxA4HD KMD 2183.96436714, REVS 2.36599993
fiat/revs sendtoaddress RHUpvFhHv1umX1JsV5S8smAKAsN5CxA4HD 2.36599993
sleep 1
# RAhvJHePdAb1PF9jjZhP2F7r72ebL9pA1f KMD 3457.02047726, REVS 68.56389987
fiat/revs sendtoaddress RAhvJHePdAb1PF9jjZhP2F7r72ebL9pA1f 68.56389987
sleep 1
# RDCjGgoZ1tvCWop6m5wPYkr83wdFrofF6M KMD 76598.36955552, REVS 1519.19347187
fiat/revs sendtoaddress RDCjGgoZ1tvCWop6m5wPYkr83wdFrofF6M 1519.19347187
sleep 1
# RLAEm3H2LMSNzJmveLkcf2nS18AnqWR7pJ KMD 82831.36892196, REVS 1643.94000000
fiat/revs sendtoaddress RLAEm3H2LMSNzJmveLkcf2nS18AnqWR7pJ 1643.94000000
sleep 1
# RSUfnwTLE36E3Nx8PptxVoAfSRtMeGQsFL KMD 67327.03192299, REVS 1282.48928243
fiat/revs sendtoaddress RSUfnwTLE36E3Nx8PptxVoAfSRtMeGQsFL 1282.48928243
sleep 1
# RPkkQmMmyLQe8Th7ZP5GoF6kSUs1DTNfAf KMD 1538.42929417, REVS 30.51202988
fiat/revs sendtoaddress RPkkQmMmyLQe8Th7ZP5GoF6kSUs1DTNfAf 30.51202988
sleep 1
# RSkhXmiPCxqdp4bM4ux7VxAwMoCv2Uar6d KMD 73542.70261753, REVS 1459.56877203
fiat/revs sendtoaddress RSkhXmiPCxqdp4bM4ux7VxAwMoCv2Uar6d 1459.56877203
sleep 1
# RUJvR3TXCAcizk7dXdFc6GKRFS6jZfjtyY KMD 10419.10088055, REVS 206.75776925
fiat/revs sendtoaddress RUJvR3TXCAcizk7dXdFc6GKRFS6jZfjtyY 206.75776925
sleep 1
# RLZmhbeB2tXTas9grzAeqaL2RFAXVmDVpU KMD 43480.56469698, REVS 50.30001915
fiat/revs sendtoaddress RLZmhbeB2tXTas9grzAeqaL2RFAXVmDVpU 50.30001915
sleep 1
# RLCDEXwfJ75P1iKgWGfR9geJmjZ84A4XXJ KMD 105141.23597043, REVS 1006.07261743
fiat/revs sendtoaddress RLCDEXwfJ75P1iKgWGfR9geJmjZ84A4XXJ 1006.07261743
sleep 1
# RW1FmQGcpPv87WZVSCaMgjj74shMb3Y6Zi KMD 33700.59190315, REVS 380.47576230
fiat/revs sendtoaddress RW1FmQGcpPv87WZVSCaMgjj74shMb3Y6Zi 380.47576230
sleep 1
# RQUMrGYr4SsHgbN56WP7tuEpWUcd62KidP KMD 61230.10078656, REVS 600.00100000
fiat/revs sendtoaddress RQUMrGYr4SsHgbN56WP7tuEpWUcd62KidP 600.00100000
sleep 1
# RP8CkGhyfhdoVpGqGbVmEmRL7gGdqKBdkt KMD 153725.02014837, REVS 3049.70000000
fiat/revs sendtoaddress RP8CkGhyfhdoVpGqGbVmEmRL7gGdqKBdkt 3049.70000000
sleep 1
# RRupn47XfLSMhXEuShtCCPBCv8P6LYXrLN KMD 790607.74140148, REVS 15691.16324116
fiat/revs sendtoaddress RRupn47XfLSMhXEuShtCCPBCv8P6LYXrLN 15691.16324116
sleep 1
# RRX73tynW4sxCmqyYBQrS9nMcDUcXuX1yG KMD 26022.54788263, REVS 5.39446042
fiat/revs sendtoaddress RRX73tynW4sxCmqyYBQrS9nMcDUcXuX1yG 5.39446042
sleep 1
# R9u7V63TLwJPH1shvAGHRG61aci61yy7RN KMD 20764.40163902, REVS 291.83028199
fiat/revs sendtoaddress R9u7V63TLwJPH1shvAGHRG61aci61yy7RN 291.83028199
sleep 1
# RKAxvqvC3apzrb8udG9trBxiNhhNXaLkz4 KMD 6483.53169406, REVS 5.41696484
fiat/revs sendtoaddress RKAxvqvC3apzrb8udG9trBxiNhhNXaLkz4 5.41696484
sleep 1
# RV5cgPjqt37QBHr94VL5HnXWqcwdqoqoC3 KMD 81008.20903630, REVS 1607.10337790
fiat/revs sendtoaddress RV5cgPjqt37QBHr94VL5HnXWqcwdqoqoC3 1607.10337790
sleep 1
# RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v KMD 14010.00244099, REVS 277.86367220
fiat/revs sendtoaddress RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v 277.86367220
sleep 1
# RF4iG6huXb9u6Pt8281WvnBjhdEtiVUnp4 KMD 674.21697725, REVS 13.37190382
fiat/revs sendtoaddress RF4iG6huXb9u6Pt8281WvnBjhdEtiVUnp4 13.37190382
sleep 1
# RW3gz9fEadohRLZerK9r8zXkugk5swWHrf KMD 21219.62483892, REVS 421.20000000
fiat/revs sendtoaddress RW3gz9fEadohRLZerK9r8zXkugk5swWHrf 421.20000000
sleep 1
# RJ89radoRzRr5oDsf71QZ7BXUTiHcyVSUu KMD 52588.80320859, REVS 1043.00609779
fiat/revs sendtoaddress RJ89radoRzRr5oDsf71QZ7BXUTiHcyVSUu 1043.00609779
sleep 1
# RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 KMD 668547.16129881, REVS 13259.45302721
fiat/revs sendtoaddress RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 13259.45302721
sleep 1
# R9ibGGfsFHD8MxLRL4q2a6ezxAaHHPJvLc KMD 241619.45649268, REVS 4792.09548598
fiat/revs sendtoaddress R9ibGGfsFHD8MxLRL4q2a6ezxAaHHPJvLc 4792.09548598
sleep 1
# RGwuMmW1ZBMrHJwJucEy5JEV3BZWv7eQnm KMD 9071868.91817425, REVS 180010.00000000
fiat/revs sendtoaddress RGwuMmW1ZBMrHJwJucEy5JEV3BZWv7eQnm 180010.00000000
sleep 1
# RT6Ckpw8yM2Q7yaCxejiVTrxELGQPtnGPm KMD 25778.27244764, REVS 225.87592741
fiat/revs sendtoaddress RT6Ckpw8yM2Q7yaCxejiVTrxELGQPtnGPm 225.87592741
sleep 1
# RGf4wwbHVYYZrVPVZg6XdS3mWvbzHSebzu KMD 6387.59296405, REVS 126.73871740
fiat/revs sendtoaddress RGf4wwbHVYYZrVPVZg6XdS3mWvbzHSebzu 126.73871740
sleep 1
# RJAbNiCSRaMxUky9h8as6orZY3cu2rSW8z KMD 492782.94486222, REVS 9773.48000000
fiat/revs sendtoaddress RJAbNiCSRaMxUky9h8as6orZY3cu2rSW8z 9773.48000000
sleep 1
# RSW5SvtjWiGYN3iwb2mteYP7Hn223Zk1tP KMD 343847.33707184, REVS 6001.47957339
fiat/revs sendtoaddress RSW5SvtjWiGYN3iwb2mteYP7Hn223Zk1tP 6001.47957339
sleep 1
# RFPKxBL8iLQGmkoUukXdFU7VkXyGJLSsGw KMD 36335.50253541, REVS 413.60001059
fiat/revs sendtoaddress RFPKxBL8iLQGmkoUukXdFU7VkXyGJLSsGw 413.60001059
sleep 1
# RVFspAKoUpDMAiiEUiQQEpqdqXDMB48Jqp KMD 47464.51702590, REVS 634.55156126
fiat/revs sendtoaddress RVFspAKoUpDMAiiEUiQQEpqdqXDMB48Jqp 634.55156126
sleep 1
# RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 KMD 36359.70475507, REVS 100.00000000
fiat/revs sendtoaddress RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 100.00000000
sleep 1
# R9ce1xHEaWnRRP5jrWozEfPf9ZJgX7jnxd KMD 915808.36366861, REVS 18163.44258555
fiat/revs sendtoaddress R9ce1xHEaWnRRP5jrWozEfPf9ZJgX7jnxd 18163.44258555
sleep 1
# RS1rdGqAhXvwFFTVyUCx695y84E3N3emcU KMD 18822.21903353, REVS 360.77089072
fiat/revs sendtoaddress RS1rdGqAhXvwFFTVyUCx695y84E3N3emcU 360.77089072
sleep 1
# RLgKsmgdzwNCt8CgqZ5J6cZhTat9HeZgxG KMD 62376.97840244, REVS 1045.22605497
fiat/revs sendtoaddress RLgKsmgdzwNCt8CgqZ5J6cZhTat9HeZgxG 1045.22605497
sleep 1
# RUBESyzjgZUts3fD6W7abpgMj4qRFSSszC KMD 541390.42407502, REVS 10592.65522652
fiat/revs sendtoaddress RUBESyzjgZUts3fD6W7abpgMj4qRFSSszC 10592.65522652
sleep 1
# RSNu7Kd9p33aDrgT2AM8buy7fUSQZ2N3Gs KMD 130769.80646849, REVS 2593.58831601
fiat/revs sendtoaddress RSNu7Kd9p33aDrgT2AM8buy7fUSQZ2N3Gs 2593.58831601
sleep 1
# RCrCe4dsMzXzzp7GLahubjg73VGK2rnczC KMD 6843.04832293, REVS 25.10000000
fiat/revs sendtoaddress RCrCe4dsMzXzzp7GLahubjg73VGK2rnczC 25.10000000
sleep 1
# RVTCRzofA2cV6FwGcvn1uGjZJmP5s9G1o9 KMD 95283.12042643, REVS 497.50723875
fiat/revs sendtoaddress RVTCRzofA2cV6FwGcvn1uGjZJmP5s9G1o9 497.50723875
sleep 1
# total KMD 45769105.32172734 REVS 426291.27268935

View File

@@ -1,78 +0,0 @@
sleep 9999999
# RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4 KMD 205767.24475092, REVS 4084.38717211
sleep 1
fiat/revs sendtoaddress RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4 4084.38717211
# RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx KMD 138163.01002402, REVS 2740.59474723
sleep 1
fiat/revs sendtoaddress RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx 2740.59474723
# RHfHV1LTG5rz3T2HApavCto9973puD93qt KMD 243998.92767004, REVS 4839.53600000
sleep 1
fiat/revs sendtoaddress RHfHV1LTG5rz3T2HApavCto9973puD93qt 4839.53600000
# RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy KMD 36785.74330117, REVS 730.28056435
sleep 1
fiat/revs sendtoaddress RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy 730.28056435
# RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB KMD 567760.05597770, REVS 11191.99000000
sleep 1
fiat/revs sendtoaddress RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB 11191.99000000
# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 7771.42052436, REVS 0.62700000
sleep 1
fiat/revs sendtoaddress RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u 0.62700000
# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 18186.86986853, REVS 143.39272495
sleep 1
fiat/revs sendtoaddress RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK 143.39272495
# RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu KMD 2375.16051963, REVS 47.12337252
sleep 1
fiat/revs sendtoaddress RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu 47.12337252
# RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta KMD 70173.29001640, REVS 1392.33555151
sleep 1
fiat/revs sendtoaddress RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta 1392.33555151
# REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 KMD 220390.81840860, REVS 1384.18511377
sleep 1
fiat/revs sendtoaddress REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 1384.18511377
# RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ KMD 479029.87110523, REVS 9502.00000000
sleep 1
fiat/revs sendtoaddress RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ 9502.00000000
# RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz KMD 230594.13977661, REVS 8.48502608
sleep 1
fiat/revs sendtoaddress RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz 8.48502608
# RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv KMD 25505.74161232, REVS 506.00000000
sleep 1
fiat/revs sendtoaddress RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv 506.00000000
# RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5 KMD 4516.65527532, REVS 31.96541397
sleep 1
fiat/revs sendtoaddress RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5 31.96541397
# RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH KMD 35011.78668474, REVS 310.59835083
sleep 1
fiat/revs sendtoaddress RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH 310.59835083
# R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks KMD 201.26853079, REVS 3.99180609
sleep 1
fiat/revs sendtoaddress R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks 3.99180609
# RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig KMD 663.13491046, REVS 13.16292943
sleep 1
fiat/revs sendtoaddress RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig 13.16292943
# RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK KMD 29548.60287586, REVS 586.04438779
sleep 1
fiat/revs sendtoaddress RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK 586.04438779
# RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK KMD 100186.19238242, REVS 1944.84440292
sleep 1
fiat/revs sendtoaddress RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK 1944.84440292
# RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq KMD 1853646.03638691, REVS 415.68775429
sleep 1
fiat/revs sendtoaddress RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq 415.68775429
# RFREgr9p32GanT4YcM25hMcPYkvRLDNkja KMD 151544.96672946, REVS 3005.62695376
sleep 1
fiat/revs sendtoaddress RFREgr9p32GanT4YcM25hMcPYkvRLDNkja 3005.62695376
# RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4 KMD 295382.69930466, REVS 5860.00000000
sleep 1
fiat/revs sendtoaddress RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4 5860.00000000
# RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT KMD 59621.32507756, REVS 606.36817953
sleep 1
fiat/revs sendtoaddress RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT 606.36817953
# RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p KMD 23159.75532541, REVS 459.58469952
sleep 1
fiat/revs sendtoaddress RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p 459.58469952
# RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ KMD 77304.58455563, REVS 1533.20000000
sleep 1
fiat/revs sendtoaddress RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ 1533.20000000
# total KMD 0.00000000 REVS 51342.01215065

View File

@@ -1,25 +0,0 @@
b35af354357e56e2cb628d6b871b29ccecc9451d81428920e99e096be6769f7a
826e2d89119eb6bef82515cbe13c155cdbda7fe6f69f7710e9cc5ce8e9e32c0d
9f9e1bc5277765087b5a1102599745eccd88ba7e5480bcd67a326e9450c8c3ce
74c469d3659d3a21354fe29abd611ad536bb1525bd05e3ddd208860c1d195b60
4863817beae6277158d4993a3919b5285706743d24865cd3d8cdd02f595abc13
727210250e6144f72ed11bbcc14a6c4f49293fcd6e3140e431268e9645a2c000
221fa9b9d8904c669bf5404d4c2bd23f3de85cfb1638550d94b8eaa3880c7442
5d8e3dcc179dfe9610bb7f55fe14674924abb8049e44e797beb1117651a679f4
3fa7ecd3ced13aebdbba27d1f276f19ba6787a118c1db9a5d70b60b49ce8b4c7
a48c18753fa85a9b8a4d8dd33ae984828277d1f0b3105479f838bdb9339efc1a
fdffe296333e9101e6c86b0d4d6562c6e53e303ea26d0741caa94d681d1764aa
6d4a5569b3f02148e579a09829d732ce6a4adada2eaacf5be2656619599818ea
8628904bff0ee39c4f70275e9011a6606bacad8a5ffa3d81a82b0ca659e04f0f
62ee7a9f2aecbb287a6f589a803fc9164ab3132f3c48b19be8de29ee6f07ac3b
d7093749b27f66af626c716aec55abb35c19f7d06b0006d0340b8f5f902b74e3
4e6893dc5cc35cae915f5fb29cc8780bff9c1c92975a83ca779f74a5efcba3fd
0f089e6e19c490ff25f8df648a3c692a4ebbc439c6e21962d8fc4c19749b5df3
d790f0c31ef22d61cab33fd067b004093b5b39dccda0015df5cf096d666f81b5
0193eb50a1c1f255f391e03a83a11ea3f59dff8aa66fad44eeb20bc10b3eff66
07157664c81db45d96a3e92f2719cffa058e4b1e61fbf83873470a1ceb195a70
f311706621dc0e5abb2af3e75fbabeb42fc08fe6a2ef73689089374f724a024f
800c9a65a0a1e7ad1381dc1770aed25fc0c7869d84f24de55861accb679f228b
40cd628126f1b9791e67c2fc2ef091c1a1fdf9a59739cb048084d76054235f23
9786cfe6f46932d70282ff9252bcc088bce2a4aab2f03a369a2596c9964eea51
bed3728d27935b12889559b05133418becd7daac6b12155e4bfc60c32bc6720f

View File

@@ -1,48 +0,0 @@
sleep 999999
# RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU KMD 501.64865701, REVS 9.95750000
sleep 1
fiat/revs sendtoaddress RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU 9.95750000
# RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf KMD 62103.45021354, REVS 50.00000000
sleep 1
fiat/revs sendtoaddress RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf 50.00000000
# RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71 KMD 12520.16564088, REVS 138.94305839
sleep 1
fiat/revs sendtoaddress RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71 138.94305839
# RKb5ay26iSzmBoqm51vPveyErH9BYG3dry KMD 3674.15911735, REVS 72.89043156
sleep 1
fiat/revs sendtoaddress RKb5ay26iSzmBoqm51vPveyErH9BYG3dry 72.89043156
# RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx KMD 612851.03780014, REVS 5433.13031755
sleep 1
fiat/revs sendtoaddress RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx 5433.13031755
# RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp KMD 519232.27493854, REVS 10298.05578171
sleep 1
fiat/revs sendtoaddress RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp 10298.05578171
# RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i KMD 19106.59220646, REVS 374.39305755
sleep 1
fiat/revs sendtoaddress RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i 374.39305755
# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 1212.14061568, REVS 24.05385000
sleep 1
fiat/revs sendtoaddress RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf 24.05385000
# RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza KMD 10347.76210933, REVS 205.22959870
sleep 1
fiat/revs sendtoaddress RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza 205.22959870
# RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr KMD 71712.83911390, REVS 500.67180183
sleep 1
fiat/revs sendtoaddress RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr 500.67180183
# RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr KMD 16435.34703311, REVS 114.80740001
sleep 1
fiat/revs sendtoaddress RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr 114.80740001
# RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr KMD 17137.93285029, REVS 340.00462653
sleep 1
fiat/revs sendtoaddress RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr 340.00462653
# RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF KMD 409543.68954327, REVS 8123.68911362
sleep 1
fiat/revs sendtoaddress RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF 8123.68911362
# RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d KMD 302.06577591, REVS 5.99094155
sleep 1
fiat/revs sendtoaddress RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d 5.99094155
# RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL KMD 30407.13753317, REVS 411.30538288
sleep 1
fiat/revs sendtoaddress RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL 411.30538288
# total KMD 0.00000000 REVS 26103.12286188

View File

@@ -1,15 +0,0 @@
bc4eca8000603d16ae491bf1bf4f5fda622f54d3b0ffdaefe12337461bb88d5f
cda5da13119d348565085119b37951f0ee2f6866d677bbca2295d5d44e365b4a
ce9516059a943070ec233716c878e90bfcf6456c9a35c587fc9f6c74008d2d72
c1f32cbd341d9e7e51046378ad072b0aaa55d1fc3b970b606ed708d3bb02d7d6
f2a2f2a2b4cc99b5cc89fefe8340252b0bbb7ecd83df809f2bf782a06d9bcdd0
5e44a6d50cd1cb64fa6349b49d5793d12988c4c3d517bb271f396a9fd66d3cae
6f6771ef52833bf504397c80f06e58a77e58387d809b42c8ae3bb6301796dcf0
96d12c7828f3f3fa7983aac02b724f5a53897856b7419e0728d78ae7e3756765
84fde41cd955564a18f6141349dffb26dc8ad498fcb3494052a8aeb0157ffb3c
93d6d89195f5332f7bae6e9ffc65d5892fa169446d90ed3d7d5017389a2a3ff6
2dc7e37ff11703c01e1a6301746d2586549fe091bbf6cf7bf80c6b49c1f38d1c
1732b6942035ba7482f9a6c77a47f90b529c51d8b22c4d14a7a430d7b8cf3303
733a0ef1b7ef603664271f7a3667e39809f9a4f7b618a4a9c00c3e8a6876d57c
cf2ed6deeaf6600b2fff0b5db13c5f950dc655b06420eee816edbfad7c07c991
16ae9bf3ed2d47c8b8fc088a6773c3316642c97ff573d5f2e185f89dadf39b14

View File

@@ -1,44 +0,0 @@
sleep 9999999
# RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg KMD 5669.98491054, REVS 112.56208000
sleep 1
fiat/revs sendtoaddress RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg 112.56208000
# RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W KMD 43088.74729573, REVS 470.87980000
sleep 1
fiat/revs sendtoaddress RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W 470.87980000
# RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW KMD 55892.82951156, REVS 1070.41924580
sleep 1
fiat/revs sendtoaddress RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW 1070.41924580
# RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK KMD 335.54240549, REVS 6.65853993
sleep 1
fiat/revs sendtoaddress RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK 6.65853993
# RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh KMD 163589.49612623, REVS 3245.93000000
sleep 1
fiat/revs sendtoaddress RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh 3245.93000000
# RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc KMD 98858.55994787, REVS 1384.95819177
sleep 1
fiat/revs sendtoaddress RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc 1384.95819177
# RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9 KMD 5226.14889591, REVS 103.72248253
sleep 1
fiat/revs sendtoaddress RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9 103.72248253
# RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK KMD 159251.95713851, REVS 3160.13095281
sleep 1
fiat/revs sendtoaddress RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK 3160.13095281
# RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq KMD 28529.48507541, REVS 566.06461415
sleep 1
fiat/revs sendtoaddress RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq 566.06461415
# RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72 KMD 8637.01756743, REVS 171.30000000
sleep 1
fiat/revs sendtoaddress RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72 171.30000000
# total KMD 0.00000000 REVS 10292.62590699
17f76404644686bdc3f58c562fb86036d9d13e540486a13f9c89daa26449ca45
df9e8d5430fd80035a4397a464a5a1b75a168e94c660a7f5eb9ac30f992ba3df
0a6c099f5dd33803223e743f099530df86d7a0bd3c2ab29d1de99ccf8d854b46
4ed406ac9e171d930460659d9a5f3c806d51313516b4fbf3812c1bc3f27e1106
83d733a0004ab00dc2106368405ec00f2a641721c9bdbdf24d7e88ce5f99df5c
76eb52c04c27566aa6181d1523e2cb6db413419b3a1ffe1b18ade8669de9f20b
be8fbc1408d013e586add3ca8c3677c17079d52f9d10a6e3fc08ed51dabc2598
cec00429c9802cea98789c73426294ba065d99dc29400a329c2a510a50160651
30500a29f6e9da29c67ea51a2718421e0ca945018f8a6eee1622c7462b9fed4a
ebc16e614204d51e09c23df54d0888741d3a40bea3c05bf3898a64fbf9826444

View File

@@ -1,94 +0,0 @@
8f7d4648657dd7f8aa70d8e83539ae0592cbfafc6a961fe75d7f7f613b4d5737
5669.98491054 <- expected amount RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg
0f5681bbc1441e39cd3226847e3863489bc3ffe6b00c161e453a897b6a4e1268
8353.36815152 <- expected amount RXbWQbnpsQ3iSBBj5bn2HDq3WvqRPJg5Ek
34cfb92756c33c9fc2b0f1126884044711a83a6deb05c8b38cc744b7a87f34f5
9683.15249375 <- expected amount RKCDBxUx7mbCnViLt423jdLt6oNpW7SH7z
cad96a82897ec8d240bb410a1c1b54922444d7bc6383ef31ae153646d4cb0837
43088.74729573 <- expected amount RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W
ccef457f43908a2f18c86c3c1431a9b3857263413a756ca46117655fae2acec3
50806.03038250 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct
216f60dff778c0701def1ea8eb582959591369c7a67864bf2ef20ca99178138b
2015.79933830 <- expected amount RDqaDbfFHrnPAnyLY6b9A3CFZZjivhdYSJ
96e0916f1598824cfa1e2a590a0dc683be93c6fa8dbffb6153b341906de84398
48415.76246875 <- expected amount RBGX2Z43Fiey6tkgRCL9rzc3gNhdcvQyzf
e0b44fb9e74984823a307c82b70ddb7a173976fa43aec61440d9cd53654a8e93
7885.04483652 <- expected amount RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ
6bff9d66cafe0f249de24a6be6312f75ea97cce10c40bd2ffd4a785758787782
2076.57141858 <- expected amount RVUby7nAZAEKQc1mNu89KGchwgVN6H74Pb
d4c509d86d3ddeb3be1ea733e2c79c816c0639f3ba1738d1f50140915292949e
55892.82951156 <- expected amount RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW
615c5efe7cbddd2e07d2282d215f307cbdc7e102ce4e3c1e134b96086736e459
110983.78643539 <- expected amount RPAueErz2MDLv1T4VNVRkkWRPmUKDXxNyW
1baad4f5d826832d13b0ddc7379b7235a38caa42b5098f273811109b974a6dbf
135104.07865436 <- expected amount RQ2pMNHbPGagXKQoVzrgF2o718GmP7A74Z
c70b43c915aac7f917026d6229f5a7ce15184de37ed5f8aa4756d8416a3cde70
8376.94442691 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3
8ceab84b76f983a4bc0ba4743027666fae243fa463f3b51bfd4cb26c39bc7731
47849.00411034 <- expected amount RHSA9ocZc77tHiFvVQ2h26AJQFsionWAXK
4b08e4b3ea8608e97d8ccdd30c4785f03c443002127269c1936134c9f2cc717d
15163.82967582 <- expected amount RS8F3LcQ8DUSoBacUKBKzMR2Wxe3hCSToY
d2c320a2fafa054cd166b331937fd5fe005f07ec02f9fd5977ca466ed663d0eb
3002.22564175 <- expected amount RLijku3v2wyCcGykdbsUViqDCNaVkVkQpc
cf93b70a0ff58ec115c03e0a395a5b413610437f40bd496707ae426df1a46aa8
14101.70011189 <- expected amount RMeaeKG7vrTpryBGVEWQ8twjQDnRVAhpqH
6be9eb9a87781ebcbd633946c891b98499001d38c934e827371a7b79d57b0de0
5832.55634776 <- expected amount RUDEQESpyWvpwdfrieiBoNo93WHaKhGxGf
e63deddaf983e5cf537f34b9777a65f001f4dda5bb86dc8b1c8f5d0ead105435
890.85002942 <- expected amount RMat1mSDDigFHhVL74mjBia9uHo5w24MLQ
f382d7ec4a9f9cf4283776449521e6c2c73a44863f119a6fa3ddd319c042f08c
335.54240549 <- expected amount RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK
f04aaada09059b8df995cf29c7f6d0c7ca20ed7e70d698bd21df1e61c70d2cca
19366.30498750 <- expected amount RVcMp4KgwCg6GnUJAAU2dmCvPjAa9JrEds
8496fcbe66360a2753f1795dc4b0bb1a93fa121de4b521410e046611bc04f2e5
163589.49612623 <- expected amount RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh
9b3e499b36112979a084534143826776699b2a5def69e656d7aa7dc98a381501
3873.26099750 <- expected amount RB1j3QidCF9PTKQaZMGKe6Hzm5jdY8Mzus
17e55956fe10117b7e65a272fed473efa2dd387ab794932eebb9924e434719f0
7746.52199500 <- expected amount RFcH8p3Ke5y4UL3pdL9KCkJWp3aRdBwWpg
4499caf8325016189dc4cbaf102d3c5a358105c135defd90afbc000fbed92795
16670.51967129 <- expected amount RJDkJJd66n4Q4jVWbZJQKyXTf29ZqzeXac
41d0583c6f0720b27976f717d729c7445e10264b0663af6baa43e2ad0fe5fff0
7746.52199500 <- expected amount RKzELkcNJu4g9DWQsFFeQtFZQE5u9vevuK
eb979d5a6d79b6e0466fc3dbdd2a2f73812fb5788bfcad2b160da1e1b96828c5
74455.81274009 <- expected amount RKpUFnxUn9mJCZmNECEQT7xEubHECUPCem
2ec16b1596c2daa8d14642478d0ad6e6fa5d143980794f1c717c4e7ba2765749
98858.55994787 <- expected amount RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc
4d59bf3a6dcd11242c3a7c20402c38e41fb8f936d63e0c5b3f6490248fd989ed
5226.14889591 <- expected amount RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9
505e5b9d3e9ac0ee9a435e7fdb9819b53fd1169fceb9c6e4b3b2173031beac16
753.34926401 <- expected amount RBtfFBdYiryB6fyWoubm4XNqZwXqzAbJEK
b2243873085e98d346e3f2341a203c3644f1fb78fe60294f5838eff96f2121dd
159251.95713851 <- expected amount RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK
75740f609901350eebc9493aff3dcfb070e107b493a2b51aa1acccfb9dedd88c
693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS
9beeaaa5dd83e3967f35d60073f88a320276e7a3aa61a4a06b7f8b46079fa4b4
2304.59029350 <- expected amount RT1xC82iwXtZeDLLYz3tgQRCHKsRD62Jt5
b7508390ec18fc559112de1f5ddcd6f27c74f9a41415ae97c89b01c6718afc64
6506.14889316 <- expected amount RGPEHHmPFaMPSLMQxEao2uVPTfN8vBCmym
c6eb29abc0c447043f94cac4df49b3ce640d27be2730d18c7ba3f0fe7d21861b
38732.60997500 <- expected amount RBUEoAzoydjckYewPsW2kfTr8TGFgnR2Ec
bf0e8dff8de3ce4c07b7cc09703978d7db0dc7660f312186b4c3eff2a97fd638
916.79536397 <- expected amount RVQS9NGKsbBJuKDhJnPssTRevrE428dxDK
186e0d779d5a6a644e7d972aecafe4fb1739059933a0e50ad9a82ced1c8974e4
48415.76246875 <- expected amount RHiUqYUohv49bvB2wbDe1mAkwyEFwUEnrb
37ed3649d5e2f83a0c4ee11748b076fffe8a2fb16650cad7fa39cbbe3ddc9246
16542.25810519 <- expected amount RSWPtfGaHPL1g7SMqbLm1YZ8o3QM6krzo1
2dc98a59906d57f9e57b3231d19749eb9979533d3a2c35ec5adb3cb91bfd7c7b
2322923.09575692 <- expected amount RFMcTK36Wzjo5QEk1wAH2CbATqsYvzgwXH
35a28b0551bbe3d3e5cfa989b5a073bea55784a9df162ebcafc61bffb8ff5834
28529.48507541 <- expected amount RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq
3b3aabeb6483d8c37265d24ef76389f96158970485866de1005ba28d8069877b
8637.01756743 <- expected amount RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72
684728bb5ff281762990da11e7463c6e992b5e98cb0cc7965a3470b8a664484a
1212.26932063 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf
a021d23ab591ed687f7ba0bccbd98ecbb7d8d1f967176bb2f2e1e6fe1d83af34
32148.06627925 <- expected amount RBD72Bh4wxGi8q8xQbLfwMF2RAkTZ7sVZT
b9ab02076864711a964c149346141f01f686b50fd345e6eb5bc3f218b40c4c50
1924.55258644 <- expected amount RVih8N9Qh1jf4CCF5ySsAY8DR42eTxYqpB
d5760b4049c8818f6486d1b81b0715f6971f88b0f49e8daab4382fe6980ddd85
44542.50147125 <- expected amount RWez2L8rPoTmqj8kYKqxLdeD9BFuDibMyJ
c9bb31764aab4cd631fa733940c0b35470cad48d247ef227372cc84375cd8d8b
49199.88128813 <- expected amount RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN
08075d8b984266c27ed5f029b88b682596ace07cc43b2db50d4491dc810ced04
30170.24616125 <- expected amount RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es

View File

@@ -1,27 +0,0 @@
sleep 999999
# RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB KMD 843.49707566, REVS 16.72927581
sleep 1
fiat/revs sendtoaddress RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB 16.72927581
# RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n KMD 3090.02793673, REVS 3.67077856
sleep 1
fiat/revs sendtoaddress RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n 3.67077856
# RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk KMD 79613.96546024, REVS 1579.43521640
sleep 1
fiat/revs sendtoaddress RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk 1579.43521640
# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 20106.39865075, REVS 0.09000000
sleep 1
fiat/revs sendtoaddress RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut 0.09000000
# RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw KMD 867960.91662544, REVS 11685.48356181
sleep 1
fiat/revs sendtoaddress RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw 11685.48356181
# RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj KMD 19695.58704144, REVS 390.89494454
sleep 1
fiat/revs sendtoaddress RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj 390.89494454
# RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo KMD 2981.62619009, REVS 30.35300490
sleep 1
fiat/revs sendtoaddress RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo 30.35300490
# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 40914.30625015, REVS 476.17156540
sleep 1
fiat/revs sendtoaddress RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX 476.17156540
# total KMD 0.00000000 REVS 14182.82834742

View File

@@ -1,107 +0,0 @@
f8b8a27ca722196f5f745f7778fc8aed873c3b040a1a964e704e63ebf5185edd
b7e28fadcedd54f973a9e91df42c3d02bd1436f2377f28e6c866cafadf2c947b
dc3adb9035b939ce50e4144920acb9fc4ff1fc36b226bf6cca13e1d2a7ab36c8
8c64142d44edd729b9972361b8dbd14e5f3f022daee1b2ec1ff3b3f69a755884
d15d1de5f494c22bcd4b9717ba416efbecb78d9d143209b31fd9362be13b9dea
4b99586c873574fd4e6f2055130a85e194ea7da61303ccd2b6839f7d6754ad92
0645a7c8a584e9fe3f5dce8cb5972b9ab15f580abcd4fd12bdd19bd2bbca5d4b
a8ca857443e07b225d8a6271ab761e7636c568159582e7d8540998fe47b37b86
20b13d8b02b1f728c2b19a09876e2eeab68aa3a51cd1c0b539c18f980e244106
84491a5ed8421013e546f32e6407d4d916297176944fbc1daa99b4b7d30673db
0ff635aadfdbdb4d6887d04a1ecaed449bf708c36da782781dec0601057c6ede
4034cf5a74b9a0c5ea725ff6d227b738b1015dafb88e610d2c42bc2e56f4cd9a
7644c293c0b80e186ac8f73eeef1390458b1a2febbffe6e03442809c7a1b52ca
f6f2ceee809d3a02d32c08839965f90cc9783c7c0c979df48f17f63702bc26e2
8be21cf583d6fff597bba5fb537ae2c29b9f797f31c5d33641e377332a14396e
32652dd110bc58128354a8f1b55d027c21cf805f34183c746494d763dc5f944a
26a8db0f5dfa4f8dc0ac40f409070e7ba0bb507bb99138639382f503dbbaa11b
5f8ca3d9d4360990b7f164b0c8a6f8541e449395a17c0024b593346454cee653
6ef36fb6b117c326819d644ad59eaa17834b1bd4d2565906f39d0c239b3ee5fa
6a9664882c7fa2c033db4fba4d25d10db381e0005e10d08034d569c97849046e
0ef90e1eb2c1d73dca4270e16511bca3458f040ad066965859aec3c660609aaf
c6ece66a5a6254774b799ca3a167d3d28567e0239ff2738d90497a271b5e1113
feaaa2e13f87b1116969f1eba327d9a1ce9f3bdf900c5413a12172b4b425421d
411823d20770f587c4b77140680516964f178e143249da0fd643141b422bb4e5
15c646b807f0bfde249e7db39cf2734712ab35487bd69797473973c87ea96945
7a8a83984b699741d2ecad3c8cba537762106648bae8a590bb8468e84d1749a5
4bcd8c28879d255d53c56475a0d8aa2be0bf831db6f7e15ad1f77a0841e950a6
d472c0868258d14810ceeaaac010bb1f927ece44b55d7e2cda42214baddb0ea0
69acf622b21eb4eba6af5d506d4d11831ee4533814ba6a0300072354de25a625
20bcdf8d19f96fea65b7130193e0d5ab54b5e4a2150b8a6ade3bf4e98bf98d0c
0c5bad3e366c301e730fbf58a83b219f5265f0a596feb89bbe0306bd87a4b72b
33744e5ee5df4dd46a7e133825a5af4734baafbe3f1d3c849e5d36e8c038b282
d4cce84308b475327d6fec1505cb12f30a1cd266b34c9dc810a14df5eac5f825
eafe1f16f6bf6ef1fe987039e2daf80723fc78752d2896ff6d99ae9cd0143a26
a7033c2b1772e461a897012c9ecca796a9f3f9f0622beb006f3dbabdcbeaa5f1
bb35fa7bed699d2c1188a0df41371e4fac1ca34eefdcfb4cd7cba398300493c3
3de0201d7b0e0d531116c457dd857e1b92ad4ba99b1283f4e6ea346641ba270b
fa1641370e84b65f43086c90f37a0c79d918cb7330f95977849560f5db90ec7a
0dcbe1b19e716b2ae5ebe7ecce917e26fb09a8890480f2b7e8315f7b6fdf9de8
35a134a0ca04f3cf402827df17616f64e0b488ddfa277f9d287a3aa524258a0b
08e7c05da62f384287ed42ac138d1d5da6968d3320fb855cf66a3a72685f6ec7
fa0b0b65fb2f66f26379c6eb7f0b299d916ed0dbf7a569d7bae4fc455cb6cfc2
88794bbb699f130951c40dc99a27d2c7c7016e12824fd1040cbedf86980de04d
3d2b8a2bd53af7f871d9c5c3ada5a8742b9ca14918efbdc0b50655fbd6a9c43c
91928c3a9e0ab6710cf6b517234420ba8455592af3c9da7662f8a3ce2fa1e823
1e311229a68642300d6e4cae166334df4a3e87c0e52e86760ccc0234d2ebecd1
9a82ddea65986359f0e69bd9d06db7f0f3ab99bf6be2ae2cfaa24e3de74ec170
c0a151d520e4c11eb23f75a0b3b3a09c5dcdb4283edc5f7aaa5082336337e3c4
ca850ff82776e1e72d82a2d0c4c35235e4841cec6f2b36d8d4e37aa46d06a5e4
5b4060b77f23488e5f2ad57c775dfb62e235140f42d57720cb985ee218d97d64
403183a0ab2a672c6968e9c88190910d8949bd03808b353291e150ac6e5e49a4
5a86136b1ecf2d9a43dd42d3d902653ca24c8ecc71001097ca035e3750ba8998
780ea40a7fea9bab8547c2917c60c90a7a88ce38bb1f3af06197dd3341504987
4e1b419e3d67c35351fe18e2f001a404c08c04f8b6148412c7a5d7ee01f91a73
4231eb801746ac3bd08e57533498a74400570c28f4bc4c2f8a1424be3d4b1bb1
e1bc9dcf2dd758717480f29e62a24a9e250b356d5ef275de46bc580002ed85d0
25e0a1f1c0d8db40acedfd491ae445e2242d6fa0ca39b18ccb4e9d6eff86dbb0
053839195f085b1586d46ab54dd05b17e91e4f0876d0a53832543774a8fb0b1d
9deeabbcaca2e613254eca4b15dea6e86d6fa7ec8893baffe713b8ed796fc3cb
c6e0f0089b9741e4c75d3080a1549cd5ea87e7605501e2419ee9186817c60a8a
a1bca1dd1011c23bde3babeff2120ebd48282b3a9b41c10a0b80dc38e3efdef9
563f1812684dc33528418877fa5bbcb15b83c4d3496b076f4f3bdad38f0fdb6a
06a3ca90a32455b03b5f6008737d25fab7fc02f0126b40e25f440d4ad8c98caf
36b8f751739ec405427830b06b8020f9975bc29ea93faf72e1e99c22231bed88
ef9247fd847739e2ec786a23663da32efff73c6e4b9b02f43411332ad1eac945
1d3fe9e86a4692029ea13b153f423fc9be211dd3d7207f374e5360a8a1812f0a
afe379fcb8d097448decdcaebc8669c2b6f05c9a593f89265b44280231d900f2
07873c642e76432ae77193bdee90fb21c3fe1d2d47cb87689d20feb47ecf6884
904c0e81c754b190b459be69c5ac925d274aa91e8d69639375adfc7bc3659c23
34cbc40d34fcc916845b7a991f3d430831a919c782556a0dab5b4083cf0b277d
38c0d0d6055d6e37513af175c5232a97a04e16a6c64d2e5711e0ed0e01868264
e1988acd516c445a36a425d4e881b6ba620ec31be7fc2e86ff40113030611a41
0472010fbe40e01a55bdca2bfe06b9383c41ec8a4d70c54ecb32b7f1765a85f4
4058e9174d9fbdf611c481552a0c9038b4905341ad31156fadb62e924156b971
c0b23f4f41480765fda1efb44af0eb118685e70392e004e5b5a68ae4cb741452
dde373fff9ce038d5b2524506038f0986b459fca9550452e3248c34b40041ece
98e70c5491278d48f0ee5fbaf63a1ffac7ab7975ec8def8e711f8821df214c32
45e995c9a816a7ccfd34823ae88375f7e7b2d52a9fe5f1953748d06c8c9f920b
d3196f666e093f6295ff5d9bbb5fad3d735c79efc3a0ef2682a5d10abbc047d9
47819cadf315ee1931a475219d61fa2367a73310749f23cfa994ef9e0324fff3
aa4719fd7745191531c68c140ec52728cb9d3ffaea5875967f75dbb7ab7a2b57
83dfacc40a05c80e1a8e4cae7a0cbb98a30f76ad010efb63b9a515b490f7676e
4c118313fff51fc72ec2c49045679e6bb9a9aeb7143b576b1f3eb07429a0b806
f208fd7abeb82b6aa0218db68421045078cde1521129029dd2ffafa759208cbc
cf58359f2b61ab6fd73f176bd094154d04f83752a86bd91a2b7879123a51cbf0
3e10f831b75abd7bb89fa74dd6b74d5f07a2d818c44eccec496896dfadac9534
250204ddd107ece1d5092a4cd1163115ede9e754ef136d80d912ccfc132e0ac5
676d1ea16b0fd80025953ecc999213d4e0b1b002f2b4193d7616ec97a269a49f
4ca289d052c847b502ce756ed65f035e38e78575ee9fa0e68df89595151967fb
ccdec5f135b9dee61540fb3f0cca5a372189d69c1461242eaa11c788557740d8
f3ebba346b9ad00771ce1ee67dafab3f875c307ba39ab8439f63822d4c78c656
4496f369401f0e7778fbaa9199505f8ab093c0cc22fdefe3a6d0a465b3c0d078
b0eb34108101f19e10248066d9a339596bded6dd7a84d0be64c701e837b5f596
796577570b9a7dce40bcc476c95c72d903531367db6ebc9d5d457d77634d0123
26ee642aaa9f2fbeb1603ac695ce13dcfa8709af07e0cd71bce85c2ccb3ac4cf
ada15a386b1ded5afb41bd30946b9bac14a5bf8912ffcd12f086f29dfe31b3b2
073202790ae224da09b17aed4c18d8395433d5e6ea910bd04c1b952444b8a239
cb38a03e8afa8b0dfcdbe13070ea6d048ea1cc9a1054ba86c6ab88511e2661d4
e8dba03f46da7dfa258be5376fc1dec714c0104423191b3ad14a476bbcbce929
6c9dd8171202deab1d5d8af6aa1b7c1ea6f4cb8654cb3241040659674b700308
49f2add7db2978cacc1798cd08b67f33d435606d2b3dc877a673dfdeaa7617b3
84ae90011844413779316580fc2731e391829237e7b356354ae1266e5712ac3d
efffc292acaa38e458ef396c818dda28c9e2971065f65abeaa0a4d951b141dfe
f03e0af2f1fd32263d5a4149fedd9128c3bc7616088c208abbd5c1f065cb5249
1814b8d5550ceb07acecc3c4995dd2d582af9bf6f6e6b5a40319f824570f18c9
73e622d891f13d8c136214eaeeddc2c9e7d721844abf797916fb0c4b2a9e9e49
6cee8ae520488bbe9cb516490e94876e0828c27bffdb72f7e9695d5ec9ee3b2c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -307,5 +307,31 @@
"157.230.45.184",
"165.22.52.123"
]
}
},
{
"ac_name": "COMMOD",
"ac_supply": "0",
"ac_reward": "204800000000,100000000",
"ac_end": "482130,0",
"ac_halving": "43830,525960",
"ac_decay": "50000000,10000000",
"ac_eras": "2",
"ac_cc": "777",
"ac_public": "1",
"addnode": [
"34.246.186.176",
"34.251.151.148"
]
},
{
"ac_name": "WLC21",
"ac_supply": "21000000",
"ac_reward": "190258751",
"ac_staked": "90",
"ac_public": "1",
"addnode": [
"37.187.225.231",
"51.38.38.134"
]
}
]

View File

@@ -20,16 +20,16 @@
#include "CCinclude.h"
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,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4);
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 GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin);
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin);
UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin);
UniValue GatewaysBind(const CPubKey& pk, uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector<CPubKey> pubkeys,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4);
UniValue GatewaysDeposit(const CPubKey& pk, 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);
UniValue GatewaysClaim(const CPubKey& pk, uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount);
UniValue GatewaysWithdraw(const CPubKey& pk, uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount);
UniValue GatewaysPartialSign(const CPubKey& pk, uint64_t txfee,uint256 txidaddr,std::string refcoin,std::string hex);
UniValue GatewaysCompleteSigning(const CPubKey& pk, uint64_t txfee,uint256 txidaddr,std::string refcoin,std::string hex);
UniValue GatewaysMarkDone(const CPubKey& pk, uint64_t txfee,uint256 withdrawtxid,std::string refcoin);
UniValue GatewaysPendingDeposits(const CPubKey& pk, uint256 bindtxid,std::string refcoin);
UniValue GatewaysPendingWithdraws(const CPubKey& pk, uint256 bindtxid,std::string refcoin);
UniValue GatewaysProcessedWithdraws(const CPubKey& pk, uint256 bindtxid,std::string refcoin);
// CCcustom
UniValue GatewaysInfo(uint256 bindtxid);

View File

@@ -20,11 +20,11 @@
#include "CCinclude.h"
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 OracleFund(int64_t txfee,uint256 oracletxid);
std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee);
std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount);
std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> data);
UniValue OracleCreate(const CPubKey& pk, int64_t txfee,std::string name,std::string description,std::string format);
UniValue OracleFund(const CPubKey& pk, int64_t txfee,uint256 oracletxid);
UniValue OracleRegister(const CPubKey& pk, int64_t txfee,uint256 oracletxid,int64_t datafee);
UniValue OracleSubscribe(const CPubKey& pk, int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount);
UniValue OracleData(const CPubKey& pk, int64_t txfee,uint256 oracletxid,std::vector <uint8_t> data);
// CCcustom
UniValue OracleDataSample(uint256 reforacletxid,uint256 txid);
UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num);

View File

@@ -22,14 +22,14 @@
bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
// CCcustom
std::string PegsCreate(uint64_t txfee,int64_t amount,std::vector<uint256> bindtxids);
std::string PegsFund(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
std::string PegsGet(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
std::string PegsRedeem(uint64_t txfee,uint256 pegstxid, uint256 tokenid);
std::string PegsLiquidate(uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint256 liquidatetxid);
std::string PegsExchange(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
UniValue PegsAccountHistory(uint256 pegstxid);
UniValue PegsAccountInfo(uint256 pegstxid);
UniValue PegsCreate(const CPubKey& pk,uint64_t txfee,int64_t amount,std::vector<uint256> bindtxids);
UniValue PegsFund(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
UniValue PegsGet(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
UniValue PegsRedeem(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid);
UniValue PegsLiquidate(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint256 liquidatetxid);
UniValue PegsExchange(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
UniValue PegsAccountHistory(const CPubKey& pk,uint256 pegstxid);
UniValue PegsAccountInfo(const CPubKey& pk,uint256 pegstxid);
UniValue PegsWorstAccounts(uint256 pegstxid);
UniValue PegsInfo(uint256 pegstxid);

View File

@@ -19,6 +19,7 @@
#include "komodo_defs.h"
#include "CCinclude.h"
int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks);
extern void GetKomodoEarlytxidScriptPub();
extern CScript KOMODO_EARLYTXID_SCRIPTPUB;

View File

@@ -19,7 +19,6 @@
UniValue AssetOrders(uint256 refassetid, CPubKey pk, uint8_t additionalEvalCode)
{
static uint256 zero;
UniValue result(UniValue::VARR);
struct CCcontract_info *cpAssets, assetsC;
@@ -35,7 +34,7 @@ UniValue AssetOrders(uint256 refassetid, CPubKey pk, uint8_t additionalEvalCode)
std::vector<uint8_t> origpubkey;
CTransaction ordertx;
uint8_t funcid, evalCode;
char numstr[32], funcidstr[16], origaddr[64], origtokenaddr[64], assetidstr[65];
char numstr[32], funcidstr[16], origaddr[64], origtokenaddr[64];
txid = it->first.txhash;
LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() checking txid=" << txid.GetHex() << std::endl);
@@ -46,8 +45,8 @@ UniValue AssetOrders(uint256 refassetid, CPubKey pk, uint8_t additionalEvalCode)
{
LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() checking ordertx.vout.size()=" << ordertx.vout.size() << " funcid=" << (char)(funcid ? funcid : ' ') << " assetid=" << assetid.GetHex() << std::endl);
if (refassetid != zero && assetid == refassetid ||
pk != CPubKey() && pk == pubkey2pk(origpubkey) && (funcid == 'S' || funcid == 's'))
if (pk == CPubKey() && (refassetid == zeroid || assetid == refassetid) // tokenorders
|| pk != CPubKey() && pk == pubkey2pk(origpubkey) && (funcid == 'S' || funcid == 's')) // mytokenorders, returns only asks (is this correct?)
{
LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() it->first.index=" << it->first.index << " ordertx.vout[it->first.index].nValue=" << ordertx.vout[it->first.index].nValue << std::endl);
@@ -61,7 +60,7 @@ UniValue AssetOrders(uint256 refassetid, CPubKey pk, uint8_t additionalEvalCode)
funcidstr[0] = funcid;
funcidstr[1] = 0;
item.push_back(Pair("funcid", funcidstr));
item.push_back(Pair("txid", uint256_str(assetidstr, txid)));
item.push_back(Pair("txid", txid.GetHex()));
item.push_back(Pair("vout", (int64_t)it->first.index));
if (funcid == 'b' || funcid == 'B')
{
@@ -77,18 +76,17 @@ UniValue AssetOrders(uint256 refassetid, CPubKey pk, uint8_t additionalEvalCode)
sprintf(numstr, "%llu", (long long)ordertx.vout[0].nValue);
item.push_back(Pair("askamount", numstr));
}
if (origpubkey.size() == 33)
if (origpubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE)
{
GetCCaddress(cp, origaddr, pubkey2pk(origpubkey));
item.push_back(Pair("origaddress", origaddr));
GetTokensCCaddress(cpTokens, origtokenaddr, pubkey2pk(origpubkey));
item.push_back(Pair("origtokenaddress", origtokenaddr));
}
if (assetid != zeroid)
item.push_back(Pair("tokenid", uint256_str(assetidstr, assetid)));
item.push_back(Pair("tokenid", assetid.GetHex()));
if (assetid2 != zeroid)
item.push_back(Pair("otherid", uint256_str(assetidstr, assetid2)));
item.push_back(Pair("otherid", assetid2.GetHex()));
if (price > 0)
{
if (funcid == 's' || funcid == 'S' || funcid == 'e' || funcid == 'e')

View File

@@ -21,12 +21,12 @@
#define CHANNELS_MAXPAYMENTS 1000
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,uint256 tokenid);
std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret);
std::string ChannelClose(uint64_t txfee,uint256 opentxid);
std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid);
UniValue ChannelsList();
UniValue ChannelOpen(const CPubKey& pk,uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment,uint256 tokenid);
UniValue ChannelPayment(const CPubKey& pk,uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret);
UniValue ChannelClose(const CPubKey& pk,uint64_t txfee,uint256 opentxid);
UniValue ChannelRefund(const CPubKey& pk,uint64_t txfee,uint256 opentxid,uint256 closetxid);
UniValue ChannelsList(const CPubKey& pk);
// CCcustom
UniValue ChannelsInfo(uint256 opentxid);
UniValue ChannelsInfo(const CPubKey& pk,uint256 opentxid);
#endif

View File

@@ -402,14 +402,6 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
cp->validate = PegsValidate;
cp->ismyvin = IsPegsInput;
break;
case EVAL_MARMARA:
strcpy(cp->unspendableCCaddr,MarmaraCCaddr);
strcpy(cp->normaladdr,MarmaraNormaladdr);
strcpy(cp->CChexstr,MarmaraCChexstr);
memcpy(cp->CCpriv,MarmaraCCpriv,32);
cp->validate = MarmaraValidate;
cp->ismyvin = IsMarmaraInput;
break;
case EVAL_PAYMENTS:
strcpy(cp->unspendableCCaddr,PaymentsCCaddr);
strcpy(cp->normaladdr,PaymentsNormaladdr);

View File

@@ -25,8 +25,8 @@
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
// CCcustom
std::string FaucetFund(uint64_t txfee,int64_t funds);
std::string FaucetGet(uint64_t txfee);
UniValue FaucetFund(const CPubKey& mypk,uint64_t txfee,int64_t funds);
UniValue FaucetGet(const CPubKey& mypk,uint64_t txfee);
UniValue FaucetInfo();
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,7 @@
#define CC_REWARDS_H
#include "CCinclude.h"
#include <gmp.h>
#define EVAL_REWARDS 0xe5
#define REWARDSCC_MAXAPR (COIN * 25)

View File

@@ -824,9 +824,8 @@ std::string CreateToken(int64_t txfee, int64_t tokensupply, std::string name, st
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (AddNormalinputs(mtx, mypk, tokensupply + 2 * txfee, 64) > 0)
if (AddNormalinputs2(mtx, tokensupply + 2 * txfee, 64) > 0) // add normal inputs only from mypk
{
int64_t mypkInputs = TotalPubkeyNormalInputs(mtx, mypk);
if (mypkInputs < tokensupply) { // check that tokens amount are really issued with mypk (because in the wallet there maybe other privkeys)
CCerror = "some inputs signed not with -pubkey=pk";

View File

@@ -19,14 +19,7 @@
std::vector<CPubKey> NULL_pubkeys;
struct NSPV_CCmtxinfo NSPV_U;
/*
FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and the opreturn.
This allows the contract transaction functions to create the appropriate vins and vouts and have FinalizeCCTx create a properly signed transaction.
By using -addressindex=1, it allows tracking of all the CC addresses
*/
/* see description to function definition in CCinclude.h */
bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey)
{
#ifdef ENABLE_WALLET
@@ -41,17 +34,35 @@ bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScrip
return(false);
}
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret,std::vector<CPubKey> pubkeys)
/*
FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and the opreturn.
This allows the contract transaction functions to create the appropriate vins and vouts and have FinalizeCCTx create a properly signed transaction.
By using -addressindex=1, it allows tracking of all the CC addresses
*/
std::string FinalizeCCTx(uint64_t CCmask, struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey mypk, uint64_t txfee, CScript opret, std::vector<CPubKey> pubkeys)
{
UniValue sigData = FinalizeCCTxExt(false, CCmask, cp, mtx, mypk, txfee, opret, pubkeys);
return sigData[JSON_HEXTX].getValStr();
}
// extended version that supports signInfo object with conds to vins map for remote cc calls
UniValue FinalizeCCTxExt(bool remote, uint64_t CCmask, struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey mypk, uint64_t txfee, CScript opret, std::vector<CPubKey> pubkeys)
{
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
CTransaction vintx; std::string hex; CPubKey globalpk; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0;
int64_t utxovalues[CC_MAXVINS],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0,normalvins=0,ccvins=0;
int32_t i,flag,mgret,utxovout,n,err = 0;
char myaddr[64], destaddr[64], unspendable[64], mytokensaddr[64], mysingletokensaddr[64], unspendabletokensaddr[64],CC1of2CCaddr[64];
uint8_t *privkey, myprivkey[32], unspendablepriv[32], /*tokensunspendablepriv[32],*/ *msg32 = 0;
uint8_t *privkey = NULL, myprivkey[32] = { '\0' }, unspendablepriv[32] = { '\0' }, /*tokensunspendablepriv[32],*/ *msg32 = 0;
CC *mycond=0, *othercond=0, *othercond2=0,*othercond4=0, *othercond3=0, *othercond1of2=NULL, *othercond1of2tokens = NULL, *cond=0, *condCC2=0,*mytokenscond = NULL, *mysingletokenscond = NULL, *othertokenscond = NULL;
CPubKey unspendablepk /*, tokensunspendablepk*/;
struct CCcontract_info *cpTokens, tokensC;
UniValue sigData(UniValue::VARR),result(UniValue::VOBJ);
const UniValue sigDataNull = NullUniValue;
globalpk = GetUnspendable(cp,0);
n = mtx.vout.size();
for (i=0; i<n; i++)
@@ -63,9 +74,18 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
if ( (n= mtx.vin.size()) > CC_MAXVINS )
{
fprintf(stderr,"FinalizeCCTx: %d is too many vins\n",n);
return("0");
result.push_back(Pair(JSON_HEXTX, "0"));
return result;
}
Myprivkey(myprivkey);
//Myprivkey(myprivkey); // for NSPV mode we need to add myprivkey for the explicitly defined mypk param
#ifdef ENABLE_WALLET
// get privkey for mypk
CKeyID keyID = mypk.GetID();
CKey vchSecret;
if (pwalletMain->GetKey(keyID, vchSecret))
memcpy(myprivkey, vchSecret.begin(), sizeof(myprivkey));
#endif
GetCCaddress(cp,myaddr,mypk);
mycond = MakeCCcond1(cp->evalcode,mypk);
@@ -109,7 +129,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
{
fprintf(stderr,"vin.%d vout.%d is bigger than vintx.%d\n",i,mtx.vin[i].prevout.n,(int32_t)vintx.vout.size());
memset(myprivkey,0,32);
return("");
return UniValue(UniValue::VOBJ);
}
}
if (normalvins>1 && ccvins)
@@ -164,8 +184,18 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
{
if ( KOMODO_NSPV_FULLNODE )
{
if ( SignTx(mtx,i,vintx.vout[utxovout].nValue,vintx.vout[utxovout].scriptPubKey) == 0 )
fprintf(stderr,"signing error for vini.%d of %llx\n",i,(long long)vinimask);
if (!remote)
{
if (SignTx(mtx, i, vintx.vout[utxovout].nValue, vintx.vout[utxovout].scriptPubKey) == 0)
fprintf(stderr, "signing error for vini.%d of %llx\n", i, (long long)vinimask);
}
else
{
// if no myprivkey for mypk it means remote call from nspv superlite client
// add sigData for superlite client
UniValue cc(UniValue::VNULL);
AddSigData2UniValue(sigData, i, cc, HexStr(vintx.vout[utxovout].scriptPubKey), vintx.vout[utxovout].nValue ); // store vin i with scriptPubKey
}
}
else
{
@@ -282,7 +312,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
{
fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr);
memset(myprivkey,0,32);
return("");
return sigDataNull;
}
}
uint256 sighash = SignatureHash(CCPubKey(cond), mtx, i, SIGHASH_ALL,utxovalues[i],consensusBranchId, &txdata);
@@ -296,15 +326,33 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
fprintf(stderr,"%02x",((uint8_t *)sighash.begin())[z]);
fprintf(stderr," sighash [%d] %.8f %x\n",i,(double)utxovalues[i]/COIN,consensusBranchId);
}
if ( cc_signTreeSecp256k1Msg32(cond,privkey,sighash.begin()) != 0 )
if (!remote) // we have privkey in the wallet
{
mtx.vin[i].scriptSig = CCSig(cond);
if (cc_signTreeSecp256k1Msg32(cond, privkey, sighash.begin()) != 0)
{
mtx.vin[i].scriptSig = CCSig(cond);
}
else
{
fprintf(stderr, "vini.%d has CC signing error address.(%s) %s\n", i, destaddr, EncodeHexTx(mtx).c_str());
memset(myprivkey, 0, sizeof(myprivkey));
return sigDataNull;
}
}
else
else // no privkey locally - remote call
{
fprintf(stderr,"vini.%d has CC signing error address.(%s) %s\n",i,destaddr,EncodeHexTx(mtx).c_str());
memset(myprivkey,0,sizeof(myprivkey));
return("");
// serialize cc:
UniValue ccjson;
ccjson.read(cc_conditionToJSONString(cond));
if (ccjson.empty())
{
fprintf(stderr, "vini.%d can't serialize CC.(%s) %s\n", i, destaddr, EncodeHexTx(mtx).c_str());
memset(myprivkey, 0, sizeof(myprivkey));
return sigDataNull;
}
AddSigData2UniValue(sigData, i, ccjson, std::string(), vintx.vout[utxovout].nValue); // store vin i with scriptPubKey
}
}
} else fprintf(stderr,"FinalizeCCTx2 couldnt find %s mgret.%d\n",mtx.vin[i].prevout.hash.ToString().c_str(),mgret);
@@ -334,8 +382,12 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
memset(myprivkey,0,sizeof(myprivkey));
std::string strHex = EncodeHexTx(mtx);
if ( strHex.size() > 0 )
return(strHex);
else return("0");
result.push_back(Pair(JSON_HEXTX, strHex));
else {
result.push_back(Pair(JSON_HEXTX, "0"));
}
if (sigData.size() > 0) result.push_back(Pair(JSON_SIGDATA,sigData));
return result;
}
void NSPV_CCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr,bool ccflag);
@@ -412,7 +464,10 @@ void SetCCtxids(std::vector<uint256> &txids,char *coinaddr,bool ccflag, uint8_t
{
if ( GetAddressIndex((*it).first, (*it).second, addressIndex) == 0 )
return;
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it1=addressIndex.begin(); it1!=addressIndex.end(); it1++) txids.push_back(it1->first.txhash);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it1=addressIndex.begin(); it1!=addressIndex.end(); it1++)
{
if (it1->second>=0) txids.push_back(it1->first.txhash);
}
}
}
@@ -579,11 +634,15 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
else return(belowi);
}
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs)
int64_t AddNormalinputsLocal(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs)
{
int32_t abovei,belowi,ind,vout,i,n = 0; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
if ( KOMODO_NSPV_SUPERLITE )
return(NSPV_AddNormalinputs(mtx,mypk,total,maxinputs,&NSPV_U));
// if (mypk != pubkey2pk(Mypubkey())) //remote superlite mypk, do not use wallet since it is not locked for non-equal pks (see rpcs with nspv support)!
// return(AddNormalinputs3(mtx, mypk, total, maxinputs));
#ifdef ENABLE_WALLET
assert(pwalletMain != NULL);
const CKeyStore& keystore = *pwalletMain;
@@ -675,12 +734,20 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
return(0);
}
int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinputs)
// always uses -pubkey param as mypk
int64_t AddNormalinputs2(CMutableTransaction &mtx, int64_t total, int32_t maxinputs)
{
CPubKey mypk = pubkey2pk(Mypubkey());
return AddNormalinputsRemote(mtx, mypk, total, maxinputs);
}
// has additional mypk param for nspv calls
int64_t AddNormalinputsRemote(CMutableTransaction &mtx, CPubKey mypk, int64_t total, int32_t maxinputs)
{
int32_t abovei,belowi,ind,vout,i,n = 0; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; struct CC_utxo *utxos,*up;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
if ( KOMODO_NSPV_SUPERLITE )
return(NSPV_AddNormalinputs(mtx,pubkey2pk(Mypubkey()),total,maxinputs,&NSPV_U));
return(NSPV_AddNormalinputs(mtx,mypk,total,maxinputs,&NSPV_U));
utxos = (struct CC_utxo *)calloc(CC_MAXVINS,sizeof(*utxos));
if ( maxinputs > CC_MAXVINS )
maxinputs = CC_MAXVINS;
@@ -688,7 +755,7 @@ int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinput
threshold = total/maxinputs;
else threshold = total;
sum = 0;
Getscriptaddress(coinaddr,CScript() << Mypubkey() << OP_CHECKSIG);
Getscriptaddress(coinaddr,CScript() << vscript_t(mypk.begin(), mypk.end()) << OP_CHECKSIG);
SetCCunspents(unspentOutputs,coinaddr,false);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
@@ -766,3 +833,21 @@ int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinput
}
return(0);
}
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs,bool remote)
{
if (!remote) return (AddNormalinputsLocal(mtx,mypk,total,maxinputs));
else return (AddNormalinputsRemote(mtx,mypk,total,maxinputs));
}
void AddSigData2UniValue(UniValue &sigdata, int32_t vini, UniValue& ccjson, std::string sscriptpubkey, int64_t amount)
{
UniValue elem(UniValue::VOBJ);
elem.push_back(Pair("vin", vini));
if (!ccjson.empty())
elem.push_back(Pair("cc", ccjson));
if (!sscriptpubkey.empty())
elem.push_back(Pair("scriptPubKey", sscriptpubkey));
elem.push_back(Pair("amount", amount));
sigdata.push_back(elem);
}

View File

@@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* Copyright <EFBFBD> 2014-2019 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
@@ -93,13 +93,23 @@ CPubKey buf2pk(uint8_t *buf33)
return(pk);
}
CPubKey pubkey2pk(std::vector<uint8_t> pubkey)
CPubKey pubkey2pk(std::vector<uint8_t> vpubkey)
{
CPubKey pk; int32_t i,n; uint8_t *dest,*pubkey33;
n = pubkey.size();
dest = (uint8_t *)pk.begin();
pubkey33 = (uint8_t *)pubkey.data();
for (i=0; i<n; i++)
dest[i] = pubkey33[i];
CPubKey pk;
pk.Set(vpubkey.begin(), vpubkey.end());
return(pk);
}
void CCLogPrintStr(const char *category, int level, const std::string &str)
{
if (level < 0)
level = 0;
if (level > CCLOG_MAXLEVEL)
level = CCLOG_MAXLEVEL;
for (int i = level; i <= CCLOG_MAXLEVEL; i++)
if (LogAcceptCategory((std::string(category) + std::string("-") + std::to_string(i)).c_str()) || // '-debug=cctokens-0', '-debug=cctokens-1',...
i == 0 && LogAcceptCategory(std::string(category).c_str())) { // also supporting '-debug=cctokens' for CCLOG_INFO
LogPrintStr(str);
break;
}
}

View File

@@ -16,6 +16,7 @@
/*
CCutils has low level functions that are universally useful for all contracts.
*/
#include "CCinclude.h"
#include "komodo_structs.h"
#include "key_io.h"
@@ -169,7 +170,12 @@ bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_
return true;
}
// set additional 'unspendable' addr
uint32_t GetLatestTimestamp(int32_t height)
{
if ( KOMODO_NSPV_SUPERLITE ) return ((uint32_t)NSPV_blocktime(height));
return(komodo_heightstamp(height));
} // :P
void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr)
{
cp->unspendableEvalcode2 = evalcode;
@@ -178,7 +184,6 @@ void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *
strcpy(cp->unspendableaddr2,coinaddr);
}
// set yet another additional 'unspendable' addr
void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr)
{
cp->unspendableEvalcode3 = evalcode;
@@ -187,7 +192,6 @@ void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *
strcpy(cp->unspendableaddr3,coinaddr);
}
// set pubkeys, myprivkey and 1of2 cc addr for spending from 1of2 cryptocondition vout:
void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, uint8_t *priv, char *coinaddr)
{
cp->coins1of2pk[0] = pk1;
@@ -196,8 +200,6 @@ void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, uint8_t
strcpy(cp->coins1of2addr,coinaddr);
}
// set pubkeys, myprivkey and 1of2 cc addr for spending from 1of2 token cryptocondition vout
// to get tokenaddr use GetTokensCCaddress()
void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, uint8_t *priv, char *tokenaddr)
{
cp->tokens1of2pk[0] = pk1;
@@ -358,7 +360,6 @@ bool GetCCaddress1of2(struct CCcontract_info *cp,char *destaddr,CPubKey pk,CPubK
return(destaddr[0] != 0);
}
// get scriptPubKey adddress for three/dual eval token 1of2 cc vout
bool GetTokensCCaddress1of2(struct CCcontract_info *cp, char *destaddr, CPubKey pk, CPubKey pk2)
{
CC *payoutCond;

116
src/cc/COptCCParams.cpp Normal file
View File

@@ -0,0 +1,116 @@
/*Descriptson and examples of COptCCParams class found in:
script/standard.h/cpp
class COptCCParams
structure of data in vData payload attached to end of CCvout:
param
OP_1
param
OP_2 ... etc until OP_16
OP_PUSHDATA4 is the last OP code to tell things its at the end.
taken from standard.cpp line 22: COptCCParams::COptCCParams(std::vector<unsigned char> &vch)
EXAMPLE taken from Verus how to create scriptPubKey from COptCCParams class:
EXAMPLE taken from Verus how to decode scriptPubKey from COptCCParams class:
*/
bool MakeGuardedOutput(CAmount value, CPubKey &dest, CTransaction &stakeTx, CTxOut &vout)
{
CCcontract_info *cp, C;
cp = CCinit(&C,EVAL_STAKEGUARD);
CPubKey ccAddress = CPubKey(ParseHex(cp->CChexstr));
// return an output that is bound to the stake transaction and can be spent by presenting either a signed condition by the original
// destination address or a properly signed stake transaction of the same utxo on a fork
vout = MakeCC1of2vout(EVAL_STAKEGUARD, value, dest, ccAddress);
std::vector<CPubKey> vPubKeys = std::vector<CPubKey>();
vPubKeys.push_back(dest);
vPubKeys.push_back(ccAddress);
std::vector<std::vector<unsigned char>> vData = std::vector<std::vector<unsigned char>>();
CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION);
hw << stakeTx.vin[0].prevout.hash;
hw << stakeTx.vin[0].prevout.n;
uint256 utxo = hw.GetHash();
vData.push_back(std::vector<unsigned char>(utxo.begin(), utxo.end())); // Can we use any data here to construct vector?
CStakeParams p;
if (GetStakeParams(stakeTx, p))
{
// prev block hash and height is here to make validation easy
vData.push_back(std::vector<unsigned char>(p.prevHash.begin(), p.prevHash.end()));
std::vector<unsigned char> height = std::vector<unsigned char>(4);
for (int i = 0; i < 4; i++)
{
height[i] = (p.blkHeight >> (8 * i)) & 0xff;
}
vData.push_back(height);
COptCCParams ccp = COptCCParams(COptCCParams::VERSION, EVAL_STAKEGUARD, 1, 2, vPubKeys, vData);
vout.scriptPubKey << ccp.AsVector() << OP_DROP;
return true;
}
return false;
}
bool ValidateMatchingStake(const CTransaction &ccTx, uint32_t voutNum, const CTransaction &stakeTx, bool &cheating)
{
// an invalid or non-matching stake transaction cannot cheat
cheating = false;
//printf("ValidateMatchingStake: ccTx.vin[0].prevout.hash: %s, ccTx.vin[0].prevout.n: %d\n", ccTx.vin[0].prevout.hash.GetHex().c_str(), ccTx.vin[0].prevout.n);
if (ccTx.IsCoinBase())
{
CStakeParams p;
if (ValidateStakeTransaction(stakeTx, p))
{
std::vector<std::vector<unsigned char>> vParams = std::vector<std::vector<unsigned char>>();
CScript dummy;
if (ccTx.vout[voutNum].scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) && vParams.size() > 0)
{
COptCCParams ccp = COptCCParams(vParams[0]);
if (ccp.IsValid() & ccp.vData.size() >= 3 && ccp.vData[2].size() <= 4)
{
CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION);
hw << stakeTx.vin[0].prevout.hash;
hw << stakeTx.vin[0].prevout.n;
uint256 utxo = hw.GetHash();
uint32_t height = 0;
int i, dataLen = ccp.vData[2].size();
for (i = dataLen - 1; i >= 0; i--)
{
height = (height << 8) + ccp.vData[2][i];
}
// for debugging strange issue
// printf("iterator: %d, height: %d, datalen: %d\n", i, height, dataLen);
if (utxo == uint256(ccp.vData[0]))
{
if (p.prevHash != uint256(ccp.vData[1]) && p.blkHeight >= height)
{
cheating = true;
return true;
}
// if block height is equal and we are at the else, prevHash must have been equal
else if (p.blkHeight == height)
{
return true;
}
}
}
}
}
}
return false;
}

View File

@@ -570,7 +570,7 @@ std::string Faucet2Fund(struct CCcontract_info *cp,uint64_t txfee,int64_t funds)
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
cclibpk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
if ( AddNormalinputs2(mtx,funds+txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,cclibpk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));

View File

@@ -461,30 +461,32 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
else return 0;
}
std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment, uint256 tokenid)
UniValue ChannelOpen(const CPubKey& pk, uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment, uint256 tokenid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
uint8_t hash[32],hashdest[32]; uint64_t amount,tokens=0,funds; int32_t i; uint256 hashchain,entropy,hentropy;
CPubKey mypk; struct CCcontract_info *cp,*cpTokens,C,CTokens;
if ( numpayments <= 0 || payment <= 0 || numpayments > CHANNELS_MAXPAYMENTS )
{
CCerror = strprintf("invalid ChannelOpen param numpayments.%d max.%d payment.%lld\n",numpayments,CHANNELS_MAXPAYMENTS,(long long)payment);
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid ChannelOpen param numpayments." << numpayments << " payment." << payment << " - max_numpayments." << CHANNELS_MAXPAYMENTS);
if (!destpub.IsFullyValid())
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid destination pubkey");
if (numpayments <1)
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid number of payments, must be greater than 0");
if (payment <1)
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid payment amount, must be greater than 0");
cp = CCinit(&C,EVAL_CHANNELS);
cpTokens = CCinit(&CTokens,EVAL_TOKENS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
funds = numpayments * payment;
if (tokenid!=zeroid)
{
amount=AddNormalinputs(mtx,mypk,txfee+2*CC_MARKER_VALUE,5);
amount=AddNormalinputs(mtx,mypk,txfee+2*CC_MARKER_VALUE,5,pk.IsValid());
tokens=AddTokenCCInputs(cpTokens, mtx, mypk, tokenid, funds, 64);
}
else amount=AddNormalinputs(mtx,mypk,funds+txfee+2*CC_MARKER_VALUE,64);
else amount=AddNormalinputs(mtx,mypk,funds+txfee+2*CC_MARKER_VALUE,64,pk.IsValid());
if (amount+tokens >= funds+txfee+2*CC_MARKER_VALUE)
{
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1);
@@ -500,14 +502,12 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,CC_MARKER_VALUE,mypk));
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,CC_MARKER_VALUE,destpub));
if (tokenid!=zeroid && tokens>funds) mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS,tokens-funds,mypk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('O',tokenid,zeroid,mypk,destpub,numpayments,payment,hashchain)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('O',tokenid,zeroid,mypk,destpub,numpayments,payment,hashchain)));
}
CCerror = strprintf("error adding funds");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "error adding funds");
}
std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret)
UniValue ChannelPayment(const CPubKey& pk, uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,srcpub,destpub; uint256 txid,hashchain,gensecret,hashblock,entropy,hentropy,prevtxid,param3,tokenid;
@@ -519,41 +519,23 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
cp = CCinit(&C,EVAL_CHANNELS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
{
CCerror = strprintf("invalid channel open txid");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
if (amount <1)
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid payment amount, must be greater than 0");
if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open txid");
if ((numvouts=channelOpenTx.vout.size()) > 0 && DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, tokenid, txid, srcpub, destpub, totalnumpayments, payment, hashchain)=='O')
{
if (mypk != srcpub && mypk != destpub)
{
CCerror = strprintf("this is not our channel");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if (mypk != srcpub && mypk != destpub)
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "this is not our channel");
else if (amount % payment != 0 || amount<payment)
{
CCerror = strprintf("invalid amount, not a magnitude of payment size");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid amount, not a magnitude of payment size");
else if (mypk == destpub && secret==zeroid) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid secret, secret is necessary when making payment from destination");
}
else
{
CCerror = strprintf("invalid channel open tx");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
if (komodo_txnotarizedconfirmed(opentxid)==false)
{
CCerror = strprintf("channelsopen tx not yet confirmed/notarized");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if (AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,3) > 0)
else
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open tx");
if (komodo_txnotarizedconfirmed(opentxid)==false) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "channelsopen tx not yet confirmed/notarized");
if (AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,3,pk.IsValid()) > 0)
{
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && (change=funds-amount)>=0)
{
@@ -563,16 +545,9 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
(funcid == 'P' || funcid=='O'))
{
if (numpayments > prevdepth)
{
CCerror = strprintf("not enough funds in channel for that amount");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
} else if (numpayments == 0)
{
CCerror = strprintf("invalid amount");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "not enough funds in channel for that amount");
else if (numpayments == 0)
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid amount");
if (secret!=zeroid)
{
endiancpy(hash, (uint8_t * ) & secret, 32);
@@ -582,12 +557,7 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
memcpy(hash, hashdest, 32);
}
endiancpy((uint8_t * ) & gensecret, hashdest, 32);
if (gensecret!=hashchain)
{
CCerror = strprintf("invalid secret supplied");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if (gensecret!=hashchain) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid secret supplied");
}
else
{
@@ -605,33 +575,23 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
else endiancpy((uint8_t * ) & secret, (uint8_t * ) & hentropy, 32);
}
}
else
{
CCerror = strprintf("invalid previous tx");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid previous tx");
if (tokenid!=zeroid) mtx.vout.push_back(MakeTokensCC1of2vout(EVAL_CHANNELS, change, srcpub, destpub));
else mtx.vout.push_back(MakeCC1of2vout(EVAL_CHANNELS, change, srcpub, destpub));
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,CC_MARKER_VALUE,srcpub));
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,CC_MARKER_VALUE,destpub));
if (tokenid!=zeroid) mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, amount, destpub));
else mtx.vout.push_back(CTxOut(amount, CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG));
return (FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeChannelsOpRet('P', tokenid, opentxid, srcpub, destpub, prevdepth-numpayments, numpayments, secret)));
}
else
{
CCerror = strprintf("error adding CC inputs");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
return (FinalizeCCTxExt(pk.IsValid(), 0, cp, mtx, mypk, txfee, EncodeChannelsOpRet('P', tokenid, opentxid, srcpub, destpub, prevdepth-numpayments, numpayments, secret)));
}
else
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "error adding CC inputs");
}
CCerror = strprintf("error adding normal inputs");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "error adding normal inputs");
}
std::string ChannelClose(uint64_t txfee,uint256 opentxid)
UniValue ChannelClose(const CPubKey& pk, uint64_t txfee,uint256 opentxid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,srcpub,destpub; struct CCcontract_info *cp,C;
@@ -644,32 +604,16 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid)
cp = CCinit(&C,EVAL_CHANNELS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
{
CCerror = strprintf("invalid channel open txid");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open txid");
if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,numpayments,payment,hashchain)!='O')
{
CCerror = strprintf("invalid channel open tx");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open tx");
if (komodo_txnotarizedconfirmed(opentxid)==false)
{
CCerror = strprintf("channelsopen tx not yet confirmed/notarized");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream <<"channelsopen tx not yet confirmed/notarized");
if (mypk != srcpub)
{
CCerror = strprintf("cannot close, you are not channel owner");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,3) > 0 )
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "cannot close, you are not channel owner");
if ( AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,3,pk.IsValid()) > 0 )
{
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && funds>0)
{
@@ -680,18 +624,12 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid)
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('C',tokenid,opentxid,mypk,destpub,funds/payment,payment,zeroid)));
}
else
{
CCerror = strprintf("error adding CC inputs");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "error adding CC inputs");
}
CCerror = strprintf("error adding normal inputs");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "error adding normal inputs");
}
std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
UniValue ChannelRefund(const CPubKey& pk, uint64_t txfee,uint256 opentxid,uint256 closetxid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk; struct CCcontract_info *cp,C; int64_t funds,payment,param2;
@@ -704,56 +642,24 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
cp = CCinit(&C,EVAL_CHANNELS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
if (myGetTransaction(closetxid,channelCloseTx,hashblock) == 0)
{
CCerror = strprintf("invalid channel close txid");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel close txid");
if ((numvouts=channelCloseTx.vout.size()) < 1 || DecodeChannelsOpRet(channelCloseTx.vout[numvouts-1].scriptPubKey,tokenid,txid,srcpub,destpub,param1,param2,param3)!='C')
{
CCerror = strprintf("invalid channel close tx");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel close tx");
if (komodo_txnotarizedconfirmed(closetxid)==false)
{
CCerror = strprintf("channelsclose tx not yet confirmed/notarized");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "channelsclose tx not yet confirmed/notarized");
if (txid!=opentxid)
{
CCerror = strprintf("open and close txid are not from same channel");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "open and close txid are not from same channel");
if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
{
CCerror = strprintf("invalid channel open txid");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open txid");
if (komodo_txnotarizedconfirmed(opentxid)==false)
{
CCerror = strprintf("channelsopen tx not yet confirmed/notarized");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "channelsopen tx not yet confirmed/notarized");
if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,tokenid,txid,srcpub,destpub,numpayments,payment,hashchain)!='O')
{
CCerror = strprintf("invalid channel open tx");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open tx");
if (mypk != srcpub)
{
CCerror = strprintf("cannot refund, you are not the channel owner");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,3) > 0 )
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "cannot refund, you are not the channel owner");
if ( AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,3,pk.IsValid()) > 0 )
{
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && funds>0)
{
@@ -767,32 +673,22 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('R',tokenid,opentxid,mypk,destpub,funds/payment,payment,closetxid)));
}
else
{
CCerror = strprintf("previous tx is invalid");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "previous tx is invalid");
}
else
{
CCerror = strprintf("error adding CC inputs");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "error adding CC inputs");
}
CCerror = strprintf("error adding normal inputs");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("channelscc",CCLOG_INFO, stream << "error adding normal inputs");
}
UniValue ChannelsList()
UniValue ChannelsList(const CPubKey& pk)
{
UniValue result(UniValue::VOBJ); std::vector<uint256> txids; struct CCcontract_info *cp,C; uint256 txid,hashBlock,tmp_txid,param3,tokenid;
CTransaction tx; char myCCaddr[65],addr[65],str[256]; CPubKey mypk,srcpub,destpub; int32_t vout,numvouts,param1;
CTransaction tx; char myCCaddr[65],str[512],pub[34]; CPubKey mypk,srcpub,destpub; int32_t vout,numvouts,param1;
int64_t nValue,param2;
cp = CCinit(&C,EVAL_CHANNELS);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
GetCCaddress(cp,myCCaddr,mypk);
SetCCtxids(txids,myCCaddr,true,EVAL_CHANNELS,zeroid,'O');
result.push_back(Pair("result","success"));
@@ -804,8 +700,7 @@ UniValue ChannelsList()
{
if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,param1,param2,param3) == 'O')
{
GetCCaddress1of2(cp,addr,srcpub,destpub);
sprintf(str,"%s - %lld payments of %lld satoshi",addr,(long long)param1,(long long)param2);
sprintf(str,"%lld payments of %lld satoshi to %s",(long long)param1,(long long)param2,pubkey33_str(pub,(uint8_t *)&destpub));
result.push_back(Pair(txid.GetHex().data(),str));
}
}
@@ -813,7 +708,7 @@ UniValue ChannelsList()
return(result);
}
UniValue ChannelsInfo(uint256 channeltxid)
UniValue ChannelsInfo(const CPubKey& pk,uint256 channeltxid)
{
UniValue result(UniValue::VOBJ),array(UniValue::VARR); CTransaction tx,opentx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain,tokenid;
struct CCcontract_info *cp,C; char CCaddr[65],addr[65],str[512]; int32_t vout,numvouts,param1,numpayments;
@@ -821,7 +716,7 @@ UniValue ChannelsInfo(uint256 channeltxid)
std::vector<uint256> txids; std::vector<CTransaction> txs;
cp = CCinit(&C,EVAL_CHANNELS);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
if (myGetTransaction(channeltxid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 &&
(DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,opentxid,srcpub,destpub,param1,param2,param3) == 'O'))

View File

@@ -62,7 +62,7 @@ UniValue custom_func1(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
if ( txfee == 0 )
txfee = CUSTOM_TXFEE;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,COIN+txfee,64) >= COIN+txfee ) // add utxo to mtx
if ( AddNormalinputs2(mtx,COIN+txfee,64) >= COIN+txfee ) // add utxo to mtx
{
// make op_return payload as normal.
CScript opret = custom_opret('1',mypk);

View File

@@ -15,12 +15,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <memory.h>
#include "cJSON.c"
bits256 zeroid;
void myprintf(const char* format, ...)
{
va_list marker;
va_start( marker, format );
vfprintf(stdout, format, marker);
fflush(stdout);
va_end( marker );
}
char hexbyte(int32_t c)
{
c &= 0xf;
@@ -64,7 +74,7 @@ int32_t unhex(char c)
int32_t hex;
if ( (hex= _unhex(c)) < 0 )
{
//printf("unhex: illegal hexchar.(%c)\n",c);
//myprintf("unhex: illegal hexchar.(%c)\n",c);
}
return(hex);
}
@@ -74,7 +84,7 @@ 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);
//myprintf("decode.(%s)\n",hex);
if ( is_hexstr(hex,n) <= 0 )
{
memset(bytes,0,n);
@@ -89,7 +99,7 @@ int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex)
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));
myprintf("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++;
@@ -116,10 +126,10 @@ int32_t init_hexbytes_noT(char *hexbytes,unsigned char *message,long len)
{
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]);
//myprintf("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);
//myprintf("len.%ld\n",len*2+1);
return((int32_t)len*2+1);
}
@@ -143,7 +153,7 @@ char *clonestr(char *str)
char *clone;
if ( str == 0 || str[0]==0)
{
printf("warning cloning nullstr.%p\n",str);
myprintf("warning cloning nullstr.%p\n",str);
//#ifdef __APPLE__
// while ( 1 ) sleep(1);
//#endif
@@ -165,8 +175,8 @@ int32_t safecopy(char *dest,char *src,long len)
dest[i] = src[i];
if ( i == len )
{
printf("safecopy: %s too long %ld\n",src,len);
//printf("divide by zero! %d\n",1/zeroval());
myprintf("safecopy: %s too long %ld\n",src,len);
//myprintf("divide by zero! %d\n",1/zeroval());
#ifdef __APPLE__
//getchar();
#endif
@@ -236,7 +246,7 @@ void *loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep)
{
fclose(fp);
*lenp = 0;
//printf("loadfile null size.(%s)\n",fname);
//myprintf("loadfile null size.(%s)\n",fname);
return(0);
}
if ( filesize > buflen )
@@ -246,17 +256,17 @@ void *loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep)
}
rewind(fp);
if ( buf == 0 )
printf("Null buf ???\n");
myprintf("Null buf ???\n");
else
{
if ( fread(buf,1,(long)filesize,fp) != (unsigned long)filesize )
printf("error reading filesize.%ld\n",(long)filesize);
myprintf("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);
//myprintf("loaded.(%s)\n",buf);
} //else myprintf("OS_loadfile couldnt load.(%s)\n",fname);
return(buf);
}
@@ -284,7 +294,7 @@ 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);
//myprintf("(%s) -> (%s)\n",url,jsonstr);
json = cJSON_Parse(jsonstr);
free(jsonstr);
}
@@ -303,7 +313,7 @@ uint64_t get_btcusd()
if ( (bpi= jobj(pjson,"bpi")) != 0 && (usd= jobj(bpi,"USD")) != 0 )
{
btcusd = jdouble(usd,"rate_float") * SATOSHIDEN;
printf("BTC/USD %.4f\n",dstr(btcusd));
myprintf("BTC/USD %.4f\n",dstr(btcusd));
}
free_json(pjson);
}
@@ -319,13 +329,13 @@ cJSON *get_cli(char *refcoin,char **retstrp,char *acname,char *method,char *arg0
if ( acname[0] != 0 )
{
if ( refcoin[0] == 0 )
printf("must supply reference coin\n");
myprintf("must supply reference coin\n");
sprintf(cmdstr,"./komodo-cli -ac_name=%s %s %s %s %s %s > %s 2>/tmp/oraclefeed.error\n",acname,method,arg0,arg1,arg2,arg3,fname);
}
else if ( REFCOIN_CLI != 0 && REFCOIN_CLI[0] != 0 )
{
sprintf(cmdstr,"%s %s %s %s %s %s > %s 2>/tmp/oraclefeed.error\n",REFCOIN_CLI,method,arg0,arg1,arg2,arg3,fname);
//printf("ref.(%s) REFCOIN_CLI (%s)\n",refcoin,cmdstr);
//myprintf("ref.(%s) REFCOIN_CLI (%s)\n",refcoin,cmdstr);
}
#ifdef TESTMODE
fprintf(stderr,"cmd: %s\n",cmdstr);
@@ -355,7 +365,7 @@ bits256 broadcasttx(char *refcoin,char *acname,cJSON *hexjson)
{
if ( (retjson= get_cli(refcoin,&retstr,acname,"sendrawtransaction",hexstr,"","","")) != 0 )
{
if (strcmp("error",jstr(retjson,"result"))==0) printf("%s\n",jstr(retjson,"error"));
if (strcmp("error",jstr(retjson,"result"))==0) myprintf("%s\n",jstr(retjson,"error"));
free_json(retjson);
}
else if ( retstr != 0 )
@@ -457,7 +467,7 @@ cJSON *get_gatewayspending(int8_t type,char *refcoin,char *acname,char *bindtxid
else if (type==1) sprintf(function,"%s","importgatewaypendingwithdraws");
if ( (retjson= get_cli(refcoin,&retstr,acname,function,bindtxidstr,refcoin,"","")) != 0 )
{
//printf("pending.(%s)\n",jprint(retjson,0));
//myprintf("pending.(%s)\n",jprint(retjson,0));
return(retjson);
}
else if ( retstr != 0 )
@@ -476,7 +486,7 @@ cJSON *get_gatewaysprocessed(int8_t type,char *refcoin,char *acname,char *bindtx
else if (type==1) sprintf(function,"%s","importgatewayprocessed");
if ( (retjson= get_cli(refcoin,&retstr,acname,function,bindtxidstr,refcoin,"","")) != 0 )
{
//printf("pending.(%s)\n",jprint(retjson,0));
//myprintf("pending.(%s)\n",jprint(retjson,0));
return(retjson);
}
else if ( retstr != 0 )
@@ -492,7 +502,7 @@ cJSON *get_rawmempool(char *refcoin,char *acname)
cJSON *retjson; char *retstr;
if ( (retjson= get_cli(refcoin,&retstr,acname,"getrawmempool","","","","")) != 0 )
{
//printf("mempool.(%s)\n",jprint(retjson,0));
//myprintf("mempool.(%s)\n",jprint(retjson,0));
return(retjson);
}
else if ( retstr != 0 )
@@ -507,11 +517,11 @@ 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);
myprintf("warning: assumes %s has addressindex enabled\n",refcoin);
sprintf(jsonbuf,"{\\\"addresses\\\":[\\\"%s\\\"]}",coinaddr);
if ( (retjson= get_cli(refcoin,&retstr,acname,"getaddressutxos",jsonbuf,"","","")) != 0 )
{
//printf("addressutxos.(%s)\n",jprint(retjson,0));
//myprintf("addressutxos.(%s)\n",jprint(retjson,0));
return(retjson);
}
else if ( retstr != 0 )
@@ -561,7 +571,7 @@ void importaddress(char *refcoin,char *acname,char *depositaddr, char *label,int
else strcpy(rescanstr,"false");
if ( (retjson= get_cli(refcoin,&retstr,acname,"importaddress",depositaddr,label,rescanstr,"")) != 0 )
{
printf("importaddress.(%s)\n",jprint(retjson,0));
myprintf("importaddress.(%s)\n",jprint(retjson,0));
free_json(retjson);
}
else if ( retstr != 0 )
@@ -585,7 +595,7 @@ void addmultisigaddress(char *refcoin,char *acname,int32_t M, char *pubkeys)
{
sprintf(addr,"\"%s\"",retstr);
get_cli(refcoin,&retstr,acname,"importaddress",addr,"\"\"","false","");
printf("addmultisigaddress.(%s)\n",retstr);
myprintf("addmultisigaddress.(%s)\n",retstr);
free_json(retjson);
}
}
@@ -628,7 +638,7 @@ char *createrawtx(char *refcoin,char *acname,char *depositaddr,char *withdrawadd
else txfee = 10000;
if ( satoshis < txfee )
{
printf("createrawtx: satoshis %.8f < txfee %.8f\n",(double)satoshis/SATOSHIDEN,(double)txfee/SATOSHIDEN);
myprintf("createrawtx: satoshis %.8f < txfee %.8f\n",(double)satoshis/SATOSHIDEN,(double)txfee/SATOSHIDEN);
return(0);
}
sprintf(array,"\'[\"%s\"]\'",depositaddr);
@@ -655,26 +665,26 @@ char *createrawtx(char *refcoin,char *acname,char *depositaddr,char *withdrawadd
sprintf(argB,"\'%s\'",tmpB);
if ( (retjson2= get_cli(refcoin,&txstr,acname,"createrawtransaction",argA,argB,"","")) != 0 )
{
printf("createrawtx: unexpected JSON2.(%s)\n",jprint(retjson2,0));
myprintf("createrawtx: unexpected JSON2.(%s)\n",jprint(retjson2,0));
free_json(retjson2);
}
else if ( txstr == 0 )
printf("createrawtx: null txstr and JSON2\n");
myprintf("createrawtx: null txstr and JSON2\n");
free(tmpA);
free(tmpB);
free(argA);
free(argB);
}
else printf("not enough funds to create withdraw tx\n");
else myprintf("not enough funds to create withdraw tx\n");
}
free_json(retjson);
}
else if ( retstr != 0 )
{
printf("createrawtx: unexpected null JSON, retstr.(%s)\n",retstr);
myprintf("createrawtx: unexpected null JSON, retstr.(%s)\n",retstr);
free(retstr);
}
else printf("createrawtx: null retstr and JSON\n");
else myprintf("createrawtx: null retstr and JSON\n");
return(txstr);
}
@@ -694,7 +704,7 @@ cJSON *addsignature(char *refcoin,char *acname,char *rawtx, int M)
}
else if ( retstr != 0 )
{
printf("error parsing signrawtransaction.(%s)\n",retstr);
myprintf("error parsing signrawtransaction.(%s)\n",retstr);
free(retstr);
}
return(0);
@@ -708,13 +718,13 @@ bits256 gatewayspartialsign(int8_t type,char *refcoin,char *acname,bits256 txid,
if ( (retjson= get_cli(refcoin,&retstr,acname,function,bits256_str(str,txid),refcoin,hex,"")) != 0 )
{
if (strcmp("error",jstr(retjson,"result"))!=0) txid=broadcasttx(refcoin,acname,retjson);
else printf("%s\n",jstr(retjson,"error"));
else myprintf("%s\n",jstr(retjson,"error"));
free(retjson);
return (txid);
}
else if ( retstr != 0 )
{
printf("error parsing gatewayspartialsing.(%s)\n",retstr);
myprintf("error parsing gatewayspartialsing.(%s)\n",retstr);
free(retstr);
}
return (zeroid);
@@ -729,13 +739,13 @@ bits256 gatewayscompletesigning(int8_t type,char *refcoin,char *acname,bits256 w
if ( (retjson= get_cli(refcoin,&retstr,acname,function,bits256_str(str,withtxid),refcoin,hex,"")) != 0 )
{
if (strcmp("error",jstr(retjson,"result"))!=0) txid=broadcasttx(refcoin,acname,retjson);
else printf("%s\n",jstr(retjson,"error"));
else myprintf("%s\n",jstr(retjson,"error"));
free(retjson);
return (txid);
}
else if ( retstr != 0 )
{
printf("error parsing gatewayscompletesigning.(%s)\n",retstr);
myprintf("error parsing gatewayscompletesigning.(%s)\n",retstr);
free(retstr);
}
return (zeroid);
@@ -750,13 +760,13 @@ bits256 gatewaysmarkdone(int8_t type,char *refcoin,char *acname,bits256 withtxid
if ( (retjson= get_cli(refcoin,&retstr,acname,function,bits256_str(str,withtxid),refcoin,"","")) != 0 )
{
if (strcmp("error",jstr(retjson,"result"))!=0) txid=broadcasttx(refcoin,acname,retjson);
else printf("%s\n",jstr(retjson,"error"));
else myprintf("%s\n",jstr(retjson,"error"));
free(retjson);
return (txid);
}
else if ( retstr != 0 )
{
printf("error parsing gatewaysmarkdone.(%s)\n",retstr);
myprintf("error parsing gatewaysmarkdone.(%s)\n",retstr);
free(retstr);
}
return (zeroid);
@@ -778,7 +788,7 @@ int32_t get_gatewaysinfo(int8_t type,char *refcoin,char *acname,char *depositadd
*Mp = jint(retjson,"M");
*Np = jint(retjson,"N");
}
else printf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
else myprintf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
if ((pubarray=jarray(&n,retjson,"pubkeys"))!=0)
{
*pubkeys=malloc((sizeof(char)*70*n)+64);
@@ -797,7 +807,7 @@ int32_t get_gatewaysinfo(int8_t type,char *refcoin,char *acname,char *depositadd
}
else if ( retstr != 0 )
{
printf("error parsing get_gatewaysinfo.(%s)\n",retstr);
myprintf("error parsing get_gatewaysinfo.(%s)\n",retstr);
free(retstr);
}
if ( *Mp <= 0 || *Np <= 0 )
@@ -1049,10 +1059,10 @@ int32_t main(int32_t argc,char **argv)
cJSON *clijson,*clijson2,*regjson,*item; int32_t type,i,retval,M,N,n,height,prevheight = 0; char *pubkeys,*format,*acname,*oraclestr,*bindtxidstr,*pkstr,*pubstr,*retstr,*retstr2,depositaddr[64],hexstr[4096],refcoin[64]; uint64_t price; bits256 txid;
if ( argc < 6 )
{
printf("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT $BINDTXID [refcoin_cli]\n");
myprintf("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT $BINDTXID [refcoin_cli]\n");
return(-1);
}
printf("Powered by CoinDesk (%s) %.8f\n","https://www.coindesk.com/price/",dstr(get_btcusd()));
myprintf("Powered by CoinDesk (%s) %.8f\n","https://www.coindesk.com/price/",dstr(get_btcusd()));
acname = argv[1];
oraclestr = argv[2];
pkstr = argv[3];
@@ -1063,7 +1073,7 @@ int32_t main(int32_t argc,char **argv)
else REFCOIN_CLI = "./komodo-cli";
if ( strncmp(format,"Ihh",3) != 0 && format[0] != 'L' )
{
printf("only formats of L and Ihh are supported now\n");
myprintf("only formats of L and Ihh are supported now\n");
return(-1);
}
M = N = 0;
@@ -1078,7 +1088,7 @@ int32_t main(int32_t argc,char **argv)
strcpy(refcoin,jstr(clijson,"name"));
if ( strcmp("KMD",refcoin) != 0 && argc != 7 )
{
printf("need to specify path to refcoin's cli as last argv\n");
myprintf("need to specify path to refcoin's cli as last argv\n");
exit(0);
}
pubkeys=0;
@@ -1086,7 +1096,7 @@ int32_t main(int32_t argc,char **argv)
else if ( get_gatewaysinfo(1,refcoin,acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr,&pubkeys) == 0 ) type=1;
else
{
printf("cant find bindtxid.(%s)\n",bindtxidstr);
myprintf("cant find bindtxid.(%s)\n",bindtxidstr);
exit(0);
}
if (validateaddress(refcoin,"",depositaddr,"iswatchonly")==0 && validateaddress(refcoin,"",depositaddr,"ismine")==0)
@@ -1095,7 +1105,7 @@ int32_t main(int32_t argc,char **argv)
else addmultisigaddress(refcoin,"",M,pubkeys);
}
if (pubkeys!=0) free(pubkeys);
printf("set refcoin %s <- %s [%s] M.%d of N.%d\n",depositaddr,refcoin,REFCOIN_CLI,M,N);
myprintf("set refcoin %s <- %s [%s] M.%d of N.%d\n",depositaddr,refcoin,REFCOIN_CLI,M,N);
}
if ( (regjson= jarray(&n,clijson,"registered")) != 0 )
{
@@ -1112,14 +1122,14 @@ int32_t main(int32_t argc,char **argv)
if ( bits256_nonz(txid) != 0 )
{
prevheight = height;
printf("%s ht.%d <- %s\n",refcoin,height,hexstr);
myprintf("%s ht.%d <- %s\n",refcoin,height,hexstr);
update_gatewayspending(type,refcoin,acname,bindtxidstr,M,N);
}
free_json(clijson2);
}
else if ( retstr2 != 0 )
{
printf("error parsing oraclesdata.(%s)\n",retstr2);
myprintf("error parsing oraclesdata.(%s)\n",retstr2);
free(retstr2);
}
}
@@ -1131,7 +1141,7 @@ int32_t main(int32_t argc,char **argv)
}
if ( retstr != 0 )
{
printf("got json parse error.(%s)\n",retstr);
myprintf("got json parse error.(%s)\n",retstr);
free(retstr);
}
sleep(10);

View File

@@ -1,4 +1,3 @@
// Copyright 2019 The Hush developers
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* *
@@ -37,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) \

View File

@@ -172,20 +172,20 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
} else fprintf(stderr,"vout.%d nValue %.8f too small or already spent in mempool\n",vout,(double)nValue/COIN);
} else fprintf(stderr,"couldnt get tx\n");
} else fprintf(stderr,"couldn't get tx\n");
}
return(totalinputs);
}
std::string FaucetGet(uint64_t txfee)
UniValue FaucetGet(const CPubKey& pk, uint64_t txfee)
{
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;
CPubKey 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;
faucetpk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
CPubKey mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
if ( (inputs= AddFaucetInputs(cp,mtx,faucetpk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
@@ -198,42 +198,40 @@ std::string FaucetGet(uint64_t txfee)
for (i=0; i<1000000; i++,j++)
{
tmpmtx = mtx;
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_FAUCET << (uint8_t)'G' << j));
if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 )
UniValue result = FinalizeCCTxExt(pk.IsValid (),-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_FAUCET << (uint8_t)'G' << j));
if ( (len= (int32_t)result[JSON_HEXTX].getValStr().size()) > 0 && len < 65536 )
{
len >>= 1;
decode_hex(buf,len,(char *)rawhex.c_str());
decode_hex(buf,len,(char *)result[JSON_HEXTX].getValStr().c_str());
hash = bits256_doublesha256(0,buf,len);
if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 )
{
fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL));
return(rawhex);
return result;
}
//fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]);
}
}
fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL));
return("");
} else fprintf(stderr,"cant find faucet inputs\n");
return("");
CCERR_RESULT("faucet",CCLOG_ERROR, stream << "couldn't generate valid txid " << (uint32_t)time(NULL));
} else CCERR_RESULT("faucet",CCLOG_ERROR, stream << "can't find faucet inputs");
}
std::string FaucetFund(uint64_t txfee,int64_t funds)
UniValue FaucetFund(const CPubKey& pk, uint64_t txfee,int64_t funds)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C;
CPubKey faucetpk; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_FAUCET);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
CPubKey mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
faucetpk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
if ( AddNormalinputs(mtx,mypk,funds+txfee,64,pk.IsValid()) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,funds,faucetpk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,opret));
}
return("");
CCERR_RESULT("faucet",CCLOG_ERROR, stream << "can't find normal inputs");
}
UniValue FaucetInfo()

View File

@@ -862,12 +862,12 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
return(0);
}
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,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4)
UniValue GatewaysBind(const CPubKey& pk, uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector<CPubKey> pubkeys,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CTransaction oracletx; uint8_t taddr,prefix,prefix2,wiftype; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock;
struct CCcontract_info *cp,*cpTokens,C,CTokens; std::string name,description,format; int32_t i,numvouts; int64_t fullsupply;
char destaddr[64],coinaddr[64],myTokenCCaddr[64],str[65],*fstr;
char destaddr[64],coinaddr[64],myTokenCCaddr[64],*fstr;
cp = CCinit(&C,EVAL_GATEWAYS);
cpTokens = CCinit(&CTokens,EVAL_TOKENS);
@@ -887,118 +887,64 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "set prefix " << prefix << ", prefix2 " << prefix2 << ", wiftype " << wiftype << ", taddr " << taddr << " for " << coin << std::endl);
}
if ( N == 0 || N > 15 || M > N )
{
CCerror = strprintf("illegal M.%d or N.%d",M,N);
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "illegal M." << M << " or N." << N);
if ( pubkeys.size() != N )
{
CCerror = strprintf("M.%d N.%d but pubkeys[%d]",M,N,(int32_t)pubkeys.size());
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "M."<< M << " N." << N << " but pubkeys[" <<( int32_t)pubkeys.size() << "]");
for (i=0; i<N; i++)
{
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pubkeys[i])) << OP_CHECKSIG);
if ( CCaddress_balance(coinaddr,0) == 0 )
{
CCerror = strprintf("M.%d N.%d but pubkeys[%d] has no balance",M,N,i);
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "M." << M << " N." << N << " but pubkeys[" << i << "] has no balance");
}
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
_GetCCaddress(myTokenCCaddr,EVAL_TOKENS,mypk);
gatewayspk = GetUnspendable(cp,0);
if ( _GetCCaddress(destaddr,EVAL_GATEWAYS,gatewayspk) == 0 )
{
CCerror = strprintf("Gateway bind.%s (%s) cant create globaladdr",coin.c_str(),uint256_str(str,tokenid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "Gateway bind." << coin << " (" << tokenid.GetHex() << ") cant create globaladdr");
if ( (fullsupply=CCfullsupply(tokenid)) != totalsupply )
{
CCerror = strprintf("Gateway bind.%s (%s) globaladdr.%s totalsupply %.8f != fullsupply %.8f",coin.c_str(),uint256_str(str,tokenid),cp->unspendableCCaddr,(double)totalsupply/COIN,(double)fullsupply/COIN);
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "Gateway bind." << coin << " ("<< tokenid.GetHex() << ") globaladdr." <<cp->unspendableCCaddr << " totalsupply " << (double)totalsupply/COIN << " != fullsupply " << (double)fullsupply/COIN);
if ( CCtoken_balance(myTokenCCaddr,tokenid) != totalsupply )
{
CCerror = strprintf("token balance on %s %.8f != %.8f",myTokenCCaddr,(double)CCtoken_balance(myTokenCCaddr,tokenid)/COIN,(double)totalsupply/COIN);
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "token balance on " << myTokenCCaddr << " " << (double)CCtoken_balance((char *)myTokenCCaddr,tokenid)/COIN << "!=" << (double)totalsupply/COIN);
if ( myGetTransaction(oracletxid,oracletx,hashBlock) == 0 || (numvouts= oracletx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find oracletxid %s",uint256_str(str,oracletxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex());
if ( DecodeOraclesCreateOpRet(oracletx.vout[numvouts-1].scriptPubKey,name,description,format) != 'C' )
{
CCerror = strprintf("mismatched oracle name %s != %s",name.c_str(),coin.c_str());
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "mismatched oracle name " << name << " != " << coin);
if ( (fstr=(char *)format.c_str()) == 0 || strncmp(fstr,"Ihh",3) != 0 )
{
CCerror = strprintf("illegal format (%s) != (%s)",fstr,(char *)"Ihh");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "illegal format (" << fstr << ") != (Ihh)");
if ( GatewaysBindExists(cp,gatewayspk,tokenid) != 0 )
{
CCerror = strprintf("Gateway bind.%s (%s) already exists",coin.c_str(),uint256_str(str,tokenid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,2) > 0 )
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "Gateway bind." << coin << " (" << tokenid.GetHex() << ") already exists");
if ( AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,2,pk.IsValid()) > 0 )
{
if (AddTokenCCInputs(cpTokens, mtx, mypk, tokenid, totalsupply, 64)>0)
{
mtx.vout.push_back(MakeTokensCC1vout(cp->evalcode,totalsupply,gatewayspk));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CC_MARKER_VALUE,gatewayspk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysBindOpRet('B',tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeGatewaysBindOpRet('B',tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)));
}
}
CCerror = strprintf("cant find enough inputs");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find enough inputs");
}
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)
UniValue GatewaysDeposit(const CPubKey& pk, 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)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CTransaction bindtx; CPubKey mypk; uint256 oracletxid,merkleroot,mhash,hashBlock,tokenid,txid;
CTransaction tx; CPubKey mypk; uint256 oracletxid,merkleroot,mhash,hashBlock,tokenid,txid;
int64_t totalsupply; int32_t i,m,n,numvouts; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::string coin; struct CCcontract_info *cp,C;
std::vector<CPubKey> pubkeys,publishers; std::vector<uint256>txids; char str[67],depositaddr[64],txidaddr[64];
std::vector<CPubKey> pubkeys,publishers; std::vector<uint256>txids; char str[65],depositaddr[64],txidaddr[64];
cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "GatewaysDeposit ht." << height << " " << refcoin << " " << (double)amount/COIN << " numpks." << (int32_t)pubkeys.size() << std::endl);
if ( myGetTransaction(bindtxid,bindtx,hashBlock) == 0 || (numvouts= bindtx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( DecodeGatewaysBindOpRet(depositaddr,bindtx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin )
{
CCerror = strprintf("invalid coin - bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find bindtxid " << bindtxid.GetHex());
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin )
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid coin - bindtxid " << bindtxid.GetHex() << " coin." << coin);
if (komodo_txnotarizedconfirmed(bindtxid)==false)
{
CCerror = strprintf("gatewaysbind tx not yet confirmed/notarized");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewaysbind tx not yet confirmed/notarized");
n = (int32_t)pubkeys.size();
merkleroot = zeroid;
for (i=m=0; i<n; i++)
@@ -1017,141 +963,80 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
}
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "cointxid." << cointxid.GetHex() << " m." << m << " of n." << n << std::endl);
if ( merkleroot == zeroid || m < n/2 )
{
CCerror = strprintf("couldnt find merkleroot for ht.%d %s oracle.%s m.%d vs n.%d",height,coin.c_str(),uint256_str(str,oracletxid),m,n);
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "couldnt find merkleroot for ht." << height << " " << coin << " oracle." << oracletxid.GetHex() << " m." << m << " vs n." << n);
if ( CCCointxidExists("gatewayscc-1",cointxid) != 0 )
{
CCerror = strprintf("cointxid.%s already exists",uint256_str(str,cointxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cointxid." << cointxid.GetHex() << " already exists");
if ( GatewaysVerify(depositaddr,oracletxid,claimvout,coin,cointxid,deposithex,proof,merkleroot,destpub,taddr,prefix,prefix2) != amount )
{
CCerror = strprintf("deposittxid didnt validate");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( AddNormalinputs(mtx,mypk,txfee+2*CC_MARKER_VALUE,3) > 0 )
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "deposittxid didnt validate");
if ( AddNormalinputs(mtx,mypk,txfee+2*CC_MARKER_VALUE,3,pk.IsValid()) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CC_MARKER_VALUE,destpub));
mtx.vout.push_back(CTxOut(CC_MARKER_VALUE,CScript() << ParseHex(HexStr(CCtxidaddr(txidaddr,cointxid))) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysDepositOpRet('D',bindtxid,coin,publishers,txids,height,cointxid,claimvout,deposithex,proof,destpub,amount)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeGatewaysDepositOpRet('D',bindtxid,coin,publishers,txids,height,cointxid,claimvout,deposithex,proof,destpub,amount)));
}
CCerror = strprintf("cant find enough inputs");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find enough inputs");
}
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount)
UniValue GatewaysClaim(const CPubKey& pk, uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CTransaction tx; CPubKey mypk,gatewayspk,tmpdestpub; struct CCcontract_info *cp,C; uint8_t M,N,taddr,prefix,prefix2,wiftype;
std::string coin, deposithex; std::vector<CPubKey> msigpubkeys,publishers; int64_t totalsupply,depositamount,tmpamount,inputs,CCchange=0;
std::string coin, deposithex; std::vector<CPubKey> pubkeys,publishers; int64_t totalsupply,depositamount,tmpamount,inputs,CCchange=0;
int32_t numvouts,claimvout,height; std::vector<uint8_t> proof;
uint256 hashBlock,tokenid,oracletxid,tmptxid,cointxid; char str[65],depositaddr[64],coinaddr[64],destaddr[64]; std::vector<uint256> txids;
uint256 hashBlock,tokenid,oracletxid,tmptxid,cointxid; char depositaddr[64],coinaddr[64],destaddr[64]; std::vector<uint256> txids;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || coin != refcoin )
{
CCerror = strprintf("invalid coin - bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find bindtxid " << bindtxid.GetHex());
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin )
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid coin - bindtxid " << bindtxid.GetHex() << " coin." << coin);
if (komodo_txnotarizedconfirmed(bindtxid)==false)
{
CCerror = strprintf("gatewaysbind tx not yet confirmed/notarized");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewaysbind tx not yet confirmed/notarized");
if ( myGetTransaction(deposittxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find deposittxid %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find deposittxid " << bindtxid.GetHex());
if (DecodeGatewaysDepositOpRet(tx.vout[numvouts-1].scriptPubKey,tmptxid,coin,publishers,txids,height,cointxid,claimvout,deposithex,proof,tmpdestpub,tmpamount) != 'D' || coin != refcoin)
{
CCerror = strprintf("invalid coin - deposittxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid coin - deposittxid " << bindtxid.GetHex() << " coin." << coin);
if (komodo_txnotarizedconfirmed(deposittxid)==false)
{
CCerror = strprintf("gatewaysdeposit tx not yet confirmed/notarized");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewaysdeposit tx not yet confirmed/notarized");
if (tmpdestpub!=destpub)
{
CCerror = strprintf("different destination pubkey from desdeposit tx");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "different destination pubkey from desdeposit tx");
if ( (depositamount=GatewaysDepositval(tx,mypk)) != amount )
{
CCerror = strprintf("invalid Gateways deposittxid %s %.8f != %.8f",uint256_str(str,deposittxid),(double)depositamount/COIN,(double)amount/COIN);
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid Gateways deposittxid " << deposittxid.GetHex() << " " << (double)depositamount/COIN << " != " << (double)amount/COIN << ", remember claim must be done from destination pubkey from deposit tx!");
if ((inputs=AddGatewaysInputs(cp, mtx, gatewayspk, bindtxid, amount, 60)) > 0)
{
if ( inputs > amount ) CCchange = (inputs - amount);
mtx.vin.push_back(CTxIn(deposittxid,0,CScript()));
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS,amount,destpub));
if ( CCchange != 0 ) mtx.vout.push_back(MakeTokensCC1vout(EVAL_GATEWAYS,CCchange,gatewayspk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysClaimOpRet('C',tokenid,bindtxid,refcoin,deposittxid,destpub,amount)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeGatewaysClaimOpRet('C',tokenid,bindtxid,refcoin,deposittxid,destpub,amount)));
}
CCerror = strprintf("cant find enough tokens in gateways address for given amount");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find enough tokens in gateways address for given amount");
}
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount)
UniValue GatewaysWithdraw(const CPubKey& pk, uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CTransaction tx; CPubKey mypk,gatewayspk,signerpk; uint256 txid,tokenid,hashBlock,oracletxid,tmptokenid,tmpbindtxid,withdrawtxid; int32_t vout,numvouts;
int64_t nValue,totalsupply,inputs,CCchange=0,tmpamount; uint8_t funcid,K,M,N,taddr,prefix,prefix2,wiftype; std::string coin,hex;
std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64]; struct CCcontract_info *cp,C,*cpTokens,CTokens;
std::vector<CPubKey> pubkeys; char depositaddr[64],coinaddr[64]; struct CCcontract_info *cp,C,*cpTokens,CTokens;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_GATEWAYS);
cpTokens = CCinit(&CTokens,EVAL_TOKENS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp, 0);
if( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || coin != refcoin )
{
CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find bindtxid " << bindtxid.GetHex());
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin )
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid coin - bindtxid " << bindtxid.GetHex() << " coin." << coin);
if (komodo_txnotarizedconfirmed(bindtxid)==false)
{
CCerror = strprintf("gatewaysbind tx not yet confirmed/notarized");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewaysbind tx not yet confirmed/notarized");
_GetCCaddress(coinaddr,EVAL_GATEWAYS,gatewayspk);
SetCCunspents(unspentOutputs,coinaddr,true);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
@@ -1165,23 +1050,14 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
{
if (funcid=='W' && DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,tmpbindtxid,coin,withdrawpub,tmpamount)=='W'
&& refcoin==coin && tmptokenid==tokenid && tmpbindtxid==bindtxid)
{
CCerror = strprintf("unable to create withdraw, another withdraw pending");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "unable to create withdraw, another withdraw pending");
else if (funcid=='P' && DecodeGatewaysPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,hex)=='P' &&
myGetTransaction(withdrawtxid,tx,hashBlock)!=0 && (numvouts=tx.vout.size())>0 && DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,tmpbindtxid,coin,withdrawpub,tmpamount)=='W'
&& refcoin==coin && tmptokenid==tokenid && tmpbindtxid==bindtxid)
{
CCerror = strprintf("unable to create withdraw, another withdraw pending");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "unable to create withdraw, another withdraw pending");
}
}
if( AddNormalinputs(mtx, mypk, txfee+CC_MARKER_VALUE, 2) > 0 )
if( AddNormalinputs(mtx, mypk, txfee+CC_MARKER_VALUE, 2,pk.IsValid()) > 0 )
{
if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, tokenid, amount, 60)) > 0)
{
@@ -1189,286 +1065,159 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CC_MARKER_VALUE,gatewayspk));
mtx.vout.push_back(MakeTokensCC1vout(EVAL_GATEWAYS,amount,gatewayspk));
if ( CCchange != 0 ) mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, CCchange, mypk));
return(FinalizeCCTx(0, cpTokens, mtx, mypk, txfee,EncodeGatewaysWithdrawOpRet('W',tokenid,bindtxid,refcoin,withdrawpub,amount)));
return(FinalizeCCTxExt(pk.IsValid(),0, cpTokens, mtx, mypk, txfee,EncodeGatewaysWithdrawOpRet('W',tokenid,bindtxid,refcoin,withdrawpub,amount)));
}
else
{
CCerror = strprintf("not enough balance of tokens for withdraw");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "not enough balance of tokens for withdraw");
}
CCerror = strprintf("cant find enough normal inputs");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find enough normal inputs");
}
std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refcoin, std::string hex)
UniValue GatewaysPartialSign(const CPubKey& pk, uint64_t txfee,uint256 lasttxid,std::string refcoin, std::string hex)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,withdrawpub,signerpk,gatewayspk; struct CCcontract_info *cp,C; CTransaction tx,tmptx;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; char funcid,str[65],depositaddr[64];
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; char funcid,depositaddr[64];
int32_t numvouts; uint256 withdrawtxid,hashBlock,bindtxid,tokenid,oracletxid,tmptokenid; std::string coin,tmphex; int64_t amount,totalsupply;
uint8_t K=0,M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> pubkeys;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
if (myGetTransaction(lasttxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())<=0
|| (funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))==0 || (funcid!='W' && funcid!='P'))
{
CCerror = strprintf("can't find last tx %s",uint256_str(str,lasttxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find last tx " << lasttxid.GetHex());
if (funcid=='W')
{
withdrawtxid=lasttxid;
if (DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin)
{
CCerror = strprintf("invalid withdraw tx %s",uint256_str(str,lasttxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw tx " << lasttxid.GetHex());
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
{
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayswithdraw tx not yet confirmed/notarized");
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find bind tx " << bindtxid.GetHex());
else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|| refcoin!=coin || tokenid!=tmptokenid)
{
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid bind tx " << bindtxid.GetHex());
}
else if (funcid=='P')
{
if (DecodeGatewaysPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,tmphex)!='P' || refcoin!=coin)
{
CCerror = strprintf("cannot decode partialsign tx opret %s",uint256_str(str,lasttxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cannot decode partialsign tx opret " << lasttxid.GetHex());
else if (myGetTransaction(withdrawtxid,tmptx,hashBlock)==0 || (numvouts= tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find withdraw tx %s",uint256_str(str,withdrawtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find withdraw tx " << withdrawtxid.GetHex());
else if (DecodeGatewaysWithdrawOpRet(tmptx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W'
|| refcoin!=coin)
{
CCerror = strprintf("invalid withdraw tx %s",uint256_str(str,lasttxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw tx " << withdrawtxid.GetHex());
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
{
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayswithdraw tx not yet confirmed/notarized");
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find bind tx " << bindtxid.GetHex());
else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|| refcoin!=coin || tokenid!=tmptokenid)
{
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid bind tx " << bindtxid.GetHex());
}
if (AddNormalinputs(mtx,mypk,txfee,1)!=0)
if (AddNormalinputs(mtx,mypk,txfee,1,pk.IsValid())!=0)
{
mtx.vin.push_back(CTxIn(tx.GetHash(),0,CScript()));
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CC_MARKER_VALUE,gatewayspk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysPartialOpRet('P',withdrawtxid,refcoin,K+1,mypk,hex)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeGatewaysPartialOpRet('P',withdrawtxid,refcoin,K+1,mypk,hex)));
}
CCerror = strprintf("error adding funds for partialsign");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "error adding funds for partialsign");
}
std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string refcoin,std::string hex)
UniValue GatewaysCompleteSigning(const CPubKey& pk, uint64_t txfee,uint256 lasttxid,std::string refcoin,std::string hex)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,gatewayspk,signerpk,withdrawpub; struct CCcontract_info *cp,C; char funcid,str[65],depositaddr[64]; int64_t amount,totalsupply;
CPubKey mypk,gatewayspk,signerpk,withdrawpub; struct CCcontract_info *cp,C; char funcid,depositaddr[64]; int64_t amount,totalsupply;
std::string coin,tmphex; CTransaction tx,tmptx; uint256 withdrawtxid,hashBlock,tokenid,tmptokenid,bindtxid,oracletxid; int32_t numvouts;
uint8_t K=0,M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> pubkeys;
cp = CCinit(&C,EVAL_GATEWAYS);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
if ( txfee == 0 )
txfee = 10000;
if (myGetTransaction(lasttxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())<=0
|| (funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))==0 || (funcid!='W' && funcid!='P'))
{
CCerror = strprintf("invalid last txid %s",uint256_str(str,lasttxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid last txid " << lasttxid.GetHex());
if (funcid=='W')
{
withdrawtxid=lasttxid;
if (DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin)
{
CCerror = strprintf("cannot decode withdraw tx opret %s",uint256_str(str,lasttxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw tx " << lasttxid.GetHex());
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
{
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayswithdraw tx not yet confirmed/notarized");
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find bind tx " << bindtxid.GetHex());
else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|| refcoin!=coin || tokenid!=tmptokenid)
{
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid bind tx " << bindtxid.GetHex());
}
else if (funcid=='P')
{
if (DecodeGatewaysPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,tmphex)!='P' || refcoin!=coin)
{
CCerror = strprintf("cannot decode partialsign tx opret %s",uint256_str(str,lasttxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (myGetTransaction(withdrawtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())==0)
{
CCerror = strprintf("invalid withdraw txid %s",uint256_str(str,withdrawtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (DecodeGatewaysWithdrawOpRet(tmptx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin)
{
CCerror = strprintf("cannot decode withdraw tx opret %s",uint256_str(str,withdrawtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if (DecodeGatewaysPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,tmphex)!='P' || refcoin!=coin)
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cannot decode partialsign tx opret " << lasttxid.GetHex());
else if (myGetTransaction(withdrawtxid,tmptx,hashBlock)==0 || (numvouts= tmptx.vout.size())<=0)
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find withdraw tx " << withdrawtxid.GetHex());
else if (DecodeGatewaysWithdrawOpRet(tmptx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W'
|| refcoin!=coin)
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw tx " << withdrawtxid.GetHex());
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
{
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayswithdraw tx not yet confirmed/notarized");
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find bind tx " << bindtxid.GetHex());
else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|| refcoin!=coin || tokenid!=tmptokenid)
{
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid bind tx " << bindtxid.GetHex());
}
if (AddNormalinputs(mtx,mypk,txfee,1)!=0)
if (AddNormalinputs(mtx,mypk,txfee,1,pk.IsValid())!=0)
{
mtx.vin.push_back(CTxIn(lasttxid,0,CScript()));
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CC_MARKER_VALUE,gatewayspk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysCompleteSigningOpRet('S',withdrawtxid,refcoin,K+1,hex)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeGatewaysCompleteSigningOpRet('S',withdrawtxid,refcoin,K+1,hex)));
}
CCerror = strprintf("error adding funds for completesigning");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "error adding funds for completesigning");
}
std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string refcoin)
UniValue GatewaysMarkDone(const CPubKey& pk, uint64_t txfee,uint256 completetxid,std::string refcoin)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk; struct CCcontract_info *cp,C; char str[65],depositaddr[64]; CTransaction tx; int32_t numvouts;
CPubKey mypk; struct CCcontract_info *cp,C; char depositaddr[64]; CTransaction tx; int32_t numvouts;
uint256 withdrawtxid,bindtxid,oracletxid,tokenid,tmptokenid,hashBlock; std::string coin,hex;
uint8_t K,M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> pubkeys; int64_t amount,totalsupply; CPubKey withdrawpub;
cp = CCinit(&C,EVAL_GATEWAYS);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
if ( txfee == 0 )
txfee = 10000;
if (myGetTransaction(completetxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())<=0)
{
CCerror = strprintf("invalid completesigning txid %s",uint256_str(str,completetxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid completesigning txid " << completetxid.GetHex());
else if (DecodeGatewaysCompleteSigningOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,hex)!='S' || refcoin!=coin)
{
CCerror = strprintf("cannot decode completesigning tx opret %s",uint256_str(str,completetxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cannot decode completesigning tx opret " << completetxid.GetHex());
if (komodo_txnotarizedconfirmed(completetxid)==false)
{
CCerror = strprintf("gatewayscompletesigning tx not yet confirmed/notarized");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayscompletesigning tx not yet confirmed/notarized");
else if (myGetTransaction(withdrawtxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())==0)
{
CCerror = strprintf("invalid withdraw txid %s",uint256_str(str,withdrawtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw txid " << withdrawtxid.GetHex());
else if (DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin)
{
CCerror = strprintf("cannot decode withdraw tx opret %s\n",uint256_str(str,withdrawtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cannot decode withdraw tx opret " << withdrawtxid.GetHex());
else if (myGetTransaction(bindtxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find bind tx " << bindtxid.GetHex());
else if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|| refcoin!=coin || tokenid!=tmptokenid)
{
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if (AddNormalinputs(mtx,mypk,txfee,1)!=0)
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid bind tx " << bindtxid.GetHex());
if (AddNormalinputs(mtx,mypk,txfee,1,pk.IsValid())!=0)
{
mtx.vin.push_back(CTxIn(completetxid,0,CScript()));
mtx.vout.push_back(CTxOut(CC_MARKER_VALUE,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysMarkDoneOpRet('M',withdrawtxid,refcoin,completetxid)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeGatewaysMarkDoneOpRet('M',withdrawtxid,refcoin,completetxid)));
}
CCerror = strprintf("error adding funds for markdone");
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "error adding funds for markdone");
}
UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin)
UniValue GatewaysPendingDeposits(const CPubKey& pk, uint256 bindtxid,std::string refcoin)
{
UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,hex,pub;
CPubKey mypk,gatewayspk,destpub; std::vector<CPubKey> pubkeys,publishers; std::vector<uint256> txids;
@@ -1478,7 +1227,7 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin)
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_GATEWAYS);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_GATEWAYS,mypk);
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
@@ -1523,7 +1272,7 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin)
return(result);
}
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
UniValue GatewaysPendingWithdraws(const CPubKey& pk, uint256 bindtxid,std::string refcoin)
{
UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,hex; CPubKey mypk,gatewayspk,withdrawpub,signerpk;
std::vector<CPubKey> msigpubkeys; uint256 hashBlock,tokenid,txid,tmpbindtxid,tmptokenid,oracletxid,withdrawtxid; uint8_t K,M,N,taddr,prefix,prefix2,wiftype;
@@ -1532,7 +1281,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_GATEWAYS);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_GATEWAYS,gatewayspk);
GetTokensCCaddress(cp,tokensaddr,gatewayspk);
@@ -1611,7 +1360,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
return(result);
}
UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin)
UniValue GatewaysProcessedWithdraws(const CPubKey& pk, uint256 bindtxid,std::string refcoin)
{
UniValue result(UniValue::VOBJ),processed(UniValue::VARR); CTransaction tx; std::string coin,hex;
CPubKey mypk,gatewayspk,withdrawpub; std::vector<CPubKey> msigpubkeys;
@@ -1621,7 +1370,7 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin)
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_GATEWAYS);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_GATEWAYS,gatewayspk);
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )

View File

@@ -628,72 +628,79 @@ template <typename Helper> UniValue _HeirFund(int64_t txfee, int64_t amount, std
CPubKey myPubkey = pubkey2pk(Mypubkey());
if (AddNormalinputs(mtx, myPubkey, markerfee, 3) > 0) {
int64_t inputs, change;
if ((inputs=Helper::addOwnerInputs(tokenid, mtx, myPubkey, amount, (int32_t)64)) > 0) {
mtx.vout.push_back(Helper::make1of2Vout(amount, myPubkey, heirPubkey));
// add a marker for finding all plans in HeirList()
// TODO: change marker either to cc or normal txidaddr unspendable
struct CCcontract_info *cpHeir, heirC;
cpHeir = CCinit(&heirC, EVAL_HEIR);
CPubKey heirUnspendablePubKey = GetUnspendable(cpHeir, 0);
// mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(heirUnspendablePubKey)) << OP_CHECKSIG)); <-- bad marker cause it was spendable by anyone
mtx.vout.push_back(MakeCC1vout(EVAL_HEIR, markerfee, heirUnspendablePubKey)); // this marker spending is disabled in the validation code
// calc and add change vout:
if (inputs > amount)
change = (inputs - amount); // -txfee <-- txfee pays user
//std::cerr << "HeirFund() inputs=" << inputs << " amount=" << amount << " txfee=" << txfee << " change=" << change << '\n';
if (change != 0) { // vout[1]
mtx.vout.push_back(Helper::makeUserVout(change, myPubkey));
}
// check owner pubkey in vins
bool hasMypubkey = false;
bool hasNotMypubkey = false;
CheckVinPubkey(mtx.vin, myPubkey, hasMypubkey, hasNotMypubkey);
// for initial funding do not allow to sign by non-owner key:
if (hasNotMypubkey) {
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "using non-owner inputs not allowed"));
return result;
}
// add 1of2 vout validation pubkeys:
std::vector<CPubKey> voutTokenPubkeys;
voutTokenPubkeys.push_back(myPubkey);
voutTokenPubkeys.push_back(heirPubkey);
// add change for txfee and opreturn vouts and sign tx:
std::string rawhextx = FinalizeCCTx(0, cp, mtx, myPubkey, txfee,
Helper::makeCreateOpRet(tokenid, voutTokenPubkeys, myPubkey, heirPubkey, inactivityTimeSec, heirName, memo));
if (!rawhextx.empty()) {
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", rawhextx));
}
else {
std::cerr << "HeirAdd error in FinalizeCCtx" << std::endl;
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "sign error"));
}
}
else { // TODO: need result return unification with heiradd and claim
std::cerr << "HeirFund() could not find owner cc inputs" << std::endl;
if (!tokenid.IsNull()) // add normals only for tokens
{
if (AddNormalinputs(mtx, myPubkey, txfee + markerfee, 4) < txfee + markerfee)
{
std::cerr << "HeirFund() could not find normal inputs for txfee" << std::endl;
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "could not find owner cc inputs"));
result.push_back(Pair("error", "could not find normal inputs for txfee"));
return result;
}
}
else {
std::cerr << "HeirFund() could not find normal inputs" << std::endl;
int64_t inputs;
int64_t addAmount = tokenid.IsNull() ? (txfee + markerfee + amount) : amount; // for coins add txfee markerfee amount in one call
if ((inputs=Helper::addOwnerInputs(tokenid, mtx, myPubkey, addAmount, (int32_t)64)) >= addAmount)
{
mtx.vout.push_back(Helper::make1of2Vout(amount, myPubkey, heirPubkey));
// add a marker for finding all plans in HeirList()
// TODO: change marker either to cc or normal txidaddr unspendable
struct CCcontract_info *cpHeir, heirC;
cpHeir = CCinit(&heirC, EVAL_HEIR);
CPubKey heirUnspendablePubKey = GetUnspendable(cpHeir, 0);
// mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(heirUnspendablePubKey)) << OP_CHECKSIG)); <-- bad marker cause it was spendable by anyone
mtx.vout.push_back(MakeCC1vout(EVAL_HEIR, markerfee, heirUnspendablePubKey)); // this marker spending is disabled in the validation code
if (!tokenid.IsNull())
{
int64_t ccChange = 0;
// calc and add token change vout:
if (inputs > amount)
ccChange = (inputs - amount); // -txfee <-- txfee pays user
//std::cerr << "HeirFund() inputs=" << inputs << " amount=" << amount << " txfee=" << txfee << " change=" << change << '\n';
if (ccChange != 0)
mtx.vout.push_back(Helper::makeUserVout(ccChange, myPubkey));
}
// check owner pubkey in vins
bool hasMypubkey = false;
bool hasNotMypubkey = false;
CheckVinPubkey(mtx.vin, myPubkey, hasMypubkey, hasNotMypubkey);
// for initial funding do not allow to sign by non-owner key:
if (hasNotMypubkey) {
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "using non-owner inputs not allowed"));
return result;
}
// add 1of2 vout token validation pubkeys - used only for tokens
std::vector<CPubKey> voutTokenPubkeys;
voutTokenPubkeys.push_back(myPubkey);
voutTokenPubkeys.push_back(heirPubkey);
// add change for txfee and opreturn vouts and sign tx:
std::string rawhextx = FinalizeCCTx(0, cp, mtx, myPubkey, txfee,
Helper::makeCreateOpRet(tokenid, voutTokenPubkeys, myPubkey, heirPubkey, inactivityTimeSec, heirName, memo));
if (!rawhextx.empty()) {
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", rawhextx));
}
else {
std::cerr << "HeirAdd error in FinalizeCCtx" << std::endl;
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "sign error"));
}
}
else { // TODO: need result return unification with heiradd and claim
std::cerr << "HeirFund() could not find owner inputs for amount (normal inputs for coins, cc inputs for tokens)" << std::endl;
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "could not find normal inputs"));
result.push_back(Pair("error", "could not find owner inputs"));
}
return result;
}
@@ -716,7 +723,6 @@ template <class Helper> UniValue _HeirAdd(uint256 fundingtxid, int64_t txfee, in
{
UniValue result(UniValue::VOBJ);
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
int64_t inputs, CCchange = 0;
struct CCcontract_info *cp, C;
std::string rawhex;
@@ -736,89 +742,93 @@ template <class Helper> UniValue _HeirAdd(uint256 fundingtxid, int64_t txfee, in
return result;
}
if (AddNormalinputs(mtx, myPubkey, markerfee, 3) > 0) { // some for marker
int64_t inputs, change;
if ((inputs = Helper::addOwnerInputs(tokenid, mtx, myPubkey, amount, 64)) > 0) { // TODO: why 64 max inputs?
// we do not use markers anymore - storing data in opreturn is better
// add marker vout:
/* char markeraddr[64];
CPubKey markerpubkey = CCtxidaddr(markeraddr, fundingtxid);
mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG)); // txfee 1, txfee 2 - for miners
std::cerr << "HeirAdd() adding markeraddr=" << markeraddr << '\n'; */
// add cryptocondition to spend this funded amount for either pk
mtx.vout.push_back(Helper::make1of2Vout(amount, ownerPubkey, heirPubkey));
if (!tokenid.IsNull()) // add normals only for tokens
{
if (AddNormalinputs(mtx, myPubkey, txfee + markerfee, 4) < txfee + markerfee)
{
std::cerr << "HeirFund() could not find normal inputs for txfee" << std::endl;
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "could not find normal inputs for txfee"));
return result;
}
}
char markeraddr[64];
CPubKey markerPubkey = CCtxidaddr(markeraddr, fundingtxid);
mtx.vout.push_back(CTxOut(markerfee, CScript() << ParseHex(HexStr(markerPubkey)) << OP_CHECKSIG)); // marker to prevent archiving of the funds add vouts
int64_t inputs;
int64_t addAmount = tokenid.IsNull() ? (txfee + markerfee + amount) : amount; // for coins add txfee markerfee amount in one call
if ((inputs = Helper::addOwnerInputs(tokenid, mtx, myPubkey, addAmount, 64)) >= addAmount) { // TODO: why 64 max inputs?
// we do not use markers anymore - storing data in opreturn is better
// add marker vout:
/* char markeraddr[64];
CPubKey markerpubkey = CCtxidaddr(markeraddr, fundingtxid);
mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG)); // txfee 1, txfee 2 - for miners
std::cerr << "HeirAdd() adding markeraddr=" << markeraddr << '\n'; */
// add cryptocondition to spend this funded amount for either pk
mtx.vout.push_back(Helper::make1of2Vout(amount, ownerPubkey, heirPubkey));
char markeraddr[64];
CPubKey markerPubkey = CCtxidaddr(markeraddr, fundingtxid);
mtx.vout.push_back(CTxOut(markerfee, CScript() << ParseHex(HexStr(markerPubkey)) << OP_CHECKSIG)); // marker to prevent archiving of the funds add vouts
if (!tokenid.IsNull())
{
int64_t ccChange = 0;
if (inputs > amount)
change = (inputs - amount); // -txfee <-- txfee pays user
ccChange = (inputs - amount); // -txfee <-- txfee pays user
//std::cerr << "HeirAdd() inputs=" << inputs << " amount=" << amount << " txfee=" << txfee << " change=" << change << '\n';
if (change != 0) { // vout[1]
mtx.vout.push_back(Helper::makeUserVout(change, myPubkey));
}
// check owner pubkey in vins
bool hasMypubkey = false;
bool hasNotMypubkey = false;
CheckVinPubkey(mtx.vin, myPubkey, hasMypubkey, hasNotMypubkey);
// for additional funding do not allow to sign by both owner and non-owner keys (is this a donation or not?):
if (hasMypubkey && hasNotMypubkey) {
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "using both owner and non-owner inputs is not allowed"));
return result;
}
// warn the user he's making a donation if this is all non-owner keys:
if (hasNotMypubkey) {
result.push_back(Pair("result", "warning"));
result.push_back(Pair("warning", "you are about to make a donation to heir fund"));
}
else {
result.push_back(Pair("result", "success"));
}
// add 1of2 vout validation pubkeys - needed only for tokens:
std::vector<CPubKey> voutTokenPubkeys;
voutTokenPubkeys.push_back(ownerPubkey);
voutTokenPubkeys.push_back(heirPubkey);
// add opreturn 'A' and sign tx: // this txfee ignored
std::string rawhextx = (FinalizeCCTx(0, cp, mtx, myPubkey, txfee,
Helper::makeAddOpRet(tokenid, voutTokenPubkeys, fundingtxid, hasHeirSpendingBegun)));
if (!rawhextx.empty()) {
result.push_back(Pair("hex", rawhextx));
}
else {
std::cerr << "HeirAdd error in FinalizeCCtx" << std::endl;
result.clear();
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "sign error"));
}
if (ccChange != 0)
mtx.vout.push_back(Helper::makeUserVout(ccChange, myPubkey));
}
else {
std::cerr << "HeirAdd cannot find owner cc inputs" << std::endl;
// check owner pubkey in vins
bool hasMypubkey = false;
bool hasNotMypubkey = false;
CheckVinPubkey(mtx.vin, myPubkey, hasMypubkey, hasNotMypubkey);
// for additional funding do not allow to sign by both owner and non-owner keys (is this a donation or not?):
if (hasMypubkey && hasNotMypubkey) {
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "using both owner and non-owner inputs is not allowed"));
return result;
}
// warn the user he's making a donation if this is all non-owner keys:
if (hasNotMypubkey) {
result.push_back(Pair("result", "warning"));
result.push_back(Pair("warning", "you are about to make a donation to heir fund"));
}
else {
result.push_back(Pair("result", "success"));
}
// add 1of2 vout validation pubkeys - needed only for tokens:
std::vector<CPubKey> voutTokenPubkeys;
voutTokenPubkeys.push_back(ownerPubkey);
voutTokenPubkeys.push_back(heirPubkey);
// add opreturn 'A' and sign tx:
std::string rawhextx = (FinalizeCCTx(0, cp, mtx, myPubkey, txfee,
Helper::makeAddOpRet(tokenid, voutTokenPubkeys, fundingtxid, hasHeirSpendingBegun)));
if (!rawhextx.empty()) {
result.push_back(Pair("hex", rawhextx));
}
else {
std::cerr << "HeirAdd error in FinalizeCCtx" << std::endl;
result.clear();
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "can't find owner cc inputs"));
result.push_back(Pair("error", "sign error"));
}
}
else {
std::cerr << "HeirAdd cannot find normal inputs for tx fee" << std::endl;
std::cerr << "HeirAdd cannot find owner inputs for amount (normal inputs for coins, cc inputs for tokens)" << std::endl;
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "can't find normal inputs for tx fee"));
}
result.push_back(Pair("error", "can't find owner inputs"));
}
return result;
}
@@ -833,10 +843,12 @@ UniValue HeirAddCaller(uint256 fundingtxid, int64_t txfee, std::string strAmount
std::string heirName, memo;
uint8_t hasHeirSpendingBegun = 0;
if ((latesttxid = FindLatestFundingTx(fundingtxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo, hasHeirSpendingBegun)) != zeroid) {
// get latest tx to see if it is a token or coin
if ((latesttxid = FindLatestFundingTx(fundingtxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo, hasHeirSpendingBegun)) != zeroid)
{
if (tokenid == zeroid) {
int64_t amount = (int64_t)(atof(strAmount.c_str()) * COIN);
if (amount <= 0) {
int64_t amount = 0;
if (!ParseFixedPoint(strAmount, 8, &amount) || amount <= 0 ) {
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "invalid amount"));
@@ -844,7 +856,8 @@ UniValue HeirAddCaller(uint256 fundingtxid, int64_t txfee, std::string strAmount
}
return _HeirAdd<CoinHelper>(fundingtxid, txfee, amount, latesttxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, hasHeirSpendingBegun);
}
else {
else
{
int64_t amount = atoll(strAmount.c_str());
if (amount <= 0) {
UniValue result(UniValue::VOBJ);
@@ -1003,15 +1016,18 @@ UniValue HeirClaimCaller(uint256 fundingtxid, int64_t txfee, std::string strAmou
std::string heirName, memo;
uint8_t hasHeirSpendingBegun = 0;
if ((latesttxid = FindLatestFundingTx(fundingtxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo, hasHeirSpendingBegun)) != zeroid) {
if (tokenid == zeroid) {
int64_t amount = (int64_t)(atof(strAmount.c_str()) * COIN);
if (amount < 0) {
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "invalid amount"));
return result;
}
// find latest tx to see if it is a token or coin:
if ((latesttxid = FindLatestFundingTx(fundingtxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo, hasHeirSpendingBegun)) != zeroid)
{
if (tokenid == zeroid)
{
int64_t amount = 0;
if (!ParseFixedPoint(strAmount, 8, &amount) || amount <= 0) { // using ParseFixedPoint instead atof to avoid round errors
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "invalid amount"));
return result;
}
return _HeirClaim<CoinHelper>(fundingtxid, txfee, amount, latesttxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, hasHeirSpendingBegun);
}
else {

View File

@@ -1,65 +0,0 @@
How this works:
- earlytxid must be a transaction included in the chain before block KOMODO_EARLYTXID_HEIGHT. The chain MUST not have any other of these type of tx before block KOMODO_EARLYTXID_HEIGHT, or someone may be able to change it and mess things up.
- When it gets to block KOMODO_EARLYTXID_HEIGHT, it takes the txid specified by the -earlytxid param (does not affect magic)
- Looks up the transaction searches for the opreturn, then permenantly appends it to the end of ac_script in RAM.
- After every daemon restart, the first time the daemon mines a block, or receives a block that pays ac_script it will look up the op_return and save it again.
- this enables it to always reach consensus but doesnt need to constantly keep looking up the tx in the chain.
- The trick is to use ac_founders=101 or higher so that nothing is ever paid to the unspendable CC address. Although it should still work without this it burns coins.
-ac_script can be any Global CC address you can spend to with an OP_RETURN. Here we use example of paymentsCC being used to fund a rewards plan, and a set of founders address's.
you can get the ac_script from another chain, but the op_return payload must generated on the chain itself. this command gives you the needed info to get the scripPubKey Hex:
./komodo-cli -ac_name=TEST paymentsfund '["5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682",1000]'
append: b8, to the end of ac_script, this changes magic value for -earlytxid chains vs normal ac_script and allows bypass of ac_supply paid to the scritpt as it would be unspendable and you would be unable to create the needed plans with no coins.
-ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8
-testnode=1 is not affecting magic and allows mining on a single node, we can use this to bootstrap the chain before syncing a second node to save time.
start chain and make sure to do the following steps before block 100 (set generate false/true is a good idea between steps)
./komodod -ac_name=TESTHC -ac_supply=1000000 -ac_reward=100000000000 -ac_cc=2 -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 -ac_founders=150 -ac_blocktime=20 -ac_nk=96,5 -testnode=1
create rewards plan and fund it with all or a % of the premine. Must be some amount. eg.
./komodo-cli -ac_name=TESTHC rewardscreatefunding test 50000 25 0 2 500
do rewards add funding:
./komodo-cli -ac_name=TESTHC rewardsaddfunding test 47a3150150bd196bd2086cae5e0c6b01a23785a04139fa660d169121a534b38e 1000
and get the script pubkey and op_return from this tx (no need to send it)
./komodo-cli -ac_name=TESTHC decoderawtransaction 010000000204ca4c7aaae62bb8fc9412ac010e047fa8d33c3f87d2adeb3e02170642ddfe370000000049483045022100d7b9a
4f28ca3a35f34dcdb6075e905cde1eaa962bd0619d0a8ed8e17e952bc99022077308e12325fc2a02c752ec3df9aeee1fc219ea54a4d3884834582b75c89815e01ffffffff08800132da3233d80c65e87b6db6a76dcf
188e4fdfa23198d69f647e67754cfb0000000049483045022100d6a8f7a1c4f6013f5897768ae0117fe61dfb72352d3e6652e64a6588db3ffcb102202aa1d041b24f9cbbf7028295b7c5e7f18b4f95ae39c13031dab
7f06634438e6801ffffffff0300e8764817000000302ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401ccf0c0764817000000232103bbec93af84
0933ae2d35fc56eff24f34dbe26871402552f84c44f690945ccd79ac00000000000000002c6a2ae54174657374000000008eb334a52191160d66fa3941a08537a2016b0c5eae6c08d26b19bd500115a34700000000
From the return of this you need the scriptpubkey hex of vout 0:
scriptPubKey: 2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc
and the scriptpubkey hex of the OP_RETURN in vout 2.
OP_RETURN: 6a2ae54174657374000000008eb334a52191160d66fa3941a08537a2016b0c5eae6c08d26b19bd500115a347
create txidopreturn for this payment:
./komodo-cli -ac_name=TESTHC paymentstxidopret '[50,"2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc","6a2ae54174657374000000008eb334a52191160d66fa3941a08537a2016b0c5eae6c08d26b19bd500115a347"]'
create the txidopret for the founders reward(s) pubkeys: should be able to be a few here, not sure of max number yet. These can pay anything that does not need an opreturn. allocation and scriptpubkey hex.
./komodo-cli -ac_name=TESTHC paymentstxidopret '[50,"76a9146bf5dd9f679c87a3f83ea176f82148d26653c04388ac"]'
create payments plan:
./komodo-cli -ac_name=TESTHC paymentscreate '[0,0,"61f55f2f87dad3a37d42731a8cb73b3ebea1817abfa176218162c360a8bd7145","0550014823ffa0aa99d7dd7ca5292f4dd0a1b9156eddec03412c953f095181bc"]'
gives plan txid: ee7765be874fb084c00538b1b0488e8ecb857de253f09a9ba6ea8d3579b77d33
paymentsfund:
To do this you first need to change the type of tx generated by paymentsfund RPC. in payments.cpp go to line: 639 and comment it out, then uncomment the block of code under this.
change the line 646 to line 647 with comments, and line 650/651 aswell. This enables the RPC to generate the ccvout opreturn payload you need without sending the payment on the chain. Just decode the raw hex.
./komodo-cli -ac_name=TESTHC paymentsfund '["ee7765be874fb084c00538b1b0488e8ecb857de253f09a9ba6ea8d3579b77d33",1000,1]'
get the payment fund scriptpubkey hex from vout 0: (the split it at OP_CHECKCRYPTOCONDITION or 'cc' )
2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401cc 2a0401f00101246a22f046337db779358deaa69b9af053e27d85cb8e8e48b0b13805c084b04f87be6577ee75
put the second half into an OP_RETURN: (the remaining part of the the above scriptpubkey) eg.
./komodo-cli -ac_name=TESTHC opreturn_burn 1 2a0401f00101246a22f046337db779358deaa69b9af053e27d85cb8e8e48b0b13805c084b04f87be6577ee75
opret_burn takes any burn amount and arbitrary hex string. (RPC works, but may have bugs, likely use this for LABS too with some fixes)
this gives a raw hex. Decode it and check the OP_RETURN is right before sending.
-earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce
restart the chain with earlytxid param before height 100 on all nodes (if not using -testnode=1)
./komodod -ac_name=TESTHC -ac_supply=1000000 -ac_reward=100000000000 -ac_cc=2 -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 -ac_founders=150 -ac_blocktime=20 -ac_nk=96,5 -earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce
once the payments plan has been funded with the mined coinbase you can issue payments release when conditions of the plan are met to fund founders reward/rewards plan. eg.
./komodo-cli -ac_name=TESTHC paymentsrelease '["ee7765be874fb084c00538b1b0488e8ecb857de253f09a9ba6ea8d3579b77d33",500]'

View File

@@ -1,4 +1,6 @@
#!/bin/sh
#!/bin/bash
# Copyright (c) 2019 The Hush developers
rm *.so rogue/rogue games/tetris games/prices
echo rogue

File diff suppressed because it is too large Load Diff

View File

@@ -639,15 +639,15 @@ bool OraclesDataValidate(struct CCcontract_info *cp,Eval* eval,const CTransactio
else return(true);
}
int32_t GetLatestTimestamp(int32_t height)
/*nt32_t GetLatestTimestamp(int32_t height)
{
if ( KOMODO_NSPV_SUPERLITE ) return (NSPV_blocktime(height));
return(komodo_heightstamp(height));
}
} */
bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
{
uint256 oracletxid,batontxid; uint64_t txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts; int64_t amount; uint256 hashblock;
uint256 oracletxid,batontxid,txid; uint64_t txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts; int64_t amount; uint256 hashblock;
uint8_t *script; std::vector<uint8_t> vopret,data; CPubKey publisher,tmppk,oraclespk; char tmpaddress[64],vinaddress[64],oraclesaddr[64];
CTransaction tmptx; std::string name,desc,format;
@@ -702,10 +702,16 @@ bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
return eval->Invalid("invalid marker for oraclescreate!");
else if ( IsCCInput(tx.vin[0].scriptSig) != 0 )
return eval->Invalid("vin.0 is normal for oraclesregister!");
else if ((*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 0 || myGetTransaction(tx.vin[tx.vin.size()-1].prevout.hash,tmptx,hashblock)==0
else if ((*cp->ismyvin)(tx.vin[1].scriptSig) == 0 && (*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 0)
return eval->Invalid("there is no CC vin from oraclesfund tx");
else if ((*cp->ismyvin)(tx.vin[1].scriptSig) == 1 && (myGetTransaction(tx.vin[1].prevout.hash,tmptx,hashblock)==0 || DecodeOraclesOpRet(tmptx.vout[tmptx.vout.size()-1].scriptPubKey,txid,tmppk,amount)!='F'
|| tmptx.vout[tx.vin[1].prevout.n].nValue!=CC_MARKER_VALUE || !Getscriptaddress(vinaddress,tmptx.vout[tx.vin[1].prevout.n].scriptPubKey)
|| !GetCCaddress(cp,tmpaddress,tmppk) || strcmp(tmpaddress,vinaddress)!=0) || oracletxid!=txid)
return eval->Invalid("invalid vin.1 for oraclesregister, it must be CC vin or pubkey not same as vin pubkey, register and fund tx must be done from owner of pubkey that registers to oracle!!");
else if ((*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 1 && (myGetTransaction(tx.vin[tx.vin.size()-1].prevout.hash,tmptx,hashblock)==0 || DecodeOraclesOpRet(tmptx.vout[tmptx.vout.size()-1].scriptPubKey,txid,tmppk,amount)!='F'
|| tmptx.vout[tx.vin[tx.vin.size()-1].prevout.n].nValue!=CC_MARKER_VALUE || !Getscriptaddress(vinaddress,tmptx.vout[tx.vin[tx.vin.size()-1].prevout.n].scriptPubKey)
|| !GetCCaddress(cp,tmpaddress,tmppk) || strcmp(tmpaddress,vinaddress)!=0)
return eval->Invalid("vin."+std::to_string(tx.vin.size()-1)+" is CC for oraclesregister or pubkey not same as vin pubkey, register must be done from owner of pubkey that registers to oracle!!");
|| !GetCCaddress(cp,tmpaddress,tmppk) || strcmp(tmpaddress,vinaddress)!=0) || oracletxid!=txid)
return eval->Invalid("invalid vin."+std::to_string(tx.vin.size()-1)+" for oraclesregister, it must be CC vin or pubkey not same as vin pubkey, register and fund tx must be done from owner of pubkey that registers to oracle!!");
else if (CCtxidaddr(tmpaddress,oracletxid).IsValid() && ConstrainVout(tx.vout[0],0,tmpaddress,txfee)==0)
return eval->Invalid("invalid marker for oraclesregister!");
else if (!Getscriptaddress(tmpaddress,CScript() << ParseHex(HexStr(tmppk)) << OP_CHECKSIG) || ConstrainVout(tx.vout[2],0,tmpaddress,CC_MARKER_VALUE)==0)
@@ -851,18 +857,20 @@ int64_t AddMyOraclesFunds(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
return (0);
}
std::string OracleCreate(int64_t txfee,std::string name,std::string description,std::string format)
UniValue OracleCreate(const CPubKey& pk, int64_t txfee,std::string name,std::string description,std::string format)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C; char fmt;
CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C; char fmt;
cp = CCinit(&C,EVAL_ORACLES);
if ( name.size() > 32 || description.size() > 4096 || format.size() > 4096 )
{
CCerror = strprintf("name.%d or description.%d is too big",(int32_t)name.size(),(int32_t)description.size());
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
if ( name.size() > 32)
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "name."<< (int32_t)name.size() << " must be less then 32");
if (description.size() > 4096)
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "description."<< (int32_t)description.size() << " must be less then 4096");
if (format.size() > 4096 )
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "format."<< (int32_t)format.size() << " must be less then 4096");
if ( name.size() == 0 )
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "name must not be empty");
for(int i = 0; i < format.size(); i++)
{
fmt=format[i];
@@ -872,154 +880,125 @@ std::string OracleCreate(int64_t txfee,std::string name,std::string description,
case 'c': case 'C': case 't': case 'T':
case 'i': case 'I': case 'l': case 'L':
case 'h': break;
default: CCerror = strprintf("invalid format type");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
default: CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "invalid format type");
}
}
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
Oraclespk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
if ( AddNormalinputs(mtx,mypk,2*txfee,3,pk.IsValid()) > 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)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesCreateOpRet('C',name,description,format)));
}
CCerror = strprintf("error adding normal inputs");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding normal inputs");
}
std::string OracleFund(int64_t txfee,uint256 oracletxid)
UniValue OracleFund(const CPubKey& pk, int64_t txfee,uint256 oracletxid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,oraclespk; struct CCcontract_info *cp,C;
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CTransaction tx;
CPubKey mypk,oraclespk; struct CCcontract_info *cp,C; std::string name,desc,format; int32_t numvouts; uint256 hashBlock;
if (GetLatestTimestamp(komodo_get_current_height())<PUBKEY_SPOOFING_FIX_ACTIVATION)
{
CCerror = strprintf("oraclesfund not active yet, activation scheduled for July 15th");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
if (GetLatestTimestamp(komodo_currentheight())<PUBKEY_SPOOFING_FIX_ACTIVATION)
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "oraclesfund not active yet, activation scheduled for July 15th");
if (myGetTransaction(oracletxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex());
if (DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,desc,format)!='C')
CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex());
cp = CCinit(&C,EVAL_ORACLES);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,2))
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
if (AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,2,pk.IsValid()))
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CC_MARKER_VALUE,mypk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('F',oracletxid,mypk,CC_MARKER_VALUE)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('F',oracletxid,mypk,CC_MARKER_VALUE)));
}
CCerror = strprintf("error adding normal inputs");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding normal inputs");
}
std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee)
UniValue OracleRegister(const CPubKey& pk, int64_t txfee,uint256 oracletxid,int64_t datafee)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,markerpubkey,batonpk,oraclespk; struct CCcontract_info *cp,C; char markeraddr[64],batonaddr[64];
std::string name,desc,format; int32_t numvouts; uint256 hashBlock; CTransaction tx;
cp = CCinit(&C,EVAL_ORACLES);
if ( txfee == 0 )
txfee = 10000;
if (myGetTransaction(oracletxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex());
if (DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,desc,format)!='C')
CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex());
if ( datafee < txfee )
{
CCerror = strprintf("datafee must be txfee or more");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
mypk = pubkey2pk(Mypubkey());
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "datafee must be txfee or more");
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
oraclespk = GetUnspendable(cp,0);
batonpk = OracleBatonPk(batonaddr,cp);
markerpubkey = CCtxidaddr(markeraddr,oracletxid);
if (AddNormalinputs(mtx,mypk,3*txfee,4))
if (AddNormalinputs(mtx,mypk,3*txfee,4,pk.IsValid()))
{
if (GetLatestTimestamp(komodo_get_current_height())>PUBKEY_SPOOFING_FIX_ACTIVATION && AddMyOraclesFunds(cp,mtx,mypk,oracletxid)!=CC_MARKER_VALUE)
{
CCerror = strprintf("error adding inputs from your Oracles CC address, please fund it first with oraclesfund rpc!");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
if (GetLatestTimestamp(komodo_currentheight())>PUBKEY_SPOOFING_FIX_ACTIVATION && AddMyOraclesFunds(cp,mtx,mypk,oracletxid)!=CC_MARKER_VALUE)
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding inputs from your Oracles CC address, please fund it first with oraclesfund rpc!");
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,batonpk));
if (GetLatestTimestamp(komodo_get_current_height())>PUBKEY_SPOOFING_FIX_ACTIVATION) mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('R',oracletxid,mypk,datafee)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('R',oracletxid,mypk,datafee)));
}
CCerror = strprintf("error adding normal inputs");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding normal inputs");
}
std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount)
UniValue OracleSubscribe(const CPubKey& pk, int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; char markeraddr[64];
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CTransaction tx;
CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; char markeraddr[64]; std::string name,desc,format; int32_t numvouts; uint256 hashBlock;
cp = CCinit(&C,EVAL_ORACLES);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (myGetTransaction(oracletxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex());
if (DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,desc,format)!='C')
CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
markerpubkey = CCtxidaddr(markeraddr,oracletxid);
if ( AddNormalinputs(mtx,mypk,amount + 2*txfee,64) > 0 )
if ( AddNormalinputs(mtx,mypk,amount + 2*txfee,64,pk.IsValid()) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,publisher));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('S',oracletxid,mypk,amount)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('S',oracletxid,mypk,amount)));
}
CCerror = strprintf("error adding normal inputs");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding normal inputs");
}
std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> data)
UniValue OracleData(const CPubKey& pk, int64_t txfee,uint256 oracletxid,std::vector <uint8_t> data)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CScript pubKey; CPubKey mypk,batonpk; int64_t offset,datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid,hashBlock;
char coinaddr[64],batonaddr[64]; std::vector <uint8_t> prevdata; CTransaction tx; std::string name,description,format; int32_t len,numvouts;
cp = CCinit(&C,EVAL_ORACLES);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
if ( data.size() > 8192 )
{
CCerror = strprintf("datasize %d is too big",(int32_t)data.size());
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "datasize " << (int32_t)data.size() << " is too big");
if ( (datafee= OracleDatafee(pubKey,oracletxid,mypk)) <= 0 )
{
CCerror = strprintf("datafee %.8f is illegal",(double)datafee/COIN);
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "datafee " << (double)datafee/COIN << "is illegal");
if ( myGetTransaction(oracletxid,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 0 )
{
if ( DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,description,format) == 'C' )
{
if (oracle_parse_data_format(data,format)==0)
{
CCerror = strprintf("data does not match length or content format specification");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "data does not match length or content format specification");
}
else
{
CCerror = strprintf("invalid oracle txid opret data");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "invalid oracle txid opret data");
}
else
{
CCerror = strprintf("invalid oracle txid");
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "invalid oracle txid");
if ( txfee == 0 )
txfee = 10000;
GetCCaddress(cp,coinaddr,mypk);
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 ) // have enough funds even if baton utxo not there
if ( AddNormalinputs(mtx,mypk,2*txfee,3,pk.IsValid()) > 0 ) // have enough funds even if baton utxo not there
{
batonpk = OracleBatonPk(batonaddr,cp);
batontxid = OracleBatonUtxo(txfee,cp,oracletxid,batonaddr,mypk,prevdata);
@@ -1031,18 +1010,13 @@ std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> da
if ( inputs > datafee )
CCchange = (inputs - datafee);
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,mypk));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,batonpk));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CC_MARKER_VALUE,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 {
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");
fprintf(stderr,"%s\n", CCerror.c_str() );
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesData('D',oracletxid,batontxid,mypk,data)));
} else
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "couldnt find enough oracle inputs " << coinaddr << ", limit 1 per utxo");
}
return("");
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "couldnt add normal inputs");
}
UniValue OracleFormat(uint8_t *data,int32_t datalen,char *format,int32_t formatlen)
@@ -1096,7 +1070,7 @@ UniValue OracleDataSample(uint256 reforacletxid,uint256 txid)
UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num)
{
UniValue result(UniValue::VOBJ),b(UniValue::VARR); CTransaction tx,oracletx; uint256 txid,hashBlock,btxid,oracletxid;
CPubKey pk; std::string name,description,format; int32_t numvouts,n=0,vout; std::vector<uint8_t> data; char *formatstr = 0;
CPubKey pk; std::string name,description,format; int32_t numvouts,n=0,vout; std::vector<uint8_t> data; char *formatstr = 0, addr[64];
std::vector<uint256> txids; int64_t nValue;
result.push_back(Pair("result","success"));
@@ -1110,8 +1084,10 @@ UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num)
{
const CTransaction &txmempool = *it;
const uint256 &hash = txmempool.GetHash();
if ((numvouts=txmempool.vout.size())>0 && DecodeOraclesData(txmempool.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid )
if ((numvouts=txmempool.vout.size())>0 && txmempool.vout[1].nValue==CC_MARKER_VALUE && DecodeOraclesData(txmempool.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid )
{
Getscriptaddress(addr,txmempool.vout[1].scriptPubKey);
if (strcmp(addr,batonaddr)!=0) continue;
if ( (formatstr= (char *)format.c_str()) == 0 )
formatstr = (char *)"";
UniValue a(UniValue::VOBJ);
@@ -1119,7 +1095,10 @@ UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num)
a.push_back(Pair("data",OracleFormat((uint8_t *)data.data(),(int32_t)data.size(),formatstr,(int32_t)format.size())));
b.push_back(a);
if ( ++n >= num && num != 0)
break;
{
result.push_back(Pair("samples",b));
return(result);
}
}
}
SetCCtxids(txids,batonaddr,true,EVAL_ORACLES,reforacletxid,'D');
@@ -1130,7 +1109,7 @@ UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num)
txid=*it;
if (myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 0 )
{
if ( DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid )
if ( tx.vout[1].nValue==CC_MARKER_VALUE && DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid )
{
if ( (formatstr= (char *)format.c_str()) == 0 )
formatstr = (char *)"";
@@ -1139,13 +1118,20 @@ UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num)
a.push_back(Pair("data",OracleFormat((uint8_t *)data.data(),(int32_t)data.size(),formatstr,(int32_t)format.size())));
b.push_back(a);
if ( ++n >= num && num != 0)
break;
{
result.push_back(Pair("samples",b));
return(result);
}
}
}
}
}
}
else
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex());
}
else
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex());
result.push_back(Pair("samples",b));
return(result);
}
@@ -1216,7 +1202,11 @@ UniValue OracleInfo(uint256 origtxid)
}
result.push_back(Pair("registered",a));
}
else
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex());
}
else
CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex());
return(result);
}

View File

@@ -89,6 +89,13 @@ int64_t mpz_get_si2( mpz_t op )
return ret;
}
uint64_t mpz_get_ui2( mpz_t op )
{
uint64_t ret = 0;
mpz_export(&ret, NULL, 1, sizeof(ret), 0, 0, op);
return ret;
}
CScript EncodePaymentsTxidOpRet(int64_t allocation,std::vector<uint8_t> scriptPubKey,std::vector<uint8_t> destopret)
{
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;

View File

@@ -16,6 +16,8 @@
#include "CCPegs.h"
#include "../importcoin.h"
#include "key_io.h"
#include <gmp.h>
/*
pegs CC is able to create a coin backed (by any supported coin with gateways CC deposits) and pegged to any synthetic price that is able to be calculated based on prices CC
@@ -88,9 +90,10 @@ pegs CC is able to create a coin backed (by any supported coin with gateways CC
// start of consensus code
#ifndef PEGS_THRESHOLDS
#define PEGS_THRESHOLDS
#define PEGS_ACCOUNT_MAX_DEBT 80
#define PEGS_GLOBAL_RED_ZONE 60
#define PEGS_ACCOUNT_YELLOW_ZONE 60
#define PEGS_ACCOUNT_THRESHOLD 90
#define PEGS_GLOBAL_THRESHOLD 60
#define PEGS_ACCOUNT_RED_ZONE 90
#endif // PEGS_THRESHOLDS
#define CC_MARKER_VALUE 10000
@@ -99,6 +102,8 @@ extern uint64_t ASSETCHAINS_PEGSCCPARAMS[3];
extern uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,uint256 &tokenid,std::string &coin,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector<CPubKey> &gatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2,uint8_t &wiftype);
extern int64_t GetTokenBalance(CPubKey pk, uint256 tokenid);
extern int32_t komodo_currentheight();
extern int32_t prices_syntheticvec(std::vector<uint16_t> &vec, std::vector<std::string> synthetic);
extern int64_t prices_syntheticprice(std::vector<uint16_t> vec, int32_t height, int32_t minmax, int16_t leverage);
CScript EncodePegsCreateOpRet(std::vector<uint256> bindtxids)
{
@@ -512,21 +517,17 @@ char PegsFindAccount(struct CCcontract_info *cp,CPubKey pk,uint256 pegstxid, uin
else return(0);
}
double PegsGetTokenPrice(uint256 tokenid)
int64_t PegsGetTokenPrice(uint256 tokenid)
{
int64_t *tokensyn,*btcusd; double price; CTransaction tokentx; uint256 hashBlock;
int64_t price; CTransaction tokentx; uint256 hashBlock; std::vector<uint16_t> exp;
std::string name,desc; std::vector<uint8_t> vorigpubkey; int32_t numvouts;
if (myGetTransaction(tokenid,tokentx,hashBlock)!=0 && (numvouts=tokentx.vout.size())>0 && DecodeTokenCreateOpRet(tokentx.vout[numvouts-1].scriptPubKey,vorigpubkey,name,desc)=='c')
{
tokensyn = (int64_t *)calloc(sizeof(*tokensyn) * 3, 1 + PRICES_DAYWINDOW * 2 + PRICES_SMOOTHWIDTH);
btcusd = (int64_t *)calloc(sizeof(*btcusd) * 3, 1 + PRICES_DAYWINDOW * 2 + PRICES_SMOOTHWIDTH);
if (komodo_priceget(tokensyn, komodo_priceind((name+"_BTC").c_str()), komodo_currentheight(), 1) >= 0 && komodo_priceget(btcusd, komodo_priceind("BTC_USD"), komodo_currentheight(), 1) >= 0)
{
price=tokensyn[2]*btcusd[2];
price=price/COIN/COIN;
std::vector<std::string> vexpr;
SplitStr(desc, vexpr);
if (prices_syntheticvec(exp, vexpr)>=0 && (price = prices_syntheticprice(exp, komodo_currentheight(), 0, 1))>=0)
return (price);
}
}
return (0);
}
@@ -544,6 +545,34 @@ std::string PegsGetTokenName(uint256 tokenid)
return("");
}
int64_t PegsGetTokensAmountPerPrice(int64_t amount,uint256 tokenid)
{
mpz_t res,a,b;
mpz_init(res);
mpz_init(a);
mpz_init(b);
mpz_set_si(a, amount);
mpz_set_si(b, COIN);
mpz_mul(res, a, b);
mpz_set_si(a, PegsGetTokenPrice(tokenid));
mpz_tdiv_q(res, res, a);
return (mpz_get_si(res));
}
double PegsGetRatio(uint256 tokenid,std::pair<int64_t,int64_t> account)
{
mpz_t res,a,b;
mpz_init(res);
mpz_init(a);
mpz_init(b);
mpz_set_si(a, account.first);
mpz_set_si(b, PegsGetTokenPrice(tokenid));
mpz_mul(res, a, b);
mpz_set_si(a, COIN);
mpz_tdiv_q(res, res, a);
return ((double)account.second)*100/mpz_get_si(res);
}
double PegsGetAccountRatio(uint256 pegstxid,uint256 tokenid,uint256 accounttxid)
{
int64_t amount; uint256 hashBlock,tmptokenid,tmppegstxid;
@@ -555,7 +584,7 @@ double PegsGetAccountRatio(uint256 pegstxid,uint256 tokenid,uint256 accounttxid)
(funcid=DecodePegsOpRet(tx,tmppegstxid,tmptokenid))!=0 && pegstxid==tmppegstxid && tokenid==tmptokenid)
{
PegsDecodeAccountTx(tx,pk,amount,account);
return ((double)account.second*100/(account.first*PegsGetTokenPrice(tokenid)));
return PegsGetRatio(tokenid,account);
}
return (0);
}
@@ -565,7 +594,7 @@ double PegsGetGlobalRatio(uint256 pegstxid)
char coinaddr[64]; int64_t nValue,amount,globaldebt=0; uint256 txid,accounttxid,hashBlock,tmppegstxid,tokenid;
CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,pk;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::pair<int64_t,int64_t> account;
std::map<uint256,std::pair<int64_t,int64_t>> globalaccounts; double globaldeposit=0;
std::map<uint256,std::pair<int64_t,int64_t>> globalaccounts;
struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_PEGS);
@@ -598,12 +627,29 @@ double PegsGetGlobalRatio(uint256 pegstxid)
globalaccounts[tokenid].first+=nValue;
}
}
mpz_t res,globaldeposit,a,b;
mpz_init(res);
mpz_init(globaldeposit);
mpz_init(a);
mpz_init(b);
mpz_set_si(globaldeposit, 0);
for (std::map<uint256,std::pair<int64_t,int64_t>>::iterator it = globalaccounts.begin(); it != globalaccounts.end(); ++it)
{
globaldeposit+=globalaccounts[it->first].first*PegsGetTokenPrice(it->first);
mpz_set_si(res, 0);
mpz_set_si(a, globalaccounts[it->first].first);
mpz_set_si(b, PegsGetTokenPrice(it->first));
mpz_mul(res,a,b);
mpz_add(globaldeposit,globaldeposit,res);
globaldebt+=globalaccounts[it->first].second;
}
if (globaldebt>0) return ((double)globaldebt*100/globaldeposit);
if (globaldebt>0)
{
mpz_set_si(res, 0);
mpz_set_si(a, COIN);
mpz_tdiv_q(res, globaldeposit, a);
printf("%lu %lu\n",globaldebt,mpz_get_si(res));
return ((double)globaldebt)*100/mpz_get_si(res);
}
return (0);
}
@@ -643,7 +689,7 @@ std::string PegsFindBestAccount(struct CCcontract_info *cp,uint256 pegstxid, uin
else return("");
}
std::string PegsCreate(uint64_t txfee,int64_t amount, std::vector<uint256> bindtxids)
UniValue PegsCreate(const CPubKey& pk,uint64_t txfee,int64_t amount, std::vector<uint256> bindtxids)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,pegspk; struct CCcontract_info *cp,C; CTransaction tx; int32_t numvouts; int64_t totalsupply; std::string coin;
@@ -652,34 +698,24 @@ std::string PegsCreate(uint64_t txfee,int64_t amount, std::vector<uint256> bindt
cp = CCinit(&C,EVAL_PEGS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
for(auto txid : bindtxids)
{
if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex());
if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B')
{
CCerror = strprintf("invalid bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex());
}
if ( AddNormalinputs(mtx,mypk,amount,64) >= amount )
if ( AddNormalinputs(mtx,mypk,amount,64,pk.IsValid()) >= amount )
{
for (int i=0; i<100; i++) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,(amount-txfee)/100,pegspk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePegsCreateOpRet(bindtxids)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsCreateOpRet(bindtxids)));
}
CCerror = strprintf("error adding normal inputs");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "error adding normal inputs");
}
std::string PegsFund(uint64_t txfee,uint256 pegstxid, uint256 tokenid,int64_t amount)
UniValue PegsFund(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid,int64_t amount)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); std::string coin;
CTransaction pegstx,tx; int32_t numvouts; int64_t totalsupply,balance=0,funds=0,tokenfunds=0; uint256 accounttxid=zeroid,hashBlock,txid,tmptokenid,oracletxid;
@@ -690,35 +726,18 @@ std::string PegsFund(uint64_t txfee,uint256 pegstxid, uint256 tokenid,int64_t am
cpTokens = CCinit(&CTokens,EVAL_TOKENS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find pegstxid %s",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex());
if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C')
{
CCerror = strprintf("invalid pegstxid ",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex());
for(auto txid : bindtxids)
{
if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex());
if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B')
{
CCerror = strprintf("invalid bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex());
if (tmptokenid==tokenid)
{
found=true;
@@ -726,21 +745,13 @@ std::string PegsFund(uint64_t txfee,uint256 pegstxid, uint256 tokenid,int64_t am
}
}
if (!found)
{
CCerror = strprintf("invalid tokenid ",tokenid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid tokenid " << tokenid.GetHex());
if ((balance=GetTokenBalance(mypk,tokenid))>=amount)
{
PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,account);
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "current accounttxid=" << accounttxid.GetHex() << " [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
if (accounttxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,accounttxid,1) != 0)
{
CCerror = strprintf("previous account tx not yet confirmed");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous account tx not yet confirmed");
if (accounttxid!=zeroid && (funds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee,1))>=txfee)
{
funds+=2*CC_MARKER_VALUE;
@@ -763,23 +774,16 @@ std::string PegsFund(uint64_t txfee,uint256 pegstxid, uint256 tokenid,int64_t am
if (funds>txfee+2*CC_MARKER_VALUE) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,funds-(txfee+2*CC_MARKER_VALUE),pegspk));
account.first+=amount;
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "new account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePegsFundOpRet(tokenid,pegstxid,mypk,amount,account)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsFundOpRet(tokenid,pegstxid,mypk,amount,account)));
}
}
else
{
CCerror = strprintf("not enough balance in pegs global CC address");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream <<"not enough balance in pegs global CC address");
}
CCerror = strprintf("not enough balance (%lld) for this amount of tokens %lld",balance,amount);
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance (" << balance << ") for this amount of tokens " << amount);
}
std::string PegsGet(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount)
UniValue PegsGet(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount)
{
CMutableTransaction burntx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()),mtx;
CTransaction pegstx,tx; int32_t numvouts; int64_t funds=0; uint256 accounttxid=zeroid,hashBlock,pricestxid; char coinaddr[64];
@@ -789,32 +793,16 @@ std::string PegsGet(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t am
cp = CCinit(&C,EVAL_PEGS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find pegstxid %s",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex());
if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C')
{
CCerror = strprintf("invalid pegstxid ",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex());
if (PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,account)==0)
{
CCerror = strprintf("cannot find account from which to issue coins, fund account first with pegsfund!");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cannot find account from which to issue coins, fund account first with pegsfund!");
if (accounttxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,accounttxid,1) != 0)
{
CCerror = strprintf("previous account tx not yet confirmed");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous account tx not yet confirmed");
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "current accounttxid=" << accounttxid.GetHex() << " [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
// spending markers
vouts.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,pegspk,pegspk));
@@ -822,6 +810,12 @@ std::string PegsGet(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t am
// coin issue
vouts.push_back(CTxOut(amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
account.second+=amount;
if (PegsGetRatio(tokenid,account)>PEGS_ACCOUNT_MAX_DEBT)
{
CCerror = strprintf("not possible to take more than %d%% of the deposit",PEGS_ACCOUNT_MAX_DEBT);
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "new account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
// burn tx does not exist in pegs method but it must be created in order for import validation to pass
// fictive burntx input of previous account state tx
@@ -836,12 +830,12 @@ std::string PegsGet(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t am
Myprivkey(mypriv);
GetCCaddress1of2(cp,coinaddr,mypk,pegspk);
CCaddr1of2set(cp,mypk,pegspk,mypriv,coinaddr);
std::string retstr = FinalizeCCTx(0,cp,mtx,mypk,txfee,opret);
UniValue retstr = FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,opret);
memset(mypriv,0,sizeof(mypriv));
return(retstr);
}
std::string PegsRedeem(uint64_t txfee,uint256 pegstxid, uint256 tokenid)
UniValue PegsRedeem(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); std::string coin;
CTransaction pegstx,tx; int32_t numvouts; int64_t totalsupply,pegsfunds=0,funds=0,tokenfunds=0,amount; uint256 accounttxid=zeroid,hashBlock,txid,tmptokenid,oracletxid;
@@ -852,34 +846,18 @@ std::string PegsRedeem(uint64_t txfee,uint256 pegstxid, uint256 tokenid)
cpTokens = CCinit(&CTokens,EVAL_TOKENS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find pegstxid %s",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex());
if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C')
{
CCerror = strprintf("invalid pegstxid ",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex());
for(auto txid : bindtxids)
{
if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex());
if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B')
{
CCerror = strprintf("invalid bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex());
if (tmptokenid==tokenid)
{
found=true;
@@ -887,25 +865,13 @@ std::string PegsRedeem(uint64_t txfee,uint256 pegstxid, uint256 tokenid)
}
}
if (!found)
{
CCerror = strprintf("invalid tokenid ",tokenid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid tokenid " << tokenid.GetHex());
if (PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,account)==0)
{
CCerror = strprintf("cannot find account from which to redeem tokens!");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cannot find account from which to redeem tokens!");
if (accounttxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,accounttxid,1) != 0)
{
CCerror = strprintf("previous account tx not yet confirmed");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous account tx not yet confirmed");
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "current accounttxid=" << accounttxid.GetHex() << " [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
if ((funds=AddNormalinputs(mtx,mypk,account.second,64))>=account.second )
if ((funds=AddNormalinputs(mtx,mypk,account.second,64,pk.IsValid()))>=account.second )
{
if (accounttxid!=zeroid && (pegsfunds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee,1))>=txfee)
{
@@ -928,39 +894,31 @@ std::string PegsRedeem(uint64_t txfee,uint256 pegstxid, uint256 tokenid)
account.first=0;
account.second=0;
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "new account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
std::string retstr = FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePegsReedemOpRet(tokenid,pegstxid,mypk,amount,account));
UniValue retstr = FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsReedemOpRet(tokenid,pegstxid,mypk,amount,account));
memset(mypriv,0,32);
return(retstr);
}
else
{
CCerror = strprintf("not enough balance in pegs global CC address");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
memset(mypriv,0,32);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address");
}
}
CCerror = strprintf("not enough tokens in pegs account (%lld) to redeem this amount of tokens %lld",tokenfunds,account.first);
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
memset(mypriv,0,32);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough tokens in pegs account (" << tokenfunds << ") to redeem this amount of tokens " << account.first);
}
else
{
CCerror = strprintf("not enough balance in pegs global CC address");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
memset(mypriv,0,32);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address");
}
}
CCerror = strprintf("to redeem from account and close it you must redeem full debt ammount %lld instead of %lld",account.second,funds);
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
memset(mypriv,0,32);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "to redeem from account and close it you must redeem full debt ammount " << account.second << " instead of " << funds);
}
std::string PegsExchange(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount)
UniValue PegsExchange(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); std::string coin;
CTransaction pegstx,tx; int32_t numvouts; int64_t totalsupply,pegsfunds=0,funds=0,tokenfunds=0,tokenamount,tmpamount; uint256 accounttxid=zeroid,hashBlock,txid,tmptokenid,oracletxid;
@@ -971,34 +929,18 @@ std::string PegsExchange(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64
cpTokens = CCinit(&CTokens,EVAL_TOKENS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find pegstxid %s",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex());
if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C')
{
CCerror = strprintf("invalid pegstxid ",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex());
for(auto txid : bindtxids)
{
if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex());
if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B')
{
CCerror = strprintf("invalid bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex());
if (tmptokenid==tokenid)
{
found=true;
@@ -1006,43 +948,23 @@ std::string PegsExchange(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64
}
}
if (!found)
{
CCerror = strprintf("invalid tokenid ",tokenid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid tokenid " << tokenid.GetHex());
if (PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,account)!=0)
{
CCerror = strprintf("you have active account, please close account first before exchanging other coins!");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ((funds=AddNormalinputs(mtx,mypk,amount,64))>=amount )
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "you have active account, please close account first before exchanging other coins!");
if ((funds=AddNormalinputs(mtx,mypk,amount,64,pk.IsValid()))>=amount )
{
if ((pegsfunds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee,1))>=txfee)
{
tokenamount=amount/PegsGetTokenPrice(tokenid);
tokenamount=PegsGetTokensAmountPerPrice(amount,tokenid);
tokenfunds=AddPegsTokenInputs(cp,mtx,pegstxid,tokenid,pegspk,CPubKey(),tokenamount,64);
if (tokenfunds<tokenamount)
{
if (PegsFindBestAccount(cp,pegstxid,tokenid,tokenamount-tokenfunds,accounttxid,account).empty())
{
CCerror = strprintf("cannot find account from which to get tokens for exchange!");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cannot find account from which to get tokens for exchange!");
if (accounttxid!=zeroid && myGetTransaction(accounttxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0 || PegsDecodeAccountTx(tx,tmppk,tmpamount,account).empty())
{
CCerror = strprintf("invalid account tx from which to exchange coins to tokens %s!",accounttxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid account tx from which to exchange coins to tokens " << accounttxid.GetHex());
if (accounttxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,accounttxid,1) != 0)
{
CCerror = strprintf("previous account tx not yet confirmed");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous account tx not yet confirmed");
tokenfunds+=AddPegsTokenInputs(cp,mtx,pegstxid,tokenid,tmppk,pegspk,tokenamount,64);
mtx.vin.push_back(CTxIn(accounttxid,0,CScript()));
mtx.vin.push_back(CTxIn(accounttxid,1,CScript()));
@@ -1070,35 +992,23 @@ std::string PegsExchange(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64
}
else if (pegsfunds>txfee) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,pegsfunds-txfee,pegspk));
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "modified account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePegsExchangeOpRet(tokenid,pegstxid,mypk,tmppk,amount,account)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsExchangeOpRet(tokenid,pegstxid,mypk,tmppk,amount,account)));
}
else
{
CCerror = strprintf("not enough balance in pegs global CC address");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address");
}
CCerror = strprintf("not enough tokens in pegs account (%lld) to exchange to this amount of tokens %lld",tokenfunds,tokenamount);
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough tokens in pegs account (" << tokenfunds << ") to exchange to this amount of tokens " << tokenamount);
}
else
{
CCerror = strprintf("not enough balance in pegs global CC address");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address");
}
CCerror = strprintf("not enough funds to exchange %lld coins to tokens - balance %lld",amount,funds);
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough funds to exchange " << amount << " coins to tokens - balance " << funds);
}
std::string PegsLiquidate(uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint256 liquidatetxid)
UniValue PegsLiquidate(const CPubKey& pk,uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint256 liquidatetxid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); std::string coin;
CTransaction pegstx,tx; int32_t numvouts; int64_t totalsupply,pegsfunds=0,funds=0,tokenfunds=0,amount,burnamount;
CTransaction pegstx,tx; int32_t numvouts; int64_t totalsupply,pegsfunds=0,funds=0,tokenfunds=0,amount,tmpamount,tokenamount,burnamount;
CPubKey mypk,pegspk,tmppk; struct CCcontract_info *cp,*cpTokens,CTokens,C; char depositaddr[64],coinaddr[64]; std::pair <int64_t,int64_t> account(0,0),myaccount(0,0);
uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> pubkeys; bool found=false; std::vector<uint256> bindtxids;
uint256 hashBlock,txid,tmptokenid,oracletxid,accounttxid;
@@ -1107,34 +1017,18 @@ std::string PegsLiquidate(uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint
cpTokens = CCinit(&CTokens,EVAL_TOKENS);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find pegstxid %s",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex());
if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C')
{
CCerror = strprintf("invalid pegstxid ",pegstxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
for(auto txid : bindtxids)
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex());
for(auto txid : bindtxids)
{
if (myGetTransaction(txid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("cant find bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find bindtxid " << txid.GetHex());
if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tmptokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype)!='B')
{
CCerror = strprintf("invalid bindtxid %s",txid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid bindtxid " << txid.GetHex());
if (tmptokenid==tokenid)
{
found=true;
@@ -1142,45 +1036,23 @@ std::string PegsLiquidate(uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint
}
}
if (!found)
{
CCerror = strprintf("invalid tokenid ",tokenid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid tokenid " << tokenid.GetHex());
if (PegsFindAccount(cp,mypk,pegstxid,tokenid,accounttxid,myaccount)==0)
{
CCerror = strprintf("cannot find account, you must have an account to liquidate another account!");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cannot find account, you must have an account to liquidate another account!");
if (accounttxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,accounttxid,1) != 0)
{
CCerror = strprintf("previous account tx not yet confirmed");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if (PegsGetAccountRatio(pegstxid,tokenid,liquidatetxid)<(ASSETCHAINS_PEGSCCPARAMS[0]?ASSETCHAINS_PEGSCCPARAMS[0]:PEGS_ACCOUNT_THRESHOLD) || PegsGetGlobalRatio(pegstxid)<(ASSETCHAINS_PEGSCCPARAMS[1]?ASSETCHAINS_PEGSCCPARAMS[1]:PEGS_GLOBAL_THRESHOLD))
{
CCerror = strprintf("not able to liquidate account until account ratio > %lu%% and global ratio > %lu%%",(ASSETCHAINS_PEGSCCPARAMS[0]?ASSETCHAINS_PEGSCCPARAMS[0]:PEGS_ACCOUNT_THRESHOLD),(ASSETCHAINS_PEGSCCPARAMS[1]?ASSETCHAINS_PEGSCCPARAMS[1]:PEGS_GLOBAL_THRESHOLD));
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous account tx not yet confirmed");
if (PegsGetAccountRatio(pegstxid,tokenid,liquidatetxid)<(ASSETCHAINS_PEGSCCPARAMS[0]?ASSETCHAINS_PEGSCCPARAMS[0]:PEGS_ACCOUNT_RED_ZONE) || PegsGetGlobalRatio(pegstxid)<(ASSETCHAINS_PEGSCCPARAMS[1]?ASSETCHAINS_PEGSCCPARAMS[1]:PEGS_ACCOUNT_RED_ZONE))
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not able to liquidate account until account ratio > " << (ASSETCHAINS_PEGSCCPARAMS[0]?ASSETCHAINS_PEGSCCPARAMS[0]:PEGS_ACCOUNT_RED_ZONE) << "% and global ratio > " << (ASSETCHAINS_PEGSCCPARAMS[1]?ASSETCHAINS_PEGSCCPARAMS[1]:PEGS_ACCOUNT_RED_ZONE) << "%");
if (liquidatetxid!=zeroid && myGetTransaction(liquidatetxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0 || PegsDecodeAccountTx(tx,tmppk,amount,account).empty())
{
CCerror = strprintf("cannot find account to liquidate or invalid tx %s!",liquidatetxid.GetHex());
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cannot find account to liquidate or invalid tx " << liquidatetxid.GetHex());
if (liquidatetxid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,liquidatetxid,1) != 0)
{
CCerror = strprintf("previous liquidate account tx not yet confirmed");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "previous liquidate account tx not yet confirmed");
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "current accounttxid=" << accounttxid.GetHex() << " [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
amount=account.first;
burnamount=account.second*0.9;
if ((funds=AddNormalinputs(mtx,mypk,txfee+account.second,64))>=txfee+burnamount)
tokenamount=account.first;
burnamount=account.second;
tmpamount=PegsGetTokensAmountPerPrice(burnamount,tokenid)*105/100;
amount=tmpamount+((tokenamount-tmpamount)*10/100);
if ((funds=AddNormalinputs(mtx,mypk,account.second,64))>=burnamount)
{
if (liquidatetxid!=zeroid && (pegsfunds=AddPegsInputs(cp,mtx,pegspk,CPubKey(),txfee,1))>=txfee)
{
@@ -1189,49 +1061,45 @@ std::string PegsLiquidate(uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint
mtx.vin.push_back(CTxIn(liquidatetxid,1,CScript()));
GetCCaddress1of2(cp,coinaddr,tmppk,pegspk);
CCaddr1of2set(cp,tmppk,pegspk,cp->CCpriv,coinaddr);
if ((tokenfunds=AddPegsTokenInputs(cp,mtx,pegstxid,tokenid,tmppk,pegspk,amount,64))==amount)
if ((tokenfunds=AddPegsTokenInputs(cp,mtx,pegstxid,tokenid,tmppk,pegspk,tokenamount,64))==tokenamount)
{
if (pegsfunds>=txfee+2*CC_MARKER_VALUE)
{
mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,pegspk,pegspk));
mtx.vout.push_back(MakeCC1of2vout(EVAL_PEGS,CC_MARKER_VALUE,tmppk,pegspk));
mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS,(int64_t)(amount*0.95),mypk));
mtx.vout.push_back(MakeTokensCC1vout(EVAL_PEGS,amount-(int64_t)(amount*0.95),pegspk));
mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS,amount,mypk));
mtx.vout.push_back(MakeTokensCC1vout(EVAL_PEGS,tokenamount-amount,pegspk));
mtx.vout.push_back(CTxOut(burnamount,CScript() << ParseHex(HexStr(CCtxidaddr(coinaddr,pegstxid))) << OP_CHECKSIG));
if (pegsfunds>txfee+2*CC_MARKER_VALUE) mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,pegsfunds-(txfee+2*CC_MARKER_VALUE),pegspk));
account.first=0;
account.second=0;
LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "new account [deposit=" << account.first << ",debt=" << account.second << "]" << std::endl);
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePegsLiquidateOpRet(tokenid,pegstxid,mypk,amount,account)));
return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodePegsLiquidateOpRet(tokenid,pegstxid,mypk,amount,account)));
}
CCerror = strprintf("not enough balance in pegs global CC address");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address");
}
CCerror = strprintf("tokens amount in pegs account (%lld) not matching amount in account %lld",tokenfunds,account.first); // this shouldn't happen
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "tokens amount in pegs account " << tokenfunds << " not matching amount in account " << account.first); // this shouldn't happen
}
CCerror = strprintf("not enough balance in pegs global CC address");
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough balance in pegs global CC address");
}
CCerror = strprintf("not enough funds to liquidate account, you must liquidate full debt ammount %lld instead of %lld",txfee+account.second,funds);
LOGSTREAM("pegscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "not enough funds to liquidate account, you must liquidate full debt ammount " << txfee+account.second << " instead of " << funds);
}
UniValue PegsAccountHistory(uint256 pegstxid)
UniValue PegsAccountHistory(const CPubKey& pk,uint256 pegstxid)
{
char coinaddr[64]; int64_t nValue,amount; uint256 txid,accounttxid,hashBlock,tmptokenid,tmppegstxid;
CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,pk; std::map<uint256,std::pair<int64_t,int64_t>> accounts;
std::vector<uint256> txids; std::pair<int64_t,int64_t> account;
CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,tmppk; std::map<uint256,std::pair<int64_t,int64_t>> accounts;
std::vector<uint256> txids; std::pair<int64_t,int64_t> account; std::vector<uint256> bindtxids;
UniValue result(UniValue::VOBJ),acc(UniValue::VARR); struct CCcontract_info *cp,C;
if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex());
if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C')
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex());
result.push_back(Pair("result","success"));
result.push_back(Pair("name","pegsaccounthistory"));
cp = CCinit(&C,EVAL_PEGS);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,mypk,pegspk);
SetCCtxids(txids,coinaddr,true,EVAL_PEGS,pegstxid,0);
@@ -1242,7 +1110,7 @@ UniValue PegsAccountHistory(uint256 pegstxid)
(funcid=DecodePegsOpRet(tx,tmppegstxid,tmptokenid))!=0 && pegstxid==tmppegstxid)
{
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("action",PegsDecodeAccountTx(tx,pk,amount,account)));
obj.push_back(Pair("action",PegsDecodeAccountTx(tx,tmppk,amount,account)));
obj.push_back(Pair("amount",amount));
obj.push_back(Pair("accounttxid",txid.GetHex()));
obj.push_back(Pair("token",PegsGetTokenName(tmptokenid)));
@@ -1255,17 +1123,21 @@ UniValue PegsAccountHistory(uint256 pegstxid)
return(result);
}
UniValue PegsAccountInfo(uint256 pegstxid)
UniValue PegsAccountInfo(const CPubKey& pk,uint256 pegstxid)
{
char coinaddr[64]; int64_t nValue,amount; uint256 txid,accounttxid,hashBlock,tmptokenid,tmppegstxid; std::map<uint256,std::pair<int64_t,int64_t>> accounts;
CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,pk;
CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,tmppk; std::vector<uint256> bindtxids;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::pair<int64_t,int64_t> account;
UniValue result(UniValue::VOBJ),acc(UniValue::VARR); struct CCcontract_info *cp,C;
if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex());
if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C')
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex());
result.push_back(Pair("result","success"));
result.push_back(Pair("name","pegsaccountinfo"));
cp = CCinit(&C,EVAL_PEGS);
mypk = pubkey2pk(Mypubkey());
mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,mypk,pegspk);
SetCCunspents(unspentOutputs,coinaddr,true);
@@ -1279,7 +1151,7 @@ UniValue PegsAccountInfo(uint256 pegstxid)
(funcid=DecodePegsOpRet(tx,tmppegstxid,tmptokenid))!=0 && pegstxid==tmppegstxid)
{
//LOGSTREAM("pegscc",CCLOG_DEBUG2, stream << "txid=" << txid.GetHex() << ", vout=" << vout << ", nValue=" << nValue << ", tokenid=" << tmptokenid.GetHex() << std::endl);
PegsDecodeAccountTx(tx,pk,amount,account);
PegsDecodeAccountTx(tx,tmppk,amount,account);
accounts[tmptokenid].first=account.first;
accounts[tmptokenid].second=account.second;
}
@@ -1288,10 +1160,10 @@ UniValue PegsAccountInfo(uint256 pegstxid)
{
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("token",PegsGetTokenName(it->first)));
obj.push_back(Pair("deposit",(double)accounts[it->first].first/COIN));
obj.push_back(Pair("debt",(double)accounts[it->first].second/COIN));
if (accounts[it->first].first==0 || accounts[it->first].second==0 || PegsGetTokenPrice(it->first)==0) obj.push_back(Pair("ratio",0));
else obj.push_back(Pair("ratio",strprintf("%.2f%%",(double)accounts[it->first].second*100/(accounts[it->first].first*PegsGetTokenPrice(it->first)))));
obj.push_back(Pair("deposit",accounts[it->first].first));
obj.push_back(Pair("debt",accounts[it->first].second));
if (accounts[it->first].first==0 || accounts[it->first].second==0 || PegsGetTokenPrice(it->first)<=0) obj.push_back(Pair("ratio",0));
else obj.push_back(Pair("ratio",strprintf("%.2f%%",PegsGetRatio(it->first,accounts[it->first]))));
acc.push_back(obj);
}
result.push_back(Pair("account info",acc));
@@ -1301,14 +1173,17 @@ UniValue PegsAccountInfo(uint256 pegstxid)
UniValue PegsWorstAccounts(uint256 pegstxid)
{
char coinaddr[64]; int64_t nValue,amount; uint256 txid,accounttxid,hashBlock,tmppegstxid,tokenid,prev;
CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,pk; double ratio;
CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey pegspk,pk; double ratio; std::vector<uint256> bindtxids;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::pair<int64_t,int64_t> account;
UniValue result(UniValue::VOBJ),acc(UniValue::VARR); struct CCcontract_info *cp,C; std::multimap<uint256,UniValue> map;
if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex());
if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C')
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex());
result.push_back(Pair("result","success"));
result.push_back(Pair("name","pegsworstaccounts"));
cp = CCinit(&C,EVAL_PEGS);
mypk = pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,pegspk,pegspk);
SetCCunspents(unspentOutputs,coinaddr,true);
@@ -1321,9 +1196,9 @@ UniValue PegsWorstAccounts(uint256 pegstxid)
(funcid=DecodePegsOpRet(tx,tmppegstxid,tokenid))!=0 && pegstxid==tmppegstxid)
{
PegsDecodeAccountTx(tx,pk,amount,account);
if (account.first==0 || account.second==0 || PegsGetTokenPrice(tokenid)==0) ratio=0;
else ratio=(double)account.second*100/(account.first*PegsGetTokenPrice(tokenid));
if (ratio>80)
if (account.first==0 || account.second==0 || PegsGetTokenPrice(tokenid)<=0) ratio=0;
else ratio=PegsGetRatio(tokenid,account);
if (ratio>PEGS_ACCOUNT_RED_ZONE)
{
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("accounttxid",txid.GetHex()));
@@ -1352,15 +1227,18 @@ UniValue PegsWorstAccounts(uint256 pegstxid)
UniValue PegsInfo(uint256 pegstxid)
{
char coinaddr[64]; int64_t nValue,amount; uint256 txid,accounttxid,hashBlock,tmppegstxid,tokenid;
CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey mypk,pegspk,pk;
CTransaction tx; int32_t numvouts,vout; char funcid; CPubKey pegspk,pk; std::vector<uint256> bindtxids;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::pair<int64_t,int64_t> account;
std::map<uint256,std::pair<int64_t,int64_t>> globalaccounts; double globaldeposit=0;
UniValue result(UniValue::VOBJ),acc(UniValue::VARR); struct CCcontract_info *cp,C;
if (myGetTransaction(pegstxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "cant find pegstxid " << pegstxid.GetHex());
if (DecodePegsCreateOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxids)!='C')
CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid pegstxid " << pegstxid.GetHex());
result.push_back(Pair("result","success"));
result.push_back(Pair("name","pegsinfo"));
cp = CCinit(&C,EVAL_PEGS);
mypk = pubkey2pk(Mypubkey());
pegspk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,pegspk,pegspk);
SetCCunspents(unspentOutputs,coinaddr,true);
@@ -1396,8 +1274,8 @@ UniValue PegsInfo(uint256 pegstxid)
obj.push_back(Pair("token",PegsGetTokenName(it->first)));
obj.push_back(Pair("total deposit",globalaccounts[it->first].first));
obj.push_back(Pair("total debt",globalaccounts[it->first].second));
if (globalaccounts[it->first].first==0 || globalaccounts[it->first].second==0 || PegsGetTokenPrice(it->first)==0) obj.push_back(Pair("total ratio",0));
else obj.push_back(Pair("total ratio",strprintf("%.2f%%",(double)globalaccounts[it->first].second*100/(globalaccounts[it->first].first*PegsGetTokenPrice(it->first)))));
if (globalaccounts[it->first].first==0 || globalaccounts[it->first].second==0 || PegsGetTokenPrice(it->first)<=0) obj.push_back(Pair("total ratio",0));
else obj.push_back(Pair("total ratio",strprintf("%.2f%%",PegsGetRatio(it->first,globalaccounts[it->first]))));
acc.push_back(obj);
}
result.push_back(Pair("info",acc));

View File

@@ -65,24 +65,62 @@
vout.n-1: opreturn 'U' sbits fundingtxid
*/
int64_t RewardsCalc(int64_t amount,uint256 txid,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit)
/// the following are compatible with windows
/// mpz_set_lli sets a long long singed int to a big num mpz_t for very large integer math
extern void mpz_set_lli( mpz_t rop, long long op );
// mpz_get_si2 gets a mpz_t and returns a signed long long int
extern int64_t mpz_get_si2( mpz_t op );
// mpz_get_ui2 gets a mpz_t and returns a unsigned long long int
extern uint64_t mpz_get_ui2( mpz_t op );
uint64_t RewardsCalc(int64_t amount, uint256 txid, int64_t APR, int64_t minseconds, int64_t maxseconds, uint32_t timestamp)
{
int32_t numblocks; uint64_t duration,reward = 0;
int32_t numblocks; int64_t duration; uint64_t reward = 0;
//fprintf(stderr,"minseconds %llu maxseconds %llu\n",(long long)minseconds,(long long)maxseconds);
if ( (duration= CCduration(numblocks,txid)) < minseconds )
{
fprintf(stderr,"duration %llu < minseconds %llu\n",(long long)duration,(long long)minseconds);
fprintf(stderr,"duration %lli < minseconds %lli\n",(long long)duration,(long long)minseconds);
return(0);
//duration = (uint32_t)time(NULL) - (1532713903 - 3600 * 24);
} else if ( duration > maxseconds )
duration = maxseconds;
if ( 0 ) // amount * APR * duration / COIN * 100 * 365*24*3600
/* if ( 0 ) // amount * APR * duration / COIN * 100 * 365*24*3600
reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100);
else reward = (((amount * duration) / (365 * 24 * 3600LL)) * (APR / 1000000)) / 10000;
*/
if ( !hush_hardfork_active(timestamp) )
reward = (((amount * duration) / (365 * 24 * 3600LL)) * (APR / 1000000)) / 10000;
else
{
// declare and init the mpz_t big num variables
mpz_t mpzAmount, mpzDuration, mpzReward, mpzAPR, mpzModifier;
mpz_init(mpzAmount);
mpz_init(mpzDuration);
mpz_init(mpzAPR);
mpz_init(mpzReward);
mpz_init(mpzModifier);
// set the inputs to big num variables
mpz_set_lli(mpzAmount, amount);
mpz_set_lli(mpzDuration, duration);
mpz_set_lli(mpzAPR, APR);
mpz_set_lli(mpzModifier, COIN*100*365*24*3600LL);
// (amount * APR * duration)
mpz_mul(mpzReward, mpzAmount, mpzDuration);
mpz_mul(mpzReward, mpzReward, mpzAPR);
// total_of_above / (COIN * 100 * 365*24*3600LL)
mpz_tdiv_q(mpzReward, mpzReward, mpzModifier);
// set result to variable we can use and return it.
reward = mpz_get_ui2(mpzReward);
}
if ( reward > amount )
reward = amount;
fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f vals %.8f %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN,(double)((amount * duration) / (365 * 24 * 3600LL))/COIN,(double)(((amount * duration) / (365 * 24 * 3600LL)) * (APR / 1000000))/COIN);
fprintf(stderr, "amount.%lli duration.%lli APR.%lli reward.%llu\n", (long long)amount, (long long)duration, (long long)APR, (long long)reward);
//fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f vals %.8f %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN,(double)((amount * duration) / (365 * 24 * 3600LL))/COIN,(double)(((amount * duration) / (365 * 24 * 3600LL)) * (APR / 1000000))/COIN);
return(reward);
}
@@ -259,7 +297,7 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
if ( !CheckTxFee(tx, txfee, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime, dummy) )
return eval->Invalid("txfee is too high");
amount = vinTx.vout[0].nValue;
reward = RewardsCalc(amount,tx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit);
reward = RewardsCalc((int64_t)amount,tx.vin[0].prevout.hash,(int64_t)APR,(int64_t)minseconds,(int64_t)maxseconds,GetLatestTimestamp(eval->GetCurrentHeight()));
if ( reward == 0 )
return eval->Invalid("no eligible rewards");
if ( numvins == 1 && tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
@@ -671,7 +709,7 @@ std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint2
}
if ( amount > txfee )
{
reward = RewardsCalc(amount,mtx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit);
reward = RewardsCalc((int64_t)amount,mtx.vin[0].prevout.hash,(int64_t)APR,(int64_t)minseconds,(int64_t)maxseconds,komodo_chainactive_timestamp());
if ( scriptPubKey.size() > 0 )
{
if ( reward > txfee )

View File

@@ -138,6 +138,7 @@ class CBlockIndex;
// 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.
// TODO: delete this junk
class CChainPower
{
public:
@@ -256,17 +257,105 @@ public:
//! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
CChainPower chainPower;
// block stats
//! Number of transactions in this block.
//! Note: in a potential headers-first mode, this number cannot be relied upon
unsigned int nTx;
// chain stats
//! Number of notarization transactions in this block.
int64_t nNotarizations;
//! (memory only) Number of payments (shielded or transparent) in the block
//! up to and including this block. One transaction can contain one or more
//! payments. This stat allows us to calculate ratios of shielded/transparent
//! when combined with shielded payment stats
int64_t nPayments;
//! (memory only) Number of shielded transactions (of any kind) in the block up to and including this block.
//! A shielded transaction is defined as a transaction that contains at least 1 JoinSplit, which includes
//! shielding/de-shielding and other complex transaction possibilties including multiple taddrs/zaddrs as
//! inputs and outputs.
int64_t nShieldedTx;
//! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined
//! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent
// inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc...
int64_t nFullyShieldedTx;
//! (memory only) Number of shielding payments. A shielding payment is defined
//! as having a shielded output but transparent input: t->z
int64_t nShieldingPayments;
//! (memory only) Number of shielded payments. A shielded payment is defined
//! as having a shielded input or output: t->z or z->t
int64_t nShieldedPayments;
//! (memory only) Number of fully shielded payments. A fully shielded payment is defined
//! as having a shielded input and shielded output: z->z
int64_t nFullyShieldedPayments;
//! (memory only) Number of deshielding transactions. A deshielding transaction is defined
//! as a transaction containing JoinSplits and at least one transparent output.
int64_t nDeshieldingTx;
//! (memory only) Number of deshielding payments. A deshielding payment is defined
//! as one transparent input and one shielded output: z->t
int64_t nDeshieldingPayments;
//! (memory only) Number of shielding transactions. A shielding transaction is defined
//! as a transaction containing JoinSplits and at least one transparent input
// i.e. t->z or t->(z,t) or z->(z,z,t)
int64_t nShieldingTx;
//! (memory only) Number of transactions in the chain up to and including this block.
//! This value will be non-zero only if and only if transactions for this block and all its parents are available.
//! Change to 64-bit type when necessary; won't happen before 2030
unsigned int nChainTx;
//! Number of notarization transactions in this chain
int64_t nChainNotarizations;
//! (memory only) Number of payments (shielded or transparent) in the chain
//! up to and including this block. One transaction can contain one or more
//! payments. This stat allows us to calculate ratios of shielded/transparent
//! when combined with shielded payment stats
int64_t nChainPayments;
//! (memory only) Number of shielded transactions (of any kind) in the chain up to and including this block.
//! A shielded transaction is defined as a transaction that contains at least 1 JoinSplit, which includes
//! shielding/de-shielding and other complex transaction possibilties including multiple taddrs/zaddrs as
//! inputs and outputs.
int64_t nChainShieldedTx;
//! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined
//! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent
// inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc...
int64_t nChainFullyShieldedTx;
//! (memory only) Number of shielding payments. A shielding payment is defined
//! as having a shielded output but transparent input: t->z
int64_t nChainShieldingPayments;
//! (memory only) Number of shielded payments. A shielded payment is defined
//! as having a shielded input or output: t->z or z->t
int64_t nChainShieldedPayments;
//! (memory only) Number of fully shielded payments. A fully shielded payment is defined
//! as having a shielded input and shielded output: z->z
int64_t nChainFullyShieldedPayments;
//! (memory only) Number of deshielding transactions. A deshielding transaction is defined
//! as a transaction containing JoinSplits and at least one transparent output.
int64_t nChainDeshieldingTx;
//! (memory only) Number of deshielding payments. A deshielding payment is defined
//! as one transparent input and one shielded output: z->t
int64_t nChainDeshieldingPayments;
//! (memory only) Number of shielding transactions. A shielding transaction is defined
//! as a transaction containing JoinSplits and at least one transparent input
// i.e. t->z or t->(z,t) or z->(z,z,t)
int64_t nChainShieldingTx;
//! Verification status of this block. See enum BlockStatus
unsigned int nStatus;
@@ -326,6 +415,28 @@ public:
nTx = 0;
nChainTx = 0;
nChainPayments = 0;
nChainShieldedTx = 0;
nChainShieldingTx = 0;
nChainDeshieldingTx = 0;
nChainNotarizations = 0;
nChainFullyShieldedTx = 0;
nChainShieldedPayments = 0;
nChainShieldingPayments = 0;
nChainDeshieldingPayments = 0;
nChainFullyShieldedPayments = 0;
nPayments = 0;
nShieldedTx = 0;
nShieldingTx = 0;
nNotarizations = 0;
nDeshieldingTx = 0;
nFullyShieldedTx = 0;
nShieldedPayments = 0;
nShieldingPayments = 0;
nDeshieldingPayments = 0;
nFullyShieldedPayments = 0;
nStatus = 0;
nCachedBranchId = boost::none;
hashSproutAnchor = uint256();
@@ -501,6 +612,7 @@ public:
READWRITE(VARINT(nStatus));
READWRITE(VARINT(nTx));
if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
READWRITE(VARINT(nFile));
if (nStatus & BLOCK_HAVE_DATA)
@@ -542,10 +654,27 @@ public:
if ((s.GetType() & SER_DISK) && (nVersion >= SAPLING_VALUE_VERSION)) {
READWRITE(nSaplingValue);
}
/*
if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) && ASSETCHAINS_NOTARY_PAY[0] != 0 )
{
READWRITE(nNotaryPay);
READWRITE(segid);
}
*/
// These values only serialized when -zindex enabled
if((s.GetType() & SER_DISK) && fZindex) {
READWRITE(nShieldedTx);
READWRITE(nShieldingTx);
READWRITE(nDeshieldingTx);
READWRITE(nFullyShieldedTx);
READWRITE(nPayments);
READWRITE(nNotarizations);
READWRITE(nShieldedPayments);
READWRITE(nShieldingPayments);
READWRITE(nDeshieldingPayments);
READWRITE(nFullyShieldedPayments);
}
}

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2019 The Hush developers
// Copyright (c) 2019-2020 The Hush developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -246,7 +246,7 @@ class CTestNetParams : public CChainParams {
public:
CTestNetParams() {
strNetworkID = "test";
strCurrencyUnits = "TAZ";
strCurrencyUnits = "TUSH";
bip44CoinType = 1;
consensus.fCoinbaseMustBeProtected = true;
consensus.nSubsidySlowStartInterval = 20000;
@@ -304,7 +304,6 @@ public:
vFixedSeeds.clear();
vSeeds.clear();
//vSeeds.push_back(CDNSSeedData("z.cash", "dns.testnet.z.cash")); // Komodo
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
@@ -583,7 +582,7 @@ void *chainparams_commandline()
pCurrentParams->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);
pCurrentParams->consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = ASSETCHAINS_SAPLING;
pCurrentParams->consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = ASSETCHAINS_SAPLING;
pCurrentParams->consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = ASSETCHAINS_OVERWINTER;
// Generated at 1575831755 via hush3 contrib/checkpoints.pl by Duke Leto
if (strcmp(ASSETCHAINS_SYMBOL,"HUSH3") == 0) {

View File

@@ -33,8 +33,8 @@
//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
// Must be kept in sync with configure.ac !
#define CLIENT_VERSION_MAJOR 3
#define CLIENT_VERSION_MINOR 2
#define CLIENT_VERSION_REVISION 2
#define CLIENT_VERSION_MINOR 3
#define CLIENT_VERSION_REVISION 0
#define CLIENT_VERSION_BUILD 50
//! Set to true for release, false for prerelease or test build

View File

@@ -618,13 +618,13 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const
{
for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
if (GetNullifier(spendDescription.nullifier, SAPLING)) { // Prevent double spends
fprintf(stderr,"%s: sapling nullifier %s exists, preventing double spend\n", __FUNCTION__, spendDescription.nullifier);
LogPrintf("%s: sapling nullifier %s exists, preventing double spend\n", __FUNCTION__, spendDescription.nullifier.GetHex().c_str());
return false;
}
SaplingMerkleTree tree;
if (!GetSaplingAnchorAt(spendDescription.anchor, tree)) {
fprintf(stderr,"%s: missing sapling anchor: %s \n", __FUNCTION__, spendDescription.anchor);
LogPrintf("%s: missing sapling anchor: %s \n", __FUNCTION__, spendDescription.anchor.GetHex().c_str());
return false;
}
}

View File

@@ -1,7 +1,7 @@
#include "cc/eval.h"
#include "crosschain.h"
#include "notarisationdb.h"
#include "notaries_staked.h"
int GetSymbolAuthority(const char* symbol)
{

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Copyright (c) 2019-2020 The Hush developers
// Released under the GPLv3
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -17,7 +19,7 @@
#include "compat/endian.h"
#if defined(NDEBUG)
# error "Zcash cannot be compiled without assertions."
# error "Hush cannot be compiled without assertions."
#endif
uint16_t static inline ReadLE16(const unsigned char* ptr)

View File

@@ -1,606 +0,0 @@
/*
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]);
}

View File

@@ -1,126 +0,0 @@
/*
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

@@ -1,375 +0,0 @@
/*
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

@@ -1,33 +0,0 @@
#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

View File

@@ -3,12 +3,22 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypto/sha256.h"
#include "crypto/common.h"
#include <assert.h>
#include <string.h>
#include <stdexcept>
#if defined(__x86_64__) || defined(__amd64__)
#if defined(EXPERIMENTAL_ASM)
#include <cpuid.h>
namespace sha256_sse4
{
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
}
#endif
#endif
// Internal implementation code.
namespace
{
@@ -44,9 +54,10 @@ void inline Initialize(uint32_t* s)
s[7] = 0x5be0cd19ul;
}
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
void Transform(uint32_t* s, const unsigned char* chunk)
/** Perform a number of SHA-256 transformations, processing 64-byte chunks. */
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
{
while (blocks--) {
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
@@ -126,11 +137,59 @@ void Transform(uint32_t* s, const unsigned char* chunk)
s[5] += f;
s[6] += g;
s[7] += h;
chunk += 64;
}
}
} // namespace sha256
typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t);
bool SelfTest(TransformType tr) {
static const unsigned char in1[65] = {0, 0x80};
static const unsigned char in2[129] = {
0,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0
};
static const uint32_t init[8] = {0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul};
static const uint32_t out1[8] = {0xe3b0c442ul, 0x98fc1c14ul, 0x9afbf4c8ul, 0x996fb924ul, 0x27ae41e4ul, 0x649b934cul, 0xa495991bul, 0x7852b855ul};
static const uint32_t out2[8] = {0xce4153b0ul, 0x147c2a86ul, 0x3ed4298eul, 0xe0676bc8ul, 0x79fc77a1ul, 0x2abe1f49ul, 0xb2b055dful, 0x1069523eul};
uint32_t buf[8];
memcpy(buf, init, sizeof(buf));
// Process nothing, and check we remain in the initial state.
tr(buf, nullptr, 0);
if (memcmp(buf, init, sizeof(buf))) return false;
// Process the padded empty string (unaligned)
tr(buf, in1 + 1, 1);
if (memcmp(buf, out1, sizeof(buf))) return false;
// Process 64 spaces (unaligned)
memcpy(buf, init, sizeof(buf));
tr(buf, in2 + 1, 2);
if (memcmp(buf, out2, sizeof(buf))) return false;
return true;
}
TransformType Transform = sha256::Transform;
} // namespace
std::string SHA256AutoDetect()
{
#if defined(EXPERIMENTAL_ASM) && (defined(__x86_64__) || defined(__amd64__))
uint32_t eax, ebx, ecx, edx;
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx >> 19) & 1) {
Transform = sha256_sse4::Transform;
assert(SelfTest(Transform));
return "sse4";
}
#endif
assert(SelfTest(Transform));
return "standard";
}
////// SHA-256
@@ -148,14 +207,14 @@ CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
memcpy(buf + bufsize, data, 64 - bufsize);
bytes += 64 - bufsize;
data += 64 - bufsize;
sha256::Transform(s, buf);
Transform(s, buf, 1);
bufsize = 0;
}
while (end >= data + 64) {
// Process full chunks directly from the source.
sha256::Transform(s, data);
bytes += 64;
data += 64;
if (end - data >= 64) {
size_t blocks = (end - data) / 64;
Transform(s, data, blocks);
data += 64 * blocks;
bytes += 64 * blocks;
}
if (end > data) {
// Fill the buffer with what remains.

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Copyright (c) 2014-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -7,13 +7,19 @@
#include <stdint.h>
#include <stdlib.h>
#include <string>
/** A hasher class for SHA-256. */
class CSHA256
{
public:
static const size_t OUTPUT_SIZE = 32;
private:
uint32_t s[8];
unsigned char buf[64];
size_t bytes;
void FinalizeNoPadding(unsigned char hash[OUTPUT_SIZE], bool enforce_compression);
public:
CSHA256();
CSHA256& Write(const unsigned char* data, size_t len);
void Finalize(unsigned char hash[OUTPUT_SIZE]);
@@ -21,12 +27,11 @@ public:
FinalizeNoPadding(hash, true);
};
CSHA256& Reset();
private:
uint32_t s[8];
unsigned char buf[64];
size_t bytes;
void FinalizeNoPadding(unsigned char hash[OUTPUT_SIZE], bool enforce_compression);
};
/** Autodetect the best available SHA256 implementation.
* Returns the name of the implementation.
*/
std::string SHA256AutoDetect();
#endif // BITCOIN_CRYPTO_SHA256_H

1506
src/crypto/sha256_sse4.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
// Copyright (c) 2012-2014 The Bitcoin Core developers
// Copyright (c) 2019 The Hush developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -143,6 +144,7 @@ public:
CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
ssValue >> value;
} catch(std::exception &e) {
LogPrintf("%s: CDataStream error - %s\n", __FUNCTION__, e.what());
return false;
}
return true;
@@ -207,7 +209,8 @@ public:
try {
CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
ssValue >> value;
} catch (const std::exception&) {
} catch (const std::exception &e) {
LogPrintf("%s: CDataStream error - %s\n", __FUNCTION__, e.what());
return false;
}
return true;

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2017 The Zcash developers
// Copyright (c) 2018-2019 The Hush developers
// Copyright (c) 2019 The Hush developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -49,7 +49,7 @@ void EnforceNodeDeprecation(int nHeight, bool forceLogging, bool fThread) {
if (blocksToDeprecation == 0 || forceLogging) {
msg = strprintf(_("This version has been deprecated as of block height %d."),
DEPRECATION_HEIGHT) + " " +
_("You should upgrade to the latest version of Hush! See Discord for more info: https://myhush.org/discord");
_("You should upgrade to the latest version of Hush.");
LogPrintf("*** %s\n", msg);
CAlert::Notify(msg, fThread);
uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
@@ -58,7 +58,7 @@ void EnforceNodeDeprecation(int nHeight, bool forceLogging, bool fThread) {
} else if (blocksToDeprecation == DEPRECATION_WARN_LIMIT || (blocksToDeprecation < DEPRECATION_WARN_LIMIT && forceLogging)) {
msg = strprintf(_("This version will be deprecated at block height %d, and will automatically shut down."),
DEPRECATION_HEIGHT) + " " +
_("You should upgrade to the latest version of Hush! See Discord for more info: https://myhush.org/discord");
_("You should upgrade to the latest version of Hush.");
LogPrintf("*** %s\n", msg);
CAlert::Notify(msg, fThread);
uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_WARNING);

View File

@@ -1,4 +1,5 @@
// Copyright (c) 2017 The Zcash developers
// Copyright (c) 2019 The Hush developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -24,8 +25,8 @@
// * Shut down WEEKS_UNTIL_DEPRECATION weeks' worth of blocks after the estimated release block height.
// * A warning is shown during the DEPRECATION_WARN_LIMIT worth of blocks prior to shut down.
static const int WEEKS_UNTIL_DEPRECATION = 52;
static const int DEPRECATION_HEIGHT = 2200000;
static const int APPROX_RELEASE_HEIGHT = DEPRECATION_HEIGHT - (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 60);
static const int DEPRECATION_HEIGHT = 5555555;
static const int APPROX_RELEASE_HEIGHT = DEPRECATION_HEIGHT - (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 60);
// Number of blocks before deprecation to warn users
static const int DEPRECATION_WARN_LIMIT = 60 * 24 * 60; // 2 months

View File

@@ -1,3 +1,6 @@
// Copyright (c) 2019-2020 The Hush developers
// Released under the GPLv3
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -135,7 +138,7 @@ TEST_F(DeprecationTest, AlertNotify) {
// -alertnotify restricts the message to safe characters.
auto expectedMsg = strprintf(
"This version will be deprecated at block height %d, and will automatically shut down. You should upgrade to the latest version of Zcash.",
"This version will be deprecated at block height %d, and will automatically shut down. You should upgrade to the latest version of Hush.",
DEPRECATION_HEIGHT);
// Windows built-in echo semantics are different than posixy shells. Quotes and

24
src/hush-smart-chain Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/bash
# Copyright (c) 2019-2020 Hush developers
# set working directory to the location of this script
# readlink -f does not always exist
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )"
cd $DIR
NAME=HUSH3
CLIENTNAME="GoldenSandtrout"
DEFAULTS="-ac_sapling=1 -clientname=$CLIENTNAME"
# This is a Hush-flavored KMD that allows us to pass in arbitary CLI
# flags, since hushd is specific to Hush mainnet
KMD=${KOMODOD:-./komodod}
if [ -f $KMD ]; then
$KMD $DEFAULTS "$@"
else
# We prefix our binary when installed
# system wide on Debain system, to prevent clashes
KMD=hush-komodod
$KMD $DEFAULTS "$@"
fi

View File

@@ -541,7 +541,6 @@ std::string HelpMessage(HelpMessageMode mode)
#ifdef ENABLE_MINING
strUsage += HelpMessageGroup(_("Mining options:"));
strUsage += HelpMessageOpt("-mint", strprintf(_("Mint/stake coins automatically (default: %u)"), 0));
strUsage += HelpMessageOpt("-gen", strprintf(_("Mine/generate coins (default: %u)"), 0));
strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin mining if enabled (-1 = all cores, default: %d)"), 0));
strUsage += HelpMessageOpt("-equihashsolver=<name>", _("Specify the Equihash solver to be used if enabled (default: \"default\")"));
@@ -602,11 +601,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-ac_reward", _("Block reward in satoshis, default is 0"));
strUsage += HelpMessageOpt("-ac_sapling", _("Sapling activation block height"));
strUsage += HelpMessageOpt("-ac_script", _("P2SH/multisig address to receive founders rewards"));
strUsage += HelpMessageOpt("-ac_staked", _("Percentage of blocks that are Proof-Of-Stake, default 0"));
strUsage += HelpMessageOpt("-ac_supply", _("Starting supply, default is 0"));
strUsage += HelpMessageOpt("-ac_timelockfrom", _("Timelocked coinbase start height"));
strUsage += HelpMessageOpt("-ac_timelockgte", _("Timelocked coinbase minimum amount to be locked"));
strUsage += HelpMessageOpt("-ac_timelockto", _("Timelocked coinbase stop height"));
strUsage += HelpMessageOpt("-ac_txpow", _("Enforce transaction-rate limit, default 0"));
return strUsage;
@@ -810,7 +805,7 @@ static void ZC_LoadParams(
float elapsed;
bool found = false;
char cwd[1024];
getcwd(cwd, sizeof(cwd));
bool ret = getcwd(cwd, sizeof(cwd));
LogPrintf("Looking for sapling params, PWD=%s\n", cwd);
@@ -822,7 +817,7 @@ static void ZC_LoadParams(
boost::filesystem::path sapling_spend = "sapling-spend.params";
boost::filesystem::path sapling_output = "sapling-output.params";
if (files_exist(sapling_spend, sapling_output)) {
fprintf(stderr,"Found sapling params in .\n");
LogPrintf("Found sapling params in .\n");
found = true;
}
@@ -831,7 +826,7 @@ static void ZC_LoadParams(
sapling_spend = fs::path("/usr/share/hush") / "sapling-spend.params";
sapling_output = fs::path("/usr/share/hush") / "sapling-output.params";
if (files_exist(sapling_spend, sapling_output)) {
fprintf(stderr,"Found sapling params in /usr/share/hush\n");
LogPrintf("Found sapling params in /usr/share/hush\n");
found=true;
}
}
@@ -841,7 +836,7 @@ static void ZC_LoadParams(
sapling_spend = boost::filesystem::path("..") / "sapling-spend.params";
sapling_output = boost::filesystem::path("..") / "sapling-output.params";
if (files_exist(sapling_spend, sapling_output)) {
fprintf(stderr,"Found sapling params in ..\n");
LogPrintf("Found sapling params in ..\n");
found = true;
}
}
@@ -851,7 +846,7 @@ static void ZC_LoadParams(
sapling_spend = boost::filesystem::path("..") / "hush3" / "sapling-spend.params";
sapling_output = boost::filesystem::path("..") / "hush3" / "sapling-output.params";
if (files_exist(sapling_spend, sapling_output)) {
fprintf(stderr,"Found sapling params in ../hush3\n");
LogPrintf("Found sapling params in ../hush3\n");
found = true;
}
}
@@ -861,7 +856,7 @@ static void ZC_LoadParams(
sapling_spend = boost::filesystem::path("/Applications/silentdragon.app/Contents/MacOS") / "sapling-spend.params";
sapling_output = boost::filesystem::path("/Applications/silentdragon.app/Contents/MacOS") / "sapling-output.params";
if (files_exist(sapling_spend, sapling_output)) {
fprintf(stderr,"Found sapling params in /Applications/Contents/MacOS\n");
LogPrintf("Found sapling params in /Applications/Contents/MacOS\n");
found = true;
}
}
@@ -871,7 +866,7 @@ static void ZC_LoadParams(
sapling_spend = boost::filesystem::path("./silentdragon.app/Contents/MacOS") / "sapling-spend.params";
sapling_output = boost::filesystem::path("./silentdragon.app/Contents/MacOS") / "sapling-output.params";
if (files_exist(sapling_spend, sapling_output)) {
fprintf(stderr,"Found sapling params in /Applications/Contents/MacOS\n");
LogPrintf("Found sapling params in /Applications/Contents/MacOS\n");
found = true;
}
}
@@ -882,13 +877,14 @@ static void ZC_LoadParams(
sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
sapling_output = ZC_GetParamsDir() / "sapling-output.params";
if (files_exist(sapling_spend, sapling_output)) {
fprintf(stderr,"Found sapling params in ~/.zcash\n");
LogPrintf("Found sapling params in ~/.zcash\n");
found = true;
}
}
if (!found) {
// No Sapling params, at least we tried
LogPrintf("No Sapling params found! :(\n");
NoParamsShutdown();
return;
}
@@ -896,7 +892,7 @@ static void ZC_LoadParams(
boost::system::error_code ec1, ec2;
boost::uintmax_t spend_size = file_size(sapling_spend, ec1);
boost::uintmax_t output_size = file_size(sapling_output, ec2);
fprintf(stderr,"Sapling spend: %d bytes, output: %d bytes\n", spend_size, output_size);
fprintf(stderr,"Sapling spend: %d bytes, output: %d bytes\n", (int)spend_size, (int)output_size);
// We could check sha hashes, but we mostly want to detect on-disk file corruption
// or people having a full harddrive. Full validation happens in librustzcash_init_zksnark_params
@@ -905,13 +901,13 @@ static void ZC_LoadParams(
boost::uintmax_t output_valid = 3592860;
//TODO: passing the exact reason for corruption to GUI
if (spend_size != spend_valid) {
fprintf(stderr,"Sapling spend %d bytes != %d is invalid!\n", spend_size, spend_valid);
LogPrintf("Sapling spend %d bytes != %d is invalid!\n", (int)spend_size, (int)spend_valid);
CorruptParamsShutdown();
return;
}
if (output_size != output_valid) {
fprintf(stderr,"Sapling ouput %d bytes != %d is invalid!\n", output_size, output_valid);
LogPrintf("Sapling ouput %d bytes != %d is invalid!\n", (int)output_size, (int)output_valid);
CorruptParamsShutdown();
return;
}
@@ -1378,6 +1374,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
ECC_Start();
globalVerifyHandle.reset(new ECCVerifyHandle());
std::string sha256_algo = SHA256AutoDetect();
LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
//fprintf(stderr,"%s tik10\n", __FUNCTION__);
// Sanity check
if (!InitSanityCheck())
@@ -1756,11 +1755,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
boost::filesystem::remove(GetDataDir() / "komodostate");
boost::filesystem::remove(GetDataDir() / "signedmasks");
pblocktree->WriteReindexing(true);
fprintf(stderr, "%s: Deleted komodostate and signedmasks...\n", __FUNCTION__);
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files
if (fPruneMode)
CleanupBlockRevFiles();
}
fprintf(stderr, "%s: Loading block index...\n", __FUNCTION__);
if (!LoadBlockIndex()) {
strLoadError = _("Error loading block database");
break;
@@ -1820,14 +1822,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
if ( KOMODO_REWIND == 0 )
{
if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3),
GetArg("-checkblocks", 288))) {
LogPrintf("Verifying block DB...");
if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3), GetArg("-checkblocks", 288))) {
strLoadError = _("Corrupted block database detected");
break;
}
}
} catch (const std::exception& e) {
if (fDebug) LogPrintf("%s\n", e.what());
LogPrintf("%s: Error opening block database: %s\n", __FUNCTION__, e.what());
strLoadError = _("Error opening block database");
break;
}
@@ -1838,7 +1840,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (!fLoaded) {
// first suggest a reindex
if (!fReset) {
fprintf(stderr,"%s error in hd data\n", __FUNCTION__);
fprintf(stderr,"%s: error in hd data\n", __FUNCTION__);
bool fRet = uiInterface.ThreadSafeMessageBox(
strLoadError + ".\n\n" + _("error in HDD data, might just need to update to latest, if that doesnt work, then you need to resync"),
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);

View File

@@ -16,7 +16,7 @@
#ifndef H_KOMODO_H
#define H_KOMODO_H
#include "komodo_defs.h"
#include "notaries_staked.h"
#ifdef _WIN32
#define printf(...)
@@ -835,18 +835,6 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block)
}
//fprintf(stderr,"%s connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight);
// Wallet Filter. Disabled here. Cant be activated by notaries or pools with some changes.
if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 || IS_STAKED_NOTARY > -1 )
{
staked_era = STAKED_era(pindex->GetBlockTime());
if ( !fJustCheck && staked_era != lastStakedEra )
{
uint8_t tmp_pubkeys[64][33];
int8_t numSN = numStakedNotaries(tmp_pubkeys,staked_era);
UpdateNotaryAddrs(tmp_pubkeys,numSN);
STAKED_ERA = staked_era;
lastStakedEra = staked_era;
}
}
numnotaries = komodo_notaries(pubkeys,pindex->GetHeight(),pindex->GetBlockTime());
calc_rmd160_sha256(rmd160,pubkeys[0],33);
if ( pindex->GetHeight() > hwmheight )

View File

@@ -28,13 +28,12 @@
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp);
int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp);
unsigned int lwmaGetNextPOSRequired(const CBlockIndex* pindexLast, const Consensus::Params& params);
bool EnsureWalletIsAvailable(bool avoidException);
extern bool fRequestShutdown;
extern CScript KOMODO_EARLYTXID_SCRIPTPUB;
int32_t MarmaraSignature(uint8_t *utxosig,CMutableTransaction &txNew);
uint8_t DecodeMaramaraCoinbaseOpRet(const CScript scriptPubKey,CPubKey &pk,int32_t &height,int32_t &unlockht);
uint32_t komodo_heightstamp(int32_t height);
//#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"curl",(char *)"http://127.0.0.1:7776",0,0,(char *)(cmdstr))
@@ -263,7 +262,7 @@ try_again:
}
else if ( numretries >= 1 )
{
fprintf(stderr,"Maximum number of retries exceeded!\n");
fprintf(stderr,"%s: Maximum number of retries exceeded!\n", __FUNCTION__);
free(s.ptr);
return(0);
}
@@ -545,6 +544,18 @@ int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t
return(retval);
}
CScript komodo_makeopret(CBlock *pblock, bool fNew)
{
std::vector<uint256> vLeaves;
vLeaves.push_back(pblock->hashPrevBlock);
for (int32_t i = 0; i < pblock->vtx.size()-(fNew ? 0 : 1); i++)
vLeaves.push_back(pblock->vtx[i].GetHash());
uint256 merkleroot = GetMerkleRoot(vLeaves);
CScript opret;
opret << OP_RETURN << E_MARSHAL(ss << merkleroot);
return(opret);
}
/*uint256 komodo_getblockhash(int32_t height)
{
uint256 hash; char params[128],*hexstr,*jsonstr; cJSON *result; int32_t i; uint8_t revbuf[32];
@@ -682,66 +693,26 @@ int32_t komodo_WhoStaked(CBlock *pblock, CTxDestination &addressout)
return(0);
}
bool MarmaraPoScheck(char *destaddr,CScript opret,CTransaction staketx);
int32_t komodo_isPoS2(CBlock *pblock)
bool komodo_checkopret(CBlock *pblock, CScript &merkleroot)
{
CBlockIndex *pindex = komodo_blockindex(pblock->GetHash());
if ( pindex != 0 && pindex->segid >= -1 )
{
//fprintf(stderr,"isPoSblock segid.%d\n",pindex->segid);
if ( pindex->segid == -1 )
return(0);
else return(1);
}
return (-1);
merkleroot = pblock->vtx.back().vout.back().scriptPubKey;
return(merkleroot.IsOpReturn() && merkleroot == komodo_makeopret(pblock, false));
}
extern const uint32_t nHushHardforkHeight;
bool hush_hardfork_active(uint32_t time)
{
//This allows simulating a different height via CLI option, with hardcoded height as default
uint32_t nHardForkHeight = GetArg("-hardfork-height", nHushHardforkHeight);
bool isactive = chainActive.Height() > nHardForkHeight;
fprintf(stderr, "%s: active=%d at height=%d and forkheight=%d\n", __FUNCTION__, (int)isactive, chainActive.Height(), nHardForkHeight);
return isactive;
}
int32_t komodo_isPoS(CBlock *pblock,int32_t height,bool fJustCheck)
{
int32_t n,vout,numvouts,ret; uint32_t txtime; uint64_t value; char voutaddr[64],destaddr[64]; CTxDestination voutaddress; uint256 txid; CScript opret;
if ( ASSETCHAINS_STAKED != 0 )
{
if ( fJustCheck )
{
// check pindex first, if that does not work, continue with slow check.
if ( (ret= komodo_isPoS2(pblock)) == 1 )
return (1);
else if ( ret == 0 )
return (0);
}
n = pblock->vtx.size();
//fprintf(stderr,"ht.%d check for PoS numtx.%d numvins.%d numvouts.%d\n",height,n,(int32_t)pblock->vtx[n-1].vin.size(),(int32_t)pblock->vtx[n-1].vout.size());
if ( n > 1 && pblock->vtx[n-1].vin.size() == 1 && pblock->vtx[n-1].vout.size() == 1+(ASSETCHAINS_MARMARA!=0) )
{
txid = pblock->vtx[n-1].vin[0].prevout.hash;
vout = pblock->vtx[n-1].vin[0].prevout.n;
txtime = komodo_txtime(opret,&value,txid,vout,destaddr);
if ( ExtractDestination(pblock->vtx[n-1].vout[0].scriptPubKey,voutaddress) )
{
strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str());
//fprintf(stderr,"voutaddr.%s vs destaddr.%s\n",voutaddr,destaddr);
if ( pblock->vtx[n-1].vout[0].nValue == value && strcmp(destaddr,voutaddr) == 0 )
{
if ( ASSETCHAINS_MARMARA == 0 )
return(1);
else
{
if ( pblock->vtx[n-1].vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 && (numvouts= pblock->vtx[n-1].vout.size()) == 2 )
{
//fprintf(stderr,"validate proper %s %s signature and unlockht preservation\n",voutaddr,destaddr);
return(MarmaraPoScheck(destaddr,opret,pblock->vtx[n-1]));
}
else
{
fprintf(stderr,"reject ht.%d PoS block\n",height);
return(strcmp(ASSETCHAINS_SYMBOL,"MTST2") == 0); // allow until MTST3
}
}
}
}
}
}
return(0);
}
@@ -968,6 +939,7 @@ void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height)
int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height)
{
// after the season HF block ALL new notaries instantly become elegible.
int32_t i,j,n,duplicate; CBlock block; CBlockIndex *pindex; uint8_t notarypubs33[64][33];
memset(mids,-1,sizeof(*mids)*66);
n = komodo_notaries(notarypubs33,height,0);
@@ -1224,6 +1196,7 @@ int32_t komodo_isrealtime(int32_t *kmdheightp)
int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t cmptime,int32_t dispflag)
{
dispflag = 1;
if ( KOMODO_REWIND == 0 && ASSETCHAINS_SYMBOL[0] == 0 && (int64_t)tx.nLockTime >= LOCKTIME_THRESHOLD ) //1473793441 )
{
if ( txheight > 246748 )
@@ -2055,7 +2028,7 @@ bool KOMODO_TEST_ASSETCHAIN_SKIP_POW = 0;
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
{
uint256 hash; arith_uint256 bnTarget,bhash; bool fNegative,fOverflow; uint8_t *script,pubkey33[33],pubkeys[64][33]; int32_t i,scriptlen,possible,PoSperc,is_PoSblock=0,n,failed = 0,notaryid = -1; int64_t checktoshis,value; CBlockIndex *pprev;
uint256 hash,merkleroot; arith_uint256 bnTarget,bhash; bool fNegative,fOverflow; uint8_t *script,pubkey33[33],pubkeys[64][33]; int32_t i,scriptlen,possible,PoSperc,is_PoSblock=0,n,failed = 0,notaryid = -1; int64_t checktoshis,value; CBlockIndex *pprev;
if ( KOMODO_TEST_ASSETCHAIN_SKIP_POW == 0 && Params().NetworkIDString() == "regtest" )
KOMODO_TEST_ASSETCHAIN_SKIP_POW = 1;
if ( !CheckEquihashSolution(pblock, Params()) )
@@ -2185,10 +2158,10 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
// the default daemon miner, checks the actual vins so the only way this will fail, is if someone changes the miner,
// and then creates txs to the crypto address meeting min sigs and puts it in tx position 1.
// If they go through this effort, the block will still fail at connect block, and will be auto purged by the temp file fix.
if ( failed == 0 && ASSETCHAINS_NOTARY_PAY[0] != 0 && pblock->vtx[0].vout.size() > 1 )
if ( failed == 0 && ASSETCHAINS_NOTARY_PAY[0] != 0 && pblock->vtx.size() > 1 )
{
// We check the full validation in ConnectBlock directly to get the amount for coinbase. So just approx here.
if ( slowflag == 0 )
if ( slowflag == 0 && pblock->vtx[0].vout.size() > 1 )
{
// Check the notarisation tx is to the crypto address.
if ( !komodo_is_notarytx(pblock->vtx[1]) == 1 )
@@ -2349,193 +2322,3 @@ struct komodo_staking *komodo_addutxo(struct komodo_staking *array,int32_t *numk
kp->scriptPubKey = pk;
return(array);
}
int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig)
{
static struct komodo_staking *array; static int32_t numkp,maxkp; static uint32_t lasttime;
int32_t PoSperc;
set<CBitcoinAddress> setAddress; struct komodo_staking *kp; int32_t winners,segid,minage,nHeight,counter=0,i,m,siglen=0,nMinDepth = 1,nMaxDepth = 99999999; vector<COutput> vecOutputs; uint32_t block_from_future_rejecttime,besttime,eligible,earliest = 0; CScript best_scriptPubKey; arith_uint256 mindiff,ratio,bnTarget,tmpTarget; CBlockIndex *tipindex,*pindex; CTxDestination address; bool fNegative,fOverflow; uint8_t hashbuf[256]; CTransaction tx; uint256 hashBlock;
if (!EnsureWalletIsAvailable(0))
return 0;
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
assert(pwalletMain != NULL);
*utxovaluep = 0;
memset(utxotxidp,0,sizeof(*utxotxidp));
memset(utxovoutp,0,sizeof(*utxovoutp));
memset(utxosig,0,72);
if ( (tipindex= chainActive.Tip()) == 0 )
return(0);
nHeight = tipindex->GetHeight() + 1;
// Get the PoS% so we can pass it to komodo_stake, this is to adjust PoS dofficulty when it is under the target %!
tmpTarget = komodo_PoWtarget(&PoSperc,bnTarget,nHeight,ASSETCHAINS_STAKED);
if ( (minage= nHeight*3) > 6000 ) // about 100 blocks
minage = 6000;
komodo_segids(hashbuf,nHeight-101,100);
if ( *blocktimep < tipindex->nTime+60)
*blocktimep = tipindex->nTime+60;
bool resetstaker = false;
if ( array != 0 )
{
CBlockIndex* pblockindex = chainActive[tipindex->GetHeight()];
CBlock block; CTxDestination addressout;
if ( ASSETCHAINS_MARMARA != 0 )
resetstaker = true;
else if( ReadBlockFromDisk(block, pblockindex, 1) && komodo_WhoStaked(&block, addressout) != 0 && IsMine(*pwalletMain,addressout) != 0 )
{
resetstaker = true;
fprintf(stderr, "Reset ram staker after mining a block!\n");
}
}
if ( resetstaker || array == 0 || time(NULL) > lasttime+600 )
{
LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
if ( array != 0 )
{
free(array);
array = 0;
maxkp = numkp = 0;
lasttime = 0;
}
if ( ASSETCHAINS_MARMARA == 0 )
{
BOOST_FOREACH(const COutput& out, vecOutputs)
{
if ( (tipindex= chainActive.Tip()) == 0 || tipindex->GetHeight()+1 > nHeight )
{
fprintf(stderr,"chain tip changed during staking loop t.%u counter.%d\n",(uint32_t)time(NULL),counter);
return(0);
}
counter++;
if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth )
{
//fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth);
continue;
}
CAmount nValue = out.tx->vout[out.i].nValue;
if ( nValue < COIN || !out.fSpendable )
continue;
const CScript& pk = out.tx->vout[out.i].scriptPubKey;
if ( ExtractDestination(pk,address) != 0 )
{
if ( IsMine(*pwalletMain,address) == 0 )
continue;
if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 )
{
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk);
//fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp);
}
}
}
}
else
{
struct CCcontract_info *cp,C; uint256 txid; int32_t vout,ht,unlockht; CAmount nValue; char coinaddr[64]; CPubKey mypk,Marmarapk,pk;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_MARMARA);
mypk = pubkey2pk(Mypubkey());
Marmarapk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,Marmarapk,mypk);
SetCCunspents(unspentOutputs,coinaddr,true);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( (nValue= it->second.satoshis) < COIN )
continue;
if ( GetTransaction(txid,tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
const CScript &scriptPubKey = tx.vout[vout].scriptPubKey;
if ( DecodeMaramaraCoinbaseOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,pk,ht,unlockht) != 0 && pk == mypk )
{
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,txid,vout,coinaddr,hashbuf,(CScript)scriptPubKey);
}
// else fprintf(stderr,"SKIP addutxo %.8f numkp.%d vs max.%d\n",(double)nValue/COIN,numkp,maxkp);
}
}
}
lasttime = (uint32_t)time(NULL);
//fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp);
}
block_from_future_rejecttime = (uint32_t)GetAdjustedTime() + 57;
for (i=winners=0; i<numkp; i++)
{
if ( fRequestShutdown || !GetBoolArg("-gen",false) )
return(0);
if ( (tipindex= chainActive.Tip()) == 0 || tipindex->GetHeight()+1 > nHeight )
{
fprintf(stderr,"chain tip changed during staking loop t.%u counter.%d\n",(uint32_t)time(NULL),counter);
return(0);
}
kp = &array[i];
eligible = komodo_stake(0,bnTarget,nHeight,kp->txid,kp->vout,0,(uint32_t)tipindex->nTime+27,kp->address,PoSperc);
if ( eligible > 0 )
{
besttime = 0;
if ( eligible == komodo_stake(1,bnTarget,nHeight,kp->txid,kp->vout,eligible,(uint32_t)tipindex->nTime+27,kp->address,PoSperc) )
{
// have elegible utxo to stake with.
if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || kp->nValue < *utxovaluep)) )
{
// is better than the previous best, so use it instead.
earliest = eligible;
best_scriptPubKey = kp->scriptPubKey;
*utxovaluep = (uint64_t)kp->nValue;
decode_hex((uint8_t *)utxotxidp,32,(char *)kp->txid.GetHex().c_str());
*utxovoutp = kp->vout;
*txtimep = kp->txtime;
}
if ( eligible < block_from_future_rejecttime ) // nothing gained by going earlier
break;
} else continue;
}
}
if ( numkp < 500 && array != 0 )
{
free(array);
array = 0;
maxkp = numkp = 0;
lasttime = 0;
}
if ( earliest != 0 )
{
bool signSuccess; SignatureData sigdata; uint64_t txfee; uint8_t *ptr; uint256 revtxid,utxotxid;
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
const CKeyStore& keystore = *pwalletMain;
txNew.vin.resize(1);
txNew.vout.resize(1);
txfee = 0;
for (i=0; i<32; i++)
((uint8_t *)&revtxid)[i] = ((uint8_t *)utxotxidp)[31 - i];
txNew.vin[0].prevout.hash = revtxid;
txNew.vin[0].prevout.n = *utxovoutp;
txNew.vout[0].scriptPubKey = best_scriptPubKey;
txNew.vout[0].nValue = *utxovaluep - txfee;
txNew.nLockTime = earliest;
CTransaction txNewConst(txNew);
if ( ASSETCHAINS_MARMARA == 0 )
{
signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, *utxovaluep, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId);
UpdateTransaction(txNew,0,sigdata);
ptr = (uint8_t *)&sigdata.scriptSig[0];
siglen = sigdata.scriptSig.size();
for (i=0; i<siglen; i++)
utxosig[i] = ptr[i];
}
else
{
siglen = MarmaraSignature(utxosig,txNew);
if ( siglen > 0 )
signSuccess = true;
else signSuccess = false;
}
if (!signSuccess)
fprintf(stderr,"failed to create signature\n");
else
*blocktimep = earliest;
}
return(siglen);
}

View File

@@ -57,6 +57,12 @@ extern "C"
{
#endif
#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;
#endif
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())

View File

@@ -1,4 +1,4 @@
// Copyright © 2019 The Hush developers
// Copyright (c) 2019 The Hush developers
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* *
@@ -17,7 +17,7 @@
#ifndef KOMODO_DEFS_H
#define KOMODO_DEFS_H
#include "arith_uint256.h"
#include "chain.h"
#include "komodo_nk.h"
#define KOMODO_EARLYTXID_HEIGHT 100
@@ -34,6 +34,9 @@
#define KOMODO_FIRSTFUNGIBLEID 100
#define KOMODO_SAPLING_ACTIVATION 1544832000 // Dec 15th, 2018
#define KOMODO_SAPLING_DEADLINE 1550188800 // Feb 15th, 2019
#define ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX 57
#define ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF 27
#define ASSETCHAINS_STAKED_MIN_POW_DIFF 536900000 // 537000000 537300000
#define _COINBASE_MATURITY 100
// KMD Notary Seasons
@@ -43,10 +46,18 @@
// 1751328000 = dummy timestamp, 1 July 2025!
// 7113400 = 5x current KMD blockheight.
// to add 4th season, change NUM_KMD_SEASONS to 4, and add timestamp and height of activation to these arrays.
#define NUM_KMD_SEASONS 3
#define NUM_KMD_SEASONS 4
#define NUM_KMD_NOTARIES 64
static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, 1751328000};
static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {814000, 1444000, 7113400};
// Approximately mid-day Jan 21 EST
const uint32_t nHushHardforkHeight = 162000;
// No coins/code are currently using timestamp activated fork
const uint32_t nHushHardforkTimestamp = 1579680124; // Jan 22nd 8am UTC
static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, 1751328000};
static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {1,2,nHushHardforkHeight, 5*nHushHardforkHeight};
// Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above.
static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] =
@@ -248,6 +259,73 @@ static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] =
{"gt_AR", "0348430538a4944d3162bb4749d8c5ed51299c2434f3ee69c11a1f7815b3f46135" },
{"patchkez_SH", "03f45e9beb5c4cd46525db8195eb05c1db84ae7ef3603566b3d775770eba3b96ee" },
{"decker_AR", "03ffdf1a116300a78729608d9930742cd349f11a9d64fcc336b8f18592dd9c91bc" }, // 63
},
{
// Season 3.5 third party NN pubkeys from https://github.com/KomodoPlatform/dPoW/blob/master/iguana/3rd_party
{"madmax_NA", "02ef81a360411adf71184ff04d0c5793fc41fd1d7155a28dd909f21f35f4883ac1" },
{"alright_AR", "036a6bca1c2a8166f79fa8a979662892742346cc972b432f8e61950a358d705517" },
{"strob_NA", "02049202f3872877e81035549f6f3a0f868d0ad1c9b0e0d2b48b1f30324255d26d" },
{"hunter_EU", "0378224b4e9d8a0083ce36f2963ec0a4e231ec06b0c780de108e37f41181a89f6a" },
{"phm87_SH", "03889a10f9df2caef57220628515693cf25316fe1b0693b0241419e75d0d0e66ed" },
{"chainmakers_NA", "030e4822bddba10eb50d52d7da13106486651e4436962078ee8d681bc13f4993e9" },
{"indenodes_EU", "03a416533cace0814455a1bb1cd7861ce825a543c6f6284a432c4c8d8875b7ace9" },
{"blackjok3r_SH", "03d23bb5aad3c20414078472220cc5c26bc5aeb41e43d72c99158d450f714d743a" },
{"chainmakers_EU", "034f8c0a504856fb3d80a94c3aa78828c1152daf8ccc45a17c450f32a1e242bb0c" },
{"titomane_AR", "0358cd6d7460654a0ddd5125dd6fa0402d0719999444c6cc3888689a0b4446136a" },
{"fullmoon_SH", "0275031fa79846c5d667b1f7c4219c487d439cd367dd294f73b5ecd55b4e673254" },
{"indenodes_NA", "02b3908eda4078f0e9b6704451cdc24d418e899c0f515fab338d7494da6f0a647b" },
{"chmex_EU", "03e5b7ab96b7271ecd585d6f22807fa87da374210a843ec3a90134cbf4a62c3db1" },
{"metaphilibert_SH", "03b21ff042bf1730b28bde43f44c064578b41996117ac7634b567c3773089e3be3" },
{"ca333_DEV", "029c0342ce2a4f9146c7d1ee012b26f5c2df78b507fb4461bf48df71b4e3031b56" },
{"cipi_NA", "034406ac4cf94e84561c5d3f25384dd59145e92fefc5972a037dc6a44bfa286688" },
{"pungocloud_SH", "0203064e291045187927cc35ed350e046bba604e324bb0e3b214ea83c74c4713b1" },
{"voskcoin_EU", "037bfd946f1dd3736ddd2cb1a0731f8b83de51be5d1be417496fbc419e203bc1fe" },
{"decker_DEV", "02fca8ee50e49f480de275745618db7b0b3680b0bdcce7dcae7d2e0fd5c3345744" },
{"cryptoeconomy_EU", "037d04b7d16de61a44a3fc766bea4b7791023a36675d6cee862fe53defd04dd8f2" },
{"etszombi_EU", "02f65da26061d1b9f1756a274918a37e83086dbfe9a43d2f0b35b9d2f593b31907" },
{"karasugoi_NA", "024ba10f7f5325fd6ec6cab50c5242d142d00fab3537c0002097c0e98f72014177" },
{"pirate_AR", "0353e2747f89968741c24f254caec24f9f49a894a0039ee9ba09234fcbad75c77d" },
{"metaphilibert_AR", "0239e34ad22957bbf4c8df824401f237b2afe8d40f7a645ecd43e8f27dde1ab0da" },
{"zatjum_SH", "03643c3b0a07a34f6ae7b048832e0216b935408dfc48b0c7d3d4faceb38841f3f3" },
{"madmax_AR", "038735b4f6881925e5a9b14275af80fa2b712c8bd57eef26b97e5b153218890e38" },
{"lukechilds_NA", "024607d85ea648511fa50b13f29d16beb2c3a248c586b449707d7be50a6060cf50" },
{"cipi_AR", "025b7655826f5fd3a807cbb4918ef9f02fe64661153ca170db981e9b0861f8c5ad" },
{"tonyl_AR", "03a8db38075c80348889871b4318b0a79a1fd7e9e21daefb4ca6e4f05e5963569c" },
{"infotech_DEV", "0399ff59b0244103486a94acf1e4a928235cb002b20e26a6f3163b4a0d5e62db91" },
{"fullmoon_NA", "02adf6e3cb8a3c94d769102aec9faf2cb073b7f2979ce64efb1161a596a8d16312" },
{"etszombi_AR", "03c786702b81e0122157739c8e2377cf945998d36c0d187ec5c5ff95855848dfdd" },
{"node-9_EU", "024f2402daddee0c8169ccd643e5536c2cf95b9690391c370a65c9dd0169fc3dc6" },
{"phba2061_EU", "02dc98f064e3bf26a251a269893b280323c83f1a4d4e6ccd5e84986cc3244cb7c9" },
{"indenodes_AR", "0242778789986d614f75bcf629081651b851a12ab1cc10c73995b27b90febb75a2" },
{"and1-89_EU", "029f5a4c6046de880cc95eb448d20c80918339daff7d71b73dd3921895559d7ca3" },
{"komodopioneers_SH", "02ae196a1e93444b9fcac2b0ccee428a4d9232a00b3a508484b5bccaedc9bac55e" },
{"komodopioneers_EU", "03c7fef345ca6b5326de9d5a38498638801eee81bfea4ca8ffc3dacac43c27b14d" },
{"d0ct0r_NA", "0235b211469d7c1881d30ab647e0d6ddb4daf9466f60e85e6a33a92e39dedde3a7" },
{"kolo_DEV", "03dc7c71a5ef7104f81e62928446c4216d6e9f68d944c893a21d7a0eba74b1cb7c" },
{"peer2cloud_AR", "0351c784d966dbb79e1bab4fad7c096c1637c98304854dcdb7d5b5aeceb94919b4" },
{"webworker01_SH", "0221365d89a6f6373b15daa4a50d56d34ad1b4b8a48a7fd090163b6b5a5ecd7a0a" },
{"webworker01_NA", "03bfc36a60194b495c075b89995f307bec68c1bcbe381b6b29db47af23494430f9" },
{"pbca26_NA", "038319dcf74916486dbd506ac866d184c17c3202105df68c8335a1a1079ef0dfcc" },
{"indenodes_SH", "031d1584cf0eb4a2d314465e49e2677226b1615c3718013b8d6b4854c15676a58c" },
{"pirate_NA", "034899e6e884b3cb1f491d296673ab22a6590d9f62020bea83d721f5c68b9d7aa7" },
{"lukechilds_AR", "031ee242e67a8166e489c0c4ed1e5f7fa32dff19b4c1749de35f8da18befa20811" },
{"dragonhound_NA", "022405dbc2ea320131e9f0c4115442c797bf0f2677860d46679ac4522300ce8c0a" },
{"fullmoon_AR", "03cd152ae20adcc389e77acad25953fc2371961631b35dc92cf5c96c7729c2e8d9" },
{"chainzilla_SH", "03fe36ff13cb224217898682ce8b87ba6e3cdd4a98941bb7060c04508b57a6b014" },
{"titomane_EU", "03d691cd0914a711f651082e2b7b27bee778c1309a38840e40a6cf650682d17bb5" },
{"jeezy_EU", "022bca828b572cb2b3daff713ed2eb0bbc7378df20f799191eebecf3ef319509cd" },
{"titomane_SH", "038c2a64f7647633c0e74eec93f9a668d4bf80214a43ed7cd08e4e30d3f2f7acfb" },
{"alien_AR", "024f20c096b085308e21893383f44b4faf1cdedea9ad53cc7d7e7fbfa0c30c1e71" },
{"pirate_EU", "0371f348b4ac848cdfb732758f59b9fdd64285e7adf769198771e8e203638db7e6" },
{"thegaltmines_NA", "03e1d4cec2be4c11e368ff0c11e80cd1b09da8026db971b643daee100056b110fa" },
{"computergenie_NA", "02f945d87b7cd6e9f2173a110399d36b369edb1f10bdf5a4ba6fd4923e2986e137" },
{"nutellalicka_SH", "035ec5b9e88734e5bd0f3bd6533e52f917d51a0e31f83b2297aabb75f9798d01ef" },
{"chainstrike_SH", "0221f9dee04b7da1f3833c6ea7f7325652c951b1c239052b0dadb57209084ca6a8" },
{"hunter_SH", "02407db70ad30ce4dfaee8b4ae35fae88390cad2b0ba0373fdd6231967537ccfdf" },
{"alien_EU", "022b85908191788f409506ebcf96a892f3274f352864c3ed566c5a16de63953236" },
{"gt_AR", "0307c1cf89bd8ed4db1b09a0a98cf5f746fc77df3803ecc8611cf9455ec0ce6960" },
{"patchkez_SH", "03d7c187689bf829ca076a30bbf36d2e67bb74e16a3290d8a55df21d6cb15c80c1" },
{"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" }
}
};
@@ -271,11 +349,14 @@ int32_t MAX_BLOCK_SIZE(int32_t height);
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
extern uint32_t ASSETCHAIN_INIT, ASSETCHAINS_MAGIC;
extern int32_t ASSETCHAINS_LWMAPOS, ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER,ASSETCHAINS_BLOCKTIME;
extern int32_t ASSETCHAINS_LWMAPOS, ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER,ASSETCHAINS_BLOCKTIME;
extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_FOUNDERS_REWARD;
extern int32_t ASSETCHAINS_LWMAPOS, ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER,ASSETCHAINS_BLOCKTIME;
extern int32_t KOMODO_BLOCK_POSUNITS, KOMODO_CONSECUTIVE_POS_THRESHOLD, KOMODO_NOPOS_THRESHHOLD;
extern uint64_t ASSETCHAINS_TIMELOCKGTE;
extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH,KOMODO_INITDONE;
extern uint32_t ASSETCHAINS_ALGO,ASSETCHAINS_EQUIHASH,KOMODO_INITDONE;
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,KOMODO_ON_DEMAND,KOMODO_PASSPORT_INITDONE,ASSETCHAINS_STAKED,KOMODO_NSPV;
extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_LASTERA,ASSETCHAINS_CBOPRET;
@@ -286,8 +367,6 @@ extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY,ASSETCHAINS_SCRIPTP
extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_MARMARA;
extern std::vector<std::string> ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS;
extern int32_t KOMODO_BLOCK_POSUNITS, KOMODO_CONSECUTIVE_POS_THRESHOLD, KOMODO_NOPOS_THRESHHOLD;
extern uint256 KOMODO_EARLYTXID;
extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE,KOMODO_DEALERNODE;
@@ -296,20 +375,22 @@ extern std::string CCerror,ASSETCHAINS_CCLIB;
extern uint8_t ASSETCHAINS_CCDISABLES[256];
extern int32_t USE_EXTERNAL_PUBKEY;
extern std::string NOTARY_PUBKEY;
extern std::string NOTARY_PUBKEY,NOTARY_ADDRESS;
extern int32_t KOMODO_EXCHANGEWALLET;
extern std::string DONATION_PUBKEY;
extern uint8_t ASSETCHAINS_PRIVATE;
extern int32_t USE_EXTERNAL_PUBKEY;
extern char NOTARYADDRS[64][64]; // should be depreciated later. Only affects labs.
extern char NOTARYADDRS[64][64];
extern char NOTARY_ADDRESSES[NUM_KMD_SEASONS][64][64];
extern int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL;
extern int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL,IS_STAKED_NOTARY,STAKED_ERA;
extern int32_t ASSETCHAINS_EARLYTXIDCONTRACT;
extern int32_t ASSETCHAINS_STAKED_SPLIT_PERCENTAGE;
int tx_height( const uint256 &hash );
extern std::vector<std::string> vWhiteListAddress;
extern std::map <std::int8_t, int32_t> mapHeightEvalActivate;
void komodo_netevent(std::vector<uint8_t> payload);
int32_t getacseason(uint32_t timestamp);
int32_t getkmdseason(int32_t height);
#define IGUANA_MAXSCRIPTSIZE 10001
#define KOMODO_KVDURATION 1440
@@ -341,8 +422,19 @@ uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256
int32_t komodo_currentheight();
int32_t komodo_notarized_bracket(struct notarized_checkpoint *nps[2],int32_t height);
arith_uint256 komodo_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime);
bool hush_hardfork_active(uint32_t time);
uint256 Parseuint256(const char *hexstr);
void komodo_sendmessage(int32_t minpeers, int32_t maxpeers, const char *message, std::vector<uint8_t> payload);
CBlockIndex *komodo_getblockindex(uint256 hash);
int32_t komodo_nextheight();
CBlockIndex *komodo_blockindex(uint256 hash);
CBlockIndex *komodo_chainactive(int32_t height);
int32_t komodo_blockheight(uint256 hash);
bool komodo_txnotarizedconfirmed(uint256 txid);
int32_t komodo_blockload(CBlock& block, CBlockIndex *pindex);
uint32_t komodo_chainactive_timestamp();
uint32_t GetLatestTimestamp(int32_t height);
#ifndef KOMODO_NSPV_FULLNODE
#define KOMODO_NSPV_FULLNODE (KOMODO_NSPV <= 0)

View File

@@ -20,7 +20,6 @@
/*#include "secp256k1/include/secp256k1.h"
#include "secp256k1/include/secp256k1_schnorrsig.h"
#include "secp256k1/include/secp256k1_musig.h"
int32_t dummy_linker_tricker()
{
secp256k1_context *ctx = 0; std::vector<uint8_t> musig64; CPubKey pk; secp256k1_schnorrsig musig; secp256k1_pubkey combined_pk;
@@ -28,8 +27,6 @@ int32_t dummy_linker_tricker()
return(1);
}*/
int32_t MarmaraValidateCoinbase(int32_t height,CTransaction tx);
int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base)
{
int32_t baseid; struct komodo_state *sp; int64_t netliability,maxallowed,maxval;
@@ -703,8 +700,29 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim
{
if ( i == 0 && txn_count > 1 && block.vtx[txn_count-1].vout.size() > 0 && block.vtx[txn_count-1].vout[0].nValue == 5000 )
{
/*
if ( block.vtx[txn_count-1].vin.size() == 1 && GetTransaction(block.vtx[txn_count-1].vin[0].prevout.hash,tx,hash,false) && block.vtx[0].vout[0].scriptPubKey == tx.vout[block.vtx[txn_count-1].vin[0].prevout.n].scriptPubKey )
notmatched = 1;
*/
if ( block.vtx[txn_count-1].vin.size() == 1 ) {
uint256 hashNotaryProofVin = block.vtx[txn_count-1].vin[0].prevout.hash;
int fNotaryProofVinTxFound = GetTransaction(hashNotaryProofVin,tx,hash,false);
if (!fNotaryProofVinTxFound) {
// try to search in the same block
BOOST_FOREACH(const CTransaction &txInThisBlock, block.vtx) {
if (txInThisBlock.GetHash() == hashNotaryProofVin) {
fNotaryProofVinTxFound = 1;
tx = txInThisBlock;
hash = block.GetHash();
break;
}
}
}
if ( fNotaryProofVinTxFound && block.vtx[0].vout[0].scriptPubKey == tx.vout[block.vtx[txn_count-1].vin[0].prevout.n].scriptPubKey )
{
notmatched = 1;
}
}
}
n = block.vtx[i].vin.size();
for (j=0; j<n; j++)
@@ -720,14 +738,6 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim
}
}
}
if ( height > 0 && ASSETCHAINS_MARMARA != 0 && (height & 1) == 0 )
{
if ( MarmaraValidateCoinbase(height,block.vtx[0]) < 0 )
{
fprintf(stderr,"MARMARA error ht.%d constrains even height blocks to pay 100%% to CC in vout0 with opreturn\n",height);
return(-1);
}
}
if ( ASSETCHAINS_SYMBOL[0] == 0 ||
((ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD) && height > 1) ||
NetworkUpgradeActive(height, Params().GetConsensus(), Consensus::UPGRADE_SAPLING) )
@@ -1232,7 +1242,6 @@ void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_
printf("numR.%d numV.%d numN.%d count.%d\n",numR,numV,numN,count);
/*else if ( func == 'K' ) // KMD height: stop after 1st
else if ( func == 'T' ) // KMD height+timestamp: stop after 1st
else if ( func == 'N' ) // notarization, scan backwards 1440+ blocks;
else if ( func == 'V' ) // price feed: can stop after 1440+
else if ( func == 'R' ) // opreturn:*/
@@ -2016,7 +2025,6 @@ const char *Techstocks[] =
{ "AAPL","ADBE","ADSK","AKAM","AMD","AMZN","ATVI","BB","CDW","CRM","CSCO","CYBR","DBX","EA","FB","GDDY","GOOG","GRMN","GSAT","HPQ","IBM","INFY","INTC","INTU","JNPR","MSFT","MSI","MU","MXL","NATI","NCR","NFLX","NTAP","NVDA","ORCL","PANW","PYPL","QCOM","RHT","S","SHOP","SNAP","SPOT","SYMC","SYNA","T","TRIP","TWTR","TXN","VMW","VOD","VRSN","VZ","WDC","XRX","YELP","YNDX","ZEN"
};
const char *Metals[] = { "XAU", "XAG", "XPT", "XPD", };
const char *Markets[] = { "DJIA", "SPX", "NDX", "VIX" };
*/
@@ -2142,7 +2150,6 @@ int32_t get_cryptoprices(uint32_t *prices,const char *list[],int32_t n,std::vect
}
return(price);
}
uint32_t get_currencyprice(const char *symbol)
{
char url[512]; cJSON *json,*obj; uint32_t price = 0;
@@ -2155,7 +2162,6 @@ uint32_t get_currencyprice(const char *symbol)
}
return(price);
}
int32_t get_stocks(const char *list[],int32_t n)
{
int32_t i,errs=0; uint32_t price;
@@ -2822,3 +2828,4 @@ int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblo
pthread_mutex_unlock(&pricemutex);
return(retval);
}

View File

@@ -48,11 +48,6 @@ struct komodo_state KOMODO_STATES[34];
int COINBASE_MATURITY = _COINBASE_MATURITY;//100;
unsigned int WITNESS_CACHE_SIZE = _COINBASE_MATURITY+10;
uint256 KOMODO_EARLYTXID;
int32_t KOMODO_BLOCK_POSUNITS = 1024; // one block is 1024 units
int32_t KOMODO_MIN_STAKEAGE = 150; // 1/2 this should also be a cap on the POS averaging window, or startup could be too easy
int32_t KOMODO_CONSECUTIVE_POS_THRESHOLD = 7;
int32_t KOMODO_NOPOS_THRESHHOLD = 150; // if we have no POS blocks in this many blocks, set to default difficulty
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,IS_STAKED_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,STAKED_ERA,KOMODO_CONNECTING = -1,KOMODO_DEALERNODE,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS,ASSETCHAINS_CBMATURITY,KOMODO_NSPV;
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1;

View File

@@ -431,6 +431,20 @@ void NSPV_broadcast_purge(struct NSPV_broadcastresp *ptr)
memset(ptr,0,sizeof(*ptr));
}
int32_t NSPV_rwremoterpcresp(int32_t rwflag,uint8_t *serialized,struct NSPV_remoterpcresp *ptr, int32_t slen)
{
int32_t len = 0;
len+=iguana_rwbuf(rwflag,&serialized[len],sizeof(ptr->method),(uint8_t*)ptr->method);
len+=iguana_rwbuf(rwflag,&serialized[len],slen-len,(uint8_t*)ptr->json);
return(len);
}
void NSPV_remoterpc_purge(struct NSPV_remoterpcresp *ptr)
{
if ( ptr != 0 )
memset(ptr,0,sizeof(*ptr));
}
// useful utility functions
uint256 NSPV_doublesha256(uint8_t *data,int32_t datalen)

View File

@@ -44,12 +44,16 @@
#define NSPV_TXIDSRESP 0x0f
#define NSPV_MEMPOOL 0x10
#define NSPV_MEMPOOLRESP 0x11
#define NSPV_CCMODULEUTXOS 0x12
#define NSPV_CCMODULEUTXOSRESP 0x13
#define NSPV_MEMPOOL_ALL 0
#define NSPV_MEMPOOL_ADDRESS 1
#define NSPV_MEMPOOL_ISSPENT 2
#define NSPV_MEMPOOL_INMEMPOOL 3
#define NSPV_MEMPOOL_CCEVALCODE 4
#define NSPV_CC_TXIDS 16
#define NSPV_REMOTERPC 0x14
#define NSPV_REMOTERPCRESP 0x15
int32_t NSPV_gettransaction(int32_t skipvalidation,int32_t vout,uint256 txid,int32_t height,CTransaction &tx,uint256 &hashblock,int32_t &txheight,int32_t &currentheight,int64_t extradata,uint32_t tiptime,int64_t &rewardsum);
UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis);
@@ -179,4 +183,10 @@ struct NSPV_CCmtxinfo
struct NSPV_utxoresp used[NSPV_MAXVINS];
};
struct NSPV_remoterpcresp
{
char method[64];
char json[11000];
};
#endif // KOMODO_NSPV_DEFSH

View File

@@ -20,6 +20,13 @@
// NSPV_get... functions need to return the exact serialized length, which is the size of the structure minus size of pointers, plus size of allocated data
#include "notarisationdb.h"
#include "rpc/server.h"
static std::map<std::string,bool> nspv_remote_commands = {{"channelsopen", true},{"channelspayment", true},{"channelsclose", true},{"channelsrefund", true},
{"channelslist", true},{"channelsinfo", true},{"oraclescreate", true},{"oraclesfund", true},{"oraclesregister", true},{"oraclessubscribe", true},
{"oraclesdata", true},{"oraclesinfo", false},{"oracleslist", false},{"gatewaysbind", true},{"gatewaysdeposit", true},{"gatewaysclaim", true},{"gatewayswithdraw", true},
{"gatewayspartialsign", true},{"gatewayscompletesigning", true},{"gatewaysmarkdone", true},{"gatewayspendingdeposits", true},{"gatewayspendingwithdraws", true},
{"gatewaysprocessed", true},{"gatewaysinfo", false},{"gatewayslist", false},{"faucetfund", true},{"faucetget", true}};
struct NSPV_ntzargs
{
@@ -206,6 +213,229 @@ int32_t NSPV_getaddressutxos(struct NSPV_utxosresp *ptr,char *coinaddr,bool isCC
return(0);
}
class BaseCCChecker {
public:
/// base check function
/// @param vouts vouts where checked vout and opret are
/// @param nvout vout index to check
/// @param evalcode which must be in the opret
/// @param funcids allowed funcids in string
/// @param filtertxid txid that should be in the opret (after funcid)
virtual bool checkCC(uint256 txid, const std::vector<CTxOut> &vouts, int32_t nvout, uint8_t evalcode, std::string funcids, uint256 filtertxid) = 0;
};
/// default cc vout checker for use in NSPV_getccmoduleutxos
/// checks if a vout is cc, has required evalcode, allowed funcids and txid
/// check both cc opret and last vout opret
/// maybe customized in via inheritance
class DefaultCCChecker : public BaseCCChecker {
private:
public:
DefaultCCChecker() { }
virtual bool checkCC(uint256 txid, const std::vector<CTxOut> &vouts, int32_t nvout, uint8_t evalcode, std::string funcids, uint256 filtertxid)
{
CScript opret, dummy;
std::vector< vscript_t > vParams;
vscript_t vopret;
if (nvout < vouts.size())
{
// first check if it is cc vout
if (vouts[nvout].scriptPubKey.IsPayToCryptoCondition(&dummy, vParams))
{
// try to find cc opret
if (vParams.size() > 0)
{
COptCCParams p(vParams[0]); // parse vout data
if (p.vData.size() > 0)
{
vopret = p.vData[0]; // get opret data
}
}
// if no cc opret check last vout opret
if (vopret.size() == 0)
{
GetOpReturnData(vouts.back().scriptPubKey, vopret);
}
if (vopret.size() > 2)
{
uint8_t opretEvalcode, opretFuncid;
uint256 opretTxid;
bool isEof = true;
bool isCreateTx = false;
// parse opret first 3 fields:
bool parseOk = E_UNMARSHAL(vopret,
ss >> opretEvalcode;
ss >> opretFuncid;
if (funcids.size() > 0 && opretFuncid == funcids[0]) // this means that we check txid only for second+ funcid in array (considering that the first funcid is the creation txid itself like tokens)
{
isCreateTx = true;
}
else
{
ss >> opretTxid;
isCreateTx = false;
}
isEof = ss.eof(); );
opretTxid = revuint256(opretTxid);
std::cerr << __func__ << " " << "opretEvalcode=" << opretEvalcode << " opretFuncid=" << (char)opretFuncid << " isCreateTx=" << isCreateTx << " opretTxid=" << opretTxid.GetHex() << std::endl;
if( parseOk /*parseOk=true if eof reached*/|| !isEof /*more data means okay*/)
{
if (evalcode == opretEvalcode && std::find(funcids.begin(), funcids.end(), (char)opretFuncid) != funcids.end() &&
(isCreateTx && filtertxid == txid || !isCreateTx && filtertxid == opretTxid))
{
return true;
}
}
}
}
}
return false;
}
};
static class DefaultCCChecker defaultCCChecker;
// table of pluggable cc vout checkers for usage in NSPV_getccmoduleutxos
// if the checker is not in the table for a evalcode then defaultCCChecker is used
static std::map<uint8_t, class BaseCCChecker*> ccCheckerTable =
{
};
// implements SPV server's part, gets cc module utxos, filtered by evalcode, funcid and txid on opret, for the specified amount
// if the amount param is 0 returns total available filtere utxo amount and returns no utxos
// first char funcid in the string param is considered as the creation tx funcid so filtertxid is compared to the creation txid itself
// for other funcids filtertxid is compared to the txid in opreturn
int32_t NSPV_getccmoduleutxos(struct NSPV_utxosresp *ptr, char *coinaddr, int64_t amount, uint8_t evalcode, std::string funcids, uint256 filtertxid)
{
int64_t total = 0, totaladded = 0;
uint32_t locktime;
int32_t tipheight=0, len, maxlen;
int32_t maxinputs = CC_MAXVINS;
std::vector<struct CC_utxo> utxoSelected;
utxoSelected.reserve(CC_MAXVINS);
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
SetCCunspents(unspentOutputs, coinaddr, true);
maxlen = MAX_BLOCK_SIZE(tipheight) - 512;
//maxlen /= sizeof(*ptr->utxos); // TODO why was this? we need maxlen in bytes, don't we?
//ptr->numutxos = (uint16_t)unspentOutputs.size();
//if (ptr->numutxos >= 0 && ptr->numutxos < maxlen)
//{
ptr->utxos = NULL;
ptr->numutxos = 0;
strncpy(ptr->coinaddr, coinaddr, sizeof(ptr->coinaddr) - 1);
ptr->CCflag = 1;
tipheight = chainActive.LastTip()->GetHeight();
ptr->nodeheight = tipheight; // will be checked in libnspv
//}
// select all appropriate utxos:
std::cerr << __func__ << " " << "searching addr=" << coinaddr << std::endl;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it = unspentOutputs.begin(); it != unspentOutputs.end(); it++)
{
if (myIsutxo_spentinmempool(ignoretxid, ignorevin, it->first.txhash, (int32_t)it->first.index) == 0)
{
//const CCoins *pcoins = pcoinsTip->AccessCoins(it->first.txhash); <-- no opret in coins
CTransaction tx;
uint256 hashBlock;
int32_t nvout = it->first.index;
if (myGetTransaction(it->first.txhash, tx, hashBlock))
{
class BaseCCChecker *baseChecker = ccCheckerTable[evalcode];
// if a checker is set for evalcode use it otherwise use the default checker:
if (baseChecker && baseChecker->checkCC(it->first.txhash, tx.vout, nvout, evalcode, funcids, filtertxid) || defaultCCChecker.checkCC(it->first.txhash, tx.vout, nvout, evalcode, funcids, filtertxid))
{
std::cerr << __func__ << " " << "filtered utxo with amount=" << tx.vout[nvout].nValue << std::endl;
struct CC_utxo utxo;
utxo.txid = it->first.txhash;
utxo.vout = (int32_t)it->first.index;
utxo.nValue = it->second.satoshis;
//utxo.height = it->second.blockHeight;
utxoSelected.push_back(utxo);
total += it->second.satoshis;
}
}
else
std::cerr << __func__ << " " << "ERROR: cant load tx for txid, please reindex" << std::endl;
}
}
if (amount == 0) {
// just return total value
ptr->total = total;
len = (int32_t)(sizeof(*ptr) - sizeof(ptr->utxos)/*subtract not serialized part of NSPV_utxoresp*/);
return len;
}
// pick optimal utxos for the requested amount
CAmount remains = amount;
std::vector<struct CC_utxo> utxoAdded;
while (utxoSelected.size() > 0)
{
int64_t below = 0, above = 0;
int32_t abovei = -1, belowi = -1, ind = -1;
if (CC_vinselect(&abovei, &above, &belowi, &below, utxoSelected.data(), utxoSelected.size(), remains) < 0)
{
std::cerr << "error CC_vinselect" << " remains=" << remains << " amount=" << amount << " abovei=" << abovei << " belowi=" << belowi << " ind=" << " utxoSelected.size()=" << utxoSelected.size() << ind << std::endl;
return 0;
}
if (abovei >= 0) // best is 'above'
ind = abovei;
else if (belowi >= 0) // second try is 'below'
ind = belowi;
else
{
std::cerr << "error finding unspent" << " remains=" << remains << " amount=" << amount << " abovei=" << abovei << " belowi=" << belowi << " ind=" << " utxoSelected.size()=" << utxoSelected.size() << ind << std::endl;
return 0;
}
utxoAdded.push_back(utxoSelected[ind]);
total += utxoSelected[ind].nValue;
remains -= utxoSelected[ind].nValue;
// remove used utxo[ind]:
utxoSelected[ind] = utxoSelected.back();
utxoSelected.pop_back();
if (total >= amount) // found the requested amount
break;
if (utxoAdded.size() >= maxinputs) // reached maxinputs
break;
}
ptr->numutxos = (uint16_t)utxoAdded.size();
ptr->total = total;
ptr->utxos = (NSPV_utxoresp*)calloc(ptr->numutxos, sizeof(ptr->utxos[0]));
for (uint16_t i = 0; i < ptr->numutxos; i++)
{
ptr->utxos[i].satoshis = utxoAdded[i].nValue;
ptr->utxos[i].txid = utxoAdded[i].txid;
ptr->utxos[i].vout = utxoAdded[i].vout;
}
len = (int32_t)(sizeof(*ptr) - sizeof(ptr->utxos)/*subtract not serialized part of NSPV_utxoresp*/ + sizeof(*ptr->utxos)*ptr->numutxos);
if (len < maxlen)
return len; // good length
else
{
NSPV_utxosresp_purge(ptr);
return 0;
}
}
int32_t NSPV_getaddresstxids(struct NSPV_txidsresp *ptr,char *coinaddr,bool isCC,int32_t skipcount,uint32_t filter)
{
int32_t maxlen,txheight,ind=0,n = 0,len = 0; CTransaction tx; uint256 hashBlock;
@@ -425,6 +655,62 @@ int32_t NSPV_mempooltxids(struct NSPV_mempoolresp *ptr,char *coinaddr,uint8_t is
return(0);
}
int32_t NSPV_remoterpc(struct NSPV_remoterpcresp *ptr,char *json,int n)
{
std::vector<uint256> txids; int32_t i,len = 0; UniValue result; std::string response;
UniValue request(UniValue::VOBJ),rpc_result(UniValue::VOBJ); JSONRequest jreq; CPubKey mypk;
try
{
request.read(json,n);
jreq.parse(request);
strcpy(ptr->method,jreq.strMethod.c_str());
len+=sizeof(ptr->method);
std::map<std::string, bool>::iterator it = nspv_remote_commands.find(jreq.strMethod);
if (it==nspv_remote_commands.end())
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not supported!");
const CRPCCommand *cmd=tableRPC[jreq.strMethod];
if (!cmd)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
if (it->second)
{
if (!request.exists("mypk"))
throw JSONRPCError(RPC_PARSE_ERROR, "No pubkey supplied in remote rpc request, necessary for this type of rpc");
std::string str=request["mypk"].get_str();
mypk=pubkey2pk(ParseHex(str));
if (!mypk.IsValid())
throw JSONRPCError(RPC_PARSE_ERROR, "Not valid pubkey passed in remote rpc call");
}
if ((result = cmd->actor(jreq.params,false,mypk)).isObject() || result.isArray())
{
rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
response=rpc_result.write();
memcpy(ptr->json,response.c_str(),response.size());
len+=response.size();
return (len);
}
else throw JSONRPCError(RPC_MISC_ERROR, "Error in executing RPC on remote node");
}
catch (const UniValue& objError)
{
rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id);
response=rpc_result.write();
}
catch (const runtime_error& e)
{
rpc_result = JSONRPCReplyObj(NullUniValue,JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
response=rpc_result.write();
}
catch (const std::exception& e)
{
rpc_result = JSONRPCReplyObj(NullUniValue,JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
response=rpc_result.write();
}
memcpy(ptr->json,response.c_str(),response.size());
len+=response.size();
return (len);
}
uint8_t *NSPV_getrawtx(CTransaction &tx,uint256 &hashBlock,int32_t *txlenp,uint256 txid)
{
uint8_t *rawtx = 0;
@@ -860,7 +1146,85 @@ void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a req
}
}
}
}
else if ( request[0] == NSPV_REMOTERPC )
{
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_remoterpcresp R; int32_t p;
p = 1;
p+=iguana_rwnum(0,&request[p],sizeof(slen),&slen);
memset(&R,0,sizeof(R));
if (request.size() == p+slen && (slen=NSPV_remoterpc(&R,(char *)&request[p],slen))>0 )
{
response.resize(1 + slen);
response[0] = NSPV_REMOTERPCRESP;
NSPV_rwremoterpcresp(1,&response[1],&R,slen);
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
NSPV_remoterpc_purge(&R);
}
}
}
else if (request[0] == NSPV_CCMODULEUTXOS) // get cc module utxos from coinaddr for the requested amount, evalcode, funcid list and txid
{
//fprintf(stderr,"utxos: %u > %u, ind.%d, len.%d\n",timestamp,pfrom->prevtimes[ind],ind,len);
if (timestamp > pfrom->prevtimes[ind])
{
struct NSPV_utxosresp U;
char coinaddr[64];
int64_t amount;
uint8_t evalcode;
char funcids[27];
uint256 filtertxid;
bool errorFormat = false;
const int32_t BITCOINADDRESSMINLEN = 20;
int32_t minreqlen = sizeof(uint8_t) + sizeof(uint8_t) + BITCOINADDRESSMINLEN + sizeof(amount) + sizeof(evalcode) + sizeof(uint8_t) + sizeof(filtertxid);
int32_t maxreqlen = sizeof(uint8_t) + sizeof(uint8_t) + sizeof(coinaddr)-1 + sizeof(amount) + sizeof(evalcode) + sizeof(uint8_t) + sizeof(funcids)-1 + sizeof(filtertxid);
if (len >= minreqlen && len <= maxreqlen)
{
n = 1;
int32_t addrlen = request[n++];
if (addrlen < sizeof(coinaddr))
{
memcpy(coinaddr, &request[n], addrlen);
coinaddr[addrlen] = 0;
n += addrlen;
iguana_rwnum(0, &request[n], sizeof(amount), &amount);
n += sizeof(amount);
iguana_rwnum(0, &request[n], sizeof(evalcode), &evalcode);
n += sizeof(evalcode);
int32_t funcidslen = request[n++];
if (funcidslen < sizeof(funcids))
{
memcpy(funcids, &request[n], funcidslen);
funcids[funcidslen] = 0;
n += funcidslen;
iguana_rwbignum(0, &request[n], sizeof(filtertxid), (uint8_t *)&filtertxid);
std::cerr << __func__ << " " << "request addr=" << coinaddr << " amount=" << amount << " evalcode=" << (int)evalcode << " funcids=" << funcids << " filtertxid=" << filtertxid.GetHex() << std::endl;
memset(&U, 0, sizeof(U));
if ((slen = NSPV_getccmoduleutxos(&U, coinaddr, amount, evalcode, funcids, filtertxid)) > 0)
{
std::cerr << __func__ << " " << "created utxos, slen=" << slen << std::endl;
response.resize(1 + slen);
response[0] = NSPV_CCMODULEUTXOSRESP;
if (NSPV_rwutxosresp(1, &response[1], &U) == slen)
{
pfrom->PushMessage("nSPV", response);
pfrom->prevtimes[ind] = timestamp;
std::cerr << __func__ << " " << "returned nSPV response" << std::endl;
}
NSPV_utxosresp_purge(&U);
}
}
}
}
}
}
}
}
#endif // KOMODO_NSPVFULLNODE_H

View File

@@ -203,6 +203,12 @@ void komodo_nSPVresp(CNode *pfrom,std::vector<uint8_t> response) // received a r
NSPV_rwbroadcastresp(0,&response[1],&NSPV_broadcastresult);
fprintf(stderr,"got broadcast response %u size.%d %s retcode.%d\n",timestamp,(int32_t)response.size(),NSPV_broadcastresult.txid.GetHex().c_str(),NSPV_broadcastresult.retcode);
break;
case NSPV_CCMODULEUTXOSRESP:
NSPV_utxosresp_purge(&NSPV_utxosresult);
NSPV_rwutxosresp(0, &response[1], &NSPV_utxosresult);
fprintf(stderr, "got cc module utxos response %u size.%d\n", timestamp, (int32_t)response.size());
break;
default: fprintf(stderr,"unexpected response %02x size.%d at %u\n",response[0],(int32_t)response.size(),timestamp);
break;
}
@@ -925,4 +931,51 @@ UniValue NSPV_broadcast(char *hex)
return(NSPV_broadcast_json(&B,txid));
}
// gets cc utxos filtered by evalcode, funcid and txid in opret, for the specified amount
// if amount == 0 returns total and no utxos
// funcids is string of funcid symbols like "ct". The first symbol is considered as creation tx funcid and filtertxid will be compared to the creation tx id itself.
// For second+ funcids the filtertxid will be compared to txid in opret
UniValue NSPV_ccmoduleutxos(char *coinaddr, int64_t amount, uint8_t evalcode, std::string funcids, uint256 filtertxid)
{
UniValue result(UniValue::VOBJ); uint8_t msg[512]; int32_t i, iter, slen, len = 0;
uint8_t CCflag = 1;
NSPV_utxosresp_purge(&NSPV_utxosresult);
if (bitcoin_base58decode(msg, coinaddr) != 25)
{
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "invalid address"));
return(result);
}
msg[len++] = NSPV_CCMODULEUTXOS;
slen = (int32_t)strlen(coinaddr);
msg[len++] = slen;
memcpy(&msg[len], coinaddr, slen), len += slen;
len += iguana_rwnum(1, &msg[len], sizeof(amount), &amount);
len += iguana_rwnum(1, &msg[len], sizeof(evalcode), &evalcode);
slen = (int32_t)(funcids.size());
msg[len++] = slen;
memcpy(&msg[len], funcids.data(), slen), len += slen;
len += iguana_rwbignum(1, &msg[len], sizeof(filtertxid), (uint8_t *)&filtertxid);
for (iter = 0; iter<3; iter++)
if (NSPV_req(0, msg, len, NODE_ADDRINDEX, msg[0] >> 1) != 0)
{
for (i = 0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ((NSPV_inforesult.height == 0 || NSPV_utxosresult.nodeheight >= NSPV_inforesult.height) && strcmp(coinaddr, NSPV_utxosresult.coinaddr) == 0 && CCflag == NSPV_utxosresult.CCflag)
return(NSPV_utxosresp_json(&NSPV_utxosresult));
}
}
else sleep(1);
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "no utxos result"));
result.push_back(Pair("lastpeer", NSPV_lastpeer));
return(result);
}
#endif // KOMODO_NSPVSUPERLITE_H

View File

@@ -388,8 +388,13 @@ UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis) // what its a
mtx.nExpiryHeight = 0;
mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
mtx.nVersion = SAPLING_TX_VERSION;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
mtx.nLockTime = (uint32_t)time(NULL) - 777;
if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
if ( !hush_hardfork_active((uint32_t)chainActive.LastTip()->nTime) )
mtx.nLockTime = (uint32_t)time(NULL) - 777;
else
mtx.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast();
}
memset(used,0,sizeof(used));
if ( NSPV_addinputs(used,mtx,satoshis+txfee,64,NSPV_utxosresult.utxos,NSPV_utxosresult.numutxos) > 0 )

View File

@@ -1,3 +1,4 @@
// Copyright (c) 2019 The Hush developers
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* *
@@ -13,12 +14,9 @@
* *
******************************************************************************/
#include "komodo_defs.h"
#include "komodo_cJSON.h"
#include "notaries_staked.h"
#define KOMODO_MAINNET_START 178999
#define KOMODO_NOTARIES_HEIGHT1 814000
@@ -69,7 +67,7 @@ int32_t getkmdseason(int32_t height)
return(1);
for (int32_t i = 1; i < NUM_KMD_SEASONS; i++)
{
if ( height <= KMD_SEASON_HEIGHTS[i] && height >= KMD_SEASON_HEIGHTS[i-1] )
if ( height <= KMD_SEASON_HEIGHTS[i] && height > KMD_SEASON_HEIGHTS[i-1] )
return(i+1);
}
return(0);
@@ -81,7 +79,7 @@ int32_t getacseason(uint32_t timestamp)
return(1);
for (int32_t i = 1; i < NUM_KMD_SEASONS; i++)
{
if ( timestamp <= KMD_SEASON_TIMESTAMPS[i] && timestamp >= KMD_SEASON_TIMESTAMPS[i-1] )
if ( timestamp <= KMD_SEASON_TIMESTAMPS[i] && timestamp > KMD_SEASON_TIMESTAMPS[i-1] )
return(i+1);
}
return(0);
@@ -101,15 +99,12 @@ int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestam
if ( is_STAKED(ASSETCHAINS_SYMBOL) == 0 )
{
int32_t kmd_season = 0;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
// This is KMD, use block heights to determine the KMD notary season..
if ( height >= KOMODO_NOTARIES_HARDCODED )
kmd_season = getkmdseason(height);
}
else
{
// This is a non LABS assetchain, use timestamp to detemine notary pubkeys.
bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false;
if ( ishush3 ) {
// This is HUSH, use block heights to determine the notary season..
kmd_season = getkmdseason(height);
} else {
// Use timestamp to detemine notary pubkeys.
kmd_season = getacseason(timestamp);
}
if ( kmd_season != 0 )
@@ -120,7 +115,7 @@ int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestam
decode_hex(kmd_pubkeys[kmd_season-1][i],33,(char *)notaries_elected[kmd_season-1][i][1]);
if ( ASSETCHAINS_PRIVATE != 0 )
{
// this is PIRATE, we need to populate the address array for the notary exemptions.
// we need to populate the address array for the notary exemptions.
for (i = 0; i<NUM_KMD_NOTARIES; i++)
pubkey2addr((char *)NOTARY_ADDRESSES[kmd_season-1][i],(uint8_t *)kmd_pubkeys[kmd_season-1][i]);
}
@@ -130,16 +125,6 @@ int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestam
return(NUM_KMD_NOTARIES);
}
}
else if ( timestamp != 0 )
{
// here we can activate our pubkeys for LABS chains everythig is in notaries_staked.cpp
int32_t staked_era; int8_t numSN;
uint8_t staked_pubkeys[64][33];
staked_era = STAKED_era(timestamp);
numSN = numStakedNotaries(staked_pubkeys,staked_era);
memcpy(pubkeys,staked_pubkeys,numSN * 33);
return(numSN);
}
htind = height / KOMODO_ELECTION_GAP;
if ( htind >= KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP )

View File

@@ -1,3 +1,4 @@
// Copyright (c) 2019 The Hush developers
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* *
@@ -1845,7 +1846,6 @@ void komodo_args(char *argv0)
ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script","");
ASSETCHAINS_BEAMPORT = GetArg("-ac_beam",0);
ASSETCHAINS_CODAPORT = GetArg("-ac_coda",0);
ASSETCHAINS_MARMARA = GetArg("-ac_marmara",0);
ASSETCHAINS_CBOPRET = GetArg("-ac_cbopret",0);
ASSETCHAINS_CBMATURITY = GetArg("-ac_cbmaturity",0);
ASSETCHAINS_ADAPTIVEPOW = GetArg("-ac_adaptivepow",0);
@@ -1964,15 +1964,6 @@ void komodo_args(char *argv0)
}
if ( (ASSETCHAINS_STAKED= GetArg("-ac_staked",0)) > 100 )
ASSETCHAINS_STAKED = 100;
// for now, we only support 50% PoS due to other parts of the algorithm needing adjustment for
// other values
if ( (ASSETCHAINS_LWMAPOS = GetArg("-ac_lwmapos",0)) != 0 )
{
ASSETCHAINS_LWMAPOS = 50;
}
ASSETCHAINS_SAPLING = GetArg("-ac_sapling", -1);
if (ASSETCHAINS_SAPLING == -1)
{
@@ -2030,11 +2021,7 @@ void komodo_args(char *argv0)
printf("ASSETCHAINS_FOUNDERS needs an ASSETCHAINS_OVERRIDE_PUBKEY or ASSETCHAINS_SCRIPTPUB\n");
}
}
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 && ASSETCHAINS_MARMARA != 0 )
{
fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n");
StartShutdown();
}
if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || KOMODO_SNAPSHOT_INTERVAL != 0 || ASSETCHAINS_EARLYTXIDCONTRACT != 0 || ASSETCHAINS_CBMATURITY != 0 || ASSETCHAINS_ADAPTIVEPOW != 0 )
{
fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size());
@@ -2326,16 +2313,7 @@ fprintf(stderr,"extralen.%d before disable bits\n",extralen);
{
BITCOIND_RPCPORT = GetArg("-rpcport", ASSETCHAINS_RPCPORT);
//fprintf(stderr,"(%s) port.%u chain params initialized\n",ASSETCHAINS_SYMBOL,BITCOIND_RPCPORT);
if ( strcmp("PIRATE",ASSETCHAINS_SYMBOL) == 0 && ASSETCHAINS_HALVING[0] == 77777 )
{
ASSETCHAINS_HALVING[0] *= 5;
fprintf(stderr,"PIRATE halving changed to %d %.1f days ASSETCHAINS_LASTERA.%llu\n",(int32_t)ASSETCHAINS_HALVING[0],(double)ASSETCHAINS_HALVING[0]/1440,(long long)ASSETCHAINS_LASTERA);
}
else if ( ASSETCHAINS_PRIVATE != 0 )
{
fprintf(stderr,"-ac_private for a non-PIRATE chain is not supported. The only reason to have an -ac_private chain is for total privacy and that is best achieved with the largest anon set. PIRATE has that and it is recommended to just use PIRATE\n");
StartShutdown();
}
// Set cc enables for all existing ac_cc chains here.
if ( strcmp("AXO",ASSETCHAINS_SYMBOL) == 0 )
{

View File

@@ -48,7 +48,6 @@
#include "validationinterface.h"
#include "wallet/asyncrpcoperation_sendmany.h"
#include "wallet/asyncrpcoperation_shieldcoinbase.h"
#include "notaries_staked.h"
#include <cstring>
#include <algorithm>
@@ -117,6 +116,14 @@ bool fAlerts = DEFAULT_ALERTS;
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
#define ASSETCHAINS_MAX_ERAS 7
extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1];
extern uint32_t ASSETCHAINS_MAGIC;
extern uint64_t ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
extern int32_t ASSETCHAINS_STAKED;
extern uint64_t ASSETCHAINS_CBOPRET;
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
@@ -152,25 +159,8 @@ namespace {
bool operator()(CBlockIndex *pa, const CBlockIndex *pb) const {
// First sort by most total work, ...
if (ASSETCHAINS_LWMAPOS) {
/* Decker:
seems we had CChainPower classes compare here from Verus, it's slow, bcz of hard
arith_uint256 math in bool operator<(const CChainPower &p1, const CChainPower &p2),
this slows down setBlockIndexCandidates.insert operations in LoadBlockIndexDB(),
so, for faster block index db loading we will use check from Verus only for LWMAPOS
enabled chains.
*/
if (pa->chainPower > pb->chainPower) return false;
if (pa->chainPower < pb->chainPower) return true;
}
else
{
if (pa->chainPower.chainWork > pb->chainPower.chainWork) return false;
if (pa->chainPower.chainWork < pb->chainPower.chainWork) return true;
}
if (pa->chainPower.chainWork > pb->chainPower.chainWork) return false;
if (pa->chainPower.chainWork < pb->chainPower.chainWork) return true;
// ... then by earliest time received, ...
if (pa->nSequenceId < pb->nSequenceId) return false;
@@ -940,20 +930,34 @@ bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
{
int32_t i;
if (tx.nLockTime == 0)
if (tx.nLockTime == 0)
return true;
if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
return true;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
if ( txin.nSequence == 0xfffffffe && (((int64_t)tx.nLockTime >= LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime > nBlockTime) || ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime > nBlockHeight)) )
if ( !hush_hardfork_active(nBlockTime) && txin.nSequence == 0xfffffffe &&
//if ( (nBlockTime <= ASSETCHAINS_STAKED_HF_TIMESTAMP ) && txin.nSequence == 0xfffffffe &&
(
((int64_t)tx.nLockTime >= LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime > nBlockTime) ||
((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime > nBlockHeight)
)
)
{
}
//else if ( nBlockTime > ASSETCHAINS_STAKED_HF_TIMESTAMP && txin.nSequence == 0xfffffffe &&
else if ( hush_hardfork_active(nBlockTime) && txin.nSequence == 0xfffffffe &&
(
((int64_t)tx.nLockTime >= LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime <= nBlockTime) ||
((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime <= nBlockHeight))
)
{
}
else if (!txin.IsFinal())
{
//printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
LogPrintf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
return false;
}
}
@@ -1160,6 +1164,7 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde
if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID)
{
//return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"),REJECT_INVALID, "bad-sapling-tx-version-group-id");
if ( 0 )
{
string strHex = EncodeHexTx(tx);
fprintf(stderr,"invalid Sapling rawtx.%s\n",strHex.c_str());
@@ -1332,7 +1337,7 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde
}
bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState &state,
libzcash::ProofVerifier& verifier)
libzcash::ProofVerifier& verifier,int32_t txIndex, int32_t numTxs)
{
static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n;
if ( *(int32_t *)&array[0] == 0 )
@@ -1732,7 +1737,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
}
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, int dosLevel, bool fSkipExpiry)
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, int dosLevel)
{
AssertLockHeld(cs_main);
if (pfMissingInputs)
@@ -1743,14 +1748,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if ( nextBlockHeight <= 1 || chainActive.LastTip() == 0 )
tiptime = (uint32_t)time(NULL);
else tiptime = (uint32_t)chainActive.LastTip()->nTime;
// is it already in the memory pool?
uint256 hash = tx.GetHash();
if (pool.exists(hash))
{
//fprintf(stderr,"already in mempool\n");
return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
}
//fprintf(stderr,"addmempool 0\n");
// Node operator can choose to reject tx by number of transparent inputs
static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
@@ -1766,21 +1763,21 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
}
//fprintf(stderr,"addmempool 1\n");
auto verifier = libzcash::ProofVerifier::Strict();
if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,chainActive.LastTip()->GetHeight()+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
{
//fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
return error("AcceptToMemoryPool: komodo_validate_interest failed");
}
if (!CheckTransaction(tiptime,tx, state, verifier))
if (!CheckTransaction(tiptime,tx, state, verifier, 0, 0))
{
return error("AcceptToMemoryPool: CheckTransaction failed");
}
// DoS level set to 10 to be more forgiving.
// Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
if (!fSkipExpiry && !ContextualCheckTransaction(0,0,0,tx, state, nextBlockHeight, (dosLevel == -1) ? 10 : dosLevel))
if (!ContextualCheckTransaction(0,0,0,tx, state, nextBlockHeight, (dosLevel == -1) ? 10 : dosLevel))
{
return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
}
@@ -1791,26 +1788,34 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),REJECT_INVALID, "coinbase");
}
// Rather not work on nonstandard transactions (unless -testnet/-regtest)
string reason;
if (!fSkipExpiry && Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
{
//
//fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\nscriptPubKey: %s\n",reason.c_str(),tx.vout[0].scriptPubKey.ToString().c_str());
return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
}
// Only accept nLockTime-using transactions that can be mined in the next
// block; we don't want our mempool filled up with transactions that can't
// be mined yet.
if (!fSkipExpiry && !CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
{
//fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
}
//fprintf(stderr,"addmempool 3\n");
// is it already in the memory pool?
uint256 hash = tx.GetHash();
if (pool.exists(hash))
{
//fprintf(stderr,"already in mempool\n");
return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
}
// Check for conflicts with in-memory transactions
if (!fSkipExpiry)
{
LOCK(pool.cs); // protect pool.mapNextTx
for (unsigned int i = 0; i < tx.vin.size(); i++)
@@ -1837,7 +1842,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
}
//fprintf(stderr,"addmempool 4\n");
{
CCoinsView dummy;
CCoinsViewCache view(&dummy);
@@ -1861,7 +1865,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if (ExistsImportTombstone(tx, view))
return state.Invalid(false, REJECT_DUPLICATE, "import tombstone exists");
}
else if (!fSkipExpiry)
else
{
// do all inputs exist?
// Note that this does not check for the presence of actual outputs (see the next check for that),
@@ -1873,10 +1877,13 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if (pfMissingInputs)
*pfMissingInputs = true;
//fprintf(stderr,"missing inputs\n");
return state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing");
return false;
/*
https://github.com/zcash/zcash/blob/master/src/main.cpp#L1490
state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing");
*/
}
}
// are the actual inputs available?
if (!view.HaveInputs(tx))
{
@@ -1884,59 +1891,50 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
}
}
// are the joinsplit's requirements met?
if (!view.HaveJoinSplitRequirements(tx))
{
//fprintf(stderr,"accept failure.2\n");
return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
}
// Bring the best block into scope
view.GetBestBlock();
if (!fSkipExpiry)
nValueIn = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime);
nValueIn = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime);
if ( 0 && interest != 0 )
fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
// we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
view.SetBackend(dummy);
}
// Check for non-standard pay-to-script-hash in inputs
if (!fSkipExpiry && Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
return error("AcceptToMemoryPool: reject nonstandard transaction input");
// Check that the transaction doesn't have an excessive number of
// sigops, making it impossible to mine. Since the coinbase transaction
// itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
// MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
// merely non-standard transaction.
unsigned int nSigOps = GetLegacySigOpCount(tx);
if (!fSkipExpiry)
nSigOps += GetP2SHSigOpCount(tx, view);
nSigOps += GetP2SHSigOpCount(tx, view);
if (nSigOps > MAX_STANDARD_TX_SIGOPS)
{
fprintf(stderr,"accept failure.4\n");
return state.DoS(1, error("AcceptToMemoryPool: too many sigops %s, %d > %d", hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
}
CAmount nValueOut = tx.GetValueOut();
double dPriority = 0;
CAmount nFees = 0;
if (!fSkipExpiry)
{
dPriority = view.GetPriority(tx, chainActive.Height());
nFees = nValueIn-nValueOut;
}
CAmount nFees = nValueIn-nValueOut;
double dPriority = view.GetPriority(tx, chainActive.Height());
if ( nValueOut > 777777*COIN && KOMODO_VALUETOOBIG(nValueOut - 777777*COIN) != 0 ) // some room for blockreward and txfees
return state.DoS(100, error("AcceptToMemoryPool: GetValueOut too big"),REJECT_INVALID,"tx valueout is too big");
// Keep track of transactions that spend a coinbase, which we re-scan
// during reorgs to ensure COINBASE_MATURITY is still met.
bool fSpendsCoinbase = false;
if (!fSkipExpiry && !tx.IsCoinImport() && !tx.IsPegsImport()) {
if (!tx.IsCoinImport() && !tx.IsPegsImport()) {
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
const CCoins *coins = view.AccessCoins(txin.prevout.hash);
if (coins->IsCoinBase()) {
@@ -1945,15 +1943,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
}
}
//fprintf(stderr,"addmempool 5\n");
// Grab the branch ID we expect this transaction to commit to. We don't
// yet know if it does, but if the entry gets added to the mempool, then
// it has passed ContextualCheckInputs and therefore this is correct.
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId);
unsigned int nSize = entry.GetTxSize();
// Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
// In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
@@ -1966,17 +1964,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee");
}
}
// Require that free transactions have sufficient priority to be mined in the next block.
if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
fprintf(stderr,"accept failure.6\n");
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
}
// Continuously rate-limit free (really, very-low-fee) transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make others' transactions take longer to confirm.
if ( !fSkipExpiry && fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize) && !tx.IsCoinImport() && !tx.IsPegsImport())
if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize) && !tx.IsCoinImport() && !tx.IsPegsImport())
{
static CCriticalSection csFreeLimiter;
static double dFreeCount;
@@ -1998,8 +1996,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
dFreeCount += nSize;
}
if (!fSkipExpiry && !tx.IsCoinImport() && !tx.IsPegsImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
if (!tx.IsCoinImport() && !tx.IsPegsImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
{
string errmsg = strprintf("absurdly high fees %s, %d > %d",
hash.ToString(),
@@ -2012,12 +2010,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
PrecomputedTransactionData txdata(tx);
if (!fSkipExpiry && !ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
{
//fprintf(stderr,"accept failure.9\n");
return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
}
// Check again against just the consensus-critical mandatory script
// verification flags, in case of bugs in the standard flags that cause
// transactions to pass as valid when they're actually invalid. For
@@ -2034,7 +2032,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->GetHeight() + 1;
}
//fprintf(stderr,"addmempool 7\n");
if (!fSkipExpiry && !ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
{
if ( flag != 0 )
KOMODO_CONNECTING = -1;
@@ -2043,24 +2042,36 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if ( flag != 0 )
KOMODO_CONNECTING = -1;
// Store transaction in memory
pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
if (!fSkipExpiry && !tx.IsCoinImport())
{
// Add memory address index
if (fAddressIndex) {
pool.addAddressIndex(entry, view);
}
LOCK(pool.cs);
// Store transaction in memory
pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
if (!tx.IsCoinImport())
{
// Add memory address index
if (fAddressIndex) {
pool.addAddressIndex(entry, view);
}
// Add memory spent index
if (fSpentIndex) {
pool.addSpentIndex(entry, view);
// Add memory spent index
if (fSpentIndex) {
pool.addSpentIndex(entry, view);
}
}
}
}
//SyncWithWallets(tx,NULL);
// This should be here still?
//SyncWithWallets(tx, NULL);
return true;
}
bool CCTxFixAcceptToMemPoolUnchecked(CTxMemPool& pool, const CTransaction &tx)
{
// called from CheckBlock which is in cs_main and mempool.cs locks already.
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
CTxMemPoolEntry entry(tx, 0, GetTime(), 0, chainActive.Height(), mempool.HasNoInputsOf(tx), false, consensusBranchId);
//fprintf(stderr, "adding %s to mempool from block %d\n",tx.GetHash().ToString().c_str(),chainActive.GetHeight());
pool.addUnchecked(tx.GetHash(), entry, false);
return true;
}
@@ -2127,59 +2138,6 @@ struct CompareBlocksByHeightMain
}
};
bool RemoveOrphanedBlocks(int32_t notarized_height)
{
LOCK(cs_main);
std::vector<const CBlockIndex*> prunedblocks;
std::set<const CBlockIndex*, CompareBlocksByHeightMain> setTips;
int32_t m=0,n = 0;
// get notarised timestamp and use this as a backup incase the forked block has no height.
// we -600 to make sure the time is within future block constraints.
uint32_t notarized_timestamp = komodo_heightstamp(notarized_height)-600;
// Most of this code is a direct copy from GetChainTips RPC. Which gives a return of all
// blocks that are not in the main chain.
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
{
n++;
setTips.insert(item.second);
}
n = 0;
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
{
const CBlockIndex* pprev=0;
n++;
if ( item.second != 0 )
pprev = item.second->pprev;
if (pprev)
setTips.erase(pprev);
}
const CBlockIndex *forked;
BOOST_FOREACH(const CBlockIndex* block, setTips)
{
// We skip anything over notarised height to avoid breaking normal consensus rules.
if ( block->GetHeight() > notarized_height || block->nTime > notarized_timestamp )
continue;
// We can also check if the block is in the active chain as a backup test.
forked = chainActive.FindFork(block);
// Here we save each forked block to a vector for removal later.
if ( forked != 0 )
prunedblocks.push_back(block);
}
if (prunedblocks.size() > 0 && pblocktree->EraseBatchSync(prunedblocks))
{
// Blocks cleared from disk succesfully, using internal DB batch erase function. Which exists, but has never been used before.
// We need to try and clear the block index from mapBlockIndex now, otherwise node will need a restart.
BOOST_FOREACH(const CBlockIndex* block, prunedblocks)
{
m++;
mapBlockIndex.erase(block->GetBlockHash());
}
fprintf(stderr, "%s removed %d orphans from %d blocks before %d\n",ASSETCHAINS_SYMBOL,m,n, notarized_height);
return true;
}
return false;
}
/*uint64_t myGettxout(uint256 hash,int32_t n)
{
CCoins coins;
@@ -2199,7 +2157,12 @@ bool myAddtomempool(CTransaction &tx, CValidationState *pstate, bool fSkipExpiry
pstate = &state;
CTransaction Ltx; bool fMissingInputs,fOverrideFees = false;
if ( mempool.lookup(tx.GetHash(),Ltx) == 0 )
return(AcceptToMemoryPool(mempool, *pstate, tx, false, &fMissingInputs, !fOverrideFees, -1, fSkipExpiry));
{
if ( !fSkipExpiry )
return(AcceptToMemoryPool(mempool, *pstate, tx, false, &fMissingInputs, !fOverrideFees, -1));
else
return(CCTxFixAcceptToMemPoolUnchecked(mempool,tx));
}
else return(true);
}
@@ -2428,12 +2391,6 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
}
//uint64_t komodo_moneysupply(int32_t height);
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1];
extern uint32_t ASSETCHAINS_MAGIC;
extern uint64_t ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
extern int32_t ASSETCHAINS_STAKED;
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
{
@@ -2504,8 +2461,6 @@ bool IsInitialBlockDownload()
}
bool state;
arith_uint256 bigZero = arith_uint256();
arith_uint256 minWork = UintToArith256(chainParams.GetConsensus().nMinimumChainWork);
CBlockIndex *ptr = chainActive.Tip();
if (ptr == NULL)
@@ -2513,11 +2468,6 @@ bool IsInitialBlockDownload()
//fprintf(stderr,"nullptr in IsInitialDownload\n");
return true;
}
if (0 && ptr->chainPower < CChainPower(ptr, bigZero, minWork))
{
fprintf(stderr,"chainpower insufficient in IsInitialDownload\n");
return true;
}
state = ((chainActive.Height() < ptr->GetHeight() - 24*60) ||
ptr->GetBlockTime() < (GetTime() - nMaxTipAge));
if ( KOMODO_INSYNC != 0 )
@@ -2671,17 +2621,15 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
if (!pindexBestInvalid || pindexNew->chainPower > pindexBestInvalid->chainPower)
pindexBestInvalid = pindexNew;
LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__,
pindexNew->GetBlockHash().ToString(), pindexNew->GetHeight(),
log(pindexNew->chainPower.chainWork.getdouble())/log(2.0),
log(pindexNew->chainPower.chainStake.getdouble())/log(2.0),
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime()));
CBlockIndex *tip = chainActive.LastTip();
assert (tip);
LogPrintf("%s: current best=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
tip->GetBlockHash().ToString(), chainActive.Height(),
log(tip->chainPower.chainWork.getdouble())/log(2.0),
log(tip->chainPower.chainStake.getdouble())/log(2.0),
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
CheckForkWarningConditions();
}
@@ -3413,9 +3361,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
auto verifier = libzcash::ProofVerifier::Strict();
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
int32_t futureblock;
CAmount blockReward = 0; uint64_t notarypaycheque = 0;
CAmount blockReward = GetBlockSubsidy(pindex->GetHeight(), chainparams.GetConsensus());
uint64_t notarypaycheque = 0;
// Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
if (!CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
if ( !CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
{
//fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
return false;
@@ -3532,7 +3481,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CAmount nFees = 0;
int nInputs = 0;
uint64_t valueout;
int64_t voutsum = 0,prevsum=0,interest,sum = 0;
int64_t voutsum = 0, prevsum = 0, interest, sum = 0;
unsigned int nSigOps = 0;
CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
@@ -3731,7 +3680,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
blockReward += nFees + GetBlockSubsidy(pindex->GetHeight(), chainparams.GetConsensus()) + sum;
blockReward += nFees + sum;
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 &&
{
uint64_t checktoshis;
@@ -4007,15 +3956,17 @@ void static UpdateTip(CBlockIndex *pindexNew) {
progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
}
LogPrintf("%s: new best=%s height=%d log2_work=%.8g log2_stake=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
log(chainActive.Tip()->chainPower.chainWork.getdouble())/log(2.0),
log(chainActive.Tip()->chainPower.chainStake.getdouble())/log(2.0),
(unsigned long)chainActive.LastTip()->nChainTx,
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), progress,
pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
cvBlockChange.notify_all();
/*
// https://github.com/zcash/zcash/issues/3992 -> https://github.com/zcash/zcash/commit/346d11d3eb2f8162df0cb00b1d1f49d542495198
// Check the version of the last 100 blocks to see if we need to upgrade:
static bool fWarned = false;
@@ -4039,6 +3990,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
fWarned = true;
}
}
*/
}
/**
@@ -4127,17 +4079,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
for (int i = 0; i < block.vtx.size(); i++)
{
CTransaction &tx = block.vtx[i];
if ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block,pindexDelete->GetHeight(),true) != 0)))
{
#ifdef ENABLE_WALLET
if ( !GetBoolArg("-disablewallet", false) && KOMODO_NSPV_FULLNODE )
pwalletMain->EraseFromWallet(tx.GetHash());
#endif
}
else
{
SyncWithWallets(tx, NULL);
}
SyncWithWallets(tx, NULL);
}
// Update cached incremental witnesses
GetMainSignals().ChainTip(pindexDelete, &block, newSproutTree, newSaplingTree, false);
@@ -4232,8 +4174,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
pblock = &block;
}
KOMODO_CONNECTING = (int32_t)pindexNew->GetHeight();
fprintf(stderr,"%s connecting ht.%d maxsize.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pindexNew->GetHeight(),MAX_BLOCK_SIZE(pindexNew->GetHeight()),(int32_t)::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
//fprintf(stderr,"%s connecting ht.%d maxsize.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pindexNew->GetHeight(),MAX_BLOCK_SIZE(pindexNew->GetHeight()),(int32_t)::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
// Get the current commitment tree
SproutMerkleTree oldSproutTree;
SaplingMerkleTree oldSaplingTree;
@@ -4417,7 +4358,6 @@ static void PruneBlockIndexCandidates() {
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
*/
static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
//fprintf(stderr,"%s: fSkipdpow=%d\n", __FUNCTION__, fSkipdpow);
AssertLockHeld(cs_main);
bool fInvalidFound = false;
const CBlockIndex *pindexOldTip = chainActive.Tip();
@@ -4429,9 +4369,37 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc
notarizedht = komodo_notarized_height(&prevMoMheight,&notarizedhash,&txid);
if ( !fSkipdpow && pindexFork != 0 && pindexOldTip->GetHeight() > notarizedht && pindexFork->GetHeight() < notarizedht )
{
fprintf(stderr,"pindexOldTip->GetHeight().%d > notarizedht %d && pindexFork->GetHeight().%d is < notarizedht %d, so ignore it\n",(int32_t)pindexOldTip->GetHeight(),notarizedht,(int32_t)pindexFork->GetHeight(),notarizedht);
LogPrintf("pindexOldTip->GetHeight().%d > notarizedht %d && pindexFork->GetHeight().%d is < notarizedht %d, so ignore it\n",(int32_t)pindexOldTip->GetHeight(),notarizedht,(int32_t)pindexFork->GetHeight(),notarizedht);
// *** DEBUG ***
if (1)
{
const CBlockIndex *pindexLastNotarized = mapBlockIndex[notarizedhash];
auto msg = "- " + strprintf(_("Current tip : %s, height %d, work %s"),
pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight(), pindexOldTip->chainPower.chainWork.GetHex()) + "\n" +
"- " + strprintf(_("New tip : %s, height %d, work %s"),
pindexMostWork->phashBlock->GetHex(), pindexMostWork->GetHeight(), pindexMostWork->chainPower.chainWork.GetHex()) + "\n" +
"- " + strprintf(_("Fork point : %s, height %d"),
pindexFork->phashBlock->GetHex(), pindexFork->GetHeight()) + "\n" +
"- " + strprintf(_("Last ntrzd : %s, height %d"),
pindexLastNotarized->phashBlock->GetHex(), pindexLastNotarized->GetHeight());
LogPrintf("[ Debug ]\n%s\n",msg);
int nHeight = pindexFork ? pindexFork->GetHeight() : -1;
int nTargetHeight = std::min(nHeight + 32, pindexMostWork->GetHeight());
LogPrintf("[ Debug ] nHeight = %d, nTargetHeight = %d\n", nHeight, nTargetHeight);
CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
while (pindexIter && pindexIter->GetHeight() != nHeight) {
LogPrintf("[ Debug -> New blocks list ] %s, height %d\n", pindexIter->phashBlock->GetHex(), pindexIter->GetHeight());
pindexIter = pindexIter->pprev;
}
}
CValidationState tmpstate;
InvalidateBlock(tmpstate,pindexMostWork); // trying to invalidate longest chain, which tried to reorg notarized chain (in case of fork point below last notarized block)
return state.DoS(100, error("ActivateBestChainStep(): pindexOldTip->GetHeight().%d > notarizedht %d && pindexFork->GetHeight().%d is < notarizedht %d, so ignore it",(int32_t)pindexOldTip->GetHeight(),notarizedht,(int32_t)pindexFork->GetHeight(),notarizedht),
REJECT_INVALID, "past-notarized-height");
REJECT_INVALID, "past-notarized-height");
}
// - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks.
// - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain,
@@ -4553,7 +4521,6 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc
* that is already loaded (to avoid loading it again from disk).
*/
bool ActivateBestChain(bool fSkipdpow, CValidationState &state, CBlock *pblock) {
//fprintf(stderr,"%s: fSkipdpow=%d\n", __FUNCTION__, fSkipdpow);
CBlockIndex *pindexNewTip = NULL;
CBlockIndex *pindexMostWork = NULL;
const CChainParams& chainParams = Params();
@@ -4750,6 +4717,10 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
CAmount sproutValue = 0;
CAmount saplingValue = 0;
bool isShieldedTx = false;
unsigned int nShieldedSpends=0,nShieldedOutputs=0,nPayments=0;
unsigned int nShieldedTx=0,nFullyShieldedTx=0,nDeshieldingTx=0,nShieldingTx=0;
unsigned int nShieldedPayments=0,nFullyShieldedPayments=0,nShieldingPayments=0,nDeshieldingPayments=0;
unsigned int nNotarizations=0;
for (auto tx : block.vtx) {
// Negative valueBalance "takes" money from the transparent value pool
@@ -4762,8 +4733,79 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
sproutValue += js.vpub_old;
sproutValue -= js.vpub_new;
}
}
// Ignore following stats unless -zindex enabled
if (!fZindex)
continue;
nShieldedSpends = tx.vShieldedSpend.size();
nShieldedOutputs = tx.vShieldedOutput.size();
isShieldedTx = (nShieldedSpends + nShieldedOutputs) > 0 ? true : false;
// We want to avoid full verification with a low false-positive rate
// TODO: A nefarious user could create xtns which meet these criteria and skew stats, what
// else can we look for which is not full validation?
// Can we filter on properties of tx.vout[0] ?
if(tx.vin.size()==13 && tx.vout.size()==2 && tx.vout[1].scriptPubKey.IsOpReturn() && tx.vout[1].nValue==0) {
nNotarizations++;
}
//NOTE: These are at best heuristics. Improve them as much as possible.
// You cannot compare stats generated from different sets of heuristics, so
// if you change this code, you must reindex or delete datadir + resync from scratch, or you
// will be mixing together data from two set of heuristics.
if(isShieldedTx) {
nShieldedTx++;
// NOTE: It's possible for very complex transactions to be both shielding and deshielding,
// such as (t,z)=>(t,z) Since these transactions cannot be made via RPCs currently, they
// would currently need to be made via raw transactions
if(tx.vin.size()==0 && tx.vout.size()==0) {
nFullyShieldedTx++;
} else if(tx.vin.size()>0) {
nShieldingTx++;
} else if(tx.vout.size()>0) {
nDeshieldingTx++;
}
if (nShieldedOutputs >= 1) {
// If there are shielded outputs, count each as a payment
// By default, if there is more than 1 output, we assume 1 zaddr change output which is not a payment.
// In the case of multiple outputs which spend inputs exactly, there is no change output and this
// heuristic will undercount payments. Since this edge case is rare, this seems acceptable.
// t->(t,t,z) = 1 shielded payment
// z->(z,z) = 1 shielded payment + shielded change
// t->(z,z) = 1 shielded payment + shielded change
// t->(t,z) = 1 shielded payment + transparent change
// (z,z)->z = 1 shielded payment (has this xtn ever occurred?)
// z->(z,z,z) = 2 shielded payments + shielded change
// Assume that there is always 1 change output when there are more than one output
nShieldedPayments += nShieldedOutputs > 1 ? (nShieldedOutputs-1) : 1;
// since we have at least 1 zoutput, all transparent outputs are payments, not change
nShieldedPayments += tx.vout.size();
// Fully shielded do not count toward shielding/deshielding
if(tx.vin.size()==0 && tx.vout.size()==0) {
nFullyShieldedPayments += nShieldedOutputs > 1 ? (nShieldedOutputs-1) : 1;
} else {
nShieldingPayments += nShieldedOutputs > 1 ? (nShieldedOutputs-1) : 1;
// Also count remaining taddr outputs as payments
nShieldedPayments += tx.vout.size();
}
} else if (nShieldedSpends >=1) {
// Shielded inputs with no shielded outputs. We know none are change output because
// change would flow back to the zaddr
// z->t = 1 shielded payment
// z->(t,t) = 2 shielded payments
// z->(t,t,t) = 3 shielded payments
nShieldedPayments += tx.vout.size();
nDeshieldingPayments += tx.vout.size() > 1 ? tx.vout.size()-1 : tx.vout.size();
}
nPayments += nShieldedPayments;
} else {
// No shielded payments, add transparent payments minus a change address
nPayments += tx.vout.size() > 1 ? tx.vout.size()-1 : tx.vout.size();
}
}
pindexNew->nSproutValue = sproutValue;
pindexNew->nChainSproutValue = boost::none;
pindexNew->nSaplingValue = saplingValue;
@@ -4774,6 +4816,18 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
pindexNew->nStatus |= BLOCK_HAVE_DATA;
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
if (fZindex) {
pindexNew->nPayments = nPayments;
pindexNew->nShieldedTx = nShieldedTx;
pindexNew->nFullyShieldedTx = nFullyShieldedTx;
pindexNew->nDeshieldingTx = nDeshieldingTx;
pindexNew->nShieldingTx = nShieldingTx;
pindexNew->nShieldedPayments = nShieldedPayments;
pindexNew->nFullyShieldedPayments = nFullyShieldedPayments;
pindexNew->nDeshieldingPayments = nDeshieldingPayments;
pindexNew->nShieldingPayments = nShieldingPayments;
pindexNew->nNotarizations = nNotarizations;
}
setDirtyBlockIndex.insert(pindexNew);
if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
@@ -4787,9 +4841,22 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
queue.pop_front();
pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
if (pindex->pprev) {
pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
if (fZindex) {
//fprintf(stderr,"%s: setting chain zstats\n", __FUNCTION__);
pindex->nChainNotarizations = (pindex->pprev ? pindex->pprev->nChainNotarizations : 0) + pindex->nNotarizations;
pindex->nChainShieldedTx = (pindex->pprev ? pindex->pprev->nChainShieldedTx : 0) + pindex->nShieldedTx;
pindex->nChainFullyShieldedTx = (pindex->pprev ? pindex->pprev->nChainFullyShieldedTx : 0) + pindex->nFullyShieldedTx;
pindex->nChainShieldingTx = (pindex->pprev ? pindex->pprev->nChainShieldingTx : 0) + pindex->nShieldingTx;
pindex->nChainDeshieldingTx = (pindex->pprev ? pindex->pprev->nChainDeshieldingTx : 0) + pindex->nDeshieldingTx;
pindex->nChainPayments = (pindex->pprev ? pindex->pprev->nChainPayments : 0) + pindex->nPayments;
pindex->nChainShieldedPayments = (pindex->pprev ? pindex->pprev->nChainShieldedPayments : 0) + pindex->nShieldedPayments;
pindex->nChainFullyShieldedPayments = (pindex->pprev ? pindex->pprev->nChainFullyShieldedPayments : 0) + pindex->nFullyShieldedPayments;
pindex->nChainShieldingPayments = (pindex->pprev ? pindex->pprev->nChainShieldingPayments : 0) + pindex->nShieldingPayments;
pindex->nChainDeshieldingPayments = (pindex->pprev ? pindex->pprev->nChainDeshieldingPayments : 0) + pindex->nDeshieldingPayments;
}
if (pindex->pprev) {
if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
} else {
@@ -4825,6 +4892,9 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
}
}
if (fZindex)
fprintf(stderr, "ht.%d, ShieldedPayments=%d, ShieldedTx=%d, FullyShieldedTx=%d, ntz=%d\n", pindexNew->GetHeight(), nShieldedPayments, nShieldedTx, nFullyShieldedTx, nNotarizations );
return true;
}
@@ -5105,9 +5175,10 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
fprintf(stderr," failed hash ht.%d\n",height);
return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
}
if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
if ( ASSETCHAINS_STAKED == 0 && komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
}
// Check the merkle root.
if (fCheckMerkleRoot) {
bool mutated;
@@ -5177,10 +5248,9 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
list<CTransaction> removed;
for (i=0; i<block.vtx.size(); i++)
{
CValidationState state;
CTransaction Tx;
CValidationState state; CTransaction Tx;
const CTransaction &tx = (CTransaction)block.vtx[i];
if (tx.IsCoinBase() || !tx.vjoinsplit.empty() || !tx.vShieldedSpend.empty() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block,height,true) != 0)))
if ( tx.IsCoinBase() || !tx.vjoinsplit.empty() || !tx.vShieldedSpend.empty() || (i == block.vtx.size()-1 && komodo_isPoS((CBlock *)&block,height,0) != 0) )
continue;
Tx = tx;
if ( myAddtomempool(Tx, &state, true) == false ) // happens with out of order tx in block on resync
@@ -5215,8 +5285,11 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
{
const CTransaction& tx = block.vtx[i];
if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
{
fprintf(stderr, "validate intrest failed for txnum.%i tx.%s\n", i, tx.ToString().c_str());
return error("CheckBlock: komodo_validate_interest failed");
if (!CheckTransaction(tiptime,tx, state, verifier))
}
if (!CheckTransaction(tiptime,tx, state, verifier, i, (int32_t)block.vtx.size()))
return error("CheckBlock: CheckTransaction failed");
}
@@ -6043,9 +6116,9 @@ bool static LoadBlockIndexDB()
vSortedByHeight.push_back(make_pair(pindex->GetHeight(), pindex));
//komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
}
fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
//fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
sort(vSortedByHeight.begin(), vSortedByHeight.end());
fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
//fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
{
CBlockIndex* pindex = item.second;
@@ -6056,6 +6129,20 @@ bool static LoadBlockIndexDB()
if (pindex->pprev) {
if (pindex->pprev->nChainTx) {
pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
if (fZindex) {
pindex->nChainNotarizations = pindex->pprev->nChainNotarizations + pindex->nNotarizations;
pindex->nChainShieldedTx = pindex->pprev->nChainShieldedTx + pindex->nShieldedTx;
pindex->nChainShieldedPayments = pindex->pprev->nChainShieldedPayments + pindex->nShieldedPayments;
pindex->nChainShieldingTx = pindex->pprev->nChainShieldingTx + pindex->nShieldingTx;
pindex->nChainPayments = pindex->pprev->nChainPayments + pindex->nPayments;
pindex->nChainShieldingPayments = pindex->pprev->nChainShieldingPayments + pindex->nShieldingPayments;
pindex->nChainDeshieldingTx = pindex->pprev->nChainShieldedTx + pindex->nShieldedTx;
pindex->nChainDeshieldingPayments = pindex->pprev->nChainShieldedPayments + pindex->nShieldedPayments;
pindex->nChainFullyShieldedTx = pindex->pprev->nChainFullyShieldedTx + pindex->nFullyShieldedTx;
pindex->nChainFullyShieldedPayments = pindex->pprev->nChainFullyShieldedPayments + pindex->nFullyShieldedPayments;
}
if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
} else {
@@ -6068,6 +6155,18 @@ bool static LoadBlockIndexDB()
}
} else {
pindex->nChainTx = 0;
if (fZindex) {
pindex->nChainPayments = 0;
pindex->nChainNotarizations = 0;
pindex->nChainShieldedTx = 0;
pindex->nChainFullyShieldedTx = 0;
pindex->nChainShieldedPayments = 0;
pindex->nChainShieldingPayments = 0;
pindex->nChainDeshieldingTx = 0;
pindex->nChainDeshieldingPayments = 0;
pindex->nChainFullyShieldedTx = 0;
pindex->nChainFullyShieldedPayments = 0;
}
pindex->nChainSproutValue = boost::none;
pindex->nChainSaplingValue = boost::none;
mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
@@ -6076,6 +6175,17 @@ bool static LoadBlockIndexDB()
pindex->nChainTx = pindex->nTx;
pindex->nChainSproutValue = pindex->nSproutValue;
pindex->nChainSaplingValue = pindex->nSaplingValue;
if (fZindex) {
pindex->nChainPayments = pindex->nPayments;
pindex->nChainNotarizations = pindex->nNotarizations;
pindex->nChainShieldedTx = pindex->nShieldedTx;
pindex->nChainShieldedPayments = pindex->nShieldedPayments;
pindex->nChainShieldingTx = pindex->nShieldingTx;
pindex->nChainShieldingPayments = pindex->nShieldingPayments;
pindex->nChainDeshieldingTx = pindex->nDeshieldingTx;
pindex->nChainDeshieldingPayments = pindex->nDeshieldingPayments;
pindex->nChainFullyShieldedPayments = pindex->nFullyShieldedPayments;
}
}
}
// Construct in-memory chain of branch IDs.
@@ -6131,7 +6241,7 @@ bool static LoadBlockIndexDB()
setBlkDataFiles.insert(pindex->nFile);
}
}
//fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
{
CDiskBlockPos pos(*it, 0);

View File

@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2019 The Hush developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -291,7 +292,7 @@ void PruneAndFlush();
/** (try to) add transaction to memory pool **/
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
bool* pfMissingInputs, bool fRejectAbsurdFee=false, int dosLevel=-1, bool fSkipExpiry=false);
bool* pfMissingInputs, bool fRejectAbsurdFee=false, int dosLevel=-1);
struct CNodeStateStats {
@@ -716,7 +717,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight);
/** Transaction validation functions */
/** Context-independent validity checks */
bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState& state, libzcash::ProofVerifier& verifier);
bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState& state, libzcash::ProofVerifier& verifier, int32_t txIndex, int32_t numTxs);
bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransaction& tx, CValidationState &state);
/** Check for standard transaction types
@@ -808,7 +809,6 @@ bool GetAddressUnspent(uint160 addressHash, int type,
bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW);
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW);
bool RemoveOrphanedBlocks(int32_t notarized_height);
bool PruneOneBlockFile(bool tempfile, const int fileNumber);
/** Functions for validating blocks and updating the block tree */

View File

@@ -121,6 +121,8 @@ public:
}
};
extern int8_t ASSETCHAINS_ADAPTIVEPOW;
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
{
if ( ASSETCHAINS_ADAPTIVEPOW <= 0 )
@@ -148,12 +150,9 @@ int32_t komodo_longestchain();
int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
int64_t komodo_block_unlocktime(uint32_t nHeight);
uint64_t komodo_commission(const CBlock *block,int32_t height);
int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig);
int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33);
int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33, void *ptr);
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
int32_t komodo_is_notarytx(const CTransaction& tx);
CScript Marmara_scriptPubKey(int32_t height,CPubKey pk);
CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk);
uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector<int8_t> &NotarisationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len);
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
int32_t komodo_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *script, int32_t len);
@@ -578,51 +577,6 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
int32_t stakeHeight = chainActive.Height() + 1;
//LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x stake.%i\n", nBlockSize,blocktime,pblock->nBits,isStake);
if ( ASSETCHAINS_SYMBOL[0] != 0 && isStake )
{
LEAVE_CRITICAL_SECTION(cs_main);
LEAVE_CRITICAL_SECTION(mempool.cs);
uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[512],*ptr;
CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), stakeHeight);
if (ASSETCHAINS_LWMAPOS != 0)
{
}
else
{
blocktime = GetAdjustedTime();
siglen = komodo_staked(txStaked, pblock->nBits, &blocktime, &txtime, &utxotxid, &utxovout, &utxovalue, utxosig);
// if you skip this check it will create a block too far into the future and not pass ProcessBlock or AcceptBlock.
// This has been moved from the mining loop to save CPU, and to also make ac_staked work
while ( blocktime-57 > GetAdjustedTime() )
{
sleep(1);
if ( (rand() % 100) < 1 )
fprintf(stderr, "%u seconds until elegible, waiting.\n", blocktime-((uint32_t)GetAdjustedTime()+57));
if ( chainActive.LastTip()->GetHeight() >= stakeHeight )
{
fprintf(stderr, "Block Arrived, reset staking loop.\n");
return(0);
}
if( !GetBoolArg("-gen",false) )
return(0);
}
}
if ( siglen > 0 )
{
CAmount txfees;
txfees = 0;
pblock->vtx.push_back(txStaked);
pblocktemplate->vTxFees.push_back(txfees);
pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txStaked));
nFees += txfees;
pblock->nTime = blocktime;
//printf("staking PoS ht.%d t%u lag.%u\n",(int32_t)chainActive.LastTip()->GetHeight()+1,blocktime,(uint32_t)(GetAdjustedTime() - (blocktime-13)));
} else return(0); //fprintf(stderr,"no utxos eligible for staking\n");
}
// Create coinbase tx
CMutableTransaction txNew = CreateNewContextualCMutableTransaction(consensusParams, nHeight);
@@ -644,16 +598,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
txNew.vout[0].nValue += 5000;
pblock->vtx[0] = txNew;
if ( ASSETCHAINS_MARMARA != 0 && nHeight > 0 && (nHeight & 1) == 0 )
{
char checkaddr[64];
Getscriptaddress(checkaddr,txNew.vout[0].scriptPubKey);
//`fprintf(stderr,"set mining coinbase -> %s\n",checkaddr);
txNew.vout.resize(2);
txNew.vout[1].nValue = 0;
txNew.vout[1].scriptPubKey = MarmaraCoinbaseOpret('C',nHeight,pk);
}
else if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1) && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0) && (commission= komodo_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0 )
if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1) && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0) && (commission= komodo_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0 )
{
int32_t i; uint8_t *ptr;
txNew.vout.resize(2);
@@ -754,7 +699,8 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
if ( ASSETCHAINS_SYMBOL[0] == 0 && IS_KOMODO_NOTARY != 0 && My_notaryid >= 0 )
{
uint32_t r;
uint32_t r; CScript opret; void **ptr=0;
CMutableTransaction txNotary = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1);
if ( pblock->nTime < pindexPrev->nTime+60 )
pblock->nTime = pindexPrev->nTime + 60;
@@ -768,7 +714,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
memcpy(&r,&randvals,sizeof(r));
pblock->nTime += (r % (33 - gpucount)*(33 - gpucount));
}
if ( komodo_notaryvin(txNotary,NOTARY_PUBKEY33) > 0 )
if ( komodo_notaryvin(txNotary,NOTARY_PUBKEY33,ptr) > 0 )
{
CAmount txfees = 5000;
pblock->vtx.push_back(txNotary);
@@ -933,8 +879,6 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight,
scriptPubKey[34] = OP_CHECKSIG;
}
}
if ( ASSETCHAINS_MARMARA != 0 && nHeight > 0 && (nHeight & 1) == 0 )
scriptPubKey = Marmara_scriptPubKey(nHeight,pubkey);
return CreateNewBlock(pubkey, scriptPubKey, gpucount, isStake);
}

View File

@@ -2,13 +2,10 @@
#include "notaries_staked.h"
#include "crosschain.h"
#include "cc/CCinclude.h"
#include "komodo_defs.h"
#include <cstring>
extern char NOTARYADDRS[64][64];
extern std::string NOTARY_ADDRESS,NOTARY_PUBKEY;
extern int32_t STAKED_ERA,IS_STAKED_NOTARY,IS_KOMODO_NOTARY;
extern pthread_mutex_t staked_mutex;
extern uint8_t NOTARY_PUBKEY33[33];
int8_t is_STAKED(const char *chain_name)
{

View File

@@ -23,8 +23,10 @@ static const char *iguanaSeeds[8][1] =
static const int STAKED_ERA_GAP = 777;
static const int NUM_STAKED_ERAS = 4;
static const int STAKED_NOTARIES_TIMESTAMP[NUM_STAKED_ERAS] = {1604244444, 1604244444, 1604244444, 1604244444};
static const int32_t num_notaries_STAKED[NUM_STAKED_ERAS] = { 22, 1, 1, 1 };
// Set timestamp for notary change over in position 1:
static const int STAKED_NOTARIES_TIMESTAMP[NUM_STAKED_ERAS] = {1572523200, 1704244444, 1704244444, 1704244444}; // Oct 31 noon UTC
// Set the number of keys in position 2:
static const int32_t num_notaries_STAKED[NUM_STAKED_ERAS] = { 22, 24, 1, 1 };
// Era array of pubkeys.
static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] =
@@ -54,7 +56,30 @@ static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] =
{"Exile13", "0247b2120a39faf83678b5de6883e039180ff42925bcb298d32f3792cd59001aae" }, // RTDJ3CDZ6ANbeDKab8nqTVrGw7ViAKLeDV right
},
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"blackjok3r", "035fc678bf796ad52f69e1f5759be54ec671c559a22adf27eed067e0ddf1531574"}, //RTcYRJ6WopYkUqcmksyjxoV1CueYyqxFuk
{"Alright", "02b718c60a035f77b7103a507d36aed942b4f655b8d13bce6f28b8eac523944278"}, //RG77F4mQpP1K1q2CDSc2vZSJvKUZgF8R26
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d"}, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "03745656c8991c4597828aad2820760c43c00ff2e3b381fef3b5c040f32a7b3a34"}, //RNhYJAaPHJCVXGWNVEJeP3TfepEPdhjrRr
{"smk762", "02381616fbc02d3f0398c912fe7b7daf2f3f29e55dc35287f686b15686d8135a9f"}, //RSchwBApVquaG6mXH31bQ6P83kMN4Hound
{"jorian", "0343eec31037d7b909efd968a5b5e7af60321bf7e464da28f815f0fb23ee7aadd7"}, //RJorianBXNwfNDYPxtNYJJ6vX7Z3VdTR25
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96"}, //RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"CHMEX", "031938a89a44b3c11d53ac332d01a465384a75394fddfe98055ca3fed00ccff236"}, //RCyHdP6EvVDdfpFPzbfACHMhQAN6Wd3Wdv
{"metaphilibert", "0344182c376f054e3755d712361672138660bda8005abb64067eb5aa98bdb40d10"}, //RG28QSnYFADBg1dAVkH1uPGYS6F8ioEUM2
{"gt", "02312dcecb6e4a32927a075972d3c009f3c68635d8100562cc1813ea66751b9fde"}, //RCg4tzKWQ7i3wrZEU8bvCbCQ4xRJnHnyoo
{"CMaurice", "026c6d094523e810641b89f2d7f0ddd8f0b59d97c32e1fa97f0e3e0ac119c26ae4"}, //RSjayeSuYUE1E22rBjnqoexobaRjbAZ2Yb
{"Bar_F1sh_Rel", "0395f2d9dd9ccb78caf74bff49b6d959afb95af746462e1b35f4a167d8e82b3666"}, //RBbLxJagCA9QHDazQvfnDZe874V1K4Gu8t
{"zatJUM", "030fff499b6dc0215344b28a0b6b4becdfb00cd34cd1b36b983ec14f47965fd4bc"}, //RSoEDLBasth7anxS8gbkg6KgeGiz8rhqv1
{"Oszy", "02d1dd4c5d5c00039322295aa965f9787a87d234ed4f8174231bbd6162e384eba8"}, //RWQmJQfYrZBxQhuazVrordif6sHPFJRP9W
{"gcharang", "021569dd350d99e685a739c5b36bd01f217efb4f448a6f9a56da80c5edf6ce20ee"}, //RE8SsNwhYoygXJSvw9DuQbJicDc28dwR78
{"computergenie", "027313dabde94fb72f823231d0a1c59fc7baa2e5b3bb2af97ca7d70aae116026b9"}, //RLabsCGxTRqJcJvz6foKuXAB61puJ2x8yt
{"daemonfox", "0383484bdc745b2b953c85b5a0c496a1f27bc42ae971f15779ed1532421b3dd943"}, //REScxcZm3dsWmERSax1yVgoPPadh8BYQ6k
{"SHossain", "033e90f5550dfea6c61f8d26a026ec5edcb9ecf9c69230da246f9762ee9542782d"}, //RKTwJMAs9jVSmXQq4x6jCw48i8g5xkTeQp
{"Nabob", "03ee91c20b6d26e3604022f42df6bb8de6f669da4591f93b568778cba13d9e9ddf"}, //RRwCLPZDzpHEFJnLev4phy51e2stHRUAaU
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09"}, //RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"PHBA2061", "03f4d3b286bb3d75d0095761dcca4aef778d9eb82065f95b5f9f8b8be8cad82bc7"}, //RPHba2o61CBZ1aUQhEGhgHJhJEGsR5T68i
{"ml777", "03438497e857f346e91bb269fc00d3509ab2a4d9df14931de86c8ac39aa8d82507"}, //RCRd3jESCdEgfX4gPoZsXx1Q1RQMqMa2kR
{"bishop", "026acce6b8ac3f0ed44271f1e275f220bb66ab9ff628b70bccb67b1d7d2411b320"}, //RQEUDihRhhN316K8gVLHY1neWBJjAbrtd5
{"OldManPhil", "03d0bb79578613bb8c160d0466027ce0e7dd4d0dc6777b37460ac05342cd1e6c5b"}, //RVX3cr4J2FBDoztgF8rCuQN6vTf42XAL2U
},
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x

View File

@@ -39,20 +39,7 @@ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight)
continue;
//printf("Authorised notarisation data for %s \n",data.symbol);
} else if (authority == CROSSCHAIN_STAKED) {
// We need to create auth_STAKED dynamically here based on timestamp
int32_t staked_era = STAKED_era(timestamp);
if (staked_era == 0) {
// this is an ERA GAP, so we will ignore this notarization
continue;
if ( is_STAKED(data.symbol) == 255 )
// this chain is banned... we will discard its notarisation.
continue;
} else {
// pass era slection off to notaries_staked.cpp file
auth_STAKED = Choose_auth_STAKED(staked_era);
}
if (!CheckTxAuthority(tx, auth_STAKED))
continue;
continue;
}
if (parsed) {

View File

@@ -613,133 +613,6 @@ bool DoesHashQualify(const CBlockIndex *pbindex)
return true;
}
// the goal is to keep POS at a solve time that is a ratio of block time units. the low resolution makes a stable solution more challenging
// and requires that the averaging window be quite long.
uint32_t lwmaGetNextPOSRequired(const CBlockIndex* pindexLast, const Consensus::Params& params)
{
arith_uint256 nextTarget {0}, sumTarget {0}, bnTmp, bnLimit;
bnLimit = UintToArith256(params.posLimit);
uint32_t nProofOfStakeLimit = bnLimit.GetCompact();
int64_t t = 0, solvetime = 0;
int64_t k = params.nLwmaPOSAjustedWeight;
int64_t N = params.nPOSAveragingWindow;
struct solveSequence {
int64_t solveTime;
bool consecutive;
uint32_t nBits;
solveSequence()
{
consecutive = 0;
solveTime = 0;
nBits = 0;
}
};
// Find the first block in the averaging interval as we total the linearly weighted average
// of POS solve times
const CBlockIndex* pindexFirst = pindexLast;
// we need to make sure we have a starting nBits reference, which is either the last POS block, or the default
// if we have had no POS block in the threshold number of blocks, we must return the default, otherwise, we'll now have
// a starting point
uint32_t nBits = nProofOfStakeLimit;
for (int64_t i = 0; i < KOMODO_NOPOS_THRESHHOLD; i++)
{
if (!pindexFirst)
return nProofOfStakeLimit;
CBlockHeader hdr = pindexFirst->GetBlockHeader();
pindexFirst = pindexFirst->pprev;
}
pindexFirst = pindexLast;
std::vector<solveSequence> idx = std::vector<solveSequence>();
idx.resize(N);
for (int64_t i = N - 1; i >= 0; i--)
{
// we measure our solve time in passing of blocks, where one bock == KOMODO_BLOCK_POSUNITS units
// consecutive blocks in either direction have their solve times exponentially multiplied or divided by power of 2
int x;
for (x = 0; x < KOMODO_CONSECUTIVE_POS_THRESHOLD; x++)
{
pindexFirst = pindexFirst->pprev;
if (!pindexFirst)
return nProofOfStakeLimit;
CBlockHeader hdr = pindexFirst->GetBlockHeader();
}
if (x)
{
idx[i].consecutive = false;
{
int64_t lastSolveTime = 0;
idx[i].solveTime = KOMODO_BLOCK_POSUNITS;
for (int64_t j = 0; j < x; j++)
{
lastSolveTime = KOMODO_BLOCK_POSUNITS + (lastSolveTime >> 1);
idx[i].solveTime += lastSolveTime;
}
}
idx[i].nBits = nBits;
}
else
{
idx[i].consecutive = true;
idx[i].nBits = nBits;
// go forward and halve the minimum solve time for all consecutive blocks in this run, to get here, our last block is POS,
// and if there is no POS block in front of it, it gets the normal solve time of one block
uint32_t st = KOMODO_BLOCK_POSUNITS;
for (int64_t j = i; j < N; j++)
{
if (idx[j].consecutive == true)
{
idx[j].solveTime = st;
if ((j - i) >= KOMODO_CONSECUTIVE_POS_THRESHOLD)
{
// if this is real time, return zero
if (j == (N - 1))
{
// target of 0 (virtually impossible), if we hit max consecutive POS blocks
nextTarget.SetCompact(0);
return nextTarget.GetCompact();
}
}
st >>= 1;
}
else
break;
}
}
}
for (int64_t i = N - 1; i >= 0; i--)
{
// weighted sum
t += idx[i].solveTime * i;
// Target sum divided by a factor, (k N^2).
// The factor is a part of the final equation. However we divide
// here to avoid potential overflow.
bnTmp.SetCompact(idx[i].nBits);
sumTarget += bnTmp / (k * N * N);
}
// Keep t reasonable in case strange solvetimes occurred.
if (t < N * k / 3)
t = N * k / 3;
nextTarget = t * sumTarget;
if (nextTarget > bnLimit)
nextTarget = bnLimit;
return nextTarget.GetCompact();
}
bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& params)
{
if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH)
@@ -780,6 +653,8 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,
int32_t komodo_is_special(uint8_t pubkeys[66][33],int32_t mids[66],uint32_t blocktimes[66],int32_t height,uint8_t pubkey33[33],uint32_t blocktime);
int32_t komodo_currentheight();
void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height);
bool komodo_checkopret(CBlock *pblock, CScript &merkleroot);
CScript komodo_makeopret(CBlock *pblock, bool fNew);
extern int32_t KOMODO_CHOSEN_ONE;
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
#define KOMODO_ELECTION_GAP 2000
@@ -840,7 +715,6 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t
}
if ( (flag != 0 || special2 > 0) && special2 != -2 )
{
//fprintf(stderr,"EASY MINING ht.%d\n",height);
bnTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
}
}

View File

@@ -37,8 +37,6 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
int64_t nLastBlockTime, int64_t nFirstBlockTime,
const Consensus::Params&);
unsigned int lwmaGetNextPOSRequired(const CBlockIndex* pindexLast, const Consensus::Params& params);
/** Check whether the Equihash solution in a block header is valid */
bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams&);

View File

@@ -28,17 +28,6 @@
#include "uint256.h"
#include "arith_uint256.h"
extern int32_t ASSETCHAINS_LWMAPOS;
class CPOSNonce : public uint256
{
public:
CPOSNonce() : uint256() { }
CPOSNonce(const base_blob<256> &b) : uint256(b) { }
CPOSNonce(const std::vector<unsigned char> &vch) : uint256(vch) { }
};
/** Nodes collect new transactions into a block, hash them into a hash tree,
* and scan through nonce values to make the block's hash satisfy proof-of-work
* requirements. When they solve the proof-of-work, they broadcast the block
@@ -61,8 +50,7 @@ public:
uint256 hashFinalSaplingRoot;
uint32_t nTime;
uint32_t nBits;
CPOSNonce nNonce;
//uint256 nNonce;
uint256 nNonce;
std::vector<unsigned char> nSolution;

View File

@@ -1,9 +0,0 @@
.PHONY: FORCE
all: FORCE
$(MAKE) -C .. komodo_qt test_komodo_qt
clean: FORCE
$(MAKE) -C .. komodo_qt_clean test_komodo_qt_clean
check: FORCE
$(MAKE) -C .. test_komodo_qt_check
komodo-qt komodo-qt.exe: FORCE
$(MAKE) -C .. komodo_qt

View File

@@ -1,658 +0,0 @@
// Copyright (c) 2011-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif
#include "bitcoingui.h"
#include "clientmodel.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "intro.h"
#include "networkstyle.h"
#include "optionsmodel.h"
#include "splashscreen.h"
#include "utilitydialog.h"
#include "winshutdownmonitor.h"
#ifdef ENABLE_WALLET
#include "paymentserver.h"
#include "walletmodel.h"
#endif
#include "init.h"
#include "main.h"
#include "rpc/server.h"
#include "scheduler.h"
#include "ui_interface.h"
#include "util.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#endif
#include <stdint.h>
#include <boost/filesystem/operations.hpp>
#include <boost/thread.hpp>
#include <QApplication>
#include <QDebug>
#include <QLibraryInfo>
#include <QLocale>
#include <QMessageBox>
#include <QSettings>
#include <QThread>
#include <QTimer>
#include <QTranslator>
#include <QSslConfiguration>
#if defined(QT_STATICPLUGIN)
#include <QtPlugin>
#if QT_VERSION < 0x050000
Q_IMPORT_PLUGIN(qcncodecs)
Q_IMPORT_PLUGIN(qjpcodecs)
Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
Q_IMPORT_PLUGIN(qtaccessiblewidgets)
#else
#if QT_VERSION < 0x050400
Q_IMPORT_PLUGIN(AccessibleFactory)
#endif
#if defined(QT_QPA_PLATFORM_XCB)
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_WINDOWS)
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_COCOA)
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
#endif
#endif
#endif
#if QT_VERSION < 0x050000
#include <QTextCodec>
#endif
// Declare meta types used for QMetaObject::invokeMethod
Q_DECLARE_METATYPE(bool*)
Q_DECLARE_METATYPE(CAmount)
static void InitMessage(const std::string &message)
{
LogPrintf("init message: %s\n", message);
}
/*
Translate string to current locale using Qt.
*/
static std::string Translate(const char* psz)
{
return QCoreApplication::translate("bitcoin-core", psz).toStdString();
}
static QString GetLangTerritory()
{
QSettings settings;
// Get desired locale (e.g. "de_DE")
// 1) System default language
QString lang_territory = QLocale::system().name();
// 2) Language from QSettings
QString lang_territory_qsettings = settings.value("language", "").toString();
if(!lang_territory_qsettings.isEmpty())
lang_territory = lang_territory_qsettings;
// 3) -lang command line argument
lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString()));
return lang_territory;
}
/** Set up translations */
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
{
// Remove old translators
QApplication::removeTranslator(&qtTranslatorBase);
QApplication::removeTranslator(&qtTranslator);
QApplication::removeTranslator(&translatorBase);
QApplication::removeTranslator(&translator);
// Get desired locale (e.g. "de_DE")
// 1) System default language
QString lang_territory = GetLangTerritory();
// Convert to "de" only by truncating "_DE"
QString lang = lang_territory;
lang.truncate(lang_territory.lastIndexOf('_'));
// Load language files for configured locale:
// - First load the translator for the base language, without territory
// - Then load the more specific locale translator
// Load e.g. qt_de.qm
if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
QApplication::installTranslator(&qtTranslatorBase);
// Load e.g. qt_de_DE.qm
if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
QApplication::installTranslator(&qtTranslator);
// Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
if (translatorBase.load(lang, ":/translations/"))
QApplication::installTranslator(&translatorBase);
// Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
if (translator.load(lang_territory, ":/translations/"))
QApplication::installTranslator(&translator);
}
/* qDebug() message handler --> debug.log */
#if QT_VERSION < 0x050000
void DebugMessageHandler(QtMsgType type, const char *msg)
{
const char *category = (type == QtDebugMsg) ? "qt" : NULL;
LogPrint(category, "GUI: %s\n", msg);
}
#else
void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
{
Q_UNUSED(context);
const char *category = (type == QtDebugMsg) ? "qt" : NULL;
LogPrint(category, "GUI: %s\n", msg.toStdString());
}
#endif
/** Class encapsulating Bitcoin Core startup and shutdown.
* Allows running startup and shutdown in a different thread from the UI thread.
*/
class BitcoinCore: public QObject
{
Q_OBJECT
public:
explicit BitcoinCore();
public Q_SLOTS:
void initialize();
void shutdown();
Q_SIGNALS:
void initializeResult(int retval);
void shutdownResult(int retval);
void runawayException(const QString &message);
private:
boost::thread_group threadGroup;
CScheduler scheduler;
/// Pass fatal exception message to UI thread
void handleRunawayException(const std::exception *e);
};
/** Main Bitcoin application object */
class BitcoinApplication: public QApplication
{
Q_OBJECT
public:
explicit BitcoinApplication(int &argc, char **argv);
~BitcoinApplication();
#ifdef ENABLE_WALLET
/// Create payment server
void createPaymentServer();
#endif
/// Create options model
void createOptionsModel();
/// Create main window
void createWindow(const NetworkStyle *networkStyle);
/// Create splash screen
void createSplashScreen(const NetworkStyle *networkStyle);
/// Request core initialization
void requestInitialize();
/// Request core shutdown
void requestShutdown();
/// Get process return value
int getReturnValue() { return returnValue; }
/// Get window identifier of QMainWindow (BitcoinGUI)
WId getMainWinId() const;
public Q_SLOTS:
void initializeResult(int retval);
void shutdownResult(int retval);
/// Handle runaway exceptions. Shows a message box with the problem and quits the program.
void handleRunawayException(const QString &message);
Q_SIGNALS:
void requestedInitialize();
void requestedShutdown();
void stopThread();
void splashFinished(QWidget *window);
private:
QThread *coreThread;
OptionsModel *optionsModel;
ClientModel *clientModel;
BitcoinGUI *window;
QTimer *pollShutdownTimer;
#ifdef ENABLE_WALLET
PaymentServer* paymentServer;
WalletModel *walletModel;
#endif
int returnValue;
void startThread();
};
#include "bitcoin.moc"
BitcoinCore::BitcoinCore():
QObject()
{
}
void BitcoinCore::handleRunawayException(const std::exception *e)
{
PrintExceptionContinue(e, "Runaway exception");
Q_EMIT runawayException(QString::fromStdString(strMiscWarning));
}
void BitcoinCore::initialize()
{
try
{
qDebug() << __func__ << ": Running AppInit2 in thread";
int rv = AppInit2(threadGroup, scheduler);
if(rv)
{
/* Start a dummy RPC thread if no RPC thread is active yet
* to handle timeouts.
*/
StartDummyRPCThread();
}
Q_EMIT initializeResult(rv);
} catch (const std::exception& e) {
handleRunawayException(&e);
} catch (...) {
handleRunawayException(NULL);
}
}
void BitcoinCore::shutdown()
{
try
{
qDebug() << __func__ << ": Running Shutdown in thread";
threadGroup.interrupt_all();
threadGroup.join_all();
Shutdown();
qDebug() << __func__ << ": Shutdown finished";
Q_EMIT shutdownResult(1);
} catch (const std::exception& e) {
handleRunawayException(&e);
} catch (...) {
handleRunawayException(NULL);
}
}
BitcoinApplication::BitcoinApplication(int &argc, char **argv):
QApplication(argc, argv),
coreThread(0),
optionsModel(0),
clientModel(0),
window(0),
pollShutdownTimer(0),
#ifdef ENABLE_WALLET
paymentServer(0),
walletModel(0),
#endif
returnValue(0)
{
setQuitOnLastWindowClosed(false);
}
BitcoinApplication::~BitcoinApplication()
{
if(coreThread)
{
qDebug() << __func__ << ": Stopping thread";
Q_EMIT stopThread();
coreThread->wait();
qDebug() << __func__ << ": Stopped thread";
}
delete window;
window = 0;
#ifdef ENABLE_WALLET
delete paymentServer;
paymentServer = 0;
#endif
delete optionsModel;
optionsModel = 0;
}
#ifdef ENABLE_WALLET
void BitcoinApplication::createPaymentServer()
{
paymentServer = new PaymentServer(this);
}
#endif
void BitcoinApplication::createOptionsModel()
{
optionsModel = new OptionsModel();
}
void BitcoinApplication::createWindow(const NetworkStyle *networkStyle)
{
window = new BitcoinGUI(networkStyle, 0);
pollShutdownTimer = new QTimer(window);
connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
pollShutdownTimer->start(200);
}
void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle)
{
SplashScreen *splash = new SplashScreen(0, networkStyle);
// We don't hold a direct pointer to the splash screen after creation, so use
// Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually.
splash->setAttribute(Qt::WA_DeleteOnClose);
splash->show();
connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*)));
}
void BitcoinApplication::startThread()
{
if(coreThread)
return;
coreThread = new QThread(this);
BitcoinCore *executor = new BitcoinCore();
executor->moveToThread(coreThread);
/* communication to and from thread */
connect(executor, SIGNAL(initializeResult(int)), this, SLOT(initializeResult(int)));
connect(executor, SIGNAL(shutdownResult(int)), this, SLOT(shutdownResult(int)));
connect(executor, SIGNAL(runawayException(QString)), this, SLOT(handleRunawayException(QString)));
connect(this, SIGNAL(requestedInitialize()), executor, SLOT(initialize()));
connect(this, SIGNAL(requestedShutdown()), executor, SLOT(shutdown()));
/* make sure executor object is deleted in its own thread */
connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
connect(this, SIGNAL(stopThread()), coreThread, SLOT(quit()));
coreThread->start();
}
void BitcoinApplication::requestInitialize()
{
qDebug() << __func__ << ": Requesting initialize";
startThread();
Q_EMIT requestedInitialize();
}
void BitcoinApplication::requestShutdown()
{
qDebug() << __func__ << ": Requesting shutdown";
startThread();
window->hide();
window->setClientModel(0);
pollShutdownTimer->stop();
#ifdef ENABLE_WALLET
window->removeAllWallets();
delete walletModel;
walletModel = 0;
#endif
delete clientModel;
clientModel = 0;
// Show a simple window indicating shutdown status
ShutdownWindow::showShutdownWindow(window);
// Request shutdown from core thread
Q_EMIT requestedShutdown();
}
void BitcoinApplication::initializeResult(int retval)
{
qDebug() << __func__ << ": Initialization result: " << retval;
// Set exit result: 0 if successful, 1 if failure
returnValue = retval ? 0 : 1;
if(retval)
{
#ifdef ENABLE_WALLET
PaymentServer::LoadRootCAs();
paymentServer->setOptionsModel(optionsModel);
#endif
clientModel = new ClientModel(optionsModel);
window->setClientModel(clientModel);
#ifdef ENABLE_WALLET
if(pwalletMain)
{
walletModel = new WalletModel(pwalletMain, optionsModel);
window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
}
#endif
// If -min option passed, start window minimized.
if(GetBoolArg("-min", false))
{
window->showMinimized();
}
else
{
window->show();
}
Q_EMIT splashFinished(window);
#ifdef ENABLE_WALLET
// Now that initialization/startup is done, process any command-line
// bitcoin: URIs or payment requests:
connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
window, SLOT(handlePaymentRequest(SendCoinsRecipient)));
connect(window, SIGNAL(receivedURI(QString)),
paymentServer, SLOT(handleURIOrFile(QString)));
connect(paymentServer, SIGNAL(message(QString,QString,unsigned int)),
window, SLOT(message(QString,QString,unsigned int)));
QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
#endif
} else {
quit(); // Exit main loop
}
}
void BitcoinApplication::shutdownResult(int retval)
{
qDebug() << __func__ << ": Shutdown result: " << retval;
quit(); // Exit main loop after shutdown finished
}
void BitcoinApplication::handleRunawayException(const QString &message)
{
QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + message);
::exit(1);
}
WId BitcoinApplication::getMainWinId() const
{
if (!window)
return 0;
return window->winId();
}
#ifndef BITCOIN_QT_TEST
int main(int argc, char *argv[])
{
SetupEnvironment();
/// 1. Parse command-line options. These take precedence over anything else.
// Command-line options take precedence:
ParseParameters(argc, argv);
// Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
/// 2. Basic Qt initialization (not dependent on parameters or configuration)
#if QT_VERSION < 0x050000
// Internal string conversion is all UTF-8
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
#endif
Q_INIT_RESOURCE(bitcoin);
Q_INIT_RESOURCE(bitcoin_locale);
BitcoinApplication app(argc, argv);
#if QT_VERSION > 0x050100
// Generate high-dpi pixmaps
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
#ifdef Q_OS_MAC
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
#endif
#if QT_VERSION >= 0x050500
// Because of the POODLE attack it is recommended to disable SSLv3 (https://disablessl3.com/),
// so set SSL protocols to TLS1.0+.
QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration();
sslconf.setProtocol(QSsl::TlsV1_0OrLater);
QSslConfiguration::setDefaultConfiguration(sslconf);
#endif
// Register meta types used for QMetaObject::invokeMethod
qRegisterMetaType< bool* >();
// Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
// IMPORTANT if it is no longer a typedef use the normal variant above
qRegisterMetaType< CAmount >("CAmount");
/// 3. Application identification
// must be set before OptionsModel is initialized or translations are loaded,
// as it is used to locate QSettings
QApplication::setOrganizationName(QAPP_ORG_NAME);
QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
GUIUtil::SubstituteFonts(GetLangTerritory());
/// 4. Initialization of translations, so that intro dialog is in user's language
// Now that QSettings are accessible, initialize translations
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
translationInterface.Translate.connect(Translate);
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
// but before showing splash screen.
if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version"))
{
HelpMessageDialog help(NULL, mapArgs.count("-version"));
help.showOrPrint();
return 1;
}
/// 5. Now that settings and translations are available, ask user for data directory
// User language is set up: pick a data directory
Intro::pickDataDirectory();
/// 6. Determine availability of data directory and parse komodo.conf
/// - Do not call GetDataDir(true) before this step finishes
if (!boost::filesystem::is_directory(GetDataDir(false)))
{
QMessageBox::critical(0, QObject::tr("Bitcoin Core"),
QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
return 1;
}
try {
ReadConfigFile(mapArgs, mapMultiArgs);
} catch (const std::exception& e) {
QMessageBox::critical(0, QObject::tr("Bitcoin Core"),
QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what()));
return false;
}
/// 7. Determine network (and switch to network specific options)
// - Do not call Params() before this step
// - Do this after parsing the configuration file, as the network can be switched there
// - QSettings() will use the new application name after this, resulting in network-specific settings
// - Needs to be done before createOptionsModel
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
if (!SelectParamsFromCommandLine()) {
QMessageBox::critical(0, QObject::tr("Bitcoin Core"), QObject::tr("Error: Invalid combination of -regtest and -testnet."));
return 1;
}
#ifdef ENABLE_WALLET
// Parse URIs on command line -- this can affect Params()
PaymentServer::ipcParseCommandLine(argc, argv);
#endif
QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
assert(!networkStyle.isNull());
// Allow for separate UI settings for testnets
QApplication::setApplicationName(networkStyle->getAppName());
// Re-initialize translations after changing application name (language in network-specific settings can be different)
initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
#ifdef ENABLE_WALLET
/// 8. URI IPC sending
// - Do this early as we don't want to bother initializing if we are just calling IPC
// - Do this *after* setting up the data directory, as the data directory hash is used in the name
// of the server.
// - Do this after creating app and setting up translations, so errors are
// translated properly.
if (PaymentServer::ipcSendCommandLine())
exit(0);
// Start up the payment server early, too, so impatient users that click on
// bitcoin: links repeatedly have their payment requests routed to this process:
app.createPaymentServer();
#endif
/// 9. Main GUI initialization
// Install global event filter that makes sure that long tooltips can be word-wrapped
app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
#if QT_VERSION < 0x050000
// Install qDebug() message handler to route to debug.log
qInstallMsgHandler(DebugMessageHandler);
#else
#if defined(Q_OS_WIN)
// Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
qApp->installNativeEventFilter(new WinShutdownMonitor());
#endif
// Install qDebug() message handler to route to debug.log
qInstallMessageHandler(DebugMessageHandler);
#endif
// Load GUI settings from QSettings
app.createOptionsModel();
// Subscribe to global signals from core
uiInterface.InitMessage.connect(InitMessage);
if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false))
app.createSplashScreen(networkStyle.data());
try
{
app.createWindow(networkStyle.data());
app.requestInitialize();
#if defined(Q_OS_WIN) && QT_VERSION >= 0x050000
WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("Bitcoin Core didn't yet exit safely..."), (HWND)app.getMainWinId());
#endif
app.exec();
app.requestShutdown();
app.exec();
} catch (const std::exception& e) {
PrintExceptionContinue(&e, "Runaway exception");
app.handleRunawayException(QString::fromStdString(strMiscWarning));
} catch (...) {
PrintExceptionContinue(NULL, "Runaway exception");
app.handleRunawayException(QString::fromStdString(strMiscWarning));
}
return app.getReturnValue();
}
#endif // BITCOIN_QT_TEST

View File

@@ -1,319 +0,0 @@
#include <QtGlobal>
// Automatically generated by extract_strings.py
#ifdef __GNUC__
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
static const char UNUSED *bitcoin_strings[] = {
QT_TRANSLATE_NOOP("bitcoin-core", ""
"(1 = keep tx meta data e.g. account owner and payment request information, 2 "
"= drop tx meta data)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Allow JSON-RPC connections from specified source. Valid for <ip> are a "
"single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or "
"a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"An error occurred while setting up the RPC address %s port %u for listening: "
"%s"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Bind to given address and always listen on it. Use [host]:port notation for "
"IPv6"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Bind to given address and whitelist peers connecting to it. Use [host]:port "
"notation for IPv6"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Bind to given address to listen for JSON-RPC connections. Use [host]:port "
"notation for IPv6. This option can be specified multiple times (default: "
"bind to all interfaces)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Cannot obtain a lock on data directory %s. Bitcoin Core is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Create new files with system default permissions, instead of umask 077 (only "
"effective with disabled wallet functionality)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Delete all wallet transactions and only recover those parts of the "
"blockchain through -rescan on startup"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Discover own IP addresses (default: 1 when listening and no -externalip or -"
"proxy)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Distributed under the MIT software license, see the accompanying file "
"COPYING or <http://www.opensource.org/licenses/mit-license.php>."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: Listening for incoming connections failed (listen returned error %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: Unsupported argument -socks found. Setting SOCKS version isn't "
"possible anymore, only SOCKS5 proxies are supported."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Execute command when a relevant alert is received or we see a really long "
"fork (%s in cmd is replaced by message)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Execute command when a wallet transaction changes (%s in cmd is replaced by "
"TxID)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Execute command when the best block changes (%s in cmd is replaced by block "
"hash)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Fees (in BTC/Kb) smaller than this are considered zero fee for relaying "
"(default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"How thorough the block verification of -checkblocks is (0-4, default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"If paytxfee is not set, include enough fee so transactions begin "
"confirmation on average within n blocks (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay "
"fee of %s to prevent stuck transactions)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Maintain a full transaction index, used by the getrawtransaction rpc call "
"(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Maximum size of data in data carrier transactions we relay and mine "
"(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Maximum total fees to use in a single wallet transaction; setting this too "
"low may abort large transactions (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Number of seconds to keep misbehaving peers from reconnecting (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Output debugging information (default: %u, supplying <category> is optional)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Prune configured below the minimum of %d MB. Please use a higher number."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Query for peer addresses via DNS lookup, if low on addresses (default: 1 "
"unless -connect)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Randomize credentials for every proxy connection. This enables Tor stream "
"isolation (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Reduce storage requirements by pruning (deleting) old blocks. This mode "
"disables wallet support and is incompatible with -txindex. Warning: "
"Reverting this setting requires re-downloading the entire blockchain. "
"(default: 0 = disable pruning blocks, >%u = target size in MiB to use for "
"block files)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Set the number of script verification threads (%u to %d, 0 = auto, <0 = "
"leave that many cores free, default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Set the number of threads for coin generation if enabled (-1 = all cores, "
"default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"The transaction amount is too small to send after the fee has been deducted"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"This is a pre-release test build - use at your own risk - do not use for "
"mining or merchant applications"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"This product includes software developed by the OpenSSL Project for use in "
"the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software "
"written by Eric Young and UPnP software written by Thomas Bernard."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"To use bitcoind, or the -server option to komodo-qt, you must set an "
"rpcpassword in the configuration file:\n"
"%s\n"
"It is recommended you use the following random password:\n"
"rpcuser=bitcoinrpc\n"
"rpcpassword=%s\n"
"(you do not need to remember this password)\n"
"The username and password MUST NOT be the same.\n"
"If the file does not exist, create it with owner-readable-only file "
"permissions.\n"
"It is also recommended to set alertnotify so you are notified of problems;\n"
"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to bind to %s on this computer. Bitcoin Core is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: "
"%s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"WARNING: abnormally high number of blocks generated, %d blocks received in "
"the last %d hours (%d expected)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"WARNING: check your network connection, %d blocks received in the last %d "
"hours (%d expected)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: -maxtxfee is set very high! Fees this large could be paid on a "
"single transaction."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: -paytxfee is set very high! This is the transaction fee you will "
"pay if you send a transaction."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: Please check that your computer's date and time are correct! If "
"your clock is wrong Bitcoin Core will not work properly."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: The network does not appear to fully agree! Some miners appear to "
"be experiencing issues."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: We do not appear to fully agree with our peers! You may need to "
"upgrade, or other nodes may need to upgrade."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: error reading wallet.dat! All keys read correctly, but transaction "
"data or address book entries might be missing or incorrect."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as "
"wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect "
"you should restore from a backup."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Whitelist peers connecting from the given netmask or IP address. Can be "
"specified multiple times."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Whitelisted peers cannot be DoS banned and their transactions are always "
"relayed, even if they are already in the mempool, useful e.g. for a gateway"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"You need to rebuild the database using -reindex to go back to unpruned "
"mode. This will redownload the entire blockchain"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept public REST requests (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Acceptable ciphers (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Activating best chain..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Can't run with a wallet in prune mode."),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -whitebind address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Choose data directory on startup (default: 0)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through SOCKS5 proxy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connection options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) 2009-%i The Bitcoin Core Developers"),
QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"),
QT_TRANSLATE_NOOP("bitcoin-core", "Could not parse -rpcbind value %s as network address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Debugging/Testing options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Do not load the wallet and disable wallet RPC calls"),
QT_TRANSLATE_NOOP("bitcoin-core", "error with HDD data, maybe just need to update to latest version"),
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing wallet database environment %s!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin Core"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see debug.log for details"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."),
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in BTC/kB) to add to transactions you send (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: %u, 0 = all)"),
QT_TRANSLATE_NOOP("bitcoin-core", "If <category> is not supplied, output all debugging information."),
QT_TRANSLATE_NOOP("bitcoin-core", "Importing..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file"),
QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Incorrect or no genesis block found. Wrong datadir for network?"),
QT_TRANSLATE_NOOP("bitcoin-core", "Information"),
QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. Bitcoin Core is shutting down."),
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -onion address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -maxtxfee=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -minrelaytxfee=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -mintxfee=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: %u or testnet: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Make the wallet broadcast transactions"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."),
QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4, ipv6 or onion)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Prune cannot be configured with a negative value."),
QT_TRANSLATE_NOOP("bitcoin-core", "Prune mode is incompatible with -txindex."),
QT_TRANSLATE_NOOP("bitcoin-core", "Pruning blockstore..."),
QT_TRANSLATE_NOOP("bitcoin-core", "RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "RPC support for HTTP persistent connections (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files on startup"),
QT_TRANSLATE_NOOP("bitcoin-core", "Receive and display P2P network alerts (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set SSL root certificates for payment request (default: -system-)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: system locale)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Signing transaction failed"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout in milliseconds (minimum: 1, default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"),
QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"),
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."),
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"),
QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 1 when listening)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet %s resides outside data directory %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin Core to complete"),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: This version is obsolete; upgrade required!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -benchmark ignored, use -debug=bench."),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -debugnet ignored, use -debug=net."),
QT_TRANSLATE_NOOP("bitcoin-core", "You need to rebuild the database using -reindex to change -txindex"),
QT_TRANSLATE_NOOP("bitcoin-core", "Zapping all transactions from wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "on startup"),
QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"),
};

View File

@@ -1,52 +0,0 @@
// Copyright (c) 2011-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_GUICONSTANTS_H
#define BITCOIN_QT_GUICONSTANTS_H
/* Milliseconds between model updates */
static const int MODEL_UPDATE_DELAY = 250;
/* AskPassphraseDialog -- Maximum passphrase length */
static const int MAX_PASSPHRASE_SIZE = 1024;
/* BitcoinGUI -- Size of icons in status bar */
static const int STATUSBAR_ICONSIZE = 16;
/* Invalid field background style */
#define STYLE_INVALID "background:#FF8080"
/* Transaction list -- unconfirmed transaction */
#define COLOR_UNCONFIRMED QColor(128, 128, 128)
/* Transaction list -- negative amount */
#define COLOR_NEGATIVE QColor(255, 0, 0)
/* Transaction list -- bare address (without label) */
#define COLOR_BAREADDRESS QColor(140, 140, 140)
/* Transaction list -- TX status decoration - open until date */
#define COLOR_TX_STATUS_OPENUNTILDATE QColor(64, 64, 255)
/* Transaction list -- TX status decoration - offline */
#define COLOR_TX_STATUS_OFFLINE QColor(192, 192, 192)
/* Transaction list -- TX status decoration - default color */
#define COLOR_BLACK QColor(0, 0, 0)
/* Tooltips longer than this (in characters) are converted into rich text,
so that they can be word-wrapped.
*/
static const int TOOLTIP_WRAP_THRESHOLD = 80;
/* Maximum allowed URI length */
static const int MAX_URI_LENGTH = 255;
/* QRCodeDialog -- size of exported QR Code image */
#define EXPORT_IMAGE_SIZE 256
/* Number of frames in spinner animation */
#define SPINNER_FRAMES 35
#define QAPP_ORG_NAME "Bitcoin"
#define QAPP_ORG_DOMAIN "bitcoin.org"
#define QAPP_APP_NAME_DEFAULT "Komodo-Qt"
#define QAPP_APP_NAME_TESTNET "Komodo-Qt-testnet"
#endif // BITCOIN_QT_GUICONSTANTS_H

View File

@@ -1,293 +0,0 @@
// Copyright (c) 2011-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "intro.h"
#include "ui_intro.h"
#include "guiutil.h"
#include "scicon.h"
#include "util.h"
#include <boost/filesystem.hpp>
#include <QFileDialog>
#include <QSettings>
#include <QMessageBox>
/* Minimum free space (in bytes) needed for data directory */
static const uint64_t GB_BYTES = 1000000000LL;
static const uint64_t BLOCK_CHAIN_SIZE = 20LL * GB_BYTES;
/* Check free space asynchronously to prevent hanging the UI thread.
Up to one request to check a path is in flight to this thread; when the check()
function runs, the current path is requested from the associated Intro object.
The reply is sent back through a signal.
This ensures that no queue of checking requests is built up while the user is
still entering the path, and that always the most recently entered path is checked as
soon as the thread becomes available.
*/
class FreespaceChecker : public QObject
{
Q_OBJECT
public:
FreespaceChecker(Intro *intro);
enum Status {
ST_OK,
ST_ERROR
};
public Q_SLOTS:
void check();
Q_SIGNALS:
void reply(int status, const QString &message, quint64 available);
private:
Intro *intro;
};
#include "intro.moc"
FreespaceChecker::FreespaceChecker(Intro *intro)
{
this->intro = intro;
}
void FreespaceChecker::check()
{
namespace fs = boost::filesystem;
QString dataDirStr = intro->getPathToCheck();
fs::path dataDir = GUIUtil::qstringToBoostPath(dataDirStr);
uint64_t freeBytesAvailable = 0;
int replyStatus = ST_OK;
QString replyMessage = tr("A new data directory will be created.");
/* Find first parent that exists, so that fs::space does not fail */
fs::path parentDir = dataDir;
fs::path parentDirOld = fs::path();
while(parentDir.has_parent_path() && !fs::exists(parentDir))
{
parentDir = parentDir.parent_path();
/* Check if we make any progress, break if not to prevent an infinite loop here */
if (parentDirOld == parentDir)
break;
parentDirOld = parentDir;
}
try {
freeBytesAvailable = fs::space(parentDir).available;
if(fs::exists(dataDir))
{
if(fs::is_directory(dataDir))
{
QString separator = "<code>" + QDir::toNativeSeparators("/") + tr("name") + "</code>";
replyStatus = ST_OK;
replyMessage = tr("Directory already exists. Add %1 if you intend to create a new directory here.").arg(separator);
} else {
replyStatus = ST_ERROR;
replyMessage = tr("Path already exists, and is not a directory.");
}
}
} catch (const fs::filesystem_error&)
{
/* Parent directory does not exist or is not accessible */
replyStatus = ST_ERROR;
replyMessage = tr("Cannot create data directory here.");
}
Q_EMIT reply(replyStatus, replyMessage, freeBytesAvailable);
}
Intro::Intro(QWidget *parent) :
QDialog(parent),
ui(new Ui::Intro),
thread(0),
signalled(false)
{
ui->setupUi(this);
ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(BLOCK_CHAIN_SIZE/GB_BYTES));
startThread();
}
Intro::~Intro()
{
delete ui;
/* Ensure thread is finished before it is deleted */
Q_EMIT stopThread();
thread->wait();
}
QString Intro::getDataDirectory()
{
return ui->dataDirectory->text();
}
void Intro::setDataDirectory(const QString &dataDir)
{
ui->dataDirectory->setText(dataDir);
if(dataDir == getDefaultDataDirectory())
{
ui->dataDirDefault->setChecked(true);
ui->dataDirectory->setEnabled(false);
ui->ellipsisButton->setEnabled(false);
} else {
ui->dataDirCustom->setChecked(true);
ui->dataDirectory->setEnabled(true);
ui->ellipsisButton->setEnabled(true);
}
}
QString Intro::getDefaultDataDirectory()
{
return GUIUtil::boostPathToQString(GetDefaultDataDir());
}
void Intro::pickDataDirectory()
{
namespace fs = boost::filesystem;
QSettings settings;
/* If data directory provided on command line, no need to look at settings
or show a picking dialog */
if(!GetArg("-datadir", "").empty())
return;
/* 1) Default data directory for operating system */
QString dataDir = getDefaultDataDirectory();
/* 2) Allow QSettings to override default dir */
dataDir = settings.value("strDataDir", dataDir).toString();
if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", false))
{
/* If current default data directory does not exist, let the user choose one */
Intro intro;
intro.setDataDirectory(dataDir);
intro.setWindowIcon(SingleColorIcon(":icons/bitcoin"));
while(true)
{
if(!intro.exec())
{
/* Cancel clicked */
exit(0);
}
dataDir = intro.getDataDirectory();
try {
TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir));
break;
} catch (const fs::filesystem_error&) {
QMessageBox::critical(0, tr("Bitcoin Core"),
tr("Error: Specified data directory \"%1\" cannot be created.").arg(dataDir));
/* fall through, back to choosing screen */
}
}
settings.setValue("strDataDir", dataDir);
}
/* Only override -datadir if different from the default, to make it possible to
* override -datadir in the komodo.conf file in the default data directory
* (to be consistent with bitcoind behavior)
*/
if(dataDir != getDefaultDataDirectory())
SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting
}
void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable)
{
switch(status)
{
case FreespaceChecker::ST_OK:
ui->errorMessage->setText(message);
ui->errorMessage->setStyleSheet("");
break;
case FreespaceChecker::ST_ERROR:
ui->errorMessage->setText(tr("Error") + ": " + message);
ui->errorMessage->setStyleSheet("QLabel { color: #800000 }");
break;
}
/* Indicate number of bytes available */
if(status == FreespaceChecker::ST_ERROR)
{
ui->freeSpace->setText("");
} else {
QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES);
if(bytesAvailable < BLOCK_CHAIN_SIZE)
{
freeString += " " + tr("(of %n GB needed)", "", BLOCK_CHAIN_SIZE/GB_BYTES);
ui->freeSpace->setStyleSheet("QLabel { color: #800000 }");
} else {
ui->freeSpace->setStyleSheet("");
}
ui->freeSpace->setText(freeString + ".");
}
/* Don't allow confirm in ERROR state */
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(status != FreespaceChecker::ST_ERROR);
}
void Intro::on_dataDirectory_textChanged(const QString &dataDirStr)
{
/* Disable OK button until check result comes in */
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
checkPath(dataDirStr);
}
void Intro::on_ellipsisButton_clicked()
{
QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(0, "Choose data directory", ui->dataDirectory->text()));
if(!dir.isEmpty())
ui->dataDirectory->setText(dir);
}
void Intro::on_dataDirDefault_clicked()
{
setDataDirectory(getDefaultDataDirectory());
}
void Intro::on_dataDirCustom_clicked()
{
ui->dataDirectory->setEnabled(true);
ui->ellipsisButton->setEnabled(true);
}
void Intro::startThread()
{
thread = new QThread(this);
FreespaceChecker *executor = new FreespaceChecker(this);
executor->moveToThread(thread);
connect(executor, SIGNAL(reply(int,QString,quint64)), this, SLOT(setStatus(int,QString,quint64)));
connect(this, SIGNAL(requestCheck()), executor, SLOT(check()));
/* make sure executor object is deleted in its own thread */
connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
connect(this, SIGNAL(stopThread()), thread, SLOT(quit()));
thread->start();
}
void Intro::checkPath(const QString &dataDir)
{
mutex.lock();
pathToCheck = dataDir;
if(!signalled)
{
signalled = true;
Q_EMIT requestCheck();
}
mutex.unlock();
}
QString Intro::getPathToCheck()
{
QString retval;
mutex.lock();
retval = pathToCheck;
signalled = false; /* new request can be queued now */
mutex.unlock();
return retval;
}

View File

@@ -1,91 +0,0 @@
// Copyright (c) 2011-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "macnotificationhandler.h"
#undef slots
#import <objc/runtime.h>
#include <Cocoa/Cocoa.h>
// Add an obj-c category (extension) to return the expected bundle identifier
@implementation NSBundle(returnCorrectIdentifier)
- (NSString *)__bundleIdentifier
{
if (self == [NSBundle mainBundle]) {
return @"org.bitcoinfoundation.Komodo-Qt";
} else {
return [self __bundleIdentifier];
}
}
@end
void MacNotificationHandler::showNotification(const QString &title, const QString &text)
{
// check if users OS has support for NSUserNotification
if(this->hasUserNotificationCenterSupport()) {
// okay, seems like 10.8+
QByteArray utf8 = title.toUtf8();
char* cString = (char *)utf8.constData();
NSString *titleMac = [[NSString alloc] initWithUTF8String:cString];
utf8 = text.toUtf8();
cString = (char *)utf8.constData();
NSString *textMac = [[NSString alloc] initWithUTF8String:cString];
// do everything weak linked (because we will keep <10.8 compatibility)
id userNotification = [[NSClassFromString(@"NSUserNotification") alloc] init];
[userNotification performSelector:@selector(setTitle:) withObject:titleMac];
[userNotification performSelector:@selector(setInformativeText:) withObject:textMac];
id notificationCenterInstance = [NSClassFromString(@"NSUserNotificationCenter") performSelector:@selector(defaultUserNotificationCenter)];
[notificationCenterInstance performSelector:@selector(deliverNotification:) withObject:userNotification];
[titleMac release];
[textMac release];
[userNotification release];
}
}
// sendAppleScript just take a QString and executes it as apple script
void MacNotificationHandler::sendAppleScript(const QString &script)
{
QByteArray utf8 = script.toUtf8();
char* cString = (char *)utf8.constData();
NSString *scriptApple = [[NSString alloc] initWithUTF8String:cString];
NSAppleScript *as = [[NSAppleScript alloc] initWithSource:scriptApple];
NSDictionary *err = nil;
[as executeAndReturnError:&err];
[as release];
[scriptApple release];
}
bool MacNotificationHandler::hasUserNotificationCenterSupport(void)
{
Class possibleClass = NSClassFromString(@"NSUserNotificationCenter");
// check if users OS has support for NSUserNotification
if(possibleClass!=nil) {
return true;
}
return false;
}
MacNotificationHandler *MacNotificationHandler::instance()
{
static MacNotificationHandler *s_instance = NULL;
if (!s_instance) {
s_instance = new MacNotificationHandler();
Class aPossibleClass = objc_getClass("NSBundle");
if (aPossibleClass) {
// change NSBundle -bundleIdentifier method to return a correct bundle identifier
// a bundle identifier is required to use OSXs User Notification Center
method_exchangeImplementations(class_getInstanceMethod(aPossibleClass, @selector(bundleIdentifier)),
class_getInstanceMethod(aPossibleClass, @selector(__bundleIdentifier)));
}
}
return s_instance;
}

View File

@@ -1,37 +0,0 @@
IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico"
#include <windows.h> // needed for VERSIONINFO
#include "../../clientversion.h" // holds the needed client version information
#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
#define VER_FILEVERSION VER_PRODUCTVERSION
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4" // U.S. English - multilingual (hex)
BEGIN
VALUE "CompanyName", "Bitcoin"
VALUE "FileDescription", "Bitcoin Core (GUI node for Bitcoin)"
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "komodo-qt"
VALUE "LegalCopyright", COPYRIGHT_STR
VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
VALUE "OriginalFilename", "komodo-qt.exe"
VALUE "ProductName", "Bitcoin Core"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
END
END

View File

@@ -1,49 +0,0 @@
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif
#include "util.h"
#include "uritests.h"
#ifdef ENABLE_WALLET
#include "paymentservertests.h"
#endif
#include <QCoreApplication>
#include <QObject>
#include <QTest>
#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000
#include <QtPlugin>
Q_IMPORT_PLUGIN(qcncodecs)
Q_IMPORT_PLUGIN(qjpcodecs)
Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
#endif
// This is all you need to run all the tests
int main(int argc, char *argv[])
{
SetupEnvironment();
bool fInvalid = false;
// Don't remove this, it's needed to access
// QCoreApplication:: in the tests
QCoreApplication app(argc, argv);
app.setApplicationName("Komodo-Qt-test");
URITests test1;
if (QTest::qExec(&test1) != 0)
fInvalid = true;
#ifdef ENABLE_WALLET
PaymentServerTests test2;
if (QTest::qExec(&test2) != 0)
fInvalid = true;
#endif
return fInvalid;
}

View File

@@ -1,326 +0,0 @@
// Copyright (c) 2011-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "transactiondesc.h"
#include "bitcoinunits.h"
#include "guiutil.h"
#include "paymentserver.h"
#include "transactionrecord.h"
#include "base58.h"
#include "consensus/consensus.h"
#include "main.h"
#include "script/script.h"
#include "timedata.h"
#include "util.h"
#include "wallet/db.h"
#include "wallet/wallet.h"
#include <stdint.h>
#include <string>
using namespace std;
QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx)
{
AssertLockHeld(cs_main);
if (!CheckFinalTx(wtx))
{
if (wtx.nLockTime < LOCKTIME_THRESHOLD)
return tr("Open for %n more block(s)", "", wtx.nLockTime - chainActive.Height());
else
return tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.nLockTime));
}
else
{
int nDepth = wtx.GetDepthInMainChain();
if (nDepth < 0)
return tr("conflicted");
else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
return tr("%1/offline").arg(nDepth);
else if (nDepth < 6)
return tr("%1/unconfirmed").arg(nDepth);
else
return tr("%1 confirmations").arg(nDepth);
}
}
QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionRecord *rec, int unit)
{
QString strHTML;
LOCK2(cs_main, wallet->cs_wallet);
strHTML.reserve(4000);
strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
int64_t nTime = wtx.GetTxTime();
CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
CAmount nNet = nCredit - nDebit;
strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx);
int nRequests = wtx.GetRequestCount();
if (nRequests != -1)
{
if (nRequests == 0)
strHTML += tr(", has not been successfully broadcast yet");
else if (nRequests > 0)
strHTML += tr(", broadcast through %n node(s)", "", nRequests);
}
strHTML += "<br>";
strHTML += "<b>" + tr("Date") + ":</b> " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>";
//
// From
//
if (wtx.IsCoinBase())
{
strHTML += "<b>" + tr("Source") + ":</b> " + tr("Generated") + "<br>";
}
else if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty())
{
// Online transaction
strHTML += "<b>" + tr("From") + ":</b> " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "<br>";
}
else
{
// Offline transaction
if (nNet > 0)
{
// Credit
if (CBitcoinAddress(rec->address).IsValid())
{
CTxDestination address = CBitcoinAddress(rec->address).Get();
if (wallet->mapAddressBook.count(address))
{
strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>";
strHTML += "<b>" + tr("To") + ":</b> ";
strHTML += GUIUtil::HtmlEscape(rec->address);
QString addressOwned = (::IsMine(*wallet, address) == ISMINE_SPENDABLE) ? tr("own address") : tr("watch-only");
if (!wallet->mapAddressBook[address].name.empty())
strHTML += " (" + addressOwned + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + ")";
else
strHTML += " (" + addressOwned + ")";
strHTML += "<br>";
}
}
}
}
//
// To
//
if (wtx.mapValue.count("to") && !wtx.mapValue["to"].empty())
{
// Online transaction
std::string strAddress = wtx.mapValue["to"];
strHTML += "<b>" + tr("To") + ":</b> ";
CTxDestination dest = CBitcoinAddress(strAddress).Get();
if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].name.empty())
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest].name) + " ";
strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>";
}
//
// Amount
//
if (wtx.IsCoinBase() && nCredit == 0)
{
//
// Coinbase
//
CAmount nUnmatured = 0;
for (int i = 0; i < wtx.vout.size(); i++)
nUnmatured += wallet->GetCredit(wtx, i, ISMINE_ALL);
strHTML += "<b>" + tr("Credit") + ":</b> ";
if (wtx.IsInMainChain())
strHTML += BitcoinUnits::formatHtmlWithUnit(unit, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")";
else
strHTML += "(" + tr("not accepted") + ")";
strHTML += "<br>";
}
else if (nNet > 0)
{
//
// Credit
//
strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nNet) + "<br>";
}
else
{
isminetype fAllFromMe = ISMINE_SPENDABLE;
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
{
isminetype mine = wallet->IsMine(txin);
if(fAllFromMe > mine) fAllFromMe = mine;
}
isminetype fAllToMe = ISMINE_SPENDABLE;
for (int i = 0; i < wtx.vout.size(); i++)
{
isminetype mine = wallet->IsMine(wtx, i);
if(fAllToMe > mine) fAllToMe = mine;
}
if (fAllFromMe)
{
if(fAllFromMe == ISMINE_WATCH_ONLY)
strHTML += "<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>";
//
// Debit
//
for (int i = 0; i < wtx.vout.size(); i++)
{
const CTxOut& txout = wtx.vout[i];
// Ignore change
isminetype toSelf = wallet->IsMine(wtx, i);
if ((toSelf == ISMINE_SPENDABLE) && (fAllFromMe == ISMINE_SPENDABLE))
continue;
if (!wtx.mapValue.count("to") || wtx.mapValue["to"].empty())
{
// Offline transaction
CTxDestination address;
if (ExtractDestination(txout.scriptPubKey, address))
{
strHTML += "<b>" + tr("To") + ":</b> ";
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].name.empty())
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
if(toSelf == ISMINE_SPENDABLE)
strHTML += " (own address)";
else if(toSelf == ISMINE_WATCH_ONLY)
strHTML += " (watch-only)";
strHTML += "<br>";
}
}
strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -txout.nValue) + "<br>";
if(toSelf)
strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, txout.nValue) + "<br>";
}
if (fAllToMe)
{
// Payment to self
CAmount nChange = wtx.GetChange();
CAmount nValue = nCredit - nChange;
strHTML += "<b>" + tr("Total debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nValue) + "<br>";
strHTML += "<b>" + tr("Total credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nValue) + "<br>";
}
CAmount nTxFee = nDebit - wtx.GetValueOut();
if (nTxFee > 0)
strHTML += "<b>" + tr("Transaction fee") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nTxFee) + "<br>";
}
else
{
//
// Mixed debit transaction
//
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
if (wallet->IsMine(txin))
strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet->GetDebit(txin, ISMINE_ALL)) + "<br>";
for (int i = 0; i < wtx.vout.size(); i++)
if (wallet->IsMine(wtx, i))
strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, wallet->GetCredit(wtx, i, ISMINE_ALL)) + "<br>";
}
}
strHTML += "<b>" + tr("Net amount") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nNet, true) + "<br>";
//
// Message
//
if (wtx.mapValue.count("message") && !wtx.mapValue["message"].empty())
strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["message"], true) + "<br>";
if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty())
strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>";
strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), rec->idx) + "<br>";
// Message from normal bitcoin:URI (bitcoin:123...?message=example)
Q_FOREACH (const PAIRTYPE(string, string)& r, wtx.vOrderForm)
if (r.first == "Message")
strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>";
//
// PaymentRequest info:
//
Q_FOREACH (const PAIRTYPE(string, string)& r, wtx.vOrderForm)
{
if (r.first == "PaymentRequest")
{
PaymentRequestPlus req;
req.parse(QByteArray::fromRawData(r.second.data(), r.second.size()));
QString merchant;
if (req.getMerchant(PaymentServer::getCertStore(), merchant))
strHTML += "<b>" + tr("Merchant") + ":</b> " + GUIUtil::HtmlEscape(merchant) + "<br>";
}
}
if (wtx.IsCoinBase())
{
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
if ( ASSETCHAINS_SYMBOL[0] == 0 )
COINBASE_MATURITY = _COINBASE_MATURITY;
quint32 numBlocksToMaturity = COINBASE_MATURITY + 1;
strHTML += "<br>" + tr("Generated coins must mature %1 blocks and have any applicable time locks open before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(numBlocksToMaturity)) + "<br>";
// we need to display any possible CLTV lock time
}
//
// Debug view
//
if (fDebug)
{
strHTML += "<hr><br>" + tr("Debug information") + "<br><br>";
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
if(wallet->IsMine(txin))
strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet->GetDebit(txin, ISMINE_ALL)) + "<br>";
for (int i = 0; i < wtx.vout.size(); i++)
if (wallet->IsMine(wtx, i))
strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, wallet->GetCredit(wtx, i, ISMINE_ALL)) + "<br>";
strHTML += "<br><b>" + tr("Transaction") + ":</b><br>";
strHTML += GUIUtil::HtmlEscape(wtx.ToString(), true);
strHTML += "<br><b>" + tr("Inputs") + ":</b>";
strHTML += "<ul>";
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
{
COutPoint prevout = txin.prevout;
CCoins prev;
if(pcoinsTip->GetCoins(prevout.hash, prev))
{
if (prevout.n < prev.vout.size())
{
strHTML += "<li>";
const CTxOut &vout = prev.vout[prevout.n];
CTxDestination address;
if (ExtractDestination(vout.scriptPubKey, address))
{
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].name.empty())
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
strHTML += QString::fromStdString(CBitcoinAddress(address).ToString());
}
strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatHtmlWithUnit(unit, vout.nValue);
strHTML = strHTML + " IsMine=" + (wallet->IsMine(prev, prevout.n) & ISMINE_SPENDABLE ? tr("true") : tr("false")) + "</li>";
strHTML = strHTML + " IsWatchOnly=" + (wallet->IsMine(prev, prevout.n) & ISMINE_WATCH_ONLY ? tr("true") : tr("false")) + "</li>";
}
}
}
strHTML += "</ul>";
}
strHTML += "</font></html>";
return strHTML;
}

View File

@@ -1,173 +0,0 @@
// Copyright (c) 2011-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "utilitydialog.h"
#include "ui_helpmessagedialog.h"
#include "bitcoingui.h"
#include "clientmodel.h"
#include "guiutil.h"
#include "clientversion.h"
#include "init.h"
#include "util.h"
#include <stdio.h>
#include <QCloseEvent>
#include <QLabel>
#include <QRegExp>
#include <QTextTable>
#include <QTextCursor>
#include <QVBoxLayout>
/** "Help message" or "About" dialog box */
HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
QDialog(parent),
ui(new Ui::HelpMessageDialog)
{
ui->setupUi(this);
QString version = tr("Bitcoin Core") + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion());
/* On x86 add a bit specifier to the version so that users can distinguish between
* 32 and 64 bit builds. On other architectures, 32/64 bit may be more ambigious.
*/
#if defined(__x86_64__)
version += " " + tr("(%1-bit)").arg(64);
#elif defined(__i386__ )
version += " " + tr("(%1-bit)").arg(32);
#endif
if (about)
{
setWindowTitle(tr("About Bitcoin Core"));
/// HTML-format the license message from the core
QString licenseInfo = QString::fromStdString(LicenseInfo());
QString licenseInfoHTML = licenseInfo;
// Make URLs clickable
QRegExp uri("<(.*)>", Qt::CaseSensitive, QRegExp::RegExp2);
uri.setMinimal(true); // use non-greedy matching
licenseInfoHTML.replace(uri, "<a href=\"\\1\">\\1</a>");
// Replace newlines with HTML breaks
licenseInfoHTML.replace("\n\n", "<br><br>");
ui->aboutMessage->setTextFormat(Qt::RichText);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
text = version + "\n" + licenseInfo;
ui->aboutMessage->setText(version + "<br><br>" + licenseInfoHTML);
ui->aboutMessage->setWordWrap(true);
ui->helpMessage->setVisible(false);
} else {
setWindowTitle(tr("Command-line options"));
QString header = tr("Usage:") + "\n" +
" komodo-qt [" + tr("command-line options") + "] " + "\n";
QTextCursor cursor(ui->helpMessage->document());
cursor.insertText(version);
cursor.insertBlock();
cursor.insertText(header);
cursor.insertBlock();
QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
text = version + "\n" + header + "\n" + coreOptions;
QTextTableFormat tf;
tf.setBorderStyle(QTextFrameFormat::BorderStyle_None);
tf.setCellPadding(2);
QVector<QTextLength> widths;
widths << QTextLength(QTextLength::PercentageLength, 35);
widths << QTextLength(QTextLength::PercentageLength, 65);
tf.setColumnWidthConstraints(widths);
QTextCharFormat bold;
bold.setFontWeight(QFont::Bold);
Q_FOREACH (const QString &line, coreOptions.split("\n")) {
if (line.startsWith(" -"))
{
cursor.currentTable()->appendRows(1);
cursor.movePosition(QTextCursor::PreviousCell);
cursor.movePosition(QTextCursor::NextRow);
cursor.insertText(line.trimmed());
cursor.movePosition(QTextCursor::NextCell);
} else if (line.startsWith(" ")) {
cursor.insertText(line.trimmed()+' ');
} else if (line.size() > 0) {
//Title of a group
if (cursor.currentTable())
cursor.currentTable()->appendRows(1);
cursor.movePosition(QTextCursor::Down);
cursor.insertText(line.trimmed(), bold);
cursor.insertTable(1, 2, tf);
}
}
ui->helpMessage->moveCursor(QTextCursor::Start);
ui->scrollArea->setVisible(false);
ui->aboutLogo->setVisible(false);
}
}
HelpMessageDialog::~HelpMessageDialog()
{
delete ui;
}
void HelpMessageDialog::printToConsole()
{
// On other operating systems, the expected action is to print the message to the console.
fprintf(stdout, "%s\n", qPrintable(text));
}
void HelpMessageDialog::showOrPrint()
{
#if defined(WIN32)
// On Windows, show a message box, as there is no stderr/stdout in windowed applications
exec();
#else
// On other operating systems, print help text to console
printToConsole();
#endif
}
void HelpMessageDialog::on_okButton_accepted()
{
close();
}
/** "Shutdown" window */
ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f):
QWidget(parent, f)
{
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(new QLabel(
tr("Bitcoin Core is shutting down...") + "<br /><br />" +
tr("Do not shut down the computer until this window disappears.")));
setLayout(layout);
}
void ShutdownWindow::showShutdownWindow(BitcoinGUI *window)
{
if (!window)
return;
// Show a simple window indicating shutdown status
QWidget *shutdownWindow = new ShutdownWindow();
// We don't hold a direct pointer to the shutdown window after creation, so use
// Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually.
shutdownWindow->setAttribute(Qt::WA_DeleteOnClose);
shutdownWindow->setWindowTitle(window->windowTitle());
// Center shutdown window at where main window was
const QPoint global = window->mapToGlobal(window->rect().center());
shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2);
shutdownWindow->show();
}
void ShutdownWindow::closeEvent(QCloseEvent *event)
{
event->ignore();
}

View File

@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2019 The Hush developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Some files were not shown because too many files have changed in this diff Show More