diff --git a/Makefile.am b/Makefile.am index 143b2cc68..d3171b206 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,6 +15,7 @@ endif BITCOIND_BIN=$(top_builddir)/src/zcashd$(EXEEXT) BITCOIN_CLI_BIN=$(top_builddir)/src/zcash-cli$(EXEEXT) +#WALLET_UTILITY_BIN=$(top_builddir)/src/wallet-utility$(EXEEXT) BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) if TARGET_DARWIN @@ -32,26 +33,26 @@ endif DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ - $(top_srcdir)/contrib/devtools/security-check.py + $(top_srcdir)/contrib/devtools/security-check.py WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ - $(top_srcdir)/share/pixmaps/nsis-header.bmp \ - $(top_srcdir)/share/pixmaps/nsis-wizard.bmp + $(top_srcdir)/share/pixmaps/nsis-header.bmp \ + $(top_srcdir)/share/pixmaps/nsis-wizard.bmp if TARGET_DARWIN OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) $(OSX_BASE_LPROJ_DIR) \ - $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) \ - $(top_srcdir)/contrib/macdeploy/DS_Store \ - $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ - $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh + $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) \ + $(top_srcdir)/contrib/macdeploy/DS_Store \ + $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ + $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh endif if TARGET_DARWIN COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \ - leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \ - baseline_filtered.info block_test_filtered.info \ - leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info + leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \ + baseline_filtered.info block_test_filtered.info \ + leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info # zcash-gtest.info zcash-gtest_filtered.info zcash-gtest_coverage.info else COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \ @@ -104,9 +105,9 @@ $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings: $(OSX_BASE_LPROJ_DIR $(INSTALL_DATA) $< $@ OSX_APP_BUILT=$(OSX_APP)/Contents/PkgInfo $(OSX_APP)/Contents/Resources/empty.lproj \ - $(OSX_APP)/Contents/Resources/bitcoin.icns $(OSX_APP)/Contents/Info.plist \ - $(OSX_APP)/Contents/MacOS/Bitcoin-Qt $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings - + $(OSX_APP)/Contents/Resources/bitcoin.icns $(OSX_APP)/Contents/Info.plist \ + $(OSX_APP)/Contents/MacOS/Bitcoin-Qt $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings + endif if BUILD_DARWIN @@ -155,6 +156,9 @@ $(BITCOIND_BIN): FORCE $(BITCOIN_CLI_BIN): FORCE $(MAKE) -C src $(@F) +#$(WALLET_UTILITY_BIN): FORCE +# $(MAKE) -C src $(@F) + if USE_LCOV baseline.info: @@ -163,27 +167,27 @@ baseline.info: if BUILD_DARWIN baseline_filtered.info: baseline.info $(LCOV) -r $< "/usr/include/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/*.h" \ - "$(abs_builddir)/depends/$(BUILD)/include/boost/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/gmock/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/gtest/*" \ - "$(abs_builddir)/src/gtest/*" \ - "$(abs_builddir)/src/test/*" \ - "$(abs_builddir)/src/wallet/gtest/*" \ - "$(abs_builddir)/src/wallet/test/*" \ - -o $@ + "$(abs_builddir)/depends/$(BUILD)/include/*.h" \ + "$(abs_builddir)/depends/$(BUILD)/include/boost/*" \ + "$(abs_builddir)/depends/$(BUILD)/include/gmock/*" \ + "$(abs_builddir)/depends/$(BUILD)/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ else baseline_filtered.info: baseline.info $(LCOV) -r $< "/usr/include/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/*.h" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/boost/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gmock/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gtest/*" \ - "$(abs_builddir)/src/gtest/*" \ - "$(abs_builddir)/src/test/*" \ - "$(abs_builddir)/src/wallet/gtest/*" \ - "$(abs_builddir)/src/wallet/test/*" \ - -o $@ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/*.h" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/boost/*" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gmock/*" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ endif leveldb_baseline.info: baseline_filtered.info @@ -192,27 +196,27 @@ leveldb_baseline.info: baseline_filtered.info if BUILD_DARWIN leveldb_baseline_filtered.info: leveldb_baseline.info $(LCOV) -r $< "/usr/include/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/*.h" \ - "$(abs_builddir)/depends/$(BUILD)/include/boost/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/gmock/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/gtest/*" \ - "$(abs_builddir)/src/gtest/*" \ - "$(abs_builddir)/src/test/*" \ - "$(abs_builddir)/src/wallet/gtest/*" \ - "$(abs_builddir)/src/wallet/test/*" \ - -o $@ + "$(abs_builddir)/depends/$(BUILD)/include/*.h" \ + "$(abs_builddir)/depends/$(BUILD)/include/boost/*" \ + "$(abs_builddir)/depends/$(BUILD)/include/gmock/*" \ + "$(abs_builddir)/depends/$(BUILD)/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ else leveldb_baseline_filtered.info: leveldb_baseline.info $(LCOV) -r $< "/usr/include/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/*.h" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/boost/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gmock/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gtest/*" \ - "$(abs_builddir)/src/gtest/*" \ - "$(abs_builddir)/src/test/*" \ - "$(abs_builddir)/src/wallet/gtest/*" \ - "$(abs_builddir)/src/wallet/test/*" \ - -o $@ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/*.h" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/boost/*" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gmock/*" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ endif baseline_filtered_combined.info: leveldb_baseline_filtered.info baseline_filtered.info @@ -227,27 +231,27 @@ test_bitcoin.info: baseline_filtered_combined.info if BUILD_DARWIN test_bitcoin_filtered.info: test_bitcoin.info $(LCOV) -r $< "/usr/include/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/*.h" \ - "$(abs_builddir)/depends/$(BUILD)/include/boost/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/gmock/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/gtest/*" \ - "$(abs_builddir)/src/gtest/*" \ - "$(abs_builddir)/src/test/*" \ - "$(abs_builddir)/src/wallet/gtest/*" \ - "$(abs_builddir)/src/wallet/test/*" \ - -o $@ + "$(abs_builddir)/depends/$(BUILD)/include/*.h" \ + "$(abs_builddir)/depends/$(BUILD)/include/boost/*" \ + "$(abs_builddir)/depends/$(BUILD)/include/gmock/*" \ + "$(abs_builddir)/depends/$(BUILD)/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ else test_bitcoin_filtered.info: test_bitcoin.info $(LCOV) -r $< "/usr/include/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/*.h" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/boost/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gmock/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gtest/*" \ - "$(abs_builddir)/src/gtest/*" \ - "$(abs_builddir)/src/test/*" \ - "$(abs_builddir)/src/wallet/gtest/*" \ - "$(abs_builddir)/src/wallet/test/*" \ - -o $@ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/*.h" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/boost/*" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gmock/*" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ endif @@ -261,32 +265,32 @@ block_test.info: test_bitcoin_filtered.info if BUILD_DARWIN block_test_filtered.info: block_test.info $(LCOV) -r $< "/usr/include/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/*.h" \ - "$(abs_builddir)/depends/$(BUILD)/include/boost/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/gmock/*" \ - "$(abs_builddir)/depends/$(BUILD)/include/gtest/*" \ - "$(abs_builddir)/src/gtest/*" \ - "$(abs_builddir)/src/test/*" \ - "$(abs_builddir)/src/wallet/gtest/*" \ - "$(abs_builddir)/src/wallet/test/*" \ - -o $@ + "$(abs_builddir)/depends/$(BUILD)/include/*.h" \ + "$(abs_builddir)/depends/$(BUILD)/include/boost/*" \ + "$(abs_builddir)/depends/$(BUILD)/include/gmock/*" \ + "$(abs_builddir)/depends/$(BUILD)/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ else block_test_filtered.info: block_test.info $(LCOV) -r $< "/usr/include/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/*.h" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/boost/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gmock/*" \ - "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gtest/*" \ - "$(abs_builddir)/src/gtest/*" \ - "$(abs_builddir)/src/test/*" \ - "$(abs_builddir)/src/wallet/gtest/*" \ - "$(abs_builddir)/src/wallet/test/*" \ - -o $@ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/*.h" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/boost/*" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gmock/*" \ + "$(abs_builddir)/depends/x86_64-unknown-linux-gnu/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ endif test_bitcoin_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info - $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -o $@ + $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -o $@ if ! BUILD_DARWIN zcash-gtest_coverage.info: baseline_filtered_combined.info zcash-gtest_filtered.info @@ -295,7 +299,7 @@ endif if BUILD_DARWIN total_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info zcash-gtest_filtered.info block_test_filtered.info - $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -a zcash-gtest_filtered.info -a block_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt + $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -a zcash-gtest_filtered.info -a block_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt else total_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info zcash-gtest_filtered.info block_test_filtered.info $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -a zcash-gtest_filtered.info -a block_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt @@ -303,19 +307,19 @@ endif test_bitcoin.coverage/.dirstamp: test_bitcoin_coverage.info - $(GENHTML) -s $< -o $(@D) - @touch $@ + $(GENHTML) -s $< -o $(@D) + @touch $@ if TARGET_DARWIN zcash-gtest.coverage/.dirstamp: zcash-gtest_coverage.info - $(GENHTML) -s $< -o $(@D) - @touch $@ + $(GENHTML) -s $< -o $(@D) + @touch $@ cov-zcash: zcash-gtest.coverage/.dirstamp endif total.coverage/.dirstamp: total_coverage.info - $(GENHTML) -s $< -o $(@D) - @touch $@ + $(GENHTML) -s $< -o $(@D) + @touch $@ if BUILD_DARWIN cov: test_bitcoin.coverage/.dirstamp cov-zcash total.coverage/.dirstamp diff --git a/README-mac.md b/README-mac.md index c085cb617..f3dd5e281 100644 --- a/README-mac.md +++ b/README-mac.md @@ -1,4 +1,6 @@ -First off you need Apple's Xcode (at least version 7, preferably 8.x) and the Xcode Command Line Tools: +## Install for Mac OS X + +First off you need Apple's Xcode (at least version 7, preferably 8.x or later) and the Xcode Command Line Tools: https://itunes.apple.com/us/app/xcode/id497799835?mt=12 @@ -11,25 +13,51 @@ And this is the list of brew packages you'll need installed: ```shell brew tap discoteq/discoteq; brew install flock brew install autoconf autogen automake -brew tap homebrew/versions; brew install homebrew/versions/gcc5 +brew install gcc@6 brew install binutils brew install protobuf brew install coreutils brew install wget ``` +or + +```shell +brew tap discoteq/discoteq; brew install flock autoconf autogen automake gcc@6 binutils protobuf coreutils wget +``` + Get all that installed, then run: ```shell -git clone https://github.com/j-cimb-barker/komodo.git +git clone https://github.com/jl777/komodo.git cd komodo -git checkout dev ./zcutil/build-mac.sh +./zcutil/fetch-params.sh ``` To build a distributable version of komodo then run the makeDistrib.sh script after building. -When you are done building, you need to do a few things in the [Configuration](https://github.com/zcash/zcash/wiki/1.0-User-Guide#configuration) section of the Zcash User Guide differently because we are on the Mac. All instances of `~/.zcash` need to be replaced by `~/Library/Application\ Support/Zcash` -The fetch-params.sh script, however, has already been altered to fetch the proving keys into the correct directory to conform to Mac specific naming conventions. +When you are done building, you need to create `Komodo.conf` the Mac way. + +```shell +mkdir ~/Library/Application\ Support/Komodo +touch ~/Library/Application\ Support/Komodo/Komodo.conf +nano ~/Library/Application\ Support/Komodo/Komodo.conf +``` + +Add the following lines to the Komodo.conf file: + +```shell +rpcuser=dontuseweakusernameoryougetrobbed +rpcpassword=dontuseweakpasswordoryougetrobbed +txindex=1 +addnode=5.9.102.210 +addnode=78.47.196.146 +addnode=178.63.69.164 +addnode=88.198.65.74 +addnode=5.9.122.241 +addnode=144.76.94.38 +addnode=89.248.166.91 +``` Happy Building diff --git a/README.md b/README.md index d39f83675..5d85d013d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -Komodo 1.0.15 +## Komodo with Bitcore +This version of Komodo contains Bitcore support for komodo and all its assetchains. ## Komodod This software is Komodo client, generally you will use this if you want to mine KMD or setup a full node. @@ -230,3 +231,4 @@ Instead of generating 1 secret address, generate 100 and make a script file with And make sure to delete all traces of this when the JUMBLR is finished. You will end up with 100 addresses that have an average of 1000 KMD each. So as long as you are careful and dont do a 10,000 KMD transaction (that will link 10 of your secret addresses together), you can appear as 100 different people each with 1000 KMD. + diff --git a/configure.ac b/configure.ac index decf2b2e6..7de40ff26 100644 --- a/configure.ac +++ b/configure.ac @@ -232,7 +232,7 @@ CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" AC_ARG_WITH([utils], [AS_HELP_STRING([--with-utils], - [build zcash-cli zcash-tx (default=yes)])], + [build zcash-cli zcash-tx wallet-utility (default=yes)])], [build_bitcoin_utils=$withval], [build_bitcoin_utils=yes]) @@ -805,7 +805,7 @@ AC_MSG_CHECKING([whether to build bitcoind]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AC_MSG_RESULT($build_bitcoind) -AC_MSG_CHECKING([whether to build utils (zcash-cli zcash-tx)]) +AC_MSG_CHECKING([whether to build utils (zcash-cli zcash-tx wallet-utility)]) AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) AC_MSG_RESULT($build_bitcoin_utils) diff --git a/darwin.host.mk.patch b/darwin.host.mk.patch index 426702563..deeb7a810 100644 --- a/darwin.host.mk.patch +++ b/darwin.host.mk.patch @@ -5,8 +5,8 @@ OSX_SDK_VERSION=10.9 OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk LD64_VERSION=241.9 -! darwin_CC=gcc-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -! darwin_CXX=g++-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) +! darwin_CC=gcc-6 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) +! darwin_CXX=g++-6 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) darwin_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) diff --git a/darwin.mk.patch b/darwin.mk.patch index 80bc5b2d9..fdfd7bc38 100644 --- a/darwin.mk.patch +++ b/darwin.mk.patch @@ -2,8 +2,8 @@ --- ../../komodo-jl777/depends/builders/darwin.mk 2017-01-03 09:48:21.646034937 +0000 *************** *** 1,5 **** -! build_darwin_CC = gcc-5 -! build_darwin_CXX = g++-5 +! build_darwin_CC = gcc-6 +! build_darwin_CXX = g++-6 build_darwin_AR: = $(shell xcrun -f ar) build_darwin_RANLIB: = $(shell xcrun -f ranlib) build_darwin_STRIP: = $(shell xcrun -f strip) @@ -21,8 +21,8 @@ ! build_darwin_DOWNLOAD = wget --timeout=$(DOWNLOAD_CONNECT_TIMEOUT) --tries=$(DOWNLOAD_RETRIES) -nv -O #darwin host on darwin builder. overrides darwin host preferences. -! darwin_CC= gcc-5 -! darwin_CXX= g++-5 +! darwin_CC= gcc-6 +! darwin_CXX= g++-6 darwin_AR:=$(shell xcrun -f ar) darwin_RANLIB:=$(shell xcrun -f ranlib) darwin_STRIP:=$(shell xcrun -f strip) diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index b986aecec..f9b066fcf 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -1,5 +1,5 @@ -build_darwin_CC = gcc-5 -build_darwin_CXX = g++-5 +build_darwin_CC = gcc-6 +build_darwin_CXX = g++-6 build_darwin_AR: = $(shell xcrun -f ar) build_darwin_RANLIB: = $(shell xcrun -f ranlib) build_darwin_STRIP: = $(shell xcrun -f strip) @@ -7,19 +7,11 @@ build_darwin_OTOOL: = $(shell xcrun -f otool) build_darwin_NM: = $(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) build_darwin_SHA256SUM = shasum -a 256 -#<<<<<<< HEAD -##build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -f -o +build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -f -o #darwin host on darwin builder. overrides darwin host preferences. -#darwin_CC= gcc-5 -#darwin_CXX= g++-5 -#======= -build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o - -#darwin host on darwin builder. overrides darwin host preferences. -darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) -darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) -stdlib=libc++ -#>>>>>>> zcash/master +darwin_CC= gcc-6 +darwin_CXX= g++-6 darwin_AR:=$(shell xcrun -f ar) darwin_RANLIB:=$(shell xcrun -f ranlib) darwin_STRIP:=$(shell xcrun -f strip) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 4f1748657..5eaeddc26 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,15 +1,9 @@ OSX_MIN_VERSION=10.8 OSX_SDK_VERSION=10.11 OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk -#<<<<<<< HEAD -#LD64_VERSION=241.9 -#darwin_CC=gcc-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -#darwin_CXX=g++-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -#======= LD64_VERSION=253.9 -darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++ -#>>>>>>> zcash/master +darwin_CC=gcc-6 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) +darwin_CXX=g++-6 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) darwin_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 099993a62..8f3fd1b1c 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,17 +1,17 @@ + package=boost -$(package)_version=1_62_0 -$(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.62.0 +$(package)_version=1_66_0 +$(package)_download_path=https://dl.bintray.com/boostorg/release/1.66.0/source $(package)_file_name=$(package)_$($(package)_version).tar.bz2 -$(package)_sha256_hash=36c96b0f6155c98404091d8ceb48319a28279ca0333fba1ad8611eb90afb2ca0 -$(package)_patches=deprecated_auto_ptr.patch include_poll.patch +$(package)_sha256_hash=5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9 define $(package)_set_vars $(package)_config_opts_release=variant=release $(package)_config_opts_debug=variant=debug -$(package)_config_opts=--layout=tagged --build-type=complete --user-config=user-config.jam -$(package)_config_opts+=link=static -sNO_BZIP2=1 -sNO_ZLIB=1 +$(package)_config_opts=--layout=system --user-config=user-config.jam +$(package)_config_opts+=threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1 $(package)_config_opts_linux=threadapi=pthread runtime-link=shared -$(package)_config_opts_darwin=--toolset=gcc threadapi=pthread runtime-link=shared +$(package)_config_opts_darwin=--toolset=gcc runtime-link=shared threadapi=pthread $(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static $(package)_config_opts_x86_64_mingw32=address-model=64 $(package)_config_opts_i686_mingw32=address-model=32 @@ -25,10 +25,9 @@ $(package)_cxxflags=-std=c++11 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC endef + define $(package)_preprocess_cmds - echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cxxflags) $($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$(boost_archiver_$(host_os))\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam && \ - patch -p1 < $($(package)_patch_dir)/deprecated_auto_ptr.patch && \ - patch -p1 < $($(package)_patch_dir)/include_poll.patch + echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cxxflags) $($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$(boost_archiver_$(host_os))\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam endef define $(package)_config_cmds diff --git a/depends/packages/googletest.mk b/depends/packages/googletest.mk index b9fa3e7e8..1275593f5 100644 --- a/depends/packages/googletest.mk +++ b/depends/packages/googletest.mk @@ -14,7 +14,8 @@ endif ifeq ($(build_os),darwin) $(package)_install=ginstall define $(package)_build_cmds - $(MAKE) -C make gtest.a + $(MAKE) -C googlemock/make gmock.a && \ + $(MAKE) -C googletest/make gtest.a endef else $(package)_install=install diff --git a/depends/packages/libgmp.mk b/depends/packages/libgmp.mk index 496a2751e..d8e41573a 100644 --- a/depends/packages/libgmp.mk +++ b/depends/packages/libgmp.mk @@ -19,7 +19,6 @@ $(package)_config_opts=--enable-cxx --disable-shared else $(package)_version=6.1.1 $(package)_download_path=https://supernetorg.bintray.com/misc - $(package)_file_name=gmp-$($(package)_version).tar.bz2 $(package)_sha256_hash=a8109865f2893f1373b0a8ed5ff7429de8db696fc451b1036bd7bdf95bbeffd6 $(package)_dependencies= diff --git a/depends/packages/librustzcash.mk b/depends/packages/librustzcash.mk index bfd8fef1e..20126776a 100644 --- a/depends/packages/librustzcash.mk +++ b/depends/packages/librustzcash.mk @@ -7,7 +7,6 @@ $(package)_sha256_hash=a5760a90d4a1045c8944204f29fa2a3cf2f800afee400f88bf89bbfe2 $(package)_git_commit=91348647a86201a9482ad4ad68398152dc3d635e $(package)_dependencies=rust - ifeq ($(host_os),mingw32) define $(package)_build_cmds ~/.cargo/bin/cargo build --release --target=x86_64-pc-windows-gnu --verbose diff --git a/depends/packages/libsodium.mk b/depends/packages/libsodium.mk index 91e6f27b7..efa5d90de 100644 --- a/depends/packages/libsodium.mk +++ b/depends/packages/libsodium.mk @@ -1,17 +1,20 @@ +ifeq ($(build_os),darwin) +package=libsodium +$(package)_version=1.0.11 +$(package)_download_path=https://supernetorg.bintray.com/misc +$(package)_file_name=libsodium-1.0.11.tar.gz +$(package)_sha256_hash=a14549db3c49f6ae2170cbbf4664bd48ace50681045e8dbea7c8d9fb96f9c765 +$(package)_dependencies= +$(package)_config_opts= +else package=libsodium -#<<<<<<< HEAD -#$(package)_version=1.0.11 -#$(package)_download_path=https://supernetorg.bintray.com/misc -#$(package)_file_name=libsodium-1.0.11.tar.gz -#$(package)_sha256_hash=a14549db3c49f6ae2170cbbf4664bd48ace50681045e8dbea7c8d9fb96f9c765 -#======= $(package)_version=1.0.15 $(package)_download_path=https://download.libsodium.org/libsodium/releases/ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4 -#>>>>>>> zcash/master $(package)_dependencies= $(package)_config_opts= +endif define $(package)_preprocess_cmds cd $($(package)_build_subdir); ./autogen.sh diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 3c78e29c3..9174db320 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,7 +1,12 @@ rust_packages := rust librustzcash -proton_packages := proton -zcash_packages := libgmp libsodium +ifeq ($(build_os),darwin) + zcash_packages := libsnark libgmp libsodium +else + proton_packages := proton + zcash_packages := libgmp libsodium +endif + ifeq ($(host_os),linux) packages := boost openssl libevent zeromq $(zcash_packages) googletest #googlemock else diff --git a/depends/packages/proton.mk b/depends/packages/proton.mk index aa49f380f..39428f54b 100644 --- a/depends/packages/proton.mk +++ b/depends/packages/proton.mk @@ -1,6 +1,6 @@ package=proton $(package)_version=0.17.0 -$(package)_download_path=http://apache.cs.utah.edu/qpid/proton/$($(package)_version) +$(package)_download_path=https://archive.apache.org/dist/qpid/proton/$($(package)_version) $(package)_file_name=qpid-proton-$($(package)_version).tar.gz $(package)_sha256_hash=6ffd26d3d0e495bfdb5d9fefc5349954e6105ea18cc4bb191161d27742c5a01a $(package)_patches=minimal-build.patch @@ -21,4 +21,3 @@ endef define $(package)_stage_cmds cd build; $(MAKE) VERBOSE=1 DESTDIR=$($(package)_staging_prefix_dir) install endef - diff --git a/depends/packages/rust.mk b/depends/packages/rust.mk index eb28c76d1..2e3f0b204 100644 --- a/depends/packages/rust.mk +++ b/depends/packages/rust.mk @@ -1,23 +1,16 @@ package=rust $(package)_version=1.16.0 $(package)_download_path=https://static.rust-lang.org/dist -#<<<<<<< HEAD -#ifeq ($(build_os),darwin) -#$(package)_file_name=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz -#$(package)_sha256_hash=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926 -#else ifeq ($(host_os),mingw32) -#$(package)_file_name=rust-$($(package)_version)-i686-unknown-linux-gnu.tar.gz -#$(package)_sha256_hash=b5859161ebb182d3b75fa14a5741e5de87b088146fb0ef4a30f3b2439c6179c5 -#else -#$(package)_file_name=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz -#$(package)_sha256_hash=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd -#endif -#======= -$(package)_file_name_linux=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz -$(package)_sha256_hash_linux=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd -$(package)_file_name_darwin=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz -$(package)_sha256_hash_darwin=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926 -#>>>>>>> zcash/master +ifeq ($(build_os),darwin) +$(package)_file_name=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz +$(package)_sha256_hash=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926 +else ifeq ($(host_os),mingw32) +$(package)_file_name=rust-$($(package)_version)-i686-unknown-linux-gnu.tar.gz +$(package)_sha256_hash=b5859161ebb182d3b75fa14a5741e5de87b088146fb0ef4a30f3b2439c6179c5 +else +$(package)_file_name=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz +$(package)_sha256_hash=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd +endif define $(package)_stage_cmds ./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig diff --git a/libsnark.mk.patch b/libsnark.mk.patch index f43ea2188..28a60c8b6 100644 --- a/libsnark.mk.patch +++ b/libsnark.mk.patch @@ -14,7 +14,7 @@ - ifeq ($(build_os),darwin) - define $(package)_build_cmds -- CC=gcc-5 CXX=g++-5 CXXFLAGS="-arch x86_64 -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=0 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT +- CC=gcc-6 CXX=g++-6 CXXFLAGS="-arch x86_64 -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1" $(MAKE) lib DEPINST=$(host_prefix) CURVE=ALT_BN128 MULTICORE=0 NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT - endef - else define $(package)_build_cmds diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 0ed693951..50de39f64 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -44,6 +44,9 @@ testScripts=( 'key_import_export.py' 'nodehandling.py' 'reindex.py' + 'addressindex.py' + 'timestampindex.py' + 'spentindex.py' 'decodescript.py' 'disablewallet.py' 'zcjoinsplit.py' diff --git a/qa/rpc-tests/addressindex.py b/qa/rpc-tests/addressindex.py new file mode 100644 index 000000000..11fa7ffdb --- /dev/null +++ b/qa/rpc-tests/addressindex.py @@ -0,0 +1,349 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test addressindex generation and fetching +# + +import time +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.script import * +from test_framework.mininode import * +import binascii + +class AddressIndexTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self): + self.nodes = [] + # Nodes 0/1 are "wallet" nodes + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-relaypriority=0"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-addressindex"])) + # Nodes 2/3 are used for testing + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-addressindex", "-relaypriority=0"])) + self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-addressindex"])) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + connect_nodes(self.nodes[0], 3) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + print "Mining blocks..." + self.nodes[0].generate(105) + self.sync_all() + + chain_height = self.nodes[1].getblockcount() + assert_equal(chain_height, 105) + assert_equal(self.nodes[1].getbalance(), 0) + assert_equal(self.nodes[2].getbalance(), 0) + + # Check that balances are correct + balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") + assert_equal(balance0["balance"], 0) + + # Check p2pkh and p2sh address indexes + print "Testing p2pkh and p2sh address index..." + + txid0 = self.nodes[0].sendtoaddress("mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 10) + self.nodes[0].generate(1) + + txidb0 = self.nodes[0].sendtoaddress("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", 10) + self.nodes[0].generate(1) + + txid1 = self.nodes[0].sendtoaddress("mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 15) + self.nodes[0].generate(1) + + txidb1 = self.nodes[0].sendtoaddress("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", 15) + self.nodes[0].generate(1) + + txid2 = self.nodes[0].sendtoaddress("mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 20) + self.nodes[0].generate(1) + + txidb2 = self.nodes[0].sendtoaddress("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", 20) + self.nodes[0].generate(1) + + self.sync_all() + + txids = self.nodes[1].getaddresstxids("mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs") + assert_equal(len(txids), 3) + assert_equal(txids[0], txid0) + assert_equal(txids[1], txid1) + assert_equal(txids[2], txid2) + + txidsb = self.nodes[1].getaddresstxids("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") + assert_equal(len(txidsb), 3) + assert_equal(txidsb[0], txidb0) + assert_equal(txidsb[1], txidb1) + assert_equal(txidsb[2], txidb2) + + # Check that limiting by height works + print "Testing querying txids by range of block heights.." + height_txids = self.nodes[1].getaddresstxids({ + "addresses": ["2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br"], + "start": 105, + "end": 110 + }) + assert_equal(len(height_txids), 2) + assert_equal(height_txids[0], txidb0) + assert_equal(height_txids[1], txidb1) + + # Check that multiple addresses works + multitxids = self.nodes[1].getaddresstxids({"addresses": ["2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs"]}) + assert_equal(len(multitxids), 6) + assert_equal(multitxids[0], txid0) + assert_equal(multitxids[1], txidb0) + assert_equal(multitxids[2], txid1) + assert_equal(multitxids[3], txidb1) + assert_equal(multitxids[4], txid2) + assert_equal(multitxids[5], txidb2) + + # Check that balances are correct + balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") + assert_equal(balance0["balance"], 45 * 100000000) + + # Check that outputs with the same address will only return one txid + print "Testing for txid uniqueness..." + addressHash = "6349a418fc4578d10a372b54b45c280cc8c4382f".decode("hex") + scriptPubKey = CScript([OP_HASH160, addressHash, OP_EQUAL]) + unspent = self.nodes[0].listunspent() + tx = CTransaction() + tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] + tx.vout = [CTxOut(10, scriptPubKey), CTxOut(11, scriptPubKey)] + tx.rehash() + + signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) + sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) + + self.nodes[0].generate(1) + self.sync_all() + + txidsmany = self.nodes[1].getaddresstxids("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") + assert_equal(len(txidsmany), 4) + assert_equal(txidsmany[3], sent_txid) + + # Check that balances are correct + print "Testing balances..." + balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") + assert_equal(balance0["balance"], 45 * 100000000 + 21) + + # Check that balances are correct after spending + print "Testing balances after spending..." + privkey2 = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG" + address2 = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW" + addressHash2 = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc".decode("hex") + scriptPubKey2 = CScript([OP_DUP, OP_HASH160, addressHash2, OP_EQUALVERIFY, OP_CHECKSIG]) + self.nodes[0].importprivkey(privkey2) + + unspent = self.nodes[0].listunspent() + tx = CTransaction() + tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] + amount = unspent[0]["amount"] * 100000000 + tx.vout = [CTxOut(amount, scriptPubKey2)] + tx.rehash() + signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) + spending_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) + self.nodes[0].generate(1) + self.sync_all() + balance1 = self.nodes[1].getaddressbalance(address2) + assert_equal(balance1["balance"], amount) + + tx = CTransaction() + tx.vin = [CTxIn(COutPoint(int(spending_txid, 16), 0))] + send_amount = 1 * 100000000 + 12840 + change_amount = amount - send_amount - 10000 + tx.vout = [CTxOut(change_amount, scriptPubKey2), CTxOut(send_amount, scriptPubKey)] + tx.rehash() + + signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) + sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) + self.nodes[0].generate(1) + self.sync_all() + + balance2 = self.nodes[1].getaddressbalance(address2) + assert_equal(balance2["balance"], change_amount) + + # Check that deltas are returned correctly + deltas = self.nodes[1].getaddressdeltas({"addresses": [address2], "start": 1, "end": 200}) + balance3 = 0 + for delta in deltas: + balance3 += delta["satoshis"] + assert_equal(balance3, change_amount) + assert_equal(deltas[0]["address"], address2) + assert_equal(deltas[0]["blockindex"], 1) + + # Check that entire range will be queried + deltasAll = self.nodes[1].getaddressdeltas({"addresses": [address2]}) + assert_equal(len(deltasAll), len(deltas)) + + # Check that deltas can be returned from range of block heights + deltas = self.nodes[1].getaddressdeltas({"addresses": [address2], "start": 113, "end": 113}) + assert_equal(len(deltas), 1) + + # Check that unspent outputs can be queried + print "Testing utxos..." + utxos = self.nodes[1].getaddressutxos({"addresses": [address2]}) + assert_equal(len(utxos), 1) + assert_equal(utxos[0]["satoshis"], change_amount) + + # Check that indexes will be updated with a reorg + print "Testing reorg..." + + best_hash = self.nodes[0].getbestblockhash() + self.nodes[0].invalidateblock(best_hash) + self.nodes[1].invalidateblock(best_hash) + self.nodes[2].invalidateblock(best_hash) + self.nodes[3].invalidateblock(best_hash) + self.sync_all() + + balance4 = self.nodes[1].getaddressbalance(address2) + assert_equal(balance4, balance1) + + utxos2 = self.nodes[1].getaddressutxos({"addresses": [address2]}) + assert_equal(len(utxos2), 1) + assert_equal(utxos2[0]["satoshis"], amount) + + # Check sorting of utxos + self.nodes[2].generate(150) + + txidsort1 = self.nodes[2].sendtoaddress(address2, 50) + self.nodes[2].generate(1) + txidsort2 = self.nodes[2].sendtoaddress(address2, 50) + self.nodes[2].generate(1) + self.sync_all() + + utxos3 = self.nodes[1].getaddressutxos({"addresses": [address2]}) + assert_equal(len(utxos3), 3) + assert_equal(utxos3[0]["height"], 114) + assert_equal(utxos3[1]["height"], 264) + assert_equal(utxos3[2]["height"], 265) + + # Check mempool indexing + print "Testing mempool indexing..." + + privKey3 = "cVfUn53hAbRrDEuMexyfgDpZPhF7KqXpS8UZevsyTDaugB7HZ3CD" + address3 = "mw4ynwhS7MmrQ27hr82kgqu7zryNDK26JB" + addressHash3 = "aa9872b5bbcdb511d89e0e11aa27da73fd2c3f50".decode("hex") + scriptPubKey3 = CScript([OP_DUP, OP_HASH160, addressHash3, OP_EQUALVERIFY, OP_CHECKSIG]) + address4 = "2N8oFVB2vThAKury4vnLquW2zVjsYjjAkYQ" + scriptPubKey4 = CScript([OP_HASH160, addressHash3, OP_EQUAL]) + unspent = self.nodes[2].listunspent() + + tx = CTransaction() + tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] + amount = unspent[0]["amount"] * 100000000 + tx.vout = [CTxOut(amount, scriptPubKey3)] + tx.rehash() + signed_tx = self.nodes[2].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) + memtxid1 = self.nodes[2].sendrawtransaction(signed_tx["hex"], True) + time.sleep(2) + + tx2 = CTransaction() + tx2.vin = [CTxIn(COutPoint(int(unspent[1]["txid"], 16), unspent[1]["vout"]))] + amount = unspent[1]["amount"] * 100000000 + tx2.vout = [ + CTxOut(amount / 4, scriptPubKey3), + CTxOut(amount / 4, scriptPubKey3), + CTxOut(amount / 4, scriptPubKey4), + CTxOut(amount / 4, scriptPubKey4) + ] + tx2.rehash() + signed_tx2 = self.nodes[2].signrawtransaction(binascii.hexlify(tx2.serialize()).decode("utf-8")) + memtxid2 = self.nodes[2].sendrawtransaction(signed_tx2["hex"], True) + time.sleep(2) + + mempool = self.nodes[2].getaddressmempool({"addresses": [address3]}) + assert_equal(len(mempool), 3) + assert_equal(mempool[0]["txid"], memtxid1) + assert_equal(mempool[0]["address"], address3) + assert_equal(mempool[0]["index"], 0) + assert_equal(mempool[1]["txid"], memtxid2) + assert_equal(mempool[1]["index"], 0) + assert_equal(mempool[2]["txid"], memtxid2) + assert_equal(mempool[2]["index"], 1) + + self.nodes[2].generate(1); + self.sync_all(); + mempool2 = self.nodes[2].getaddressmempool({"addresses": [address3]}) + assert_equal(len(mempool2), 0) + + tx = CTransaction() + tx.vin = [ + CTxIn(COutPoint(int(memtxid2, 16), 0)), + CTxIn(COutPoint(int(memtxid2, 16), 1)) + ] + tx.vout = [CTxOut(amount / 2 - 10000, scriptPubKey2)] + tx.rehash() + self.nodes[2].importprivkey(privKey3) + signed_tx3 = self.nodes[2].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) + memtxid3 = self.nodes[2].sendrawtransaction(signed_tx3["hex"], True) + time.sleep(2) + + mempool3 = self.nodes[2].getaddressmempool({"addresses": [address3]}) + assert_equal(len(mempool3), 2) + assert_equal(mempool3[0]["prevtxid"], memtxid2) + assert_equal(mempool3[0]["prevout"], 0) + assert_equal(mempool3[1]["prevtxid"], memtxid2) + assert_equal(mempool3[1]["prevout"], 1) + + # sending and receiving to the same address + privkey1 = "cQY2s58LhzUCmEXN8jtAp1Etnijx78YRZ466w4ikX1V4UpTpbsf8" + address1 = "myAUWSHnwsQrhuMWv4Br6QsCnpB41vFwHn" + address1hash = "c192bff751af8efec15135d42bfeedf91a6f3e34".decode("hex") + address1script = CScript([OP_DUP, OP_HASH160, address1hash, OP_EQUALVERIFY, OP_CHECKSIG]) + + self.nodes[0].sendtoaddress(address1, 10) + self.nodes[0].generate(1) + self.sync_all() + + utxos = self.nodes[1].getaddressutxos({"addresses": [address1]}) + assert_equal(len(utxos), 1) + + tx = CTransaction() + tx.vin = [ + CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["outputIndex"])) + ] + amount = utxos[0]["satoshis"] - 1000 + tx.vout = [CTxOut(amount, address1script)] + tx.rehash() + self.nodes[0].importprivkey(privkey1) + signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) + mem_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) + + self.sync_all() + mempool_deltas = self.nodes[2].getaddressmempool({"addresses": [address1]}) + assert_equal(len(mempool_deltas), 2) + + # Include chaininfo in results + print "Testing results with chain info..." + + deltas_with_info = self.nodes[1].getaddressdeltas({ + "addresses": [address2], + "start": 1, + "end": 200, + "chainInfo": True + }) + start_block_hash = self.nodes[1].getblockhash(1); + end_block_hash = self.nodes[1].getblockhash(200); + assert_equal(deltas_with_info["start"]["height"], 1) + assert_equal(deltas_with_info["start"]["hash"], start_block_hash) + assert_equal(deltas_with_info["end"]["height"], 200) + assert_equal(deltas_with_info["end"]["hash"], end_block_hash) + + utxos_with_info = self.nodes[1].getaddressutxos({"addresses": [address2], "chainInfo": True}) + expected_tip_block_hash = self.nodes[1].getblockhash(267); + assert_equal(utxos_with_info["height"], 267) + assert_equal(utxos_with_info["hash"], expected_tip_block_hash) + + print "Passed\n" + + +if __name__ == '__main__': + AddressIndexTest().main() \ No newline at end of file diff --git a/qa/rpc-tests/spentindex.py b/qa/rpc-tests/spentindex.py new file mode 100644 index 000000000..ebe2b8cc2 --- /dev/null +++ b/qa/rpc-tests/spentindex.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test addressindex generation and fetching +# + +import time +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.script import * +from test_framework.mininode import * +import binascii + +class SpentIndexTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self): + self.nodes = [] + # Nodes 0/1 are "wallet" nodes + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-spentindex"])) + # Nodes 2/3 are used for testing + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-spentindex"])) + self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-spentindex", "-txindex"])) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + connect_nodes(self.nodes[0], 3) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + print "Mining blocks..." + self.nodes[0].generate(105) + self.sync_all() + + chain_height = self.nodes[1].getblockcount() + assert_equal(chain_height, 105) + + # Check that + print "Testing spent index..." + + privkey = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG" + address = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW" + addressHash = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc".decode("hex") + scriptPubKey = CScript([OP_DUP, OP_HASH160, addressHash, OP_EQUALVERIFY, OP_CHECKSIG]) + unspent = self.nodes[0].listunspent() + tx = CTransaction() + amount = unspent[0]["amount"] * 100000000 + tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] + tx.vout = [CTxOut(amount, scriptPubKey)] + tx.rehash() + + signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) + txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) + self.nodes[0].generate(1) + self.sync_all() + + print "Testing getspentinfo method..." + + # Check that the spentinfo works standalone + info = self.nodes[1].getspentinfo({"txid": unspent[0]["txid"], "index": unspent[0]["vout"]}) + assert_equal(info["txid"], txid) + assert_equal(info["index"], 0) + assert_equal(info["height"], 106) + + print "Testing getrawtransaction method..." + + # Check that verbose raw transaction includes spent info + txVerbose = self.nodes[3].getrawtransaction(unspent[0]["txid"], 1) + assert_equal(txVerbose["vout"][unspent[0]["vout"]]["spentTxId"], txid) + assert_equal(txVerbose["vout"][unspent[0]["vout"]]["spentIndex"], 0) + assert_equal(txVerbose["vout"][unspent[0]["vout"]]["spentHeight"], 106) + + # Check that verbose raw transaction includes input values + txVerbose2 = self.nodes[3].getrawtransaction(txid, 1) + assert_equal(txVerbose2["vin"][0]["value"], Decimal(unspent[0]["amount"])) + assert_equal(txVerbose2["vin"][0]["valueSat"], amount) + + # Check that verbose raw transaction includes address values and input values + privkey2 = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG" + address2 = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW" + addressHash2 = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc".decode("hex") + scriptPubKey2 = CScript([OP_DUP, OP_HASH160, addressHash2, OP_EQUALVERIFY, OP_CHECKSIG]) + tx2 = CTransaction() + tx2.vin = [CTxIn(COutPoint(int(txid, 16), 0))] + tx2.vout = [CTxOut(amount, scriptPubKey2)] + tx.rehash() + self.nodes[0].importprivkey(privkey) + signed_tx2 = self.nodes[0].signrawtransaction(binascii.hexlify(tx2.serialize()).decode("utf-8")) + txid2 = self.nodes[0].sendrawtransaction(signed_tx2["hex"], True) + + # Check the mempool index + self.sync_all() + txVerbose3 = self.nodes[1].getrawtransaction(txid2, 1) + assert_equal(txVerbose3["vin"][0]["address"], address2) + assert_equal(txVerbose3["vin"][0]["value"], Decimal(unspent[0]["amount"])) + assert_equal(txVerbose3["vin"][0]["valueSat"], amount) + + # Check the database index + block_hash = self.nodes[0].generate(1) + self.sync_all() + + txVerbose4 = self.nodes[3].getrawtransaction(txid2, 1) + assert_equal(txVerbose4["vin"][0]["address"], address2) + assert_equal(txVerbose4["vin"][0]["value"], Decimal(unspent[0]["amount"])) + assert_equal(txVerbose4["vin"][0]["valueSat"], amount) + + + # Check block deltas + print "Testing getblockdeltas..." + + block = self.nodes[3].getblockdeltas(block_hash[0]) + assert_equal(len(block["deltas"]), 2) + assert_equal(block["deltas"][0]["index"], 0) + assert_equal(len(block["deltas"][0]["inputs"]), 0) + assert_equal(len(block["deltas"][0]["outputs"]), 0) + assert_equal(block["deltas"][1]["index"], 1) + assert_equal(block["deltas"][1]["txid"], txid2) + assert_equal(block["deltas"][1]["inputs"][0]["index"], 0) + assert_equal(block["deltas"][1]["inputs"][0]["address"], "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW") + assert_equal(block["deltas"][1]["inputs"][0]["satoshis"], amount * -1) + assert_equal(block["deltas"][1]["inputs"][0]["prevtxid"], txid) + assert_equal(block["deltas"][1]["inputs"][0]["prevout"], 0) + assert_equal(block["deltas"][1]["outputs"][0]["index"], 0) + assert_equal(block["deltas"][1]["outputs"][0]["address"], "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW") + assert_equal(block["deltas"][1]["outputs"][0]["satoshis"], amount) + + print "Passed\n" + + +if __name__ == '__main__': + SpentIndexTest().main() \ No newline at end of file diff --git a/qa/rpc-tests/timestampindex.py b/qa/rpc-tests/timestampindex.py new file mode 100644 index 000000000..23244159f --- /dev/null +++ b/qa/rpc-tests/timestampindex.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test timestampindex generation and fetching +# + +import time + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + + +class TimestampIndexTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self): + self.nodes = [] + # Nodes 0/1 are "wallet" nodes + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-timestampindex"])) + # Nodes 2/3 are used for testing + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-timestampindex"])) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + connect_nodes(self.nodes[0], 3) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + print "Mining 25 blocks..." + blockhashes = self.nodes[0].generate(25) + time.sleep(3) + print "Mining 25 blocks..." + blockhashes.extend(self.nodes[0].generate(25)) + time.sleep(3) + print "Mining 25 blocks..." + blockhashes.extend(self.nodes[0].generate(25)) + self.sync_all() + low = self.nodes[1].getblock(blockhashes[0])["time"] + high = low + 76 + + print "Checking timestamp index..." + hashes = self.nodes[1].getblockhashes(high, low) + + assert_equal(len(hashes), len(blockhashes)) + + assert_equal(hashes, blockhashes) + + print "Passed\n" + + +if __name__ == '__main__': + TimestampIndexTest().main() \ No newline at end of file diff --git a/qa/rpc-tests/txindex.py b/qa/rpc-tests/txindex.py new file mode 100644 index 000000000..e59b6d7d9 --- /dev/null +++ b/qa/rpc-tests/txindex.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test txindex generation and fetching +# + +import time +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.script import * +from test_framework.mininode import * +import binascii + +class TxIndexTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self): + self.nodes = [] + # Nodes 0/1 are "wallet" nodes + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-txindex"])) + # Nodes 2/3 are used for testing + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-txindex"])) + self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-txindex"])) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + connect_nodes(self.nodes[0], 3) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + print "Mining blocks..." + self.nodes[0].generate(105) + self.sync_all() + + chain_height = self.nodes[1].getblockcount() + assert_equal(chain_height, 105) + + print "Testing transaction index..." + + privkey = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG" + address = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW" + addressHash = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc".decode("hex") + scriptPubKey = CScript([OP_DUP, OP_HASH160, addressHash, OP_EQUALVERIFY, OP_CHECKSIG]) + unspent = self.nodes[0].listunspent() + tx = CTransaction() + amount = unspent[0]["amount"] * 100000000 + tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] + tx.vout = [CTxOut(amount, scriptPubKey)] + tx.rehash() + + signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) + txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) + self.nodes[0].generate(1) + self.sync_all() + + # Check verbose raw transaction results + verbose = self.nodes[3].getrawtransaction(unspent[0]["txid"], 1) + assert_equal(verbose["vout"][0]["valueSat"], 5000000000); + assert_equal(verbose["vout"][0]["value"], 50); + + print "Passed\n" + + +if __name__ == '__main__': + TxIndexTest().main() \ No newline at end of file diff --git a/qa/zcash/create_wallet_200k_utxos.py b/qa/zcash/create_wallet_200k_utxos.py old mode 100755 new mode 100644 diff --git a/qa/zcash/full-test-suite.sh b/qa/zcash/full-test-suite.sh new file mode 100755 index 000000000..af4fb2791 --- /dev/null +++ b/qa/zcash/full-test-suite.sh @@ -0,0 +1,201 @@ +#!/usr/bin/env python2 +# +# Execute all of the automated tests related to Zcash. +# + +import argparse +import os +import re +import subprocess +import sys + +REPOROOT = os.path.dirname( + os.path.dirname( + os.path.dirname( + os.path.abspath(__file__) + ) + ) +) + +def repofile(filename): + return os.path.join(REPOROOT, filename) + + +# +# Custom test runners +# + +RE_RPATH_RUNPATH = re.compile('No RPATH.*No RUNPATH') +RE_FORTIFY_AVAILABLE = re.compile('FORTIFY_SOURCE support available.*Yes') +RE_FORTIFY_USED = re.compile('Binary compiled with FORTIFY_SOURCE support.*Yes') + +def test_rpath_runpath(filename): + output = subprocess.check_output( + [repofile('qa/zcash/checksec.sh'), '--file', repofile(filename)] + ) + if RE_RPATH_RUNPATH.search(output): + print('PASS: %s has no RPATH or RUNPATH.' % filename) + return True + else: + print('FAIL: %s has an RPATH or a RUNPATH.' % filename) + print(output) + return False + +def test_fortify_source(filename): + proc = subprocess.Popen( + [repofile('qa/zcash/checksec.sh'), '--fortify-file', repofile(filename)], + stdout=subprocess.PIPE, + ) + line1 = proc.stdout.readline() + line2 = proc.stdout.readline() + proc.terminate() + if RE_FORTIFY_AVAILABLE.search(line1) and RE_FORTIFY_USED.search(line2): + print('PASS: %s has FORTIFY_SOURCE.' % filename) + return True + else: + print('FAIL: %s is missing FORTIFY_SOURCE.' % filename) + return False + +def check_security_hardening(): + ret = True + + # PIE, RELRO, Canary, and NX are tested by make check-security. + ret &= subprocess.call(['make', '-C', repofile('src'), 'check-security']) == 0 + + ret &= test_rpath_runpath('src/zcashd') + ret &= test_rpath_runpath('src/zcash-cli') + ret &= test_rpath_runpath('src/zcash-gtest') + ret &= test_rpath_runpath('src/zcash-tx') + ret &= test_rpath_runpath('src/test/test_bitcoin') + ret &= test_rpath_runpath('src/zcash/GenerateParams') + + # NOTE: checksec.sh does not reliably determine whether FORTIFY_SOURCE + # is enabled for the entire binary. See issue #915. + ret &= test_fortify_source('src/zcashd') + ret &= test_fortify_source('src/zcash-cli') + ret &= test_fortify_source('src/zcash-gtest') + ret &= test_fortify_source('src/zcash-tx') + ret &= test_fortify_source('src/test/test_bitcoin') + ret &= test_fortify_source('src/zcash/GenerateParams') + + return ret + +def ensure_no_dot_so_in_depends(): + arch_dir = os.path.join( + REPOROOT, + 'depends', + 'x86_64-unknown-linux-gnu', + ) + + exit_code = 0 + + if os.path.isdir(arch_dir): + lib_dir = os.path.join(arch_dir, 'lib') + libraries = os.listdir(lib_dir) + + for lib in libraries: + if lib.find(".so") != -1: + print lib + exit_code = 1 + else: + exit_code = 2 + print "arch-specific build dir not present: {}".format(arch_dir) + print "Did you build the ./depends tree?" + print "Are you on a currently unsupported architecture?" + + if exit_code == 0: + print "PASS." + else: + print "FAIL." + + return exit_code == 0 + +def util_test(): + return subprocess.call( + [repofile('src/test/bitcoin-util-test.py')], + cwd=repofile('src'), + env={'PYTHONPATH': repofile('src/test'), 'srcdir': repofile('src')} + ) == 0 + + +# +# Tests +# + +STAGES = [ + 'btest', + 'gtest', + 'sec-hard', + 'no-dot-so', + 'util-test', + 'secp256k1', + 'libsnark', + 'univalue', + 'rpc', +] + +STAGE_COMMANDS = { + 'btest': [repofile('src/test/test_bitcoin'), '-p'], + 'gtest': [repofile('src/zcash-gtest')], + 'sec-hard': check_security_hardening, + 'no-dot-so': ensure_no_dot_so_in_depends, + 'util-test': util_test, + 'secp256k1': ['make', '-C', repofile('src/secp256k1'), 'check'], + 'libsnark': ['make', '-C', repofile('src'), 'libsnark-tests'], + 'univalue': ['make', '-C', repofile('src/univalue'), 'check'], + 'rpc': [repofile('qa/pull-tester/rpc-tests.sh')], +} + + +# +# Test driver +# + +def run_stage(stage): + print('Running stage %s' % stage) + print('=' * (len(stage) + 14)) + print + + cmd = STAGE_COMMANDS[stage] + if type(cmd) == type([]): + ret = subprocess.call(cmd) == 0 + else: + ret = cmd() + + print + print('-' * (len(stage) + 15)) + print('Finished stage %s' % stage) + print + + return ret + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--list-stages', dest='list', action='store_true') + parser.add_argument('stage', nargs='*', default=STAGES, + help='One of %s'%STAGES) + args = parser.parse_args() + + # Check for list + if args.list: + for s in STAGES: + print(s) + sys.exit(0) + + # Check validity of stages + for s in args.stage: + if s not in STAGES: + print("Invalid stage '%s' (choose from %s)" % (s, STAGES)) + sys.exit(1) + + # Run the stages + passed = True + for s in args.stage: + passed &= run_stage(s) + + if not passed: + print("!!! One or more test stages failed !!!") + sys.exit(1) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/qa/zcash/performance-measurements.sh b/qa/zcash/performance-measurements.sh index 15f3077b5..3370bd20f 100755 --- a/qa/zcash/performance-measurements.sh +++ b/qa/zcash/performance-measurements.sh @@ -338,4 +338,4 @@ case "$1" in esac # Cleanup -rm -rf "$DATADIR" +rm -rf "$DATADIR" \ No newline at end of file diff --git a/qa/zcash/test-depends-sources-mirror.py b/qa/zcash/test-depends-sources-mirror.py index e09c2c238..6b612d715 100755 --- a/qa/zcash/test-depends-sources-mirror.py +++ b/qa/zcash/test-depends-sources-mirror.py @@ -40,4 +40,4 @@ for filename in get_depends_sources_list(): sys.exit(1) print "PASS." -sys.exit(0) +sys.exit(0) \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 00acd5e05..a1232968d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -72,12 +72,12 @@ $(LIBCRYPTOCONDITIONS): $(wildcard cryptoconditions/src/*) $(wildcard cryptocond # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: EXTRA_LIBRARIES = \ - crypto/libbitcoin_crypto.a \ - libbitcoin_util.a \ - libbitcoin_common.a \ - libbitcoin_server.a \ - libbitcoin_cli.a \ - libzcash.a + crypto/libbitcoin_crypto.a \ + libbitcoin_util.a \ + libbitcoin_common.a \ + libbitcoin_server.a \ + libbitcoin_cli.a \ + libzcash.a if ENABLE_WALLET BITCOIN_INCLUDES += $(BDB_CPPFLAGS) EXTRA_LIBRARIES += libbitcoin_wallet.a @@ -100,13 +100,17 @@ bin_PROGRAMS = noinst_PROGRAMS = TESTS = -if BUILD_BITCOIND +#if BUILD_BITCOIND bin_PROGRAMS += komodod -endif +#endif if BUILD_BITCOIN_UTILS bin_PROGRAMS += komodo-cli komodo-tx endif +if ENABLE_WALLET + bin_PROGRAMS += wallet-utility +endif + LIBZCASH_H = \ zcash/IncrementalMerkleTree.hpp \ @@ -122,6 +126,8 @@ LIBZCASH_H = \ .PHONY: FORCE collate-libsnark check-symbols check-security # bitcoin core # BITCOIN_CORE_H = \ + addressindex.h \ + spentindex.h \ addrman.h \ alert.h \ amount.h \ @@ -235,7 +241,7 @@ BITCOIN_CORE_H = \ obj/build.h: FORCE @$(MKDIR_P) $(builddir)/obj @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \ - $(abs_top_srcdir) + $(abs_top_srcdir) libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: zcashd @@ -292,9 +298,9 @@ LIBBITCOIN_ZMQ=libbitcoin_zmq.a libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS) libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_zmq_a_SOURCES = \ - zmq/zmqabstractnotifier.cpp \ - zmq/zmqnotificationinterface.cpp \ - zmq/zmqpublishnotifier.cpp + zmq/zmqabstractnotifier.cpp \ + zmq/zmqnotificationinterface.cpp \ + zmq/zmqpublishnotifier.cpp endif if ENABLE_PROTON @@ -336,33 +342,33 @@ libbitcoin_wallet_a_SOURCES = \ crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_CONFIG_INCLUDES) crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) crypto_libbitcoin_crypto_a_SOURCES = \ - crypto/common.h \ - crypto/equihash.cpp \ - crypto/equihash.h \ - crypto/equihash.tcc \ - crypto/hmac_sha256.cpp \ - crypto/hmac_sha256.h \ - crypto/hmac_sha512.cpp \ - crypto/hmac_sha512.h \ - crypto/ripemd160.cpp \ - crypto/ripemd160.h \ - crypto/sha1.cpp \ - crypto/sha1.h \ - crypto/sha256.cpp \ - crypto/sha256.h \ - crypto/sha512.cpp \ - crypto/sha512.h + crypto/common.h \ + crypto/equihash.cpp \ + crypto/equihash.h \ + crypto/equihash.tcc \ + crypto/hmac_sha256.cpp \ + crypto/hmac_sha256.h \ + crypto/hmac_sha512.cpp \ + crypto/hmac_sha512.h \ + crypto/ripemd160.cpp \ + crypto/ripemd160.h \ + crypto/sha1.cpp \ + crypto/sha1.h \ + crypto/sha256.cpp \ + crypto/sha256.h \ + crypto/sha512.cpp \ + crypto/sha512.h if ENABLE_MINING EQUIHASH_TROMP_SOURCES = \ - pow/tromp/equi_miner.h \ - pow/tromp/equi.h \ - pow/tromp/osx_barrier.h + pow/tromp/equi_miner.h \ + pow/tromp/equi.h \ + pow/tromp/osx_barrier.h crypto_libbitcoin_crypto_a_CPPFLAGS += \ - -DEQUIHASH_TROMP_ATOMIC + -DEQUIHASH_TROMP_ATOMIC crypto_libbitcoin_crypto_a_SOURCES += \ - ${EQUIHASH_TROMP_SOURCES} + ${EQUIHASH_TROMP_SOURCES} endif # common: shared between zcashd and non-server tools @@ -402,23 +408,23 @@ libbitcoin_common_a_SOURCES = \ libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_util_a_SOURCES = \ - support/pagelocker.cpp \ - chainparamsbase.cpp \ - clientversion.cpp \ - compat/glibc_sanity.cpp \ - compat/glibcxx_sanity.cpp \ - compat/strnlen.cpp \ - random.cpp \ - rpcprotocol.cpp \ - support/cleanse.cpp \ - sync.cpp \ - uint256.cpp \ - util.cpp \ - utilmoneystr.cpp \ - utilstrencodings.cpp \ - utiltime.cpp \ - $(BITCOIN_CORE_H) \ - $(LIBZCASH_H) + support/pagelocker.cpp \ + chainparamsbase.cpp \ + clientversion.cpp \ + compat/glibc_sanity.cpp \ + compat/glibcxx_sanity.cpp \ + compat/strnlen.cpp \ + random.cpp \ + rpcprotocol.cpp \ + support/cleanse.cpp \ + sync.cpp \ + uint256.cpp \ + util.cpp \ + utilmoneystr.cpp \ + utilstrencodings.cpp \ + utiltime.cpp \ + $(BITCOIN_CORE_H) \ + $(LIBZCASH_H) if GLIBC_BACK_COMPAT libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp @@ -428,9 +434,9 @@ endif libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_cli_a_SOURCES = \ - rpcclient.cpp \ - $(BITCOIN_CORE_H) \ - $(LIBZCASH_H) + rpcclient.cpp \ + $(BITCOIN_CORE_H) \ + $(LIBZCASH_H) nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h # @@ -486,23 +492,45 @@ komodo_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) komodo_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) komodo_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +# wallet-utility binary # +if ENABLE_WALLET +wallet_utility_SOURCES = wallet-utility.cpp +wallet_utility_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +wallet_utility_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +wallet_utility_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +endif + if TARGET_WINDOWS komodo_cli_SOURCES += bitcoin-cli-res.rc endif komodo_cli_LDADD = \ - $(LIBBITCOIN_CLI) \ - $(LIBUNIVALUE) \ - $(LIBBITCOIN_UTIL) \ - $(BOOST_LIBS) \ - $(SSL_LIBS) \ - $(CRYPTO_LIBS) \ - $(EVENT_LIBS) \ - $(LIBZCASH) \ - $(LIBSNARK) \ - $(LIBBITCOIN_CRYPTO) \ - $(LIBZCASH_LIBS) -# + $(LIBBITCOIN_CLI) \ + $(LIBUNIVALUE) \ + $(LIBBITCOIN_UTIL) \ + $(BOOST_LIBS) \ + $(SSL_LIBS) \ + $(CRYPTO_LIBS) \ + $(EVENT_LIBS) \ + $(LIBZCASH) \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBZCASH_LIBS) + +if ENABLE_WALLET +wallet_utility_LDADD = \ + libbitcoin_wallet.a \ + $(LIBBITCOIN_COMMON) \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBSECP256K1) \ + $(LIBBITCOIN_UTIL) \ + $(BOOST_LIBS) \ + $(BDB_LIBS) \ + $(CRYPTO_LIBS) \ + $(LIBZCASH) \ + $(LIBSNARK) \ + $(LIBZCASH_LIBS)\ + $(LIBCRYPTOCONDITIONS) +endif # zcash-tx binary # komodo_tx_SOURCES = komodo-tx.cpp @@ -531,20 +559,20 @@ komodo_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) # zcash protocol primitives # libzcash_a_SOURCES = \ - zcash/IncrementalMerkleTree.cpp \ - zcash/NoteEncryption.cpp \ - zcash/Address.cpp \ - zcash/JoinSplit.cpp \ - zcash/Proof.cpp \ - zcash/Note.cpp \ - zcash/prf.cpp \ - zcash/util.cpp \ - zcash/circuit/commitment.tcc \ - zcash/circuit/gadget.tcc \ - zcash/circuit/merkle.tcc \ - zcash/circuit/note.tcc \ - zcash/circuit/prfs.tcc \ - zcash/circuit/utils.tcc + zcash/IncrementalMerkleTree.cpp \ + zcash/NoteEncryption.cpp \ + zcash/Address.cpp \ + zcash/JoinSplit.cpp \ + zcash/Proof.cpp \ + zcash/Note.cpp \ + zcash/prf.cpp \ + zcash/util.cpp \ + zcash/circuit/commitment.tcc \ + zcash/circuit/gadget.tcc \ + zcash/circuit/merkle.tcc \ + zcash/circuit/note.tcc \ + zcash/circuit/prfs.tcc \ + zcash/circuit/utils.tcc libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) $(HARDENED_CXXFLAGS) $(HARDENED_LDFLAGS) -pipe $(SAN_LDFLAGS) -O1 -g -Wstack-protector $(SAN_CXXFLAGS) -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES) @@ -572,7 +600,7 @@ libzcashconsensus_la_SOURCES = \ utilstrencodings.cpp if GLIBC_BACK_COMPAT - libzcashconsensus_la_SOURCES += compat/glibc_compat.cpp +libzcashconsensus_la_SOURCES += compat/glibc_compat.cpp endif libzcashconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 582ecb577..ff270bd6a 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -15,87 +15,90 @@ EXTRA_DIST += \ test/data/tx394b54bb.hex \ test/data/txcreate1.hex \ test/data/txcreate2.hex \ - test/data/txcreatesign.hex + test/data/txcreatesign.hex \ + test/wallet-utility.py \ + test/data/wallet.dat JSON_TEST_FILES = \ - test/data/script_valid.json \ - test/data/base58_keys_valid.json \ - test/data/base58_encode_decode.json \ - test/data/base58_keys_invalid.json \ - test/data/script_invalid.json \ - test/data/tx_invalid.json \ - test/data/tx_valid.json \ - test/data/sighash.json \ - test/data/merkle_roots.json \ - test/data/merkle_roots_empty.json \ - test/data/merkle_serialization.json \ - test/data/merkle_witness_serialization.json \ - test/data/merkle_path.json \ - test/data/merkle_commitments.json \ - test/data/g1_compressed.json \ - test/data/g2_compressed.json + test/data/script_valid.json \ + test/data/base58_keys_valid.json \ + test/data/base58_encode_decode.json \ + test/data/base58_keys_invalid.json \ + test/data/script_invalid.json \ + test/data/tx_invalid.json \ + test/data/tx_valid.json \ + test/data/sighash.json \ + test/data/merkle_roots.json \ + test/data/merkle_roots_empty.json \ + test/data/merkle_serialization.json \ + test/data/merkle_witness_serialization.json \ + test/data/merkle_path.json \ + test/data/merkle_commitments.json \ + test/data/g1_compressed.json \ + test/data/g2_compressed.json RAW_TEST_FILES = test/data/alertTests.raw GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h) BITCOIN_TESTS =\ - test/arith_uint256_tests.cpp \ - test/bignum.h \ - test/addrman_tests.cpp \ - test/alert_tests.cpp \ - test/allocator_tests.cpp \ - test/base32_tests.cpp \ - test/base58_tests.cpp \ - test/base64_tests.cpp \ - test/bip32_tests.cpp \ - test/bloom_tests.cpp \ - test/checkblock_tests.cpp \ - test/Checkpoints_tests.cpp \ - test/coins_tests.cpp \ - test/compress_tests.cpp \ - test/crypto_tests.cpp \ - test/DoS_tests.cpp \ - test/equihash_tests.cpp \ - test/getarg_tests.cpp \ - test/hash_tests.cpp \ - test/key_tests.cpp \ - test/main_tests.cpp \ - test/mempool_tests.cpp \ - test/miner_tests.cpp \ - test/mruset_tests.cpp \ - test/multisig_tests.cpp \ - test/netbase_tests.cpp \ - test/pmt_tests.cpp \ - test/policyestimator_tests.cpp \ - test/pow_tests.cpp \ - test/raii_event_tests.cpp \ - test/reverselock_tests.cpp \ - test/rpc_tests.cpp \ - test/sanity_tests.cpp \ - test/scheduler_tests.cpp \ - test/script_P2SH_tests.cpp \ - test/script_tests.cpp \ - test/scriptnum_tests.cpp \ - test/serialize_tests.cpp \ - test/sighash_tests.cpp \ - test/sigopcount_tests.cpp \ - test/skiplist_tests.cpp \ - test/test_bitcoin.cpp \ - test/test_bitcoin.h \ - test/timedata_tests.cpp \ - test/torcontrol_tests.cpp \ - test/transaction_tests.cpp \ - test/uint256_tests.cpp \ - test/univalue_tests.cpp \ - test/util_tests.cpp \ - test/sha256compress_tests.cpp + test/arith_uint256_tests.cpp \ + test/bignum.h \ + test/addrman_tests.cpp \ + test/alert_tests.cpp \ + test/allocator_tests.cpp \ + test/base32_tests.cpp \ + test/base58_tests.cpp \ + test/base64_tests.cpp \ + test/bip32_tests.cpp \ + test/bloom_tests.cpp \ + test/checkblock_tests.cpp \ + test/Checkpoints_tests.cpp \ + test/coins_tests.cpp \ + test/compress_tests.cpp \ + test/crypto_tests.cpp \ + test/DoS_tests.cpp \ + test/equihash_tests.cpp \ + test/getarg_tests.cpp \ + test/hash_tests.cpp \ + test/key_tests.cpp \ + test/main_tests.cpp \ + test/mempool_tests.cpp \ + test/miner_tests.cpp \ + test/mruset_tests.cpp \ + test/multisig_tests.cpp \ + test/netbase_tests.cpp \ + test/pmt_tests.cpp \ + test/policyestimator_tests.cpp \ + test/pow_tests.cpp \ + test/raii_event_tests.cpp \ + test/reverselock_tests.cpp \ + test/rpc_tests.cpp \ + test/sanity_tests.cpp \ + test/scheduler_tests.cpp \ + test/script_P2SH_tests.cpp \ + test/script_P2PKH_tests.cpp \ + test/script_tests.cpp \ + test/scriptnum_tests.cpp \ + test/serialize_tests.cpp \ + test/sighash_tests.cpp \ + test/sigopcount_tests.cpp \ + test/skiplist_tests.cpp \ + test/test_bitcoin.cpp \ + test/test_bitcoin.h \ + test/timedata_tests.cpp \ + test/torcontrol_tests.cpp \ + test/transaction_tests.cpp \ + test/uint256_tests.cpp \ + test/univalue_tests.cpp \ + test/util_tests.cpp \ + test/sha256compress_tests.cpp if ENABLE_WALLET BITCOIN_TESTS += \ - test/accounting_tests.cpp \ - wallet/test/wallet_tests.cpp \ - test/rpc_wallet_tests.cpp + test/accounting_tests.cpp \ + wallet/test/wallet_tests.cpp \ + test/rpc_wallet_tests.cpp endif test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) @@ -137,6 +140,10 @@ bitcoin_test_clean : FORCE check-local: @echo "Running test/bitcoin-util-test.py..." $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py +if ENABLE_WALLET + @echo "Running test/wallet-utility.py..." + $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/wallet-utility.py +endif $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check diff --git a/src/ac/axo b/src/ac/axo new file mode 100755 index 000000000..18d38cac0 --- /dev/null +++ b/src/ac/axo @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=AXO $1 $2 $3 $4 $5 $6 diff --git a/src/ac/beer b/src/ac/beer new file mode 100755 index 000000000..34317bb93 --- /dev/null +++ b/src/ac/beer @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=BEER $1 $2 $3 $4 $5 $6 diff --git a/src/ac/bet b/src/ac/bet new file mode 100755 index 000000000..ed99ce59f --- /dev/null +++ b/src/ac/bet @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=BET $1 $2 $3 $4 $5 $6 diff --git a/src/ac/bntn b/src/ac/bntn new file mode 100755 index 000000000..7ae6f4e8d --- /dev/null +++ b/src/ac/bntn @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=BNTN $1 $2 $3 $4 $5 $6 diff --git a/src/ac/bots b/src/ac/bots new file mode 100755 index 000000000..15c0fc288 --- /dev/null +++ b/src/ac/bots @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=BOTS $1 $2 $3 $4 $5 $6 diff --git a/src/ac/btch b/src/ac/btch new file mode 100755 index 000000000..6a57ea8d1 --- /dev/null +++ b/src/ac/btch @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=BTCH $1 $2 $3 $4 $5 $6 diff --git a/src/ac/ceal b/src/ac/ceal new file mode 100755 index 000000000..0cbeba67b --- /dev/null +++ b/src/ac/ceal @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=CEAL $1 $2 $3 $4 $5 $6 diff --git a/src/ac/chain b/src/ac/chain new file mode 100755 index 000000000..c55d30fbd --- /dev/null +++ b/src/ac/chain @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=CHAIN $1 $2 $3 $4 $5 $6 diff --git a/src/ac/coqui b/src/ac/coqui new file mode 100755 index 000000000..d4fcb63d5 --- /dev/null +++ b/src/ac/coqui @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=COQUI $1 $2 $3 $4 $5 $6 diff --git a/src/ac/crypto b/src/ac/crypto new file mode 100755 index 000000000..5a3d46188 --- /dev/null +++ b/src/ac/crypto @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=CRYPTO $1 $2 $3 $4 $5 $6 diff --git a/src/ac/dex b/src/ac/dex new file mode 100755 index 000000000..67331201a --- /dev/null +++ b/src/ac/dex @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=DEX $1 $2 $3 $4 $5 $6 diff --git a/src/ac/dsec b/src/ac/dsec new file mode 100755 index 000000000..a050ca94f --- /dev/null +++ b/src/ac/dsec @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=DSEC $1 $2 $3 $4 $5 $6 diff --git a/src/ac/etomic b/src/ac/etomic new file mode 100755 index 000000000..76eb0191c --- /dev/null +++ b/src/ac/etomic @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=ETOMIC $1 $2 $3 $4 $5 $6 diff --git a/src/ac/hodl b/src/ac/hodl new file mode 100755 index 000000000..a5430db59 --- /dev/null +++ b/src/ac/hodl @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=HODL $1 $2 $3 $4 $5 $6 diff --git a/src/ac/jumblr b/src/ac/jumblr new file mode 100755 index 000000000..2969c5009 --- /dev/null +++ b/src/ac/jumblr @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=JUMBLR $1 $2 $3 $4 $5 $6 diff --git a/src/ac/kv b/src/ac/kv new file mode 100755 index 000000000..997fccb33 --- /dev/null +++ b/src/ac/kv @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=KV $1 $2 $3 $4 $5 $6 diff --git a/src/ac/mesh b/src/ac/mesh new file mode 100755 index 000000000..19b359509 --- /dev/null +++ b/src/ac/mesh @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=MESH $1 $2 $3 $4 $5 $6 diff --git a/src/ac/mgw b/src/ac/mgw new file mode 100755 index 000000000..9afa86b7a --- /dev/null +++ b/src/ac/mgw @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=MGW $1 $2 $3 $4 $5 $6 diff --git a/src/ac/mnz b/src/ac/mnz new file mode 100755 index 000000000..f4e1f3501 --- /dev/null +++ b/src/ac/mnz @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=MNZ $1 $2 $3 $4 $5 $6 diff --git a/src/ac/mshark b/src/ac/mshark new file mode 100755 index 000000000..1f0c950c6 --- /dev/null +++ b/src/ac/mshark @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=MSHARK $1 $2 $3 $4 $5 $6 diff --git a/src/ac/ninja b/src/ac/ninja new file mode 100755 index 000000000..f7722abb0 --- /dev/null +++ b/src/ac/ninja @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=NINJA $1 $2 $3 $4 $5 $6 diff --git a/src/ac/oot b/src/ac/oot new file mode 100755 index 000000000..4c7c6b683 --- /dev/null +++ b/src/ac/oot @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=OOT $1 $2 $3 $4 $5 $6 diff --git a/src/ac/pangea b/src/ac/pangea new file mode 100755 index 000000000..9920189ea --- /dev/null +++ b/src/ac/pangea @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=PANGEA $1 $2 $3 $4 $5 $6 diff --git a/src/ac/pizza b/src/ac/pizza new file mode 100755 index 000000000..d8400d9d3 --- /dev/null +++ b/src/ac/pizza @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=PIZZA $1 $2 $3 $4 $5 $6 diff --git a/src/ac/prlpay b/src/ac/prlpay new file mode 100755 index 000000000..3d1063d13 --- /dev/null +++ b/src/ac/prlpay @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=PRLPAY $1 $2 $3 $4 $5 $6 diff --git a/src/ac/revs b/src/ac/revs new file mode 100755 index 000000000..b898eb5dc --- /dev/null +++ b/src/ac/revs @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=REVS $1 $2 $3 $4 $5 $6 diff --git a/src/ac/supernet b/src/ac/supernet new file mode 100755 index 000000000..d841ffa0e --- /dev/null +++ b/src/ac/supernet @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=SUPERNET $1 $2 $3 $4 $5 $6 diff --git a/src/fiat/vote2018 b/src/ac/vote2018 similarity index 100% rename from src/fiat/vote2018 rename to src/ac/vote2018 diff --git a/src/ac/wlc b/src/ac/wlc new file mode 100755 index 000000000..ef7c47b90 --- /dev/null +++ b/src/ac/wlc @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=WLC $1 $2 $3 $4 $5 $6 diff --git a/src/addressindex.h b/src/addressindex.h new file mode 100644 index 000000000..643f06e13 --- /dev/null +++ b/src/addressindex.h @@ -0,0 +1,82 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 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_ADDRESSINDEX_H +#define BITCOIN_ADDRESSINDEX_H + +#include "uint256.h" +#include "amount.h" + +struct CMempoolAddressDelta +{ + int64_t time; + CAmount amount; + uint256 prevhash; + unsigned int prevout; + + CMempoolAddressDelta(int64_t t, CAmount a, uint256 hash, unsigned int out) { + time = t; + amount = a; + prevhash = hash; + prevout = out; + } + + CMempoolAddressDelta(int64_t t, CAmount a) { + time = t; + amount = a; + prevhash.SetNull(); + prevout = 0; + } +}; + +struct CMempoolAddressDeltaKey +{ + int type; + uint160 addressBytes; + uint256 txhash; + unsigned int index; + int spending; + + CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, int s) { + type = addressType; + addressBytes = addressHash; + txhash = hash; + index = i; + spending = s; + } + + CMempoolAddressDeltaKey(int addressType, uint160 addressHash) { + type = addressType; + addressBytes = addressHash; + txhash.SetNull(); + index = 0; + spending = 0; + } +}; + +struct CMempoolAddressDeltaKeyCompare +{ + bool operator()(const CMempoolAddressDeltaKey& a, const CMempoolAddressDeltaKey& b) const { + if (a.type == b.type) { + if (a.addressBytes == b.addressBytes) { + if (a.txhash == b.txhash) { + if (a.index == b.index) { + return a.spending < b.spending; + } else { + return a.index < b.index; + } + } else { + return a.txhash < b.txhash; + } + } else { + return a.addressBytes < b.addressBytes; + } + } else { + return a.type < b.type; + } + } +}; + +#endif // BITCOIN_ADDRESSINDEX_H \ No newline at end of file diff --git a/src/assetchains b/src/assetchains index 517687097..a8ab28155 100755 --- a/src/assetchains +++ b/src/assetchains @@ -21,7 +21,7 @@ function komodo_asset () supply=" " fi - $komodo_binary -pubkey=$pubkey -ac_name=$1 $supply -addnode=$seed_ip $gen $args & + $komodo_binary -ac_name=$1 $gen $supply $args -pubkey=$pubkey -addnode=$seed_ip & sleep $delay } @@ -47,7 +47,6 @@ komodo_asset MNZ 257142858 komodo_asset AXO 200000000 komodo_asset ETOMIC 100000000 komodo_asset BTCH 20998641 -komodo_asset VOTE2018 600000000 komodo_asset PIZZA 100000000 komodo_asset BEER 100000000 komodo_asset NINJA 100000000 @@ -55,3 +54,4 @@ komodo_asset OOT 216000000 komodo_asset BNTN 500000000 komodo_asset CHAIN 999999 komodo_asset PRLPAY 500000000 +komodo_asset DSEC 7000000 diff --git a/src/assetchains.old b/src/assetchains.old index c025e0430..4e56fe639 100755 --- a/src/assetchains.old +++ b/src/assetchains.old @@ -24,7 +24,6 @@ echo $pubkey ./komodod -pubkey=$pubkey -ac_name=AXO -ac_supply=200000000 -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=ETOMIC -ac_supply=100000000 -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=BTCH -ac_supply=20998641 -addnode=78.47.196.146 & -./komodod -pubkey=$pubkey -ac_name=VOTE2018 -ac_supply=600000000 -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=BEER -ac_supply=100000000 -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=PIZZA -ac_supply=100000000 -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=NINJA -ac_supply=100000000 -addnode=78.47.196.146 & @@ -32,6 +31,7 @@ echo $pubkey ./komodod -pubkey=$pubkey -ac_name=BNTN -ac_supply=500000000 -addnode=94.130.169.205 & ./komodod -pubkey=$pubkey -ac_name=CHAIN -ac_supply=999999 -addnode=78.47.146.222 & ./komodod -pubkey=$pubkey -ac_name=PRLPAY -ac_supply=500000000 -addnode=13.250.226.125 & +./komodod -pubkey=$pubkey -ac_name=DSEC -ac_supply=7000000 -addnode=185.148.147.30 & #sleep $delay #./komodod -pubkey=$pubkey -ac_name=USD -addnode=78.47.196.146 $1 & diff --git a/src/assetchains_stop b/src/assetchains_stop new file mode 100755 index 000000000..e55231b1a --- /dev/null +++ b/src/assetchains_stop @@ -0,0 +1,40 @@ +#!/bin/bash +args=("$@") +komodo_cli='./komodo-cli' +delay=20 + +function komodo_stop () +{ + $komodo_cli --ac_name=$1 stop +} + +#set -x + +komodo_stop REVS +komodo_stop SUPERNET +komodo_stop DEX +komodo_stop PANGEA +komodo_stop JUMBLR +komodo_stop BET +komodo_stop CRYPTO +komodo_stop HODL +komodo_stop MSHARK +komodo_stop BOTS +komodo_stop MGW +komodo_stop COQUI +komodo_stop WLC +komodo_stop KV +komodo_stop CEAL +komodo_stop MESH +komodo_stop MNZ +komodo_stop AXO +komodo_stop ETOMIC +komodo_stop BTCH +komodo_stop PIZZA +komodo_stop BEER +komodo_stop NINJA +komodo_stop OOT +komodo_stop BNTN +komodo_stop CHAIN +komodo_stop PRLPAY +komodo_stop DSEC diff --git a/src/base58.cpp b/src/base58.cpp index c9c64bc58..c086cc854 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -275,6 +275,23 @@ CTxDestination CBitcoinAddress::Get() const return CNoDestination(); } +bool CBitcoinAddress::GetIndexKey(uint160& hashBytes, int& type) const +{ + if (!IsValid()) { + return false; + } else if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) { + memcpy(&hashBytes, &vchData[0], 20); + type = 1; + return true; + } else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS)) { + memcpy(&hashBytes, &vchData[0], 20); + type = 2; + return true; + } + + return false; +} + bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const { if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) diff --git a/src/base58.h b/src/base58.h index 24e7abfc8..73e1c4d94 100644 --- a/src/base58.h +++ b/src/base58.h @@ -163,6 +163,7 @@ public: CTxDestination Get() const; bool GetKeyID(CKeyID &keyID) const; + bool GetIndexKey(uint160& hashBytes, int& type) const; bool IsScript() const; }; diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 285d06c3f..bf189e483 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -76,7 +76,7 @@ public: #include "komodo_cJSON.c" #include "komodo_notary.h" -void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout) +void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth) { } @@ -202,7 +202,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) { std::string host = GetArg("-rpcconnect", "127.0.0.1"); int port = GetArg("-rpcport", BaseParams().RPCPort()); - BITCOIND_PORT = port; + BITCOIND_RPCPORT = port; // Obtain event base raii_event_base base = obtain_event_base(); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index bf4934da4..5c12cfa2f 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -45,6 +45,8 @@ static bool fDaemon; #define KOMODO_ASSETCHAIN_MAXLEN 65 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; void komodo_passport_iteration(); +uint64_t komodo_interestsum(); +int32_t komodo_longestchain(); void WaitForShutdown(boost::thread_group* threadGroup) { @@ -56,8 +58,14 @@ void WaitForShutdown(boost::thread_group* threadGroup) if ( ASSETCHAINS_SYMBOL[0] == 0 ) { komodo_passport_iteration(); - MilliSleep(1000); - } else MilliSleep(1000); + MilliSleep(10000); + } + else + { + komodo_interestsum(); + komodo_longestchain(); + MilliSleep(20000); + } fShutdown = ShutdownRequested(); } if (threadGroup) @@ -125,7 +133,7 @@ bool AppInit(int argc, char* argv[]) sleep(1); #endif } - printf("initialized %s\n",ASSETCHAINS_SYMBOL); + printf("initialized %s at %u\n",ASSETCHAINS_SYMBOL,(uint32_t)time(NULL)); if (!boost::filesystem::is_directory(GetDataDir(false))) { fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 49c4a2244..d78e1351b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -79,7 +79,7 @@ void *chainparams_commandline(void *ptr); #include "komodo_defs.h" extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -extern uint16_t ASSETCHAINS_PORT; +extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; extern uint32_t ASSETCHAIN_INIT; extern uint32_t ASSETCHAINS_MAGIC; extern uint64_t ASSETCHAINS_SUPPLY; @@ -209,7 +209,7 @@ void CChainParams::SetCheckpointData(CChainParams::CCheckpointData checkpointDat void *chainparams_commandline(void *ptr) { CChainParams::CCheckpointData checkpointData; - while ( ASSETCHAINS_PORT == 0 ) + while ( ASSETCHAINS_P2PPORT == 0 ) { #ifdef _WIN32 boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); @@ -217,15 +217,17 @@ void *chainparams_commandline(void *ptr) sleep(1); #endif } - //fprintf(stderr,">>>>>>>> port.%u\n",ASSETCHAINS_PORT); + //fprintf(stderr,">>>>>>>> port.%u\n",ASSETCHAINS_P2PPORT); if ( ASSETCHAINS_SYMBOL[0] != 0 ) { - mainParams.SetDefaultPort(ASSETCHAINS_PORT); + mainParams.SetDefaultPort(ASSETCHAINS_P2PPORT); + if ( ASSETCHAINS_RPCPORT == 0 ) + ASSETCHAINS_RPCPORT = ASSETCHAINS_P2PPORT + 1; mainParams.pchMessageStart[0] = ASSETCHAINS_MAGIC & 0xff; mainParams.pchMessageStart[1] = (ASSETCHAINS_MAGIC >> 8) & 0xff; mainParams.pchMessageStart[2] = (ASSETCHAINS_MAGIC >> 16) & 0xff; mainParams.pchMessageStart[3] = (ASSETCHAINS_MAGIC >> 24) & 0xff; - fprintf(stderr,">>>>>>>>>> %s: port.%u/%u magic.%08x %u %u coins\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_PORT,ASSETCHAINS_PORT+1,ASSETCHAINS_MAGIC,ASSETCHAINS_MAGIC,(uint32_t)ASSETCHAINS_SUPPLY); + fprintf(stderr,">>>>>>>>>> %s: p2p.%u rpc.%u magic.%08x %u %u coins\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_MAGIC,ASSETCHAINS_MAGIC,(uint32_t)ASSETCHAINS_SUPPLY); checkpointData = //(Checkpoints::CCheckpointData) { @@ -530,11 +532,16 @@ public: BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K)); nEquihashN = N; nEquihashK = K; - genesis.nTime = 1296688602; - genesis.nBits = KOMODO_MINDIFF_NBITS; - genesis.nNonce = uint256S("0x0000000000000000000000000000000000000000000000000000000000000021"); - genesis.nSolution = ParseHex("0f2a976db4c4263da10fd5d38eb1790469cf19bdb4bf93450e09a72fdff17a3454326399"); + + genesis = CreateGenesisBlock( + 1296688602, + uint256S("0x0000000000000000000000000000000000000000000000000000000000000009"), + ParseHex("01936b7db1eb4ac39f151b8704642d0a8bda13ec547d54cd5e43ba142fc6d8877cab07b3"), + KOMODO_MINDIFF_NBITS, 4, 0); consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x029f11d80ef9765602235e1bc9727e3eb6ba20839319f761fee920d63401e327")); + assert(genesis.hashMerkleRoot == uint256S("0xc4eaa58879081de3c24a7b117ed2b28300e7ec4c4c1dff1d3f1268b7857a4ddb")); + nDefaultPort = 17779; nPruneAfterHeight = 1000; diff --git a/src/clientversion.cpp b/src/clientversion.cpp index ae67e678f..9b523e582 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -48,10 +48,11 @@ const std::string CLIENT_NAME("MagicBean"); #include "build.h" #endif -//! git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$ +//! git will put "#define GIT_ARCHIVE 1" on the next line inside archives. +#define GIT_ARCHIVE 1 #ifdef GIT_ARCHIVE -#define GIT_COMMIT_ID "$Format:%h$" -#define GIT_COMMIT_DATE "$Format:%cD$" +#define GIT_COMMIT_ID "a86845f3dc" +#define GIT_COMMIT_DATE "Wed, 21 Feb 2018 16:15:11 +0200" #endif #define RENDER_BETA_STRING(num) "-beta" DO_STRINGIZE(num) diff --git a/src/coins.cpp b/src/coins.cpp index bb40af9cc..42939ccac 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -462,6 +462,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const const COutPoint &prevout = tx.vin[i].prevout; const CCoins* coins = AccessCoins(prevout.hash); if (!coins || !coins->IsAvailable(prevout.n)) { + fprintf(stderr,"HaveInputs missing input %s/v%d\n",prevout.hash.ToString().c_str(),prevout.n); return false; } } diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index d2e7dec3f..c2972e598 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -17,7 +17,7 @@ static const int32_t OVERWINTER_MAX_TX_VERSION = 3; /** The maximum allowed size for a serialized block, in bytes (network rule) */ static const unsigned int MAX_BLOCK_SIZE = 2000000; /** The maximum allowed number of signature check operations in a block (network rule) */ -static const unsigned int MAX_BLOCK_SIGOPS = 20000; +extern unsigned int MAX_BLOCK_SIGOPS; /** The maximum size of a transaction (network rule) */ static const unsigned int MAX_TX_SIZE = 100000; /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ diff --git a/src/cryptoconditions/src/cryptoconditions.c b/src/cryptoconditions/src/cryptoconditions.c index 2f136917e..6fd54f245 100644 --- a/src/cryptoconditions/src/cryptoconditions.c +++ b/src/cryptoconditions/src/cryptoconditions.c @@ -13,7 +13,12 @@ #include "src/eval.c" #include "src/json_rpc.c" #include -#include + +#ifdef __LP64__ +#include +#else +#include // Index into CTransaction.vjoinsplit +#endif struct CCType *CCTypeRegistry[] = { diff --git a/src/cryptoconditions/src/json_rpc.c b/src/cryptoconditions/src/json_rpc.c index 42c13612c..13cffec1d 100644 --- a/src/cryptoconditions/src/json_rpc.c +++ b/src/cryptoconditions/src/json_rpc.c @@ -1,8 +1,12 @@ #include "cryptoconditions.h" #include "internal.h" #include -#include +#ifdef __LP64__ +#include +#else +#include // Index into CTransaction.vjoinsplit +#endif static cJSON *jsonCondition(CC *cond) { cJSON *root = cJSON_CreateObject(); diff --git a/src/cryptoconditions/src/secp256k1.c b/src/cryptoconditions/src/secp256k1.c index 73f7a9164..78b9c4e9e 100644 --- a/src/cryptoconditions/src/secp256k1.c +++ b/src/cryptoconditions/src/secp256k1.c @@ -1,6 +1,11 @@ #define _GNU_SOURCE 1 +#if __linux #include +#elif defined(_WIN32) || defined(_WIN64) +#include +#endif + #include #include diff --git a/src/deprecation.cpp b/src/deprecation.cpp index 9f394e720..73ff8046d 100644 --- a/src/deprecation.cpp +++ b/src/deprecation.cpp @@ -11,12 +11,13 @@ #include "chainparams.h" static const std::string CLIENT_VERSION_STR = FormatVersion(CLIENT_VERSION); +extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; void EnforceNodeDeprecation(int nHeight, bool forceLogging) { // Do not enforce deprecation in regtest or on testnet std::string networkID = Params().NetworkIDString(); - if (networkID != "main") return; + if (networkID != "main" || ASSETCHAINS_SYMBOL[0] != 0 ) return; int blocksToDeprecation = DEPRECATION_HEIGHT - nHeight; bool disableDeprecation = (GetArg("-disabledeprecation", "") == CLIENT_VERSION_STR); @@ -58,4 +59,4 @@ void EnforceNodeDeprecation(int nHeight, bool forceLogging) { LogPrintf("*** %s\n", msg); uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_WARNING); } -} \ No newline at end of file +} diff --git a/src/dpowassets b/src/dpowassets index 14bb39912..40bb89cce 100755 --- a/src/dpowassets +++ b/src/dpowassets @@ -2,9 +2,9 @@ set -x source pubkey.txt echo $pubkey +sleep 3 - -curl --url "http://127.0.0.1:7776" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"REVS\",\"pubkey\":\"$pubkey\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"REVS\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"SUPERNET\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"DEX\",\"pubkey\":\"$pubkey\"}" @@ -22,14 +22,15 @@ curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dp curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CEAL\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MESH\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MNZ\",\"pubkey\":\"$pubkey\"}" -curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CHIPS\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"AXO\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"ETOMIC\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BTCH\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CHAIN\",\"pubkey\":\"$pubkey\"}" -curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"VOTE2018\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"NINJA\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"OOT\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BNTN\",\"pubkey\":\"$pubkey\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"PRLPAY\",\"pubkey\":\"$pubkey\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"DSEC\",\"pubkey\":\"$pubkey\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CHIPS\",\"pubkey\":\"$pubkey\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"GAME\",\"freq\":5,\"pubkey\":\"$pubkey\"}" diff --git a/src/fiat-cli b/src/fiat-cli index ce2e7a51d..463906cf2 100755 --- a/src/fiat-cli +++ b/src/fiat-cli @@ -22,9 +22,9 @@ echo etomic; fiat/etomic $1 $2 $3 $4 echo btch; fiat/btch $1 $2 $3 $4 echo pizza; fiat/pizza $1 $2 $3 $4 echo beer; fiat/beer $1 $2 $3 $4 -echo vote2018; fiat/vote2018 $1 $2 $3 $4 echo ninja; fiat/ninja $1 $2 $3 $4 echo oot; fiat/oot $1 $2 $3 $4 echo bntn; fiat/bntn $1 $2 $3 $4 echo chain; fiat/chain $1 $2 $3 $4 echo prlpay; fiat/prlpay $1 $2 $3 $4 +echo dsec; fiat/dsec $1 $2 $3 $4 diff --git a/src/fiat/dsec b/src/fiat/dsec new file mode 100755 index 000000000..a050ca94f --- /dev/null +++ b/src/fiat/dsec @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=DSEC $1 $2 $3 $4 $5 $6 diff --git a/src/gtest/test_checkblock.cpp b/src/gtest/test_checkblock.cpp index e098cfdae..284cff134 100644 --- a/src/gtest/test_checkblock.cpp +++ b/src/gtest/test_checkblock.cpp @@ -22,6 +22,7 @@ public: MOCK_CONST_METHOD0(GetRejectReason, std::string()); }; +int32_t futureblock; TEST(CheckBlock, VersionTooLow) { auto verifier = libzcash::ProofVerifier::Strict(); @@ -30,7 +31,7 @@ TEST(CheckBlock, VersionTooLow) { MockCValidationState state; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "version-too-low", false)).Times(1); - EXPECT_FALSE(CheckBlock(0,0,block, state, verifier, false, false)); + EXPECT_FALSE(CheckBlock(&futureblock,0,0,block, state, verifier, false, false)); } @@ -230,4 +231,4 @@ TEST(ContextualCheckBlock, BlockOverwinterRulesRejectSproutTx) { // Revert to default UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); -} \ No newline at end of file +} diff --git a/src/init.cpp b/src/init.cpp index 7268c362c..aa55d1782 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -370,7 +370,9 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); #endif strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0)); - + strUsage += HelpMessageOpt("-addressindex", strprintf(_("Maintain a full address index, used to query for the balance, txids and unspent outputs for addresses (default: %u)"), DEFAULT_ADDRESSINDEX)); + strUsage += HelpMessageOpt("-timestampindex", strprintf(_("Maintain a timestamp index for block hashes, used to query blocks hashes by a range of timestamps (default: %u)"), DEFAULT_TIMESTAMPINDEX)); + strUsage += HelpMessageOpt("-spentindex", strprintf(_("Maintain a full spent index, used to query the spending txid and input index for an outpoint (default: %u)"), DEFAULT_SPENTINDEX)); strUsage += HelpMessageGroup(_("Connection options:")); strUsage += HelpMessageOpt("-addnode=", _("Add a node to connect to and attempt to keep the connection open")); strUsage += HelpMessageOpt("-banscore=", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100)); @@ -1364,18 +1366,34 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } + // block tree db settings + int dbMaxOpenFiles = GetArg("-dbmaxopenfiles", DEFAULT_DB_MAX_OPEN_FILES); + bool dbCompression = GetBoolArg("-dbcompression", DEFAULT_DB_COMPRESSION); + + LogPrintf("Block index database configuration:\n"); + LogPrintf("* Using %d max open files\n", dbMaxOpenFiles); + LogPrintf("* Compression is %s\n", dbCompression ? "enabled" : "disabled"); + // cache size calculations int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20); nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache int64_t nBlockTreeDBCache = nTotalCache / 8; - if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", true)) - nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB + + if (GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX) || GetBoolArg("-spentindex", DEFAULT_SPENTINDEX)) { + // enable 3/4 of the cache if addressindex and/or spentindex is enabled + nBlockTreeDBCache = nTotalCache * 3 / 4; + } else { + if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false)) { + nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB + } + } nTotalCache -= nBlockTreeDBCache; int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache nTotalCache -= nCoinDBCache; nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache LogPrintf("Cache configuration:\n"); + LogPrintf("* Max cache setting possible %.1fMiB\n", nMaxDbCache); LogPrintf("* Using %.1fMiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024)); LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024)); LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024)); @@ -1396,7 +1414,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) delete pcoinscatcher; delete pblocktree; - pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); + pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex, dbCompression, dbMaxOpenFiles); pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex); pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview); pcoinsTip = new CCoinsViewCache(pcoinscatcher); @@ -1424,7 +1442,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) break; } KOMODO_LOADINGBLOCKS = 0; - // Check for changed -txindex state if (fTxIndex != GetBoolArg("-txindex", true)) { strLoadError = _("You need to rebuild the database using -reindex to change -txindex"); diff --git a/src/komodo.h b/src/komodo.h index 859e3db9d..36c7c2ef3 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -54,6 +54,7 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char #include "komodo_jumblr.h" #include "komodo_gateway.h" #include "komodo_events.h" +#include "komodo_ccdata.h" void komodo_currentheight_set(int32_t height) { @@ -120,7 +121,7 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char MoMdepth = 0; } //if ( matched != 0 ) global independent states -> inside *sp - komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height);//,MoM,MoMdepth); + komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height,MoM,MoMdepth); } else if ( func == 'U' ) // deprecated { @@ -265,7 +266,7 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long memset(&MoM,0,sizeof(MoM)); MoMdepth = 0; } - komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height);//,MoM,MoMdepth); + komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height,MoM,MoMdepth); } else if ( func == 'U' ) // deprecated { @@ -349,13 +350,14 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long return(-1); } -void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout)//,uint256 MoM,int32_t MoMdepth) +void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth) { static FILE *fp; static int32_t errs,didinit; static uint256 zero; struct komodo_state *sp; char fname[512],symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; int32_t retval,ht,func; uint8_t num,pubkeys[64][33]; if ( didinit == 0 ) { portable_mutex_init(&KOMODO_KV_mutex); + portable_mutex_init(&KOMODO_CC_mutex); didinit = 1; } if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) @@ -480,10 +482,9 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar //printf("ht.%d func N ht.%d errs.%d\n",height,NOTARIZED_HEIGHT,errs); if ( sp != 0 ) { - //if ( sp->MoMdepth > 0 && sp->MoM != zero ) - // fputc('M',fp); - //else - fputc('N',fp); + if ( sp->MoMdepth > 0 && sp->MoM != zero ) + fputc('M',fp); + else fputc('N',fp); if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) errs++; if ( fwrite(&sp->NOTARIZED_HEIGHT,1,sizeof(sp->NOTARIZED_HEIGHT),fp) != sizeof(sp->NOTARIZED_HEIGHT) ) @@ -492,24 +493,49 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar errs++; if ( fwrite(&sp->NOTARIZED_DESTTXID,1,sizeof(sp->NOTARIZED_DESTTXID),fp) != sizeof(sp->NOTARIZED_DESTTXID) ) errs++; - /*if ( sp->MoMdepth > 0 && sp->MoM != zero ) + if ( sp->MoMdepth > 0 && sp->MoM != zero ) { if ( fwrite(&sp->MoM,1,sizeof(sp->MoM),fp) != sizeof(sp->MoM) ) errs++; if ( fwrite(&sp->MoMdepth,1,sizeof(sp->MoMdepth),fp) != sizeof(sp->MoMdepth) ) errs++; - }*/ - komodo_eventadd_notarized(sp,symbol,height,dest,sp->NOTARIZED_HASH,sp->NOTARIZED_DESTTXID,sp->NOTARIZED_HEIGHT);//,sp->MoM,sp->MoMdepth); + } + komodo_eventadd_notarized(sp,symbol,height,dest,sp->NOTARIZED_HASH,sp->NOTARIZED_DESTTXID,sp->NOTARIZED_HEIGHT,sp->MoM,sp->MoMdepth); } } fflush(fp); } } +int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height) +{ + static int32_t last_rewind; int32_t rewindtarget; CBlockIndex *pindex; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; + if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) + return(0); + if ( IsInitialBlockDownload() == 0 && ((pindex= mapBlockIndex[srchash]) == 0 || pindex->nHeight != notarized_height) ) + { + if ( sp->NOTARIZED_HEIGHT > 0 && sp->NOTARIZED_HEIGHT < notarized_height ) + rewindtarget = sp->NOTARIZED_HEIGHT - 1; + else if ( notarized_height > 101 ) + rewindtarget = notarized_height - 101; + else rewindtarget = 0; + if ( rewindtarget != 0 && rewindtarget > KOMODO_REWIND && rewindtarget > last_rewind ) + { + if ( last_rewind != 0 ) + { + //KOMODO_REWIND = rewindtarget; + fprintf(stderr,"%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n",ASSETCHAINS_SYMBOL,notarized_height,srchash.ToString().c_str(),sp->NOTARIZED_HEIGHT,rewindtarget); + } + last_rewind = rewindtarget; + } + return(0); + } else return(1); +} + int32_t komodo_voutupdate(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) { static uint256 zero; static FILE *signedfp; - int32_t opretlen,nid,k,len = 0; uint256 srchash,desttxid; uint8_t crypto777[33]; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; + int32_t opretlen,nid,offset,k,MoMdepth,matched,len = 0; uint256 MoM,srchash,desttxid; uint8_t crypto777[33]; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) return(-1); if ( scriptlen == 35 && scriptbuf[0] == 33 && scriptbuf[34] == 0xac ) @@ -556,6 +582,8 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr } if ( scriptbuf[len++] == 0x6a ) { + struct komodo_ccdata ccdata; struct komodo_ccdataMoMoM MoMoMdata; + int32_t validated = 0,nameoffset,opoffset = 0; if ( (opretlen= scriptbuf[len++]) == 0x4c ) opretlen = scriptbuf[len++]; else if ( opretlen == 0x4d ) @@ -563,96 +591,152 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr opretlen = scriptbuf[len++]; opretlen += (scriptbuf[len++] << 8); } - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - printf("[%s] notarized.%d notarizedht.%d sp.Nht %d sp.ht %d opretlen.%d (%c %c %c)\n",ASSETCHAINS_SYMBOL,notarized,*notarizedheightp,sp->NOTARIZED_HEIGHT,sp->CURRENT_HEIGHT,opretlen,scriptbuf[len+32*2+4],scriptbuf[len+32*2+4+1],scriptbuf[len+32*2+4+2]); - if ( j == 1 && opretlen >= 32*2+4 && strcmp(ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 ) + opoffset = len; + matched = 0; + if ( ASSETCHAINS_SYMBOL[0] == 0 ) { + if ( strcmp("KMD",(char *)&scriptbuf[len+32 * 2 + 4]) == 0 ) + matched = 1; + } + else + { + if ( strcmp(ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 ) + matched = 1; + } + offset = 32 * (1 + matched) + 4; + nameoffset = (int32_t)strlen((char *)&scriptbuf[len+offset]); + if ( nameoffset == 2 ) + nameoffset += 2; + else nameoffset++; + memset(&ccdata,0,sizeof(ccdata)); + strncpy(ccdata.symbol,(char *)&scriptbuf[len+offset],sizeof(ccdata.symbol)); + if ( j == 1 && opretlen >= len+offset-opoffset ) + { + memset(&MoMoMdata,0,sizeof(MoMoMdata)); + if ( matched == 0 && bitweight(signedmask) >= KOMODO_MINRATIFY ) + notarized = 1; + if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 ) + notarized = 1; + if ( 0 && opretlen != 149 ) + printf("[%s].%d (%s) matched.%d i.%d j.%d notarized.%d %llx opretlen.%d len.%d offset.%d opoffset.%d\n",ASSETCHAINS_SYMBOL,height,ccdata.symbol,matched,i,j,notarized,(long long)signedmask,opretlen,len,offset,opoffset); len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&srchash); len += iguana_rwnum(0,&scriptbuf[len],sizeof(*notarizedheightp),(uint8_t *)notarizedheightp); - len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid); - if ( strcmp("PIZZA",ASSETCHAINS_SYMBOL) == 0 && opretlen == 110 ) + if ( matched != 0 ) + len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid); + if ( matched != 0 ) + validated = komodo_validate_chain(srchash,*notarizedheightp); + else validated = 1; + if ( notarized != 0 && validated != 0 ) { - notarized = 1; - } - static int32_t last_rewind; - int32_t rewindtarget,validated = 0; - CBlockIndex *pindex;// - if ( IsInitialBlockDownload() == 0 && ((pindex= mapBlockIndex[srchash]) == 0 || pindex->nHeight != *notarizedheightp) ) - { - if ( sp->NOTARIZED_HEIGHT > 0 && sp->NOTARIZED_HEIGHT < *notarizedheightp ) - rewindtarget = sp->NOTARIZED_HEIGHT - 1; - else if ( *notarizedheightp > 101 ) - rewindtarget = *notarizedheightp - 101; - else rewindtarget = 0; - if ( rewindtarget != 0 && rewindtarget > KOMODO_REWIND && rewindtarget > last_rewind ) + //sp->NOTARIZED_HEIGHT = *notarizedheightp; + //sp->NOTARIZED_HASH = srchash; + //sp->NOTARIZED_DESTTXID = desttxid; + memset(&MoM,0,sizeof(MoM)); + MoMdepth = 0; + len += nameoffset; + ccdata.MoMdata.notarized_height = *notarizedheightp; + ccdata.MoMdata.height = height; + ccdata.MoMdata.txi = i; + //printf("nameoffset.%d len.%d + 36 %d vs opretlen.%d\n",nameoffset,len,len+36,opretlen); + if ( len+36-opoffset <= opretlen ) { - if ( last_rewind != 0 ) + len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&MoM); + len += iguana_rwnum(0,&scriptbuf[len],sizeof(MoMdepth),(uint8_t *)&MoMdepth); + ccdata.MoMdata.MoM = MoM; + ccdata.MoMdata.MoMdepth = MoMdepth; + if ( len+sizeof(ccdata.CCid)-opoffset <= opretlen ) { - //KOMODO_REWIND = rewindtarget; - fprintf(stderr,"%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n",ASSETCHAINS_SYMBOL,*notarizedheightp,srchash.ToString().c_str(),sp->NOTARIZED_HEIGHT,rewindtarget); + len += iguana_rwnum(0,&scriptbuf[len],sizeof(ccdata.CCid),(uint8_t *)&ccdata.CCid); + ccdata.len = sizeof(ccdata.CCid); + if ( ASSETCHAINS_SYMBOL[0] != 0 ) + { + // MoMoM, depth, numpairs, (notarization ht, MoMoM offset) + if ( len+48-opoffset <= opretlen && strcmp(ccdata.symbol,ASSETCHAINS_SYMBOL) == 0 ) + { + len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdstarti); + len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdendi); + len += iguana_rwbignum(0,&scriptbuf[len],sizeof(MoMoMdata.MoMoM),(uint8_t *)&MoMoMdata.MoMoM); + len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.MoMoMdepth); + len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.numpairs); + MoMoMdata.len += sizeof(MoMoMdata.MoMoM) + sizeof(uint32_t)*4; + if ( len+MoMoMdata.numpairs*8-opoffset == opretlen ) + { + MoMoMdata.pairs = (struct komodo_ccdatapair *)calloc(MoMoMdata.numpairs,sizeof(*MoMoMdata.pairs)); + for (k=0; k sp->NOTARIZED_HEIGHT && *notarizedheightp < height && validated != 0 ) - { - int32_t nameoffset = (int32_t)strlen(ASSETCHAINS_SYMBOL) + 1; - sp->NOTARIZED_HEIGHT = *notarizedheightp; - sp->NOTARIZED_HASH = srchash; - sp->NOTARIZED_DESTTXID = desttxid; - /*memset(&sp->MoM,0,sizeof(sp->MoM)); - sp->MoMdepth = 0; - if ( len+36 <= opretlen ) - { - len += iguana_rwbignum(0,&scriptbuf[len+nameoffset],32,(uint8_t *)&sp->MoM); - len += iguana_rwnum(0,&scriptbuf[len+nameoffset],sizeof(sp->MoMdepth),(uint8_t *)&sp->MoMdepth); - if ( sp->MoM == zero || sp->MoMdepth > 1440 || sp->MoMdepth < 0 ) + if ( MoM == zero || MoMdepth > *notarizedheightp || MoMdepth < 0 ) { - memset(&sp->MoM,0,sizeof(sp->MoM)); - sp->MoMdepth = 0; + memset(&MoM,0,sizeof(MoM)); + MoMdepth = 0; } else { - //printf("VALID %s MoM.%s [%d]\n",ASSETCHAINS_SYMBOL,sp->MoM.ToString().c_str(),sp->MoMdepth); + komodo_rwccdata(ASSETCHAINS_SYMBOL,1,&ccdata,&MoMoMdata); + if ( matched != 0 ) + printf("[%s] matched.%d VALID (%s) MoM.%s [%d]\n",ASSETCHAINS_SYMBOL,matched,ccdata.symbol,MoM.ToString().c_str(),MoMdepth); } - }*/ - komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0);//,sp->MoM,sp->MoMdepth); - len += nameoffset; - //if ( ASSETCHAINS_SYMBOL[0] != 0 ) - // printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + if ( MoMoMdata.pairs != 0 ) + free(MoMoMdata.pairs); + memset(&ccdata,0,sizeof(ccdata)); + memset(&MoMoMdata,0,sizeof(MoMoMdata)); + } + else if ( ASSETCHAINS_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 ) + komodo_rwccdata((char *)"KMD",1,&ccdata,0); + if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height ) { - if ( signedfp == 0 ) + sp->NOTARIZED_HEIGHT = *notarizedheightp; + sp->NOTARIZED_HASH = srchash; + sp->NOTARIZED_DESTTXID = desttxid; + if ( MoM != zero && MoMdepth > 0 ) { - char fname[512]; - komodo_statefname(fname,ASSETCHAINS_SYMBOL,(char *)"signedmasks"); - if ( (signedfp= fopen(fname,"rb+")) == 0 ) - signedfp = fopen(fname,"wb"); - else fseek(signedfp,0,SEEK_END); + sp->MoM = MoM; + sp->MoMdepth = MoMdepth; } - if ( signedfp != 0 ) + komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth); + if ( ASSETCHAINS_SYMBOL[0] != 0 ) + printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); + if ( ASSETCHAINS_SYMBOL[0] == 0 ) { - fwrite(&height,1,sizeof(height),signedfp); - fwrite(&signedmask,1,sizeof(signedmask),signedfp); - fflush(signedfp); - } - if ( opretlen > len && scriptbuf[len] == 'A' ) - { - //for (i=0; i len && scriptbuf[len] == 'A' ) + { + //for (i=0; iNOTARIZED_HEIGHT ) - printf("validated.%d notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s (%s) len.%d opretlen.%d\n",validated,notarized,(long long)signedmask,height,*notarizedheightp,sp->NOTARIZED_HEIGHT,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),desttxid.ToString().c_str(),(char *)&scriptbuf[len],len,opretlen); + } else if ( opretlen != 149 && height > 600000 && matched != 0 ) + printf("%s validated.%d notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s len.%d opretlen.%d\n",ccdata.symbol,validated,notarized,(long long)signedmask,height,*notarizedheightp,sp->NOTARIZED_HEIGHT,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),desttxid.ToString().c_str(),len,opretlen); } - else if ( i == 0 && j == 1 && opretlen == 149 ) + else if ( matched != 0 && i == 0 && j == 1 && opretlen == 149 ) { if ( notaryid >= 0 && notaryid < 64 ) komodo_paxpricefeed(height,&scriptbuf[len],opretlen); } - else + else if ( matched != 0 ) { //int32_t k; for (k=0; knHeight != hwmheight ) + { printf("%s hwmheight.%d vs pindex->nHeight.%d t.%u reorg.%d\n",ASSETCHAINS_SYMBOL,hwmheight,pindex->nHeight,(uint32_t)pindex->nTime,hwmheight-pindex->nHeight); + komodo_purge_ccdata((int32_t)pindex->nHeight); + hwmheight = pindex->nHeight; + } komodo_event_rewind(sp,symbol,pindex->nHeight); - komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0);//,zero,0); + komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0,zero,0); } komodo_currentheight_set(chainActive.Tip()->nHeight); if ( pindex != 0 ) @@ -861,7 +949,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( ((signedmask & 1) != 0 && numvalid >= KOMODO_MINRATIFY) || bitweight(signedmask) > (numnotaries/3) ) { memset(&txhash,0,sizeof(txhash)); - komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0);//,zero,0); + komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0,zero,0); printf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,height); } else printf("signedmask.%llx numvalid.%d wt.%d numnotaries.%d\n",(long long)signedmask,numvalid,bitweight(signedmask),numnotaries); } @@ -870,7 +958,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( NOTARY_PUBKEY33[0] != 0 && ASSETCHAINS_SYMBOL[0] == 0 ) printf("%s ht.%d\n",ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL,height); if ( pindex->nHeight == hwmheight ) - komodo_stateupdate(height,0,0,0,zero,0,0,0,0,height,(uint32_t)pindex->nTime,0,0,0,0);//,zero,0); + komodo_stateupdate(height,0,0,0,zero,0,0,0,0,height,(uint32_t)pindex->nTime,0,0,0,0,zero,0); } else fprintf(stderr,"komodo_connectblock: unexpected null pindex\n"); //KOMODO_INITDONE = (uint32_t)time(NULL); //fprintf(stderr,"%s end connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight); diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index a7142de10..c434e33a3 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -411,7 +411,7 @@ int32_t komodo_verifynotarizedscript(int32_t height,uint8_t *script,int32_t len, for (i=0; i<32; i++) ((uint8_t *)&hash)[i] = script[2+i]; if ( hash == NOTARIZED_HASH ) - return(0); + return(1); for (i=0; i<32; i++) printf("%02x",((uint8_t *)&NOTARIZED_HASH)[i]); printf(" notarized, "); @@ -504,7 +504,7 @@ int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t uint256 hash; char params[128],*hexstr,*jsonstr; cJSON *result; int32_t i; uint8_t revbuf[32]; memset(&hash,0,sizeof(hash)); sprintf(params,"[%d]",height); - if ( (jsonstr= komodo_issuemethod(KMDUSERPASS,(char *)"getblockhash",params,BITCOIND_PORT)) != 0 ) + if ( (jsonstr= komodo_issuemethod(KMDUSERPASS,(char *)"getblockhash",params,BITCOIND_RPCPORT)) != 0 ) { if ( (result= cJSON_Parse(jsonstr)) != 0 ) { @@ -592,7 +592,6 @@ void komodo_disconnect(CBlockIndex *pindex,CBlock& block) } else printf("komodo_disconnect: ht.%d cant get komodo_state.(%s)\n",pindex->nHeight,ASSETCHAINS_SYMBOL); } - int32_t komodo_is_notarytx(const CTransaction& tx) { uint8_t *ptr; static uint8_t crypto777[33]; @@ -729,45 +728,45 @@ uint32_t komodo_heightstamp(int32_t height) } /*void komodo_pindex_init(CBlockIndex *pindex,int32_t height) gets data corrupted - { - int32_t i,num; uint8_t pubkeys[64][33]; CBlock block; - if ( pindex->didinit != 0 ) - return; - //printf("pindex.%d komodo_pindex_init notary.%d from height.%d\n",pindex->nHeight,pindex->notaryid,height); - if ( pindex->didinit == 0 ) - { - pindex->notaryid = -1; - if ( KOMODO_LOADINGBLOCKS == 0 ) - memset(pindex->pubkey33,0xff,33); - else memset(pindex->pubkey33,0,33); - if ( komodo_blockload(block,pindex) == 0 ) - { - komodo_block2pubkey33(pindex->pubkey33,&block); - //for (i=0; i<33; i++) - // fprintf(stderr,"%02x",pindex->pubkey33[i]); - //fprintf(stderr," set pubkey at height %d/%d\n",pindex->nHeight,height); - //if ( pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3 ) - // pindex->didinit = (KOMODO_LOADINGBLOCKS == 0); - } // else fprintf(stderr,"error loading block at %d/%d",pindex->nHeight,height); - } - if ( pindex->didinit != 0 && pindex->nHeight >= 0 && (num= komodo_notaries(pubkeys,(int32_t)pindex->nHeight,(uint32_t)pindex->nTime)) > 0 ) - { - for (i=0; ipubkey33,33) == 0 ) - { - pindex->notaryid = i; - break; - } - } - if ( 0 && i == num ) - { - for (i=0; i<33; i++) - fprintf(stderr,"%02x",pindex->pubkey33[i]); - fprintf(stderr," unmatched pubkey at height %d/%d\n",pindex->nHeight,height); - } - } - }*/ +{ + int32_t i,num; uint8_t pubkeys[64][33]; CBlock block; + if ( pindex->didinit != 0 ) + return; + //printf("pindex.%d komodo_pindex_init notary.%d from height.%d\n",pindex->nHeight,pindex->notaryid,height); + if ( pindex->didinit == 0 ) + { + pindex->notaryid = -1; + if ( KOMODO_LOADINGBLOCKS == 0 ) + memset(pindex->pubkey33,0xff,33); + else memset(pindex->pubkey33,0,33); + if ( komodo_blockload(block,pindex) == 0 ) + { + komodo_block2pubkey33(pindex->pubkey33,&block); + //for (i=0; i<33; i++) + // fprintf(stderr,"%02x",pindex->pubkey33[i]); + //fprintf(stderr," set pubkey at height %d/%d\n",pindex->nHeight,height); + //if ( pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3 ) + // pindex->didinit = (KOMODO_LOADINGBLOCKS == 0); + } // else fprintf(stderr,"error loading block at %d/%d",pindex->nHeight,height); + } + if ( pindex->didinit != 0 && pindex->nHeight >= 0 && (num= komodo_notaries(pubkeys,(int32_t)pindex->nHeight,(uint32_t)pindex->nTime)) > 0 ) + { + for (i=0; ipubkey33,33) == 0 ) + { + pindex->notaryid = i; + break; + } + } + if ( 0 && i == num ) + { + for (i=0; i<33; i++) + fprintf(stderr,"%02x",pindex->pubkey33[i]); + fprintf(stderr," unmatched pubkey at height %d/%d\n",pindex->nHeight,height); + } + } +}*/ void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) { @@ -781,32 +780,32 @@ void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) } /*int8_t komodo_minerid(int32_t height,uint8_t *destpubkey33) - { - int32_t num,i,numnotaries; CBlockIndex *pindex; uint32_t timestamp=0; uint8_t pubkey33[33],pubkeys[64][33]; - if ( (pindex= chainActive[height]) != 0 ) - { - if ( pindex->didinit != 0 ) - { - if ( destpubkey33 != 0 ) - memcpy(destpubkey33,pindex->pubkey33,33); - return(pindex->notaryid); - } - komodo_index2pubkey33(pubkey33,pindex,height); - if ( destpubkey33 != 0 ) - memcpy(destpubkey33,pindex->pubkey33,33); - if ( pindex->didinit != 0 ) - return(pindex->notaryid); - timestamp = pindex->GetBlockTime(); - if ( (num= komodo_notaries(pubkeys,height,timestamp)) > 0 ) - { - for (i=0; ididinit != 0 ) + { + if ( destpubkey33 != 0 ) + memcpy(destpubkey33,pindex->pubkey33,33); + return(pindex->notaryid); + } + komodo_index2pubkey33(pubkey33,pindex,height); + if ( destpubkey33 != 0 ) + memcpy(destpubkey33,pindex->pubkey33,33); + if ( pindex->didinit != 0 ) + return(pindex->notaryid); + timestamp = pindex->GetBlockTime(); + if ( (num= komodo_notaries(pubkeys,height,timestamp)) > 0 ) + { + for (i=0; i 807000 ) return(-2); } @@ -912,7 +925,7 @@ int32_t komodo_is_special(uint8_t pubkeys[66][33],int32_t mids[66],uint32_t bloc return(0); } -/*int32_t komodo_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) +int32_t komodo_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) { int32_t depth,notarized_ht; uint256 MoM,kmdtxid; depth = komodo_MoMdata(¬arized_ht,&MoM,&kmdtxid,nHeight,MoMoMp,MoMoMoffsetp,MoMoMdepthp,kmdstartip,kmdendip); @@ -926,7 +939,7 @@ int32_t komodo_is_special(uint8_t pubkeys[66][33],int32_t mids[66],uint32_t bloc *kmdtxidp = kmdtxid; } return(depth); -}*/ +} int32_t komodo_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 hash) { @@ -950,7 +963,7 @@ int32_t komodo_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 has fprintf(stderr,"[%s] nHeight.%d == NOTARIZED_HEIGHT.%d, diff hash\n",ASSETCHAINS_SYMBOL,nHeight,notarized_height); return(-1); } - } else fprintf(stderr,"[%s] unexpected error notary_hash %s ht.%d at ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,notary->nHeight); + } //else fprintf(stderr,"[%s] unexpected error notary_hash %s ht.%d at ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,notary->nHeight); } //else if ( notarized_height > 0 && notarized_height != 73880 && notarized_height >= 170000 ) // fprintf(stderr,"[%s] couldnt find notarized.(%s %d) ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,pindex->nHeight); @@ -1020,22 +1033,21 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_ { if ( txheight < 247205 ) cmptime -= 16000; - if ( (int64_t)tx.nLockTime < cmptime-3600 ) + if ( (int64_t)tx.nLockTime < cmptime-KOMODO_MAXMEMPOOLTIME ) { - if ( tx.nLockTime != 1477258935 || dispflag != 0 ) + if ( tx.nLockTime != 1477258935 && dispflag != 0 ) { - fprintf(stderr,"komodo_validate_interest.%d reject.%d [%d] locktime %u cmp2.%u\n",dispflag,txheight,(int32_t)(tx.nLockTime - (cmptime-3600)),(uint32_t)tx.nLockTime,cmptime); + fprintf(stderr,"komodo_validate_interest.%d reject.%d [%d] locktime %u cmp2.%u\n",dispflag,txheight,(int32_t)(tx.nLockTime - (cmptime-KOMODO_MAXMEMPOOLTIME)),(uint32_t)tx.nLockTime,cmptime); } return(-1); } if ( 0 && dispflag != 0 ) - fprintf(stderr,"validateinterest.%d accept.%d [%d] locktime %u cmp2.%u\n",dispflag,(int32_t)txheight,(int32_t)(tx.nLockTime - (cmptime-3600)),(int32_t)tx.nLockTime,cmptime); + fprintf(stderr,"validateinterest.%d accept.%d [%d] locktime %u cmp2.%u\n",dispflag,(int32_t)txheight,(int32_t)(tx.nLockTime - (cmptime-KOMODO_MAXMEMPOOLTIME)),(int32_t)tx.nLockTime,cmptime); } } return(0); } - /* komodo_checkPOW (fast) is called early in the process and should only refer to data immediately available. it is a filter to prevent bad blocks from going into the local DB. The more blocks we can filter out at this stage, the less junk in the local DB that will just get purged later on. @@ -1072,12 +1084,12 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh { CBlockIndex *pindex; uint8_t hashbuf[128]; char address[64]; bits256 addrhash; arith_uint256 hashval; uint256 hash,pasthash; int64_t diff=0; int32_t segid,minage,i,iter=0; uint32_t txtime,winner = 0; uint64_t value,coinage,supply = ASSETCHAINS_SUPPLY + nHeight*ASSETCHAINS_REWARD/SATOSHIDEN; txtime = komodo_txtime(&value,txid,vout,address); + if ( blocktime < prevtime+57 ) + blocktime = prevtime+57; if ( value == 0 || txtime == 0 || blocktime == 0 || prevtime == 0 ) return(0); if ( (minage= nHeight*3) > 6000 ) minage = 6000; - if ( blocktime < prevtime+57 ) - blocktime = prevtime+57; if ( blocktime > txtime+minage && (pindex= komodo_chainactive(nHeight>200?nHeight-200:1)) != 0 ) { vcalc_sha256(0,(uint8_t *)&addrhash,(uint8_t *)address,(int32_t)strlen(address)); @@ -1175,15 +1187,15 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he { bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256((goalperc) * (goalperc)); /*if ( height > 1165 ) - { - if ( height > 1180 ) - { - if ( height > 1230 ) - bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256((goalperc) * (goalperc)); - else bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc); - } - else bnTarget = (ave * arith_uint256(goalperc * goalperc)) / arith_uint256(2 * (percPoS + goalperc) * (percPoS + goalperc)); - } else bnTarget = (ave * arith_uint256(goalperc)) / arith_uint256(percPoS + goalperc);*/ + { + if ( height > 1180 ) + { + if ( height > 1230 ) + bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256((goalperc) * (goalperc)); + else bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc); + } + else bnTarget = (ave * arith_uint256(goalperc * goalperc)) / arith_uint256(2 * (percPoS + goalperc) * (percPoS + goalperc)); + } else bnTarget = (ave * arith_uint256(goalperc)) / arith_uint256(percPoS + goalperc);*/ if ( 1 ) { for (i=31; i>=24; i--) @@ -1344,4 +1356,3 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) else return(0); } - diff --git a/src/komodo_cJSON.c b/src/komodo_cJSON.c index ca2c6517c..8569b7802 100755 --- a/src/komodo_cJSON.c +++ b/src/komodo_cJSON.c @@ -56,7 +56,7 @@ static int32_t cJSON_strcasecmp(const char *s1,const char *s2) // the following written by jl777 /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/src/komodo_ccdata.h b/src/komodo_ccdata.h new file mode 100644 index 000000000..058e38cee --- /dev/null +++ b/src/komodo_ccdata.h @@ -0,0 +1,295 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef H_KOMODOCCDATA_H +#define H_KOMODOCCDATA_H + +struct komodo_ccdata *CC_data; +int32_t CC_firstheight; + +bits256 iguana_merkle(bits256 *tree,int32_t txn_count) +{ + int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; + if ( txn_count == 1 ) + return(tree[0]); + prev = 0; + while ( txn_count > 1 ) + { + if ( (txn_count & 1) != 0 ) + tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; + n += txn_count; + for (i=0; i> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized)); + } + prev = n; + txn_count >>= 1; + } + return(tree[n]); +} + +uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth) +{ + static uint256 zero; bits256 MoM,*tree; CBlockIndex *pindex; int32_t i; + if ( MoMdepth >= height ) + return(zero); + tree = (bits256 *)calloc(MoMdepth * 3,sizeof(*tree)); + for (i=0; ihashMerkleRoot,sizeof(bits256)); + else + { + free(tree); + return(zero); + } + } + MoM = iguana_merkle(tree,MoMdepth); + free(tree); + return(*(uint256 *)&MoM); +} + +struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi) +{ + struct komodo_ccdata_entry *allMoMs=0; bits256 *tree,tmp; struct komodo_ccdata *ccdata,*tmpptr; int32_t i,num,max; + num = max = 0; + portable_mutex_lock(&KOMODO_CC_mutex); + DL_FOREACH_SAFE(CC_data,ccdata,tmpptr) + { + if ( ccdata->MoMdata.height <= kmdendi && ccdata->MoMdata.height >= kmdstarti ) + { + if ( num >= max ) + { + max += 100; + allMoMs = (struct komodo_ccdata_entry *)realloc(allMoMs,max * sizeof(*allMoMs)); + } + allMoMs[num].MoM = ccdata->MoMdata.MoM; + allMoMs[num].notarized_height = ccdata->MoMdata.notarized_height; + allMoMs[num].kmdheight = ccdata->MoMdata.height; + allMoMs[num].txi = ccdata->MoMdata.txi; + strcpy(allMoMs[num].symbol,ccdata->symbol); + num++; + } + if ( ccdata->MoMdata.height < kmdstarti ) + break; + } + portable_mutex_unlock(&KOMODO_CC_mutex); + if ( (*nump= num) > 0 ) + { + tree = (bits256 *)calloc(sizeof(bits256),num*3); + for (i=0; i= 0) { + if ( mdata->numpairs >= maxpairs ) + { + maxpairs += 100; + mdata->pairs = (struct komodo_ccdatapair *)realloc(mdata->pairs,sizeof(*mdata->pairs)*maxpairs); + //fprintf(stderr,"pairs reallocated to %p num.%d\n",mdata->pairs,mdata->numpairs); + } + } else { + fprintf(stderr,"komodo_addpair.maxpairs %d must be >= 0\n",(int32_t)maxpairs); + return(-1); + } + mdata->pairs[mdata->numpairs].notarized_height = notarized_height; + mdata->pairs[mdata->numpairs].MoMoMoffset = offset; + mdata->numpairs++; + return(maxpairs); +} + +int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height) +{ + uint8_t hexdata[8192]; struct komodo_ccdata *ccdata,*tmpptr; int32_t len,maxpairs,i,retval=-1,depth,starti,endi,CCid=0; struct komodo_ccdata_entry *allMoMs; + starti = endi = depth = len = maxpairs = 0; + hexstr[0] = 0; + if ( sizeof(hexdata)*2+1 > hexsize ) + { + fprintf(stderr,"hexsize.%d too small for %d\n",hexsize,(int32_t)sizeof(hexdata)); + return(-1); + } + memset(mdata,0,sizeof(*mdata)); + portable_mutex_lock(&KOMODO_CC_mutex); + DL_FOREACH_SAFE(CC_data,ccdata,tmpptr) + { + if ( ccdata->MoMdata.height < kmdheight ) + { + //fprintf(stderr,"%s notarized.%d kmd.%d\n",ccdata->symbol,ccdata->MoMdata.notarized_height,ccdata->MoMdata.height); + if ( strcmp(ccdata->symbol,symbol) == 0 ) + { + if ( endi == 0 ) + { + endi = ccdata->MoMdata.height; + CCid = ccdata->CCid; + } + if ( (mdata->numpairs == 1 && notarized_height == 0) || ccdata->MoMdata.notarized_height <= notarized_height ) + { + starti = ccdata->MoMdata.height + 1; + if ( notarized_height == 0 ) + notarized_height = ccdata->MoMdata.notarized_height; + break; + } + } + starti = ccdata->MoMdata.height; + } + } + portable_mutex_unlock(&KOMODO_CC_mutex); + mdata->kmdstarti = starti; + mdata->kmdendi = endi; + if ( starti != 0 && endi != 0 && endi >= starti ) + { + if ( (allMoMs= komodo_allMoMs(&depth,&mdata->MoMoM,starti,endi)) != 0 ) + { + mdata->MoMoMdepth = depth; + for (i=0; inumpairs > 0 ) + { + len += iguana_rwnum(1,&hexdata[len],sizeof(CCid),(uint8_t *)&CCid); + len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->kmdstarti); + len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->kmdendi); + len += iguana_rwbignum(1,&hexdata[len],sizeof(mdata->MoMoM),(uint8_t *)&mdata->MoMoM); + len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->MoMoMdepth); + len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->numpairs); + for (i=0; inumpairs; i++) + { + if ( len + sizeof(uint32_t)*2 > sizeof(hexdata) ) + { + fprintf(stderr,"%s %d %d i.%d of %d exceeds hexdata.%d\n",symbol,kmdheight,notarized_height,i,mdata->numpairs,(int32_t)sizeof(hexdata)); + break; + } + len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->pairs[i].notarized_height); + len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->pairs[i].MoMoMoffset); + } + if ( i == mdata->numpairs && len*2+1 < hexsize ) + { + init_hexbytes_noT(hexstr,hexdata,len); + //fprintf(stderr,"hexstr.(%s)\n",hexstr); + retval = 0; + } else fprintf(stderr,"%s %d %d too much hexdata[%d] for hexstr[%d]\n",symbol,kmdheight,notarized_height,len,hexsize); + } + free(allMoMs); + } + } + return(retval); +} + +void komodo_purge_ccdata(int32_t height) +{ + struct komodo_ccdata *ccdata,*tmpptr; + if ( ASSETCHAINS_SYMBOL[0] == 0 ) + { + portable_mutex_lock(&KOMODO_CC_mutex); + DL_FOREACH_SAFE(CC_data,ccdata,tmpptr) + { + if ( ccdata->MoMdata.height >= height ) + { + printf("PURGE %s notarized.%d\n",ccdata->symbol,ccdata->MoMdata.notarized_height); + DL_DELETE(CC_data,ccdata); + free(ccdata); + } else break; + } + portable_mutex_unlock(&KOMODO_CC_mutex); + } + else + { + // purge notarized data + } +} + +// this is just a demo of ccdata processing to create example data for the MoMoM and allMoMs calls +int32_t komodo_rwccdata(char *thischain,int32_t rwflag,struct komodo_ccdata *ccdata,struct komodo_ccdataMoMoM *MoMoMdata) +{ + uint256 hash,zero; bits256 tmp; int32_t i,nonz; struct komodo_ccdata *ptr; struct notarized_checkpoint *np; + return(0); // disable this path as libscott method is much better + if ( rwflag == 0 ) + { + // load from disk + } + else + { + // write to disk + } + if ( ccdata->MoMdata.height > 0 && (CC_firstheight == 0 || ccdata->MoMdata.height < CC_firstheight) ) + CC_firstheight = ccdata->MoMdata.height; + for (nonz=i=0; i<32; i++) + { + if ( (tmp.bytes[i]= ((uint8_t *)&ccdata->MoMdata.MoM)[31-i]) != 0 ) + nonz++; + } + if ( nonz == 0 ) + return(0); + memcpy(&hash,&tmp,sizeof(hash)); + //fprintf(stderr,"[%s] ccdata.%s id.%d notarized_ht.%d MoM.%s height.%d/t%d\n",ASSETCHAINS_SYMBOL,ccdata->symbol,ccdata->CCid,ccdata->MoMdata.notarized_height,hash.ToString().c_str(),ccdata->MoMdata.height,ccdata->MoMdata.txi); + if ( ASSETCHAINS_SYMBOL[0] == 0 ) + { + if ( CC_data != 0 && (CC_data->MoMdata.height > ccdata->MoMdata.height || (CC_data->MoMdata.height == ccdata->MoMdata.height && CC_data->MoMdata.txi >= ccdata->MoMdata.txi)) ) + { + printf("out of order detected? SKIP CC_data ht.%d/txi.%d vs ht.%d/txi.%d\n",CC_data->MoMdata.height,CC_data->MoMdata.txi,ccdata->MoMdata.height,ccdata->MoMdata.txi); + } + else + { + ptr = (struct komodo_ccdata *)calloc(1,sizeof(*ptr)); + *ptr = *ccdata; + portable_mutex_lock(&KOMODO_CC_mutex); + DL_PREPEND(CC_data,ptr); + portable_mutex_unlock(&KOMODO_CC_mutex); + } + } + else + { + if ( MoMoMdata != 0 && MoMoMdata->pairs != 0 ) + { + for (i=0; inumpairs; i++) + { + if ( (np= komodo_npptr(MoMoMdata->pairs[i].notarized_height)) != 0 ) + { + memset(&zero,0,sizeof(zero)); + if ( memcmp(&np->MoMoM,&zero,sizeof(np->MoMoM)) == 0 ) + { + np->MoMoM = MoMoMdata->MoMoM; + np->MoMoMdepth = MoMoMdata->MoMoMdepth; + np->MoMoMoffset = MoMoMdata->MoMoMoffset; + np->kmdstarti = MoMoMdata->kmdstarti; + np->kmdendi = MoMoMdata->kmdendi; + } + else if ( memcmp(&np->MoMoM,&MoMoMdata->MoMoM,sizeof(np->MoMoM)) != 0 || np->MoMoMdepth != MoMoMdata->MoMoMdepth || np->MoMoMoffset != MoMoMdata->MoMoMoffset || np->kmdstarti != MoMoMdata->kmdstarti || np->kmdendi != MoMoMdata->kmdendi ) + { + fprintf(stderr,"preexisting MoMoM mismatch: %s (%d %d %d %d) vs %s (%d %d %d %d)\n",np->MoMoM.ToString().c_str(),np->MoMoMdepth,np->MoMoMoffset,np->kmdstarti,np->kmdendi,MoMoMdata->MoMoM.ToString().c_str(),MoMoMdata->MoMoMdepth,MoMoMdata->MoMoMoffset,MoMoMdata->kmdstarti,MoMoMdata->kmdendi); + } + } + } + } + } + return(1); +} + +#endif diff --git a/src/komodo_curve25519.h b/src/komodo_curve25519.h index a7283e265..90d9a7e00 100644 --- a/src/komodo_curve25519.h +++ b/src/komodo_curve25519.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 6cd297c49..1d7351638 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -5,6 +5,8 @@ #define KOMODO_ELECTION_GAP 2000 #define ROUNDROBIN_DELAY 61 #define KOMODO_ASSETCHAIN_MAXLEN 65 -#define KOMODO_MAXMEMPOOLTIME 3600 +#define KOMODO_LIMITED_NETWORKSIZE 4 +#define KOMODO_MAXMEMPOOLTIME 3600 // affects consensus +#define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9" #endif diff --git a/src/komodo_events.h b/src/komodo_events.h index 219d6e479..d3eab4902 100644 --- a/src/komodo_events.h +++ b/src/komodo_events.h @@ -37,28 +37,29 @@ struct komodo_event *komodo_eventadd(struct komodo_state *sp,int32_t height,char return(ep); } -void komodo_eventadd_notarized(struct komodo_state *sp,char *symbol,int32_t height,char *dest,uint256 notarized_hash,uint256 notarized_desttxid,int32_t notarizedheight)//,uint256 MoM,int32_t MoMdepth) +void komodo_eventadd_notarized(struct komodo_state *sp,char *symbol,int32_t height,char *dest,uint256 notarized_hash,uint256 notarized_desttxid,int32_t notarizedheight,uint256 MoM,int32_t MoMdepth) { - struct komodo_event_notarized N; - if ( NOTARY_PUBKEY33[0] != 0 && komodo_verifynotarization(symbol,dest,height,notarizedheight,notarized_hash,notarized_desttxid) != 0 ) + static uint32_t counter; int32_t verified=0; char *coin; struct komodo_event_notarized N; + coin = (ASSETCHAINS_SYMBOL[0] == 0) ? (char *)"KMD" : ASSETCHAINS_SYMBOL; + if ( (ASSETCHAINS_SYMBOL[0] == 0 && height > 814000) && NOTARY_PUBKEY33[0] != 0 && (verified= komodo_verifynotarization(symbol,dest,height,notarizedheight,notarized_hash,notarized_desttxid)) < 0 ) { - if ( height > 50000 || ASSETCHAINS_SYMBOL[0] != 0 ) + if ( ASSETCHAINS_SYMBOL[0] == 0 && height > 814000 && counter++ < 10 ) printf("[%s] error validating notarization ht.%d notarized_height.%d, if on a pruned %s node this can be ignored\n",ASSETCHAINS_SYMBOL,height,notarizedheight,dest); } - else + else if ( strcmp(symbol,coin) == 0 ) { - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - fprintf(stderr,"validated [%s] ht.%d notarized %d\n",ASSETCHAINS_SYMBOL,height,notarizedheight); + if ( 0 && NOTARY_PUBKEY33[0] != 0 && verified != 0 ) + fprintf(stderr,"validated [%s] ht.%d notarized %d\n",coin,height,notarizedheight); memset(&N,0,sizeof(N)); N.blockhash = notarized_hash; N.desttxid = notarized_desttxid; N.notarizedheight = notarizedheight; - //N.MoM = MoM; - //N.MoMdepth = MoMdepth; + N.MoM = MoM; + N.MoMdepth = MoMdepth; strncpy(N.dest,dest,sizeof(N.dest)-1); komodo_eventadd(sp,height,symbol,KOMODO_EVENT_NOTARIZED,(uint8_t *)&N,sizeof(N)); if ( sp != 0 ) - komodo_notarized_update(sp,height,notarizedheight,notarized_hash,notarized_desttxid);//,MoM,MoMdepth); + komodo_notarized_update(sp,height,notarizedheight,notarized_hash,notarized_desttxid,MoM,MoMdepth); } } diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 5897484e5..410e106ae 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -688,7 +688,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim } } n = block.vtx[0].vout.size(); - script = (uint8_t *)block.vtx[0].vout[n-1].scriptPubKey.data(); + //script = (uint8_t *)block.vtx[0].vout[n-1].scriptPubKey.data(); //if ( n <= 2 || script[0] != 0x6a ) { int64_t val,prevtotal = 0; int32_t strangeout=0,overflow = 0; @@ -1349,9 +1349,11 @@ int32_t komodo_faststateinit(struct komodo_state *sp,char *fname,char *symbol,ch return(-1); } +uint64_t komodo_interestsum(); + void komodo_passport_iteration() { - static long lastpos[34]; static char userpass[33][1024]; static uint32_t lasttime,callcounter; + static long lastpos[34]; static char userpass[33][1024]; static uint32_t lasttime,callcounter,lastinterest; int32_t maxseconds = 10; FILE *fp; uint8_t *filedata; long fpos,datalen,lastfpos; int32_t baseid,limit,n,ht,isrealtime,expired,refid,blocks,longest; struct komodo_state *sp,*refsp; char *retstr,fname[512],*base,symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t buf[3],starttime; cJSON *infoobj,*result; uint64_t RTmask = 0; expired = 0; @@ -1360,6 +1362,12 @@ void komodo_passport_iteration() fprintf(stderr,"[%s] PASSPORT iteration waiting for KOMODO_INITDONE\n",ASSETCHAINS_SYMBOL); sleep(3); } + if ( komodo_chainactive_timestamp() > lastinterest ) + { + komodo_interestsum(); + komodo_longestchain(); + lastinterest = komodo_chainactive_timestamp(); + } refsp = komodo_stateptr(symbol,dest); if ( ASSETCHAINS_SYMBOL[0] == 0 ) { @@ -1486,12 +1494,12 @@ void komodo_passport_iteration() if ( sp != 0 && isrealtime == 0 ) refsp->RTbufs[0][2] = 0; } - komodo_paxtotal(); + //komodo_paxtotal(); // calls komodo_isrealtime(), which calls komodo_longestchain() refsp->RTmask |= RTmask; if ( expired == 0 && KOMODO_PASSPORT_INITDONE == 0 ) { KOMODO_PASSPORT_INITDONE = 1; - printf("READY for RPC calls at %u! done PASSPORT %s refid.%d\n",(uint32_t)time(NULL),ASSETCHAINS_SYMBOL,refid); + printf("READY for %s RPC calls at %u! done PASSPORT %s refid.%d\n",ASSETCHAINS_SYMBOL,(uint32_t)time(NULL),ASSETCHAINS_SYMBOL,refid); } } diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 8a2f87918..342d28fe8 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -15,8 +15,9 @@ #include "komodo_defs.h" +void komodo_prefetch(FILE *fp); uint32_t komodo_heightstamp(int32_t height); -void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout); +void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); void komodo_init(int32_t height); int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); @@ -45,19 +46,22 @@ struct komodo_state KOMODO_STATES[34]; int COINBASE_MATURITY = _COINBASE_MATURITY;//100; int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND; -int32_t KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE=1,ASSETCHAINS_CC; +int32_t KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE = 1; std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY; uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33]; char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096]; -uint16_t ASSETCHAINS_PORT; -uint32_t ASSETCHAIN_INIT; +uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; +uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC; uint32_t ASSETCHAINS_MAGIC = 2387029918; +uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY = 10; uint32_t KOMODO_INITDONE; -char KMDUSERPASS[4096],BTCUSERPASS[4096]; uint16_t KMD_PORT = 7771,BITCOIND_PORT = 7771; +char KMDUSERPASS[4096],BTCUSERPASS[4096]; uint16_t KMD_PORT = 7771,BITCOIND_RPCPORT = 7771; uint64_t PENDING_KOMODO_TX; +extern int32_t KOMODO_LOADINGBLOCKS; +unsigned int MAX_BLOCK_SIGOPS = 20000; struct komodo_kv *KOMODO_KV; -pthread_mutex_t KOMODO_KV_mutex; +pthread_mutex_t KOMODO_KV_mutex,KOMODO_CC_mutex; diff --git a/src/komodo_interest.h b/src/komodo_interest.h index 581592566..3141532fa 100644 --- a/src/komodo_interest.h +++ b/src/komodo_interest.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -83,13 +83,13 @@ uint64_t komodo_moneysupply(int32_t height) uint64_t _komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime) { int32_t minutes; uint64_t interest = 0; - if ( nLockTime >= LOCKTIME_THRESHOLD && tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= 60 ) + if ( nLockTime >= LOCKTIME_THRESHOLD && tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= (KOMODO_MAXMEMPOOLTIME/60) ) { if ( minutes > 365 * 24 * 60 ) minutes = 365 * 24 * 60; if ( txheight >= 1000000 && minutes > 31 * 24 * 60 ) minutes = 31 * 24 * 60; - minutes -= 59; + minutes -= ((KOMODO_MAXMEMPOOLTIME/60) - 1); interest = ((nValue / 10512000) * minutes); } return(interest); diff --git a/src/komodo_jumblr.h b/src/komodo_jumblr.h index 951ed9de0..f36bb441a 100755 --- a/src/komodo_jumblr.h +++ b/src/komodo_jumblr.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -83,7 +83,7 @@ char *jumblr_importaddress(char *address) { char params[1024]; sprintf(params,"[\"%s\", \"%s\", false]",address,address); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"importaddress",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"importaddress",params,BITCOIND_RPCPORT)); } char *jumblr_validateaddress(char *addr) @@ -91,7 +91,7 @@ char *jumblr_validateaddress(char *addr) char params[1024]; sprintf(params,"[\"%s\"]",addr); printf("validateaddress.%s\n",params); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"validateaddress",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"validateaddress",params,BITCOIND_RPCPORT)); } int32_t Jumblr_secretaddrfind(char *searchaddr) @@ -222,28 +222,28 @@ char *jumblr_zgetnewaddress() { char params[1024]; sprintf(params,"[]"); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getnewaddress",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getnewaddress",params,BITCOIND_RPCPORT)); } char *jumblr_zlistoperationids() { char params[1024]; sprintf(params,"[]"); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listoperationids",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listoperationids",params,BITCOIND_RPCPORT)); } char *jumblr_zgetoperationresult(char *opid) { char params[1024]; sprintf(params,"[[\"%s\"]]",opid); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationresult",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationresult",params,BITCOIND_RPCPORT)); } char *jumblr_zgetoperationstatus(char *opid) { char params[1024]; sprintf(params,"[[\"%s\"]]",opid); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationstatus",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getoperationstatus",params,BITCOIND_RPCPORT)); } char *jumblr_sendt_to_z(char *taddr,char *zaddr,double amount) @@ -253,7 +253,7 @@ char *jumblr_sendt_to_z(char *taddr,char *zaddr,double amount) return(clonestr((char *)"{\"error\":\"illegal address in t to z\"}")); sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",taddr,zaddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); printf("t -> z: %s\n",params); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_RPCPORT)); } char *jumblr_sendz_to_z(char *zaddrS,char *zaddrD,double amount) @@ -264,7 +264,7 @@ char *jumblr_sendz_to_z(char *zaddrS,char *zaddrD,double amount) //sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddrS,zaddrD,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddrS,zaddrD,amount-fee-JUMBLR_TXFEE,JUMBLR_TXFEE); printf("z -> z: %s\n",params); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_RPCPORT)); } char *jumblr_sendz_to_t(char *zaddr,char *taddr,double amount) @@ -274,56 +274,56 @@ char *jumblr_sendz_to_t(char *zaddr,char *taddr,double amount) return(clonestr((char *)"{\"error\":\"illegal address in z to t\"}")); sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddr,taddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); printf("z -> t: %s\n",params); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_sendmany",params,BITCOIND_RPCPORT)); } char *jumblr_zlistaddresses() { char params[1024]; sprintf(params,"[]"); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listaddresses",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listaddresses",params,BITCOIND_RPCPORT)); } char *jumblr_zlistreceivedbyaddress(char *addr) { char params[1024]; sprintf(params,"[\"%s\", 1]",addr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listreceivedbyaddress",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_listreceivedbyaddress",params,BITCOIND_RPCPORT)); } char *jumblr_getreceivedbyaddress(char *addr) { char params[1024]; sprintf(params,"[\"%s\", 1]",addr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"getreceivedbyaddress",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"getreceivedbyaddress",params,BITCOIND_RPCPORT)); } char *jumblr_importprivkey(char *wifstr) { char params[1024]; sprintf(params,"[\"%s\", \"\", false]",wifstr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"importprivkey",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"importprivkey",params,BITCOIND_RPCPORT)); } char *jumblr_zgetbalance(char *addr) { char params[1024]; sprintf(params,"[\"%s\", 1]",addr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getbalance",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"z_getbalance",params,BITCOIND_RPCPORT)); } char *jumblr_listunspent(char *coinaddr) { char params[1024]; sprintf(params,"[1, 99999999, [\"%s\"]]",coinaddr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"listunspent",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"listunspent",params,BITCOIND_RPCPORT)); } char *jumblr_gettransaction(char *txidstr) { char params[1024]; sprintf(params,"[\"%s\", 1]",txidstr); - return(jumblr_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,BITCOIND_PORT)); + return(jumblr_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,BITCOIND_RPCPORT)); } int32_t jumblr_numvins(bits256 txid) diff --git a/src/komodo_kv.h b/src/komodo_kv.h index 7c20becb1..58d550414 100644 --- a/src/komodo_kv.h +++ b/src/komodo_kv.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/src/komodo_notary.h b/src/komodo_notary.h index 127a56329..25a03f83b 100644 --- a/src/komodo_notary.h +++ b/src/komodo_notary.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -142,7 +142,7 @@ const char *Notaries_elected1[][2] = {"artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, {"artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, {"badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, - {"badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, + {"badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, // 10 {"batman_AR", "033ecb640ec5852f42be24c3bf33ca123fb32ced134bed6aa2ba249cf31b0f2563" }, {"batman_SH", "02ca5898931181d0b8aafc75ef56fce9c43656c0b6c9f64306e7c8542f6207018c" }, {"ca333_EU", "03fc87b8c804f12a6bd18efd43b0ba2828e4e38834f6b44c0bfee19f966a12ba99" }, @@ -152,7 +152,7 @@ const char *Notaries_elected1[][2] = {"cipi_AR", "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, {"cipi_NA", "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, {"crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, - {"crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, + {"crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, // 20 {"dwy_EU", "0259c646288580221fdf0e92dbeecaee214504fdc8bbdf4a3019d6ec18b7540424" }, {"emmanux_SH", "033f316114d950497fc1d9348f03770cd420f14f662ab2db6172df44c389a2667a" }, {"etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, @@ -162,7 +162,7 @@ const char *Notaries_elected1[][2] = {"goldenman_EU", "02d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388d" }, {"indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, {"indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + {"indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, // 30 {"indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, {"jackson_AR", "038ff7cfe34cb13b524e0941d5cf710beca2ffb7e05ddf15ced7d4f14fbb0a6f69" }, {"jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, @@ -172,7 +172,7 @@ const char *Notaries_elected1[][2] = {"komodopioneers_SH", "033ace50aedf8df70035b962a805431363a61cc4e69d99d90726a2d48fb195f68c" }, {"libscott_SH", "03301a8248d41bc5dc926088a8cf31b65e2daf49eed7eb26af4fb03aae19682b95" }, {"lukechilds_AR", "031aa66313ee024bbee8c17915cf7d105656d0ace5b4a43a3ab5eae1e14ec02696" }, - {"madmax_AR", "03891555b4a4393d655bf76f0ad0fb74e5159a615b6925907678edc2aac5e06a75" }, + {"madmax_AR", "03891555b4a4393d655bf76f0ad0fb74e5159a615b6925907678edc2aac5e06a75" }, // 40 {"meshbits_AR", "02957fd48ae6cb361b8a28cdb1b8ccf5067ff68eb1f90cba7df5f7934ed8eb4b2c" }, {"meshbits_SH", "025c6e94877515dfd7b05682b9cc2fe4a49e076efe291e54fcec3add78183c1edb" }, {"metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, @@ -182,7 +182,7 @@ const char *Notaries_elected1[][2] = {"peer2cloud_AR", "034e5563cb885999ae1530bd66fab728e580016629e8377579493b386bf6cebb15" }, {"peer2cloud_SH", "03396ac453b3f23e20f30d4793c5b8ab6ded6993242df4f09fd91eb9a4f8aede84" }, {"polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, - {"hyper_AR", "020f2f984d522051bd5247b61b080b4374a7ab389d959408313e8062acad3266b4" }, + {"hyper_AR", "020f2f984d522051bd5247b61b080b4374a7ab389d959408313e8062acad3266b4" }, // 50 {"hyper_EU", "03d00cf9ceace209c59fb013e112a786ad583d7de5ca45b1e0df3b4023bb14bf51" }, {"hyper_SH", "0383d0b37f59f4ee5e3e98a47e461c861d49d0d90c80e9e16f7e63686a2dc071f3" }, {"hyper_NA", "03d91c43230336c0d4b769c9c940145a8c53168bf62e34d1bccd7f6cfc7e5592de" }, @@ -192,7 +192,7 @@ const char *Notaries_elected1[][2] = {"alien_EU", "020aab8308d4df375a846a9e3b1c7e99597b90497efa021d50bcf1bbba23246527" }, {"thegaltmines_NA", "031bea28bec98b6380958a493a703ddc3353d7b05eb452109a773eefd15a32e421" }, {"titomane_AR", "029d19215440d8cb9cc6c6b7a4744ae7fb9fb18d986e371b06aeb34b64845f9325" }, - {"titomane_EU", "0360b4805d885ff596f94312eed3e4e17cb56aa8077c6dd78d905f8de89da9499f" }, + {"titomane_EU", "0360b4805d885ff596f94312eed3e4e17cb56aa8077c6dd78d905f8de89da9499f" }, // 60 {"titomane_SH", "03573713c5b20c1e682a2e8c0f8437625b3530f278e705af9b6614de29277a435b" }, {"webworker01_NA", "03bb7d005e052779b1586f071834c5facbb83470094cff5112f0072b64989f97d7" }, {"xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, @@ -383,24 +383,8 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33, } //struct komodo_state *komodo_stateptr(char *symbol,char *dest); -int32_t komodo_notarized_height(uint256 *hashp,uint256 *txidp) -{ - char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; - if ( (sp= komodo_stateptr(symbol,dest)) != 0 ) - { - *hashp = sp->NOTARIZED_HASH; - *txidp = sp->NOTARIZED_DESTTXID; - return(sp->NOTARIZED_HEIGHT); - } - else - { - memset(hashp,0,sizeof(*hashp)); - memset(txidp,0,sizeof(*txidp)); - return(0); - } -} -/*struct notarized_checkpoint *komodo_npptr(int32_t height) +struct notarized_checkpoint *komodo_npptr(int32_t height) { char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; int32_t i; struct komodo_state *sp; struct notarized_checkpoint *np = 0; if ( (sp= komodo_stateptr(symbol,dest)) != 0 ) @@ -415,6 +399,41 @@ int32_t komodo_notarized_height(uint256 *hashp,uint256 *txidp) return(0); } +int32_t komodo_prevMoMheight() +{ + static uint256 zero; + char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; int32_t i; struct komodo_state *sp; struct notarized_checkpoint *np = 0; + if ( (sp= komodo_stateptr(symbol,dest)) != 0 ) + { + for (i=sp->NUM_NPOINTS-1; i>=0; i--) + { + np = &sp->NPOINTS[i]; + if ( np->MoM != zero ) + return(np->notarized_height); + } + } + return(0); +} + +int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp) +{ + char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; + if ( (sp= komodo_stateptr(symbol,dest)) != 0 ) + { + *hashp = sp->NOTARIZED_HASH; + *txidp = sp->NOTARIZED_DESTTXID; + *prevMoMheightp = komodo_prevMoMheight(); + return(sp->NOTARIZED_HEIGHT); + } + else + { + *prevMoMheightp = 0; + memset(hashp,0,sizeof(*hashp)); + memset(txidp,0,sizeof(*txidp)); + return(0); + } +} + int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t height,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) { struct notarized_checkpoint *np = 0; @@ -435,7 +454,7 @@ int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,in memset(MoMoMp,0,sizeof(*MoMoMp)); memset(kmdtxidp,0,sizeof(*kmdtxidp)); return(0); -}*/ +} int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp) { @@ -493,7 +512,7 @@ int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *n return(0); } -void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t notarized_height,uint256 notarized_hash,uint256 notarized_desttxid)//,uint256 MoM,int32_t MoMdepth) +void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t notarized_height,uint256 notarized_hash,uint256 notarized_desttxid,uint256 MoM,int32_t MoMdepth) { struct notarized_checkpoint *np; if ( notarized_height >= nHeight ) @@ -511,8 +530,8 @@ void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t not sp->NOTARIZED_HEIGHT = np->notarized_height = notarized_height; sp->NOTARIZED_HASH = np->notarized_hash = notarized_hash; sp->NOTARIZED_DESTTXID = np->notarized_desttxid = notarized_desttxid; - //sp->MoM = np->MoM = MoM; - //sp->MoMdepth = np->MoMdepth = MoMdepth; + sp->MoM = np->MoM = MoM; + sp->MoMdepth = np->MoMdepth = MoMdepth; portable_mutex_unlock(&komodo_mutex); } @@ -540,40 +559,6 @@ void komodo_init(int32_t height) //for (i=0; i 0 ) - { - for (i=0; i offset + 6 ) decay = (long long)atof(argv[offset + 6]); - rpcport = 1 + komodo_calcport(argv[offset + 1],supply,endsubsidy,reward,halving,decay); - printf("./komodod -ac_name=%s -ac_supply=%llu -ac_end=%llu -ac_reward=%llu -ac_halving=%llu -ac_decay=%llu & # rpcport %u\n",argv[offset + 1],(long long)supply,(long long)endsubsidy,(long long)reward,(long long)halving,(long long)decay,rpcport); + rpcport = 1 + komodo_calcport(argv[offset + 1],supply,endsubsidy,reward,halving,decay,commission,staked,cc); + printf("./komodod -ac_name=%s -ac_cc=%u -ac_supply=%llu -ac_end=%llu -ac_reward=%llu -ac_halving=%llu -ac_decay=%llu & # rpcport %u\n",argv[offset + 1],cc,(long long)supply,(long long)endsubsidy,(long long)reward,(long long)halving,(long long)decay,rpcport); if ( allocated != 0 ) { char name[64],newname[64]; @@ -859,14 +861,14 @@ int main(int argc, char * argv[]) allocated[rpcport-1] = 1; for (i=0; i [%s] statename.(%s) %s\n",test,ASSETCHAINS_SYMBOL,symbol,fname); } -void komodo_configfile(char *symbol,uint16_t port) +void komodo_configfile(char *symbol,uint16_t rpcport) { static char myusername[512],mypassword[8192]; FILE *fp; uint16_t kmdport; uint8_t buf2[33]; char fname[512],buf[128],username[512],password[8192]; uint32_t crc,r,r2,i; - if ( symbol != 0 && port != 0 ) + if ( symbol != 0 && rpcport != 0 ) { r = (uint32_t)time(NULL); r2 = OS_milliseconds(); @@ -1354,7 +1354,7 @@ void komodo_configfile(char *symbol,uint16_t port) sprintf(&password[i*2],"%02x",buf2[i]); password[i*2] = 0; sprintf(buf,"%s.conf",symbol); - BITCOIND_PORT = port; + BITCOIND_RPCPORT = rpcport; #ifdef _WIN32 sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(),buf); #else @@ -1365,7 +1365,7 @@ void komodo_configfile(char *symbol,uint16_t port) #ifndef FROM_CLI if ( (fp= fopen(fname,"wb")) != 0 ) { - fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=64\nrpcallowip=127.0.0.1\n",crc,password,port); + fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=256\nrpcallowip=127.0.0.1\n",crc,password,rpcport); fclose(fp); printf("Created (%s)\n",fname); } else printf("Couldnt create (%s)\n",fname); @@ -1373,7 +1373,7 @@ void komodo_configfile(char *symbol,uint16_t port) } else { - komodo_userpass(myusername,mypassword,fp); + _komodo_userpass(myusername,mypassword,fp); mapArgs["-rpcpassword"] = mypassword; mapArgs["-rpcusername"] = myusername; //fprintf(stderr,"myusername.(%s)\n",myusername); @@ -1396,7 +1396,7 @@ void komodo_configfile(char *symbol,uint16_t port) #endif if ( (fp= fopen(fname,"rb")) != 0 ) { - if ( (kmdport= komodo_userpass(username,password,fp)) != 0 ) + if ( (kmdport= _komodo_userpass(username,password,fp)) != 0 ) KMD_PORT = kmdport; sprintf(KMDUSERPASS,"%s:%s",username,password); fclose(fp); @@ -1420,12 +1420,11 @@ uint16_t komodo_userpass(char *userpass,char *symbol) komodo_statefname(fname,symbol,confname); if ( (fp= fopen(fname,"rb")) != 0 ) { - port = komodo_userpass(username,password,fp); + port = _komodo_userpass(username,password,fp); sprintf(userpass,"%s:%s",username,password); if ( strcmp(symbol,ASSETCHAINS_SYMBOL) == 0 ) strcpy(ASSETCHAINS_USERPASS,userpass); fclose(fp); - return((int32_t)strlen(userpass)); } return(port); } @@ -1477,7 +1476,7 @@ uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp,uint8_t *extr printf("ports\n"); }*/ -char *iguanafmtstr = (char *)"curl --url \"http://127.0.0.1:7778\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":1,\\\"VALIDATE\\\":1,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"iguana\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\"}\""; +char *iguanafmtstr = (char *)"curl --url \"http://127.0.0.1:7776\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":-1,\\\"VALIDATE\\\":0,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"iguana\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\"}\""; int32_t komodo_whoami(char *pubkeystr,int32_t height,uint32_t timestamp) @@ -1503,7 +1502,7 @@ char *argv0names[] = void komodo_args(char *argv0) { extern int64_t MAX_MONEY; - std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[256],*extraptr=0; FILE *fp; uint64_t val; int32_t i,baseid,len,n,extralen = 0; + std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[256],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,baseid,len,n,extralen = 0; IS_KOMODO_NOTARY = GetBoolArg("-notary", false); if ( (KOMODO_EXCHANGEWALLET= GetBoolArg("-exchange", false)) != 0 ) fprintf(stderr,"KOMODO_EXCHANGEWALLET mode active\n"); @@ -1528,13 +1527,14 @@ void komodo_args(char *argv0) } } } - ASSETCHAINS_CC = GetArg("-ac_cc",0); // keep it outside the assetchains hashing so KMD can do it and we dont have two identical chains other than -ac_cc + ASSETCHAINS_CC = GetArg("-ac_cc",0); if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 ) { printf("KOMODO_REWIND %d\n",KOMODO_REWIND); } if ( name.c_str()[0] != 0 ) { + MAX_BLOCK_SIGOPS = 60000; ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10); ASSETCHAINS_ENDSUBSIDY = GetArg("-ac_end",0); ASSETCHAINS_REWARD = GetArg("-ac_reward",0); @@ -1575,13 +1575,13 @@ void komodo_args(char *argv0) extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_REWARD),(void *)&ASSETCHAINS_REWARD); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_HALVING),(void *)&ASSETCHAINS_HALVING); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY),(void *)&ASSETCHAINS_DECAY); - val = ASSETCHAINS_COMMISSION | ((ASSETCHAINS_STAKED & 0xff) << 32); + val = ASSETCHAINS_COMMISSION | (((uint64_t)ASSETCHAINS_STAKED & 0xff) << 32) | (((uint64_t)ASSETCHAINS_CC & 0xffffff) << 40); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(val),(void *)&val); } addn = GetArg("-seednode",""); if ( strlen(addn.c_str()) > 0 ) ASSETCHAINS_SEED = 1; - strncpy(ASSETCHAINS_SYMBOL,name.c_str(),sizeof(ASSETCHAINS_SYMBOL)-1); + strncpy(ASSETCHAINS_SYMBOL,name.c_str(),64); if ( (baseid= komodo_baseid(ASSETCHAINS_SYMBOL)) >= 0 && baseid < 32 ) MAX_MONEY = komodo_maxallowed(baseid); else if ( ASSETCHAINS_REWARD == 0 ) @@ -1589,7 +1589,7 @@ void komodo_args(char *argv0) else MAX_MONEY = (ASSETCHAINS_SUPPLY+1) * SATOSHIDEN + ASSETCHAINS_REWARD * (ASSETCHAINS_ENDSUBSIDY==0 ? 10000000 : ASSETCHAINS_ENDSUBSIDY); MAX_MONEY += (MAX_MONEY * ASSETCHAINS_COMMISSION) / SATOSHIDEN; //printf("baseid.%d MAX_MONEY.%s %.8f\n",baseid,ASSETCHAINS_SYMBOL,(double)MAX_MONEY/SATOSHIDEN); - ASSETCHAINS_PORT = komodo_port(ASSETCHAINS_SYMBOL,ASSETCHAINS_SUPPLY,&ASSETCHAINS_MAGIC,extraptr,extralen); + ASSETCHAINS_P2PPORT = komodo_port(ASSETCHAINS_SYMBOL,ASSETCHAINS_SUPPLY,&ASSETCHAINS_MAGIC,extraptr,extralen); while ( (dirname= (char *)GetDataDir(false).string().c_str()) == 0 || dirname[0] == 0 ) { fprintf(stderr,"waiting for datadir\n"); @@ -1604,11 +1604,14 @@ void komodo_args(char *argv0) { int32_t komodo_baseid(char *origbase); extern int COINBASE_MATURITY; - komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_PORT + 1); - komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL); + if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL)) != 0 ) + ASSETCHAINS_RPCPORT = port; + else komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT + 1); COINBASE_MATURITY = 1; - //fprintf(stderr,"ASSETCHAINS_PORT %s %u (%s)\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_PORT,ASSETCHAINS_USERPASS); + //fprintf(stderr,"ASSETCHAINS_RPCPORT (%s) %u\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_RPCPORT); } + if ( ASSETCHAINS_RPCPORT == 0 ) + ASSETCHAINS_RPCPORT = ASSETCHAINS_P2PPORT + 1; //ASSETCHAINS_NOTARIES = GetArg("-ac_notaries",""); //komodo_assetchain_pubkeys((char *)ASSETCHAINS_NOTARIES.c_str()); iguana_rwnum(1,magic,sizeof(ASSETCHAINS_MAGIC),(void *)&ASSETCHAINS_MAGIC); @@ -1616,10 +1619,10 @@ void komodo_args(char *argv0) sprintf(&magicstr[i<<1],"%02x",magic[i]); magicstr[8] = 0; #ifndef FROM_CLI - sprintf(fname,"gen%s",ASSETCHAINS_SYMBOL); + sprintf(fname,"%s_7776",ASSETCHAINS_SYMBOL); if ( (fp= fopen(fname,"wb")) != 0 ) { - fprintf(fp,iguanafmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_PORT,ASSETCHAINS_PORT+1,"78.47.196.146"); + fprintf(fp,iguanafmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,"78.47.196.146"); fclose(fp); //printf("created (%s)\n",fname); } else printf("error creating (%s)\n",fname); @@ -1628,7 +1631,8 @@ void komodo_args(char *argv0) else { char fname[512],username[512],password[4096]; int32_t iter; FILE *fp; - ASSETCHAINS_PORT = 8777; + ASSETCHAINS_P2PPORT = 7770; + ASSETCHAINS_RPCPORT = 7771; for (iter=0; iter<2; iter++) { strcpy(fname,GetDataDir().string().c_str()); @@ -1653,7 +1657,7 @@ void komodo_args(char *argv0) #endif if ( (fp= fopen(fname,"rb")) != 0 ) { - komodo_userpass(username,password,fp); + _komodo_userpass(username,password,fp); sprintf(iter == 0 ? KMDUSERPASS : BTCUSERPASS,"%s:%s",username,password); fclose(fp); //printf("KOMODO.(%s) -> userpass.(%s)\n",fname,KMDUSERPASS); @@ -1662,8 +1666,11 @@ void komodo_args(char *argv0) break; } } - BITCOIND_PORT = GetArg("-rpcport", BaseParams().RPCPort()); - //fprintf(stderr,"%s chain params initialized\n",ASSETCHAINS_SYMBOL); + if ( ASSETCHAINS_SYMBOL[0] != 0 ) + { + BITCOIND_RPCPORT = GetArg("-rpcport", ASSETCHAINS_RPCPORT); + //fprintf(stderr,"(%s) port.%u chain params initialized\n",ASSETCHAINS_SYMBOL,BITCOIND_RPCPORT); + } else BITCOIND_RPCPORT = GetArg("-rpcport", BaseParams().RPCPort()); } void komodo_nameset(char *symbol,char *dest,char *source) @@ -1696,3 +1703,24 @@ struct komodo_state *komodo_stateptr(char *symbol,char *dest) komodo_nameset(symbol,dest,ASSETCHAINS_SYMBOL); return(komodo_stateptrget(symbol)); } + +void komodo_prefetch(FILE *fp) +{ + long fsize,fpos; int32_t incr = 16*1024*1024; + fpos = ftell(fp); + fseek(fp,0,SEEK_END); + fsize = ftell(fp); + if ( fsize > incr ) + { + char *ignore = (char *)malloc(incr); + if ( ignore != 0 ) + { + rewind(fp); + while ( fread(ignore,1,incr,fp) == incr ) // prefetch + fprintf(stderr,"."); + free(ignore); + } + } + fseek(fp,fpos,SEEK_SET); +} + diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp index b5d024abb..3f1abbe14 100644 --- a/src/leveldbwrapper.cpp +++ b/src/leveldbwrapper.cpp @@ -27,14 +27,14 @@ void HandleError(const leveldb::Status& status) throw leveldb_error("Unknown database error"); } -static leveldb::Options GetOptions(size_t nCacheSize) +static leveldb::Options GetOptions(size_t nCacheSize, bool compression, int maxOpenFiles) { leveldb::Options options; options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously options.filter_policy = leveldb::NewBloomFilterPolicy(10); - options.compression = leveldb::kNoCompression; - options.max_open_files = 64; + options.compression = compression ? leveldb::kSnappyCompression : leveldb::kNoCompression; + options.max_open_files = maxOpenFiles; if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) { // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error // on corruption in later versions. @@ -43,14 +43,14 @@ static leveldb::Options GetOptions(size_t nCacheSize) return options; } -CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe) +CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe, bool compression, int maxOpenFiles) { penv = NULL; readoptions.verify_checksums = true; iteroptions.verify_checksums = true; iteroptions.fill_cache = false; syncoptions.sync = true; - options = GetOptions(nCacheSize); + options = GetOptions(nCacheSize, compression, maxOpenFiles); options.create_if_missing = true; if (fMemory) { penv = leveldb::NewMemEnv(leveldb::Env::Default()); diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h index 639f736a5..2a6e345f1 100644 --- a/src/leveldbwrapper.h +++ b/src/leveldbwrapper.h @@ -86,7 +86,7 @@ private: leveldb::DB* pdb; public: - CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false); + CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool compression = false, int maxOpenFiles = 64); ~CLevelDBWrapper(); template diff --git a/src/main.cpp b/src/main.cpp index 3a7bcdeba..119967a46 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,6 +56,7 @@ extern uint8_t NOTARY_PUBKEY33[33]; extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN; int32_t KOMODO_NEWBLOCKS; int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block); +void komodo_broadcast(CBlock *pblock,int32_t limit); BlockMap mapBlockIndex; CChain chainActive; @@ -68,6 +69,9 @@ bool fExperimentalMode = false; bool fImporting = false; bool fReindex = false; bool fTxIndex = false; +bool fAddressIndex = false; +bool fTimestampIndex = false; +bool fSpentIndex = false; bool fHavePruned = false; bool fPruneMode = false; bool fIsBareMultisigStd = true; @@ -1291,10 +1295,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa COutPoint outpoint = tx.vin[i].prevout; if (pool.mapNextTx.count(outpoint)) { - static uint32_t counter; + //static uint32_t counter; // Disable replacement feature for now //if ( counter++ < 100 ) - fprintf(stderr,"Disable replacement feature for now\n"); + //fprintf(stderr,"Disable replacement feature for now\n"); return false; } } @@ -1484,6 +1488,16 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if ( komodo_is_notarytx(tx) == 0 ) KOMODO_ON_DEMAND++; pool.addUnchecked(hash, entry, !IsInitialBlockDownload()); + + // Add memory address index + if (fAddressIndex) { + pool.addAddressIndex(entry, view); + } + + // Add memory spent index + if (fSpentIndex) { + pool.addSpentIndex(entry, view); + } } SyncWithWallets(tx, NULL); @@ -1491,6 +1505,55 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return true; } +bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector > &hashes) +{ + if (!fTimestampIndex) + return error("Timestamp index not enabled"); + + if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes)) + return error("Unable to get hashes for timestamps"); + + return true; +} + +bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) +{ + if (!fSpentIndex) + return false; + + if (mempool.getSpentIndex(key, value)) + return true; + + if (!pblocktree->ReadSpentIndex(key, value)) + return false; + + return true; +} + +bool GetAddressIndex(uint160 addressHash, int type, + std::vector > &addressIndex, int start, int end) +{ + if (!fAddressIndex) + return error("address index not enabled"); + + if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end)) + return error("unable to get txids for address"); + + return true; +} + +bool GetAddressUnspent(uint160 addressHash, int type, + std::vector > &unspentOutputs) +{ + if (!fAddressIndex) + return error("address index not enabled"); + + if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) + return error("unable to get txids for address"); + + return true; +} + /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) { @@ -1538,7 +1601,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock if (pindexSlow) { CBlock block; - if (ReadBlockFromDisk(block, pindexSlow)) { + if (ReadBlockFromDisk(block, pindexSlow,1)) { BOOST_FOREACH(const CTransaction &tx, block.vtx) { if (tx.GetHash() == hash) { txOut = tx; @@ -1593,7 +1656,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::M return true; } -bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos) +bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW) { uint8_t pubkey33[33]; block.SetNull(); @@ -1615,7 +1678,7 @@ bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos) return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString()); } // Check the header - if ( 0 ) + if ( 0 && checkPOW != 0 ) { komodo_block2pubkey33(pubkey33,(CBlock *)&block); if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime))) @@ -1630,11 +1693,11 @@ bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos) return true; } -bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW) { if ( pindex == 0 ) return false; - if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos())) + if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos(),checkPOW)) return false; if (block.GetHash() != pindex->GetBlockHash()) return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s", @@ -2190,7 +2253,6 @@ namespace { catch (const std::exception& e) { return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } - // Verify checksum CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); hasher << hashBlock; @@ -2272,12 +2334,45 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) return error("DisconnectBlock(): block and undo data inconsistent"); - + std::vector > addressIndex; + std::vector > addressUnspentIndex; + std::vector > spentIndex; + // undo transactions in reverse order for (int i = block.vtx.size() - 1; i >= 0; i--) { const CTransaction &tx = block.vtx[i]; uint256 hash = tx.GetHash(); - + if (fAddressIndex) { + + for (unsigned int k = tx.vout.size(); k-- > 0;) { + const CTxOut &out = tx.vout[k]; + + if (out.scriptPubKey.IsPayToScriptHash()) { + vector hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22); + + // undo receiving activity + addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue)); + + // undo unspent index + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue())); + + } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { + vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); + + // undo receiving activity + addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue)); + + // undo unspent index + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue())); + + } else { + continue; + } + + } + + } + // Check that all outputs are available and match the outputs in the block itself // exactly. { @@ -2314,6 +2409,39 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex const CTxInUndo &undo = txundo.vprevout[j]; if (!ApplyTxInUndo(undo, view, out)) fClean = false; + + const CTxIn input = tx.vin[j]; + + if (fSpentIndex) { + // undo and delete the spent index + spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue())); + } + + if (fAddressIndex) { + const CTxOut &prevout = view.GetOutputFor(tx.vin[j]); + if (prevout.scriptPubKey.IsPayToScriptHash()) { + vector hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22); + + // undo spending activity + addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1)); + + // restore unspent index + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight))); + + + } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { + vector hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23); + + // undo spending activity + addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1)); + + // restore unspent index + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight))); + + } else { + continue; + } + } } } } @@ -2328,7 +2456,15 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex *pfClean = fClean; return true; } - + + if (fAddressIndex) { + if (!pblocktree->EraseAddressIndex(addressIndex)) { + return AbortNode(state, "Failed to delete address index"); + } + if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) { + return AbortNode(state, "Failed to write address unspent index"); + } + } return fClean; } @@ -2448,7 +2584,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } auto verifier = libzcash::ProofVerifier::Strict(); auto disabledVerifier = libzcash::ProofVerifier::Disabled(); - int32_t futureblock; // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in if (!CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 ) @@ -2510,7 +2645,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin std::vector > vPos; vPos.reserve(block.vtx.size()); blockundo.vtxundo.reserve(block.vtx.size() - 1); - + std::vector > addressIndex; + std::vector > addressUnspentIndex; + std::vector > spentIndex; // Construct the incremental merkle tree at the current // block position, auto old_tree_root = view.GetBestAnchor(); @@ -2537,6 +2674,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin for (unsigned int i = 0; i < block.vtx.size(); i++) { const CTransaction &tx = block.vtx[i]; + const uint256 txhash = tx.GetHash(); nInputs += tx.vin.size(); nSigOps += GetLegacySigOpCount(tx); if (nSigOps > MAX_BLOCK_SIGOPS) @@ -2546,14 +2684,50 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (!tx.IsCoinBase()) { if (!view.HaveInputs(tx)) + { return state.DoS(100, error("ConnectBlock(): inputs missing/spent"), REJECT_INVALID, "bad-txns-inputs-missingorspent"); - + } // are the JoinSplit's requirements met? if (!view.HaveJoinSplitRequirements(tx)) return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"), REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met"); - + if (fAddressIndex || fSpentIndex) + { + for (size_t j = 0; j < tx.vin.size(); j++) { + + const CTxIn input = tx.vin[j]; + const CTxOut &prevout = view.GetOutputFor(tx.vin[j]); + uint160 hashBytes; + int addressType; + + if (prevout.scriptPubKey.IsPayToScriptHash()) { + hashBytes = uint160(vector (prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22)); + addressType = 2; + } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { + hashBytes = uint160(vector (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); + addressType = 1; + } else { + hashBytes.SetNull(); + addressType = 0; + } + + if (fAddressIndex && addressType > 0) { + // record spending activity + addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1)); + + // remove address from unspent index + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue())); + } + + if (fSpentIndex) { + // add the spent index to determine the txid and input that spent an output + // and to find the amount and address from an input + spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, addressType, hashBytes))); + } + } + + } // Add in sigops done by pay-to-script-hash inputs; // this is to prevent a "rogue miner" from creating // an incredibly-expensive-to-validate block. @@ -2575,6 +2749,36 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return false; control.Add(vChecks); } + + if (fAddressIndex) { + for (unsigned int k = 0; k < tx.vout.size(); k++) { + const CTxOut &out = tx.vout[k]; + + if (out.scriptPubKey.IsPayToScriptHash()) { + vector hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22); + + // record receiving activity + addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue)); + + // record unspent output + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); + + } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { + vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); + + // record receiving activity + addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue)); + + // record unspent output + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); + + } else { + continue; + } + + } + } + //if ( ASSETCHAINS_SYMBOL[0] == 0 ) // komodo_earned_interest(pindex->nHeight,sum); CTxUndo undoDummy; @@ -2605,14 +2809,14 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin 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); CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum; - if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && block.vtx[0].vout.size() > 1 ) + if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 ) { uint64_t checktoshis; - if ( (checktoshis= komodo_commission((const CBlock *)&block)) != 0 ) + if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 ) { if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis ) blockReward += checktoshis; - else fprintf(stderr,"checktoshis %.8f vs actual vout[1] %.8f\n",dstr(checktoshis),dstr(block.vtx[0].vout[1].nValue)); + else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size()); } } if ( block.vtx[0].GetValueOut() > blockReward+1 ) @@ -2667,7 +2871,41 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (fTxIndex) if (!pblocktree->WriteTxIndex(vPos)) return AbortNode(state, "Failed to write transaction index"); - + if (fAddressIndex) { + if (!pblocktree->WriteAddressIndex(addressIndex)) { + return AbortNode(state, "Failed to write address index"); + } + + if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) { + return AbortNode(state, "Failed to write address unspent index"); + } + } + + if (fSpentIndex) + if (!pblocktree->UpdateSpentIndex(spentIndex)) + return AbortNode(state, "Failed to write transaction index"); + + if (fTimestampIndex) { + unsigned int logicalTS = pindex->nTime; + unsigned int prevLogicalTS = 0; + + // retrieve logical timestamp of the previous block + if (pindex->pprev) + if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS)) + LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__); + + if (logicalTS <= prevLogicalTS) { + logicalTS = prevLogicalTS + 1; + LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS); + } + + if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash()))) + return AbortNode(state, "Failed to write timestamp index"); + + if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS))) + return AbortNode(state, "Failed to write blockhash index"); + } + // add this block to the view's block chain view.SetBestBlock(pindex->GetBlockHash()); @@ -2856,7 +3094,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { assert(pindexDelete); // Read block from disk. CBlock block; - if (!ReadBlockFromDisk(block, pindexDelete)) + if (!ReadBlockFromDisk(block, pindexDelete,1)) return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor(); @@ -2923,7 +3161,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * int64_t nTime1 = GetTimeMicros(); CBlock block; if (!pblock) { - if (!ReadBlockFromDisk(block, pindexNew)) + if (!ReadBlockFromDisk(block, pindexNew,1)) return AbortNode(state, "Failed to read block"); pblock = █ } @@ -2982,6 +3220,8 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1; LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001); LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001); + if ( ASSETCHAINS_SYMBOL[0] == 0 ) + komodo_broadcast(pblock,8); return true; } @@ -3081,8 +3321,8 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight, pindexOldTip->nChainWork.GetHex()) + "\n" + "- " + strprintf(_("New tip: %s, height %d, work %s"), pindexMostWork->phashBlock->GetHex(), pindexMostWork->nHeight, pindexMostWork->nChainWork.GetHex()) + "\n" + - "- " + strprintf(_("Fork point: %s, height %d"), - pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" + + "- " + strprintf(_("Fork point: %s %s, height %d"), + ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" + _("Please help, human!"); LogPrintf("*** %s\n", msg); uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR); @@ -3539,26 +3779,20 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, { if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600) *futureblockp = 1; - LogPrintf("CheckBlockHeader block from future %d error\n",blockhdr.GetBlockTime() - GetAdjustedTime()); + LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime()); return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new"); } } - /*if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60) - return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new"); - else*/ - if ( ASSETCHAINS_STAKED != 0 && pindex != 0 && pindex->pprev != 0 && pindex->nTime <= pindex->pprev->nTime ) - { - fprintf(stderr,"ht.%d %u vs ht.%d %u, is not monotonic\n",pindex->nHeight,pindex->nTime,pindex->pprev->nHeight,pindex->pprev->nTime); - return state.Invalid(error("CheckBlockHeader(): block timestamp needs to always increase"),REJECT_INVALID, "time-too-new"); - } // Check block version if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION) return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low"); // Check Equihash solution is valid - /*if ( fCheckPOW && !CheckEquihashSolution(&blockhdr, Params()) ) - return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution"); - + if ( fCheckPOW ) + { + if ( !CheckEquihashSolution(&blockhdr, Params()) ) + return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution"); + } // Check proof of work matches claimed amount /*komodo_index2pubkey33(pubkey33,pindex,height); if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) ) @@ -3567,39 +3801,7 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, } int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime); - -int32_t komodo_reverify_blockcheck(CValidationState& state,int32_t height,CBlockIndex *pindex) -{ - static int32_t oneshot; - CBlockIndex *tipindex; int32_t rewindtarget; - if ( KOMODO_REWIND != 0 ) - oneshot = KOMODO_REWIND; - if ( oneshot == 0 && IsInitialBlockDownload() == 0 && (tipindex= chainActive.Tip()) != 0 ) - { - // if 200 blocks behind longestchain and no blocks for 2 hours - if ( KOMODO_LONGESTCHAIN > height+200 && KOMODO_NEWBLOCKS == 0 ) - { - if ( GetAdjustedTime() > tipindex->nTime+3600*2 ) - { - fprintf(stderr,"possible fork: tip.%d longest.%d newblock.%d lag.%d blocktime.%u\n",tipindex->nHeight,KOMODO_LONGESTCHAIN,height,(int32_t)(GetAdjustedTime() - tipindex->nTime),tipindex->nTime); - /*KOMODO_REWIND = tipindex->nHeight - 11; - rewindtarget = tipindex->nHeight - 11; - fprintf(stderr,"rewindtarget <- %d\n",rewindtarget); - oneshot = 1; - while ( rewindtarget > 0 && (tipindex= chainActive.Tip()) != 0 && tipindex->nHeight > rewindtarget ) - { - fprintf(stderr,"%d ",(int32_t)tipindex->nHeight); - InvalidateBlock(state,tipindex); - if ( !DisconnectTip(state) ) - break; - } - tipindex = chainActive.Tip(); - fprintf(stderr,"rewind done to %d\n",tipindex!=0?tipindex->nHeight:-1);*/ - } - } - } - return(0); -} +int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height); bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state, libzcash::ProofVerifier& verifier, @@ -3608,19 +3810,18 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C uint8_t pubkey33[33]; uint256 hash; // These are checks that are independent of context. hash = block.GetHash(); - // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader. if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW)) { if ( *futureblockp == 0 ) { - LogPrintf("CheckBlock header error\n"); + LogPrintf("CheckBlock header error"); return false; } } if ( fCheckPOW ) { - //if ( !CheckEquihashSolution(&block, Params()) ) + //if ( !CheckEquihashSolution(&block, Params()) ) // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution"); komodo_block2pubkey33(pubkey33,(CBlock *)&block); if ( !CheckProofOfWork(height,pubkey33,hash,block.nBits,Params().GetConsensus(),block.nTime) ) @@ -3633,24 +3834,19 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW"); } - /*if ( fCheckPOW && !CheckEquihashSolution(&block, Params()) ) - return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution"); - komodo_block2pubkey33(pubkey33,(CBlock *)&block); - if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime) ) - return state.DoS(1, error("CheckBlock(): proof of work failed"),REJECT_INVALID, "high-hash");*/ // Check the merkle root. if (fCheckMerkleRoot) { bool mutated; uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated); if (block.hashMerkleRoot != hashMerkleRoot2) - return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"), + return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"), REJECT_INVALID, "bad-txnmrklroot", true); // Check for merkle tree malleability (CVE-2012-2459): repeating sequences // of transactions in a block without affecting the merkle root of a block, // while still invalidating it. if (mutated) - return state.DoS(100, error("CheckBlock(): duplicate transaction"), + return state.DoS(100, error("CheckBlock: duplicate transaction"), REJECT_INVALID, "bad-txns-duplicate", true); } @@ -3660,25 +3856,25 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C // Size limits if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) - return state.DoS(100, error("CheckBlock(): size limits failed"), + return state.DoS(100, error("CheckBlock: size limits failed"), REJECT_INVALID, "bad-blk-length"); // First transaction must be coinbase, the rest must not be if (block.vtx.empty() || !block.vtx[0].IsCoinBase()) - return state.DoS(100, error("CheckBlock(): first tx is not coinbase"), + return state.DoS(100, error("CheckBlock: first tx is not coinbase"), REJECT_INVALID, "bad-cb-missing"); for (unsigned int i = 1; i < block.vtx.size(); i++) if (block.vtx[i].IsCoinBase()) - return state.DoS(100, error("CheckBlock(): more than one coinbase"), + return state.DoS(100, error("CheckBlock: more than one coinbase"), REJECT_INVALID, "bad-cb-multiple"); // Check transactions BOOST_FOREACH(const CTransaction& tx, block.vtx) { - if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,1) < 0 ) + if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 ) return error("CheckBlock: komodo_validate_interest failed"); if (!CheckTransaction(tx, state, verifier)) - return error("CheckBlock(): CheckTransaction failed"); + return error("CheckBlock: CheckTransaction failed"); } unsigned int nSigOps = 0; BOOST_FOREACH(const CTransaction& tx, block.vtx) @@ -3686,14 +3882,14 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C nSigOps += GetLegacySigOpCount(tx); } if (nSigOps > MAX_BLOCK_SIGOPS) - return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), + return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"), REJECT_INVALID, "bad-blk-sigops", true); if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 ) - //if ( komodo_check_deposit(ASSETCHAINS_SYMBOL[0] == 0 ? height : pindex != 0 ? (int32_t)pindex->nHeight : chainActive.Tip()->nHeight+1,block,pindex==0||pindex->pprev==0?0:pindex->pprev->nTime) < 0 ) { - static uint32_t counter; + //static uint32_t counter; //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 ) - fprintf(stderr,"check deposit rejection\n"); + // fprintf(stderr,"check deposit rejection\n"); + LogPrintf("CheckBlockHeader komodo_check_deposit error"); return(false); } return true; @@ -3712,7 +3908,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta int nHeight = pindexPrev->nHeight+1; // Check proof of work - if ( (nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) + if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) { cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) << endl; return state.DoS(100, error("%s: incorrect proof of work", __func__), @@ -3730,11 +3926,11 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash)) { /*CBlockIndex *heightblock = chainActive[nHeight]; - if ( heightblock != 0 && heightblock->GetBlockHash() == hash ) - { - //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight); - return true; - }*/ + if ( heightblock != 0 && heightblock->GetBlockHash() == hash ) + { + //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight); + return true; + }*/ return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch"); } // Don't accept any forks from the main chain prior to last checkpoint @@ -3803,8 +3999,8 @@ bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidat static uint256 zero; const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); - - // Check for duplicate + + // Check for duplicate uint256 hash = block.GetHash(); BlockMap::iterator miSelf = mapBlockIndex.find(hash); CBlockIndex *pindex = NULL; @@ -3817,6 +4013,15 @@ bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidat *ppindex = pindex; if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK ) return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate"); + /*if ( pindex != 0 && hash == komodo_requestedhash ) + { + fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str()); + memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash)); + komodo_requestedcount = 0; + }*/ + + //if ( pindex == 0 ) + // fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str()); return true; } if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0)) @@ -3865,6 +4070,12 @@ bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidat } if (ppindex) *ppindex = pindex; + /*if ( pindex != 0 && hash == komodo_requestedhash ) + { + fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str()); + memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash)); + komodo_requestedcount = 0; + }*/ return true; } @@ -3967,7 +4178,7 @@ void komodo_currentheight_set(int32_t height); CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash) { - CBlockIndex *pindex; + CBlockIndex *pindex = 0; BlockMap::iterator miSelf = mapBlockIndex.find(hash); if ( miSelf != mapBlockIndex.end() ) { @@ -3976,7 +4187,7 @@ CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash) miSelf->second = AddToBlockIndex(*pblock); //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second); } - if ( hash != Params().GetConsensus().hashGenesisBlock ) + /*if ( hash != Params().GetConsensus().hashGenesisBlock ) { miSelf = mapBlockIndex.find(pblock->hashPrevBlock); if ( miSelf != mapBlockIndex.end() ) @@ -3987,8 +4198,9 @@ CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash) fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str()); } } - } + }*/ } + return(pindex); } CBlockIndex *oldkomodo_ensure(CBlock *pblock,uint256 hash) @@ -4022,24 +4234,24 @@ CBlockIndex *oldkomodo_ensure(CBlock *pblock,uint256 hash) } else LogPrintf("komodo_ensure unexpected null pindex\n"); } /*if ( hash != Params().GetConsensus().hashGenesisBlock ) - { - miSelf = mapBlockIndex.find(pblock->hashPrevBlock); - if ( miSelf == mapBlockIndex.end() ) - previndex = InsertBlockIndex(pblock->hashPrevBlock); - if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() ) - { - if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail - { - if ( previndex == 0 ) - previndex = InsertBlockIndex(pblock->hashPrevBlock); - if ( previndex != 0 ) - { - miSelf->second = previndex; - LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str()); - } else LogPrintf("komodo_ensure unexpected null previndex\n"); - } - } else LogPrintf("komodo_ensure unexpected null miprev\n"); - } + { + miSelf = mapBlockIndex.find(pblock->hashPrevBlock); + if ( miSelf == mapBlockIndex.end() ) + previndex = InsertBlockIndex(pblock->hashPrevBlock); + if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() ) + { + if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail + { + if ( previndex == 0 ) + previndex = InsertBlockIndex(pblock->hashPrevBlock); + if ( previndex != 0 ) + { + miSelf->second = previndex; + LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str()); + } else LogPrintf("komodo_ensure unexpected null previndex\n"); + } + } else LogPrintf("komodo_ensure unexpected null miprev\n"); + } }*/ return(pindex); } @@ -4050,8 +4262,8 @@ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNo bool checked; uint256 hash; int32_t futureblock=0; auto verifier = libzcash::ProofVerifier::Disabled(); hash = pblock->GetHash(); - //fprintf(stderr,"process newblock %s\n",hash.ToString().c_str()); - if ( chainActive.Tip() != 0 ) + + if ( chainActive.Tip() != 0 ) komodo_currentheight_set(chainActive.Tip()->nHeight); checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0); { @@ -4248,10 +4460,9 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes) return true; } - FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) { - static int32_t didinit[1000]; long fsize,fpos; int32_t incr = 16*1024*1024; + static int32_t didinit[64]; if (pos.IsNull()) return NULL; boost::filesystem::path path = GetBlockPosFilename(pos, prefix); @@ -4265,22 +4476,7 @@ FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) } if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 ) { - fpos = ftell(file); - fseek(file,0,SEEK_END); - fsize = ftell(file); - if ( fsize > incr ) - { - char *ignore = (char *)malloc(incr); - if ( ignore != 0 ) - { - rewind(file); - while ( fread(ignore,1,incr,file) == incr ) - fprintf(stderr,"."); - free(ignore); - //fprintf(stderr,"blk.%d loaded %ld bytes set fpos.%ld loading.%d\n",(int)pos.nFile,(long)ftell(file),(long)fpos,KOMODO_LOADINGBLOCKS); - } - } - fseek(file,fpos,SEEK_SET); + komodo_prefetch(file); didinit[pos.nFile] = 1; } if (pos.nPos) { @@ -4322,7 +4518,8 @@ CBlockIndex * InsertBlockIndex(uint256 hash) throw runtime_error("LoadBlockIndex(): new CBlockIndex failed"); mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); - + //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str()); + return pindexNew; } @@ -4331,9 +4528,10 @@ CBlockIndex * InsertBlockIndex(uint256 hash) bool static LoadBlockIndexDB() { const CChainParams& chainparams = Params(); + LogPrintf("%s: start loading guts\n", __func__); if (!pblocktree->LoadBlockIndexGuts()) return false; - + LogPrintf("%s: loaded guts\n", __func__); boost::this_thread::interruption_point(); // Calculate nChainWork @@ -4345,7 +4543,9 @@ bool static LoadBlockIndexDB() vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); //komodo_pindex_init(pindex,(int32_t)pindex->nHeight); } + //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)); BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) { CBlockIndex* pindex = item.second; @@ -4394,7 +4594,8 @@ bool static LoadBlockIndexDB() pindexBestHeader = pindex; //komodo_pindex_init(pindex,(int32_t)pindex->nHeight); } - + //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL)); + // Load block file info pblocktree->ReadLastBlockFile(nLastBlockFile); vinfoBlockFile.resize(nLastBlockFile + 1); @@ -4423,6 +4624,7 @@ bool static LoadBlockIndexDB() } //komodo_pindex_init(pindex,(int32_t)pindex->nHeight); } + //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL)); for (std::set::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) { CDiskBlockPos pos(*it, 0); @@ -4444,7 +4646,18 @@ bool static LoadBlockIndexDB() // Check whether we have a transaction index pblocktree->ReadFlag("txindex", fTxIndex); LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled"); - + // Check whether we have an address index + pblocktree->ReadFlag("addressindex", fAddressIndex); + LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled"); + + // Check whether we have a timestamp index + pblocktree->ReadFlag("timestampindex", fTimestampIndex); + LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled"); + + // Check whether we have a spent index + pblocktree->ReadFlag("spentindex", fSpentIndex); + LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled"); + // Fill in-memory data BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) { @@ -4510,6 +4723,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth CValidationState state; // No need to verify JoinSplits twice auto verifier = libzcash::ProofVerifier::Disabled(); + //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL)); for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) { boost::this_thread::interruption_point(); @@ -4518,11 +4732,11 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth break; CBlock block; // check level 0: read from disk - if (!ReadBlockFromDisk(block, pindex)) + if (!ReadBlockFromDisk(block, pindex,0)) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity int32_t futureblock; - if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, verifier,0)) + if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, verifier,0) ) return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 2: verify undo validity if (nCheckLevel >= 2 && pindex) { @@ -4548,6 +4762,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth if (ShutdownRequested()) return true; } + //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL)); if (pindexFailure) return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions); @@ -4559,7 +4774,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)))); pindex = chainActive.Next(pindex); CBlock block; - if (!ReadBlockFromDisk(block, pindex)) + if (!ReadBlockFromDisk(block, pindex,0)) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); if (!ConnectBlock(block, state, pindex, coins,false, true)) return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); @@ -4765,6 +4980,16 @@ bool InitBlockIndex() { // Use the provided setting for -txindex in the new database fTxIndex = GetBoolArg("-txindex", true); pblocktree->WriteFlag("txindex", fTxIndex); + // Use the provided setting for -addressindex in the new database + fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); + pblocktree->WriteFlag("addressindex", fAddressIndex); + + // Use the provided setting for -timestampindex in the new database + fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX); + pblocktree->WriteFlag("timestampindex", fTimestampIndex); + + fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); + pblocktree->WriteFlag("spentindex", fSpentIndex); LogPrintf("Initializing databases...\n"); // Only add the genesis block if not reindexing (in which case we reuse the one already on disk) @@ -4808,7 +5033,8 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) int nLoaded = 0; try { // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor - CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); + //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); + CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); uint64_t nRewind = blkdat.GetPos(); while (!blkdat.eof()) { boost::this_thread::interruption_point(); @@ -4874,7 +5100,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) std::pair::iterator, std::multimap::iterator> range = mapBlocksUnknownParent.equal_range(head); while (range.first != range.second) { std::multimap::iterator it = range.first; - if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->nHeight:0,block, it->second)) + if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->nHeight:0,block, it->second,1)) { LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), head.ToString()); @@ -5233,7 +5459,7 @@ void static ProcessGetData(CNode* pfrom) { // Send block from disk CBlock block; - if (!ReadBlockFromDisk(block, (*mi).second)) + if (!ReadBlockFromDisk(block, (*mi).second,1)) { assert(!"cannot load block from disk"); } @@ -5739,7 +5965,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vector vHeaders; int nLimit = MAX_HEADERS_RESULTS; LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id); - //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->nHeight : -1) ) + //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->nHeight : -1) )// no need to ever suppress this { pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->nHeight : -1); for (; pindex; pindex = chainActive.Next(pindex)) @@ -5750,6 +5976,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } pfrom->PushMessage("headers", vHeaders); } + /*else if ( NOTARY_PUBKEY33[0] != 0 ) + { + static uint32_t counter; + if ( counter++ < 3 ) + fprintf(stderr,"you can ignore redundant getheaders from peer.%d %d prev.%d\n",(int32_t)pfrom->id,(int32_t)(pindex ? pindex->nHeight : -1),pfrom->lasthdrsreq); + }*/ } @@ -5918,7 +6150,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int nDoS; if (state.IsInvalid(nDoS) && futureblock == 0) { - if (nDoS > 0) + if (nDoS > 0 && futureblock == 0) Misbehaving(pfrom->GetId(), nDoS/nDoS); return error("invalid header received"); } @@ -6549,6 +6781,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // // Message: getdata (blocks) // + static uint256 zero; vector vGetData; if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vector vToDownload; @@ -6567,7 +6800,21 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } } } - + /*CBlockIndex *pindex; + if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 ) + { + LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId()); + fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId()); + vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash)); + MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex); + komodo_requestedcount++; + if ( komodo_requestedcount > 16 ) + { + memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash)); + komodo_requestedcount = 0; + } + }*/ + // // Message: getdata (non-blocks) // diff --git a/src/main.h b/src/main.h index 4035de136..ef46cd83d 100644 --- a/src/main.h +++ b/src/main.h @@ -22,6 +22,7 @@ #include "script/script.h" #include "script/serverchecker.h" #include "script/standard.h" +#include "spentindex.h" #include "sync.h" #include "tinyformat.h" #include "txmempool.h" @@ -101,6 +102,12 @@ static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60; /** Maximum length of reject messages. */ static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; +static const bool DEFAULT_ADDRESSINDEX = false; +static const bool DEFAULT_TIMESTAMPINDEX = false; +static const bool DEFAULT_SPENTINDEX = false; +static const unsigned int DEFAULT_DB_MAX_OPEN_FILES = 1000; +static const bool DEFAULT_DB_COMPRESSION = true; + // Sanity check the magic numbers when we change them BOOST_STATIC_ASSERT(DEFAULT_BLOCK_MAX_SIZE <= MAX_BLOCK_SIZE); BOOST_STATIC_ASSERT(DEFAULT_BLOCK_PRIORITY_SIZE <= DEFAULT_BLOCK_MAX_SIZE); @@ -268,6 +275,338 @@ struct CNodeStateStats { std::vector vHeightInFlight; }; +struct CTimestampIndexIteratorKey { + unsigned int timestamp; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 4; + } + template + void Serialize(Stream& s, int nType, int nVersion) const { + ser_writedata32be(s, timestamp); + } + template + void Unserialize(Stream& s, int nType, int nVersion) { + timestamp = ser_readdata32be(s); + } + + CTimestampIndexIteratorKey(unsigned int time) { + timestamp = time; + } + + CTimestampIndexIteratorKey() { + SetNull(); + } + + void SetNull() { + timestamp = 0; + } +}; + +struct CTimestampIndexKey { + unsigned int timestamp; + uint256 blockHash; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 36; + } + template + void Serialize(Stream& s, int nType, int nVersion) const { + ser_writedata32be(s, timestamp); + blockHash.Serialize(s, nType, nVersion); + } + template + void Unserialize(Stream& s, int nType, int nVersion) { + timestamp = ser_readdata32be(s); + blockHash.Unserialize(s, nType, nVersion); + } + + CTimestampIndexKey(unsigned int time, uint256 hash) { + timestamp = time; + blockHash = hash; + } + + CTimestampIndexKey() { + SetNull(); + } + + void SetNull() { + timestamp = 0; + blockHash.SetNull(); + } +}; + +struct CTimestampBlockIndexKey { + uint256 blockHash; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 32; + } + + template + void Serialize(Stream& s, int nType, int nVersion) const { + blockHash.Serialize(s, nType, nVersion); + } + + template + void Unserialize(Stream& s, int nType, int nVersion) { + blockHash.Unserialize(s, nType, nVersion); + } + + CTimestampBlockIndexKey(uint256 hash) { + blockHash = hash; + } + + CTimestampBlockIndexKey() { + SetNull(); + } + + void SetNull() { + blockHash.SetNull(); + } +}; + +struct CTimestampBlockIndexValue { + unsigned int ltimestamp; + size_t GetSerializeSize(int nType, int nVersion) const { + return 4; + } + + template + void Serialize(Stream& s, int nType, int nVersion) const { + ser_writedata32be(s, ltimestamp); + } + + template + void Unserialize(Stream& s, int nType, int nVersion) { + ltimestamp = ser_readdata32be(s); + } + + CTimestampBlockIndexValue (unsigned int time) { + ltimestamp = time; + } + + CTimestampBlockIndexValue() { + SetNull(); + } + + void SetNull() { + ltimestamp = 0; + } +}; + +struct CAddressUnspentKey { + unsigned int type; + uint160 hashBytes; + uint256 txhash; + size_t index; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 57; + } + template + void Serialize(Stream& s, int nType, int nVersion) const { + ser_writedata8(s, type); + hashBytes.Serialize(s, nType, nVersion); + txhash.Serialize(s, nType, nVersion); + ser_writedata32(s, index); + } + template + void Unserialize(Stream& s, int nType, int nVersion) { + type = ser_readdata8(s); + hashBytes.Unserialize(s, nType, nVersion); + txhash.Unserialize(s, nType, nVersion); + index = ser_readdata32(s); + } + + CAddressUnspentKey(unsigned int addressType, uint160 addressHash, uint256 txid, size_t indexValue) { + type = addressType; + hashBytes = addressHash; + txhash = txid; + index = indexValue; + } + + CAddressUnspentKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + txhash.SetNull(); + index = 0; + } +}; + +struct CAddressUnspentValue { + CAmount satoshis; + CScript script; + int blockHeight; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(satoshis); + READWRITE(script); + READWRITE(blockHeight); + } + + CAddressUnspentValue(CAmount sats, CScript scriptPubKey, int height) { + satoshis = sats; + script = scriptPubKey; + blockHeight = height; + } + + CAddressUnspentValue() { + SetNull(); + } + + void SetNull() { + satoshis = -1; + script.clear(); + blockHeight = 0; + } + + bool IsNull() const { + return (satoshis == -1); + } +}; + +struct CAddressIndexKey { + unsigned int type; + uint160 hashBytes; + int blockHeight; + unsigned int txindex; + uint256 txhash; + size_t index; + bool spending; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 66; + } + template + void Serialize(Stream& s, int nType, int nVersion) const { + ser_writedata8(s, type); + hashBytes.Serialize(s, nType, nVersion); + // Heights are stored big-endian for key sorting in LevelDB + ser_writedata32be(s, blockHeight); + ser_writedata32be(s, txindex); + txhash.Serialize(s, nType, nVersion); + ser_writedata32(s, index); + char f = spending; + ser_writedata8(s, f); + } + template + void Unserialize(Stream& s, int nType, int nVersion) { + type = ser_readdata8(s); + hashBytes.Unserialize(s, nType, nVersion); + blockHeight = ser_readdata32be(s); + txindex = ser_readdata32be(s); + txhash.Unserialize(s, nType, nVersion); + index = ser_readdata32(s); + char f = ser_readdata8(s); + spending = f; + } + + CAddressIndexKey(unsigned int addressType, uint160 addressHash, int height, int blockindex, + uint256 txid, size_t indexValue, bool isSpending) { + type = addressType; + hashBytes = addressHash; + blockHeight = height; + txindex = blockindex; + txhash = txid; + index = indexValue; + spending = isSpending; + } + + CAddressIndexKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + blockHeight = 0; + txindex = 0; + txhash.SetNull(); + index = 0; + spending = false; + } + +}; + +struct CAddressIndexIteratorKey { + unsigned int type; + uint160 hashBytes; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 21; + } + template + void Serialize(Stream& s, int nType, int nVersion) const { + ser_writedata8(s, type); + hashBytes.Serialize(s, nType, nVersion); + } + template + void Unserialize(Stream& s, int nType, int nVersion) { + type = ser_readdata8(s); + hashBytes.Unserialize(s, nType, nVersion); + } + + CAddressIndexIteratorKey(unsigned int addressType, uint160 addressHash) { + type = addressType; + hashBytes = addressHash; + } + + CAddressIndexIteratorKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + } +}; + +struct CAddressIndexIteratorHeightKey { + unsigned int type; + uint160 hashBytes; + int blockHeight; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 25; + } + template + void Serialize(Stream& s, int nType, int nVersion) const { + ser_writedata8(s, type); + hashBytes.Serialize(s, nType, nVersion); + ser_writedata32be(s, blockHeight); + } + template + void Unserialize(Stream& s, int nType, int nVersion) { + type = ser_readdata8(s); + hashBytes.Unserialize(s, nType, nVersion); + blockHeight = ser_readdata32be(s); + } + + CAddressIndexIteratorHeightKey(unsigned int addressType, uint160 addressHash, int height) { + type = addressType; + hashBytes = addressHash; + blockHeight = height; + } + + CAddressIndexIteratorHeightKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + blockHeight = 0; + } +}; + struct CDiskTxPos : public CDiskBlockPos { unsigned int nTxOffset; // after header @@ -431,11 +770,18 @@ public: ScriptError GetScriptError() const { return error; } }; +bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector > &hashes); +bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); +bool GetAddressIndex(uint160 addressHash, int type, + std::vector > &addressIndex, + int start = 0, int end = 0); +bool GetAddressUnspent(uint160 addressHash, int type, + std::vector > &unspentOutputs); /** Functions for disk access for blocks */ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); -bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos); -bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW); +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW); /** Functions for validating blocks and updating the block tree */ diff --git a/src/miner.cpp b/src/miner.cpp index 8a56b72d1..264a6e2d4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -113,14 +113,15 @@ extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33]; uint32_t Mining_start,Mining_height; int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize); -uint64_t komodo_paxtotal(); +//uint64_t komodo_paxtotal(); int32_t komodo_baseid(char *origbase); -int32_t komodo_is_issuer(); -int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *symbol,int32_t tokomodo); -int32_t komodo_isrealtime(int32_t *kmdheightp); +//int32_t komodo_is_issuer(); +//int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *symbol,int32_t tokomodo); +//int32_t komodo_isrealtime(int32_t *kmdheightp); int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag); uint64_t komodo_commission(const CBlock *block); 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); CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { @@ -133,7 +134,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) return NULL; } CBlock *pblock = &pblocktemplate->block; // pointer for convenience - if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) >= 0 && chainActive.Tip()->nHeight >= ASSETCHAINS_MINHEIGHT ) + /*if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) >= 0 && chainActive.Tip()->nHeight >= ASSETCHAINS_MINHEIGHT ) { isrealtime = komodo_isrealtime(&kmdheight); deposits = komodo_paxtotal(); @@ -154,7 +155,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) KOMODO_ON_DEMAND = 0; if ( 0 && deposits != 0 ) printf("miner KOMODO_DEPOSIT %llu pblock->nHeight %d mempool.GetTotalTxSize(%d)\n",(long long)komodo_paxtotal(),(int32_t)chainActive.Tip()->nHeight,(int32_t)mempool.GetTotalTxSize()); - } + }*/ // -regtest only: allow overriding block.nVersion with // -blockversion=N to test forking scenarios if (Params().MineBlocksOnDemand()) @@ -211,10 +212,13 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) : pblock->GetBlockTime(); if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff) || IsExpiredTx(tx, nHeight)) - continue; - if ( komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,0) < 0 ) { - fprintf(stderr,"CreateNewBlock: komodo_validate_interest failure\n"); + //fprintf(stderr,"coinbase.%d finaltx.%d expired.%d\n",tx.IsCoinBase(),IsFinalTx(tx, nHeight, nLockTimeCutoff),IsExpiredTx(tx, nHeight)); + continue; + } + if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,0) < 0 ) + { + //fprintf(stderr,"CreateNewBlock: komodo_validate_interest failure nHeight.%d nTime.%u vs locktime.%u\n",nHeight,(uint32_t)pblock->nTime,(uint32_t)tx.nLockTime); continue; } COrphan* porphan = NULL; @@ -305,22 +309,29 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Size limits unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - if (nBlockSize + nTxSize >= nBlockMaxSize) + if (nBlockSize + nTxSize >= nBlockMaxSize-512) // room for extra autotx + { + //fprintf(stderr,"nBlockSize %d + %d nTxSize >= %d nBlockMaxSize\n",(int32_t)nBlockSize,(int32_t)nTxSize,(int32_t)nBlockMaxSize); continue; + } // Legacy limits on sigOps: unsigned int nTxSigOps = GetLegacySigOpCount(tx); if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1) + { + //fprintf(stderr,"A nBlockSigOps %d + %d nTxSigOps >= %d MAX_BLOCK_SIGOPS-1\n",(int32_t)nBlockSigOps,(int32_t)nTxSigOps,(int32_t)MAX_BLOCK_SIGOPS); continue; - + } // Skip free transactions if we're past the minimum block size: const uint256& hash = tx.GetHash(); double dPriorityDelta = 0; CAmount nFeeDelta = 0; mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) + { + //fprintf(stderr,"fee rate skip\n"); continue; - + } // Prioritise by fee once past the priority size or we run out of high-priority // transactions: if (!fSortedByFee && @@ -332,22 +343,28 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) } if (!view.HaveInputs(tx)) + { + //fprintf(stderr,"dont have inputs\n"); continue; - + } CAmount nTxFees = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime)-tx.GetValueOut(); nTxSigOps += GetP2SHSigOpCount(tx, view); if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1) + { + //fprintf(stderr,"B nBlockSigOps %d + %d nTxSigOps >= %d MAX_BLOCK_SIGOPS-1\n",(int32_t)nBlockSigOps,(int32_t)nTxSigOps,(int32_t)MAX_BLOCK_SIGOPS); continue; - + } // Note that flags: we don't want to set mempool/IsStandard() // policy here, but we still have to ensure that the block we // create only contains transactions that are valid in new blocks. CValidationState state; PrecomputedTransactionData txdata(tx); if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId)) + { + //fprintf(stderr,"context failure\n"); continue; - + } UpdateCoins(tx, view, nHeight); // Added @@ -384,7 +401,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; - blocktime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); //pblock->nTime = blocktime + 1; pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); //LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits); @@ -392,28 +409,20 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid,revtxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[128],*ptr; CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1); - blocktime += 2; + //if ( blocktime > pindexPrev->GetMedianTimePast()+60 ) + // blocktime = pindexPrev->GetMedianTimePast() + 60; if ( (siglen= komodo_staked(txStaked,pblock->nBits,&blocktime,&txtime,&utxotxid,&utxovout,&utxovalue,utxosig)) > 0 ) { CAmount txfees = 0; + if ( GetAdjustedTime() < blocktime-13 ) + return(0); pblock->vtx.push_back(txStaked); pblocktemplate->vTxFees.push_back(txfees); pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txStaked)); nFees += txfees; pblock->nTime = blocktime; - if ( GetAdjustedTime() < pblock->nTime ) - { - printf("need to wait %d seconds to submit: ",(int32_t)(pblock->nTime - GetAdjustedTime())); - while ( GetAdjustedTime()+30 < pblock->nTime ) - { - sleep(30); - fprintf(stderr,"%d ",(int32_t)(pblock->nTime - GetAdjustedTime())); - } - fprintf(stderr,"finished waiting\n"); - //sleep(pblock->nTime - GetAdjustedTime()); - } - - } else fprintf(stderr,"no utxos eligible for staking\n"); + //printf("PoS ht.%d t%u\n",(int32_t)chainActive.Tip()->nHeight+1,blocktime); + } else return(0); //fprintf(stderr,"no utxos eligible for staking\n"); } // Create coinbase tx @@ -428,33 +437,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Add fees txNew.vout[0].nValue += nFees; txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; - - /*if ( ASSETCHAINS_SYMBOL[0] == 0 ) - { - int32_t i,opretlen; uint8_t opret[256],*ptr; - if ( (nHeight % 60) == 0 || komodo_gateway_deposits(&txNew,(char *)"KMD",1) == 0 ) - { - if ( (opretlen= komodo_pax_opreturn((int32_t)nHeight,opret,sizeof(opret))) > 0 ) // have pricefeed - { - txNew.vout.resize(2); - txNew.vout[1].scriptPubKey.resize(opretlen); - ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data(); - for (i=0; i 1 ) - fprintf(stderr,"%s txNew numvouts.%d\n",ASSETCHAINS_SYMBOL,(int32_t)txNew.vout.size()); - }*/ - + pblock->vtx[0] = txNew; - if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission((CBlock *)&pblocktemplate->block)) != 0 ) + if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission((CBlock*)&pblocktemplate->block)) != 0 ) { int32_t i; uint8_t *ptr; txNew.vout.resize(2); @@ -484,29 +469,44 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); } - if ( ASSETCHAINS_SYMBOL[0] == 0 && NOTARY_PUBKEY33[0] != 0 && pblock->nTime < pindexPrev->nTime+60 ) - { - pblock->nTime = pindexPrev->nTime + 60; - //fprintf(stderr,"block.nTime %u vs prev.%u, gettime.%u vs adjusted.%u\n",(uint32_t)pblock->nTime,(uint32_t)(pindexPrev->nTime + 60),(uint32_t)pblock->GetBlockTime(),(uint32_t)(GetAdjustedTime() + 60)); - while ( pblock->GetBlockTime() > GetAdjustedTime() + 10 ) - sleep(1); - } pblock->nSolution.clear(); pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); - - CValidationState state; - if ( !TestBlockValidity(state, *pblock, pindexPrev, false, false)) + if ( ASSETCHAINS_SYMBOL[0] == 0 && NOTARY_PUBKEY33[0] != 0 ) { - //static uint32_t counter; - //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 ) - //fprintf(stderr,"warning: miner testblockvalidity failed\n"); - return(0); + CMutableTransaction txNotary = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1); + if ( pblock->nTime < pindexPrev->nTime+65 ) + pblock->nTime = pindexPrev->nTime + 65; + if ( komodo_notaryvin(txNotary,NOTARY_PUBKEY33) > 0 ) + { + CAmount txfees = 0; + pblock->vtx.push_back(txNotary); + pblocktemplate->vTxFees.push_back(txfees); + pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txNotary)); + nFees += txfees; + //fprintf(stderr,"added notaryvin\n"); + } + else + { + fprintf(stderr,"error adding notaryvin, need to create 0.0001 utxos\n"); + return(0); + } + } + else + { + CValidationState state; + if ( !TestBlockValidity(state, *pblock, pindexPrev, false, false)) + { + //static uint32_t counter; + //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 ) + // fprintf(stderr,"warning: miner testblockvalidity failed\n"); + return(0); + } } } return pblocktemplate.release(); } - + /* #ifdef ENABLE_WALLET boost::optional GetMinerScriptPubKey(CReserveKey& reservekey) @@ -608,6 +608,26 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) return CreateNewBlock(scriptPubKey); } +void komodo_broadcast(CBlock *pblock,int32_t limit) +{ + int32_t n = 1; + //fprintf(stderr,"broadcast new block t.%u\n",(uint32_t)time(NULL)); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + if ( pnode->hSocket == INVALID_SOCKET ) + continue; + if ( (rand() % n) == 0 ) + { + pnode->PushMessage("block", *pblock); + if ( n++ > limit ) + break; + } + } + } + //fprintf(stderr,"finished broadcast new block t.%u\n",(uint32_t)time(NULL)); +} static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) #else @@ -659,7 +679,7 @@ static bool ProcessBlockFound(CBlock* pblock) return error("KomodoMiner: ProcessNewBlock, block not accepted"); TrackMinedBlock(pblock->GetHash()); - + komodo_broadcast(pblock,16); return true; } @@ -669,7 +689,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he int32_t FOUND_BLOCK,KOMODO_MAYBEMINED; extern int32_t KOMODO_LASTMINED; int32_t roundrobin_delay; -arith_uint256 HASHTarget; +arith_uint256 HASHTarget,HASHTarget_POW; #ifdef ENABLE_WALLET void static BitcoinMiner(CWallet *pwallet) @@ -734,7 +754,7 @@ void static BitcoinMiner() do { bool fvNodesEmpty; { - LOCK(cs_vNodes); + //LOCK(cs_vNodes); fvNodesEmpty = vNodes.empty(); } if (!fvNodesEmpty )//&& !IsInitialBlockDownload()) @@ -776,6 +796,7 @@ void static BitcoinMiner() static uint32_t counter; if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 ) fprintf(stderr,"created illegal block, retry\n"); + sleep(1); continue; } unique_ptr pblocktemplate(ptr); @@ -818,6 +839,9 @@ void static BitcoinMiner() j = 65; if ( (Mining_height >= 235300 && Mining_height < 236000) || (Mining_height % KOMODO_ELECTION_GAP) > 64 || (Mining_height % KOMODO_ELECTION_GAP) == 0 ) { + int32_t dispflag = 0; + if ( notaryid <= 3 || notaryid == 32 || (notaryid >= 43 && notaryid <= 45) ||notaryid == 51 || notaryid == 52 || notaryid == 56 || notaryid == 57 || notaryid == 62 ) + dispflag = 1; komodo_eligiblenotary(pubkeys,mids,blocktimes,&nonzpkeys,pindexPrev->nHeight); if ( nonzpkeys > 0 ) { @@ -827,18 +851,21 @@ void static BitcoinMiner() if ( i == 33 ) externalflag = 1; else externalflag = 0; - if ( NOTARY_PUBKEY33[0] != 0 && (notaryid < 3 || notaryid == 34 || notaryid == 51 || notaryid == 52) ) + if ( NOTARY_PUBKEY33[0] != 0 ) { for (i=1; i<66; i++) if ( memcmp(pubkeys[i],pubkeys[0],33) == 0 ) break; - if ( externalflag == 0 && i != 66 ) - printf("VIOLATION at %d\n",i); + if ( externalflag == 0 && i != 66 && mids[i] >= 0 ) + printf("VIOLATION at %d, notaryid.%d\n",i,mids[i]); for (j=gpucount=0; j<65; j++) { - if ( mids[j] >= 0 || notaryid == 34 ) - fprintf(stderr,"%d ",mids[j]); - else fprintf(stderr,"GPU "); + if ( dispflag != 0 ) + { + if ( mids[j] >= 0 ) + fprintf(stderr,"%d ",mids[j]); + else fprintf(stderr,"GPU "); + } if ( mids[j] == -1 ) gpucount++; } @@ -852,7 +879,8 @@ void static BitcoinMiner() roundrobin_delay += ((delta * i) / 64) - delta; //fprintf(stderr,"delta.%f %f %f\n",delta,(double)(gpucount - j/3) / 2,(delta * i) / 64); } - fprintf(stderr," <- prev minerids from ht.%d notary.%d gpucount.%d %.2f%% t.%u %d\n",pindexPrev->nHeight,notaryid,gpucount,100.*(double)gpucount/j,(uint32_t)time(NULL),roundrobin_delay); + if ( dispflag != 0 ) + fprintf(stderr," <- prev minerids from ht.%d notary.%d gpucount.%d %.2f%% t.%u %d\n",pindexPrev->nHeight,notaryid,gpucount,100.*(double)gpucount/j,(uint32_t)time(NULL),roundrobin_delay); } for (j=0; j<65; j++) if ( mids[j] == notaryid ) @@ -870,15 +898,15 @@ void static BitcoinMiner() if ( ASSETCHAINS_STAKED != 0 && NOTARY_PUBKEY33[0] == 0 ) { int32_t percPoS,z; - if ( Mining_height <= 100 ) + /*if ( Mining_height <= 100 ) { sleep(60); continue; - } - HASHTarget = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED); + }*/ + HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED); for (z=31; z>=0; z--) - fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]); - fprintf(stderr," PoW for staked coin\n"); + fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]); + fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%%\n",percPoS,(int32_t)ASSETCHAINS_STAKED); } while (true) { @@ -904,8 +932,10 @@ void static BitcoinMiner() crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size()); // (x_1, x_2, ...) = A(I, V, n, k) LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString()); - arith_uint256 hashTarget = HASHTarget; - //fprintf(stderr,"running solver\n"); + arith_uint256 hashTarget; + if ( NOTARY_PUBKEY33[0] == 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 ) + hashTarget = HASHTarget_POW; + else hashTarget = HASHTarget; std::function)> validBlock = #ifdef ENABLE_WALLET [&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams] @@ -913,62 +943,79 @@ void static BitcoinMiner() [&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams] #endif (std::vector soln) { + int32_t z; arith_uint256 h; CBlock B; // Write the solution to the hash and compute the result. LogPrint("pow", "- Checking solution against target\n"); pblock->nSolution = soln; solutionTargetChecks.increment(); - if ( UintToArith256(pblock->GetHash()) > HASHTarget ) - { - //if ( ASSETCHAINS_SYMBOL[0] != 0 ) - // fprintf(stderr," missed target\n"); + B = *pblock; + h = UintToArith256(B.GetHash()); + if ( h > hashTarget ) return false; - } - CValidationState state; - if ( !TestBlockValidity(state, *pblock, chainActive.Tip(), true, false)) + /*for (z=31; z>=16; z--) + fprintf(stderr,"%02x",((uint8_t *)&h)[z]); + fprintf(stderr," mined "); + for (z=31; z>=16; z--) + fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]); + fprintf(stderr," hashTarget "); + for (z=31; z>=16; z--) + fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]); + fprintf(stderr," POW\n");*/ + if ( NOTARY_PUBKEY33[0] != 0 && B.nTime > GetAdjustedTime() ) { - fprintf(stderr,"Invalid block mined, try again\n"); - return(false); + fprintf(stderr,"need to wait %d seconds to submit block\n",(int32_t)(B.nTime - GetAdjustedTime())); + while ( GetAdjustedTime() < B.nTime-2 ) + { + sleep(1); + if ( chainActive.Tip()->nHeight >= Mining_height ) + { + fprintf(stderr,"new block arrived\n"); + return(false); + } + } } if ( ASSETCHAINS_STAKED == 0 ) { - if ( Mining_start != 0 && time(NULL) < Mining_start+roundrobin_delay ) + if ( NOTARY_PUBKEY33[0] != 0 ) { - //printf("Round robin diff sleep %d\n",(int32_t)(Mining_start+roundrobin_delay-time(NULL))); - //int32_t nseconds = Mining_start+roundrobin_delay-time(NULL); - //if ( nseconds > 0 ) - // sleep(nseconds); - MilliSleep((rand() % 1700) + 1); - } - else if ( ASSETCHAINS_SYMBOL[0] != 0 ) - { - sleep(rand() % 30); + int32_t r; + if ( (r= ((Mining_height + NOTARY_PUBKEY33[16]) % 64) / 8) > 0 ) + MilliSleep((rand() % (r * 1000)) + 1000); } } else { if ( NOTARY_PUBKEY33[0] != 0 ) { - printf("need to wait %d seconds to submit\n",(int32_t)(pblock->nTime - GetAdjustedTime())); - while ( GetAdjustedTime() < pblock->nTime ) + while ( GetAdjustedTime() < B.nTime ) sleep(1); } else { - uint256 tmp = pblock->GetHash(); + uint256 tmp = B.GetHash(); int32_t z; for (z=31; z>=0; z--) fprintf(stderr,"%02x",((uint8_t *)&tmp)[z]); fprintf(stderr," mined block!\n"); } } + CValidationState state; + if ( !TestBlockValidity(state,B, chainActive.Tip(), true, false)) + { + h = UintToArith256(B.GetHash()); + for (z=31; z>=0; z--) + fprintf(stderr,"%02x",((uint8_t *)&h)[z]); + fprintf(stderr," Invalid block mined, try again\n"); + return(false); + } KOMODO_CHOSEN_ONE = 1; // Found a solution SetThreadPriority(THREAD_PRIORITY_NORMAL); LogPrintf("KomodoMiner:\n"); - LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), HASHTarget.GetHex()); + LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", B.GetHash().GetHex(), HASHTarget.GetHex()); #ifdef ENABLE_WALLET - if (ProcessBlockFound(pblock, *pwallet, reservekey)) { + if (ProcessBlockFound(&B, *pwallet, reservekey)) { #else - if (ProcessBlockFound(pblock)) { + if (ProcessBlockFound(&B)) { #endif // Ignore chain updates caused by us std::lock_guard lock{m_cs}; @@ -1083,13 +1130,17 @@ void static BitcoinMiner() // Update nNonce and nTime pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); pblock->nBits = savebits; - if ( ASSETCHAINS_STAKED == 0 || NOTARY_PUBKEY33[0] == 0 ) - UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); - if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks) + /*if ( NOTARY_PUBKEY33[0] == 0 ) { - // Changing pblock->nTime can change work required on testnet: - HASHTarget.SetCompact(pblock->nBits); - } + int32_t percPoS; + UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); + if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks) + { + // Changing pblock->nTime can change work required on testnet: + HASHTarget.SetCompact(pblock->nBits); + HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED); + } + }*/ } } } diff --git a/src/paymentdisclosure.h b/src/paymentdisclosure.h index e6a995ab4..fddb25bbe 100644 --- a/src/paymentdisclosure.h +++ b/src/paymentdisclosure.h @@ -73,7 +73,11 @@ struct PaymentDisclosurePayload { uint8_t version; // 0 = experimental, 1 = first production version, etc. uint256 esk; // zcash/NoteEncryption.cpp uint256 txid; // primitives/transaction.h + #ifdef __LP64__ + uint64_t js; + #else size_t js; // Index into CTransaction.vjoinsplit + #endif uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS libzcash::PaymentAddress zaddr; // zcash/Address.hpp std::string message; // parameter to RPC call diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index e1fb1c3c6..e4ff99246 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -53,13 +53,13 @@ void TxConfirmStats::ClearCurrent(unsigned int nBlockHeight) unsigned int TxConfirmStats::FindBucketIndex(double val) { - extern char ASSETCHAINS_SYMBOL[]; + extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; auto it = bucketMap.lower_bound(val); if ( it != bucketMap.end() ) { - static uint32_t counter; - if ( counter++ < 1 ) - fprintf(stderr,"%s FindBucketIndex violation: from val %f\n",ASSETCHAINS_SYMBOL,val); + //static uint32_t counter; + //if ( counter++ < 1 ) + // fprintf(stderr,"%s FindBucketIndex violation: from val %f\n",ASSETCHAINS_SYMBOL,val); } return it->second; } diff --git a/src/pow.cpp b/src/pow.cpp index 9ea947b00..817dcc1fe 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -123,7 +123,7 @@ CBlockIndex *komodo_chainactive(int32_t height); void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height); extern int32_t KOMODO_CHOSEN_ONE; extern uint64_t ASSETCHAINS_STAKED; -extern char ASSETCHAINS_SYMBOL[]; +extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; #define KOMODO_ELECTION_GAP 2000 int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height); @@ -136,6 +136,9 @@ bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash,unsigned int extern int32_t KOMODO_REWIND; bool fNegative,fOverflow; uint8_t origpubkey33[33]; int32_t i,nonzpkeys=0,nonz=0,special=0,special2=0,notaryid=-1,flag = 0, mids[66]; uint32_t tiptime,blocktimes[66]; arith_uint256 bnTarget; uint8_t pubkeys[66][33]; + //for (i=31; i>=0; i--) + // fprintf(stderr,"%02x",((uint8_t *)&hash)[i]); + //fprintf(stderr," checkpow\n"); memcpy(origpubkey33,pubkey33,33); memset(blocktimes,0,sizeof(blocktimes)); tiptime = komodo_chainactive_timestamp(); @@ -192,23 +195,20 @@ bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash,unsigned int return true; if ( ASSETCHAINS_SYMBOL[0] != 0 || height > 792000 ) { - if ( 1 && height > 792000 ) + //if ( 0 && height > 792000 ) { for (i=31; i>=0; i--) - printf("%02x",((uint8_t *)&hash)[i]); - printf(" hash vs "); + fprintf(stderr,"%02x",((uint8_t *)&hash)[i]); + fprintf(stderr," hash vs "); for (i=31; i>=0; i--) - printf("%02x",((uint8_t *)&bnTarget)[i]); - printf(" ht.%d special.%d notaryid.%d ht.%d mod.%d error\n",height,special,notaryid,height,(height % 35)); + fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]); + fprintf(stderr," ht.%d special.%d special2.%d flag.%d notaryid.%d mod.%d error\n",height,special,special2,flag,notaryid,(height % 35)); for (i=0; i<33; i++) - printf("%02x",pubkey33[i]); - printf(" <- pubkey\n"); + fprintf(stderr,"%02x",pubkey33[i]); + fprintf(stderr," <- pubkey\n"); for (i=0; i<33; i++) - printf("%02x",origpubkey33[i]); - printf(" <- origpubkey\n"); - for (i=0; i<66; i++) - printf("%d ",mids[i]); - printf(" minerids from ht.%d\n",height); + fprintf(stderr,"%02x",origpubkey33[i]); + fprintf(stderr," <- origpubkey\n"); } return false; } diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index d8a0a184b..170e45d59 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -264,7 +264,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (wtx.IsCoinBase()) { - extern char ASSETCHAINS_SYMBOL[]; + extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; if ( ASSETCHAINS_SYMBOL[0] == 0 ) COINBASE_MATURITY = _COINBASE_MATURITY; quint32 numBlocksToMaturity = COINBASE_MATURITY + 1; diff --git a/src/rest.cpp b/src/rest.cpp index eb0bf8fc4..8e2e4d1e6 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -214,7 +214,7 @@ static bool rest_block(HTTPRequest* req, if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); - if (!ReadBlockFromDisk(block, pblockindex)) + if (!ReadBlockFromDisk(block, pblockindex,1)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } @@ -563,7 +563,6 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) utxo.push_back(Pair("txvers", (int32_t)coin.nTxVer)); utxo.push_back(Pair("height", (int32_t)coin.nHeight)); utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue))); - //utxo.push_back(Pair("interest", ValueFromAmount(komodo_interest(coin.out.nValue,coin.nLockTime,chainActive.Tip()->nTime)))); // include the script in a json output UniValue o(UniValue::VOBJ); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 93feb57c6..fc6092e03 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -7,6 +7,7 @@ #include "chain.h" #include "chainparams.h" #include "checkpoints.h" +#include "base58.h" #include "consensus/validation.h" #include "cc/betprotocol.h" #include "main.h" @@ -14,6 +15,10 @@ #include "rpcserver.h" #include "sync.h" #include "util.h" +#include "script/script.h" +#include "script/script_error.h" +#include "script/sign.h" +#include "script/standard.h" #include @@ -124,6 +129,112 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) return result; } +UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex) +{ + UniValue result(UniValue::VOBJ); + result.push_back(Pair("hash", block.GetHash().GetHex())); + int confirmations = -1; + // Only report confirmations if the block is on the main chain + if (chainActive.Contains(blockindex)) { + confirmations = chainActive.Height() - blockindex->nHeight + 1; + } else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block is an orphan"); + } + result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); + + UniValue deltas(UniValue::VARR); + + for (unsigned int i = 0; i < block.vtx.size(); i++) { + const CTransaction &tx = block.vtx[i]; + const uint256 txhash = tx.GetHash(); + + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("txid", txhash.GetHex())); + entry.push_back(Pair("index", (int)i)); + + UniValue inputs(UniValue::VARR); + + if (!tx.IsCoinBase()) { + + for (size_t j = 0; j < tx.vin.size(); j++) { + const CTxIn input = tx.vin[j]; + + UniValue delta(UniValue::VOBJ); + + CSpentIndexValue spentInfo; + CSpentIndexKey spentKey(input.prevout.hash, input.prevout.n); + + if (GetSpentIndex(spentKey, spentInfo)) { + if (spentInfo.addressType == 1) { + delta.push_back(Pair("address", CBitcoinAddress(CKeyID(spentInfo.addressHash)).ToString())); + } else if (spentInfo.addressType == 2) { + delta.push_back(Pair("address", CBitcoinAddress(CScriptID(spentInfo.addressHash)).ToString())); + } else { + continue; + } + delta.push_back(Pair("satoshis", -1 * spentInfo.satoshis)); + delta.push_back(Pair("index", (int)j)); + delta.push_back(Pair("prevtxid", input.prevout.hash.GetHex())); + delta.push_back(Pair("prevout", (int)input.prevout.n)); + + inputs.push_back(delta); + } else { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Spent information not available"); + } + + } + } + + entry.push_back(Pair("inputs", inputs)); + + UniValue outputs(UniValue::VARR); + + for (unsigned int k = 0; k < tx.vout.size(); k++) { + const CTxOut &out = tx.vout[k]; + + UniValue delta(UniValue::VOBJ); + + if (out.scriptPubKey.IsPayToScriptHash()) { + vector hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22); + delta.push_back(Pair("address", CBitcoinAddress(CScriptID(uint160(hashBytes))).ToString())); + + } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { + vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); + delta.push_back(Pair("address", CBitcoinAddress(CKeyID(uint160(hashBytes))).ToString())); + } else { + continue; + } + + delta.push_back(Pair("satoshis", out.nValue)); + delta.push_back(Pair("index", (int)k)); + + outputs.push_back(delta); + } + + entry.push_back(Pair("outputs", outputs)); + deltas.push_back(entry); + + } + result.push_back(Pair("deltas", deltas)); + result.push_back(Pair("time", block.GetBlockTime())); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); + result.push_back(Pair("nonce", block.nNonce.GetHex())); + result.push_back(Pair("bits", strprintf("%08x", block.nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + CBlockIndex *pnext = chainActive.Next(blockindex); + if (pnext) + result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + return result; +} + UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { UniValue result(UniValue::VOBJ); @@ -310,6 +421,102 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) return mempoolToJSON(fVerbose); } +UniValue getblockdeltas(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error(""); + + std::string strHash = params[0].get_str(); + uint256 hash(uint256S(strHash)); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); + + if(!ReadBlockFromDisk(block, pblockindex,1)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); + + return blockToDeltasJSON(block, pblockindex); +} + +UniValue getblockhashes(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 2) + throw runtime_error( + "getblockhashes timestamp\n" + "\nReturns array of hashes of blocks within the timestamp range provided.\n" + "\nArguments:\n" + "1. high (numeric, required) The newer block timestamp\n" + "2. low (numeric, required) The older block timestamp\n" + "3. options (string, required) A json object\n" + " {\n" + " \"noOrphans\":true (boolean) will only include blocks on the main chain\n" + " \"logicalTimes\":true (boolean) will include logical timestamps with hashes\n" + " }\n" + "\nResult:\n" + "[\n" + " \"hash\" (string) The block hash\n" + "]\n" + "[\n" + " {\n" + " \"blockhash\": (string) The block hash\n" + " \"logicalts\": (numeric) The logical timestamp\n" + " }\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getblockhashes", "1231614698 1231024505") + + HelpExampleRpc("getblockhashes", "1231614698, 1231024505") + + HelpExampleCli("getblockhashes", "1231614698 1231024505 '{\"noOrphans\":false, \"logicalTimes\":true}'") + ); + + unsigned int high = params[0].get_int(); + unsigned int low = params[1].get_int(); + bool fActiveOnly = false; + bool fLogicalTS = false; + + if (params.size() > 2) { + if (params[2].isObject()) { + UniValue noOrphans = find_value(params[2].get_obj(), "noOrphans"); + UniValue returnLogical = find_value(params[2].get_obj(), "logicalTimes"); + + if (noOrphans.isBool()) + fActiveOnly = noOrphans.get_bool(); + + if (returnLogical.isBool()) + fLogicalTS = returnLogical.get_bool(); + } + } + + std::vector > blockHashes; + + if (fActiveOnly) + LOCK(cs_main); + + if (!GetTimestampIndex(high, low, fActiveOnly, blockHashes)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for block hashes"); + } + + UniValue result(UniValue::VARR); + + for (std::vector >::const_iterator it=blockHashes.begin(); it!=blockHashes.end(); it++) { + if (fLogicalTS) { + UniValue item(UniValue::VOBJ); + item.push_back(Pair("blockhash", it->first.GetHex())); + item.push_back(Pair("logicalts", (int)it->second)); + result.push_back(item); + } else { + result.push_back(it->first.GetHex()); + } + } + + return result; +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -486,7 +693,7 @@ UniValue getblock(const UniValue& params, bool fHelp) if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); - if(!ReadBlockFromDisk(block, pblockindex)) + if(!ReadBlockFromDisk(block, pblockindex,1)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); if (!fVerbose) @@ -539,20 +746,22 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) } #include "komodo_defs.h" +#include "komodo_structs.h" #define IGUANA_MAXSCRIPTSIZE 10001 #define KOMODO_KVDURATION 1440 #define KOMODO_KVBINARY 2 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume); int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel); int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); -//uint32_t komodo_interest_args(int32_t *txheightp,uint32_t *tiptimep,uint64_t *valuep,uint256 hash,int32_t n); int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width); int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); -//int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); +int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); +int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height); +struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi); +uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth); UniValue kvsearch(const UniValue& params, bool fHelp) { @@ -589,7 +798,93 @@ UniValue kvsearch(const UniValue& params, bool fHelp) return ret; } -/* +UniValue allMoMs(const UniValue& params, bool fHelp) +{ + struct komodo_ccdata_entry *allMoMs; uint256 MoMoM; int32_t num,i,kmdstarti,kmdendi; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); + if ( fHelp || params.size() != 2 ) + throw runtime_error("allMoMs kmdstarti kmdendi\n"); + LOCK(cs_main); + kmdstarti = atoi(params[0].get_str().c_str()); + kmdendi = atoi(params[1].get_str().c_str()); + ret.push_back(Pair("kmdstarti",kmdstarti)); + ret.push_back(Pair("kmdendi",kmdendi)); + if ( (allMoMs= komodo_allMoMs(&num,&MoMoM,kmdstarti,kmdendi)) != 0 ) + { + for (i=0; i= height ) + throw runtime_error("calc_MoM illegal height or MoMdepth\n"); + //fprintf(stderr,"height_MoM height.%d\n",height); + MoM = komodo_calcMoM(height,MoMdepth); + ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); + ret.push_back(Pair("height",height)); + ret.push_back(Pair("MoMdepth",MoMdepth)); + ret.push_back(Pair("MoM",MoM.GetHex())); + return ret; +} + UniValue height_MoM(const UniValue& params, bool fHelp) { int32_t height,depth,notarized_height,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; uint256 MoM,MoMoM,kmdtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); @@ -685,7 +980,7 @@ UniValue txMoMproof(const UniValue& params, bool fHelp) if (fHavePruned && !(blockIndex->nStatus & BLOCK_HAVE_DATA) && blockIndex->nTx > 0) throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); - if(!ReadBlockFromDisk(block, blockIndex)) + if(!ReadBlockFromDisk(block, blockIndex,1)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); // Locate the transaction in the block @@ -717,7 +1012,6 @@ UniValue txMoMproof(const UniValue& params, bool fHelp) ssProof << MoMProof(nIndex, branch, notarisationHash); return HexStr(ssProof.begin(), ssProof.end()); } -*/ UniValue minerids(const UniValue& params, bool fHelp) { @@ -772,6 +1066,7 @@ UniValue minerids(const UniValue& params, bool fHelp) a.push_back(item); } ret.push_back(Pair("mined", a)); + ret.push_back(Pair("numnotaries", numnotaries)); } else ret.push_back(Pair("error", (char *)"couldnt extract minerids")); return ret; } diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 799dca34f..5b3f0c9eb 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -96,6 +96,15 @@ static const CRPCConvertParam vRPCConvertParams[] = { "prioritisetransaction", 2 }, { "setban", 2 }, { "setban", 3 }, + { "getblockhashes", 0 }, + { "getblockhashes", 1 }, + { "getblockhashes", 2 }, + { "getspentinfo", 0}, + { "getaddresstxids", 0}, + { "getaddressbalance", 0}, + { "getaddressdeltas", 0}, + { "getaddressutxos", 0}, + { "getaddressmempool", 0}, { "zcrawjoinsplit", 1 }, { "zcrawjoinsplit", 2 }, { "zcrawjoinsplit", 3 }, @@ -125,8 +134,10 @@ static const CRPCConvertParam vRPCConvertParams[] = { "paxprices", 3 }, { "paxpending", 0 }, { "notaries", 2 }, - //{ "height_MoM", 1 }, - //{ "txMoMproof", 1 }, + { "height_MoM", 1 }, + { "MoMoMdata", 3 }, + { "allMoMs", 2 }, + { "txMoMproof", 1 }, { "minerids", 1 }, { "kvsearch", 1 }, { "kvupdate", 4 }, diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 682298485..c356ef994 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -11,6 +11,7 @@ #include "netbase.h" #include "rpcserver.h" #include "timedata.h" +#include "txmempool.h" #include "util.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" @@ -45,18 +46,22 @@ int32_t Jumblr_depositaddradd(char *depositaddr); int32_t Jumblr_secretaddradd(char *secretaddr); uint64_t komodo_interestsum(); int32_t komodo_longestchain(); -int32_t komodo_notarized_height(uint256 *hashp,uint256 *txidp); +int32_t komodo_notarized_height(int32_t *prevhtp,uint256 *hashp,uint256 *txidp); uint32_t komodo_chainactive_timestamp(); int32_t komodo_whoami(char *pubkeystr,int32_t height,uint32_t timestamp); -extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE; -extern char ASSETCHAINS_SYMBOL[]; +extern uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; +extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE,KOMODO_LONGESTCHAIN; +extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp); #define KOMODO_VERSION "0.1.1" -uint32_t komodo_chainactive_timestamp(); +extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; +extern uint32_t ASSETCHAINS_CC; +extern uint32_t ASSETCHAINS_MAGIC; +extern uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY; UniValue getinfo(const UniValue& params, bool fHelp) { - uint256 notarized_hash,notarized_desttxid; int32_t notarized_height,longestchain,kmdnotarized_height,txid_height; + uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,longestchain,kmdnotarized_height,txid_height; if (fHelp || params.size() != 0) throw runtime_error( "getinfo\n" @@ -84,22 +89,23 @@ UniValue getinfo(const UniValue& params, bool fHelp) + HelpExampleCli("getinfo", "") + HelpExampleRpc("getinfo", "") ); - -#ifdef ENABLE_WALLET - LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); -#else +//#ifdef ENABLE_WALLET +// LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); +//#else LOCK(cs_main); -#endif +//#endif proxyType proxy; GetProxy(NET_IPV4, proxy); - notarized_height = komodo_notarized_height(¬arized_hash,¬arized_desttxid); + notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid); + //fprintf(stderr,"after notarized_height %u\n",(uint32_t)time(NULL)); UniValue obj(UniValue::VOBJ); obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); obj.push_back(Pair("KMDversion", KOMODO_VERSION)); obj.push_back(Pair("notarized", notarized_height)); + obj.push_back(Pair("prevMoMheight", prevMoMheight)); obj.push_back(Pair("notarizedhash", notarized_hash.ToString())); obj.push_back(Pair("notarizedtxid", notarized_desttxid.ToString())); txid_height = notarizedtxid_height(ASSETCHAINS_SYMBOL[0] != 0 ? (char *)"KMD" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&kmdnotarized_height); @@ -109,17 +115,20 @@ UniValue getinfo(const UniValue& params, bool fHelp) if ( ASSETCHAINS_SYMBOL[0] != 0 ) obj.push_back(Pair("KMDnotarized_height", kmdnotarized_height)); obj.push_back(Pair("notarized_confirms", txid_height < kmdnotarized_height ? (kmdnotarized_height - txid_height + 1) : 0)); + //fprintf(stderr,"after notarized_confirms %u\n",(uint32_t)time(NULL)); #ifdef ENABLE_WALLET if (pwalletMain) { obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); - obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); + obj.push_back(Pair("balance", ValueFromAmount(KOMODO_WALLETBALANCE))); //pwalletMain->GetBalance() if ( ASSETCHAINS_SYMBOL[0] == 0 ) - obj.push_back(Pair("interest", ValueFromAmount(komodo_interestsum()))); + obj.push_back(Pair("interest", ValueFromAmount(KOMODO_INTERESTSUM))); //komodo_interestsum() } #endif + //fprintf(stderr,"after wallet %u\n",(uint32_t)time(NULL)); obj.push_back(Pair("blocks", (int)chainActive.Height())); - if ( (longestchain= komodo_longestchain()) != 0 && chainActive.Height() > longestchain ) + if ( (longestchain= KOMODO_LONGESTCHAIN) != 0 && chainActive.Height() > longestchain ) longestchain = chainActive.Height(); + //fprintf(stderr,"after longestchain %u\n",(uint32_t)time(NULL)); obj.push_back(Pair("longestchain", longestchain)); obj.push_back(Pair("timeoffset", GetTimeOffset())); if ( chainActive.Tip() != 0 ) @@ -149,6 +158,30 @@ UniValue getinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("lastmined", KOMODO_LASTMINED)); } } + if ( ASSETCHAINS_CC != 0 ) + obj.push_back(Pair("CCid", (int)ASSETCHAINS_CC)); + obj.push_back(Pair("name", ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL)); + if ( ASSETCHAINS_SYMBOL[0] != 0 ) + { + //obj.push_back(Pair("name", ASSETCHAINS_SYMBOL)); + obj.push_back(Pair("p2pport", ASSETCHAINS_P2PPORT)); + obj.push_back(Pair("rpcport", ASSETCHAINS_RPCPORT)); + obj.push_back(Pair("magic", (int)ASSETCHAINS_MAGIC)); + if ( ASSETCHAINS_SUPPLY != 0 ) + obj.push_back(Pair("premine", ASSETCHAINS_SUPPLY)); + if ( ASSETCHAINS_REWARD != 0 ) + obj.push_back(Pair("reward", ASSETCHAINS_REWARD)); + if ( ASSETCHAINS_HALVING != 0 ) + obj.push_back(Pair("halving", ASSETCHAINS_HALVING)); + if ( ASSETCHAINS_DECAY != 0 ) + obj.push_back(Pair("decay", ASSETCHAINS_DECAY)); + if ( ASSETCHAINS_ENDSUBSIDY != 0 ) + obj.push_back(Pair("endsubsidy", ASSETCHAINS_ENDSUBSIDY)); + if ( ASSETCHAINS_COMMISSION != 0 ) + obj.push_back(Pair("commission", ASSETCHAINS_COMMISSION)); + if ( ASSETCHAINS_STAKED != 0 ) + obj.push_back(Pair("staked", ASSETCHAINS_STAKED)); + } return obj; } @@ -562,3 +595,530 @@ UniValue setmocktime(const UniValue& params, bool fHelp) return NullUniValue; } + +bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address) +{ + if (type == 2) { + address = CBitcoinAddress(CScriptID(hash)).ToString(); + } else if (type == 1) { + address = CBitcoinAddress(CKeyID(hash)).ToString(); + } else { + return false; + } + return true; +} + +bool getAddressesFromParams(const UniValue& params, std::vector > &addresses) +{ + if (params[0].isStr()) { + CBitcoinAddress address(params[0].get_str()); + uint160 hashBytes; + int type = 0; + if (!address.GetIndexKey(hashBytes, type)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + addresses.push_back(std::make_pair(hashBytes, type)); + } else if (params[0].isObject()) { + + UniValue addressValues = find_value(params[0].get_obj(), "addresses"); + if (!addressValues.isArray()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Addresses is expected to be an array"); + } + + std::vector values = addressValues.getValues(); + + for (std::vector::iterator it = values.begin(); it != values.end(); ++it) { + + CBitcoinAddress address(it->get_str()); + uint160 hashBytes; + int type = 0; + if (!address.GetIndexKey(hashBytes, type)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + addresses.push_back(std::make_pair(hashBytes, type)); + } + } else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + + return true; +} + +bool heightSort(std::pair a, + std::pair b) { + return a.second.blockHeight < b.second.blockHeight; +} + +bool timestampSort(std::pair a, + std::pair b) { + return a.second.time < b.second.time; +} + +UniValue getaddressmempool(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressmempool\n" + "\nReturns all mempool deltas for an address (requires addressindex to be enabled).\n" + "\nArguments:\n" + "{\n" + " \"addresses\"\n" + " [\n" + " \"address\" (string) The base58check encoded address\n" + " ,...\n" + " ]\n" + "}\n" + "\nResult:\n" + "[\n" + " {\n" + " \"address\" (string) The base58check encoded address\n" + " \"txid\" (string) The related txid\n" + " \"index\" (number) The related input or output index\n" + " \"satoshis\" (number) The difference of satoshis\n" + " \"timestamp\" (number) The time the transaction entered the mempool (seconds)\n" + " \"prevtxid\" (string) The previous txid (if spending)\n" + " \"prevout\" (string) The previous transaction output index (if spending)\n" + " }\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getaddressmempool", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") + + HelpExampleRpc("getaddressmempool", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") + ); + + std::vector > addresses; + + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + + std::vector > indexes; + + if (!mempool.getAddressIndex(addresses, indexes)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + + std::sort(indexes.begin(), indexes.end(), timestampSort); + + UniValue result(UniValue::VARR); + + for (std::vector >::iterator it = indexes.begin(); + it != indexes.end(); it++) { + + std::string address; + if (!getAddressFromIndex(it->first.type, it->first.addressBytes, address)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type"); + } + + UniValue delta(UniValue::VOBJ); + delta.push_back(Pair("address", address)); + delta.push_back(Pair("txid", it->first.txhash.GetHex())); + delta.push_back(Pair("index", (int)it->first.index)); + delta.push_back(Pair("satoshis", it->second.amount)); + delta.push_back(Pair("timestamp", it->second.time)); + if (it->second.amount < 0) { + delta.push_back(Pair("prevtxid", it->second.prevhash.GetHex())); + delta.push_back(Pair("prevout", (int)it->second.prevout)); + } + result.push_back(delta); + } + + return result; +} + +UniValue getaddressutxos(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressutxos\n" + "\nReturns all unspent outputs for an address (requires addressindex to be enabled).\n" + "\nArguments:\n" + "{\n" + " \"addresses\"\n" + " [\n" + " \"address\" (string) The base58check encoded address\n" + " ,...\n" + " ],\n" + " \"chainInfo\" (boolean) Include chain info with results\n" + "}\n" + "\nResult\n" + "[\n" + " {\n" + " \"address\" (string) The address base58check encoded\n" + " \"txid\" (string) The output txid\n" + " \"height\" (number) The block height\n" + " \"outputIndex\" (number) The output index\n" + " \"script\" (strin) The script hex encoded\n" + " \"satoshis\" (number) The number of satoshis of the output\n" + " }\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getaddressutxos", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") + + HelpExampleRpc("getaddressutxos", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") + ); + + bool includeChainInfo = false; + if (params[0].isObject()) { + UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo"); + if (chainInfo.isBool()) { + includeChainInfo = chainInfo.get_bool(); + } + } + + std::vector > addresses; + + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + + std::vector > unspentOutputs; + + for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { + if (!GetAddressUnspent((*it).first, (*it).second, unspentOutputs)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } + + std::sort(unspentOutputs.begin(), unspentOutputs.end(), heightSort); + + UniValue utxos(UniValue::VARR); + + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { + UniValue output(UniValue::VOBJ); + std::string address; + if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type"); + } + + output.push_back(Pair("address", address)); + output.push_back(Pair("txid", it->first.txhash.GetHex())); + output.push_back(Pair("outputIndex", (int)it->first.index)); + output.push_back(Pair("script", HexStr(it->second.script.begin(), it->second.script.end()))); + output.push_back(Pair("satoshis", it->second.satoshis)); + output.push_back(Pair("height", it->second.blockHeight)); + utxos.push_back(output); + } + + if (includeChainInfo) { + UniValue result(UniValue::VOBJ); + result.push_back(Pair("utxos", utxos)); + + LOCK(cs_main); + result.push_back(Pair("hash", chainActive.Tip()->GetBlockHash().GetHex())); + result.push_back(Pair("height", (int)chainActive.Height())); + return result; + } else { + return utxos; + } +} + +UniValue getaddressdeltas(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1 || !params[0].isObject()) + throw runtime_error( + "getaddressdeltas\n" + "\nReturns all changes for an address (requires addressindex to be enabled).\n" + "\nArguments:\n" + "{\n" + " \"addresses\"\n" + " [\n" + " \"address\" (string) The base58check encoded address\n" + " ,...\n" + " ]\n" + " \"start\" (number) The start block height\n" + " \"end\" (number) The end block height\n" + " \"chainInfo\" (boolean) Include chain info in results, only applies if start and end specified\n" + "}\n" + "\nResult:\n" + "[\n" + " {\n" + " \"satoshis\" (number) The difference of satoshis\n" + " \"txid\" (string) The related txid\n" + " \"index\" (number) The related input or output index\n" + " \"height\" (number) The block height\n" + " \"address\" (string) The base58check encoded address\n" + " }\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getaddressdeltas", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") + + HelpExampleRpc("getaddressdeltas", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") + ); + + + UniValue startValue = find_value(params[0].get_obj(), "start"); + UniValue endValue = find_value(params[0].get_obj(), "end"); + + UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo"); + bool includeChainInfo = false; + if (chainInfo.isBool()) { + includeChainInfo = chainInfo.get_bool(); + } + + int start = 0; + int end = 0; + + if (startValue.isNum() && endValue.isNum()) { + start = startValue.get_int(); + end = endValue.get_int(); + if (start <= 0 || end <= 0) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start and end is expected to be greater than zero"); + } + if (end < start) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "End value is expected to be greater than start"); + } + } + + std::vector > addresses; + + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + + std::vector > addressIndex; + + for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { + if (start > 0 && end > 0) { + if (!GetAddressIndex((*it).first, (*it).second, addressIndex, start, end)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } else { + if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } + } + + UniValue deltas(UniValue::VARR); + + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { + std::string address; + if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type"); + } + + UniValue delta(UniValue::VOBJ); + delta.push_back(Pair("satoshis", it->second)); + delta.push_back(Pair("txid", it->first.txhash.GetHex())); + delta.push_back(Pair("index", (int)it->first.index)); + delta.push_back(Pair("blockindex", (int)it->first.txindex)); + delta.push_back(Pair("height", it->first.blockHeight)); + delta.push_back(Pair("address", address)); + deltas.push_back(delta); + } + + UniValue result(UniValue::VOBJ); + + if (includeChainInfo && start > 0 && end > 0) { + LOCK(cs_main); + + if (start > chainActive.Height() || end > chainActive.Height()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start or end is outside chain range"); + } + + CBlockIndex* startIndex = chainActive[start]; + CBlockIndex* endIndex = chainActive[end]; + + UniValue startInfo(UniValue::VOBJ); + UniValue endInfo(UniValue::VOBJ); + + startInfo.push_back(Pair("hash", startIndex->GetBlockHash().GetHex())); + startInfo.push_back(Pair("height", start)); + + endInfo.push_back(Pair("hash", endIndex->GetBlockHash().GetHex())); + endInfo.push_back(Pair("height", end)); + + result.push_back(Pair("deltas", deltas)); + result.push_back(Pair("start", startInfo)); + result.push_back(Pair("end", endInfo)); + + return result; + } else { + return deltas; + } +} + +UniValue getaddressbalance(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressbalance\n" + "\nReturns the balance for an address(es) (requires addressindex to be enabled).\n" + "\nArguments:\n" + "{\n" + " \"addresses\"\n" + " [\n" + " \"address\" (string) The base58check encoded address\n" + " ,...\n" + " ]\n" + "}\n" + "\nResult:\n" + "{\n" + " \"balance\" (string) The current balance in satoshis\n" + " \"received\" (string) The total number of satoshis received (including change)\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getaddressbalance", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") + + HelpExampleRpc("getaddressbalance", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") + ); + + std::vector > addresses; + + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + + std::vector > addressIndex; + + for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { + if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } + + CAmount balance = 0; + CAmount received = 0; + + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { + if (it->second > 0) { + received += it->second; + } + balance += it->second; + } + + UniValue result(UniValue::VOBJ); + result.push_back(Pair("balance", balance)); + result.push_back(Pair("received", received)); + + return result; + +} + +UniValue getaddresstxids(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddresstxids\n" + "\nReturns the txids for an address(es) (requires addressindex to be enabled).\n" + "\nArguments:\n" + "{\n" + " \"addresses\"\n" + " [\n" + " \"address\" (string) The base58check encoded address\n" + " ,...\n" + " ]\n" + " \"start\" (number) The start block height\n" + " \"end\" (number) The end block height\n" + "}\n" + "\nResult:\n" + "[\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getaddresstxids", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") + + HelpExampleRpc("getaddresstxids", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") + ); + + std::vector > addresses; + + if (!getAddressesFromParams(params, addresses)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + + int start = 0; + int end = 0; + if (params[0].isObject()) { + UniValue startValue = find_value(params[0].get_obj(), "start"); + UniValue endValue = find_value(params[0].get_obj(), "end"); + if (startValue.isNum() && endValue.isNum()) { + start = startValue.get_int(); + end = endValue.get_int(); + } + } + + std::vector > addressIndex; + + for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { + if (start > 0 && end > 0) { + if (!GetAddressIndex((*it).first, (*it).second, addressIndex, start, end)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } else { + if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); + } + } + } + + std::set > txids; + UniValue result(UniValue::VARR); + + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { + int height = it->first.blockHeight; + std::string txid = it->first.txhash.GetHex(); + + if (addresses.size() > 1) { + txids.insert(std::make_pair(height, txid)); + } else { + if (txids.insert(std::make_pair(height, txid)).second) { + result.push_back(txid); + } + } + } + + if (addresses.size() > 1) { + for (std::set >::const_iterator it=txids.begin(); it!=txids.end(); it++) { + result.push_back(it->second); + } + } + + return result; + +} + +UniValue getspentinfo(const UniValue& params, bool fHelp) +{ + + if (fHelp || params.size() != 1 || !params[0].isObject()) + throw runtime_error( + "getspentinfo\n" + "\nReturns the txid and index where an output is spent.\n" + "\nArguments:\n" + "{\n" + " \"txid\" (string) The hex string of the txid\n" + " \"index\" (number) The start block height\n" + "}\n" + "\nResult:\n" + "{\n" + " \"txid\" (string) The transaction id\n" + " \"index\" (number) The spending input index\n" + " ,...\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getspentinfo", "'{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}'") + + HelpExampleRpc("getspentinfo", "{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}") + ); + + UniValue txidValue = find_value(params[0].get_obj(), "txid"); + UniValue indexValue = find_value(params[0].get_obj(), "index"); + + if (!txidValue.isStr() || !indexValue.isNum()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid txid or index"); + } + + uint256 txid = ParseHashV(txidValue, "txid"); + int outputIndex = indexValue.get_int(); + + CSpentIndexKey key(txid, outputIndex); + CSpentIndexValue value; + + if (!GetSpentIndex(key, value)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get spent info"); + } + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("txid", value.txid.GetHex())); + obj.push_back(Pair("index", (int)value.inputIndex)); + obj.push_back(Pair("height", value.blockHeight)); + + return obj; +} diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 79f2b0cdd..ec4c7be2a 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -169,11 +169,14 @@ int32_t KOMODO_LONGESTCHAIN; int32_t komodo_longestchain() { int32_t ht,n=0,num=0,maxheight=0,height = 0; - LOCK(cs_main); vector vstats; - CopyNodeStats(vstats); + { + LOCK(cs_main); + CopyNodeStats(vstats); + } BOOST_FOREACH(const CNodeStats& stats, vstats) { + //fprintf(stderr,"komodo_longestchain iter.%d\n",n); CNodeStateStats statestats; bool fStateStats = GetNodeStateStats(stats.nodeid,statestats); ht = 0; diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 7bfe1269a..5f349096a 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -57,7 +57,6 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud out.push_back(Pair("addresses", a)); } - UniValue TxJoinSplitToJSON(const CTransaction& tx) { UniValue vjoinsplit(UniValue::VARR); for (unsigned int i = 0; i < tx.vjoinsplit.size(); i++) { @@ -65,7 +64,9 @@ UniValue TxJoinSplitToJSON(const CTransaction& tx) { UniValue joinsplit(UniValue::VOBJ); joinsplit.push_back(Pair("vpub_old", ValueFromAmount(jsdescription.vpub_old))); + joinsplit.push_back(Pair("vpub_oldZat", jsdescription.vpub_old)); joinsplit.push_back(Pair("vpub_new", ValueFromAmount(jsdescription.vpub_new))); + joinsplit.push_back(Pair("vpub_newZat", jsdescription.vpub_new)); joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex())); @@ -113,11 +114,12 @@ UniValue TxJoinSplitToJSON(const CTransaction& tx) { return vjoinsplit; } -uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); -void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) +void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, int nHeight = 0, int nConfirmations = 0, int nBlockTime = 0) { - entry.push_back(Pair("txid", tx.GetHash().GetHex())); + uint256 txid = tx.GetHash(); + entry.push_back(Pair("txid", txid.GetHex())); entry.push_back(Pair("overwintered", tx.fOverwintered)); entry.push_back(Pair("version", tx.nVersion)); if (tx.fOverwintered) { @@ -135,10 +137,31 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) else { in.push_back(Pair("txid", txin.prevout.hash.GetHex())); in.push_back(Pair("vout", (int64_t)txin.prevout.n)); + { + uint256 hash; CTransaction tx; CTxDestination address; + if (GetTransaction(txin.prevout.hash,tx,hash,false)) + { + if (ExtractDestination(tx.vout[txin.prevout.n].scriptPubKey, address)) + in.push_back(Pair("address", CBitcoinAddress(address).ToString())); + } + } UniValue o(UniValue::VOBJ); o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); + + // Add address and value info if spentindex enabled + CSpentIndexValue spentInfo; + CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n); + if (GetSpentIndex(spentKey, spentInfo)) { + in.push_back(Pair("value", ValueFromAmount(spentInfo.satoshis))); + in.push_back(Pair("valueSat", spentInfo.satoshis)); + if (spentInfo.addressType == 1) { + in.push_back(Pair("address", CBitcoinAddress(CKeyID(spentInfo.addressHash)).ToString())); + } else if (spentInfo.addressType == 2) { + in.push_back(Pair("address", CBitcoinAddress(CScriptID(spentInfo.addressHash)).ToString())); + } + } } in.push_back(Pair("sequence", (int64_t)txin.nSequence)); vin.push_back(in); @@ -152,16 +175,28 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - if ( pindex != 0 && tx.nLockTime > 500000000 && (tipindex= chainActive.Tip()) != 0 ) + if ( pindex != 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.Tip()) != 0 ) { - interest = komodo_interest(pindex->nHeight,txout.nValue,tx.nLockTime,tipindex->nTime); + int64_t interest; int32_t txheight; uint32_t locktime; + interest = komodo_accrued_interest(&txheight,&locktime,tx.GetHash(),i,0,txout.nValue,(int32_t)tipindex->nHeight); out.push_back(Pair("interest", ValueFromAmount(interest))); } out.push_back(Pair("valueZat", txout.nValue)); + out.push_back(Pair("valueSat", txout.nValue)); // [+] Decker out.push_back(Pair("n", (int64_t)i)); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, true); out.push_back(Pair("scriptPubKey", o)); + + // Add spent information if spentindex is enabled + CSpentIndexValue spentInfo; + CSpentIndexKey spentKey(txid, i); + if (GetSpentIndex(spentKey, spentInfo)) { + out.push_back(Pair("spentTxId", spentInfo.txid.GetHex())); + out.push_back(Pair("spentIndex", (int)spentInfo.inputIndex)); + out.push_back(Pair("spentHeight", spentInfo.blockHeight)); + } + vout.push_back(out); } entry.push_back(Pair("vout", vout)); @@ -169,18 +204,76 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) UniValue vjoinsplit = TxJoinSplitToJSON(tx); entry.push_back(Pair("vjoinsplit", vjoinsplit)); + if (!hashBlock.IsNull()) { + entry.push_back(Pair("blockhash", hashBlock.GetHex())); + + if (nConfirmations > 0) { + entry.push_back(Pair("height", nHeight)); + entry.push_back(Pair("confirmations", nConfirmations)); + entry.push_back(Pair("time", nBlockTime)); + entry.push_back(Pair("blocktime", nBlockTime)); + } else { + entry.push_back(Pair("height", -1)); + entry.push_back(Pair("confirmations", 0)); + } + } + +} + +void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) +{ + uint256 txid = tx.GetHash(); + entry.push_back(Pair("txid", txid.GetHex())); + entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); + entry.push_back(Pair("version", tx.nVersion)); + entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); + + UniValue vin(UniValue::VARR); + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + UniValue in(UniValue::VOBJ); + if (tx.IsCoinBase()) + in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + else { + in.push_back(Pair("txid", txin.prevout.hash.GetHex())); + in.push_back(Pair("vout", (int64_t)txin.prevout.n)); + UniValue o(UniValue::VOBJ); + o.push_back(Pair("asm", txin.scriptSig.ToString())); + o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + in.push_back(Pair("scriptSig", o)); + } + in.push_back(Pair("sequence", (int64_t)txin.nSequence)); + vin.push_back(in); + } + entry.push_back(Pair("vin", vin)); + + UniValue vout(UniValue::VARR); + for (unsigned int i = 0; i < tx.vout.size(); i++) { + const CTxOut& txout = tx.vout[i]; + UniValue out(UniValue::VOBJ); + out.push_back(Pair("value", ValueFromAmount(txout.nValue))); + out.push_back(Pair("valueSat", txout.nValue)); + out.push_back(Pair("n", (int64_t)i)); + UniValue o(UniValue::VOBJ); + ScriptPubKeyToJSON(txout.scriptPubKey, o, true); + out.push_back(Pair("scriptPubKey", o)); + vout.push_back(out); + } + entry.push_back(Pair("vout", vout)); + if (!hashBlock.IsNull()) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (chainActive.Contains(pindex)) { + entry.push_back(Pair("height", pindex->nHeight)); entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight)); entry.push_back(Pair("time", pindex->GetBlockTime())); entry.push_back(Pair("blocktime", pindex->GetBlockTime())); - } - else + } else { + entry.push_back(Pair("height", -1)); entry.push_back(Pair("confirmations", 0)); + } } } } @@ -279,7 +372,6 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1") ); - LOCK(cs_main); uint256 hash = ParseHashV(params[0], "parameter 1"); @@ -289,8 +381,29 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) CTransaction tx; uint256 hashBlock; - if (!GetTransaction(hash, tx, hashBlock, true)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); + int nHeight = 0; + int nConfirmations = 0; + int nBlockTime = 0; + + { + LOCK(cs_main); + if (!GetTransaction(hash, tx, hashBlock, true)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); + + BlockMap::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end() && (*mi).second) { + CBlockIndex* pindex = (*mi).second; + if (chainActive.Contains(pindex)) { + nHeight = pindex->nHeight; + nConfirmations = 1 + chainActive.Height() - pindex->nHeight; + nBlockTime = pindex->GetBlockTime(); + } else { + nHeight = -1; + nConfirmations = 0; + nBlockTime = pindex->GetBlockTime(); + } + } + } string strHex = EncodeHexTx(tx); @@ -299,7 +412,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", strHex)); - TxToJSON(tx, hashBlock, result); + TxToJSONExpanded(tx, hashBlock, result, nHeight, nConfirmations, nBlockTime); return result; } @@ -339,7 +452,7 @@ int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid }*/ CTransaction tx; uint256 hashBlock; - if ( GetTransaction(txid,tx,hashBlock,true) == 0 ) + if ( GetTransaction(txid,tx,hashBlock,false) == 0 ) return(-1); else if ( n <= tx.vout.size() ) // vout.size() seems off by 1 { @@ -417,7 +530,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) } CBlock block; - if(!ReadBlockFromDisk(block, pblockindex)) + if(!ReadBlockFromDisk(block, pblockindex,1)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); unsigned int ntxFound = 0; diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index ba55be91a..86a7aed86 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -238,9 +238,11 @@ UniValue help(const UniValue& params, bool fHelp) return tableRPC.help(strCommand); } +extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; UniValue stop(const UniValue& params, bool fHelp) { + char buf[64]; // Accept the deprecated and ignored 'detach' boolean argument if (fHelp || params.size() > 1) throw runtime_error( @@ -248,7 +250,8 @@ UniValue stop(const UniValue& params, bool fHelp) "\nStop Komodo server."); // Shutdown will take long enough that the response should get back StartShutdown(); - return "Komodo server stopping"; + sprintf(buf,"%s Komodo server stopping",ASSETCHAINS_SYMBOL); + return buf; } /** @@ -281,6 +284,8 @@ static const CRPCCommand vRPCCommands[] = { "blockchain", "getbestblockhash", &getbestblockhash, true }, { "blockchain", "getblockcount", &getblockcount, true }, { "blockchain", "getblock", &getblock, true }, + { "blockchain", "getblockdeltas", &getblockdeltas, false }, + { "blockchain", "getblockhashes", &getblockhashes, true }, { "blockchain", "getblockhash", &getblockhash, true }, { "blockchain", "getblockheader", &getblockheader, true }, { "blockchain", "getchaintips", &getchaintips, true }, @@ -292,12 +297,16 @@ static const CRPCCommand vRPCCommands[] = { "blockchain", "verifytxoutproof", &verifytxoutproof, true }, { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, { "blockchain", "verifychain", &verifychain, true }, + { "blockchain", "getspentinfo", &getspentinfo, false }, { "blockchain", "paxprice", &paxprice, true }, { "blockchain", "paxpending", &paxpending, true }, { "blockchain", "paxprices", &paxprices, true }, { "blockchain", "notaries", ¬aries, true }, - //{ "blockchain", "height_MoM", &height_MoM, true }, - //{ "blockchain", "txMoMproof", &txMoMproof, true }, + { "blockchain", "allMoMs", &allMoMs, true }, + { "blockchain", "MoMoMdata", &MoMoMdata, true }, + { "blockchain", "calc_MoM", &calc_MoM, true }, + { "blockchain", "height_MoM", &height_MoM, true }, + { "blockchain", "txMoMproof", &txMoMproof, true }, { "blockchain", "minerids", &minerids, true }, { "blockchain", "kvsearch", &kvsearch, true }, { "blockchain", "kvupdate", &kvupdate, true }, @@ -330,6 +339,13 @@ static const CRPCCommand vRPCCommands[] = { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false }, #endif +/* Address index */ + { "addressindex", "getaddressmempool", &getaddressmempool, true }, + { "addressindex", "getaddressutxos", &getaddressutxos, false }, + { "addressindex", "getaddressdeltas", &getaddressdeltas, false }, + { "addressindex", "getaddresstxids", &getaddresstxids, false }, + { "addressindex", "getaddressbalance", &getaddressbalance, false }, + /* Utility functions */ { "util", "createmultisig", &createmultisig, true }, { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ @@ -342,12 +358,12 @@ static const CRPCCommand vRPCCommands[] = { "util", "jumblr_pause", &jumblr_pause, true }, { "util", "jumblr_resume", &jumblr_resume, true }, + { "util", "invalidateblock", &invalidateblock, true }, + { "util", "reconsiderblock", &reconsiderblock, true }, /* Not shown in help */ - { "hidden", "invalidateblock", &invalidateblock, true }, - { "hidden", "reconsiderblock", &reconsiderblock, true }, { "hidden", "setmocktime", &setmocktime, true }, #ifdef ENABLE_WALLET - { "hidden", "resendwallettransactions", &resendwallettransactions, true}, + { "wallet", "resendwallettransactions", &resendwallettransactions, true}, #endif #ifdef ENABLE_WALLET diff --git a/src/rpcserver.h b/src/rpcserver.h index c4e0a6d1d..ce412cdb9 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -173,6 +173,11 @@ extern std::string HelpExampleRpc(const std::string& methodname, const std::stri extern void EnsureWalletIsUnlocked(); extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp +extern UniValue getaddressmempool(const UniValue& params, bool fHelp); +extern UniValue getaddressutxos(const UniValue& params, bool fHelp); +extern UniValue getaddressdeltas(const UniValue& params, bool fHelp); +extern UniValue getaddresstxids(const UniValue& params, bool fHelp); +extern UniValue getaddressbalance(const UniValue& params, bool fHelp); extern UniValue getpeerinfo(const UniValue& params, bool fHelp); extern UniValue ping(const UniValue& params, bool fHelp); extern UniValue addnode(const UniValue& params, bool fHelp); @@ -271,6 +276,8 @@ extern UniValue getdifficulty(const UniValue& params, bool fHelp); extern UniValue settxfee(const UniValue& params, bool fHelp); extern UniValue getmempoolinfo(const UniValue& params, bool fHelp); extern UniValue getrawmempool(const UniValue& params, bool fHelp); +extern UniValue getblockhashes(const UniValue& params, bool fHelp); +extern UniValue getblockdeltas(const UniValue& params, bool fHelp); extern UniValue getblockhash(const UniValue& params, bool fHelp); extern UniValue getblockheader(const UniValue& params, bool fHelp); extern UniValue getblock(const UniValue& params, bool fHelp); @@ -280,6 +287,7 @@ extern UniValue verifychain(const UniValue& params, bool fHelp); extern UniValue getchaintips(const UniValue& params, bool fHelp); extern UniValue invalidateblock(const UniValue& params, bool fHelp); extern UniValue reconsiderblock(const UniValue& params, bool fHelp); +extern UniValue getspentinfo(const UniValue& params, bool fHelp); extern UniValue getblocksubsidy(const UniValue& params, bool fHelp); @@ -304,8 +312,11 @@ extern UniValue z_validateaddress(const UniValue& params, bool fHelp); // in rpc extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp); // in rpcdisclosure.cpp extern UniValue z_validatepaymentdisclosure(const UniValue ¶ms, bool fHelp); // in rpcdisclosure.cpp -//extern UniValue height_MoM(const UniValue& params, bool fHelp); -//extern UniValue txMoMproof(const UniValue& params, bool fHelp); +extern UniValue allMoMs(const UniValue& params, bool fHelp); +extern UniValue MoMoMdata(const UniValue& params, bool fHelp); +extern UniValue calc_MoM(const UniValue& params, bool fHelp); +extern UniValue height_MoM(const UniValue& params, bool fHelp); +extern UniValue txMoMproof(const UniValue& params, bool fHelp); extern UniValue notaries(const UniValue& params, bool fHelp); extern UniValue minerids(const UniValue& params, bool fHelp); extern UniValue kvsearch(const UniValue& params, bool fHelp); diff --git a/src/script/cc.h b/src/script/cc.h index ad1666b86..dc019beba 100644 --- a/src/script/cc.h +++ b/src/script/cc.h @@ -6,7 +6,7 @@ #include "cryptoconditions/include/cryptoconditions.h" -extern int32_t ASSETCHAINS_CC; +extern uint32_t ASSETCHAINS_CC; bool IsCryptoConditionsEnabled(); // Limit acceptable condition types diff --git a/src/script/script.cpp b/src/script/script.cpp index df29b6244..a130df4aa 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -216,6 +216,17 @@ unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const return subscript.GetSigOpCount(true); } +bool CScript::IsPayToPublicKeyHash() const +{ + // Extra-fast test for pay-to-pubkey-hash CScripts: + return (this->size() == 25 && + (*this)[0] == OP_DUP && + (*this)[1] == OP_HASH160 && + (*this)[2] == 0x14 && + (*this)[23] == OP_EQUALVERIFY && + (*this)[24] == OP_CHECKSIG); +} + bool CScript::IsPayToScriptHash() const { // Extra-fast test for pay-to-script-hash CScripts: diff --git a/src/script/script.h b/src/script/script.h index 6b8c07b07..e5328cf06 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -566,6 +566,8 @@ public: */ unsigned int GetSigOpCount(const CScript& scriptSig) const; + bool IsPayToPublicKeyHash() const; + bool IsPayToScriptHash() const; bool IsPayToCryptoCondition() const; bool MayAcceptCryptoCondition() const; diff --git a/src/serialize.h b/src/serialize.h index f776d6d99..4501103c9 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -95,6 +95,11 @@ template inline void ser_writedata32(Stream &s, uint32_t obj) obj = htole32(obj); s.write((char*)&obj, 4); } +template inline void ser_writedata32be(Stream &s, uint32_t obj) +{ + obj = htobe32(obj); + s.write((char*)&obj, 4); +} template inline void ser_writedata64(Stream &s, uint64_t obj) { obj = htole64(obj); @@ -118,6 +123,12 @@ template inline uint32_t ser_readdata32(Stream &s) s.read((char*)&obj, 4); return le32toh(obj); } +template inline uint32_t ser_readdata32be(Stream &s) +{ + uint32_t obj; + s.read((char*)&obj, 4); + return be32toh(obj); +} template inline uint64_t ser_readdata64(Stream &s) { uint64_t obj; diff --git a/src/snark/AUTHORS b/src/snark/AUTHORS index 1b2d7a247..cdc8d66af 100644 --- a/src/snark/AUTHORS +++ b/src/snark/AUTHORS @@ -17,3 +17,6 @@ External contributors: Tadanori TERUYA Sean Bowe Daira Hopwood + @mugatu on forum.z.cash + David Mercer + Joshua Yabut diff --git a/src/snark/Makefile b/src/snark/Makefile index b865f992f..17dcfdc6e 100644 --- a/src/snark/Makefile +++ b/src/snark/Makefile @@ -6,6 +6,13 @@ #* @copyright MIT license (see LICENSE file) #*******************************************************************************/ +# Determine building operating system +ifeq ($(OS),Windows_NT) + uname_S := Windows +else + uname_S := $(shell uname -s) +endif + # To override these, use "make OPTFLAGS=..." etc. CURVE = BN128 OPTFLAGS = -O2 -march=native -mtune=native @@ -106,18 +113,9 @@ EXECUTABLES_WITH_GTEST = EXECUTABLES_WITH_SUPERCOP = \ libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark -GTEST_TESTS = libsnark/gtests +GTEST_TESTS = -GTEST_SRCS = \ - libsnark/algebra/curves/tests/test_bilinearity.cpp \ - libsnark/algebra/curves/tests/test_groups.cpp \ - libsnark/algebra/fields/tests/test_bigint.cpp \ - libsnark/algebra/fields/tests/test_fields.cpp \ - libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp \ - libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp \ - libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp \ - libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp \ - libsnark/gtests.cpp +GTEST_SRCS = DOCS = README.html @@ -175,6 +173,7 @@ all: \ $(if $(NO_GTEST),,$(EXECUTABLES_WITH_GTEST) $(GTEST_TESTS)) \ $(if $(NO_SUPERCOP),,$(EXECUTABLES_WITH_SUPERCOP)) \ $(EXECUTABLES) \ + $(LIBSNARK_A) \ $(if $(NO_DOCS),,doc) doc: $(DOCS) diff --git a/src/snark/README.md b/src/snark/README.md index 89183b43a..d5aa34006 100644 --- a/src/snark/README.md +++ b/src/snark/README.md @@ -14,7 +14,7 @@ Copyright (c) 2012-2014 SCIPR Lab and contributors (see [AUTHORS] file). [TOC]