diff --git a/configure.ac b/configure.ac index aedbd1f130e..68edc6af510 100644 --- a/configure.ac +++ b/configure.ac @@ -125,11 +125,6 @@ AC_ARG_ENABLE(tests, [use_tests=$enableval], [use_tests=yes]) -AC_ARG_ENABLE(gui-tests, - AS_HELP_STRING([--disable-gui-tests],[do not compile GUI tests (default is to compile if GUI and tests enabled)]), - [use_gui_tests=$enableval], - [use_gui_tests=$use_tests]) - AC_ARG_WITH([rapidcheck], [AS_HELP_STRING([--with-rapidcheck], [enable RapidCheck property-based tests (default is yes if librapidcheck is found)])], @@ -152,12 +147,6 @@ AC_ARG_ENABLE([fuzz], [enable_fuzz=$enableval], [enable_fuzz=no]) -AC_ARG_WITH([qrencode], - [AS_HELP_STRING([--with-qrencode], - [enable QR code support (default is yes if qt is enabled and libqrencode is found)])], - [use_qr=$withval], - [use_qr=auto]) - AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--disable-hardening], [do not attempt to harden the resulting executables (default is to harden when possible)])], @@ -221,13 +210,6 @@ AC_ARG_ENABLE([zmq], [disable ZMQ notifications])], [use_zmq=$enableval], [use_zmq=yes]) -AC_ARG_ENABLE([bip70], - [AS_HELP_STRING([--disable-bip70], - [disable BIP70 (payment protocol) support in GUI (enabled by default)])], - [enable_bip70=$enableval], - [enable_bip70=auto]) - -AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) AC_ARG_ENABLE(man, [AS_HELP_STRING([--disable-man], @@ -550,7 +532,6 @@ case $host in openssl_prefix=`$BREW --prefix openssl 2>/dev/null` bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null` - qt5_prefix=`$BREW --prefix qt5 2>/dev/null` if test x$openssl_prefix != x; then PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" export PKG_CONFIG_PATH @@ -559,10 +540,6 @@ case $host in CPPFLAGS="$CPPFLAGS -I$bdb_prefix/include" LIBS="$LIBS -L$bdb_prefix/lib" fi - if test x$qt5_prefix != x; then - PKG_CONFIG_PATH="$qt5_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" - export PKG_CONFIG_PATH - fi fi else case $build_os in @@ -1423,7 +1400,7 @@ else fi if test x$build_defi_wallet$build_defi_cli$build_defi_tx$build_defi_libs$build_defid$use_bench$use_tests = xnononononononono; then - AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests]) + AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --enable-bench or --enable-tests]) fi AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) @@ -1432,9 +1409,7 @@ AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows]) AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) AM_CONDITIONAL([ENABLE_FUZZ],[test x$enable_fuzz = xyes]) -AM_CONDITIONAL([ENABLE_BIP70],[test x$enable_bip70 = xyes]) AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes]) -AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) @@ -1503,7 +1478,7 @@ AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(ZMQ_LIBS) AC_SUBST(PROTOBUF_LIBS) AC_SUBST(QR_LIBS) -AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/config.ini]) +AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi test/config.ini]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])]) AC_CONFIG_LINKS([contrib/filter-lcov.py:contrib/filter-lcov.py]) diff --git a/contrib/testgen/gen_burn_addr.py b/contrib/testgen/gen_burn_addr.py index 0528d801a54..0f2d8475ccc 100644 --- a/contrib/testgen/gen_burn_addr.py +++ b/contrib/testgen/gen_burn_addr.py @@ -119,6 +119,7 @@ def print_usage(): print('python3 ' + sys.argv[0] + ' AddressStartString') print('Mainnet address start with string from 8F ~ 8d') print('Testnet address start with string from 73 ~ 7R') + print('Regtest address start with string from mf ~ n4') print('The address start string cannot contain these characters: 0OIl') print('For example:') print(' python3 gen_burn_addr.py 8addressForBurn') @@ -131,6 +132,9 @@ def check_start_range(fst2): if fst2 >= '8F' and fst2 <= '8d': return True + if fst2 >= 'mf' and fst2 <= 'n4': + return True + return False if __name__ == '__main__': @@ -170,6 +174,7 @@ def check_start_range(fst2): print('Address start is not correct!') print('Mainnet address start with string from 8F ~ 8d') print('Testnet address start with string from 73 ~ 7R') + print('Regtest address start with string from mf ~ n4') sys.exit(0) anotherString = startString + "X" * (34 - len(startString)) diff --git a/depends/Makefile b/depends/Makefile index 70af8751893..9ef38551e53 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -4,7 +4,6 @@ SOURCES_PATH ?= $(BASEDIR)/sources WORK_PATH = $(BASEDIR)/work BASE_CACHE ?= $(BASEDIR)/built SDK_PATH ?= $(BASEDIR)/SDKs -NO_QT ?= RAPIDCHECK ?= NO_WALLET ?= NO_ZMQ ?= @@ -91,20 +90,15 @@ $(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null) $(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) $(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) -qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) wallet_packages_$(NO_WALLET) = $(wallet_packages) upnp_packages_$(NO_UPNP) = $(upnp_packages) zmq_packages_$(NO_ZMQ) = $(zmq_packages) rapidcheck_packages_$(RAPIDCHECK) = $(rapidcheck_packages) -packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_) +packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(wallet_packages_) $(upnp_packages_) native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) -ifneq ($(qt_packages_),) -native_packages += $(qt_native_packages) -endif - ifneq ($(zmq_packages_),) packages += $(zmq_packages) endif @@ -148,7 +142,6 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \ -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \ -e 's|@allow_host_packages@|$(ALLOW_HOST_PACKAGES)|' \ - -e 's|@no_qt@|$(NO_QT)|' \ -e 's|@no_zmq@|$(NO_ZMQ)|' \ -e 's|@no_wallet@|$(NO_WALLET)|' \ -e 's|@no_upnp@|$(NO_UPNP)|' \ diff --git a/depends/README.md b/depends/README.md index ca542be13f2..69bc2a0222f 100644 --- a/depends/README.md +++ b/depends/README.md @@ -71,7 +71,6 @@ The following can be set when running make: make FOO=bar BASE_CACHE: built packages will be placed here SDK_PATH: Path where sdk's can be found (used by macOS) FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up - NO_QT: Don't download/build/cache qt and its dependencies NO_ZMQ: Don't download/build/cache packages needed for enabling zeromq NO_WALLET: Don't download/build/cache libs needed to enable the wallet NO_UPNP: Don't download/build/cache packages needed for enabling upnp diff --git a/depends/config.site.in b/depends/config.site.in index e6337520665..4eb47f79afb 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -7,19 +7,6 @@ ac_tool_prefix=${host_alias}- if test -z $with_boost; then with_boost=$depends_prefix fi -if test -z $with_qt_plugindir; then - with_qt_plugindir=$depends_prefix/plugins -fi -if test -z $with_qt_translationdir; then - with_qt_translationdir=$depends_prefix/translations -fi -if test -z $with_qt_bindir && test -z "@no_qt@"; then - with_qt_bindir=$depends_prefix/native/bin -fi -if test -z $with_protoc_bindir && test -z "@no_qt@"; then - with_protoc_bindir=$depends_prefix/native/bin -fi - if test -z $enable_wallet && test -n "@no_wallet@"; then enable_wallet=no @@ -29,10 +16,6 @@ if test -z $with_miniupnpc && test -n "@no_upnp@"; then with_miniupnpc=no fi -if test -z $with_gui && test -n "@no_qt@"; then - with_gui=no -fi - if test -z $enable_zmq && test -n "@no_zmq@"; then enable_zmq=no fi @@ -42,15 +25,6 @@ if test x@host_os@ = xdarwin; then PORT=no fi -if test x@host_os@ = xmingw32; then - if test -z $with_qt_incdir; then - with_qt_incdir=$depends_prefix/include - fi - if test -z $with_qt_libdir; then - with_qt_libdir=$depends_prefix/lib - fi -fi - PATH=$depends_prefix/native/bin:$PATH PKG_CONFIG="`which pkg-config` --static" diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 5df49b2af85..c84c5d0ab19 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,6 +1,6 @@ package=boost $(package)_version=1_70_0 -$(package)_download_path=https://dl.bintray.com/boostorg/release/1.70.0/source/ +$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/1.70.0/source/ $(package)_file_name=$(package)_$($(package)_version).tar.bz2 $(package)_sha256_hash=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk deleted file mode 100644 index 47843819150..00000000000 --- a/depends/packages/expat.mk +++ /dev/null @@ -1,26 +0,0 @@ -package=expat -$(package)_version=2.2.7 -$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_7/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=cbc9102f4a31a8dafd42d642e9a3aa31e79a0aedaa1f6efd2795ebc83174ec18 - -define $(package)_set_vars - $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm lib/*.la -endef diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk deleted file mode 100644 index ed21fbba336..00000000000 --- a/depends/packages/fontconfig.mk +++ /dev/null @@ -1,32 +0,0 @@ -package=fontconfig -$(package)_version=2.12.1 -$(package)_download_path=https://www.freedesktop.org/software/fontconfig/release/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=b449a3e10c47e1d1c7a6ec6e2016cca73d3bd68fbbd4f0ae5cc6b573f7d6c7f3 -$(package)_dependencies=freetype expat - -define $(package)_set_vars - $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -# 2.12.1 uses CHAR_WIDTH which is reserved and clashes with some glibc versions, but newer versions of fontconfig -# have broken makefiles which needlessly attempt to re-generate headers with gperf. -# Instead, change all uses of CHAR_WIDTH, and disable the rule that forces header re-generation. -# This can be removed once the upstream build is fixed. -define $(package)_build_cmds - sed -i 's/CHAR_WIDTH/CHARWIDTH/g' fontconfig/fontconfig.h src/fcobjshash.gperf src/fcobjs.h src/fcobjshash.h && \ - sed -i 's/fcobjshash.h: fcobjshash.gperf/fcobjshash.h:/' src/Makefile && \ - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm lib/*.la -endef diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk deleted file mode 100644 index f24fc69d81b..00000000000 --- a/depends/packages/freetype.mk +++ /dev/null @@ -1,26 +0,0 @@ -package=freetype -$(package)_version=2.7.1 -$(package)_download_path=https://download.savannah.gnu.org/releases/$(package) -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=3a3bb2c4e15ffb433f2032f50a5b5a92558206822e22bfe8cbe339af4aa82f88 - -define $(package)_set_vars - $(package)_config_opts=--without-zlib --without-png --without-harfbuzz --without-bzip2 --disable-static - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm lib/*.la -endef diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk deleted file mode 100644 index 058416f7930..00000000000 --- a/depends/packages/libXau.mk +++ /dev/null @@ -1,33 +0,0 @@ -package=libXau -$(package)_version=1.0.8 -$(package)_download_path=https://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=fdd477320aeb5cdd67272838722d6b7d544887dfe7de46e1e7cc0c27c2bea4f2 -$(package)_dependencies=xproto - -# When updating this package, check the default value of -# --disable-xthreads. It is currently enabled. -define $(package)_set_vars - $(package)_config_opts=--disable-shared --disable-lint-library --without-lint - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm lib/*.la -endef diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk deleted file mode 100644 index 49d3e3d15b0..00000000000 --- a/depends/packages/libxcb.mk +++ /dev/null @@ -1,48 +0,0 @@ -package=libxcb -$(package)_version=1.10 -$(package)_download_path=https://xcb.freedesktop.org/dist -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c3f2d5b5 -$(package)_dependencies=xcb_proto libXau - -define $(package)_set_vars -$(package)_config_opts=--disable-static --disable-build-docs --without-doxygen --without-launchd -# Because we pass -qt-xcb to Qt, it will compile in a set of xcb helper libraries and extensions, -# so we skip building all of the extensions here. -# More info is available from: https://doc.qt.io/qt-5.9/linux-requirements.html -$(package)_config_opts += --disable-composite --disable-damage --disable-dpms -$(package)_config_opts += --disable-dri2 --disable-dri3 --disable-glx -$(package)_config_opts += --disable-present --disable-randr --disable-record -$(package)_config_opts += --disable-render --disable-resource --disable-screensaver -$(package)_config_opts += --disable-shape --disable-shm --disable-sync -$(package)_config_opts += --disable-xevie --disable-xfixes --disable-xfree86-dri -$(package)_config_opts += --disable-xinerama --disable-xinput --disable-xkb -$(package)_config_opts += --disable-xprint --disable-selinux --disable-xtest -$(package)_config_opts += --disable-xv --disable-xvmc -endef - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux &&\ - sed "s/pthread-stubs//" -i configure -endef - -# Don't install xcb headers to the default path in order to work around a qt -# build issue: https://bugreports.qt.io/browse/QTBUG-34748 -# When using qt's internal libxcb, it may end up finding the real headers in -# depends staging. Use a non-default path to avoid that. - -define $(package)_config_cmds - $($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm -rf share/man share/doc lib/*.la -endef diff --git a/depends/packages/native_protobuf.mk b/depends/packages/native_protobuf.mk deleted file mode 100644 index 1de8c37d362..00000000000 --- a/depends/packages/native_protobuf.mk +++ /dev/null @@ -1,25 +0,0 @@ -package=native_protobuf -$(package)_version=2.6.1 -$(package)_download_path=https://github.com/google/protobuf/releases/download/v$($(package)_version) -$(package)_file_name=protobuf-$($(package)_version).tar.bz2 -$(package)_sha256_hash=ee445612d544d885ae240ffbcbf9267faa9f593b7b101f21d58beceb92661910 - -define $(package)_set_vars -$(package)_config_opts=--disable-shared --without-zlib -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C src protoc -endef - -define $(package)_stage_cmds - $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install-strip -endef - -define $(package)_postprocess_cmds - rm -rf lib include -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 9edcd1eb38e..ee0dff31b1d 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,15 +1,7 @@ packages:=boost openssl libevent -qt_native_packages = native_protobuf -qt_packages = qrencode protobuf zlib - -qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig - rapidcheck_packages = rapidcheck -qt_darwin_packages=qt -qt_mingw32_packages=qt - wallet_packages=bdb zmq_packages=zeromq diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk deleted file mode 100644 index 52975b14ecc..00000000000 --- a/depends/packages/protobuf.mk +++ /dev/null @@ -1,34 +0,0 @@ -package=protobuf -$(package)_version=$(native_$(package)_version) -$(package)_download_path=$(native_$(package)_download_path) -$(package)_file_name=$(native_$(package)_file_name) -$(package)_sha256_hash=$(native_$(package)_sha256_hash) -$(package)_dependencies=native_$(package) -$(package)_cxxflags=-std=c++11 - -define $(package)_set_vars - $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . &&\ - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub gtest/build-aux -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C src libprotobuf.la -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) -C src install-libLTLIBRARIES install-nobase_includeHEADERS &&\ - $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA -endef - -define $(package)_postprocess_cmds - rm lib/libprotoc.a lib/*.la -endef diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk deleted file mode 100644 index 3bc2cb768cc..00000000000 --- a/depends/packages/qrencode.mk +++ /dev/null @@ -1,31 +0,0 @@ -package=qrencode -$(package)_version=3.4.4 -$(package)_download_path=https://fukuchi.org/works/qrencode/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19cde1fa5 - -define $(package)_set_vars -$(package)_config_opts=--disable-shared --without-tools --without-tests --disable-sdltest -$(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap -$(package)_config_opts_linux=--with-pic -endef - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub use -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm lib/*.la -endef diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk deleted file mode 100644 index 2610c1e7484..00000000000 --- a/depends/packages/qt.mk +++ /dev/null @@ -1,221 +0,0 @@ -PACKAGE=qt -$(package)_version=5.9.7 -$(package)_download_path=https://download.qt.io/official_releases/qt/5.9/$($(package)_version)/submodules -$(package)_suffix=opensource-src-$($(package)_version).tar.xz -$(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=36dd9574f006eaa1e5af780e4b33d11fe39d09fd7c12f3b9d83294174bd28f00 -$(package)_dependencies=openssl zlib -$(package)_linux_dependencies=freetype fontconfig libxcb -$(package)_build_subdir=qtbase -$(package)_qt_libs=corelib network widgets gui plugins testlib -$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch fix_rcc_determinism.patch fix_riscv64_arch.patch xkb-default.patch no-xlib.patch - -$(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=b36da7d93c3ab6fca56b32053bb73bc619c8b192bb89b74e3bcde2705f1c2a14 - -$(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=d62e0f70d99645d6704dbb8976fb2222443061743689943d40970c52c49367a1 - -$(package)_extra_sources = $($(package)_qttranslations_file_name) -$(package)_extra_sources += $($(package)_qttools_file_name) - -define $(package)_set_vars -$(package)_config_opts_release = -release -$(package)_config_opts_debug = -debug -$(package)_config_opts += -bindir $(build_prefix)/bin -$(package)_config_opts += -c++std c++11 -$(package)_config_opts += -confirm-license -$(package)_config_opts += -dbus-runtime -$(package)_config_opts += -hostprefix $(build_prefix) -$(package)_config_opts += -no-compile-examples -$(package)_config_opts += -no-cups -$(package)_config_opts += -no-egl -$(package)_config_opts += -no-eglfs -$(package)_config_opts += -no-freetype -$(package)_config_opts += -no-gif -$(package)_config_opts += -no-glib -$(package)_config_opts += -no-icu -$(package)_config_opts += -no-ico -$(package)_config_opts += -no-iconv -$(package)_config_opts += -no-kms -$(package)_config_opts += -no-linuxfb -$(package)_config_opts += -no-libjpeg -$(package)_config_opts += -no-libudev -$(package)_config_opts += -no-mtdev -$(package)_config_opts += -no-openvg -$(package)_config_opts += -no-reduce-relocations -$(package)_config_opts += -no-qml-debug -$(package)_config_opts += -no-sql-db2 -$(package)_config_opts += -no-sql-ibase -$(package)_config_opts += -no-sql-oci -$(package)_config_opts += -no-sql-tds -$(package)_config_opts += -no-sql-mysql -$(package)_config_opts += -no-sql-odbc -$(package)_config_opts += -no-sql-psql -$(package)_config_opts += -no-sql-sqlite -$(package)_config_opts += -no-sql-sqlite2 -$(package)_config_opts += -no-use-gold-linker -$(package)_config_opts += -no-xinput2 -$(package)_config_opts += -nomake examples -$(package)_config_opts += -nomake tests -$(package)_config_opts += -opensource -$(package)_config_opts += -openssl-linked -$(package)_config_opts += -optimized-qmake -$(package)_config_opts += -pch -$(package)_config_opts += -pkg-config -$(package)_config_opts += -prefix $(host_prefix) -$(package)_config_opts += -qt-libpng -$(package)_config_opts += -qt-pcre -$(package)_config_opts += -qt-harfbuzz -$(package)_config_opts += -system-zlib -$(package)_config_opts += -static -$(package)_config_opts += -silent -$(package)_config_opts += -v -$(package)_config_opts += -no-feature-bearermanagement -$(package)_config_opts += -no-feature-colordialog -$(package)_config_opts += -no-feature-commandlineparser -$(package)_config_opts += -no-feature-concurrent -$(package)_config_opts += -no-feature-dial -$(package)_config_opts += -no-feature-filesystemwatcher -$(package)_config_opts += -no-feature-fontcombobox -$(package)_config_opts += -no-feature-ftp -$(package)_config_opts += -no-feature-image_heuristic_mask -$(package)_config_opts += -no-feature-keysequenceedit -$(package)_config_opts += -no-feature-lcdnumber -$(package)_config_opts += -no-feature-pdf -$(package)_config_opts += -no-feature-printdialog -$(package)_config_opts += -no-feature-printer -$(package)_config_opts += -no-feature-printpreviewdialog -$(package)_config_opts += -no-feature-printpreviewwidget -$(package)_config_opts += -no-feature-regularexpression -$(package)_config_opts += -no-feature-sessionmanager -$(package)_config_opts += -no-feature-sql -$(package)_config_opts += -no-feature-statemachine -$(package)_config_opts += -no-feature-syntaxhighlighter -$(package)_config_opts += -no-feature-textbrowser -$(package)_config_opts += -no-feature-textodfwriter -$(package)_config_opts += -no-feature-topleveldomain -$(package)_config_opts += -no-feature-udpsocket -$(package)_config_opts += -no-feature-undocommand -$(package)_config_opts += -no-feature-undogroup -$(package)_config_opts += -no-feature-undostack -$(package)_config_opts += -no-feature-undoview -$(package)_config_opts += -no-feature-vnc -$(package)_config_opts += -no-feature-wizard -$(package)_config_opts += -no-feature-xml - -ifneq ($(build_os),darwin) -$(package)_config_opts_darwin = -xplatform macx-clang-linux -$(package)_config_opts_darwin += -device-option MAC_SDK_PATH=$(OSX_SDK) -$(package)_config_opts_darwin += -device-option MAC_SDK_VERSION=$(OSX_SDK_VERSION) -$(package)_config_opts_darwin += -device-option CROSS_COMPILE="$(host)-" -$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) -$(package)_config_opts_darwin += -device-option MAC_TARGET=$(host) -$(package)_config_opts_darwin += -device-option MAC_LD64_VERSION=$(LD64_VERSION) -endif - -$(package)_config_opts_linux = -qt-xkbcommon-x11 -$(package)_config_opts_linux += -qt-xcb -$(package)_config_opts_linux += -no-xcb-xlib -$(package)_config_opts_linux += -no-feature-xlib -$(package)_config_opts_linux += -system-freetype -$(package)_config_opts_linux += -fontconfig -$(package)_config_opts_linux += -no-opengl -$(package)_config_opts_arm_linux += -platform linux-g++ -xplatform bitcoin-linux-g++ -$(package)_config_opts_i686_linux = -xplatform linux-g++-32 -$(package)_config_opts_x86_64_linux = -xplatform linux-g++-64 -$(package)_config_opts_aarch64_linux = -xplatform linux-aarch64-gnu-g++ -$(package)_config_opts_riscv64_linux = -platform linux-g++ -xplatform bitcoin-linux-g++ -$(package)_config_opts_mingw32 = -no-opengl -xplatform win32-g++ -device-option CROSS_COMPILE="$(host)-" -$(package)_build_env = QT_RCC_TEST=1 -$(package)_build_env += QT_RCC_SOURCE_DATE_OVERRIDE=1 -endef - -define $(package)_fetch_cmds -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_qttranslations_file_name),$($(package)_qttranslations_file_name),$($(package)_qttranslations_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_qttools_file_name),$($(package)_qttools_file_name),$($(package)_qttools_sha256_hash)) -endef - -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_qttranslations_sha256_hash) $($(package)_source_dir)/$($(package)_qttranslations_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir qtbase && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ - mkdir qttranslations && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ - mkdir qttools && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools -endef - -define $(package)_preprocess_cmds - sed -i.old "s|FT_Get_Font_Format|FT_Get_X11_Font_Format|" qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp && \ - sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ - sed -i.old "/updateqm.depends =/d" qttranslations/translations/translations.pro && \ - sed -i.old "s/src_plugins.depends = src_sql src_network/src_plugins.depends = src_network/" qtbase/src/src.pro && \ - sed -i.old "s|X11/extensions/XIproto.h|X11/X.h|" qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp && \ - sed -i.old -e 's/if \[ "$$$$XPLATFORM_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/if \[ "$$$$BUILD_ON_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/' -e 's|/bin/pwd|pwd|' qtbase/configure && \ - sed -i.old 's/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0)/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, kCGMouseButtonLeft)/' qtbase/src/plugins/platforms/cocoa/qcocoacursor.mm && \ - mkdir -p qtbase/mkspecs/macx-clang-linux &&\ - cp -f qtbase/mkspecs/macx-clang/Info.plist.lib qtbase/mkspecs/macx-clang-linux/ &&\ - cp -f qtbase/mkspecs/macx-clang/Info.plist.app qtbase/mkspecs/macx-clang-linux/ &&\ - cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ - cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ - cp -r qtbase/mkspecs/linux-arm-gnueabi-g++ qtbase/mkspecs/bitcoin-linux-g++ && \ - sed -i.old "s/arm-linux-gnueabi-/$(host)-/g" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \ - patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch &&\ - patch -p1 -i $($(package)_patch_dir)/fix_configure_mac.patch &&\ - patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch &&\ - patch -p1 -i $($(package)_patch_dir)/fix_rcc_determinism.patch &&\ - patch -p1 -i $($(package)_patch_dir)/xkb-default.patch &&\ - echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ - echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ - echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ - patch -p1 -i $($(package)_patch_dir)/fix_riscv64_arch.patch &&\ - patch -p1 -i $($(package)_patch_dir)/no-xlib.patch &&\ - echo "QMAKE_LINK_OBJECT_MAX = 10" >> qtbase/mkspecs/win32-g++/qmake.conf &&\ - echo "QMAKE_LINK_OBJECT_SCRIPT = object_script" >> qtbase/mkspecs/win32-g++/qmake.conf &&\ - sed -i.old "s|QMAKE_CFLAGS = |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_LFLAGS = |!host_build: QMAKE_LFLAGS = $($(package)_ldflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_CXXFLAGS = |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf -endef - -define $(package)_config_cmds - export PKG_CONFIG_SYSROOT_DIR=/ && \ - export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \ - export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \ - ./configure $($(package)_config_opts) && \ - echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \ - echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \ - $(MAKE) sub-src-clean && \ - cd ../qttranslations && ../qtbase/bin/qmake qttranslations.pro -o Makefile && \ - cd translations && ../../qtbase/bin/qmake translations.pro -o Makefile && cd ../.. && \ - cd qttools/src/linguist/lrelease/ && ../../../../qtbase/bin/qmake lrelease.pro -o Makefile && \ - cd ../lupdate/ && ../../../../qtbase/bin/qmake lupdate.pro -o Makefile && cd ../../../.. -endef - -define $(package)_build_cmds - $(MAKE) -C src $(addprefix sub-,$($(package)_qt_libs)) && \ - $(MAKE) -C ../qttools/src/linguist/lrelease && \ - $(MAKE) -C ../qttools/src/linguist/lupdate && \ - $(MAKE) -C ../qttranslations -endef - -define $(package)_stage_cmds - $(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && cd .. && \ - $(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \ - $(MAKE) -C qttools/src/linguist/lupdate INSTALL_ROOT=$($(package)_staging_dir) install_target && \ - $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets && \ - if `test -f qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a`; then \ - cp qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a $($(package)_staging_prefix_dir)/lib; \ - fi -endef - -define $(package)_postprocess_cmds - rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \ - rm -f lib/lib*.la lib/*.prl plugins/*/*.prl -endef diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk deleted file mode 100644 index 44110394bdd..00000000000 --- a/depends/packages/xcb_proto.mk +++ /dev/null @@ -1,27 +0,0 @@ -package=xcb_proto -$(package)_version=1.10 -$(package)_download_path=https://xcb.freedesktop.org/dist -$(package)_file_name=xcb-proto-$($(package)_version).tar.bz2 -$(package)_sha256_hash=7ef40ddd855b750bc597d2a435da21e55e502a0fefa85b274f2c922800baaf05 - -define $(package)_set_vars - $(package)_config_opts=--disable-shared - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - find -name "*.pyc" -delete && \ - find -name "*.pyo" -delete -endef diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk deleted file mode 100644 index 2462f3c647b..00000000000 --- a/depends/packages/xproto.mk +++ /dev/null @@ -1,25 +0,0 @@ -package=xproto -$(package)_version=7.0.26 -$(package)_download_path=https://xorg.freedesktop.org/releases/individual/proto -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f - -define $(package)_set_vars -$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs -endef - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk deleted file mode 100644 index 1600b11a01e..00000000000 --- a/depends/packages/zlib.mk +++ /dev/null @@ -1,27 +0,0 @@ -package=zlib -$(package)_version=1.2.11 -$(package)_download_path=https://www.zlib.net -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 - -define $(package)_set_vars -$(package)_build_opts= CC="$($(package)_cc)" -$(package)_build_opts+=CFLAGS="$($(package)_cflags) $($(package)_cppflags) -fPIC" -$(package)_build_opts+=RANLIB="$($(package)_ranlib)" -$(package)_build_opts+=AR="$($(package)_ar)" -$(package)_build_opts_darwin+=AR="$($(package)_libtool)" -$(package)_build_opts_darwin+=ARFLAGS="-o" -endef - -define $(package)_config_cmds - ./configure --static --prefix=$(host_prefix) -endef - -define $(package)_build_cmds - $(MAKE) $($(package)_build_opts) libz.a -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install $($(package)_build_opts) -endef - diff --git a/depends/patches/qt/fix_configure_mac.patch b/depends/patches/qt/fix_configure_mac.patch deleted file mode 100644 index 0d7dd647deb..00000000000 --- a/depends/patches/qt/fix_configure_mac.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- old/qtbase/mkspecs/features/mac/sdk.prf 2018-02-08 10:24:48.000000000 -0800 -+++ new/qtbase/mkspecs/features/mac/sdk.prf 2018-03-23 10:38:56.000000000 -0700 -@@ -8,21 +8,21 @@ - defineReplace(xcodeSDKInfo) { - info = $$1 - equals(info, "Path"): \ -- info = --show-sdk-path -+ infoarg = --show-sdk-path - equals(info, "PlatformPath"): \ -- info = --show-sdk-platform-path -+ infoarg = --show-sdk-platform-path - equals(info, "SDKVersion"): \ -- info = --show-sdk-version -+ infoarg = --show-sdk-version - sdk = $$2 - isEmpty(sdk): \ - sdk = $$QMAKE_MAC_SDK - - isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}) { -- QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$info 2>/dev/null") -+ QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$infoarg 2>/dev/null") - # --show-sdk-platform-path won't work for Command Line Tools; this is fine - # only used by the XCTest backend to testlib -- isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(info, "--show-sdk-platform-path")): \ -- error("Could not resolve SDK $$info for \'$$sdk\'") -+ isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(infoarg, "--show-sdk-platform-path")): \ -+ error("Could not resolve SDK $$info for \'$$sdk\' using $$infoarg") - cache(QMAKE_MAC_SDK.$${sdk}.$${info}, set stash, QMAKE_MAC_SDK.$${sdk}.$${info}) - } - ---- old/qtbase/configure 2018-02-08 10:24:48.000000000 -0800 -+++ new/qtbase/configure 2018-03-23 05:42:29.000000000 -0700 -@@ -232,8 +232,13 @@ - - sdk=$(getSingleQMakeVariable "QMAKE_MAC_SDK" "$1") - if [ -z "$sdk" ]; then echo "QMAKE_MAC_SDK must be set when building on Mac" >&2; exit 1; fi -- sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null) -- if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi -+ sysroot=$(getSingleQMakeVariable "QMAKE_MAC_SDK_PATH" "$1") -+ -+ echo "sysroot pre-configured as $sysroot"; -+ if [ -z "$sysroot" ]; then -+ sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null) -+ if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi -+ fi - - case "$sdk" in - macosx*) - - diff --git a/depends/patches/qt/fix_no_printer.patch b/depends/patches/qt/fix_no_printer.patch deleted file mode 100644 index f868ca25775..00000000000 --- a/depends/patches/qt/fix_no_printer.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- x/qtbase/src/plugins/platforms/cocoa/qprintengine_mac_p.h -+++ y/qtbase/src/plugins/platforms/cocoa/qprintengine_mac_p.h -@@ -52,6 +52,7 @@ - // - - #include -+#include - - #ifndef QT_NO_PRINTER - ---- x/qtbase/src/plugins/plugins.pro -+++ y/qtbase/src/plugins/plugins.pro -@@ -8,6 +8,3 @@ qtHaveModule(gui) { - qtConfig(imageformatplugin): SUBDIRS *= imageformats - !android:qtConfig(library): SUBDIRS *= generic - } -- --!winrt:qtHaveModule(printsupport): \ -- SUBDIRS += printsupport diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch deleted file mode 100644 index 34302a9f2d2..00000000000 --- a/depends/patches/qt/fix_qt_pkgconfig.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- old/qtbase/mkspecs/features/qt_module.prf -+++ new/qtbase/mkspecs/features/qt_module.prf -@@ -245,7 +245,7 @@ - load(qt_targets) - - # this builds on top of qt_common --!internal_module:!lib_bundle:if(unix|mingw) { -+unix|mingw { - CONFIG += create_pc - QMAKE_PKGCONFIG_DESTDIR = pkgconfig - host_build: \ diff --git a/depends/patches/qt/fix_rcc_determinism.patch b/depends/patches/qt/fix_rcc_determinism.patch deleted file mode 100644 index c1b07fe23af..00000000000 --- a/depends/patches/qt/fix_rcc_determinism.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- old/qtbase/src/tools/rcc/rcc.cpp -+++ new/qtbase/src/tools/rcc/rcc.cpp -@@ -207,7 +207,11 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib) - if (lib.formatVersion() >= 2) { - // last modified time stamp - const QDateTime lastModified = m_fileInfo.lastModified(); -- lib.writeNumber8(quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0)); -+ quint64 lastmod = quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0); -+ static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong(); -+ if (sourceDate != 0) -+ lastmod = sourceDate; -+ lib.writeNumber8(lastmod); - if (text || pass1) - lib.writeChar('\n'); - } diff --git a/depends/patches/qt/fix_riscv64_arch.patch b/depends/patches/qt/fix_riscv64_arch.patch deleted file mode 100644 index e7f29f01f9c..00000000000 --- a/depends/patches/qt/fix_riscv64_arch.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -index 20bfd36..93729fa 100644 ---- a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -+++ b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -@@ -65,7 +65,8 @@ - defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ - defined(__SH4__) || defined(__alpha__) || \ - defined(_MIPS_ARCH_MIPS32R2) || \ -- defined(__AARCH64EL__) -+ defined(__AARCH64EL__) || defined(__aarch64__) || \ -+ defined(__riscv) - #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 - #elif defined(_M_IX86) || defined(__i386__) || defined(__i386) - #if defined(_WIN32) diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf deleted file mode 100644 index 337d0eb9caf..00000000000 --- a/depends/patches/qt/mac-qmake.conf +++ /dev/null @@ -1,26 +0,0 @@ -MAKEFILE_GENERATOR = UNIX -CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname absolute_library_soname -QMAKE_INCREMENTAL_STYLE = sublib -include(../common/macx.conf) -include(../common/gcc-base-mac.conf) -include(../common/clang.conf) -include(../common/clang-mac.conf) -QMAKE_MAC_SDK_PATH=$${MAC_SDK_PATH} -QMAKE_XCODE_VERSION=4.3 -QMAKE_XCODE_DEVELOPER_PATH=/Developer -QMAKE_MACOSX_DEPLOYMENT_TARGET = $${MAC_MIN_VERSION} -QMAKE_MAC_SDK=macosx -QMAKE_MAC_SDK.macosx.Path = $${MAC_SDK_PATH} -QMAKE_MAC_SDK.macosx.platform_name = macosx -QMAKE_MAC_SDK.macosx.SDKVersion = $${MAC_SDK_VERSION} -QMAKE_MAC_SDK.macosx.PlatformPath = /phony -QMAKE_APPLE_DEVICE_ARCHS=x86_64 -!host_build: QMAKE_CFLAGS += -target $${MAC_TARGET} -!host_build: QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS -!host_build: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS -!host_build: QMAKE_LFLAGS += -target $${MAC_TARGET} -mlinker-version=$${MAC_LD64_VERSION} -QMAKE_AR = $${CROSS_COMPILE}ar cq -QMAKE_RANLIB=$${CROSS_COMPILE}ranlib -QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool -QMAKE_INSTALL_NAME_TOOL=$${CROSS_COMPILE}install_name_tool -load(qt_config) diff --git a/depends/patches/qt/no-xlib.patch b/depends/patches/qt/no-xlib.patch deleted file mode 100644 index fe82c2c73cb..00000000000 --- a/depends/patches/qt/no-xlib.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 9563cef873ae82e06f60708d706d054717e801ce Mon Sep 17 00:00:00 2001 -From: Carl Dong -Date: Thu, 18 Jul 2019 17:22:05 -0400 -Subject: [PATCH] Wrap xlib related code blocks in #if's - -They are not necessary to compile QT. ---- - qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp b/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp -index 7c62c2e2b3..c05c6c0a07 100644 ---- a/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp -+++ b/qtbase/src/plugins/platforms/xcb/qxcbcursor.cpp -@@ -49,7 +49,9 @@ - #include - #include - #include -+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) - #include -+#endif - #include - #include - -@@ -384,6 +386,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) - w->setCursor(c, isBitmapCursor); - } - -+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) - static int cursorIdForShape(int cshape) - { - int cursorId = 0; -@@ -437,6 +440,7 @@ static int cursorIdForShape(int cshape) - } - return cursorId; - } -+#endif - - xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape) - { -@@ -558,7 +562,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape) - xcb_cursor_t QXcbCursor::createFontCursor(int cshape) - { - xcb_connection_t *conn = xcb_connection(); -+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) - int cursorId = cursorIdForShape(cshape); -+#endif - xcb_cursor_t cursor = XCB_NONE; - - // Try Xcursor first -@@ -589,6 +595,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) - // Non-standard X11 cursors are created from bitmaps - cursor = createNonStandardCursor(cshape); - -+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) - // Create a glpyh cursor if everything else failed - if (!cursor && cursorId) { - cursor = xcb_generate_id(conn); -@@ -596,6 +603,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) - cursorId, cursorId + 1, - 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0); - } -+#endif - - if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) { - const char *name = cursorNames[cshape]; --- -2.22.0 - diff --git a/depends/patches/qt/xkb-default.patch b/depends/patches/qt/xkb-default.patch deleted file mode 100644 index 165abf3e2e7..00000000000 --- a/depends/patches/qt/xkb-default.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- old/qtbase/src/gui/configure.pri 2018-06-06 17:28:10.000000000 -0400 -+++ new/qtbase/src/gui/configure.pri 2018-08-17 18:43:01.589384567 -0400 -@@ -43,18 +43,11 @@ - } - - defineTest(qtConfTest_xkbConfigRoot) { -- qtConfTest_getPkgConfigVariable($${1}): return(true) -- -- for (dir, $$list("/usr/share/X11/xkb", "/usr/local/share/X11/xkb")) { -- exists($$dir) { -- $${1}.value = $$dir -- export($${1}.value) -- $${1}.cache += value -- export($${1}.cache) -- return(true) -- } -- } -- return(false) -+ $${1}.value = "/usr/share/X11/xkb" -+ export($${1}.value) -+ $${1}.cache += value -+ export($${1}.cache) -+ return(true) - } - - defineTest(qtConfTest_qpaDefaultPlatform) { diff --git a/src/Makefile.am b/src/Makefile.am index ce9316eced5..d063df76211 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -809,12 +809,6 @@ if HARDEN $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS) endif -if ENABLE_BIP70 -%.pb.cc %.pb.h: %.proto - @test -f $(PROTOC) - $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$( foundationMembers; + std::set accountDestruction; /* Block hash that is excepted from BIP16 enforcement */ uint256 BIP16Exception; /** Block height and hash at which BIP34 becomes active */ @@ -89,6 +90,10 @@ struct Params { int EunosHeight; /** Foundation share after AMK, normalized to COIN = 100% */ CAmount foundationShareDFIP1; + /** Trackable burn address */ + CScript burnAddress; + /** Previous burn address to transfer tokens from */ + CScript retiredBurnAddress; /** Struct to hold percentages for coinbase distribution. * Percentages are calculated out of 10000 */ diff --git a/src/init.cpp b/src/init.cpp index eb8e5c16c83..b62b7e3c947 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1609,6 +1609,9 @@ bool AppInitMain(InitInterfaces& interfaces) paccountHistoryDB = MakeUnique(GetDataDir() / "history", nCustomCacheSize, false, fReset || fReindexChainState); } + pburnHistoryDB.reset(); + pburnHistoryDB = MakeUnique(GetDataDir() / "burn", nCustomCacheSize, false, fReset || fReindexChainState); + // If necessary, upgrade from older database format. // This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate if (!::ChainstateActive().CoinsDB().Upgrade()) { diff --git a/src/masternodes/accountshistory.cpp b/src/masternodes/accountshistory.cpp index 512d897e1b8..80a6ab4abb9 100644 --- a/src/masternodes/accountshistory.cpp +++ b/src/masternodes/accountshistory.cpp @@ -32,8 +32,13 @@ CAccountHistoryStorage::CAccountHistoryStorage(const fs::path& dbName, std::size { } -CAccountsHistoryWriter::CAccountsHistoryWriter(CCustomCSView & storage, uint32_t height, uint32_t txn, const uint256& txid, uint8_t type, CAccountsHistoryView* historyView) - : CStorageView(new CFlushableStorageKV(static_cast(storage.GetStorage()))), height(height), txn(txn), txid(txid), type(type), historyView(historyView) +CBurnHistoryStorage::CBurnHistoryStorage(const fs::path& dbName, std::size_t cacheSize, bool fMemory, bool fWipe) + : CStorageView(new CStorageLevelDB(dbName, cacheSize, fMemory, fWipe)) +{ +} + +CAccountsHistoryWriter::CAccountsHistoryWriter(CCustomCSView & storage, uint32_t height, uint32_t txn, const uint256& txid, uint8_t type, CAccountsHistoryView* historyView, CAccountsHistoryView* burnView) + : CStorageView(new CFlushableStorageKV(static_cast(storage.GetStorage()))), height(height), txn(txn), txid(txid), type(type), historyView(historyView), burnView(burnView) { } @@ -43,15 +48,29 @@ Res CAccountsHistoryWriter::AddBalance(CScript const & owner, CTokenAmount amoun if (historyView && res.ok && amount.nValue != 0) { diffs[owner][amount.nTokenId] += amount.nValue; } + if (burnView && res.ok && amount.nValue != 0 && owner == Params().GetConsensus().burnAddress) { + burnDiffs[owner][amount.nTokenId] += amount.nValue; + } return res; } +Res CAccountsHistoryWriter::AddFeeBurn(CScript const & owner, CAmount amount) +{ + if (burnView && amount != 0) { + burnDiffs[owner][DCT_ID{0}] += amount; + } + return Res::Ok(); +} + Res CAccountsHistoryWriter::SubBalance(CScript const & owner, CTokenAmount amount) { auto res = CCustomCSView::SubBalance(owner, amount); if (historyView && res.ok && amount.nValue != 0) { diffs[owner][amount.nTokenId] -= amount.nValue; } + if (burnView && res.ok && amount.nValue != 0 && owner == Params().GetConsensus().burnAddress) { + burnDiffs[owner][amount.nTokenId] -= amount.nValue; + } return res; } @@ -62,11 +81,16 @@ bool CAccountsHistoryWriter::Flush() historyView->WriteAccountHistory({diff.first, height, txn}, {txid, type, diff.second}); } } + if (burnView) { + for (const auto& diff : burnDiffs) { + burnView->WriteAccountHistory({diff.first, height, txn}, {txid, type, diff.second}); + } + } return CCustomCSView::Flush(); } -CAccountsHistoryEraser::CAccountsHistoryEraser(CCustomCSView & storage, uint32_t height, uint32_t txn, CAccountsHistoryView* historyView) - : CStorageView(new CFlushableStorageKV(static_cast(storage.GetStorage()))), height(height), txn(txn), historyView(historyView) +CAccountsHistoryEraser::CAccountsHistoryEraser(CCustomCSView & storage, uint32_t height, uint32_t txn, CAccountsHistoryView* historyView, CAccountsHistoryView* burnView) + : CStorageView(new CFlushableStorageKV(static_cast(storage.GetStorage()))), height(height), txn(txn), historyView(historyView), burnView(burnView) { } @@ -75,6 +99,9 @@ Res CAccountsHistoryEraser::AddBalance(CScript const & owner, CTokenAmount) if (historyView) { accounts.insert(owner); } + if (burnView && owner == Params().GetConsensus().burnAddress) { + burnAccounts.insert(owner); + } return Res::Ok(); } @@ -83,6 +110,9 @@ Res CAccountsHistoryEraser::SubBalance(CScript const & owner, CTokenAmount) if (historyView) { accounts.insert(owner); } + if (burnView && owner == Params().GetConsensus().burnAddress) { + burnAccounts.insert(owner); + } return Res::Ok(); } @@ -93,7 +123,13 @@ bool CAccountsHistoryEraser::Flush() historyView->EraseAccountHistory({account, height, txn}); } } + if (burnView) { + for (const auto& account : burnAccounts) { + burnView->EraseAccountHistory({account, height, txn}); + } + } return CCustomCSView::Flush(); } std::unique_ptr paccountHistoryDB; +std::unique_ptr pburnHistoryDB; diff --git a/src/masternodes/accountshistory.h b/src/masternodes/accountshistory.h index 3e0066a20e3..b928fef6fb2 100644 --- a/src/masternodes/accountshistory.h +++ b/src/masternodes/accountshistory.h @@ -69,6 +69,12 @@ class CAccountHistoryStorage : public CAccountsHistoryView CAccountHistoryStorage(const fs::path& dbName, std::size_t cacheSize, bool fMemory = false, bool fWipe = false); }; +class CBurnHistoryStorage : public CAccountsHistoryView +{ +public: + CBurnHistoryStorage(const fs::path& dbName, std::size_t cacheSize, bool fMemory = false, bool fWipe = false); +}; + class CAccountsHistoryWriter : public CCustomCSView { const uint32_t height; @@ -76,12 +82,15 @@ class CAccountsHistoryWriter : public CCustomCSView const uint256 txid; const uint8_t type; std::map diffs; + std::map burnDiffs; CAccountsHistoryView* historyView; + CAccountsHistoryView* burnView; public: - CAccountsHistoryWriter(CCustomCSView & storage, uint32_t height, uint32_t txn, const uint256& txid, uint8_t type, CAccountsHistoryView* historyView); + CAccountsHistoryWriter(CCustomCSView & storage, uint32_t height, uint32_t txn, const uint256& txid, uint8_t type, CAccountsHistoryView* historyView, CAccountsHistoryView* burnView); Res AddBalance(CScript const & owner, CTokenAmount amount) override; Res SubBalance(CScript const & owner, CTokenAmount amount) override; + Res AddFeeBurn(CScript const & owner, CAmount amount); bool Flush(); }; @@ -90,16 +99,19 @@ class CAccountsHistoryEraser : public CCustomCSView const uint32_t height; const uint32_t txn; std::set accounts; + std::set burnAccounts; CAccountsHistoryView* historyView; + CAccountsHistoryView* burnView; public: - CAccountsHistoryEraser(CCustomCSView & storage, uint32_t height, uint32_t txn, CAccountsHistoryView* historyView); + CAccountsHistoryEraser(CCustomCSView & storage, uint32_t height, uint32_t txn, CAccountsHistoryView* historyView, CAccountsHistoryView* burnView); Res AddBalance(CScript const & owner, CTokenAmount amount) override; Res SubBalance(CScript const & owner, CTokenAmount amount) override; bool Flush(); }; extern std::unique_ptr paccountHistoryDB; +extern std::unique_ptr pburnHistoryDB; static constexpr bool DEFAULT_ACINDEX = true; diff --git a/src/masternodes/mn_checks.cpp b/src/masternodes/mn_checks.cpp index f36d7e28580..e6805617f59 100644 --- a/src/masternodes/mn_checks.cpp +++ b/src/masternodes/mn_checks.cpp @@ -1181,7 +1181,7 @@ bool ShouldReturnNonFatalError(const CTransaction& tx, uint32_t height) { return it != skippedTx.end() && it->second == tx.GetHash(); } -Res RevertCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTransaction& tx, const Consensus::Params& consensus, uint32_t height, uint32_t txn, CAccountsHistoryView* historyView) { +Res RevertCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTransaction& tx, const Consensus::Params& consensus, uint32_t height, uint32_t txn, CAccountsHistoryView* historyView, CAccountsHistoryView *burnView) { if (tx.IsCoinBase() && height > 0) { // genesis contains custom coinbase txs return Res::Ok(); } @@ -1201,7 +1201,7 @@ Res RevertCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CT break; } auto txMessage = customTypeToMessage(txType); - CAccountsHistoryEraser view(mnview, height, txn, historyView); + CAccountsHistoryEraser view(mnview, height, txn, historyView, burnView); if ((res = CustomMetadataParse(height, consensus, metadata, txMessage))) { res = CustomTxRevert(view, coins, tx, height, consensus, txMessage); } @@ -1212,7 +1212,7 @@ Res RevertCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CT return (view.Flush(), res); } -Res ApplyCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTransaction& tx, const Consensus::Params& consensus, uint32_t height, uint64_t time, uint32_t txn, CAccountsHistoryView* historyView) { +Res ApplyCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTransaction& tx, const Consensus::Params& consensus, uint32_t height, uint64_t time, uint32_t txn, CAccountsHistoryView* historyView, CAccountsHistoryView* burnView) { auto res = Res::Ok(); if (tx.IsCoinBase() && height > 0) { // genesis contains custom coinbase txs return res; @@ -1223,9 +1223,14 @@ Res ApplyCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTr return res; } auto txMessage = customTypeToMessage(txType); - CAccountsHistoryWriter view(mnview, height, txn, tx.GetHash(), uint8_t(txType), historyView); + CAccountsHistoryWriter view(mnview, height, txn, tx.GetHash(), uint8_t(txType), historyView, burnView); if ((res = CustomMetadataParse(height, consensus, metadata, txMessage))) { res = CustomTxVisit(view, coins, tx, height, consensus, txMessage, time); + + // Track burn fee + if (txType == CustomTxType::CreateToken || txType == CustomTxType::CreateMasternode) { + view.AddFeeBurn(tx.vout[0].scriptPubKey, tx.vout[0].nValue); + } } // list of transactions which aren't allowed to fail: if (!res) { diff --git a/src/masternodes/mn_checks.h b/src/masternodes/mn_checks.h index e710489e87d..71d89f3f952 100644 --- a/src/masternodes/mn_checks.h +++ b/src/masternodes/mn_checks.h @@ -245,8 +245,8 @@ CCustomTxMessage customTypeToMessage(CustomTxType txType); bool IsMempooledCustomTxCreate(const CTxMemPool& pool, const uint256& txid); Res RpcInfo(const CTransaction& tx, uint32_t height, CustomTxType& type, UniValue& results); Res CustomMetadataParse(uint32_t height, const Consensus::Params& consensus, const std::vector& metadata, CCustomTxMessage& txMessage); -Res ApplyCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTransaction& tx, const Consensus::Params& consensus, uint32_t height, uint64_t time = 0, uint32_t txn = 0, CAccountsHistoryView* historyView = nullptr); -Res RevertCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTransaction& tx, const Consensus::Params& consensus, uint32_t height, uint32_t txn = 0, CAccountsHistoryView* historyView = nullptr); +Res ApplyCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTransaction& tx, const Consensus::Params& consensus, uint32_t height, uint64_t time = 0, uint32_t txn = 0, CAccountsHistoryView* historyView = nullptr, CAccountsHistoryView *burnView = nullptr); +Res RevertCustomTx(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTransaction& tx, const Consensus::Params& consensus, uint32_t height, uint32_t txn = 0, CAccountsHistoryView* historyView = nullptr, CAccountsHistoryView *burnView = nullptr); Res CustomTxVisit(CCustomCSView& mnview, const CCoinsViewCache& coins, const CTransaction& tx, uint32_t height, const Consensus::Params& consensus, const CCustomTxMessage& txMessage, uint64_t time = 0); ResVal ApplyAnchorRewardTx(CCustomCSView& mnview, const CTransaction& tx, int height, const uint256& prevStakeModifier, const std::vector& metadata, const Consensus::Params& consensusParams); ResVal ApplyAnchorRewardTxPlus(CCustomCSView& mnview, const CTransaction& tx, int height, const std::vector& metadata, const Consensus::Params& consensusParams); diff --git a/src/masternodes/rpc_accounts.cpp b/src/masternodes/rpc_accounts.cpp index f7df06fa8c9..c27d3440bcb 100644 --- a/src/masternodes/rpc_accounts.cpp +++ b/src/masternodes/rpc_accounts.cpp @@ -1063,6 +1063,161 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { return slice; } +UniValue listburnhistory(const JSONRPCRequest& request) { + CWallet* const pwallet = GetWallet(request); + RPCHelpMan{"listburnhistory", + "\nReturns information about burn history.\n", + { + {"options", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", + { + {"maxBlockHeight", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, + "Optional height to iterate from (down to genesis block), (default = chaintip)."}, + {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, + "Maximum depth, from the genesis block is the default"}, + {"token", RPCArg::Type::STR, RPCArg::Optional::OMITTED, + "Filter by token"}, + {"txtype", RPCArg::Type::STR, RPCArg::Optional::OMITTED, + "Filter by transaction type, supported letter from {CustomTxType}"}, + {"limit", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, + "Maximum number of records to return, 100 by default"}, + }, + }, + }, + RPCResult{ + "[{},{}...] (array) Objects with burn history information\n" + }, + RPCExamples{ + HelpExampleCli("listburnhistory", "'{\"maxBlockHeight\":160,\"depth\":10}'") + + HelpExampleRpc("listburnhistory", "") + }, + }.Check(request); + + uint32_t maxBlockHeight = std::numeric_limits::max(); + uint32_t depth = maxBlockHeight; + std::string tokenFilter; + uint32_t limit = 100; + auto txType = CustomTxType::None; + bool txTypeSearch{false}; + + if (request.params.size() == 1) { + UniValue optionsObj = request.params[0].get_obj(); + RPCTypeCheckObj(optionsObj, + { + {"maxBlockHeight", UniValueType(UniValue::VNUM)}, + {"depth", UniValueType(UniValue::VNUM)}, + {"token", UniValueType(UniValue::VSTR)}, + {"txtype", UniValueType(UniValue::VSTR)}, + {"limit", UniValueType(UniValue::VNUM)}, + }, true, true); + + if (!optionsObj["maxBlockHeight"].isNull()) { + maxBlockHeight = (uint32_t) optionsObj["maxBlockHeight"].get_int64(); + } + + if (!optionsObj["depth"].isNull()) { + depth = (uint32_t) optionsObj["depth"].get_int64(); + } + + if (!optionsObj["token"].isNull()) { + tokenFilter = optionsObj["token"].get_str(); + } + + if (!optionsObj["txtype"].isNull()) { + const auto str = optionsObj["txtype"].get_str(); + if (str.size() == 1) { + // Will search for type ::None if txtype not found. + txType = CustomTxCodeToType(str[0]); + txTypeSearch = true; + } + } + + if (!optionsObj["limit"].isNull()) { + limit = (uint32_t) optionsObj["limit"].get_int64(); + } + + if (limit == 0) { + limit = std::numeric_limits::max(); + } + } + + pwallet->BlockUntilSyncedToCurrentChain(); + maxBlockHeight = std::min(maxBlockHeight, uint32_t(chainHeight(*pwallet->chain().lock()))); + depth = std::min(depth, maxBlockHeight); + + // start block for asc order + const auto startBlock = maxBlockHeight - depth; + + auto shouldSkipBlock = [startBlock, maxBlockHeight](uint32_t blockHeight) { + return startBlock > blockHeight || blockHeight > maxBlockHeight; + }; + + std::function isMatchOwner = [](CScript const &) { + return true; + }; + + std::set txs; + + auto hasToken = [&tokenFilter](TAmounts const & diffs) { + for (auto const & diff : diffs) { + auto token = pcustomcsview->GetToken(diff.first); + auto const tokenIdStr = token->CreateSymbolKey(diff.first); + if(tokenIdStr == tokenFilter) { + return true; + } + } + return false; + }; + + LOCK(cs_main); + CCustomCSView view(*pcustomcsview); + CCoinsViewCache coins(&::ChainstateActive().CoinsTip()); + std::map> ret; + + auto count = limit; + + auto shouldContinueToNextAccountHistory = [&](AccountHistoryKey const & key, CLazySerialize valueLazy) -> bool + { + if (!isMatchOwner(key.owner)) { + return false; + } + + if (shouldSkipBlock(key.blockHeight)) { + return true; + } + + const auto & value = valueLazy.get(); + + if (txTypeSearch && value.category != uint8_t(txType)) { + return true; + } + + if(!tokenFilter.empty() && !hasToken(value.diff)) { + return true; + } + + auto& array = ret.emplace(key.blockHeight, UniValue::VARR).first->second; + array.push_back(accounthistoryToJSON(key, value)); + + --count; + + return count != 0; + }; + + AccountHistoryKey startKey{Params().GetConsensus().burnAddress, maxBlockHeight, std::numeric_limits::max()}; + pburnHistoryDB->ForEachAccountHistory(shouldContinueToNextAccountHistory, startKey); + + UniValue slice(UniValue::VARR); + for (auto it = ret.cbegin(); limit != 0 && it != ret.cend(); ++it) { + const auto& array = it->second.get_array(); + for (size_t i = 0; limit != 0 && i < array.size(); ++i) { + slice.push_back(array[i]); + --limit; + } + } + + return slice; +} + UniValue accounthistorycount(const JSONRPCRequest& request) { CWallet* const pwallet = GetWallet(request); RPCHelpMan{"accounthistorycount", @@ -1379,6 +1534,77 @@ UniValue sendtokenstoaddress(const JSONRPCRequest& request) { } + +UniValue getburninfo(const JSONRPCRequest& request) { + RPCHelpMan{"getburninfo", + "\nReturns burn address and burnt coin and token information\n", + { + }, + RPCResult{ + "{\n" + " \"address\" : \"address\", (string) The defi burn address\n" + " \"amount\" : n.nnnnnnnn, (string) The amount of DFI burnt\n" + " \"tokens\" : [\n" + " { (array of burnt tokens)" + " \"name\" : \"name\"\n" + " \"amount\" : n.nnnnnnnn\n" + " ]\n" + " \"feeburn\" : n.nnnnnnnn, (string) The amount of fees burnt\n" + "}\n" + }, + RPCExamples{ + HelpExampleCli("getburninfo", "") + + HelpExampleRpc("getburninfo", "") + }, + }.Check(request); + + CAmount burntDFI{0}; + CAmount burntFee{0}; + std::map burntTokens; + auto calcBurn = [&](AccountHistoryKey const & key, CLazySerialize valueLazy) -> bool + { + const auto & value = valueLazy.get(); + + // UTXO burn + if (value.category == uint8_t(CustomTxType::None)) { + for (auto const & diff : value.diff) { + burntDFI += diff.second; + } + return true; + } + + // Fee burn + if (value.category == uint8_t(CustomTxType::CreateMasternode) || value.category == uint8_t(CustomTxType::CreateToken)) { + for (auto const & diff : value.diff) { + burntFee += diff.second; + } + return true; + } + + // Token burn + for (auto const & diff : value.diff) { + burntTokens.insert({diff.first.v, diff.second}); + } + + return true; + }; + + AccountHistoryKey startKey{Params().GetConsensus().burnAddress, std::numeric_limits::max(), std::numeric_limits::max()}; + pburnHistoryDB->ForEachAccountHistory(calcBurn, startKey); + + UniValue result(UniValue::VOBJ); + result.pushKV("address", ScriptToString(Params().GetConsensus().burnAddress)); + result.pushKV("amount", ValueFromAmount(burntDFI)); + UniValue tokens(UniValue::VARR); + for (const auto& item : burntTokens) + { + tokens.push_back(tokenAmountString({{item.first}, item.second})); + } + result.pushKV("tokens", tokens); + result.pushKV("feeburn", ValueFromAmount(burntFee)); + return result; +} + static const CRPCCommand commands[] = { // category name actor (function) params @@ -1390,9 +1616,11 @@ static const CRPCCommand commands[] = {"accounts", "accounttoaccount", &accounttoaccount, {"from", "to", "inputs"}}, {"accounts", "accounttoutxos", &accounttoutxos, {"from", "to", "inputs"}}, {"accounts", "listaccounthistory", &listaccounthistory, {"owner", "options"}}, + {"accounts", "listburnhistory", &listburnhistory, {"options"}}, {"accounts", "accounthistorycount", &accounthistorycount, {"owner", "options"}}, {"accounts", "listcommunitybalances", &listcommunitybalances, {}}, {"accounts", "sendtokenstoaddress", &sendtokenstoaddress, {"from", "to", "selectionMode"}}, + {"accounts", "getburninfo", &getburninfo, {}}, }; void RegisterAccountsRPCCommands(CRPCTable& tableRPC) { diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index f52189231af..5af2075ba3a 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -241,6 +241,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listpoolshares", 2, "is_mine_only" }, { "listaccounthistory", 1, "options" }, + { "listburnhistory", 0, "options" }, { "accounthistorycount", 1, "options" }, { "setgov", 0, "variables" }, diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 9c5e198ad4b..498b689a855 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -638,6 +638,7 @@ static void CheckInputsAndUpdateCoins(const CTransaction& tx, CCoinsViewCache& m CValidationState state; CAmount txfee = 0; bool fCheckResult = tx.IsCoinBase() || Consensus::CheckTxInputs(tx, state, mempoolDuplicate, mnview, spendheight, txfee, chainparams); + fCheckResult = fCheckResult && CheckBurnSpend(tx, mempoolDuplicate); assert(fCheckResult); UpdateCoins(tx, mempoolDuplicate, std::numeric_limits::max()); } diff --git a/src/validation.cpp b/src/validation.cpp index 8ca1104812c..6f3ea48dfc2 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1408,6 +1408,20 @@ void InitScriptExecutionCache() { (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems); } +bool CheckBurnSpend(const CTransaction &tx, const CCoinsViewCache &inputs) +{ + Coin coin; + for(size_t i = 0; i < tx.vin.size(); ++i) + { + if (inputs.GetCoin(tx.vin[i].prevout, coin) && coin.out.scriptPubKey == Params().GetConsensus().burnAddress) + { + return false; + } + } + + return true; +} + /** * Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) * This does not modify the UTXO set. @@ -1427,6 +1441,11 @@ void InitScriptExecutionCache() { */ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector *pvChecks) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { + if (!CheckBurnSpend(tx, inputs)) + { + return(state.Invalid(ValidationInvalidReason::CONSENSUS, error("CheckBurnSpend: Trying to spend burnt outputs"), REJECT_INVALID, "burnt-output")); + } + if (!tx.IsCoinBase()) { if (pvChecks) @@ -1662,6 +1681,8 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI assert(nodeId); } + std::vector eraseBurnEntries; + // undo transactions in reverse order for (int i = block.vtx.size() - 1; i >= 0; i--) { const CTransaction &tx = *(block.vtx[i]); @@ -1736,6 +1757,12 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI if (!is_spent || tx.vout[o] != coin.out || pindex->nHeight != coin.nHeight || is_coinbase != coin.fCoinBase) { fClean = false; // transaction output mismatch } + + // Check for burn outputs + if (tx.vout[o].scriptPubKey == Params().GetConsensus().burnAddress) + { + eraseBurnEntries.push_back({Params().GetConsensus().burnAddress, static_cast(pindex->nHeight), static_cast(i)}); + } } } @@ -1758,11 +1785,45 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI // process transactions revert for masternodes mnview.OnUndoTx(tx.GetHash(), (uint32_t) pindex->nHeight); - auto res = RevertCustomTx(mnview, view, tx, Params().GetConsensus(), (uint32_t) pindex->nHeight, i, paccountHistoryDB.get()); + auto res = RevertCustomTx(mnview, view, tx, Params().GetConsensus(), (uint32_t) pindex->nHeight, i, paccountHistoryDB.get(), pburnHistoryDB.get()); if (!res) { LogPrintf("%s\n", res.msg); } } + + // Remove burn balance transfers + if (pindex->nHeight == Params().GetConsensus().EunosHeight) + { + uint32_t lastTxOut; + auto shouldContinueToNextAccountHistory = [&lastTxOut, block](AccountHistoryKey const & key, CLazySerialize valueLazy) -> bool + { + if (key.owner != Params().GetConsensus().burnAddress) { + return false; + } + + if (key.blockHeight != Params().GetConsensus().EunosHeight) { + return false; + } + + lastTxOut = key.txn; + + return false; + }; + + AccountHistoryKey startKey({Params().GetConsensus().burnAddress, static_cast(Params().GetConsensus().EunosHeight), std::numeric_limits::max()}); + pburnHistoryDB->ForEachAccountHistory(shouldContinueToNextAccountHistory, startKey); + + for (uint32_t i = block.vtx.size(); i <= lastTxOut; ++i) { + pburnHistoryDB->EraseAccountHistory({Params().GetConsensus().burnAddress, static_cast(Params().GetConsensus().EunosHeight), i}); + } + } + + // Erase any UTXO burns + for (const auto& entries : eraseBurnEntries) + { + pburnHistoryDB->EraseAccountHistory(entries); + } + // move best block pointer to prevout block view.SetBestBlock(pindex->pprev->GetBlockHash()); @@ -2049,6 +2110,24 @@ static int64_t nTimeCallbacks = 0; static int64_t nTimeTotal = 0; static int64_t nBlocksTotal = 0; +// Holds position for burn TXs appended to block in burn history +static std::vector::size_type nPhantomBurnTx{0}; + +static std::map mapBurnAmounts; + +static uint32_t GetNextBurnPosition() { + return nPhantomBurnTx++; +} + +// Burn non-transaction amounts, that is burns that are not sent directly to the burn address +// in a account or UTXO transaction. When parsing TXs via ConnectBlock that result in a burn +// from an account in this way call the function below. This will add the burn to the map to +// be added to the burn index as a phantom TX appended to the end of the connecting block. +Res AddNonTxToBurnIndex(const CScript& from, const CBalances& amounts) +{ + return mapBurnAmounts[from].AddBalances(amounts.balances); +} + /** Apply the effects of this block (with given index) on the UTXO set represented by coins. * Validity checks that depend on the UTXO set are also done; ConnectBlock() * can fail if those validity checks fail (among other reasons). */ @@ -2059,6 +2138,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl assert(pindex); assert(*pindex->phashBlock == block.GetHash()); int64_t nTimeStart = GetTimeMicros(); + nPhantomBurnTx = block.vtx.size(); // Check it again in case a previous version let a bad block in // NOTE: We don't currently (re-)invoke ContextualCheckBlock() or @@ -2276,6 +2356,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : nullptr); + std::vector> writeBurnEntries; std::vector prevheights; CAmount nFees = 0; int nInputs = 0; @@ -2355,7 +2436,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl tx.GetHash().ToString(), FormatStateMessage(state)); } - const auto res = ApplyCustomTx(accountsView, view, tx, chainparams.GetConsensus(), pindex->nHeight, pindex->GetBlockTime(), i, paccountHistoryDB.get()); + const auto res = ApplyCustomTx(accountsView, view, tx, chainparams.GetConsensus(), pindex->nHeight, pindex->GetBlockTime(), i, paccountHistoryDB.get(), pburnHistoryDB.get()); if (!res.ok && (res.code & CustomTxErrCodes::Fatal)) { // we will never fail, but skip, unless transaction mints UTXOs return error("ConnectBlock(): ApplyCustomTx on %s failed with %s", @@ -2421,6 +2502,16 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl } } + // Search for burn outputs + for (uint32_t j = 0; j < tx.vout.size(); ++j) + { + if (tx.vout[j].scriptPubKey == Params().GetConsensus().burnAddress) + { + writeBurnEntries.push_back({{Params().GetConsensus().burnAddress, static_cast(pindex->nHeight), i}, + {block.vtx[i]->GetHash(), static_cast(CustomTxType::None), {{DCT_ID{0}, tx.vout[j].nValue}}}}); + } + } + CTxUndo undoDummy; if (i > 0) { blockundo.vtxundo.push_back(CTxUndo()); @@ -2517,6 +2608,66 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl cache.BayfrontFlagsCleanup(); } + if (pindex->nHeight == chainparams.GetConsensus().EunosHeight) + { + // Move funds from old burn address to new one + CBalances burnAmounts; + cache.ForEachBalance([&burnAmounts](CScript const & owner, CTokenAmount balance) { + if (owner != Params().GetConsensus().retiredBurnAddress) { + return false; + } + + burnAmounts.Add({balance.nTokenId, balance.nValue}); + + return true; + }, BalanceKey{chainparams.GetConsensus().retiredBurnAddress, DCT_ID{}}); + + AddNonTxToBurnIndex(chainparams.GetConsensus().retiredBurnAddress, burnAmounts); + + // Zero foundation balances + for (const auto& script : chainparams.GetConsensus().accountDestruction) + { + CBalances zeroAmounts; + cache.ForEachBalance([&zeroAmounts, script](CScript const & owner, CTokenAmount balance) { + if (owner != script) { + return false; + } + + zeroAmounts.Add({balance.nTokenId, balance.nValue}); + + return true; + }, BalanceKey{script, DCT_ID{}}); + + cache.SubBalances(script, zeroAmounts); + } + } + + // Add any non-Tx burns to index as phantom Txs + for (const auto& item : mapBurnAmounts) + { + for (const auto& subItem : item.second.balances) + { + // If amount cannot be deducted then burn skipped. + auto result = cache.SubBalance(item.first, {subItem.first, subItem.second}); + if (result.ok) + { + cache.AddBalance(chainparams.GetConsensus().burnAddress, {subItem.first, subItem.second}); + + // Add transfer as additional TX in block + pburnHistoryDB->WriteAccountHistory({Params().GetConsensus().burnAddress, static_cast(pindex->nHeight), GetNextBurnPosition()}, + {uint256{}, static_cast(CustomTxType::AccountToAccount), {{subItem.first, subItem.second}}}); + } + else // Log burn failure + { + CTxDestination dest; + ExtractDestination(item.first, dest); + LogPrintf("Burn failed: %s Address: %s Token: %d Amount: %d\n", result.msg, EncodeDestination(dest), subItem.first.v, subItem.second); + } + } + } + + mapBurnAmounts.clear(); + // construct undo auto& flushable = cache.GetStorage(); auto undo = CUndo::Construct(mnview.GetStorage(), flushable.GetRaw()); @@ -2528,6 +2679,12 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl } } + // Write any UTXO burns + for (const auto& entries : writeBurnEntries) + { + pburnHistoryDB->WriteAccountHistory(entries.first, entries.second); + } + if (!fIsFakeNet) { mnview.IncrementMintedBy(minterKey); @@ -2807,6 +2964,9 @@ bool CChainState::DisconnectTip(CValidationState& state, const CChainParams& cha if (paccountHistoryDB) { paccountHistoryDB->Discard(); } + if (pburnHistoryDB) { + pburnHistoryDB->Discard(); + } return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); } bool flushed = view.Flush() && mnview.Flush(); @@ -2816,6 +2976,9 @@ bool CChainState::DisconnectTip(CValidationState& state, const CChainParams& cha if (paccountHistoryDB) { paccountHistoryDB->Flush(); } + if (pburnHistoryDB) { + pburnHistoryDB->Flush(); + } if (!disconnectedConfirms.empty()) { for (auto const & confirm : disconnectedConfirms) { @@ -2966,6 +3129,9 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp if (paccountHistoryDB) { paccountHistoryDB->Discard(); } + if (pburnHistoryDB) { + pburnHistoryDB->Discard(); + } return error("%s: ConnectBlock %s failed, %s", __func__, pindexNew->GetBlockHash().ToString(), FormatStateMessage(state)); } nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2; @@ -2977,6 +3143,9 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp if (paccountHistoryDB) { paccountHistoryDB->Flush(); } + if (pburnHistoryDB) { + pburnHistoryDB->Flush(); + } // anchor rewards re-voting etc... if (!rewardedAnchors.empty()) { diff --git a/src/validation.h b/src/validation.h index 9ab8bbfe649..ec5e1c4f20e 100644 --- a/src/validation.h +++ b/src/validation.h @@ -35,6 +35,7 @@ #include class CAnchorConfirmMessage; +struct CBalances; class CChainState; class CDoubleSignFact; class CCustomCSView; @@ -243,6 +244,8 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr& block, CValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr, CBlockHeader* first_invalid = nullptr) LOCKS_EXCLUDED(cs_main); +/** Check if transaction is trying to spend a burnt output */ +bool CheckBurnSpend(const CTransaction &tx, const CCoinsViewCache &inputs); /** Open a block file (blk?????.dat) */ FILE* OpenBlockFile(const FlatFilePos &pos, bool fReadOnly = false); /** Translation to a filesystem path */ @@ -819,4 +822,6 @@ inline CAmount CalculateCoinbaseReward(const CAmount blockReward, const uint32_t return (blockReward * percentage) / 10000; } +Res AddNonTxToBurnIndex(const CScript& from, const CBalances& amounts); + #endif // DEFI_VALIDATION_H diff --git a/test/functional/feature_burn_address.py b/test/functional/feature_burn_address.py new file mode 100755 index 00000000000..e2fca39ee8d --- /dev/null +++ b/test/functional/feature_burn_address.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2019 The Bitcoin Core developers +# Copyright (c) DeFi Blockchain Developers +# Distributed under the MIT software license, see the accompanying +# file LICENSE or http://www.opensource.org/licenses/mit-license.php. +"""Test burn address tracking""" + +from test_framework.test_framework import DefiTestFramework + +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal + +from decimal import Decimal + +class BurnAddressTest(DefiTestFramework): + def set_test_params(self): + self.num_nodes = 1 + self.setup_clean_chain = True + self.extra_args = [['-txnotokens=0', '-amkheight=1', '-eunosheight=1', '-dakotaheight=1']] + + def run_test(self): + + self.nodes[0].generate(101) + + # Burn address + burn_address = "mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG" + burn_scriptpubkey = self.nodes[0].getaddressinfo(burn_address)['scriptPubKey'] + self.nodes[0].importprivkey("93ViFmLeJVgKSPxWGQHmSdT5RbeGDtGW4bsiwQM2qnQyucChMqQ") + + # Test masternode creation fee burn + collateral = self.nodes[0].getnewaddress("", "legacy") + self.nodes[0].createmasternode(collateral) + self.nodes[0].generate(1) + + # Check create masternode burn fee + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'][0:16], "6a1a446654784301") # OP_RETURN data + assert_equal(result[0]['txn'], 1) + assert_equal(result[0]['type'], 'CreateMasternode') + assert_equal(result[0]['amounts'][0], '1.00000000@DFI') + + result = self.nodes[0].getburninfo() + assert_equal(result['address'], burn_address) + assert_equal(result['amount'], Decimal('0.00000000')) + assert_equal(len(result['tokens']), 0) + assert_equal(result['feeburn'], Decimal('1.00000000')) + + # Create funded account address + funded_address = self.nodes[0].getnewaddress() + self.nodes[0].sendtoaddress(funded_address, 1) + self.nodes[0].utxostoaccount({funded_address:"3@0"}) + self.nodes[0].generate(1) + + # Test burn token + self.nodes[0].createtoken({ + "symbol": "GOLD", + "name": "shiny gold", + "collateralAddress": funded_address + }) + self.nodes[0].generate(1) + + # Check token burn fee + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], "6a1f446654785404474f4c440a7368696e7920676f6c6408000000000000000003") # OP_RETURN data + assert_equal(result[0]['txn'], 1) + assert_equal(result[0]['type'], 'CreateToken') + assert_equal(result[0]['amounts'][0], '1.00000000@DFI') + + # Mint tokens + self.nodes[0].minttokens(["100@128"]) + self.nodes[0].generate(1) + + # Send tokens to burn address + self.nodes[0].accounttoaccount(funded_address, {burn_address:"100@128"}) + self.nodes[0].generate(1) + + # Check burn history + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG') + assert_equal(result[0]['type'], 'AccountToAccount') + assert_equal(result[0]['amounts'][0], '100.00000000@GOLD#128') + + # Track utxostoaccount burn + self.nodes[0].utxostoaccount({burn_address:"1@0"}) + self.nodes[0].generate(1) + + # Check burn history + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG') + assert_equal(result[0]['type'], 'UtxosToAccount') + assert_equal(result[0]['amounts'][0], '1.00000000@DFI') + + # Try and spend from burn address account + try: + self.nodes[0].accounttoaccount(burn_address, {funded_address:"1@0"}) + except JSONRPCException as e: + errorString = e.error['message'] + assert("burnt-output" in errorString) + + # Send to burn address with accounttoaccount + self.nodes[0].accounttoaccount(funded_address, {burn_address:"1@0"}) + self.nodes[0].generate(1) + + # Check burn history + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG') + assert_equal(result[0]['type'], 'AccountToAccount') + assert_equal(result[0]['amounts'][0], '1.00000000@DFI') + + # Auto auth from failed accounttoaccount + assert_equal(result[1]['owner'], 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG') + assert_equal(result[1]['type'], 'None') + assert_equal(result[1]['amounts'][0], '0.99988640@DFI') + + # Send to burn address with accounttoutxos + self.nodes[0].accounttoutxos(funded_address, {burn_address:"2@0"}) + self.nodes[0].generate(1) + + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG') + assert_equal(result[0]['type'], 'None') + assert_equal(result[0]['amounts'][0], '2.00000000@DFI') + + # Send utxo to burn address + txid = self.nodes[0].sendtoaddress(burn_address, 10) + decodedtx = self.nodes[0].getrawtransaction(txid, 1) + self.nodes[0].generate(1) + + # Check burn history + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG') + assert_equal(result[0]['type'], 'None') + assert_equal(result[0]['amounts'][0], '10.00000000@DFI') + + # Spend TX from burn address + for outputs in decodedtx['vout']: + if outputs['scriptPubKey']['addresses'][0] == burn_address: + vout = outputs['n'] + + rawtx = self.nodes[0].createrawtransaction([{"txid":txid,"vout":vout}], [{burn_address:9.9999}]) + signed_rawtx = self.nodes[0].signrawtransactionwithwallet(rawtx) + assert_equal(signed_rawtx['complete'], True) + + # Send should fail as transaction is invalid + try: + self.nodes[0].sendrawtransaction(signed_rawtx['hex']) + except JSONRPCException as e: + errorString = e.error['message'] + assert("burnt-output" in errorString) + + # Test output of getburninfo + result = self.nodes[0].getburninfo() + assert_equal(result['address'], burn_address) + assert_equal(result['amount'], Decimal('12.99988640')) + assert_equal(result['tokens'][0], '1.00000000@DFI') + assert_equal(result['tokens'][1], '100.00000000@GOLD#128') + assert_equal(result['feeburn'], Decimal('2.00000000')) + + # Filter on tx type None + result = self.nodes[0].listburnhistory({"txtype":'0'}) + assert_equal(len(result), 3) + assert_equal(result[0]['type'], 'None') + assert_equal(result[1]['type'], 'None') + assert_equal(result[2]['type'], 'None') + + # Filter on tx type UtxosToAccount + result = self.nodes[0].listburnhistory({"txtype":'U'}) + assert_equal(len(result), 1) + assert_equal(result[0]['type'], 'UtxosToAccount') + + # Filter on tx type AccountToAccount + result = self.nodes[0].listburnhistory({"txtype":'B'}) + assert_equal(len(result), 2) + assert_equal(result[0]['type'], 'AccountToAccount') + assert_equal(result[1]['type'], 'AccountToAccount') + + # Filter on tx type CreateMasternode + result = self.nodes[0].listburnhistory({"txtype":'C'}) + assert_equal(len(result), 1) + assert_equal(result[0]['type'], 'CreateMasternode') + + # Filter on tx type CreateToken + result = self.nodes[0].listburnhistory({"txtype":'T'}) + assert_equal(len(result), 1) + assert_equal(result[0]['type'], 'CreateToken') + + # Revert all TXs and check that burn history is empty + self.nodes[0].invalidateblock(self.nodes[0].getblockhash(101)) + result = self.nodes[0].listburnhistory() + assert_equal(len(result), 0) + + result = self.nodes[0].getburninfo() + assert_equal(result['address'], burn_address) + assert_equal(result['amount'], Decimal('0.0')) + assert_equal(len(result['tokens']), 0) + +if __name__ == '__main__': + BurnAddressTest().main() diff --git a/test/functional/feature_eunos_balances.py b/test/functional/feature_eunos_balances.py new file mode 100755 index 00000000000..db91fd81fbd --- /dev/null +++ b/test/functional/feature_eunos_balances.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2019 The Bitcoin Core developers +# Copyright (c) DeFi Blockchain Developers +# Distributed under the MIT software license, see the accompanying +# file LICENSE or http://www.opensource.org/licenses/mit-license.php. +"""Test burn address tracking""" + +from test_framework.test_framework import DefiTestFramework + +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal + +from decimal import Decimal + +class TransferBurnTest(DefiTestFramework): + def set_test_params(self): + self.num_nodes = 1 + self.setup_clean_chain = True + self.extra_args = [['-txnotokens=0', '-amkheight=1', '-eunosheight=200', '-dakotaheight=1']] + + def run_test(self): + + # Burn address + old_burn_address = "mfdefichainDSTBurnAddressXXXZcE1vs" + burn_address = "mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG" + + # Destruction addresses + destruction_one = "2MxJf6Ak8MGrLoGdekrU6AusW29szZUFphH" + destruction_two = "mxiaFfAnCoXEUy4RW8NgsQM7yU5YRCiFSh" + + # Import priv keys to allow sending account DFI to them + self.nodes[0].importprivkey("cVx5Bn1MQREmdR1STQZK1dMD7XwzvUQCajTRjYjtppXzDk7F6gx2") + self.nodes[0].importprivkey("cQ3NeYsQfNT4LsEWQQTYm4iSRbKJcuvdyPLTpVxzaRxkPfnQcQxn") + + self.nodes[0].generate(101) + + # Create funded account address + address = self.nodes[0].getnewaddress() + self.nodes[0].sendtoaddress(address, 1) + self.nodes[0].generate(1) + + # Create tokens + self.nodes[0].createtoken({ + "symbol": "GOLD", + "name": "shiny gold", + "collateralAddress": address + }) + self.nodes[0].generate(1) + + # Check token burn fee + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], "6a1f446654785404474f4c440a7368696e7920676f6c6408000000000000000003") # OP_RETURN data + assert_equal(result[0]['txn'], 1) + assert_equal(result[0]['type'], 'CreateToken') + assert_equal(result[0]['amounts'][0], '1.00000000@DFI') + + self.nodes[0].createtoken({ + "symbol": "SILVER", + "name": "shiny silver", + "collateralAddress": address + }) + self.nodes[0].generate(1) + + # Check token burn fee + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], "6a2344665478540653494c5645520c7368696e792073696c76657208000000000000000003") # OP_RETURN data + assert_equal(result[0]['txn'], 1) + assert_equal(result[0]['type'], 'CreateToken') + assert_equal(result[0]['amounts'][0], '1.00000000@DFI') + + # Mint tokens + self.nodes[0].minttokens(["100@128"]) + self.nodes[0].generate(1) + + self.nodes[0].minttokens(["100@129"]) + self.nodes[0].generate(1) + + # Send tokens to burn address + self.nodes[0].accounttoaccount(address, {old_burn_address:"100@128"}) + self.nodes[0].generate(1) + + self.nodes[0].accounttoaccount(address, {old_burn_address:"100@129"}) + self.nodes[0].generate(1) + + # Check balance + result = self.nodes[0].getaccount(old_burn_address) + assert_equal(result[0], "100.00000000@GOLD#128") + assert_equal(result[1], "100.00000000@SILVER#129") + + # Send funds to destruction addresses + self.nodes[0].utxostoaccount({destruction_one:"5@0"}) + self.nodes[0].utxostoaccount({destruction_one:"5@0"}) + self.nodes[0].utxostoaccount({destruction_two:"20@0"}) + self.nodes[0].generate(1) + + # Check destruction balance + result = self.nodes[0].getaccount(destruction_one) + assert_equal(result[0], "10.00000000@DFI") + result = self.nodes[0].getaccount(destruction_two) + assert_equal(result[0], "20.00000000@DFI") + + # Move one past fork height + self.nodes[0].generate(201 - self.nodes[0].getblockcount()) + + # Check funds have moved + assert_equal(len(self.nodes[0].getaccount(old_burn_address)), 0) + result = self.nodes[0].getaccount(burn_address) + assert_equal(result[0], "100.00000000@GOLD#128") + assert_equal(result[1], "100.00000000@SILVER#129") + + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], burn_address) + assert_equal(result[0]['txn'], 2) + assert_equal(result[0]['type'], 'AccountToAccount') + assert_equal(result[0]['amounts'][0], '100.00000000@SILVER#129') + assert_equal(result[1]['owner'], burn_address) + assert_equal(result[1]['txn'], 1) + assert_equal(result[1]['type'], 'AccountToAccount') + assert_equal(result[1]['amounts'][0], '100.00000000@GOLD#128') + + result = self.nodes[0].getburninfo() + assert_equal(result['address'], burn_address) + assert_equal(result['amount'], Decimal('0.00000000')) + assert_equal(result['tokens'][0], '100.00000000@GOLD#128') + assert_equal(result['tokens'][1], '100.00000000@SILVER#129') + assert_equal(result['feeburn'], Decimal('2.00000000')) + + # Check destruction balance + result = self.nodes[0].getaccount(destruction_one) + assert_equal(len(result), 0) + result = self.nodes[0].getaccount(destruction_two) + assert_equal(len(result), 0) + + # Revert fork block + self.nodes[0].invalidateblock(self.nodes[0].getblockhash(200)) + + assert_equal(len(self.nodes[0].getaccount(burn_address)), 0) + result = self.nodes[0].getaccount(old_burn_address) + assert_equal(result[0], "100.00000000@GOLD#128") + assert_equal(result[1], "100.00000000@SILVER#129") + + assert_equal(len(self.nodes[0].listburnhistory()), 2) # Creation fee burns still present + + result = self.nodes[0].getburninfo() + assert_equal(result['address'], burn_address) + assert_equal(result['amount'], Decimal('0.00000000')) + assert_equal(len(result['tokens']), 0) + + # Check destruction balance + result = self.nodes[0].getaccount(destruction_one) + assert_equal(result[0], "10.00000000@DFI") + result = self.nodes[0].getaccount(destruction_two) + assert_equal(result[0], "20.00000000@DFI") + + # Move to fork height to reburn + self.nodes[0].generate(2) + assert_equal(len(self.nodes[0].getaccount(old_burn_address)), 0) + result = self.nodes[0].getaccount(burn_address) + assert_equal(result[0], "100.00000000@GOLD#128") + assert_equal(result[1], "100.00000000@SILVER#129") + + result = self.nodes[0].listburnhistory() + assert_equal(result[0]['owner'], burn_address) + assert_equal(result[0]['txn'], 2) + assert_equal(result[0]['type'], 'AccountToAccount') + assert_equal(result[0]['amounts'][0], '100.00000000@SILVER#129') + assert_equal(result[1]['owner'], burn_address) + assert_equal(result[1]['txn'], 1) + assert_equal(result[1]['type'], 'AccountToAccount') + assert_equal(result[1]['amounts'][0], '100.00000000@GOLD#128') + + result = self.nodes[0].getburninfo() + assert_equal(result['address'], burn_address) + assert_equal(result['amount'], Decimal('0.00000000')) + assert_equal(result['tokens'][0], '100.00000000@GOLD#128') + assert_equal(result['tokens'][1], '100.00000000@SILVER#129') + assert_equal(result['feeburn'], Decimal('2.00000000')) + + # Check destruction balance + result = self.nodes[0].getaccount(destruction_one) + assert_equal(len(result), 0) + result = self.nodes[0].getaccount(destruction_two) + assert_equal(len(result), 0) + +if __name__ == '__main__': + TransferBurnTest().main() diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 78a0a8967ea..ce8ecdbdf1a 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -612,6 +612,9 @@ def cache_path(*paths): os.remove(cache_path('wallets', entry)) os.rmdir(cache_path('wallets')) # Remove empty wallets dir + # Remove custom dirs + shutil.rmtree(cache_path('burn')) + for entry in os.listdir(cache_path()): if entry not in ['chainstate', 'blocks', 'enhancedcs', 'anchors', 'criminals', 'history']: # Only keep chainstate and blocks folder os.remove(cache_path(entry)) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index cb63eb844bb..27c90dd79b1 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -251,6 +251,8 @@ 'feature_shutdown.py', 'feature_oracles.py', 'rpc_getmininginfo.py', + 'feature_burn_address.py', + 'feature_eunos_balances.py', # Don't append tests at the end to avoid merge conflicts # Put them in a random line within the section that fits their approximate run-time ]