diff --git a/.gitignore b/.gitignore index 648ba775d..ace208d29 100644 --- a/.gitignore +++ b/.gitignore @@ -8,12 +8,17 @@ mine1.sh mine2.sh *.exe +*.pdb src/pocketcoin src/pocketcoind src/pocketcoin-cli +src/pocketcoin-gui +src/pocketcoin-node src/pocketcoin-tx +src/pocketcoin-wallet +src/test/fuzz/* +!src/test/fuzz/*.* src/test/test_pocketcoin -src/test/test_pocketcoin_fuzzy src/qt/test/test_pocketcoin-qt # autoreconf @@ -33,6 +38,7 @@ build-aux/m4/ltversion.m4 build-aux/missing build-aux/compile build-aux/test-driver +config.cache config.log config.status configure @@ -40,6 +46,7 @@ libtool src/config/pocketcoin-config.h src/config/pocketcoin-config.h.in src/config/stamp-h1 +src/obj share/setup.nsi share/qt/Info.plist @@ -71,10 +78,10 @@ src/qt/pocketcoin-qt.includes *.pyc *.o *.o-* -*.patch *.a *.pb.cc *.pb.h +*.dat *.log *.trs @@ -83,6 +90,10 @@ src/qt/pocketcoin-qt.includes *.json.h *.raw.h +# Only ignore unexpected patches +*.patch +!depends/patches/**/*.patch + #libtool object files *.lo *.la @@ -92,10 +103,14 @@ src/qt/pocketcoin-qt.includes src/**/Makefile Makefile doc/Makefile -pocketcoin-qt +!depends/Makefile +src/qt/pocketcoin-qt Pocketcoin-Qt.app background.tiff* +# Qt Creator +Makefile.am.user + # Unit-tests Makefile.test pocketcoin-qt_test @@ -107,13 +122,19 @@ qrc_*.cpp .DS_Store build +# Previous releases +releases + #lcov *.gcno *.gcda /*.info test_pocketcoin.coverage/ total.coverage/ +fuzz.coverage/ coverage_percent.txt +/cov_tool_wrapper.sh +qa-assets/ #build tests linux-coverage-build @@ -121,6 +142,7 @@ linux-build win32-build test/config.ini test/cache/* +test/.mypy_cache/ !src/leveldb*/Makefile @@ -128,6 +150,17 @@ test/cache/* libpocketcoinconsensus.pc contrib/devtools/split-debug.sh + +# Output from running db4 installation +db4/ + +# clang-check +*.plist + +osx_volname +dist/ +*.background.tiff + /confdefs.h /build_msvc/pocketcoind/testdb /build_msvc/pocketcoind/dbMessage diff --git a/CMakeLists.txt b/CMakeLists.txt index d57dc062b..a35b57cd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ add_compile_definitions(CLIENT_VERSION_MAJOR=${_CLIENT_VERSION_MAJOR} COPYRIGHT_HOLDERS_FINAL=${_COPYRIGHT_HOLDERS_FINAL} HOMEPAGE=${_HOMEPAGE}) -# TODO missing bug report url +# TODO (build): missing bug report url project ( Pocketnet-Core VERSION ${_CLIENT_VERSION_MAJOR}.${_CLIENT_VERSION_MINOR}.${_CLIENT_VERSION_REVISION} diff --git a/Makefile.am b/Makefile.am index 52d572df8..3bfdc5b59 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,7 +24,7 @@ POCKETCOIND_BIN=$(top_builddir)/src/$(POCKETCOIN_DAEMON_NAME)$(EXEEXT) POCKETCOIN_QT_BIN=$(top_builddir)/src/qt/$(POCKETCOIN_GUI_NAME)$(EXEEXT) POCKETCOIN_CLI_BIN=$(top_builddir)/src/$(POCKETCOIN_CLI_NAME)$(EXEEXT) POCKETCOIN_TX_BIN=$(top_builddir)/src/$(POCKETCOIN_TX_NAME)$(EXEEXT) -POCKETCOIN_WALLET_BIN=$(top_builddir)/src/$(POCKETCOIN_WALLET_TOOL_NAME)$(EXEEXT) +# POCKETCOIN_WALLET_BIN=$(top_builddir)/src/$(POCKETCOIN_WALLET_TOOL_NAME)$(EXEEXT) POCKETCOIN_WIN_INSTALLER=$(PACKAGE)_$(PACKAGE_VERSION)_win_x64_setup.exe POCKETCOIN_LINUX_INSTALLER = $(PACKAGE)_$(PACKAGE_VERSION)_linux_x64 POCKETCOIN_LINUX_INSTALLER_NAME = $(PACKAGE)_$(PACKAGE_VERSION)_linux_x64 @@ -81,7 +81,6 @@ $(POCKETCOIN_WIN_INSTALLER): all-recursive STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(POCKETCOIN_QT_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(POCKETCOIN_CLI_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(POCKETCOIN_TX_BIN) $(top_builddir)/release - STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(POCKETCOIN_WALLET_BIN) $(top_builddir)/release @test -f $(MAKENSIS) && echo 'OutFile "$@"' | cat $(top_builddir)/share/setup.nsi - | $(MAKENSIS) -V2 - || \ echo error: could not build $@ @echo built $@ @@ -196,8 +195,8 @@ $(POCKETCOIN_CLI_BIN): FORCE $(POCKETCOIN_TX_BIN): FORCE $(MAKE) -C src $(@F) -$(POCKETCOIN_WALLET_BIN): FORCE - $(MAKE) -C src $(@F) +# $(POCKETCOIN_WALLET_BIN): FORCE +# $(MAKE) -C src $(@F) if USE_LCOV LCOV_FILTER_PATTERN = \ diff --git a/build_msvc/pocketcoin_config.h b/build_msvc/pocketcoin_config.h index 898d86e87..57a880834 100644 --- a/build_msvc/pocketcoin_config.h +++ b/build_msvc/pocketcoin_config.h @@ -11,10 +11,10 @@ #define CLIENT_VERSION_MAJOR 0 /* Minor version */ -#define CLIENT_VERSION_MINOR 20 +#define CLIENT_VERSION_MINOR 21 /* Build revision */ -#define CLIENT_VERSION_REVISION 19 +#define CLIENT_VERSION_REVISION 0 /* Version Build */ #define CLIENT_VERSION_BUILD 0 @@ -346,7 +346,7 @@ #define PACKAGE_NAME "Pocketnet Core" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "Pocketnet Core 0.20.19" +#define PACKAGE_STRING "Pocketnet Core 0.21.0" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pocketcoin" @@ -355,7 +355,7 @@ #define PACKAGE_URL "https://github.com/pocketnetteam" /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.20.19" +#define PACKAGE_VERSION "0.21.0" /* Define to necessary symbol if this constant uses a non-standard name on your system. */ diff --git a/configure.ac b/configure.ac index f8883cc4b..590fb6fc0 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,7 @@ POCKETCOIN_DAEMON_NAME=pocketcoind POCKETCOIN_GUI_NAME=pocketcoin-qt POCKETCOIN_CLI_NAME=pocketcoin-cli POCKETCOIN_TX_NAME=pocketcoin-tx -POCKETCOIN_WALLET_TOOL_NAME=pocketcoin-wallet +# POCKETCOIN_WALLET_TOOL_NAME=pocketcoin-wallet dnl Unless the user specified ARFLAGS, force it to be cr AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to if not set]) @@ -117,7 +117,7 @@ AC_ARG_ENABLE([wallet], [enable_wallet=$enableval], [enable_wallet=yes]) -# TODO (team): we are using bundled sqlite so explicitly disable it here to avoid autotools finding it on system +# We are using bundled sqlite so explicitly disable it here to avoid autotools finding it on system # AC_ARG_WITH([sqlite], # [AS_HELP_STRING([--with-sqlite=yes|no|auto], # [enable sqlite wallet support (default: auto, i.e., enabled if wallet is enabled and sqlite is found)])], @@ -257,7 +257,7 @@ AC_ARG_WITH([mpgen], AC_ARG_ENABLE([multiprocess], [AS_HELP_STRING([--enable-multiprocess], - [build multiprocess pocketcoin-node, pocketcoin-wallet, and pocketcoin-gui executables in addition to monolithic pocketcoind and pocketcoin-qt executables. Requires libmultiprocess library. Experimental (default is no)])], + [build multiprocess pocketcoin-node, and pocketcoin-gui executables in addition to monolithic pocketcoind and pocketcoin-qt executables. Requires libmultiprocess library. Experimental (default is no)])], [enable_multiprocess=$enableval], [enable_multiprocess=no]) @@ -545,7 +545,7 @@ CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" AC_ARG_WITH([utils], [AS_HELP_STRING([--with-utils], - [build pocketcoin-cli pocketcoin-tx pocketcoin-wallet (default=yes)])], + [build pocketcoin-cli pocketcoin-tx (default=yes)])], [build_pocketcoin_utils=$withval], [build_pocketcoin_utils=yes]) @@ -561,11 +561,11 @@ AC_ARG_ENABLE([util-tx], [build_pocketcoin_tx=$enableval], [build_pocketcoin_tx=$build_pocketcoin_utils]) -AC_ARG_ENABLE([util-wallet], - [AS_HELP_STRING([--enable-util-wallet], - [build pocketcoin-wallet])], - [build_pocketcoin_wallet=$enableval], - [build_pocketcoin_wallet=$build_pocketcoin_utils]) +# AC_ARG_ENABLE([util-wallet], +# [AS_HELP_STRING([--enable-util-wallet], +# [build pocketcoin-wallet])], +# [build_pocketcoin_wallet=$enableval], +# [build_pocketcoin_wallet=$build_pocketcoin_utils]) AC_ARG_WITH([libs], [AS_HELP_STRING([--with-libs], @@ -579,7 +579,7 @@ AC_ARG_WITH([daemon], [build_pocketcoind=$withval], [build_pocketcoind=yes]) -dnl TODO openssl is removed out of bitcoin +dnl Restore openssl that was removed from bitcoin 0.21 AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) @@ -601,6 +601,7 @@ case $host in AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(libuuid missing)) AC_CHECK_LIB([advapi32], [CryptAcquireContextW],, AC_MSG_ERROR(libadvapi32 missing)) AC_CHECK_LIB([ws2_32], [WSAStartup],, AC_MSG_ERROR(libws2_32 missing)) + AC_CHECK_LIB([mswsock], [main],, AC_MSG_ERROR(libmswsock missing)) AC_CHECK_LIB([shlwapi], [PathRemoveFileSpecW],, AC_MSG_ERROR(libshlwapi missing)) AC_CHECK_LIB([iphlpapi], [GetAdaptersAddresses],, AC_MSG_ERROR(libiphlpapi missing)) @@ -1263,11 +1264,7 @@ if test x$have_miniupnpc != xno; then fi fi -if test x$build_pocketcoin_wallet$build_pocketcoin_cli$build_pocketcoin_tx$build_pocketcoind$pocketcoin_enable_qt$use_tests$use_bench = xnonononononono; then - use_boost=no -else - use_boost=yes -fi +use_boost=yes if test x$use_boost = xyes; then @@ -1580,7 +1577,7 @@ if test x$build_pocketcoin_wallet$build_pocketcoin_cli$build_pocketcoin_tx$build AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests]) fi -# TODO (team) hardcoded cause we use sqlite anyway +# Forced using sqlite AC_DEFINE([USE_SQLITE],[1],[Define if sqlite support should be compiled in]) AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) @@ -1630,7 +1627,7 @@ AC_SUBST(POCKETCOIN_DAEMON_NAME) AC_SUBST(POCKETCOIN_GUI_NAME) AC_SUBST(POCKETCOIN_CLI_NAME) AC_SUBST(POCKETCOIN_TX_NAME) -AC_SUBST(POCKETCOIN_WALLET_TOOL_NAME) +# AC_SUBST(POCKETCOIN_WALLET_TOOL_NAME) AC_SUBST(RELDFLAGS) AC_SUBST(DEBUG_CPPFLAGS) @@ -1714,7 +1711,6 @@ if test x$need_bundled_univalue = xyes; then AC_CONFIG_SUBDIRS([src/univalue]) fi -# TODO probably make this optional AC_CONFIG_SUBDIRS([src/sqlite]) ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --with-bignum=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental" diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt index c08564d46..85b303c8b 100644 --- a/contrib/seeds/nodes_main.txt +++ b/contrib/seeds/nodes_main.txt @@ -1,4 +1,3 @@ -216.108.231.40 135.181.196.243 65.21.56.203 65.21.57.14 diff --git a/depends/.gitignore b/depends/.gitignore index 72734102c..19c506ce5 100644 --- a/depends/.gitignore +++ b/depends/.gitignore @@ -8,5 +8,7 @@ i686* mips* arm* aarch64* +powerpc* riscv32* riscv64* +s390x* diff --git a/depends/Makefile b/depends/Makefile index 95379f363..1ad21f682 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -1,14 +1,44 @@ .NOTPARALLEL : +# Pattern rule to print variables, e.g. make print-top_srcdir +print-%: + @echo $* = $($*) + +# When invoking a sub-make, keep only the command line variable definitions +# matching the pattern in the filter function. +# +# e.g. invoking: +# $ make A=1 C=1 print-MAKEOVERRIDES print-MAKEFLAGS +# +# with the following in the Makefile: +# MAKEOVERRIDES := $(filter A=% B=%,$(MAKEOVERRIDES)) +# +# will print: +# MAKEOVERRIDES = A=1 +# MAKEFLAGS = -- A=1 +# +# this is because as the GNU make manual says: +# The command line variable definitions really appear in the variable +# MAKEOVERRIDES, and MAKEFLAGS contains a reference to this variable. +# +# and since the GNU make manual also says: +# variables defined on the command line are passed to the sub-make through +# MAKEFLAGS +# +# this means that sub-makes will be invoked as if: +# $(MAKE) A=1 blah blah +MAKEOVERRIDES := $(filter V=%,$(MAKEOVERRIDES)) SOURCES_PATH ?= $(BASEDIR)/sources WORK_PATH = $(BASEDIR)/work BASE_CACHE ?= $(BASEDIR)/built SDK_PATH ?= $(BASEDIR)/SDKs NO_QT ?= -RAPIDCHECK ?= +NO_QR ?= NO_WALLET ?= +NO_ZMQ ?= NO_UPNP ?= -FALLBACK_DOWNLOAD_PATH ?= https://pocketcoincore.org/depends-sources +MULTIPROCESS ?= +FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources BUILD = $(shell ./config.guess) HOST ?= $(BUILD) @@ -53,6 +83,11 @@ full_host_os:=$(subst $(host_arch)-$(host_vendor)-,,$(canonical_host)) host_os:=$(findstring linux,$(full_host_os)) host_os+=$(findstring darwin,$(full_host_os)) host_os+=$(findstring mingw32,$(full_host_os)) + +ifeq (android,$(findstring android,$(full_host_os))) +host_os:=android +endif + host_os:=$(strip $(host_os)) ifeq ($(host_os),) host_os=$(full_host_os) @@ -90,32 +125,50 @@ $(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) $(sqlite_packages) -upnp_packages_$(NO_UPNP) = $(upnp_packages) +ifneq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +build_id_string+=system_clang +$(host_arch)_$(host_os)_id_string+=system_clang +endif + +qrencode_packages_$(NO_QR) = $(qrencode_packages) -rapidcheck_packages_$(RAPIDCHECK) = $(rapidcheck_packages) +qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) $(qrencode_packages_) + +bdb_packages_$(NO_BDB) = $(bdb_packages) +sqlite_packages_$(NO_SQLITE) = $(sqlite_packages) +wallet_packages_$(NO_WALLET) = $(bdb_packages_) $(sqlite_packages_) + +upnp_packages_$(NO_UPNP) = $(upnp_packages) +zmq_packages_$(NO_ZMQ) = $(zmq_packages) +multiprocess_packages_$(MULTIPROCESS) = $(multiprocess_packages) packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_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) +ifneq ($(zmq_packages_),) +packages += $(zmq_packages) endif -ifeq ($(rapidcheck_packages_),) -packages += $(rapidcheck_packages) +ifeq ($(multiprocess_packages_),) +packages += $(multiprocess_packages) +native_packages += $(multiprocess_native_packages) endif all_packages = $(packages) $(native_packages) meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk +$(host_arch)_$(host_os)_native_binutils?=$($(host_os)_native_binutils) $(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain) include funcs.mk +binutils_path=$($($(host_arch)_$(host_os)_native_binutils)_prefixbin) +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin) +else +toolchain_path= +endif final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) @@ -131,10 +184,10 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ $(AT)sed -e 's|@HOST@|$(host)|' \ -e 's|@CC@|$(toolchain_path)$(host_CC)|' \ -e 's|@CXX@|$(toolchain_path)$(host_CXX)|' \ - -e 's|@AR@|$(toolchain_path)$(host_AR)|' \ - -e 's|@RANLIB@|$(toolchain_path)$(host_RANLIB)|' \ - -e 's|@NM@|$(toolchain_path)$(host_NM)|' \ - -e 's|@STRIP@|$(toolchain_path)$(host_STRIP)|' \ + -e 's|@AR@|$(binutils_path)$(host_AR)|' \ + -e 's|@RANLIB@|$(binutils_path)$(host_RANLIB)|' \ + -e 's|@NM@|$(binutils_path)$(host_NM)|' \ + -e 's|@STRIP@|$(binutils_path)$(host_STRIP)|' \ -e 's|@build_os@|$(build_os)|' \ -e 's|@host_os@|$(host_os)|' \ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ @@ -143,8 +196,11 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -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_qr@|$(NO_QR)|' \ + -e 's|@no_zmq@|$(NO_ZMQ)|' \ -e 's|@no_wallet@|$(NO_WALLET)|' \ -e 's|@no_upnp@|$(NO_UPNP)|' \ + -e 's|@multiprocess@|$(MULTIPROCESS)|' \ -e 's|@debug@|$(DEBUG)|' \ $< > $@ $(AT)touch $@ @@ -174,7 +230,7 @@ $(host_prefix)/share/config.site: check-packages check-packages: check-sources clean-all: clean - @rm -rf $(SOURCES_PATH) x86_64* i686* mips* arm* aarch64* riscv32* riscv64* + @rm -rf $(SOURCES_PATH) x86_64* i686* mips* arm* aarch64* powerpc* riscv32* riscv64* s390x* clean: @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) @@ -192,4 +248,6 @@ download-win: @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one download: download-osx download-linux download-win +$(foreach package,$(all_packages),$(eval $(call ext_add_stages,$(package)))) + .PHONY: install cached clean clean-all download-one download-osx download-linux download-win download check-packages check-sources diff --git a/depends/README.md b/depends/README.md index 51711463b..15bda8be1 100644 --- a/depends/README.md +++ b/depends/README.md @@ -12,72 +12,140 @@ For example: make HOST=x86_64-w64-mingw32 -j4 -A prefix will be generated that's suitable for plugging into Pocketcoin's -configure. In the above example, a dir named x86_64-w64-mingw32 will be +**Pocketcoin Core's configure script by default will ignore the depends output.** In +order for it to pick up libraries, tools, and settings from the depends build, +you must point it at the appropriate `--prefix` directory generated by the +build. In the above example, a prefix dir named x86_64-w64-mingw32 will be created. To use it for Pocketcoin: - ./configure --prefix=`pwd`/depends/x86_64-w64-mingw32 + ./configure --prefix=$PWD/depends/x86_64-w64-mingw32 Common `host-platform-triplets` for cross compilation are: -- `i686-w64-mingw32` for Win32 +- `i686-pc-linux-gnu` for Linux 32 bit +- `x86_64-pc-linux-gnu` for x86 Linux - `x86_64-w64-mingw32` for Win64 -- `x86_64-apple-darwin14` for macOS -- `x86_64-pc-linux-gnu` for x64 Linux +- `x86_64-apple-darwin16` for macOS - `arm-linux-gnueabihf` for Linux ARM 32 bit - `aarch64-linux-gnu` for Linux ARM 64 bit +- `powerpc64-linux-gnu` for Linux POWER 64-bit (big endian) +- `powerpc64le-linux-gnu` for Linux POWER 64-bit (little endian) - `riscv32-linux-gnu` for Linux RISC-V 32 bit - `riscv64-linux-gnu` for Linux RISC-V 64 bit +- `s390x-linux-gnu` for Linux S390X +- `armv7a-linux-android` for Android ARM 32 bit +- `aarch64-linux-android` for Android ARM 64 bit +- `i686-linux-android` for Android x86 32 bit +- `x86_64-linux-android` for Android x86 64 bit -No other options are needed, the paths are automatically configured. +The paths are automatically configured and no other options are needed unless targeting [Android](#Android). -Install the required dependencies: Ubuntu & Debian --------------------------------------------------- +### Install the required dependencies: Ubuntu & Debian -For macOS cross compilation: +#### For macOS cross compilation - sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python-setuptools + sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python3-setuptools libtinfo5 -For Win32/Win64 cross compilation: +#### For Win64 cross compilation - see [build-windows.md](../doc/build-windows.md#cross-compilation-for-ubuntu-and-windows-subsystem-for-linux) -For linux (including i386, ARM) cross compilation: +#### For linux (including i386, ARM) cross compilation - sudo apt-get install curl g++-aarch64-linux-gnu g++-4.8-aarch64-linux-gnu gcc-4.8-aarch64-linux-gnu binutils-aarch64-linux-gnu g++-arm-linux-gnueabihf g++-4.8-arm-linux-gnueabihf gcc-4.8-arm-linux-gnueabihf binutils-arm-linux-gnueabihf g++-4.8-multilib gcc-4.8-multilib binutils-gold bsdmainutils +Common linux dependencies: + + sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch + +For linux ARM cross compilation: + + sudo apt-get install g++-arm-linux-gnueabihf binutils-arm-linux-gnueabihf + +For linux AARCH64 cross compilation: + + sudo apt-get install g++-aarch64-linux-gnu binutils-aarch64-linux-gnu + +For linux POWER 64-bit cross compilation (there are no packages for 32-bit): + + sudo apt-get install g++-powerpc64-linux-gnu binutils-powerpc64-linux-gnu g++-powerpc64le-linux-gnu binutils-powerpc64le-linux-gnu For linux RISC-V 64-bit cross compilation (there are no packages for 32-bit): - sudo apt-get install curl g++-riscv64-linux-gnu binutils-riscv64-linux-gnu + sudo apt-get install g++-riscv64-linux-gnu binutils-riscv64-linux-gnu -RISC-V known issue: gcc-7.3.0 and gcc-7.3.1 result in a broken `test_pocketcoin` executable (see https://github.com/pocketcoin/pocketcoin/pull/13543), +RISC-V known issue: gcc-7.3.0 and gcc-7.3.1 result in a broken `test_pocketcoin` executable (see https://github.com/bitcoin/bitcoin/pull/13543), this is apparently fixed in gcc-8.1.0. -Dependency Options: -The following can be set when running make: make FOO=bar - - SOURCES_PATH: downloaded sources will be placed here - 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_WALLET: Don't download/build/cache libs needed to enable the wallet - NO_UPNP: Don't download/build/cache packages needed for enabling upnp - DEBUG: disable some optimizations and enable more runtime checking - RAPIDCHECK: build rapidcheck (experimental) - HOST_ID_SALT: Optional salt to use when generating host package ids - BUILD_ID_SALT: Optional salt to use when generating build package ids +For linux S390X cross compilation: + + sudo apt-get install g++-s390x-linux-gnu binutils-s390x-linux-gnu + +### Dependency Options +The following can be set when running make: `make FOO=bar` + +
+
SOURCES_PATH
+
downloaded sources will be placed here
+
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_QR
+
Don't download/build/cache packages needed for enabling qrencode
+
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_BDB
+
Don't download/build/cache BerkeleyDB
+
NO_SQLITE
+
Don't download/build/cache SQLite
+
NO_UPNP
+
Don't download/build/cache packages needed for enabling upnp
+
ALLOW_HOST_PACKAGES
+
Packages that are missed in dependencies (due to `NO_*` option or +build script logic) are searched for among the host system packages using +`pkg-config`. It allows building with packages of other (newer) versions
+
MULTIPROCESS
+
build libmultiprocess (experimental, requires cmake)
+
DEBUG
+
disable some optimizations and enable more runtime checking
+
HOST_ID_SALT
+
Optional salt to use when generating host package ids
+
BUILD_ID_SALT
+
Optional salt to use when generating build package ids
+
FORCE_USE_SYSTEM_CLANG
+
(EXPERTS ONLY) When cross-compiling for macOS, use Clang found in the +system's $PATH rather than the default prebuilt release of Clang +from llvm.org. Clang 8 or later is required.
+
If some packages are not built, for example `make NO_WALLET=1`, the appropriate options will be passed to pocketcoin's configure. In this case, `--disable-wallet`. -Additional targets: +### Additional targets download: run 'make download' to fetch all sources without building them download-osx: run 'make download-osx' to fetch all sources needed for macOS builds download-win: run 'make download-win' to fetch all sources needed for win builds download-linux: run 'make download-linux' to fetch all sources needed for linux builds + +### Android + +Before proceeding with an Android build one needs to get the [Android SDK](https://developer.android.com/studio) and use the "SDK Manager" tool to download the NDK and one or more "Platform packages" (these are Android versions and have a corresponding API level). +In order to build `ANDROID_API_LEVEL` (API level corresponding to the Android version targeted, e.g. Android 9.0 Pie is 28 and its "Platform package" needs to be available) and `ANDROID_TOOLCHAIN_BIN` (path to toolchain binaries depending on the platform the build is being performed on) need to be set. + +API levels from 24 to 29 have been tested to work. + +If the build includes Qt, environment variables `ANDROID_SDK` and `ANDROID_NDK` need to be set as well but can otherwise be omitted. +This is an example command for a default build with no disabled dependencies: + + ANDROID_SDK=/home/user/Android/Sdk ANDROID_NDK=/home/user/Android/Sdk/ndk-bundle make HOST=aarch64-linux-android ANDROID_API_LEVEL=28 ANDROID_TOOLCHAIN_BIN=/home/user/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin + ### Other documentation - [description.md](description.md): General description of the depends system diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index 27f550ab0..f4103fc1f 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -1,17 +1,17 @@ -build_darwin_CC: = $(shell xcrun -f clang) -build_darwin_CXX: = $(shell xcrun -f clang++) -build_darwin_AR: = $(shell xcrun -f ar) -build_darwin_RANLIB: = $(shell xcrun -f ranlib) -build_darwin_STRIP: = $(shell xcrun -f strip) -build_darwin_OTOOL: = $(shell xcrun -f otool) -build_darwin_NM: = $(shell xcrun -f nm) +build_darwin_CC:=$(shell xcrun -f clang) --sysroot $(shell xcrun --show-sdk-path) +build_darwin_CXX:=$(shell xcrun -f clang++) --sysroot $(shell xcrun --show-sdk-path) +build_darwin_AR:=$(shell xcrun -f ar) +build_darwin_RANLIB:=$(shell xcrun -f ranlib) +build_darwin_STRIP:=$(shell xcrun -f strip) +build_darwin_OTOOL:=$(shell xcrun -f otool) +build_darwin_NM:=$(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) -build_darwin_SHA256SUM = shasum -a 256 -build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o +build_darwin_SHA256SUM=shasum -a 256 +build_darwin_DOWNLOAD=curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o #darwin host on darwin builder. overrides darwin host preferences. -darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) -darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) -stdlib=libc++ +darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(shell xcrun --show-sdk-path) +darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) -stdlib=libc++ --sysroot $(shell xcrun --show-sdk-path) darwin_AR:=$(shell xcrun -f ar) darwin_RANLIB:=$(shell xcrun -f ranlib) darwin_STRIP:=$(shell xcrun -f strip) @@ -19,4 +19,5 @@ darwin_LIBTOOL:=$(shell xcrun -f libtool) darwin_OTOOL:=$(shell xcrun -f otool) darwin_NM:=$(shell xcrun -f nm) darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) +darwin_native_binutils= darwin_native_toolchain= diff --git a/depends/config.guess b/depends/config.guess index 2b79f6d83..7f9ebbe31 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2018-07-06' +timestamp='2019-09-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -84,8 +84,6 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 - # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -96,34 +94,38 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp 2>/dev/null) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in - ,,) echo "int x;" > "$dummy.c" ; - for c in cc gcc c89 c99 ; do - if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi @@ -138,7 +140,7 @@ Linux|GNU|GNU/*) # We could probably try harder. LIBC=gnu - eval "$set_cc_for_build" + set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) @@ -199,7 +201,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval "$set_cc_for_build" + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -260,6 +262,9 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" + exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; @@ -269,12 +274,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) - echo mips-dec-osf1 - exit ;; + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -389,7 +397,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval "$set_cc_for_build" + set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. @@ -482,7 +490,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ @@ -579,7 +587,7 @@ EOF exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include @@ -660,7 +668,7 @@ EOF esac fi if [ "$HP_ARCH" = "" ]; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE @@ -700,7 +708,7 @@ EOF esac if [ "$HP_ARCH" = hppa2.0w ] then - eval "$set_cc_for_build" + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -726,7 +734,7 @@ EOF echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int @@ -840,6 +848,17 @@ EOF *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + fi + exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in @@ -881,7 +900,7 @@ EOF echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin + echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" @@ -922,7 +941,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then @@ -971,23 +990,51 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" - test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -1100,7 +1147,7 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then @@ -1284,38 +1331,39 @@ EOF echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval "$set_cc_for_build" - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; @@ -1358,6 +1406,7 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. + # shellcheck disable=SC2154 if test "$cputype" = 386; then UNAME_MACHINE=i386 else @@ -1414,8 +1463,148 @@ EOF amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; esac +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in diff --git a/depends/config.site.in b/depends/config.site.in index b7a5e795c..87a337930 100755 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -16,15 +16,22 @@ 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 +if test -z $with_mpgen && test -n "@multiprocess@"; then + with_mpgen=$depends_prefix/native fi +if test -z $with_qrencode && test -n "@no_qr@"; then + with_qrencode=no +fi if test -z $enable_wallet && test -n "@no_wallet@"; then enable_wallet=no fi +if test -z $enable_multiprocess && test -n "@multiprocess@"; then + enable_multiprocess=yes +fi + if test -z $with_miniupnpc && test -n "@no_upnp@"; then with_miniupnpc=no fi @@ -33,20 +40,15 @@ 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 + if test x@host_os@ = xdarwin; then BREW=no 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" @@ -55,7 +57,7 @@ PKG_CONFIG="`which pkg-config` --static" # avoid ruining the cache. Sigh. export PKG_CONFIG_PATH=$depends_prefix/share/pkgconfig:$depends_prefix/lib/pkgconfig if test -z "@allow_host_packages@"; then - export PKGCONFIG_LIBDIR= + export PKG_CONFIG_LIBDIR=$depends_prefix/lib/pkgconfig fi CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS" @@ -67,7 +69,7 @@ fi if test -n "@CXX@" -a -z "${CXX}"; then CXX="@CXX@" fi -PYTHONPATH=$depends_prefix/native/lib/python/dist-packages:$PYTHONPATH +PYTHONPATH=$depends_prefix/native/lib/python3/dist-packages:$PYTHONPATH if test -n "@AR@"; then AR=@AR@ diff --git a/depends/config.sub b/depends/config.sub index c95acc681..a318a4686 100755 --- a/depends/config.sub +++ b/depends/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2018-07-03' +timestamp='2019-06-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -89,7 +89,7 @@ while test $# -gt 0 ; do - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) @@ -111,7 +111,8 @@ case $# in esac # Split fields of configuration type -IFS="-" read -r field1 field2 field3 field4 <&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv64 \ + | rl78 | romp | rs6000 | rx \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1356,9 +1345,9 @@ case $os in | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* \ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ - | clix* | riscos* | uniplus* | iris* | rtu* | xenix* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ | knetbsd* | mirbsd* | netbsd* \ - | bitrig* | openbsd* | solidbsd* | libertybsd* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ @@ -1376,12 +1365,13 @@ case $os in | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ | skyos* | haiku* | rdos* | toppers* | drops* | es* \ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ - | midnightbsd*) + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix) # Remember, each alternative MUST END IN *, to match a version number. ;; qnx*) - case $basic_machine in - x86-* | i*86-*) + case $cpu in + x86 | i*86) ;; *) os=nto-$os @@ -1460,9 +1450,6 @@ case $os in ns2) os=nextstep2 ;; - nsk*) - os=nsk - ;; # Preserve the version number of sinix5. sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` @@ -1507,7 +1494,7 @@ case $os in # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. - case $basic_machine in + case $cpu in arm*) os=eabi ;; @@ -1541,7 +1528,7 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +case $cpu-$vendor in score-*) os=elf ;; @@ -1722,9 +1709,8 @@ fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) +case $vendor in + unknown) case $os in riscix*) vendor=acorn @@ -1793,11 +1779,10 @@ case $basic_machine in vendor=stratus ;; esac - basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo "$basic_machine-$os" +echo "$cpu-$vendor-$os" exit # Local variables: diff --git a/depends/description.md b/depends/description.md index b47ca38b4..216c82c66 100644 --- a/depends/description.md +++ b/depends/description.md @@ -1,4 +1,4 @@ -This is a system of building and caching dependencies necessary for building Pocketcoin. +This is a system of building and caching dependencies necessary for building Pocketcoin. There are several features that make it different from most similar systems: ### It is designed to be builder and host agnostic @@ -26,7 +26,7 @@ Before building, a unique build-id is generated for each package. This id consists of a hash of all files used to build the package (Makefiles, packages, etc), and as well as a hash of the same data for each recursive dependency. If any portion of a package's build recipe changes, it will be rebuilt as well as -any other package that depends on it. If any of the main makefiles (Makefile, +any other package that depends on it. If any of the main makefiles (Makefile, funcs.mk, etc) are changed, all packages will be rebuilt. After building, the results are cached into a tarball that can be re-used and distributed. diff --git a/depends/funcs.mk b/depends/funcs.mk index 15e404e42..58d882eb0 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -41,7 +41,7 @@ endef define int_get_build_id $(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies)) -$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($(1)_dependencies))) +$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($($(1)_type)_native_binutils) $($(1)_dependencies))) $(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash))) $(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id_string)) $(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))) @@ -76,8 +76,9 @@ $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path)) #default commands +# The default behavior for tar will try to set ownership when running as uid 0 and may not succeed, --no-same-owner disables this behavior $(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash)) -$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --strip-components=1 -xf $$($(1)_source) +$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --no-same-owner --strip-components=1 -xf $$($(1)_source) $(1)_preprocess_cmds ?= $(1)_build_cmds ?= $(1)_config_cmds ?= @@ -129,11 +130,11 @@ $(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$( $(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig $(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig +$(1)_config_env+=CMAKE_MODULE_PATH=$($($(1)_type)_prefix)/lib/cmake $(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH) -$(1)_autoconf=./configure --host=$($($(1)_type)_host) --disable-dependency-tracking --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" - +$(1)_autoconf=./configure --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" ifneq ($($(1)_nm),) $(1)_autoconf += NM="$$($(1)_nm)" endif @@ -155,6 +156,20 @@ endif ifneq ($($(1)_ldflags),) $(1)_autoconf += LDFLAGS="$$($(1)_ldflags)" endif + +$(1)_cmake=env CC="$$($(1)_cc)" \ + CFLAGS="$$($(1)_cppflags) $$($(1)_cflags)" \ + CXX="$$($(1)_cxx)" \ + CXXFLAGS="$$($(1)_cppflags) $$($(1)_cxxflags)" \ + LDFLAGS="$$($(1)_ldflags)" \ + cmake -DCMAKE_INSTALL_PREFIX:PATH="$$($($(1)_type)_prefix)" +ifneq ($($(1)_type),build) +ifneq ($(host),$(build)) +$(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system) +$(1)_cmake += -DCMAKE_C_COMPILER_TARGET=$(host) +$(1)_cmake += -DCMAKE_CXX_COMPILER_TARGET=$(host) +endif +endif endef define int_add_cmds @@ -170,15 +185,15 @@ $($(1)_extracted): | $($(1)_fetched) $(AT)mkdir -p $$(@D) $(AT)cd $$(@D); $(call $(1)_extract_cmds,$(1)) $(AT)touch $$@ -$($(1)_preprocessed): | $($(1)_dependencies) $($(1)_extracted) +$($(1)_preprocessed): | $($(1)_extracted) $(AT)echo Preprocessing $(1)... $(AT)mkdir -p $$(@D) $($(1)_patch_dir) $(AT)$(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) $(AT)cd $$(@D); $(call $(1)_preprocess_cmds, $(1)) $(AT)touch $$@ -$($(1)_configured): | $($(1)_preprocessed) +$($(1)_configured): | $($(1)_dependencies) $($(1)_preprocessed) $(AT)echo Configuring $(1)... - $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar xf $($(package)_cached); ) + $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar --no-same-owner -xf $($(package)_cached); ) $(AT)mkdir -p $$(@D) $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) $(AT)touch $$@ @@ -213,6 +228,14 @@ $(1): | $($(1)_cached_checksum) endef +stages = fetched extracted preprocessed configured built staged postprocessed cached cached_checksum + +define ext_add_stages +$(foreach stage,$(stages), + $(1)_$(stage): $($(1)_$(stage)) + .PHONY: $(1)_$(stage)) +endef + # These functions create the build targets for each package. They must be # broken down into small steps so that each part is done for all packages # before moving on to the next step. Otherwise, a package's info @@ -242,4 +265,4 @@ $(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$ $(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package)))) #special exception: if a toolchain package exists, all non-native packages depend on it -$(foreach package,$(packages),$(eval $($(package)_unpacked): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) )) +$(foreach package,$(packages),$(eval $($(package)_extracted): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) $($($(host_arch)_$(host_os)_native_binutils)_cached) )) diff --git a/depends/hosts/android.mk b/depends/hosts/android.mk new file mode 100644 index 000000000..eabd84bbb --- /dev/null +++ b/depends/hosts/android.mk @@ -0,0 +1,12 @@ +ifeq ($(HOST),armv7a-linux-android) +android_AR=$(ANDROID_TOOLCHAIN_BIN)/arm-linux-androideabi-ar +android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)eabi$(ANDROID_API_LEVEL)-clang++ +android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)eabi$(ANDROID_API_LEVEL)-clang +android_RANLIB=$(ANDROID_TOOLCHAIN_BIN)/arm-linux-androideabi-ranlib +else +android_AR=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)-ar +android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang++ +android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang +android_RANLIB=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)-ranlib +endif +android_cmake_system=Android diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index a1c943d60..6099fd4c7 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,9 +1,35 @@ -OSX_MIN_VERSION=10.10 -OSX_SDK_VERSION=10.11 -OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk -LD64_VERSION=253.9 -darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++ +OSX_MIN_VERSION=10.12 +OSX_SDK_VERSION=10.15.1 +XCODE_VERSION=11.3.1 +XCODE_BUILD_ID=11C505 +LD64_VERSION=530 + +OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers + +# Flag explanations: +# +# -mlinker-version +# +# Ensures that modern linker features are enabled. See here for more +# details: https://github.com/bitcoin/bitcoin/pull/19407. +# +# -B$(build_prefix)/bin +# +# Explicitly point to our binaries (e.g. cctools) so that they are +# ensured to be found and preferred over other possibilities. +# +# -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 +# +# Forces clang to use the libc++ headers from our SDK and completely +# forget about the libc++ headers from the standard directories +# +# TODO: Once we start requiring a clang version that has the +# -stdlib++-isystem flag first introduced here: +# https://reviews.llvm.org/D64089, we should use that instead. Read the +# differential summary there for more details. +# +darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin +darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -stdlib=libc++ -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 darwin_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) @@ -14,4 +40,11 @@ darwin_release_CXXFLAGS=$(darwin_release_CFLAGS) darwin_debug_CFLAGS=-O1 darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS) +darwin_native_binutils=native_cctools +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) darwin_native_toolchain=native_cctools +else +darwin_native_toolchain= +endif + +darwin_cmake_system=Darwin diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk index 144e5f88b..258619a9d 100644 --- a/depends/hosts/default.mk +++ b/depends/hosts/default.mk @@ -13,9 +13,18 @@ default_host_OTOOL = $(host_toolchain)otool default_host_NM = $(host_toolchain)nm define add_host_tool_func +ifneq ($(filter $(origin $1),undefined default),) +# Do not consider the well-known var $1 if it is undefined or is taking a value +# that is predefined by "make" (e.g. the make variable "CC" has a predefined +# value of "cc") $(host_os)_$1?=$$(default_host_$1) $(host_arch)_$(host_os)_$1?=$$($(host_os)_$1) $(host_arch)_$(host_os)_$(release_type)_$1?=$$($(host_os)_$1) +else +$(host_os)_$1=$(or $($1),$($(host_os)_$1),$(default_host_$1)) +$(host_arch)_$(host_os)_$1=$(or $($1),$($(host_arch)_$(host_os)_$1),$$($(host_os)_$1)) +$(host_arch)_$(host_os)_$(release_type)_$1=$(or $($1),$($(host_arch)_$(host_os)_$(release_type)_$1),$$($(host_os)_$1)) +endif host_$1=$$($(host_arch)_$(host_os)_$1) endef diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index b13a0f1ad..8ab448ce5 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -29,3 +29,4 @@ i686_linux_CXX=$(default_host_CXX) -m32 x86_64_linux_CC=$(default_host_CC) -m64 x86_64_linux_CXX=$(default_host_CXX) -m64 endif +linux_cmake_system=Linux diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index dbfb62fdc..be5fec570 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -8,3 +8,5 @@ mingw32_debug_CFLAGS=-O1 mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS) mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC + +mingw_cmake_system=Windows diff --git a/depends/packages.md b/depends/packages.md index 7c8036250..eaa17c958 100644 --- a/depends/packages.md +++ b/depends/packages.md @@ -5,6 +5,10 @@ The package "mylib" will be used here as an example General tips: - mylib_foo is written as $(package)_foo in order to make recipes more similar. +- Secondary dependency packages relative to the pocketcoin binaries/libraries (i.e. + those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't + need to be shared and should be built statically whenever possible. See + [below](#secondary-dependencies) for more details. ## Identifiers Each package is required to define at least these variables: @@ -14,8 +18,9 @@ Each package is required to define at least these variables: placeholder such as 1.0 can be used. $(package)_download_path: - Location of the upstream source, without the file-name. Usually http or - ftp. + Location of the upstream source, without the file-name. Usually http, https + or ftp. Secure transmission options like https should be preferred if + available. $(package)_file_name: The upstream source filename available at the download path. @@ -27,15 +32,15 @@ These variables are optional: $(package)_build_subdir: cd to this dir before running configure/build/stage commands. - + $(package)_download_file: The file-name of the upstream source if it differs from how it should be stored locally. This can be used to avoid storing file-names with strange characters. - + $(package)_dependencies: Names of any other packages that this one depends on. - + $(package)_patches: Filenames of any patches needed to build the package @@ -129,7 +134,7 @@ the user. Other variables may be defined as needed. Stage the build results. If undefined, does nothing. The following variables are available for each recipe: - + $(1)_staging_dir: package's destination sysroot path $(1)_staging_prefix_dir: prefix path inside of the package's staging dir $(1)_extract_dir: path to the package's extracted sources @@ -145,3 +150,49 @@ $($(package)_config_opts) will be appended. Most autotools projects can be properly staged using: $(MAKE) DESTDIR=$($(package)_staging_dir) install + +## Build outputs: + +In general, the output of a depends package should not contain any libtool +archives. Instead, the package should output `.pc` (`pkg-config`) files where +possible. + +From the [Gentoo Wiki entry](https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Handling_Libtool_Archives): + +> Libtool pulls in all direct and indirect dependencies into the .la files it +> creates. This leads to massive overlinking, which is toxic to the Gentoo +> ecosystem, as it leads to a massive number of unnecessary rebuilds. + +## Secondary dependencies: + +Secondary dependency packages relative to the pocketcoin binaries/libraries (i.e. +those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't +need to be shared and should be built statically whenever possible. This +improves general build reliability as illustrated by the following example: + +When linking an executable against a shared library `libprimary` that has its +own shared dependency `libsecondary`, we may need to specify the path to +`libsecondary` on the link command using the `-rpath/-rpath-link` options, it is +not sufficient to just say `libprimary`. + +For us, it's much easier to just link a static `libsecondary` into a shared +`libprimary`. Especially because in our case, we are linking against a dummy +`libprimary` anyway that we'll throw away. We don't care if the end-user has a +static or dynamic `libseconday`, that's not our concern. With a static +`libseconday`, when we need to link `libprimary` into our executable, there's no +dependency chain to worry about as `libprimary` has all the symbols. + +## Build targets: + +To build an individual package (useful for debugging), following build targets are available. + + make ${package} + make ${package}_fetched + make ${package}_extracted + make ${package}_preprocessed + make ${package}_configured + make ${package}_built + make ${package}_staged + make ${package}_postprocessed + make ${package}_cached + make ${package}_cached_checksum diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 6c9876c2c..5953341d9 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -1,20 +1,22 @@ package=bdb $(package)_version=4.8.30 -$(package)_download_path=http://download.oracle.com/berkeley-db +$(package)_download_path=https://download.oracle.com/berkeley-db $(package)_file_name=db-$($(package)_version).NC.tar.gz $(package)_sha256_hash=12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef $(package)_build_subdir=build_unix +$(package)_patches=clang_cxx_11.patch define $(package)_set_vars -$(package)_config_opts=--disable-shared --enable-cxx --disable-replication +$(package)_config_opts=--disable-shared --enable-cxx --disable-replication --enable-option-checking $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic +$(package)_cflags+=-Wno-error=implicit-function-declaration $(package)_cxxflags=-std=c++11 +$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef define $(package)_preprocess_cmds - sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h && \ - sed -i.old 's/atomic_init/atomic_init_db/' dbinc/atomic.h mp/mp_region.c mp/mp_mvcc.c mp/mp_fget.c mutex/mut_method.c mutex/mut_tas.c && \ + patch -p1 < $($(package)_patch_dir)/clang_cxx_11.patch && \ cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub dist endef diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index e26745976..cea02dffe 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -9,19 +9,26 @@ $(package)_config_opts_release=variant=release $(package)_config_opts_debug=variant=debug $(package)_config_opts=--layout=tagged --build-type=complete --user-config=user-config.jam $(package)_config_opts+=threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1 -$(package)_config_opts_linux=threadapi=pthread runtime-link=shared -$(package)_config_opts_darwin=--toolset=darwin-4.2.1 runtime-link=shared -$(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static +$(package)_config_opts_linux=target-os=linux threadapi=pthread runtime-link=shared +$(package)_config_opts_darwin=target-os=darwin runtime-link=shared +$(package)_config_opts_mingw32=target-os=windows binary-format=pe threadapi=win32 runtime-link=static $(package)_config_opts_x86_64_mingw32=address-model=64 $(package)_config_opts_i686_mingw32=address-model=32 $(package)_config_opts_i686_linux=address-model=32 architecture=x86 +$(package)_config_opts_i686_android=address-model=32 +$(package)_config_opts_aarch64_android=address-model=64 +$(package)_config_opts_x86_64_android=address-model=64 +$(package)_config_opts_armv7a_android=address-model=32 $(package)_toolset_$(host_os)=gcc +$(package)_toolset_darwin=clang +ifneq (,$(findstring clang,$($(package)_cxx))) + $(package)_toolset_$(host_os)=clang +endif $(package)_archiver_$(host_os)=$($(package)_ar) -$(package)_toolset_darwin=darwin -$(package)_archiver_darwin=$($(package)_libtool) -$(package)_config_libraries=chrono,filesystem,system,thread,test +$(package)_config_libraries=filesystem,system,thread,test $(package)_cxxflags=-std=c++11 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC +$(package)_cxxflags_android=-fPIC endef define $(package)_preprocess_cmds @@ -29,13 +36,13 @@ define $(package)_preprocess_cmds endef define $(package)_config_cmds - ./bootstrap.sh --without-icu --with-libraries=$(boost_config_libraries) + ./bootstrap.sh --without-icu --with-libraries=$($(package)_config_libraries) --with-toolset=$($(package)_toolset_$(host_os)) endef define $(package)_build_cmds - ./b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) stage + ./b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) stage endef define $(package)_stage_cmds - ./b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) install + ./b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) install endef diff --git a/depends/packages/capnp.mk b/depends/packages/capnp.mk new file mode 100644 index 000000000..abeb26545 --- /dev/null +++ b/depends/packages/capnp.mk @@ -0,0 +1,18 @@ +package=capnp +$(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) + +define $(package)_config_cmds + $($(package)_autoconf) --with-external-capnp +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/dbus.mk b/depends/packages/dbus.mk deleted file mode 100644 index bbe037540..000000000 --- a/depends/packages/dbus.mk +++ /dev/null @@ -1,23 +0,0 @@ -package=dbus -$(package)_version=1.10.18 -$(package)_download_path=https://dbus.freedesktop.org/releases/dbus -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=6049ddd5f3f3e2618f615f1faeda0a115104423a7996b7aa73e2f36e38cc514a -$(package)_dependencies=expat - -define $(package)_set_vars - $(package)_config_opts=--disable-tests --disable-doxygen-docs --disable-xml-docs --disable-static --without-x -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C dbus libdbus-1.la -endef - -define $(package)_stage_cmds - $(MAKE) -C dbus DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-dbusincludeHEADERS install-nodist_dbusarchincludeHEADERS && \ - $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA -endef diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index acbc60eea..902fe43be 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,11 +1,13 @@ package=expat -$(package)_version=2.2.5 -$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_5/ +$(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=d9dc32efba7e74f788fcc4f212a43216fc37cf5f23f4c2339664d473353aedf6 +$(package)_sha256_hash=cbc9102f4a31a8dafd42d642e9a3aa31e79a0aedaa1f6efd2795ebc83174ec18 define $(package)_set_vars -$(package)_config_opts=--disable-static + $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking + $(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds @@ -19,3 +21,7 @@ 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 index 12695db4b..0d5f94f38 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -1,28 +1,33 @@ package=fontconfig $(package)_version=2.12.1 -$(package)_download_path=http://www.freedesktop.org/software/fontconfig/release/ +$(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 +$(package)_patches=remove_char_width_usage.patch gperf_header_regen.patch define $(package)_set_vars - $(package)_config_opts=--disable-docs --disable-static + $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking +endef + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/remove_char_width_usage.patch && \ + patch -p1 < $($(package)_patch_dir)/gperf_header_regen.patch 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 index 76b025c46..a1584608e 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -1,11 +1,12 @@ package=freetype $(package)_version=2.7.1 -$(package)_download_path=http://download.savannah.gnu.org/releases/$(package) +$(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 --disable-static + $(package)_config_opts=--without-zlib --without-png --without-harfbuzz --without-bzip2 --disable-static + $(package)_config_opts += --enable-option-checking $(package)_config_opts_linux=--with-pic endef @@ -20,3 +21,7 @@ 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/libX11.mk b/depends/packages/libX11.mk deleted file mode 100644 index 298616bea..000000000 --- a/depends/packages/libX11.mk +++ /dev/null @@ -1,27 +0,0 @@ -package=libX11 -$(package)_version=1.6.2 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=2aa027e837231d2eeea90f3a4afe19948a6eb4c8b2bec0241eba7dbc8106bd16 -$(package)_dependencies=libxcb xtrans xextproto xproto - -define $(package)_set_vars -$(package)_config_opts=--disable-xkb --disable-static -$(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 diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index 304494e3c..4c55c2df0 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -1,12 +1,15 @@ package=libXau $(package)_version=1.0.8 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ +$(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 + $(package)_config_opts=--disable-shared --disable-lint-library --without-lint + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic endef @@ -25,3 +28,7 @@ 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/libXext.mk b/depends/packages/libXext.mk deleted file mode 100644 index c0565dd67..000000000 --- a/depends/packages/libXext.mk +++ /dev/null @@ -1,26 +0,0 @@ -package=libXext -$(package)_version=1.3.2 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=f829075bc646cdc085fa25d98d5885d83b1759ceb355933127c257e8e50432e0 -$(package)_dependencies=xproto xextproto libX11 libXau - -define $(package)_set_vars - $(package)_config_opts=--disable-static -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/libevent.mk b/depends/packages/libevent.mk index 5f622f8e6..1cd5a1749 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -1,17 +1,25 @@ package=libevent -$(package)_version=2.1.8-stable +$(package)_version=2.1.11-stable $(package)_download_path=https://github.com/libevent/libevent/archive/ $(package)_file_name=release-$($(package)_version).tar.gz -$(package)_sha256_hash=316ddb401745ac5d222d7c529ef1eada12f58f6376a66c1118eee803cb70f83d +$(package)_sha256_hash=229393ab2bf0dc94694f21836846b424f3532585bac3468738b7bf752c03901e +$(package)_patches=0001-fix-windows-getaddrinfo.patch define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/0001-fix-windows-getaddrinfo.patch && \ ./autogen.sh endef +# When building for Windows, we set _WIN32_WINNT to target the same Windows +# version as we do in configure. Due to quirks in libevents build system, this +# is also required to enable support for ipv6. See #19375. define $(package)_set_vars $(package)_config_opts=--disable-shared --disable-openssl --disable-libevent-regress --disable-samples + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_release=--disable-debug-mode $(package)_config_opts_linux=--with-pic + $(package)_config_opts_android=--with-pic + $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 endef define $(package)_config_cmds @@ -27,4 +35,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds + rm lib/*.la endef diff --git a/depends/packages/libmultiprocess.mk b/depends/packages/libmultiprocess.mk new file mode 100644 index 000000000..3e5cf5f16 --- /dev/null +++ b/depends/packages/libmultiprocess.mk @@ -0,0 +1,18 @@ +package=libmultiprocess +$(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) boost capnp + +define $(package)_config_cmds + $($(package)_cmake) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 3f346d972..2204b3819 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -1,12 +1,25 @@ package=libxcb $(package)_version=1.10 -$(package)_download_path=http://xcb.freedesktop.org/dist +$(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 xproto +$(package)_dependencies=xcb_proto libXau define $(package)_set_vars -$(package)_config_opts=--disable-static +$(package)_config_opts=--disable-static --disable-build-docs --without-doxygen --without-launchd +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking +# 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 @@ -32,5 +45,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf share/man share/doc + rm -rf share/man share/doc lib/*.la endef diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index 5ad2b580d..49a584e46 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,8 +1,9 @@ package=miniupnpc $(package)_version=2.0.20180203 -$(package)_download_path=http://miniupnp.free.fr/files +$(package)_download_path=https://miniupnp.tuxfamily.org/files/ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=90dda8c7563ca6cd4a83e23b3c66dbbea89603a1675bfdb852897c2c9cc220b7 +$(package)_patches=dont_use_wingen.patch define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" @@ -14,7 +15,7 @@ endef define $(package)_preprocess_cmds mkdir dll && \ sed -e 's|MINIUPNPC_VERSION_STRING \"version\"|MINIUPNPC_VERSION_STRING \"$($(package)_version)\"|' -e 's|OS/version|$(host)|' miniupnpcstrings.h.in > miniupnpcstrings.h && \ - sed -i.old "s|miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings|miniupnpcstrings.h: miniupnpcstrings.h.in|" Makefile.mingw + patch -p1 < $($(package)_patch_dir)/dont_use_wingen.patch endef define $(package)_build_cmds diff --git a/depends/packages/native_biplist.mk b/depends/packages/native_biplist.mk index 5f247e9bf..c3054cbd1 100644 --- a/depends/packages/native_biplist.mk +++ b/depends/packages/native_biplist.mk @@ -3,13 +3,13 @@ $(package)_version=1.0.3 $(package)_download_path=https://bitbucket.org/wooster/biplist/downloads $(package)_file_name=biplist-$($(package)_version).tar.gz $(package)_sha256_hash=4c0549764c5fe50b28042ec21aa2e14fe1a2224e239a1dae77d9e7f3932aa4c6 -$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_install_libdir=$(build_prefix)/lib/python3/dist-packages define $(package)_build_cmds - python setup.py build + python3 setup.py build endef define $(package)_stage_cmds mkdir -p $($(package)_install_libdir) && \ - python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) + python3 setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) endef diff --git a/depends/packages/native_capnp.mk b/depends/packages/native_capnp.mk new file mode 100644 index 000000000..ed5a6deee --- /dev/null +++ b/depends/packages/native_capnp.mk @@ -0,0 +1,18 @@ +package=native_capnp +$(package)_version=0.7.0 +$(package)_download_path=https://capnproto.org/ +$(package)_download_file=capnproto-c++-$($(package)_version).tar.gz +$(package)_file_name=capnproto-cxx-$($(package)_version).tar.gz +$(package)_sha256_hash=c9a4c0bd88123064d483ab46ecee777f14d933359e23bff6fb4f4dbd28b4cd41 + +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/native_cctools.mk b/depends/packages/native_cctools.mk index 44d238cc4..d56b63669 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,45 +1,86 @@ package=native_cctools -$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6 -$(package)_download_path=https://github.com/theuni/cctools-port/archive +$(package)_version=55562e4073dea0fbfd0b20e0bf69ffe6390c7f97 +$(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a +$(package)_sha256_hash=e51995a843533a3dac155dd0c71362dd471597a2d23f13dff194c6285362f875 $(package)_build_subdir=cctools -$(package)_clang_version=3.7.1 -$(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version) +$(package)_patches=ld64_disable_threading.patch + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +$(package)_clang_version=8.0.0 +$(package)_clang_download_path=https://releases.llvm.org/$($(package)_clang_version) $(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz $(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz -$(package)_clang_sha256_hash=99b28a6b48e793705228a390471991386daa33a9717cd9ca007fcdde69608fd9 -$(package)_extra_sources=$($(package)_clang_file_name) +$(package)_clang_sha256_hash=9ef854b71949f825362a119bf2597f744836cb571131ae6b721cd102ffea8cd0 +endif + +$(package)_libtapi_version=3efb201881e7a76a21e0554906cf306432539cef +$(package)_libtapi_download_path=https://github.com/tpoechtrager/apple-libtapi/archive +$(package)_libtapi_download_file=$($(package)_libtapi_version).tar.gz +$(package)_libtapi_file_name=$($(package)_libtapi_version).tar.gz +$(package)_libtapi_sha256_hash=380c1ca37cfa04a8699d0887a8d3ee1ad27f3d08baba78887c73b09485c0fbd3 +$(package)_extra_sources=$($(package)_libtapi_file_name) +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +$(package)_extra_sources += $($(package)_clang_file_name) +endif + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) 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)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) +$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \ +$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) endef +else +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)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) +endef +endif +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) define $(package)_extract_cmds mkdir -p $($(package)_extract_dir) && \ echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ echo "$($(package)_clang_sha256_hash) $($(package)_source_dir)/$($(package)_clang_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \ - tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ + mkdir -p toolchain/bin toolchain/lib/clang/$($(package)_clang_version)/include && \ + mkdir -p libtapi && \ + tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ + tar --no-same-owner --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ rm -f toolchain/lib/libc++abi.so* && \ - echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \ - echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \ - chmod +x toolchain/bin/$(host)-dsymutil && \ - tar --strip-components=1 -xf $($(package)_source) + tar --no-same-owner --strip-components=1 -xf $($(package)_source) +endef +else +define $(package)_extract_cmds + mkdir -p $($(package)_extract_dir) && \ + echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + mkdir -p libtapi && \ + tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ + tar --no-same-owner --strip-components=1 -xf $($(package)_source) endef +endif define $(package)_set_vars -$(package)_config_opts=--target=$(host) --disable-lto-support -$(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib -$(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang -$(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ + $(package)_config_opts=--target=$(host) --with-libtapi=$($(package)_extract_dir) + $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib + ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) + $(package)_config_opts+=--enable-lto-support --with-llvm-config=$($(package)_extract_dir)/toolchain/bin/llvm-config + $(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang + $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ + else + $(package)_cc=clang + $(package)_cxx=clang++ + endif endef define $(package)_preprocess_cmds - cd $($(package)_build_subdir); ./autogen.sh && \ - sed -i.old "/define HAVE_PTHREADS/d" ld64/src/ld/InputFiles.h + CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/build.sh && \ + CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/install.sh && \ + patch -p1 < $($(package)_patch_dir)/ld64_disable_threading.patch endef define $(package)_config_cmds @@ -50,8 +91,12 @@ define $(package)_build_cmds $(MAKE) endef +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ + mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ + cd $($(package)_extract_dir) && \ + cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ && \ cd $($(package)_extract_dir)/toolchain && \ mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \ mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \ @@ -59,7 +104,13 @@ define $(package)_stage_cmds cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \ - cp bin/llvm-dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ - if `test -d include/c++/`; then cp -rf include/c++/ $($(package)_staging_prefix_dir)/include/; fi && \ - if `test -d lib/c++/`; then cp -rf lib/c++/ $($(package)_staging_prefix_dir)/lib/; fi + cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil +endef +else +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ + mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ + cd $($(package)_extract_dir) && \ + cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ endef +endif diff --git a/depends/packages/native_cdrkit.mk b/depends/packages/native_cdrkit.mk index cf694edb3..7bdf2d7df 100644 --- a/depends/packages/native_cdrkit.mk +++ b/depends/packages/native_cdrkit.mk @@ -1,6 +1,6 @@ package=native_cdrkit $(package)_version=1.1.11 -$(package)_download_path=http://distro.ibiblio.org/fatdog/source/600/c +$(package)_download_path=https://distro.ibiblio.org/fatdog/source/600/c $(package)_file_name=cdrkit-$($(package)_version).tar.bz2 $(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564 $(package)_patches=cdrkit-deterministic.patch @@ -9,8 +9,10 @@ define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/cdrkit-deterministic.patch endef +# Starting with 10.1, GCC defaults to -fno-common, resulting in linking errors. +# Pass -fcommon to retain the legacy behaviour. define $(package)_config_cmds - cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix) + $($(package)_cmake) -DCMAKE_C_FLAGS="$$($(1)_cflags) -fcommon" endef define $(package)_build_cmds diff --git a/depends/packages/native_ds_store.mk b/depends/packages/native_ds_store.mk index 116fa25d3..f99b689ec 100644 --- a/depends/packages/native_ds_store.mk +++ b/depends/packages/native_ds_store.mk @@ -3,14 +3,14 @@ $(package)_version=1.1.2 $(package)_download_path=https://github.com/al45tair/ds_store/archive/ $(package)_file_name=v$($(package)_version).tar.gz $(package)_sha256_hash=3b3ecb7bf0a5157f5b6010bc3af7c141fb0ad3527084e63336220d22744bc20c -$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_install_libdir=$(build_prefix)/lib/python3/dist-packages $(package)_dependencies=native_biplist define $(package)_build_cmds - python setup.py build + python3 setup.py build endef define $(package)_stage_cmds mkdir -p $($(package)_install_libdir) && \ - python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) + python3 setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) endef diff --git a/depends/packages/native_libdmg-hfsplus.mk b/depends/packages/native_libdmg-hfsplus.mk index a4ffb6046..035b76718 100644 --- a/depends/packages/native_libdmg-hfsplus.mk +++ b/depends/packages/native_libdmg-hfsplus.mk @@ -1,16 +1,18 @@ package=native_libdmg-hfsplus -$(package)_version=0.1 -$(package)_download_path=https://github.com/theuni/libdmg-hfsplus/archive -$(package)_file_name=libdmg-hfsplus-v$($(package)_version).tar.gz -$(package)_sha256_hash=6569a02eb31c2827080d7d59001869ea14484c281efab0ae7f2b86af5c3120b3 +$(package)_version=7ac55ec64c96f7800d9818ce64c79670e7f02b67 +$(package)_download_path=https://github.com/planetbeing/libdmg-hfsplus/archive +$(package)_file_name=$($(package)_version).tar.gz +$(package)_sha256_hash=56fbdc48ec110966342f0ecddd6f8f89202f4143ed2a3336e42bbf88f940850c $(package)_build_subdir=build +$(package)_patches=remove-libcrypto-dependency.patch define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/remove-libcrypto-dependency.patch && \ mkdir build endef define $(package)_config_cmds - cmake -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix)/bin .. + $($(package)_cmake) -DCMAKE_C_FLAGS="$$($(1)_cflags) -Wl,--build-id=none" .. endef define $(package)_build_cmds diff --git a/depends/packages/native_libmultiprocess.mk b/depends/packages/native_libmultiprocess.mk new file mode 100644 index 000000000..c50fdc3f6 --- /dev/null +++ b/depends/packages/native_libmultiprocess.mk @@ -0,0 +1,18 @@ +package=native_libmultiprocess +$(package)_version=5741d750a04e644a03336090d8979c6d033e32c0 +$(package)_download_path=https://github.com/chaincodelabs/libmultiprocess/archive +$(package)_file_name=$($(package)_version).tar.gz +$(package)_sha256_hash=ac848db49a6ed53e423c62d54bd87f1f08cbb0326254a8667e10bbfe5bf032a4 +$(package)_dependencies=native_capnp + +define $(package)_config_cmds + $($(package)_cmake) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/native_mac_alias.mk b/depends/packages/native_mac_alias.mk index 306c83565..e60b99dcc 100644 --- a/depends/packages/native_mac_alias.mk +++ b/depends/packages/native_mac_alias.mk @@ -3,13 +3,13 @@ $(package)_version=2.0.7 $(package)_download_path=https://github.com/al45tair/mac_alias/archive/ $(package)_file_name=v$($(package)_version).tar.gz $(package)_sha256_hash=6f606d3b6bccd2112aeabf1a063f5b5ece87005a5d7e97c8faca23b916e88838 -$(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_install_libdir=$(build_prefix)/lib/python3/dist-packages define $(package)_build_cmds - python setup.py build + python3 setup.py build endef define $(package)_stage_cmds mkdir -p $($(package)_install_libdir) && \ - python setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) + python3 setup.py install --root=$($(package)_staging_dir) --prefix=$(build_prefix) --install-lib=$($(package)_install_libdir) endef diff --git a/depends/packages/native_protobuf.mk b/depends/packages/native_protobuf.mk deleted file mode 100644 index ce50b366f..000000000 --- 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 -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 3737847f2..626b34dff 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,20 +1,25 @@ -packages:=boost openssl libevent zeromq +packages:=boost openssl libevent -qt_native_packages = native_protobuf -qt_packages = qrencode protobuf zlib +qt_packages = zlib -qt_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans +qrencode_packages = qrencode -rapidcheck_packages = rapidcheck +qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig +qt_android_packages=qt qt_darwin_packages=qt qt_mingw32_packages=qt -wallet_packages=bdb +bdb_packages=bdb sqlite_packages=sqlite +zmq_packages=zeromq + upnp_packages=miniupnpc +multiprocess_packages = libmultiprocess capnp +multiprocess_native_packages = native_libmultiprocess native_capnp + darwin_native_packages = native_biplist native_ds_store native_mac_alias ifneq ($(build_os),darwin) diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk deleted file mode 100644 index d201d1183..000000000 --- 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 -endef diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index 313e4adf2..d1687883b 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -5,8 +5,11 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19cde1fa5 define $(package)_set_vars -$(package)_config_opts=--disable-shared -without-tools --disable-sdltest +$(package)_config_opts=--disable-shared --without-tools --without-tests --disable-sdltest +$(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic +$(package)_config_opts_android=--with-pic endef define $(package)_preprocess_cmds @@ -24,3 +27,7 @@ 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 index d0cf38e30..cf4bed7dd 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,20 +1,25 @@ PACKAGE=qt -$(package)_version=5.9.6 -$(package)_download_path=http://mirrors.sohu.com/qt-all/archive/qt/5.9/$($(package)_version)/submodules +$(package)_version=5.9.8 +$(package)_download_path=https://download.qt.io/archive/qt/5.9/$($(package)_version)/submodules $(package)_suffix=opensource-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=eed620cb268b199bd83b3fc6a471c51d51e1dc2dbb5374fc97a0cc75facbe36f -$(package)_dependencies=openssl zlib -$(package)_linux_dependencies=freetype fontconfig libxcb libX11 xproto libXext +$(package)_sha256_hash=9b9dec1f67df1f94bce2955c5604de992d529dde72050239154c56352da0907d +$(package)_dependencies=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 +$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch +$(package)_patches+= fix_rcc_determinism.patch fix_riscv64_arch.patch xkb-default.patch no-xlib.patch +$(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch +$(package)_patches+= freetype_back_compat.patch drop_lrelease_dependency.patch fix_powerpc_libpng.patch +$(package)_patches+= fix_qpainter_non_determinism.patch +# Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=9822084f8e2d2939ba39f4af4c0c2320e45d5996762a9423f833055607604ed8 +$(package)_qttranslations_sha256_hash=fb5a47799754af73d3bf501fe513342cfe2fc37f64e80df5533f6110e804220c $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=50e75417ec0c74bb8b1989d1d8e981ee83690dce7dfc0c2169f7c00f397e5117 +$(package)_qttools_sha256_hash=a97556eb7b2f30252cdd8a598c396cfce2b2f79d2bae883af6d3b26a2cdcc63c $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) @@ -25,8 +30,8 @@ $(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 @@ -34,14 +39,20 @@ $(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-libproxy $(package)_config_opts += -no-libudev $(package)_config_opts += -no-mtdev +$(package)_config_opts += -no-openssl $(package)_config_opts += -no-openvg $(package)_config_opts += -no-reduce-relocations $(package)_config_opts += -no-qml-debug +$(package)_config_opts += -no-sctp +$(package)_config_opts += -no-securetransport $(package)_config_opts += -no-sql-db2 $(package)_config_opts += -no-sql-ibase $(package)_config_opts += -no-sql-oci @@ -51,50 +62,113 @@ $(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-system-proxies $(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 += -optimized-tools $(package)_config_opts += -pch $(package)_config_opts += -pkg-config $(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -qt-libpng -$(package)_config_opts += -qt-libjpeg $(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-printer -$(package)_config_opts += -no-feature-printdialog +$(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-fontcombobox +$(package)_config_opts += -no-feature-ftp +$(package)_config_opts += -no-feature-http +$(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-networkdiskcache +$(package)_config_opts += -no-feature-networkproxy +$(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-socks5 +$(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 +$(package)_config_opts_darwin = -no-dbus +$(package)_config_opts_darwin += -no-opengl + ifneq ($(build_os),darwin) -$(package)_config_opts_darwin = -xplatform macx-clang-linux +$(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 += -no-feature-sessionmanager $(package)_config_opts_linux += -fontconfig $(package)_config_opts_linux += -no-opengl +$(package)_config_opts_linux += -dbus-runtime $(package)_config_opts_arm_linux += -platform linux-g++ -xplatform pocketcoin-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_powerpc64_linux = -platform linux-g++ -xplatform pocketcoin-linux-g++ +$(package)_config_opts_powerpc64le_linux = -platform linux-g++ -xplatform pocketcoin-linux-g++ $(package)_config_opts_riscv64_linux = -platform linux-g++ -xplatform pocketcoin-linux-g++ -$(package)_config_opts_mingw32 = -no-opengl -xplatform win32-g++ -device-option CROSS_COMPILE="$(host)-" +$(package)_config_opts_s390x_linux = -platform linux-g++ -xplatform pocketcoin-linux-g++ + +$(package)_config_opts_mingw32 = -no-opengl +$(package)_config_opts_mingw32 += -no-dbus +$(package)_config_opts_mingw32 += -xplatform win32-g++ +$(package)_config_opts_mingw32 += -device-option CROSS_COMPILE="$(host)-" + +$(package)_config_opts_android = -xplatform android-clang +$(package)_config_opts_android += -android-sdk $(ANDROID_SDK) +$(package)_config_opts_android += -android-ndk $(ANDROID_NDK) +$(package)_config_opts_android += -android-ndk-platform android-$(ANDROID_API_LEVEL) +$(package)_config_opts_android += -device-option CROSS_COMPILE="$(host)-" +$(package)_config_opts_android += -egl +$(package)_config_opts_android += -qpa xcb +$(package)_config_opts_android += -no-eglfs +$(package)_config_opts_android += -no-dbus +$(package)_config_opts_android += -opengl es2 +$(package)_config_opts_android += -qt-freetype +$(package)_config_opts_android += -no-fontconfig +$(package)_config_opts_android += -L $(host_prefix)/lib +$(package)_config_opts_android += -I $(host_prefix)/include + +$(package)_config_opts_aarch64_android += -android-arch arm64-v8a +$(package)_config_opts_armv7a_android += -android-arch armeabi-v7a +$(package)_config_opts_x86_64_android += -android-arch x86_64 +$(package)_config_opts_i686_android += -android-arch i686 + $(package)_build_env = QT_RCC_TEST=1 $(package)_build_env += QT_RCC_SOURCE_DATE_OVERRIDE=1 endef @@ -112,20 +186,20 @@ define $(package)_extract_cmds 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 --strip-components=1 -xf $($(package)_source) -C qtbase && \ + tar --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ mkdir qttranslations && \ - tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ + tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ mkdir qttools && \ - tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools + tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools endef define $(package)_preprocess_cmds + patch -p1 -i $($(package)_patch_dir)/freetype_back_compat.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_powerpc_libpng.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch &&\ 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 's/if \[ "$$$$XPLATFORM_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/if \[ "$$$$BUILD_ON_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/' qtbase/configure && \ - sed -i.old 's/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0)/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, kCGMouseButtonLeft)/' qtbase/src/plugins/platforms/cocoa/qcocoacursor.mm && \ + patch -p1 -i $($(package)_patch_dir)/drop_lrelease_dependency.patch && \ + patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch &&\ 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/ &&\ @@ -138,15 +212,21 @@ define $(package)_preprocess_cmds 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 &&\ + patch -p1 -i $($(package)_patch_dir)/fix_android_qmake_conf.patch &&\ + patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.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|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" 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 "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \ + sed -i.old "s|QMAKE_CC = clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ + sed -i.old "s|QMAKE_CXX = clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \ + sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf endef define $(package)_config_cmds diff --git a/depends/packages/rapidcheck.mk b/depends/packages/rapidcheck.mk deleted file mode 100644 index 19cf1cae2..000000000 --- a/depends/packages/rapidcheck.mk +++ /dev/null @@ -1,18 +0,0 @@ -package=rapidcheck -$(package)_version=10fc0cb -$(package)_download_path=https://github.com/MarcoFalke/rapidcheck/archive -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=9640926223c00af45bce4c7df8b756b5458a89b2ba74cfe3e404467f13ce26df - -define $(package)_config_cmds - cmake -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true . -endef - -define $(package)_build_cmds - $(MAKE) && \ - mkdir -p $($(package)_staging_dir)$(host_prefix)/include && \ - cp -a include/* $($(package)_staging_dir)$(host_prefix)/include/ && \ - cp -a extras/boost_test/include/rapidcheck/* $($(package)_staging_dir)$(host_prefix)/include/rapidcheck/ && \ - mkdir -p $($(package)_staging_dir)$(host_prefix)/lib && \ - cp -a librapidcheck.a $($(package)_staging_dir)$(host_prefix)/lib/ -endef diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk index 0c7c958d6..01203a071 100644 --- a/depends/packages/xcb_proto.mk +++ b/depends/packages/xcb_proto.mk @@ -1,14 +1,9 @@ package=xcb_proto $(package)_version=1.10 -$(package)_download_path=http://xcb.freedesktop.org/dist +$(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 diff --git a/depends/packages/xextproto.mk b/depends/packages/xextproto.mk deleted file mode 100644 index 7065237bd..000000000 --- a/depends/packages/xextproto.mk +++ /dev/null @@ -1,25 +0,0 @@ -package=xextproto -$(package)_version=7.3.0 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/proto -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=f3f4b23ac8db9c3a9e0d8edb591713f3d70ef9c3b175970dd8823dfc92aa5bb0 - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . -endef - -define $(package)_set_vars -$(package)_config_opts=--disable-shared -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/xproto.mk b/depends/packages/xproto.mk index 5328ec848..6bd867d02 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -1,11 +1,12 @@ package=xproto $(package)_version=7.0.26 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/proto +$(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=--disable-shared +$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking endef define $(package)_preprocess_cmds diff --git a/depends/packages/xtrans.mk b/depends/packages/xtrans.mk deleted file mode 100644 index c313b1f60..000000000 --- a/depends/packages/xtrans.mk +++ /dev/null @@ -1,26 +0,0 @@ -package=xtrans -$(package)_version=1.3.4 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=054d4ee3efd52508c753e9f7bc655ef185a29bd2850dd9e2fc2ccc33544f583a -$(package)_dependencies= - -define $(package)_set_vars -$(package)_config_opts_linux=--with-pic --disable-static -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/zeromq.mk b/depends/packages/zeromq.mk index c9068e83a..c93aa1a74 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,20 +1,23 @@ package=zeromq -$(package)_version=4.2.5 +$(package)_version=4.3.1 $(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=cc9090ba35713d59bb2f7d7965f877036c49c5558ea0c290b0dcc6f2a17e489f -$(package)_patches=0001-fix-build-with-older-mingw64.patch 0002-disable-pthread_set_name_np.patch +$(package)_sha256_hash=bcbabe1e2c7d0eec4ed612e10b94b112dd5f06fcefa994a0c79a45d835cd21eb +$(package)_patches=remove_libstd_link.patch define $(package)_set_vars - $(package)_config_opts=--without-docs --disable-shared --without-libsodium --disable-curve --disable-curve-keygen --disable-perf --disable-Werror + $(package)_config_opts=--without-docs --disable-shared --disable-curve --disable-curve-keygen --disable-perf + $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci + $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov --disable-dependency-tracking + $(package)_config_opts += --disable-Werror --disable-drafts --enable-option-checking $(package)_config_opts_linux=--with-pic + $(package)_config_opts_android=--with-pic $(package)_cxxflags=-std=c++11 endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/0001-fix-build-with-older-mingw64.patch && \ - patch -p1 < $($(package)_patch_dir)/0002-disable-pthread_set_name_np.patch && \ - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub config + patch -p1 < $($(package)_patch_dir)/remove_libstd_link.patch && \ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub config endef define $(package)_config_cmds @@ -30,6 +33,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - sed -i.old "s/ -lstdc++//" lib/pkgconfig/libzmq.pc && \ - rm -rf bin share + rm -rf bin share lib/*.la endef diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk index d444ba5de..66cb8aa7a 100644 --- a/depends/packages/zlib.mk +++ b/depends/packages/zlib.mk @@ -1,27 +1,31 @@ package=zlib $(package)_version=1.2.12 -$(package)_download_path=http://www.zlib.net +$(package)_download_path=https://www.zlib.net $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9 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" +$(package)_config_opts= CC="$($(package)_cc)" +$(package)_config_opts+=CFLAGS="$($(package)_cflags) $($(package)_cppflags) -fPIC" +$(package)_config_opts+=RANLIB="$($(package)_ranlib)" +$(package)_config_opts+=AR="$($(package)_ar)" +$(package)_config_opts_darwin+=AR="$($(package)_libtool)" +$(package)_config_opts_darwin+=ARFLAGS="-o" +$(package)_config_opts_android+=CHOST=$(host) endef +# zlib has its own custom configure script that takes in options like CC, +# CFLAGS, RANLIB, AR, and ARFLAGS from the environment rather than from +# command-line arguments. define $(package)_config_cmds - ./configure --static --prefix=$(host_prefix) + env $($(package)_config_opts) ./configure --static --prefix=$(host_prefix) endef define $(package)_build_cmds - $(MAKE) $($(package)_build_opts) libz.a + $(MAKE) libz.a endef define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install $($(package)_build_opts) + $(MAKE) DESTDIR=$($(package)_staging_dir) install endef diff --git a/depends/patches/bdb/clang_cxx_11.patch b/depends/patches/bdb/clang_cxx_11.patch new file mode 100644 index 000000000..58f7ddc7d --- /dev/null +++ b/depends/patches/bdb/clang_cxx_11.patch @@ -0,0 +1,147 @@ +commit 3311d68f11d1697565401eee6efc85c34f022ea7 +Author: fanquake +Date: Mon Aug 17 20:03:56 2020 +0800 + + Fix C++11 compatibility + +diff --git a/dbinc/atomic.h b/dbinc/atomic.h +index 0034dcc..7c11d4a 100644 +--- a/dbinc/atomic.h ++++ b/dbinc/atomic.h +@@ -70,7 +70,7 @@ typedef struct { + * These have no memory barriers; the caller must include them when necessary. + */ + #define atomic_read(p) ((p)->value) +-#define atomic_init(p, val) ((p)->value = (val)) ++#define atomic_init_db(p, val) ((p)->value = (val)) + + #ifdef HAVE_ATOMIC_SUPPORT + +@@ -144,7 +144,7 @@ typedef LONG volatile *interlocked_val; + #define atomic_inc(env, p) __atomic_inc(p) + #define atomic_dec(env, p) __atomic_dec(p) + #define atomic_compare_exchange(env, p, o, n) \ +- __atomic_compare_exchange((p), (o), (n)) ++ __atomic_compare_exchange_db((p), (o), (n)) + static inline int __atomic_inc(db_atomic_t *p) + { + int temp; +@@ -176,7 +176,7 @@ static inline int __atomic_dec(db_atomic_t *p) + * http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html + * which configure could be changed to use. + */ +-static inline int __atomic_compare_exchange( ++static inline int __atomic_compare_exchange_db( + db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval) + { + atomic_value_t was; +@@ -206,7 +206,7 @@ static inline int __atomic_compare_exchange( + #define atomic_dec(env, p) (--(p)->value) + #define atomic_compare_exchange(env, p, oldval, newval) \ + (DB_ASSERT(env, atomic_read(p) == (oldval)), \ +- atomic_init(p, (newval)), 1) ++ atomic_init_db(p, (newval)), 1) + #else + #define atomic_inc(env, p) __atomic_inc(env, p) + #define atomic_dec(env, p) __atomic_dec(env, p) +diff --git a/mp/mp_fget.c b/mp/mp_fget.c +index 5fdee5a..0b75f57 100644 +--- a/mp/mp_fget.c ++++ b/mp/mp_fget.c +@@ -617,7 +617,7 @@ alloc: /* Allocate a new buffer header and data space. */ + + /* Initialize enough so we can call __memp_bhfree. */ + alloc_bhp->flags = 0; +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + #ifdef DIAGNOSTIC + if ((uintptr_t)alloc_bhp->buf & (sizeof(size_t) - 1)) { + __db_errx(env, +@@ -911,7 +911,7 @@ alloc: /* Allocate a new buffer header and data space. */ + MVCC_MPROTECT(bhp->buf, mfp->stat.st_pagesize, + PROT_READ); + +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + MUTEX_LOCK(env, alloc_bhp->mtx_buf); + alloc_bhp->priority = bhp->priority; + alloc_bhp->pgno = bhp->pgno; +diff --git a/mp/mp_mvcc.c b/mp/mp_mvcc.c +index 34467d2..f05aa0c 100644 +--- a/mp/mp_mvcc.c ++++ b/mp/mp_mvcc.c +@@ -276,7 +276,7 @@ __memp_bh_freeze(dbmp, infop, hp, bhp, need_frozenp) + #else + memcpy(frozen_bhp, bhp, SSZA(BH, buf)); + #endif +- atomic_init(&frozen_bhp->ref, 0); ++ atomic_init_db(&frozen_bhp->ref, 0); + if (mutex != MUTEX_INVALID) + frozen_bhp->mtx_buf = mutex; + else if ((ret = __mutex_alloc(env, MTX_MPOOL_BH, +@@ -428,7 +428,7 @@ __memp_bh_thaw(dbmp, infop, hp, frozen_bhp, alloc_bhp) + #endif + alloc_bhp->mtx_buf = mutex; + MUTEX_LOCK(env, alloc_bhp->mtx_buf); +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + F_CLR(alloc_bhp, BH_FROZEN); + } + +diff --git a/mp/mp_region.c b/mp/mp_region.c +index e6cece9..ddbe906 100644 +--- a/mp/mp_region.c ++++ b/mp/mp_region.c +@@ -224,7 +224,7 @@ __memp_init(env, dbmp, reginfo_off, htab_buckets, max_nreg) + MTX_MPOOL_FILE_BUCKET, 0, &htab[i].mtx_hash)) != 0) + return (ret); + SH_TAILQ_INIT(&htab[i].hash_bucket); +- atomic_init(&htab[i].hash_page_dirty, 0); ++ atomic_init_db(&htab[i].hash_page_dirty, 0); + } + + /* +@@ -269,7 +269,7 @@ __memp_init(env, dbmp, reginfo_off, htab_buckets, max_nreg) + hp->mtx_hash = (mtx_base == MUTEX_INVALID) ? MUTEX_INVALID : + mtx_base + i; + SH_TAILQ_INIT(&hp->hash_bucket); +- atomic_init(&hp->hash_page_dirty, 0); ++ atomic_init_db(&hp->hash_page_dirty, 0); + #ifdef HAVE_STATISTICS + hp->hash_io_wait = 0; + hp->hash_frozen = hp->hash_thawed = hp->hash_frozen_freed = 0; +diff --git a/mutex/mut_method.c b/mutex/mut_method.c +index 2588763..5c6d516 100644 +--- a/mutex/mut_method.c ++++ b/mutex/mut_method.c +@@ -426,7 +426,7 @@ atomic_compare_exchange(env, v, oldval, newval) + MUTEX_LOCK(env, mtx); + ret = atomic_read(v) == oldval; + if (ret) +- atomic_init(v, newval); ++ atomic_init_db(v, newval); + MUTEX_UNLOCK(env, mtx); + + return (ret); +diff --git a/mutex/mut_tas.c b/mutex/mut_tas.c +index f3922e0..e40fcdf 100644 +--- a/mutex/mut_tas.c ++++ b/mutex/mut_tas.c +@@ -46,7 +46,7 @@ __db_tas_mutex_init(env, mutex, flags) + + #ifdef HAVE_SHARED_LATCHES + if (F_ISSET(mutexp, DB_MUTEX_SHARED)) +- atomic_init(&mutexp->sharecount, 0); ++ atomic_init_db(&mutexp->sharecount, 0); + else + #endif + if (MUTEX_INIT(&mutexp->tas)) { +@@ -486,7 +486,7 @@ __db_tas_mutex_unlock(env, mutex) + F_CLR(mutexp, DB_MUTEX_LOCKED); + /* Flush flag update before zeroing count */ + MEMBAR_EXIT(); +- atomic_init(&mutexp->sharecount, 0); ++ atomic_init_db(&mutexp->sharecount, 0); + } else { + DB_ASSERT(env, sharecount > 0); + MEMBAR_EXIT(); diff --git a/depends/patches/fontconfig/gperf_header_regen.patch b/depends/patches/fontconfig/gperf_header_regen.patch new file mode 100644 index 000000000..7401b83d8 --- /dev/null +++ b/depends/patches/fontconfig/gperf_header_regen.patch @@ -0,0 +1,24 @@ +commit 7b6eb33ecd88768b28c67ce5d2d68a7eed5936b6 +Author: fanquake +Date: Tue Aug 25 14:34:53 2020 +0800 + + Remove rule that causes inadvertant header regeneration + + Otherwise the makefile will needlessly attempt to re-generate the + headers with gperf. This can be dropped once the upstream build is fixed. + + See #10851. + +diff --git a/src/Makefile.in b/src/Makefile.in +index f4626ad..4ae1b00 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -903,7 +903,7 @@ fcobjshash.gperf: fcobjshash.gperf.h fcobjs.h + ' - > $@.tmp && \ + mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) + +-fcobjshash.h: fcobjshash.gperf ++fcobjshash.h: + $(AM_V_GEN) $(GPERF) -m 100 $< > $@.tmp && \ + mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) + diff --git a/depends/patches/fontconfig/remove_char_width_usage.patch b/depends/patches/fontconfig/remove_char_width_usage.patch new file mode 100644 index 000000000..9f6908189 --- /dev/null +++ b/depends/patches/fontconfig/remove_char_width_usage.patch @@ -0,0 +1,62 @@ +commit 28165a9b078583dc8e9e5c344510e37582284cef +Author: fanquake +Date: Mon Aug 17 20:35:42 2020 +0800 + + Remove usage of CHAR_WIDTH + + CHAR_WIDTH which is reserved and clashes with glibc 2.25+ + + See #10851. + +diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h +index 5c72b22..843c532 100644 +--- a/fontconfig/fontconfig.h ++++ b/fontconfig/fontconfig.h +@@ -128,7 +128,7 @@ typedef int FcBool; + #define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION + + /* Adjust outline rasterizer */ +-#define FC_CHAR_WIDTH "charwidth" /* Int */ ++#define FC_CHARWIDTH "charwidth" /* Int */ + #define FC_CHAR_HEIGHT "charheight"/* Int */ + #define FC_MATRIX "matrix" /* FcMatrix */ + +diff --git a/src/fcobjs.h b/src/fcobjs.h +index 1fc4f65..d27864b 100644 +--- a/src/fcobjs.h ++++ b/src/fcobjs.h +@@ -51,7 +51,7 @@ FC_OBJECT (DPI, FcTypeDouble, NULL) + FC_OBJECT (RGBA, FcTypeInteger, NULL) + FC_OBJECT (SCALE, FcTypeDouble, NULL) + FC_OBJECT (MINSPACE, FcTypeBool, NULL) +-FC_OBJECT (CHAR_WIDTH, FcTypeInteger, NULL) ++FC_OBJECT (CHARWIDTH, FcTypeInteger, NULL) + FC_OBJECT (CHAR_HEIGHT, FcTypeInteger, NULL) + FC_OBJECT (MATRIX, FcTypeMatrix, NULL) + FC_OBJECT (CHARSET, FcTypeCharSet, FcCompareCharSet) +diff --git a/src/fcobjshash.gperf b/src/fcobjshash.gperf +index 80a0237..eb4ad84 100644 +--- a/src/fcobjshash.gperf ++++ b/src/fcobjshash.gperf +@@ -44,7 +44,7 @@ int id; + "rgba",FC_RGBA_OBJECT + "scale",FC_SCALE_OBJECT + "minspace",FC_MINSPACE_OBJECT +-"charwidth",FC_CHAR_WIDTH_OBJECT ++"charwidth",FC_CHARWIDTH_OBJECT + "charheight",FC_CHAR_HEIGHT_OBJECT + "matrix",FC_MATRIX_OBJECT + "charset",FC_CHARSET_OBJECT +diff --git a/src/fcobjshash.h b/src/fcobjshash.h +index 5a4d1ea..4e66bb0 100644 +--- a/src/fcobjshash.h ++++ b/src/fcobjshash.h +@@ -284,7 +284,7 @@ FcObjectTypeLookup (register const char *str, register unsigned int len) + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_CHARSET_OBJECT}, + {-1}, + #line 47 "fcobjshash.gperf" +- {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHAR_WIDTH_OBJECT}, ++ {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHARWIDTH_OBJECT}, + #line 48 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_CHAR_HEIGHT_OBJECT}, + #line 55 "fcobjshash.gperf" diff --git a/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch b/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch new file mode 100644 index 000000000..a98cd90bd --- /dev/null +++ b/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch @@ -0,0 +1,15 @@ +diff -ur libevent-2.1.8-stable.orig/configure.ac libevent-2.1.8-stable/configure.ac +--- libevent-2.1.8-stable.orig/configure.ac 2017-01-29 17:51:00.000000000 +0000 ++++ libevent-2.1.8-stable/configure.ac 2020-03-07 01:11:16.311335005 +0000 +@@ -389,6 +389,10 @@ + #ifdef HAVE_NETDB_H + #include + #endif ++#ifdef _WIN32 ++#include ++#include ++#endif + ]], + [[ + getaddrinfo; +Only in libevent-2.1.8-stable: configure.ac~ diff --git a/depends/patches/miniupnpc/dont_use_wingen.patch b/depends/patches/miniupnpc/dont_use_wingen.patch new file mode 100644 index 000000000..a1cc9b50d --- /dev/null +++ b/depends/patches/miniupnpc/dont_use_wingen.patch @@ -0,0 +1,26 @@ +commit e8077044df239bcf0d9e9980b0e1afb9f1f5c446 +Author: fanquake +Date: Tue Aug 18 20:50:19 2020 +0800 + + Don't use wingenminiupnpcstrings when generating miniupnpcstrings.h + + The wingenminiupnpcstrings tool is used on Windows to generate version + information. This information is irrelevant for us, and trying to use + wingenminiupnpcstrings would cause builds to fail, so just don't use it. + + We should be able to drop this once we are using 2.1 or later. See + upstream commit: 9663c55c61408fdcc39a82987d2243f816b22932. + +diff --git a/Makefile.mingw b/Makefile.mingw +index 574720e..fcc17bb 100644 +--- a/Makefile.mingw ++++ b/Makefile.mingw +@@ -74,7 +74,7 @@ wingenminiupnpcstrings: wingenminiupnpcstrings.o + + wingenminiupnpcstrings.o: wingenminiupnpcstrings.c + +-miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings ++miniupnpcstrings.h: miniupnpcstrings.h.in + wingenminiupnpcstrings $< $@ + + minixml.o: minixml.c minixml.h diff --git a/depends/patches/native_cctools/ld64_disable_threading.patch b/depends/patches/native_cctools/ld64_disable_threading.patch new file mode 100644 index 000000000..d6c58c102 --- /dev/null +++ b/depends/patches/native_cctools/ld64_disable_threading.patch @@ -0,0 +1,26 @@ +commit 584668415039adeed073decee7e04de28248afd3 +Author: fanquake +Date: Tue Aug 18 01:20:24 2020 +0000 + + Disable threading to fix non-determinism + + A bug in the file parser can cause dependencies to be calculated + differently based on which files have already been parsed. This is more + likely to occur on systems with more CPUs. + + Just disable threading for now. There is no noticable slowdown. + + See #9891. + +diff --git a/cctools/ld64/src/ld/InputFiles.h b/cctools/ld64/src/ld/InputFiles.h +index ef9c756..90a70b6 100644 +--- a/cctools/ld64/src/ld/InputFiles.h ++++ b/cctools/ld64/src/ld/InputFiles.h +@@ -25,7 +25,6 @@ + #ifndef __INPUT_FILES_H__ + #define __INPUT_FILES_H__ + +-#define HAVE_PTHREADS 1 + + #include + #include diff --git a/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch b/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch new file mode 100644 index 000000000..f346c8f2c --- /dev/null +++ b/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch @@ -0,0 +1,45 @@ +From 3e5fd3fb56bc9ff03beb535979e33dcf83fe1f70 Mon Sep 17 00:00:00 2001 +From: Cory Fields +Date: Thu, 8 May 2014 12:39:42 -0400 +Subject: [PATCH] dmg: remove libcrypto dependency + +--- + dmg/CMakeLists.txt | 16 ---------------- + 1 file changed, 16 deletions(-) + +diff --git a/dmg/CMakeLists.txt b/dmg/CMakeLists.txt +index eec62d6..3969f64 100644 +--- a/dmg/CMakeLists.txt ++++ b/dmg/CMakeLists.txt +@@ -1,12 +1,5 @@ +-INCLUDE(FindOpenSSL) + INCLUDE(FindZLIB) + +-FIND_LIBRARY(CRYPTO_LIBRARIES crypto +- PATHS +- /usr/lib +- /usr/local/lib +- ) +- + IF(NOT ZLIB_FOUND) + message(FATAL_ERROR "zlib is required for dmg!") + ENDIF(NOT ZLIB_FOUND) +@@ -18,15 +11,6 @@ link_directories(${PROJECT_BINARY_DIR}/common ${PROJECT_BINARY_DIR}/hfs) + + add_library(dmg adc.c base64.c checksum.c dmgfile.c dmglib.c filevault.c io.c partition.c resources.c udif.c) + +-IF(OPENSSL_FOUND) +- add_definitions(-DHAVE_CRYPT) +- include_directories(${OPENSSL_INCLUDE_DIR}) +- target_link_libraries(dmg ${CRYPTO_LIBRARIES}) +- IF(WIN32) +- TARGET_LINK_LIBRARIES(dmg gdi32) +- ENDIF(WIN32) +-ENDIF(OPENSSL_FOUND) +- + target_link_libraries(dmg common hfs z) + + add_executable(dmg-bin dmg.c) +-- +2.22.0 + diff --git a/depends/patches/qt/dont_hardcode_pwd.patch b/depends/patches/qt/dont_hardcode_pwd.patch new file mode 100644 index 000000000..a74e9cb09 --- /dev/null +++ b/depends/patches/qt/dont_hardcode_pwd.patch @@ -0,0 +1,27 @@ +commit 0e953866fc4672486e29e1ba6d83b4207e7b2f0b +Author: fanquake +Date: Tue Aug 18 15:09:06 2020 +0800 + + Don't hardcode pwd path + + Let a man use his builtins if he wants to! Also, removes the unnecessary + assumption that pwd lives under /bin/pwd. + + See #15581. + +diff --git a/qtbase/configure b/qtbase/configure +index 08b49a8d..faea5b55 100755 +--- a/qtbase/configure ++++ b/qtbase/configure +@@ -36,9 +36,9 @@ + relconf=`basename $0` + # the directory of this script is the "source tree" + relpath=`dirname $0` +-relpath=`(cd "$relpath"; /bin/pwd)` ++relpath=`(cd "$relpath"; pwd)` + # the current directory is the "build tree" or "object tree" +-outpath=`/bin/pwd` ++outpath=`pwd` + + WHICH="which" + diff --git a/depends/patches/qt/drop_lrelease_dependency.patch b/depends/patches/qt/drop_lrelease_dependency.patch new file mode 100644 index 000000000..f6b2c9fc8 --- /dev/null +++ b/depends/patches/qt/drop_lrelease_dependency.patch @@ -0,0 +1,20 @@ +commit 67b3ed7406e1d0762188dbad2c44a06824ba0778 +Author: fanquake +Date: Tue Aug 18 15:24:01 2020 +0800 + + Drop dependency on lrelease + + Qts buildsystem insists on using the installed lrelease, but gets + confused about how to find it. Since we manually control the build + order, just drop the dependency. + + See #9469 + +diff --git a/qttranslations/translations/translations.pro b/qttranslations/translations/translations.pro +index 694544c..eff339d 100644 +--- a/qttranslations/translations/translations.pro ++++ b/qttranslations/translations/translations.pro +@@ -109,3 +109,2 @@ updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} + silent:updateqm.commands = @echo lrelease ${QMAKE_FILE_IN} && $$updateqm.commands +-updateqm.depends = $$LRELEASE_EXE + updateqm.name = LRELEASE ${QMAKE_FILE_IN} diff --git a/depends/patches/qt/fix_android_jni_static.patch b/depends/patches/qt/fix_android_jni_static.patch new file mode 100644 index 000000000..2f6ff00f4 --- /dev/null +++ b/depends/patches/qt/fix_android_jni_static.patch @@ -0,0 +1,18 @@ +--- old/qtbase/src/plugins/platforms/android/androidjnimain.cpp ++++ new/qtbase/src/plugins/platforms/android/androidjnimain.cpp +@@ -890,6 +890,14 @@ + __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); + return -1; + } ++ ++ const jint ret = QT_PREPEND_NAMESPACE(QtAndroidPrivate::initJNI(vm, env)); ++ if (ret != 0) ++ { ++ __android_log_print(ANDROID_LOG_FATAL, "Qt", "initJNI failed"); ++ return ret; ++ } ++ + QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); + + m_javaVM = vm; + diff --git a/depends/patches/qt/fix_android_qmake_conf.patch b/depends/patches/qt/fix_android_qmake_conf.patch new file mode 100644 index 000000000..13bfff977 --- /dev/null +++ b/depends/patches/qt/fix_android_qmake_conf.patch @@ -0,0 +1,20 @@ +--- old/qtbase/mkspecs/android-clang/qmake.conf ++++ new/qtbase/mkspecs/android-clang/qmake.conf +@@ -30,7 +30,7 @@ + QMAKE_CFLAGS += -target mips64el-none-linux-android + + QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH +-QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a ++QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -nostdlib++ + QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \ + -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX \ + -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include \ +@@ -40,7 +40,7 @@ + ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH + + ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so +-ANDROID_CXX_STL_LIBS = -lc++ ++ANDROID_CXX_STL_LIBS = -lc++_shared + + QMAKE_ARM_CFLAGS_RELEASE = -Oz + QMAKE_ARM_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Oz diff --git a/depends/patches/qt/fix_powerpc_libpng.patch b/depends/patches/qt/fix_powerpc_libpng.patch new file mode 100644 index 000000000..d37b6c777 --- /dev/null +++ b/depends/patches/qt/fix_powerpc_libpng.patch @@ -0,0 +1,23 @@ +commit 6f9feb773a43c5abfa3455da2e324180e789285b +Author: fanquake +Date: Tue Sep 15 21:44:31 2020 +0800 + + Fix PowerPC build of libpng + + See https://bugreports.qt.io/browse/QTBUG-66388. + + Can be dropped when we are building qt 5.12.0 or later. + +diff --git a/qtbase/src/3rdparty/libpng/libpng.pro b/qtbase/src/3rdparty/libpng/libpng.pro +index 577b61d8..a2f56669 100644 +--- a/qtbase/src/3rdparty/libpng/libpng.pro ++++ b/qtbase/src/3rdparty/libpng/libpng.pro +@@ -10,7 +10,7 @@ MODULE_INCLUDEPATH = $$PWD + + load(qt_helper_lib) + +-DEFINES += PNG_ARM_NEON_OPT=0 ++DEFINES += PNG_ARM_NEON_OPT=0 PNG_POWERPC_VSX_OPT=0 + SOURCES += \ + png.c \ + pngerror.c \ diff --git a/depends/patches/qt/fix_qpainter_non_determinism.patch b/depends/patches/qt/fix_qpainter_non_determinism.patch new file mode 100644 index 000000000..3cfcc22f0 --- /dev/null +++ b/depends/patches/qt/fix_qpainter_non_determinism.patch @@ -0,0 +1,63 @@ +commit 2a8f7dc6ddfc414a66491522501c1574a1343ee1 +Author: Andrew Chow +Date: Sat Nov 21 01:11:04 2020 -0500 + + build: Fix determinism issue when building with Clang 8 + + When building Qt with LLVM/Clang 8 under -O3 (the default), we run into + a determinism issue in `qt_interset_spans`. The issue has been fixed for + LLVM/Clang 9, see + https://github.com/llvm/llvm-project/commit/db101864bdc938deb1d63fe4f7da761bd38e5cae + and https://reviews.llvm.org/D64601, however this fix was not backported + to 8.x. Once LLVM/Clang 9 is used, this patch can be dropped. + + The particular issue appears to be an optimization done by -O3 which + adds a temporary variable for `spans->y` in `qt_intersect_spans`. When + it does this, sometimes it chooses to use a 32-bit movs instruction + (movswl), and other times it chooses a 64-bit movs instruction (movswq). + By patching `qt_intersect_spans` to always make a temporary variable for + `spans->y`, we are able to sidestep this problem. + +diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp +index 92ab6e8375..f018009e0b 100644 +--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp ++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp +@@ -3971,22 +3971,23 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + const QSpan *clipEnd = clip->m_spans + clip->count; + + while (available && spans < end ) { ++ const short spans_y = spans->y; + if (clipSpans >= clipEnd) { + spans = end; + break; + } +- if (clipSpans->y > spans->y) { ++ if (clipSpans->y > spans_y) { + ++spans; + continue; + } +- if (spans->y != clipSpans->y) { +- if (spans->y < clip->count && clip->m_clipLines[spans->y].spans) +- clipSpans = clip->m_clipLines[spans->y].spans; ++ if (spans_y != clipSpans->y) { ++ if (spans_y < clip->count && clip->m_clipLines[spans_y].spans) ++ clipSpans = clip->m_clipLines[spans_y].spans; + else + ++clipSpans; + continue; + } +- Q_ASSERT(spans->y == clipSpans->y); ++ Q_ASSERT(spans_y == clipSpans->y); + + int sx1 = spans->x; + int sx2 = sx1 + spans->len; +@@ -4005,7 +4006,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + if (len) { + out->x = qMax(sx1, cx1); + out->len = qMin(sx2, cx2) - out->x; +- out->y = spans->y; ++ out->y = spans_y; + out->coverage = qt_div_255(spans->coverage * clipSpans->coverage); + ++out; + --available; + diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch index 34302a9f2..8c722ffb4 100644 --- a/depends/patches/qt/fix_qt_pkgconfig.patch +++ b/depends/patches/qt/fix_qt_pkgconfig.patch @@ -1,11 +1,23 @@ --- old/qtbase/mkspecs/features/qt_module.prf +++ new/qtbase/mkspecs/features/qt_module.prf -@@ -245,7 +245,7 @@ +@@ -264,7 +264,7 @@ load(qt_targets) # this builds on top of qt_common -!internal_module:!lib_bundle:if(unix|mingw) { -+unix|mingw { ++if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) { CONFIG += create_pc QMAKE_PKGCONFIG_DESTDIR = pkgconfig host_build: \ +@@ -274,9 +274,9 @@ + QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw] + QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME + QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ") +- QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION) ++ QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)$$qtPlatformTargetSuffix() + for(i, MODULE_DEPENDS): \ +- QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0)) ++ QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0))$$qtPlatformTargetSuffix() + isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \ + QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module + pclib_replace.match = $$lib_replace.match diff --git a/depends/patches/qt/freetype_back_compat.patch b/depends/patches/qt/freetype_back_compat.patch new file mode 100644 index 000000000..b0f1c98aa --- /dev/null +++ b/depends/patches/qt/freetype_back_compat.patch @@ -0,0 +1,28 @@ +commit 14bc77db61bf9d56f9b6c8b84aa02573605c19c6 +Author: fanquake +Date: Tue Aug 18 15:15:08 2020 +0800 + + Fix backwards compatibility with older Freetype versions at runtime + + A few years ago, libfreetype introduced FT_Get_Font_Format() as an alias + for FT_Get_X11_Font_Format(), but FT_Get_X11_Font_Format() was kept for abi + backwards-compatibility. + + Qt 5.9 introduced a call to FT_Get_Font_Format(). Replace it with FT_Get_X11_Font_Format() + in order to remain compatibile with older freetype, which is still used by e.g. Ubuntu Trusty. + + See #14348. + +diff --git a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp +index 3f543755..8ecc1c8c 100644 +--- a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp ++++ b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp +@@ -898,7 +898,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, + } + } + #if defined(FT_FONT_FORMATS_H) +- const char *fmt = FT_Get_Font_Format(face); ++ const char *fmt = FT_Get_X11_Font_Format(face); + if (fmt && qstrncmp(fmt, "CFF", 4) == 0) { + FT_Bool no_stem_darkening = true; + FT_Error err = FT_Property_Get(qt_getFreetype(), "cff", "no-stem-darkening", &no_stem_darkening); diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf index 337d0eb9c..4cd96df29 100644 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -18,7 +18,7 @@ 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} +!host_build: QMAKE_LFLAGS += -target $${MAC_TARGET} QMAKE_AR = $${CROSS_COMPILE}ar cq QMAKE_RANLIB=$${CROSS_COMPILE}ranlib QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool diff --git a/depends/patches/qt/no-xlib.patch b/depends/patches/qt/no-xlib.patch new file mode 100644 index 000000000..fe82c2c73 --- /dev/null +++ b/depends/patches/qt/no-xlib.patch @@ -0,0 +1,69 @@ +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/zeromq/0001-fix-build-with-older-mingw64.patch b/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch deleted file mode 100644 index b911ac567..000000000 --- a/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch +++ /dev/null @@ -1,30 +0,0 @@ -From f6866b0f166ad168618aae64c7fbee8775d3eb23 Mon Sep 17 00:00:00 2001 -From: mruddy <6440430+mruddy@users.noreply.github.com> -Date: Sat, 30 Jun 2018 09:44:58 -0400 -Subject: [PATCH] fix build with older mingw64 - ---- - src/windows.hpp | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/windows.hpp b/src/windows.hpp -index 6c3839fd..2c32ec79 100644 ---- a/src/windows.hpp -+++ b/src/windows.hpp -@@ -58,6 +58,13 @@ - #include - #include - #include -+ -+#if defined __MINGW64_VERSION_MAJOR && __MINGW64_VERSION_MAJOR < 4 -+// Workaround for mingw-w64 < v4.0 which did not include ws2ipdef.h in iphlpapi.h. -+// Fixed in mingw-w64 by 9bd8fe9148924840d315b4c915dd099955ea89d1. -+#include -+#include -+#endif - #include - - #if !defined __MINGW32__ --- -2.17.1 - diff --git a/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch b/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch deleted file mode 100644 index 022e31197..000000000 --- a/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch +++ /dev/null @@ -1,35 +0,0 @@ -From c9bbdd6581d07acfe8971e4bcebe278a3676cf03 Mon Sep 17 00:00:00 2001 -From: mruddy <6440430+mruddy@users.noreply.github.com> -Date: Sat, 30 Jun 2018 09:57:18 -0400 -Subject: [PATCH] disable pthread_set_name_np - -pthread_set_name_np adds a Glibc requirement on >= 2.12. ---- - src/thread.cpp | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/thread.cpp b/src/thread.cpp -index a1086b0c..9943f354 100644 ---- a/src/thread.cpp -+++ b/src/thread.cpp -@@ -307,7 +307,7 @@ void zmq::thread_t::setThreadName (const char *name_) - */ - if (!name_) - return; -- -+#if 0 - #if defined(ZMQ_HAVE_PTHREAD_SETNAME_1) - int rc = pthread_setname_np (name_); - if (rc) -@@ -323,6 +323,8 @@ void zmq::thread_t::setThreadName (const char *name_) - #elif defined(ZMQ_HAVE_PTHREAD_SET_NAME) - pthread_set_name_np (descriptor, name_); - #endif -+#endif -+ return; - } - - #endif --- -2.17.1 - diff --git a/depends/patches/zeromq/remove_libstd_link.patch b/depends/patches/zeromq/remove_libstd_link.patch new file mode 100644 index 000000000..ddf91e6ab --- /dev/null +++ b/depends/patches/zeromq/remove_libstd_link.patch @@ -0,0 +1,25 @@ +commit 47d4cd12a2c051815ddda78adebdb3923b260d8a +Author: fanquake +Date: Tue Aug 18 14:45:40 2020 +0800 + + Remove needless linking against libstdc++ + + This is broken for a number of reasons, including: + - g++ understands "static-libstdc++ -lstdc++" to mean "link against + whatever libstdc++ exists, probably shared", which in itself is buggy. + - another stdlib (libc++ for example) may be in use + + See #11981. + +diff --git a/src/libzmq.pc.in b/src/libzmq.pc.in +index 233bc3a..3c2bf0d 100644 +--- a/src/libzmq.pc.in ++++ b/src/libzmq.pc.in +@@ -7,6 +7,6 @@ Name: libzmq + Description: 0MQ c++ library + Version: @VERSION@ + Libs: -L${libdir} -lzmq +-Libs.private: -lstdc++ @pkg_config_libs_private@ ++Libs.private: @pkg_config_libs_private@ + Requires.private: @pkg_config_names_private@ + Cflags: -I${includedir} @pkg_config_defines@ diff --git a/doc/architecture.md b/doc/architecture.md index 7f88a9022..15147481c 100644 --- a/doc/architecture.md +++ b/doc/architecture.md @@ -113,35 +113,7 @@ Pocket sqlite database сохраняет все транзакции в раз > Здесь и далее `main.Transactions.TxOut` - `..` означает SQLite базу данных Pocket Social Data - `pocketdb/main.sqlite3` -Все типы транзакций, хранящиеся в `main.Transactions` определены как Enum и имеют зафиксированное целое значение - [src/pocketdb/models/base/Base.hpp]() -```c++ -enum TxType -{ - NOT_SUPPORTED = 0, - - USER_ACCOUNT = 100, - VIDEO_SERVER_ACCOUNT = 101, - MESSAGE_SERVER_ACCOUNT = 102, - - POST_CONTENT = 200, - VIDEO_CONTENT = 201, - TRANSLATE_CONTENT = 202, - SERVERPING_CONTENT = 203, - COMMENT_CONTENT = 204, - - SCORE_POST_ACTION = 300, - SCORE_COMMENT_ACTION = 301, - - SUBSCRIBE_ACTION = 302, - SUBSCRIBE_PRIVATE_ACTION = 303, - SUBSCRIBE_CANCEL_ACTION = 304, - - BLOCKING_ACTION = 305, - BLOCKING_CANCEL_ACTION = 306, - - COMPLAIN_ACTION = 307, -}; -``` +Все типы транзакций, хранящиеся в `main.Transactions` определены как Enum и имеют зафиксированное целое значение - [src/pocketdb/models/base/PocketTypes.h]() Сформированный блок (1) подключается к цепи (2). diff --git a/src/.idea/codeStyles/Project.xml b/src/.idea/codeStyles/Project.xml index 213c5ea87..550d10440 100644 --- a/src/.idea/codeStyles/Project.xml +++ b/src/.idea/codeStyles/Project.xml @@ -23,7 +23,7 @@ - + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7d17ed922..d11cae21e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -58,7 +58,7 @@ option(WITH_INCOMPATIBLE_BDB "Allow using a bdb version greater than 4.8" OFF) option(DISABLE_MAN "do not install man pages (default is to install)" OFF) if (NOT DISABLE_MAM) - # TODO it doesn't go anywhere + # TODO (build): build man set(ENABLE_MAN ON) endif () @@ -103,7 +103,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) include(CmakeCheckEndian.cmake) # LevelDB -# TODO only if EMBEDDED_LVLDB defined +# TODO (build): only if EMBEDDED_LVLDB defined add_subdirectory(leveldb/) @@ -119,7 +119,6 @@ add_subdirectory(secp256k1/) set(WITH_PIC ${WITH_PIC_BACKUP} CACHE BOOL "Enable fPIC" FORCE) # Finding boost -# TODO minimal boost version is increased to 1.66 because websockets (websocket/ws.h) are using lambdas as WriteHandler. This functional was implemented in 1.66. find_package(Boost 1.66 REQUIRED COMPONENTS system thread chrono filesystem date_time) ######## Boost sleep functions validation set(CHECK_BOOST_SLEEP "#include @@ -229,7 +228,7 @@ if(${_ADDRS_STUFF_COUNT} EQUAL 2) # Means we succeed with both getifaddrs and fr endif() endif() -# TODO (losty-fur): non-posix method from bsd and macos that should be enabled by specific option. +# Non-posix method from bsd and macos that should be enabled by specific option. # Checking for daemon function check_cxx_symbol_exists(daemon unistd.h _RES_DAEMON) if (_RES_DAEMON) @@ -421,8 +420,8 @@ else() endif() endif() -# TODO (losty-fur): make an option to allow disabling this -if (NOT MINGW) # TODO (losty-fur): also freebsd but probably we do not support it +# TODO (build): make an option to allow disabling this +if (NOT MINGW) # TODO (build): also this is required for freebsd but probably we do not support it check_cxx_source_compiles(" #include static thread_local int foo = 0; static void run_thread() { foo++;} @@ -435,7 +434,7 @@ if (NOT MINGW) # TODO (losty-fur): also freebsd but probably we do not support i endif () endif() -# TODO (losty-fur): add libmultiprocess stuff +# TODO (build): add libmultiprocess stuff check_cxx_source_compiles(" #include #include @@ -473,7 +472,7 @@ if (CHAR_EQUALS_INT8) endif () if (ENABLE_REDUCE_EXPORTS) - # TODO It doesn't go anywhere + # TODO (build): It doesn't go anywhere check_cxx_compiler_flag(-fvisibility=hidden VISIBILITY_HIDDEN) if (NOT VISIBILITY_HIDDEN) message(FATAL_ERROR "Cannot set default symbol visibility. Use -DENABLE_REDUCE_EXPORTS=OFF") @@ -504,7 +503,7 @@ endif (HAVE_DECL_STRNLEN) # Univalue library if (WITH_SYSTEM_UNIVALUE) - # TODO write find_package script + # TODO (build): write find_package script find_library(UNIVALUE univalue) if (NOT UNIVALUE) message(FATAL_ERROR "System univalue requested but not found") @@ -561,6 +560,7 @@ add_library(${POCKETDB} pocketdb/models/base/Transaction.h pocketdb/models/base/TransactionInput.h pocketdb/models/base/TransactionOutput.h + pocketdb/models/base/SocialTransaction.h pocketdb/models/base/Rating.h pocketdb/models/base/ReturnDtoModels.h pocketdb/models/dto/Default.h @@ -589,6 +589,7 @@ add_library(${POCKETDB} pocketdb/models/base/Transaction.cpp pocketdb/models/base/TransactionInput.cpp pocketdb/models/base/TransactionOutput.cpp + pocketdb/models/base/SocialTransaction.cpp pocketdb/models/base/Rating.cpp pocketdb/models/dto/Default.cpp pocketdb/models/dto/Coinbase.cpp @@ -614,6 +615,8 @@ add_library(${POCKETDB} pocketdb/models/dto/Complain.cpp pocketdb/models/dto/AccountSetting.cpp pocketdb/models/dto/ContentDelete.cpp + pocketdb/models/dto/moderation/Flag.h + pocketdb/models/dto/moderation/Flag.cpp pocketdb/models/web/WebTag.h pocketdb/models/web/WebContent.h pocketdb/models/dto/BoostContent.cpp @@ -719,8 +722,7 @@ if (ENABLE_GLIBC_BACK_COMPAT) target_sources(${POCKETCOIN_UTIL} PRIVATE compat/glibc_compat.cpp) endif () if (REQUIRED_SOCKET_LIB) - # TODO (losty-fur): idk what is this "socket" lib, but linking to this is done in bitcoin after specific checking. - # Probably this is specific for some unix systems but since we have the checking noticed above nothing should be broken here. + # Linking to a socket library if getifaddrs freeifaddrs functions require it (see _CHECK_SOCKET_RES_WITHOUT_LIBSOCKET) target_link_libraries(${POCKETCOIN_UTIL} PRIVATE socket) endif() target_include_directories(${POCKETCOIN_UTIL} PUBLIC ${Boost_INCLUDE_DIRS}) @@ -767,17 +769,17 @@ add_library(${POCKETCOIN_CRYPTO} serialize.h arith_uint256.cpp arith_uint256.h - util/strencodings.h # TODO maybe move to utils + util/strencodings.h # TODO (build): maybe move to utils util/strencodings.cpp ) target_link_libraries(${POCKETCOIN_CRYPTO} PRIVATE ${POCKETCOIN_COMMON} ${POCKETCOIN_SUPPORT} secp256k1) if (ENABLE_SSE41) target_sources(${POCKETCOIN_CRYPTO} PRIVATE crypto/sha256_sse41.cpp) if (MSVC) - # TODO it seems like windows fails with everything exept sse2 that is enabled by default - # Futhermore there are cmake scripts to find sse4.1 or avx support where they are always hardcoded as false for Windows - # https://github.com/magic-sph/magic/blob/master/cmake/FindSSE.cmake - # target_compile_options(${POCKETCOIN_CRYPTO} PRIVATE /arch:SSE4.1) + # TODO (build): it seems like windows fails with everything exept sse2 that is enabled by default + # Futhermore there are cmake scripts to find sse4.1 or avx support where they are always hardcoded as false for Windows: + # https://github.com/magic-sph/magic/blob/master/cmake/FindSSE.cmake + # target_compile_options(${POCKETCOIN_CRYPTO} PRIVATE /arch:SSE4.1) else () target_compile_definitions(${POCKETCOIN_CRYPTO} PRIVATE ENABLE_SSE41) target_compile_options(${POCKETCOIN_CRYPTO} PRIVATE -msse4.1) @@ -814,7 +816,7 @@ target_link_libraries(${POCKETCOIN_SYSTEM} PRIVATE ${POCKETCOIN_UTIL} ${POCKETCO target_include_directories(${POCKETCOIN_SYSTEM} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # Consensus -# TODO probably completely move this to server +# TODO (build): probably completely move this to server set(POCKETCOIN_CONSENSUS pocketcoin_consensus) add_library(${POCKETCOIN_CONSENSUS} protocol.h @@ -825,7 +827,7 @@ add_library(${POCKETCOIN_CONSENSUS} key.cpp ) target_link_libraries(${POCKETCOIN_CONSENSUS} PRIVATE ${POCKETCOIN_UTIL} ${POCKETCOIN_COMMON} ${POCKETCOIN_CRYPTO} ${POCKETDB} univalue secp256k1) -# TODO hadrdcoded because we are always building consensus +# TODO (build): hadrdcoded because we are always building consensus add_compile_definitions(HAVE_CONSENSUS_LIB=1) @@ -833,11 +835,11 @@ add_compile_definitions(HAVE_CONSENSUS_LIB=1) set(POCKETCOIN_COMMON_RPC pocketcoin_common_rpc) add_library(${POCKETCOIN_COMMON_RPC} rpc/protocol.h - # TODO (losty-fur): request is shared between cli and daemon. - # Currently it is using DBConnection that is a part of server. - # This is OK for now because we have shared headers but this should be reworked. - # PocketDB stuff should be extracted to a different lib. Specially "pocketdb/SQLiteConnection.h" - # Also sqlite should be publically linked to this new lib and removed from linking here + # TODO (build): request is shared between cli and daemon. + # Currently it is using DBConnection that is a part of server. + # This is OK for now because we have shared headers but this should be reworked. + # PocketDB stuff should be extracted to a different lib. Specially "pocketdb/SQLiteConnection.h" + # Also sqlite should be publically linked to this new lib and removed from linking here rpc/request.h rpc/request.cpp ) @@ -1078,6 +1080,8 @@ add_library(${POCKETCOIN_SERVER} pocketdb/repositories/ConsensusRepository.cpp pocketdb/repositories/CheckpointRepository.h pocketdb/repositories/CheckpointRepository.cpp + pocketdb/repositories/SystemRepository.h + pocketdb/repositories/SystemRepository.cpp pocketdb/repositories/web/NotifierRepository.h pocketdb/repositories/web/NotifierRepository.cpp pocketdb/repositories/web/WebRepository.h @@ -1110,10 +1114,10 @@ add_library(${POCKETCOIN_SERVER} pocketdb/consensus/social/AccountSetting.hpp pocketdb/consensus/social/ContentDelete.hpp pocketdb/consensus/social/BoostContent.hpp + pocketdb/consensus/moderation/Flag.hpp pocketdb/consensus/Helper.cpp pocketdb/consensus/Base.cpp pocketdb/consensus/Lottery.cpp - pocketdb/consensus/Reputation.cpp ) target_link_libraries(${POCKETCOIN_SERVER} PRIVATE ${POCKETCOIN_COMMON_RPC} ${POCKETCOIN_UTIL} ${POCKETCOIN_COMMON} ${POCKETCOIN_SYSTEM} ${POCKETCOIN_CONSENSUS} ${POCKETCOIN_CRYPTO} Event::event OpenSSL::Crypto ${CRYPT32} Boost::boost Boost::date_time) target_include_directories(${POCKETCOIN_SERVER} PRIVATE ${OPENSSL_INCLUDE_DIR} ${Event_INCLUDE_DIRS}) @@ -1156,7 +1160,6 @@ if (NOT DISABLE_WALLET) wallet/scriptpubkeyman.h wallet/scriptpubkeyman.cpp - # TODO (losty-fur): we force use sqlite. In bitcoin this is optional wallet/sqlite.h wallet/sqlite.cpp interfaces/wallet.h @@ -1171,12 +1174,11 @@ else () endif () if(REQUIRED_SOCKET_LIB) - # TODO (losty-fur): idk what is this "socket" lib, but linking to this is done in bitcoin after specific checking. - # Probably this is specific for some unix systems but since we have the checking noticed above nothing should be broken here. + # same as for above for POCKETCOIN_UTIL target_link_libraries(${POCKETCOIN_SERVER} PRIVATE socket) endif() -# TODO USE_UPNP +# TODO (build): USE_UPNP # ZMQ if (NOT DISABLE_ZMQ) @@ -1219,7 +1221,7 @@ target_link_libraries(libpocketcoin_cli PRIVATE univalue ${POCKETCOIN_UTIL} ${PO target_include_directories(libpocketcoin_cli PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) set(POCKETCOIN_CLI pocketcoin-cli) add_executable(${POCKETCOIN_CLI} pocketcoin-cli.cpp ) -# TODO (losty-fur): remove leveldb after header fix +# TODO (build): remove leveldb after header fix target_link_libraries(${POCKETCOIN_CLI} PRIVATE ${POCKETCOIN_UTIL} ${POCKETCOIN_COMMON_RPC} univalue Event::event libpocketcoin_cli leveldb) target_include_directories(${POCKETCOIN_CLI} PRIVATE ${Event_INCLUDE_DIRS}) diff --git a/src/Makefile.am b/src/Makefile.am index 5dc9224fb..8dacb2e5f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -141,6 +141,7 @@ POCKETDB_H = \ pocketdb/repositories/ConsensusRepository.h \ pocketdb/repositories/RatingsRepository.h \ pocketdb/repositories/CheckpointRepository.h \ + pocketdb/repositories/SystemRepository.h \ pocketdb/repositories/web/WebRepository.h \ pocketdb/repositories/web/WebRpcRepository.h \ pocketdb/repositories/web/NotifierRepository.h \ @@ -178,12 +179,15 @@ POCKETDB_H = \ pocketdb/consensus/social/AccountSetting.hpp \ pocketdb/consensus/social/ContentDelete.hpp \ \ + pocketdb/consensus/moderation/Flag.hpp \ + \ pocketdb/models/base/PocketTypes.h \ pocketdb/models/base/Base.h \ pocketdb/models/base/Payload.h \ pocketdb/models/base/Transaction.h \ pocketdb/models/base/TransactionInput.h \ pocketdb/models/base/TransactionOutput.h \ + pocketdb/models/base/SocialTransaction.h \ pocketdb/models/base/Rating.h \ pocketdb/models/base/Payload.h \ pocketdb/models/base/ReturnDtoModels.h \ @@ -210,6 +214,7 @@ POCKETDB_H = \ pocketdb/models/dto/Complain.h \ pocketdb/models/dto/Video.h \ pocketdb/models/dto/Article.h \ + pocketdb/models/dto/moderation/Flag.h \ \ pocketdb/models/web/WebTag.h \ pocketdb/models/web/WebContent.h \ @@ -237,6 +242,7 @@ POCKETDB_CPP = \ pocketdb/repositories/TransactionRepository.cpp \ pocketdb/repositories/RatingsRepository.cpp \ pocketdb/repositories/CheckpointRepository.cpp \ + pocketdb/repositories/SystemRepository.cpp \ pocketdb/repositories/web/WebRepository.cpp \ pocketdb/repositories/web/WebRpcRepository.cpp \ pocketdb/repositories/web/NotifierRepository.cpp \ @@ -246,13 +252,13 @@ POCKETDB_CPP = \ pocketdb/consensus/Helper.cpp \ pocketdb/consensus/Base.cpp \ pocketdb/consensus/Lottery.cpp \ - pocketdb/consensus/Reputation.cpp \ \ pocketdb/models/base/Base.cpp \ pocketdb/models/base/Payload.cpp \ pocketdb/models/base/Transaction.cpp \ pocketdb/models/base/TransactionInput.cpp \ pocketdb/models/base/TransactionOutput.cpp \ + pocketdb/models/base/SocialTransaction.cpp \ pocketdb/models/base/Rating.cpp \ pocketdb/models/base/Payload.cpp \ \ @@ -292,7 +298,8 @@ POCKETDB_CPP = \ pocketdb/models/dto/Complain.cpp \ pocketdb/models/dto/Video.cpp \ pocketdb/models/dto/BoostContent.cpp \ - pocketdb/models/dto/Article.cpp + pocketdb/models/dto/Article.cpp \ + pocketdb/models/dto/moderation/Flag.cpp # CORE POCKETCOIN_CORE_H = \ diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 59e671e28..7d4b7eda8 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -70,7 +70,7 @@ bench_bench_pocketcoin_LDADD = \ $(LIBSQLITE3) -# TODO (losty-fur): this is needed because websocket is included in "validation.h" even it is not used here. +# TODO (build): this is needed because websocket is included in "validation.h" even it is not used here. # Fix this in validation.h (probably move openssl headers to pImpl or smth) and remove ssl libs from here bench_bench_pocketcoin_LDADD += $(SSL_LIBS) $(CRYPTO_LIBS) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index fba6970dc..3dccfe832 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -65,6 +65,7 @@ class CMainParams : public CChainParams public: CMainParams() { + // TODO (losty-critical): check all below todos strNetworkID = CBaseChainParams::MAIN; networkId = NetworkMain; consensus.signet_blocks = false; // TODO (losty): may be change?? @@ -135,14 +136,14 @@ class CMainParams : public CChainParams nDefaultPort = 37070; nPruneAfterHeight = 100000; - m_assumed_blockchain_size = 50; // TODO (losty+): пока хватает 50 - будем увеличивать по мере роста - m_assumed_chain_state_size = 0; // TODO (losty+): мы не используем пока prune + m_assumed_blockchain_size = 50; // 50 is ok for now + m_assumed_chain_state_size = 0; // We do not use prune genesis = CreateGenesisBlock(1548092268, 234579, 0x1e0fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); - // TODO (losty): assertion fails here - // assert(consensus.hashGenesisBlock == uint256S("0x00000fd0f6633d395541056e8adc32961e15f8133674b2e3937c4d210ced6f3f")); - // assert(genesis.hashMerkleRoot == uint256S("0xaced9fcaba8f66be3d4d51a95cb048dda6611b8f2d2bf4541d9e2e16c07ee1c9")); + + assert(consensus.hashGenesisBlock == uint256S("0x00000fd0f6633d395541056e8adc32961e15f8133674b2e3937c4d210ced6f3f")); + assert(genesis.hashMerkleRoot == uint256S("0xaced9fcaba8f66be3d4d51a95cb048dda6611b8f2d2bf4541d9e2e16c07ee1c9")); // Note that of those which support the service bits prefix, most only support a subset of // possible options. @@ -260,9 +261,9 @@ class CTestNetParams : public CChainParams genesis = CreateGenesisBlock(1548092268, 234579, 0x1e0fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); - // TODO (losty): assertion fails here - // assert(consensus.hashGenesisBlock == uint256S("0x00000fd0f6633d395541056e8adc32961e15f8133674b2e3937c4d210ced6f3f")); - // assert(genesis.hashMerkleRoot == uint256S("0xaced9fcaba8f66be3d4d51a95cb048dda6611b8f2d2bf4541d9e2e16c07ee1c9")); + + assert(consensus.hashGenesisBlock == uint256S("0x00000fd0f6633d395541056e8adc32961e15f8133674b2e3937c4d210ced6f3f")); + assert(genesis.hashMerkleRoot == uint256S("0xaced9fcaba8f66be3d4d51a95cb048dda6611b8f2d2bf4541d9e2e16c07ee1c9")); base58Prefixes[PUBKEY_ADDRESS] = std::vector(1, 65); //T base58Prefixes[SCRIPT_ADDRESS] = std::vector(1, 78); //Y diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index c13454fc7..86627ff31 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -43,7 +43,6 @@ const CBaseChainParams& BaseParams() */ std::unique_ptr CreateBaseChainParams(const std::string& chain) { - // TODO (losty-fur): probably update ports for onion and signet. if (chain == CBaseChainParams::MAIN) { return MakeUnique("", 37071, 38081, 38082, 38083, 38084); } else if (chain == CBaseChainParams::TESTNET) { diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index ffb10af61..7ac9cd6fe 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -8,7 +8,6 @@ * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly. */ static SeedSpec6 pnSeed6_main[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x6c,0xe7,0x28}, 37070}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x87,0xb5,0xc4,0xf3}, 37070}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x15,0x38,0xcb}, 37070}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x15,0x39,0x0e}, 37070}, diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 5ae0b0632..852cfe229 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -21,6 +21,7 @@ namespace Checkpoints { for (const MapCheckpoints::value_type& i : reverse_iterate(checkpoints)) { const uint256& hash = i.second; + LOCK(cs_main); CBlockIndex* pindex = LookupBlockIndex(hash); if (pindex) { return pindex; diff --git a/src/consensus/validation.h b/src/consensus/validation.h index 7e2022335..0560ad401 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -24,7 +24,7 @@ static constexpr size_t MINIMUM_WITNESS_COMMITMENT{38}; enum class TxValidationResult { TX_RESULT_UNSET = 0, //!< initial value. Tx has not yet been rejected TX_CONSENSUS, //!< invalid by consensus rules - // TODO (losty-fur): probably rename this. 2 below are the same, but first results in node's punishment, second is common situation if current node is much behind others + // TODO (team): probably rename this. 2 below are the same, but first results in node's punishment, second is common situation if current node is much behind others TX_SOCIAL_CONSENSUS, //!< invalid by social (pocketnet) consensus rules that is critical TX_SOCIAL_UNWARRANT, //!< invalid by social (pocketnet) rules that is common if current node is much behind others /** @@ -87,6 +87,7 @@ enum class BlockValidationResult { BLOCK_SPAM, //!< error on spam detected BLOCK_STAKE_BITS, //!< error in validating stake bits. Punish with score 1 BLOCK_TIMESTAMP_INVALID, //!< incorrect stake timestamp + BLOCK_PROOF_INVALID, //!< POW block when POS expected and vice-versa }; diff --git a/src/fs.h b/src/fs.h index feccb852e..43d7369b8 100644 --- a/src/fs.h +++ b/src/fs.h @@ -42,7 +42,7 @@ namespace fsbridge { }; std::string get_filesystem_error_message(const fs::filesystem_error& e); -// TODO (losty-fur): according to description this can be removed because pocketnet is using C++17 +// TODO : according to description this can be removed because pocketnet is using C++17 // GNU libstdc++ specific workaround for opening UTF-8 paths on Windows. // // On Windows, it is only possible to reliably access multibyte file paths through diff --git a/src/httprpc.h b/src/httprpc.h index d7414d594..49a6c9058 100644 --- a/src/httprpc.h +++ b/src/httprpc.h @@ -30,6 +30,7 @@ void StopHTTPRPC(); * Precondition; HTTP and RPC has been started. */ void StartREST(const util::Ref& context); +void StartSTATIC(const util::Ref& context); /** Interrupt RPC REST subsystem. */ void InterruptREST(); @@ -37,5 +38,6 @@ void InterruptREST(); * Precondition; HTTP and RPC has been stopped. */ void StopREST(); +void StopSTATIC(); #endif diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 88d2dcb18..40fc14bd0 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -392,15 +392,17 @@ bool InitHTTPServer(const util::Ref& context) #endif // Additional pocketnet seocket - if (gArgs.GetBoolArg("-api", true)) + if (gArgs.GetBoolArg("-api", DEFAULT_API_ENABLE)) { g_webSocket = new HTTPWebSocket(eventBase, timeout, workQueuePublicDepth, workQueuePostDepth, true); RegisterPocketnetWebRPCCommands(g_webSocket->m_table_rpc, g_webSocket->m_table_post_rpc); + } - // Additional pocketnet static files socket - g_staticSocket = new HTTPSocket(eventBase, timeout, workQueueStaticDepth, true); + if (gArgs.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) g_restSocket = new HTTPSocket(eventBase, timeout, workQueueRestDepth, true); - } + + if (gArgs.GetBoolArg("-static", DEFAULT_STATIC_ENABLE)) + g_staticSocket = new HTTPSocket(eventBase, timeout, workQueueStaticDepth, true); if (!HTTPBindAddresses()) { diff --git a/src/httpserver.h b/src/httpserver.h index 445d75ea4..d65efd358 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -33,6 +33,10 @@ static const int DEFAULT_HTTP_STATIC_WORKQUEUE = 16; static const int DEFAULT_HTTP_REST_WORKQUEUE = 16; static const int DEFAULT_HTTP_SERVER_TIMEOUT = 30; +static const bool DEFAULT_API_ENABLE = true; +static const bool DEFAULT_REST_ENABLE = false; +static const bool DEFAULT_STATIC_ENABLE = false; + struct evhttp_request; class CService; diff --git a/src/init.cpp b/src/init.cpp index 12b993a78..c2a982459 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -100,8 +100,6 @@ static bool fFeeEstimatesInitialized = false; static const bool DEFAULT_PROXYRANDOMIZE = true; -static const bool DEFAULT_API_ENABLE = true; -static const bool DEFAULT_REST_ENABLE = false; static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; Statistic::RequestStatEngine gStatEngineInstance; @@ -229,6 +227,7 @@ void Shutdown(NodeContext& node) StopHTTPRPC(); StopREST(); + StopSTATIC(); StopRPC(); StopHTTPServer(); @@ -436,7 +435,7 @@ void SetupServerArgs(NodeContext& node) const auto signetChainParams = CreateChainParams(argsman, CBaseChainParams::SIGNET); const auto regtestChainParams = CreateChainParams(argsman, CBaseChainParams::REGTEST); - // TODO (losty): hidden args were not ported. + // TODO (losty-critical): hidden args were not ported. // Hidden Options std::vector hidden_args = { "-dbcrashratio", "-forcecompactdb", @@ -628,6 +627,11 @@ void SetupServerArgs(NodeContext& node) argsman.AddArg("-api", strprintf("Enable Public RPC api server (default: %u)", DEFAULT_API_ENABLE), ArgsManager::ALLOW_ANY, OptionsCategory::RPC); argsman.AddArg("-rest", strprintf("Accept public REST requests (default: %u)", DEFAULT_REST_ENABLE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC); + + argsman.AddArg("-static", strprintf("Accept public requests to static resources (default: %u)", DEFAULT_STATIC_ENABLE), ArgsManager::ALLOW_ANY, OptionsCategory::RPC); + argsman.AddArg("-staticpath", "Path to static resources (default: GetDataDir()/wwwroot", ArgsManager::ALLOW_ANY, OptionsCategory::RPC); + + argsman.AddArg("-rpcallowip=", "Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times", ArgsManager::ALLOW_ANY, OptionsCategory::RPC); argsman.AddArg("-rpcauth=", "Username and HMAC-SHA-256 hashed password for JSON-RPC connections. The field comes in the format: :$. A canonical python script is included in share/rpcauth. The client then connects normally using the rpcuser=/rpcpassword= pair of arguments. This option can be specified multiple times", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC); argsman.AddArg("-rpcbind=[:port]", "Bind to given address to listen for JSON-RPC connections. Do not expose the RPC server to untrusted networks such as the public internet! This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost)", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY | ArgsManager::SENSITIVE, OptionsCategory::RPC); @@ -661,6 +665,7 @@ void SetupServerArgs(NodeContext& node) argsman.AddArg("-sqltimeout", strprintf("Timeout for ReadOnly sql querys (default: %ds)", 10), ArgsManager::ALLOW_ANY, OptionsCategory::SQLITE); argsman.AddArg("-sqlsharedcache", strprintf("Experimental: enable shared cache for sqlite connections (default: disabled)"), ArgsManager::ALLOW_ANY, OptionsCategory::SQLITE); argsman.AddArg("-sqlcachesize", strprintf("Experimental: Cache size for SQLite connection in megabytes (default: %d mb)", 5), ArgsManager::ALLOW_ANY, OptionsCategory::SQLITE); + argsman.AddArg("-withoutweb", strprintf("Disable WEB part of database (default: %u)", false), ArgsManager::ALLOW_ANY, OptionsCategory::SQLITE); #if HAVE_DECL_DAEMON @@ -866,7 +871,7 @@ static void ThreadImport(ChainstateManager& chainman, const util::Ref& context, } // .. only web DB - if (fReindex == 5 && args.GetBoolArg("-api", true)) + if (fReindex == 5 && args.GetBoolArg("-api", DEFAULT_API_ENABLE)) { LogPrintf("Building a Web database: 0%%\n"); @@ -905,7 +910,6 @@ static void ThreadImport(ChainstateManager& chainman, const util::Ref& context, } } - // TODO (losty-fur): seems good BlockValidationState state; int64_t disconnectHeight = args.GetArg("-disconnectlast", -1); if (disconnectHeight > -1) @@ -972,14 +976,25 @@ static bool AppInitServers(const util::Ref& context, NodeContext& node) const ArgsManager& args = *Assert(node.args); RPCServer::OnStarted(&OnRPCStarted); RPCServer::OnStopped(&OnRPCStopped); + if (!InitHTTPServer(context)) return false; + StartRPC(); + node.rpc_interruption_point = RpcInterruptionPoint; + if (!StartHTTPRPC(context)) return false; - if (args.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) StartREST(context); + + if (gArgs.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) + StartREST(context); + + if (gArgs.GetBoolArg("-static", DEFAULT_STATIC_ENABLE)) + StartSTATIC(context); + StartHTTPServer(); + return true; } @@ -1534,7 +1549,7 @@ bool AppInitInterfaces(NodeContext& node) bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) { - const ArgsManager& args = *Assert(node.args); + ArgsManager& args = *Assert(node.args); const CChainParams& chainparams = Params(); // ********************************************************* Step 4a: application initialization if (!CreatePidFile(args)) { @@ -1624,10 +1639,11 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA PocketDb::InitSQLite(GetDataDir() / "pocketdb"); PocketDb::InitSQLiteCheckpoints(GetDataDir() / "checkpoints"); - + PocketWeb::PocketFrontendInst.Init(); - if (args.GetBoolArg("-api", true)) + // Always start WEB DB building thread + if (!args.GetBoolArg("-withoutweb", false)) PocketServices::WebPostProcessorInst.Start(threadGroup); // ********************************************************* Step 4b: Additional settings @@ -2068,6 +2084,12 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA } } + // // ********************************************************* Step 7.1: start db migrations + // uiInterface.InitMessage(_("Updating Pocket DB...").translated); + // bool cleanMempool = false; + // PocketDb::SQLiteDbInst.InitMigration(cleanMempool); + // if (cleanMempool) args.SoftSetBoolArg("-mempoolclean", true); + // As LoadBlockIndex can take several minutes, it's possible the user // requested to kill the GUI during the last operation. If so, exit. // As the program has not fully started yet, Shutdown() is possibly overkill. @@ -2082,9 +2104,9 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA if (!est_filein.IsNull()) ::feeEstimator.Read(est_filein); fFeeEstimatesInitialized = true; - + // ********************************************************* Step 8: start indexers - // TXIndex need! Force enabled! + // TODO (brangr): maybe not needed? g_txindex = MakeUnique(nTxIndexCache, false, fReindex); g_txindex->Start(); @@ -2292,7 +2314,8 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA // ********************************************************* Step 13: finished // Start WebSocket server - if (args.GetBoolArg("-api", true)) InitWS(); + if (args.GetBoolArg("-api", DEFAULT_API_ENABLE)) + InitWS(); gStatEngineInstance.Run(threadGroup, context); diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 895217cb8..cff490087 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -125,8 +125,8 @@ class RpcHandlerImpl : public Handler throw; } }; - // TODO (losty-fur): g_socket can possibly be null. Need some kind of segfault protection. Probably in a more generic way because this problem occurs many places - g_socket->m_table_rpc.appendCommand(m_command.name, &m_command); + if (g_socket) + g_socket->m_table_rpc.appendCommand(m_command.name, &m_command); } void disconnect() final diff --git a/src/leveldb/CMakeLists.txt b/src/leveldb/CMakeLists.txt index 2f75780ae..26cbaa9bc 100644 --- a/src/leveldb/CMakeLists.txt +++ b/src/leveldb/CMakeLists.txt @@ -256,7 +256,7 @@ endif(BUILD_SHARED_LIBS) if(HAVE_CLANG_THREAD_SAFETY) target_compile_options(leveldb - PUBLIC + PRIVATE -Werror -Wthread-safety) endif(HAVE_CLANG_THREAD_SAFETY) diff --git a/src/net.h b/src/net.h index 60cabe87e..f020d1128 100644 --- a/src/net.h +++ b/src/net.h @@ -54,8 +54,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60; static const int FEELER_INTERVAL = 120; /** The maximum number of addresses from our addrman to return in response to a getaddr message. */ static constexpr size_t MAX_ADDR_TO_SEND = 1000; -/** Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable). */ -static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 4 * 1000 * 1000; +/** Maximum length of incoming protocol messages (no message over 16 MB is currently acceptable). */ +static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 16000000; /** Maximum length of the user agent string in `version` message */ static const unsigned int MAX_SUBVERSION_LENGTH = 256; /** Maximum number of automatic outgoing nodes over which we'll relay everything (blocks, tx, addrs, etc) */ diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 7ee7557c7..0491a9bd3 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1053,6 +1053,10 @@ bool GetNodeStateStatsView(NodeId nodeid, CNodeStateStats& stats) return false; stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1; stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1; + + for (const QueuedBlock& queue : state->vBlocksInFlight) + if (queue.pindex) + stats.vHeightInFlight.push_back(queue.pindex->nHeight); } PeerRef peer = GetPeerRef(nodeid); @@ -1060,7 +1064,7 @@ bool GetNodeStateStatsView(NodeId nodeid, CNodeStateStats& stats) stats.m_misbehavior_score = WITH_LOCK(peer->m_misbehavior_mutex, return peer->m_misbehavior_score); stats.m_addr_processed = peer->m_addr_processed.load(); stats.m_addr_rate_limited = peer->m_addr_rate_limited.load(); - + return true; } @@ -1252,10 +1256,12 @@ bool PeerManager::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationSt case BlockValidationResult::BLOCK_CHECKPOINT: case BlockValidationResult::BLOCK_INVALID_PREV: case BlockValidationResult::BLOCK_SPAM: + case BlockValidationResult::BLOCK_INCOMPLETE: // Was 200 previously Misbehaving(nodeid, 100, message); return true; // Conflicting (but not necessarily invalid) data or different policy: case BlockValidationResult::BLOCK_MISSING_PREV: + case BlockValidationResult::BLOCK_PROOF_INVALID: // TODO: Handle this much more gracefully (10 DoS points is super arbitrary) Misbehaving(nodeid, 10, message); return true; @@ -1264,7 +1270,6 @@ bool PeerManager::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationSt return true; case BlockValidationResult::BLOCK_RECENT_CONSENSUS_CHANGE: case BlockValidationResult::BLOCK_TIME_FUTURE: - case BlockValidationResult::BLOCK_INCOMPLETE: // TODO (losty): validate we do not want punish in this case case BlockValidationResult::BLOCK_TIMESTAMP_INVALID: break; } diff --git a/src/pocketcoind.cpp b/src/pocketcoind.cpp index 17f7d47a4..1e2ba276b 100644 --- a/src/pocketcoind.cpp +++ b/src/pocketcoind.cpp @@ -55,7 +55,7 @@ static bool AppInit(int argc, char* argv[]) // Process help and version before taking care about datadir if (HelpRequested(args) || args.IsArgSet("-version")) { - std::string strUsage = PACKAGE_NAME " version " + FormatFullVersion() + "\n"; + std::string strUsage = PACKAGE_NAME " Daemon version " + FormatFullVersion() + "\n"; if (args.IsArgSet("-version")) { strUsage += FormatParagraph(LicenseInfo()) + "\n"; diff --git a/src/pocketdb/SQLiteDatabase.cpp b/src/pocketdb/SQLiteDatabase.cpp index 43644fae6..936d84709 100644 --- a/src/pocketdb/SQLiteDatabase.cpp +++ b/src/pocketdb/SQLiteDatabase.cpp @@ -6,13 +6,17 @@ #include "util/system.h" #include "pocketdb/pocketnet.h" #include "util/translation.h" +#include "validation.h" +#include + +#include "pocketdb/services/Serializer.h" namespace PocketDb { static void ErrorLogCallback(void* arg, int code, const char* msg) { // From sqlite3_config() documentation for the SQLITE_CONFIG_LOG option: - // "The void pointer that is the second argument t SQLITE_CONFIG_LOG is passed through as + // "The void pointer that is the second argument to SQLITE_CONFIG_LOG is passed through as // the first parameter to the application-defined logger function whenever that function is // invoked." // Assert that this is the case: @@ -59,6 +63,7 @@ namespace PocketDb RatingsRepoInst.Init(); ConsensusRepoInst.Init(); NotifierRepoInst.Init(); + SystemRepoInst.Init(); // Open, create structure and close `web` db PocketDbMigrationRef webDbMigration = std::make_shared(); @@ -110,6 +115,108 @@ namespace PocketDb } } +/* + void SQLiteDatabase::InitMigration(bool& cleanMempool) + { + + /*** Update Pocket DB from 0 to version 1 ******************************************** + * + * This migration is necessary to fill the database with TxOutputs + * records with OP_RETURN records - these records were not saved initially in the database + * + * It is also necessary to fill in the TxInputs table + * + * Since the data of these tables become critically important for the operation of the node, + * it is necessary to make sure that they are available and valid. + * To do this, a full chainActive scan is performed, checking for the presence of all data. + * + * Only after the end of the process, the DB version will be increased - in case of a process failure. + * + ************************************************************************************/ +/* const string dbNameMain = "main"; + const int newDbVersion = 1; + int dbVersion = SystemRepoInst.GetDbVersion(dbNameMain); + + if (dbVersion < newDbVersion) + { + // Clean mempool for resaving transactions data + cleanMempool = true; + + // For optimize work drop all indexes + uiInterface.InitMessage("Preparing the database for updating.."); + DropIndexes(); + + // Full rescan blockchain for resaving all transactions data + int height = 0; + int percent = ChainActive().Height() / 100; + int64_t startTime = GetTimeMicros(); + while (height <= ChainActive().Height() && !ShutdownRequested()) + { + try + { + // Read block from disk + CBlock block; + CBlockIndex* pblockindex = ChainActive()[height]; + if (!pblockindex || !ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + { + LogPrintf("Failed read block %s from disk. Stopping\n", pblockindex->GetBlockHash().GetHex()); + StartShutdown(); + return; + } + + // The default logic is used to deserialize the necessary data + // We can use standard methods to write data to the database, because inside `WHERE NOT EXISTS` is used + // This will allow us to record only the missing data without changing the existing ones. + if (auto[ok, pocketBlock] = PocketServices::Serializer::DeserializeBlock(block); ok) + { + TransRepoInst.InsertTransactions(pocketBlock); + + for (size_t i = 0; i < block.vtx.size(); i++) + { + const auto& tx = block.vtx[i]; + + ChainRepoInst.UpdateTransactionHeight( + pblockindex->GetBlockHash().GetHex(), + i, + height, + tx->GetHash().GetHex() + ); + } + } + else + { + LogPrintf("Failed deserialize block %s. Stopping\n", pblockindex->GetBlockHash().GetHex()); + StartShutdown(); + return; + } + + // Message for logging + if (height % percent == 0) + { + int64_t time = GetTimeMicros(); + uiInterface.InitMessage(tfm::format("Updating Pocket DB: %d%% (%.2fm)", (height / percent), (0.000001 * (time - startTime)) / 60.0)); + LogPrintf("Updating Pocket DB: %d%% (%.2fm)\n", (height / percent), (0.000001 * (time - startTime)) / 60.0); + } + + height += 1; + } + catch (std::exception& e) + { + LogPrintf("Unknown error: %s\n", e.what()); + StartShutdown(); + return; + } + } + + // Restore db structure + CreateStructure(); + + // Increment db version + SystemRepoInst.SetDbVersion(dbNameMain, newDbVersion); + } + } +*/ + bool SQLiteDatabase::BulkExecute(std::string sql) { try @@ -241,7 +348,8 @@ namespace PocketDb try { - LogPrintf("Migration Sqlite database `%s` structure..\n", m_file_path); + uiInterface.InitMessage(tfm::format("Updating Pocket DB `%s` structure..", m_file_path)); + LogPrintf("Updating Pocket DB`%s` structure..\n", m_file_path); if (sqlite3_get_autocommit(m_db) == 0) throw std::runtime_error(strprintf("%s: Database `%s` not opened?\n", __func__, m_file_path)); diff --git a/src/pocketdb/SQLiteDatabase.h b/src/pocketdb/SQLiteDatabase.h index 6009b80b0..ecae7e53d 100644 --- a/src/pocketdb/SQLiteDatabase.h +++ b/src/pocketdb/SQLiteDatabase.h @@ -22,7 +22,6 @@ namespace PocketDb using namespace std; void InitSQLite(fs::path path); - void InitSQLiteCheckpoints(fs::path path); class SQLiteDatabase @@ -50,6 +49,8 @@ namespace PocketDb void DropIndexes(); void Cleanup() noexcept; + + /* void InitMigration(bool& cleanMempool); */ void Close(); diff --git a/src/pocketdb/consensus/Base.h b/src/pocketdb/consensus/Base.h index 79413d70d..fdd4df84e 100644 --- a/src/pocketdb/consensus/Base.h +++ b/src/pocketdb/consensus/Base.h @@ -77,6 +77,11 @@ namespace PocketConsensus SocialConsensusResult_BadPayload = 59, SocialConsensusResult_ScoreLowReputation = 60, SocialConsensusResult_ChangeInfoDoubleInMempool = 61, + SocialConsensusResult_Duplicate = 62, + SocialConsensusResult_NotImplemeted = 63, + SocialConsensusResult_SelfFlag = 64, + SocialConsensusResult_ExceededLimit = 65, + SocialConsensusResult_LowReputation = 66, }; static inline string SocialConsensusResultString(SocialConsensusResult code) @@ -141,6 +146,13 @@ namespace PocketConsensus case (SocialConsensusResult_ScoreDeletedContent): return "ScoreDeletedContent"; case (SocialConsensusResult_RelayContentNotFound): return "RelayContentNotFound"; case (SocialConsensusResult_BadPayload): return "BadPayload"; + case (SocialConsensusResult_ChangeInfoDoubleInMempool): return "ChangeInfoDoubleInMempool"; + case (SocialConsensusResult_Duplicate): return "Duplicate"; + case (SocialConsensusResult_NotImplemeted): return "NotImplemeted"; + case (SocialConsensusResult_SelfFlag): return "SelfFlag"; + case (SocialConsensusResult_ExceededLimit): return "ExceededLimit"; + case (SocialConsensusResult_LowReputation): return "LowReputation"; + default: return "Unknown"; } } @@ -210,6 +222,8 @@ namespace PocketConsensus ConsensusLimit_lottery_referral_depth, ConsensusLimit_bad_reputation, + + ConsensusLimit_moderation_flag_count, }; /*********************************************************************************************/ @@ -253,7 +267,8 @@ namespace PocketConsensus { NetworkTest, { - {0, 100} + {0, 100}, + {761000, 10} } } } @@ -337,24 +352,10 @@ namespace PocketConsensus } } }, - // ConsensusLimit_threshold_low_likers_count - { - ConsensusLimit_threshold_low_likers_count, - { - { - NetworkMain, - { - {0, 30} - } - }, - { - NetworkTest, - { - {0, 30} - } - } - } - }, + { ConsensusLimit_threshold_low_likers_count, { + { NetworkMain, { {0, 30} }}, + { NetworkTest, { {0, 30}, {761000, 0} }} + }}, // ConsensusLimit_threshold_low_likers_depth { ConsensusLimit_threshold_low_likers_depth, @@ -1077,6 +1078,16 @@ namespace PocketConsensus } } }, + + // + // MODERATION + // + + { ConsensusLimit_moderation_flag_count, { + { NetworkMain, { {0, 30} }}, + { NetworkTest, { {0, 100} }} + }}, + }; /*********************************************************************************************/ diff --git a/src/pocketdb/consensus/Helper.cpp b/src/pocketdb/consensus/Helper.cpp index 72b5917ef..f363ed35c 100644 --- a/src/pocketdb/consensus/Helper.cpp +++ b/src/pocketdb/consensus/Helper.cpp @@ -24,6 +24,8 @@ namespace PocketConsensus ComplainConsensusFactory SocialConsensusHelper::m_complainFactory; ContentDeleteConsensusFactory SocialConsensusHelper::m_contentDeleteFactory; BoostContentConsensusFactory SocialConsensusHelper::m_boostContentFactory; + + ModerationFlagConsensusFactory SocialConsensusHelper::m_moderationFlagFactory; tuple SocialConsensusHelper::Validate(const CBlock& block, const PocketBlockRef& pBlock, int height) { @@ -193,12 +195,13 @@ namespace PocketConsensus return m_blockingCancelFactory.Instance(height)->Check(tx, static_pointer_cast(ptx)); case ACTION_COMPLAIN: return m_complainFactory.Instance(height)->Check(tx, static_pointer_cast(ptx)); - // TODO (brangr): future realize types - // case ACCOUNT_VIDEO_SERVER: - // case ACCOUNT_MESSAGE_SERVER: - // case CONTENT_SERVERPING: + + // Moderation + case MODERATION_FLAG: + return m_moderationFlagFactory.Instance(height)->Check(tx, static_pointer_cast(ptx)); + default: - return {true, SocialConsensusResult_Success}; + return {false, SocialConsensusResult_NotImplemeted}; } } @@ -247,12 +250,13 @@ namespace PocketConsensus return m_blockingCancelFactory.Instance(height)->Validate(tx, static_pointer_cast(ptx), pBlock); case ACTION_COMPLAIN: return m_complainFactory.Instance(height)->Validate(tx, static_pointer_cast(ptx), pBlock); - // TODO (brangr): future realize types - // case ACCOUNT_VIDEO_SERVER: - // case ACCOUNT_MESSAGE_SERVER: - // case CONTENT_SERVERPING: + + // Moderation + case MODERATION_FLAG: + return m_moderationFlagFactory.Instance(height)->Validate(tx, static_pointer_cast(ptx), pBlock); + default: - return {true, SocialConsensusResult_Success}; + return {false, SocialConsensusResult_NotImplemeted}; } } @@ -260,6 +264,7 @@ namespace PocketConsensus { switch (txType) { + case NOT_SUPPORTED: case TX_COINBASE: case TX_COINSTAKE: case TX_DEFAULT: diff --git a/src/pocketdb/consensus/Helper.h b/src/pocketdb/consensus/Helper.h index 5930e32db..a1a5b9bf8 100644 --- a/src/pocketdb/consensus/Helper.h +++ b/src/pocketdb/consensus/Helper.h @@ -28,6 +28,8 @@ #include "pocketdb/consensus/social/AccountSetting.hpp" #include "pocketdb/consensus/social/ContentDelete.hpp" +#include "pocketdb/consensus/moderation/Flag.hpp" + namespace PocketConsensus { using namespace std; @@ -66,6 +68,8 @@ namespace PocketConsensus static AccountSettingConsensusFactory m_accountSettingFactory; static ContentDeleteConsensusFactory m_contentDeleteFactory; static BoostContentConsensusFactory m_boostContentFactory; + + static ModerationFlagConsensusFactory m_moderationFlagFactory; }; } diff --git a/src/pocketdb/consensus/Reputation.cpp b/src/pocketdb/consensus/Reputation.cpp deleted file mode 100644 index b13d0381f..000000000 --- a/src/pocketdb/consensus/Reputation.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (c) 2018-2022 The Pocketnet developers -// Distributed under the Apache 2.0 software license, see the accompanying -// https://www.apache.org/licenses/LICENSE-2.0 - -#include "pocketdb/consensus/Reputation.h" - -namespace PocketConsensus -{ - using namespace std; - - // ------------------------------- - // Consensus checkpoint at 0 block - int64_t ReputationConsensus::GetMinLikers(int addressId) - { - return GetConsensusLimit(ConsensusLimit_threshold_likers_count); - } - - bool ReputationConsensus::AllowModifyReputation(int addressId) - { - auto minUserReputation = GetConsensusLimit(ConsensusLimit_threshold_reputation_score); - auto userReputation = PocketDb::ConsensusRepoInst.GetUserReputation(addressId); - if (userReputation < minUserReputation) - return false; - - auto minLikersCount = GetMinLikers(addressId); - auto userLikers = PocketDb::ConsensusRepoInst.GetUserLikersCount(addressId); - if (userLikers < minLikersCount) - return false; - - // All is OK - return true; - } - - tuple ReputationConsensus::SelectAddressScoreContent(shared_ptr& scoreData, bool lottery) - { - if (lottery) - return make_tuple(scoreData->ScoreAddressId, scoreData->ScoreAddressHash); - - return make_tuple(scoreData->ContentAddressId, scoreData->ContentAddressHash); - } - - bool ReputationConsensus::AllowModifyReputationOverPost(shared_ptr& scoreData, bool lottery) - { - auto[checkScoreAddressId, checkScoreAddressHash] = SelectAddressScoreContent(scoreData, lottery); - - // Check user reputation - if (!AllowModifyReputation(checkScoreAddressId)) - return false; - - // Disable reputation increment if from one address to one address > 2 scores over day - int64_t _max_scores_one_to_one = GetConsensusLimit(ConsensusLimit_scores_one_to_one); - int64_t _scores_one_to_one_depth = GetConsensusLimit(ConsensusLimit_scores_one_to_one_depth); - - std::vector values; - if (lottery) - { - values.push_back(4); - values.push_back(5); - } - else - { - values.push_back(1); - values.push_back(2); - values.push_back(3); - values.push_back(4); - values.push_back(5); - } - - auto scores_one_to_one_count = PocketDb::ConsensusRepoInst.GetScoreContentCount( - Height, scoreData, values, _scores_one_to_one_depth); - - if (scores_one_to_one_count >= _max_scores_one_to_one) - return false; - - // All its Ok! - return true; - } - - bool ReputationConsensus::AllowModifyReputationOverComment(shared_ptr& scoreData, bool lottery) - { - // Check user reputation - if (!AllowModifyReputation(scoreData->ScoreAddressId)) - return false; - - // Disable reputation increment if from one address to one address > Limit::scores_one_to_one scores over Limit::scores_one_to_one_depth - int64_t _max_scores_one_to_one = GetConsensusLimit(ConsensusLimit_scores_one_to_one_over_comment); - int64_t _scores_one_to_one_depth = GetConsensusLimit(ConsensusLimit_scores_one_to_one_depth); - - std::vector values; - if (lottery) - { - values.push_back(1); - } - else - { - values.push_back(-1); - values.push_back(1); - } - - auto scores_one_to_one_count = PocketDb::ConsensusRepoInst.GetScoreCommentCount( - Height, scoreData, values, _scores_one_to_one_depth); - - if (scores_one_to_one_count >= _max_scores_one_to_one) - return false; - - // All its Ok! - return true; - } - - AccountMode ReputationConsensus::GetAccountMode(int reputation, int64_t balance) - { - if (reputation >= GetConsensusLimit(ConsensusLimit_threshold_reputation) || - balance >= GetConsensusLimit(ConsensusLimit_threshold_balance)) - return AccountMode_Full; - else - return AccountMode_Trial; - } - tuple ReputationConsensus::GetAccountMode(string& address) - { - auto reputation = PocketDb::ConsensusRepoInst.GetUserReputation(address); - auto balance = PocketDb::ConsensusRepoInst.GetUserBalance(address); - - return {GetAccountMode(reputation, balance), reputation, balance}; - } - - bool ReputationConsensus::AllowModifyReputation(shared_ptr& scoreData, bool lottery) - { - if (scoreData->ScoreType == TxType::ACTION_SCORE_CONTENT) - return AllowModifyReputationOverPost(scoreData, lottery); - - if (scoreData->ScoreType == TxType::ACTION_SCORE_COMMENT) - return AllowModifyReputationOverComment(scoreData, lottery); - - return false; - } - - bool ReputationConsensus::AllowModifyOldPosts(int64_t scoreTime, int64_t contentTime, TxType contentType) - { - switch (contentType) - { - case CONTENT_POST: - case CONTENT_VIDEO: - case CONTENT_ARTICLE: - // case CONTENT_SERVERPING: - return (scoreTime - contentTime) < GetConsensusLimit(ConsensusLimit_scores_depth_modify_reputation); - default: - return true; - } - } - - void ReputationConsensus::PrepareAccountLikers(map>& accountLikersSrc, map>& accountLikers) - { - for (const auto& account : accountLikersSrc) - { - for (const auto& likerId : account.second) - { - if (!PocketDb::RatingsRepoInst.ExistsLiker(account.first, likerId, Height)) - { - accountLikers[account.first].clear(); - accountLikers[account.first].emplace_back(likerId); - } - } - } - } - - // ------------------------------------ - // Consensus checkpoint at 151600 block - tuple ReputationConsensus_checkpoint_151600::SelectAddressScoreContent(shared_ptr& scoreData, bool lottery) - { - return make_tuple(scoreData->ScoreAddressId, scoreData->ScoreAddressHash); - } - - // ------------------------------------- - // Consensus checkpoint at 1180000 block - int64_t ReputationConsensus_checkpoint_1180000::GetMinLikers(int addressId) - { - auto minLikersCount = GetConsensusLimit(ConsensusLimit_threshold_likers_count); - auto accountRegistrationHeight = PocketDb::ConsensusRepoInst.GetAccountRegistrationHeight(addressId); - if (Height - accountRegistrationHeight > GetConsensusLimit(ConsensusLimit_threshold_low_likers_depth)) - minLikersCount = GetConsensusLimit(ConsensusLimit_threshold_low_likers_count); - - return minLikersCount; - } - - // ------------------------------------- - // Consensus checkpoint at 1324655 block - AccountMode ReputationConsensus_checkpoint_1324655::GetAccountMode(int reputation, int64_t balance) - { - if (reputation >= GetConsensusLimit(ConsensusLimit_threshold_reputation) - || balance >= GetConsensusLimit(ConsensusLimit_threshold_balance)) - { - if (balance >= GetConsensusLimit(ConsensusLimit_threshold_balance_pro)) - return AccountMode_Pro; - else - return AccountMode_Full; - } - else - { - return AccountMode_Trial; - } - } - - // --------------------------------------- - // Consensus checkpoint at 1324655_2 block - void ReputationConsensus_checkpoint_1324655_2::PrepareAccountLikers(map>& accountLikersSrc, - map>& accountLikers) - { - for (const auto& account : accountLikersSrc) - for (const auto& likerId : account.second) - if (!PocketDb::RatingsRepoInst.ExistsLiker(account.first, likerId, Height)) - accountLikers[account.first].emplace_back(likerId); - } - - // -------------------------------------- - ReputationConsensusFactory ReputationConsensusFactoryInst; - -} \ No newline at end of file diff --git a/src/pocketdb/consensus/Reputation.h b/src/pocketdb/consensus/Reputation.h index de095e86e..31e6bb3df 100644 --- a/src/pocketdb/consensus/Reputation.h +++ b/src/pocketdb/consensus/Reputation.h @@ -16,71 +16,274 @@ namespace PocketConsensus class ReputationConsensus : public BaseConsensus { protected: - virtual int64_t GetMinLikers(int addressId); - virtual bool AllowModifyReputation(int addressId); - virtual tuple SelectAddressScoreContent(shared_ptr& scoreData, bool lottery); - virtual bool AllowModifyReputationOverPost(shared_ptr& scoreData, bool lottery); - virtual bool AllowModifyReputationOverComment(shared_ptr& scoreData, bool lottery); + virtual int64_t GetMinLikers(int64_t registrationHeight) + { + return GetConsensusLimit(ConsensusLimit_threshold_likers_count); + } + + virtual string SelectAddressScoreContent(shared_ptr& scoreData, bool lottery) + { + if (lottery) + return scoreData->ScoreAddressHash; + + return scoreData->ContentAddressHash; + } + + virtual bool AllowModifyReputationOverPost(shared_ptr& scoreData, bool lottery) + { + // Check user reputation + if (!IsShark(SelectAddressScoreContent(scoreData, lottery), ConsensusLimit_threshold_reputation_score)) + return false; + + // Disable reputation increment if from one address to one address > 2 scores over day + int64_t _max_scores_one_to_one = GetConsensusLimit(ConsensusLimit_scores_one_to_one); + int64_t _scores_one_to_one_depth = GetConsensusLimit(ConsensusLimit_scores_one_to_one_depth); + + std::vector values; + if (lottery) + { + values.push_back(4); + values.push_back(5); + } + else + { + values.push_back(1); + values.push_back(2); + values.push_back(3); + values.push_back(4); + values.push_back(5); + } + + auto scores_one_to_one_count = PocketDb::ConsensusRepoInst.GetScoreContentCount( + Height, scoreData, values, _scores_one_to_one_depth); + + if (scores_one_to_one_count >= _max_scores_one_to_one) + return false; + + // All its Ok! + return true; + } + + virtual bool AllowModifyReputationOverComment(shared_ptr& scoreData, bool lottery) + { + // Check user reputation + if (!IsShark(scoreData->ScoreAddressHash, ConsensusLimit_threshold_reputation_score)) + return false; + + // Disable reputation increment if from one address to one address > Limit::scores_one_to_one scores over Limit::scores_one_to_one_depth + int64_t _max_scores_one_to_one = GetConsensusLimit(ConsensusLimit_scores_one_to_one_over_comment); + int64_t _scores_one_to_one_depth = GetConsensusLimit(ConsensusLimit_scores_one_to_one_depth); + + vector values; + if (lottery) + { + values.push_back(1); + } + else + { + values.push_back(-1); + values.push_back(1); + } + + auto scores_one_to_one_count = PocketDb::ConsensusRepoInst.GetScoreCommentCount( + Height, scoreData, values, _scores_one_to_one_depth); + + if (scores_one_to_one_count >= _max_scores_one_to_one) + return false; + + // All its Ok! + return true; + } public: explicit ReputationConsensus(int height) : BaseConsensus(height) {} - virtual AccountMode GetAccountMode(int reputation, int64_t balance); - virtual tuple GetAccountMode(string& address); - virtual bool AllowModifyReputation(shared_ptr& scoreData, bool lottery); - virtual bool AllowModifyOldPosts(int64_t scoreTime, int64_t contentTime, TxType contentType); - virtual void PrepareAccountLikers(map>& accountLikersSrc, map>& accountLikers); + virtual bool IsShark(const AccountData& accountData, ConsensusLimit limit = ConsensusLimit_threshold_reputation) + { + auto minReputation = GetConsensusLimit(limit); + auto minLikersCount = GetMinLikers(accountData.RegistrationHeight); + + return accountData.Reputation >= minReputation && accountData.LikersCount >= minLikersCount; + } + + virtual bool IsShark(const string& address, ConsensusLimit limit = ConsensusLimit_threshold_reputation) + { + auto accountData = ConsensusRepoInst.GetAccountData(address); + return IsShark(accountData, limit); + } + + virtual AccountMode GetAccountMode(int reputation, int64_t balance) + { + if (reputation >= GetConsensusLimit(ConsensusLimit_threshold_reputation) || + balance >= GetConsensusLimit(ConsensusLimit_threshold_balance)) + return AccountMode_Full; + else + return AccountMode_Trial; + } + + virtual tuple GetAccountMode(string& address) + { + auto reputation = PocketDb::ConsensusRepoInst.GetUserReputation(address); + auto balance = PocketDb::ConsensusRepoInst.GetUserBalance(address); + + return {GetAccountMode(reputation, balance), reputation, balance}; + } + + virtual bool AllowModifyReputation(shared_ptr& scoreData, bool lottery) + { + if (scoreData->ScoreType == TxType::ACTION_SCORE_CONTENT) + return AllowModifyReputationOverPost(scoreData, lottery); + + if (scoreData->ScoreType == TxType::ACTION_SCORE_COMMENT) + return AllowModifyReputationOverComment(scoreData, lottery); + + return false; + } + + virtual bool AllowModifyOldPosts(int64_t scoreTime, int64_t contentTime, TxType contentType) + { + switch (contentType) + { + case CONTENT_POST: + case CONTENT_VIDEO: + case CONTENT_ARTICLE: + return (scoreTime - contentTime) < GetConsensusLimit(ConsensusLimit_scores_depth_modify_reputation); + default: + return true; + } + } + + virtual void PrepareAccountLikers(map>& accountLikersSrc, map>& accountLikers) + { + for (const auto& account : accountLikersSrc) + { + for (const auto& likerId : account.second) + { + if (!PocketDb::RatingsRepoInst.ExistsLiker(account.first, likerId, Height)) + { + accountLikers[account.first].clear(); + accountLikers[account.first].emplace_back(likerId); + } + } + } + } + + virtual int GetScoreContentAuthorValue(int scoreValue) + { + return (scoreValue - 3) * 10; + } + + virtual int GetScoreCommentAuthorValue(int scoreValue) + { + return scoreValue; + } }; - // ------------------------------------------ // Consensus checkpoint at 151600 block class ReputationConsensus_checkpoint_151600 : public ReputationConsensus { public: explicit ReputationConsensus_checkpoint_151600(int height) : ReputationConsensus(height) {} protected: - tuple SelectAddressScoreContent(shared_ptr& scoreData, bool lottery) override; + string SelectAddressScoreContent(shared_ptr& scoreData, bool lottery) override + { + return scoreData->ScoreAddressHash; + } }; - // ------------------------------------------ // Consensus checkpoint at 1180000 block class ReputationConsensus_checkpoint_1180000 : public ReputationConsensus_checkpoint_151600 { public: explicit ReputationConsensus_checkpoint_1180000(int height) : ReputationConsensus_checkpoint_151600(height) {} protected: - int64_t GetMinLikers(int addressId) override; + int64_t GetMinLikers(int64_t registrationHeight) override + { + if (Height - registrationHeight > GetConsensusLimit(ConsensusLimit_threshold_low_likers_depth)) + return GetConsensusLimit(ConsensusLimit_threshold_low_likers_count); + + return GetConsensusLimit(ConsensusLimit_threshold_likers_count); + } }; - // ------------------------------------------ // Consensus checkpoint at 1324655 block class ReputationConsensus_checkpoint_1324655 : public ReputationConsensus_checkpoint_1180000 { public: explicit ReputationConsensus_checkpoint_1324655(int height) : ReputationConsensus_checkpoint_1180000(height) {} - AccountMode GetAccountMode(int reputation, int64_t balance) override; + AccountMode GetAccountMode(int reputation, int64_t balance) override + { + if (reputation >= GetConsensusLimit(ConsensusLimit_threshold_reputation) + || balance >= GetConsensusLimit(ConsensusLimit_threshold_balance)) + { + if (balance >= GetConsensusLimit(ConsensusLimit_threshold_balance_pro)) + return AccountMode_Pro; + else + return AccountMode_Full; + } + else + { + return AccountMode_Trial; + } + } }; - // ------------------------------------------ // Consensus checkpoint at 1324655_2 block class ReputationConsensus_checkpoint_1324655_2 : public ReputationConsensus_checkpoint_1324655 { public: explicit ReputationConsensus_checkpoint_1324655_2(int height) : ReputationConsensus_checkpoint_1324655(height) {} - void PrepareAccountLikers(map>& accountLikersSrc, map>& accountLikers) override; + void PrepareAccountLikers(map>& accountLikersSrc, map>& accountLikers) override + { + for (const auto& account : accountLikersSrc) + for (const auto& likerId : account.second) + if (!PocketDb::RatingsRepoInst.ExistsLiker(account.first, likerId, Height)) + accountLikers[account.first].emplace_back(likerId); + } }; - // ------------------------------------------ + // Consensus checkpoint: reducing the impact on the reputation of scores 1,2 for content + class ReputationConsensus_checkpoint_scores_content_author_reducing_impact : public ReputationConsensus_checkpoint_1324655_2 + { + public: + explicit ReputationConsensus_checkpoint_scores_content_author_reducing_impact(int height) : ReputationConsensus_checkpoint_1324655_2(height) {} + int GetScoreContentAuthorValue(int scoreValue) override + { + int multiplier = 10; + if (scoreValue == 1 || scoreValue == 2) + multiplier = 1; + + return (scoreValue - 3) * multiplier; + } + }; + + // Consensus checkpoint: disable the impact on the reputation of scores -1 for comment + class ReputationConsensus_checkpoint_scores_comment_author_disable_impact : public ReputationConsensus_checkpoint_scores_content_author_reducing_impact + { + public: + explicit ReputationConsensus_checkpoint_scores_comment_author_disable_impact(int height) : ReputationConsensus_checkpoint_scores_content_author_reducing_impact(height) {} + int GetScoreCommentAuthorValue(int scoreValue) override + { + if (scoreValue == -1) + return 0; + + return scoreValue; + } + }; + + // Factory for select actual rules version class ReputationConsensusFactory { private: const vector> m_rules = { - {0, -1, [](int height) { return make_shared(height); }}, - {151600, -1, [](int height) { return make_shared(height); }}, - {1180000, 0, [](int height) { return make_shared(height); }}, - {1324655, 65000, [](int height) { return make_shared(height); }}, - {1324655, 75000, [](int height) { return make_shared(height); }}, + { 0, -1, [](int height) { return make_shared(height); }}, + { 151600, -1, [](int height) { return make_shared(height); }}, + { 1180000, 0, [](int height) { return make_shared(height); }}, + { 1324655, 65000, [](int height) { return make_shared(height); }}, + { 1324655, 75000, [](int height) { return make_shared(height); }}, + { 1700000, 761000, [](int height) { return make_shared(height); }}, + { 1700000, 772000, [](int height) { return make_shared(height); }}, }; public: shared_ptr Instance(int height) @@ -95,7 +298,7 @@ namespace PocketConsensus } }; - extern ReputationConsensusFactory ReputationConsensusFactoryInst; + static ReputationConsensusFactory ReputationConsensusFactoryInst; } #endif // POCKETCONSENSUS_REPUTATION_H \ No newline at end of file diff --git a/src/pocketdb/consensus/Social.h b/src/pocketdb/consensus/Social.h index b29e0bb14..044a9f88d 100644 --- a/src/pocketdb/consensus/Social.h +++ b/src/pocketdb/consensus/Social.h @@ -2,8 +2,8 @@ // Distributed under the Apache 2.0 software license, see the accompanying // https://www.apache.org/licenses/LICENSE-2.0 -#ifndef POCKETCONSENSUS_SOCIALT_H -#define POCKETCONSENSUS_SOCIALT_H +#ifndef POCKETCONSENSUS_SOCIAL_H +#define POCKETCONSENSUS_SOCIAL_H #include @@ -135,4 +135,4 @@ namespace PocketConsensus }; } -#endif // POCKETCONSENSUS_SOCIALT_H +#endif // POCKETCONSENSUS_SOCIAL_H diff --git a/src/pocketdb/consensus/moderation/Flag.hpp b/src/pocketdb/consensus/moderation/Flag.hpp new file mode 100644 index 000000000..a36a1f5c0 --- /dev/null +++ b/src/pocketdb/consensus/moderation/Flag.hpp @@ -0,0 +1,156 @@ +// Copyright (c) 2018-2022 The Pocketnet developers +// Distributed under the Apache 2.0 software license, see the accompanying +// https://www.apache.org/licenses/LICENSE-2.0 + +#ifndef POCKETCONSENSUS_MODERATION_FLAG_HPP +#define POCKETCONSENSUS_MODERATION_FLAG_HPP + +#include "pocketdb/consensus/Reputation.h" +#include "pocketdb/consensus/Social.h" +#include "pocketdb/models/dto/moderation/Flag.h" + +namespace PocketConsensus +{ + using namespace std; + using namespace PocketDb; + using namespace PocketConsensus; + typedef shared_ptr ModerationFlagRef; + + /******************************************************************************************************************* + * ModerationFlag consensus base class + *******************************************************************************************************************/ + class ModerationFlagConsensus : public SocialConsensus + { + public: + ModerationFlagConsensus(int height) : SocialConsensus(height) {} + + ConsensusValidateResult Validate(const CTransactionRef& tx, const ModerationFlagRef& ptx, const PocketBlockRef& block) override + { + // Base validation with calling block or mempool check + if (auto[baseValidate, baseValidateCode] = SocialConsensus::Validate(tx, ptx, block); !baseValidate) + return {false, baseValidateCode}; + + // Only `Shark` account can flag content + auto reputationConsensus = ReputationConsensusFactoryInst.Instance(Height); + if (!reputationConsensus->IsShark(*ptx->GetAddress())) + return {false, SocialConsensusResult_LowReputation}; + + // Target transaction must be a exists and is a content and author should be equals ptx->GetContentAddressHash() + if (!ConsensusRepoInst.ExistsNotDeleted( + *ptx->GetContentTxHash(), + *ptx->GetContentAddressHash(), + { ACCOUNT_USER, CONTENT_POST, CONTENT_ARTICLE, CONTENT_VIDEO, CONTENT_COMMENT, CONTENT_COMMENT_EDIT } + )) + return {false, SocialConsensusResult_NotFound}; + + return Success; + } + + ConsensusValidateResult Check(const CTransactionRef& tx, const ModerationFlagRef& ptx) override + { + return {false, SocialConsensusResult_NotAllowed}; + } + + protected: + + ConsensusValidateResult ValidateBlock(const ModerationFlagRef& ptx, const PocketBlockRef& block) override + { + // Check flag from one to one + if (ConsensusRepoInst.CountModerationFlag(*ptx->GetAddress(), *ptx->GetContentAddressHash(), false) > 0) + return {false, SocialConsensusResult_Duplicate}; + + // Count flags in chain + int count = ConsensusRepoInst.CountModerationFlag(*ptx->GetAddress(), Height - (int)GetConsensusLimit(ConsensusLimit_depth), false); + + // Count flags in block + for (auto& blockTx : *block) + { + if (!TransactionHelper::IsIn(*blockTx->GetType(), { MODERATION_FLAG }) || *blockTx->GetHash() == *ptx->GetHash()) + continue; + + auto blockPtx = static_pointer_cast(blockTx); + if (*ptx->GetAddress() == *blockPtx->GetAddress()) + if (*ptx->GetContentTxHash() == *blockPtx->GetContentTxHash()) + return {false, SocialConsensusResult_Duplicate}; + else + count += 1; + } + + // Check limit + return ValidateLimit(ptx, count); + } + + ConsensusValidateResult ValidateMempool(const ModerationFlagRef& ptx) override + { + // Check flag from one to one + if (ConsensusRepoInst.CountModerationFlag(*ptx->GetAddress(), *ptx->GetContentAddressHash(), true) > 0) + return {false, SocialConsensusResult_Duplicate}; + + // Check limit + return ValidateLimit(ptx, ConsensusRepoInst.CountModerationFlag(*ptx->GetAddress(), Height - (int)GetConsensusLimit(ConsensusLimit_depth), true)); + } + + vector GetAddressesForCheckRegistration(const ModerationFlagRef& ptx) override + { + return { *ptx->GetAddress(), *ptx->GetContentAddressHash() }; + } + + virtual ConsensusValidateResult ValidateLimit(const ModerationFlagRef& ptx, int count) + { + if (count >= GetConsensusLimit(ConsensusLimit_moderation_flag_count)) + return {false, SocialConsensusResult_ExceededLimit}; + + return Success; + } + }; + + /******************************************************************************************************************* + * Enable ModerationFlag consensus rules + *******************************************************************************************************************/ + class ModerationFlagConsensus_checkpoint_enable : public ModerationFlagConsensus + { + public: + ModerationFlagConsensus_checkpoint_enable(int height) : ModerationFlagConsensus(height) {} + protected: + ConsensusValidateResult Check(const CTransactionRef& tx, const ModerationFlagRef& ptx) override + { + if (auto[baseCheck, baseCheckCode] = SocialConsensus::Check(tx, ptx); !baseCheck) + return {false, baseCheckCode}; + + // Check required fields + if (IsEmpty(ptx->GetAddress())) return {false, SocialConsensusResult_Failed}; + if (IsEmpty(ptx->GetContentTxHash())) return {false, SocialConsensusResult_Failed}; + if (IsEmpty(ptx->GetContentAddressHash())) return {false, SocialConsensusResult_Failed}; + if (*ptx->GetAddress() == *ptx->GetContentAddressHash()) return {false, SocialConsensusResult_SelfFlag}; + if (IsEmpty(ptx->GetReason()) || *ptx->GetReason() < 1 || *ptx->GetReason() > 4) return {false, SocialConsensusResult_Failed}; + + return Success; + } + }; + + + /******************************************************************************************************************* + * Factory for select actual rules version + *******************************************************************************************************************/ + class ModerationFlagConsensusFactory + { + private: + const vector> m_rules = { + { 0, -1, [](int height) { return make_shared(height); }}, + { 1700000, 761000, [](int height) { return make_shared(height); }}, + }; + public: + shared_ptr Instance(int height) + { + int m_height = (height > 0 ? height : 0); + return (--upper_bound(m_rules.begin(), m_rules.end(), m_height, + [&](int target, const ConsensusCheckpoint& itm) + { + return target < itm.Height(Params().NetworkIDString()); + } + ))->m_func(height); + } + }; +} + +#endif // POCKETCONSENSUS_MODERATION_FLAG_HPP \ No newline at end of file diff --git a/src/pocketdb/consensus/social/Post.hpp b/src/pocketdb/consensus/social/Post.hpp index ae39afeae..37f3fa28e 100644 --- a/src/pocketdb/consensus/social/Post.hpp +++ b/src/pocketdb/consensus/social/Post.hpp @@ -304,7 +304,7 @@ namespace PocketConsensus class PostConsensusFactory { protected: - const vector> m_rules = { + const vector> m_rules = { { 0, -1, [](int height) { return make_shared(height); }}, { 1124000, -1, [](int height) { return make_shared(height); }}, { 1180000, -1, [](int height) { return make_shared(height); }}, diff --git a/src/pocketdb/helpers/PocketnetHelper.h b/src/pocketdb/helpers/PocketnetHelper.h index ff315f86a..50cfc839f 100644 --- a/src/pocketdb/helpers/PocketnetHelper.h +++ b/src/pocketdb/helpers/PocketnetHelper.h @@ -25,7 +25,8 @@ namespace PocketHelpers "PVJ1rRdS9y9sUpaBJc8quiSTJGrC3xW8EH", "PAF1BvWEH7pA24QbbEvCEasViC2Pw9BVj3", "PSADH5AY5M9RaWrDVdaMrR2C2s6dCGfNK4", - "PMyjUzHtzsmbejB87ATbrcQNatiGsT4NzG" + "PMyjUzHtzsmbejB87ATbrcQNatiGsT4NzG", + "PHdW4pwWbFdoofVhSEfPSHgradmrvZdbE5" }}, {"test", { "TG69Jioc81PiwMAJtRanfZqUmRY4TUG7nt", diff --git a/src/pocketdb/helpers/TransactionHelper.cpp b/src/pocketdb/helpers/TransactionHelper.cpp index 2f507dfbf..d562ba7cf 100644 --- a/src/pocketdb/helpers/TransactionHelper.cpp +++ b/src/pocketdb/helpers/TransactionHelper.cpp @@ -39,20 +39,19 @@ namespace PocketHelpers return TxType::CONTENT_VIDEO; else if (op == OR_ARTICLE) return TxType::CONTENT_ARTICLE; + else if (op == OR_CONTENT_BOOST) return TxType::BOOST_CONTENT; else if (op == OR_CONTENT_DELETE) return TxType::CONTENT_DELETE; - else if (op == OR_SCORE) - return TxType::ACTION_SCORE_CONTENT; - else if (op == OR_COMPLAIN) - return TxType::ACTION_COMPLAIN; + else if (op == OR_SUBSCRIBE) return TxType::ACTION_SUBSCRIBE; else if (op == OR_SUBSCRIBEPRIVATE) return TxType::ACTION_SUBSCRIBE_PRIVATE; else if (op == OR_UNSUBSCRIBE) return TxType::ACTION_SUBSCRIBE_CANCEL; + else if (op == OR_ACCOUNT_SETTING) return TxType::ACCOUNT_SETTING; else if (op == OR_USERINFO) @@ -61,18 +60,30 @@ namespace PocketHelpers return TxType::ACCOUNT_VIDEO_SERVER; else if (op == OR_MESSAGE_SERVER) return TxType::ACCOUNT_MESSAGE_SERVER; + else if (op == OR_BLOCKING) return TxType::ACTION_BLOCKING; else if (op == OR_UNBLOCKING) return TxType::ACTION_BLOCKING_CANCEL; + else if (op == OR_COMMENT) return TxType::CONTENT_COMMENT; else if (op == OR_COMMENT_EDIT) return TxType::CONTENT_COMMENT_EDIT; else if (op == OR_COMMENT_DELETE) return TxType::CONTENT_COMMENT_DELETE; + else if (op == OR_COMMENT_SCORE) return TxType::ACTION_SCORE_COMMENT; + else if (op == OR_SCORE) + return TxType::ACTION_SCORE_CONTENT; + + // MODERATION + else if (op == OR_COMPLAIN) + return TxType::ACTION_COMPLAIN; + + else if (op == OR_MODERATION_FLAG) + return TxType::MODERATION_FLAG; return TxType::TX_DEFAULT; } @@ -152,6 +163,8 @@ namespace PocketHelpers return "Subscribes"; case TxType::BOOST_CONTENT: return "Boosts"; + case TxType::MODERATION_FLAG: + return "ModFlag"; default: return ""; } @@ -326,6 +339,9 @@ namespace PocketHelpers case ACTION_COMPLAIN: ptx = make_shared(tx); break; + case MODERATION_FLAG: + ptx = make_shared(tx); + break; default: return nullptr; } @@ -401,6 +417,9 @@ namespace PocketHelpers case ACTION_COMPLAIN: ptx = make_shared(); break; + case MODERATION_FLAG: + ptx = make_shared(); + break; default: return nullptr; } @@ -421,36 +440,38 @@ namespace PocketHelpers { switch (type) { - case PocketTx::CONTENT_DELETE: + case CONTENT_DELETE: return "contentDelete"; - case PocketTx::CONTENT_POST: + case CONTENT_POST: return "share"; - case PocketTx::CONTENT_VIDEO: + case CONTENT_VIDEO: return "video"; - case PocketTx::CONTENT_ARTICLE: + case CONTENT_ARTICLE: return "article"; - case PocketTx::ACCOUNT_SETTING: + case ACCOUNT_SETTING: return "accSet"; - case PocketTx::ACTION_SCORE_CONTENT: + case ACTION_SCORE_CONTENT: return "upvoteShare"; - case PocketTx::ACTION_SUBSCRIBE: + case ACTION_SUBSCRIBE: return "subscribe"; - case PocketTx::ACTION_SUBSCRIBE_PRIVATE: + case ACTION_SUBSCRIBE_PRIVATE: return "subscribePrivate"; - case PocketTx::ACTION_SUBSCRIBE_CANCEL: + case ACTION_SUBSCRIBE_CANCEL: return "unsubscribe"; - case PocketTx::ACCOUNT_USER: + case ACCOUNT_USER: return "userInfo"; - case PocketTx::CONTENT_COMMENT: + case CONTENT_COMMENT: return "comment"; - case PocketTx::CONTENT_COMMENT_EDIT: + case CONTENT_COMMENT_EDIT: return "commentEdit"; - case PocketTx::CONTENT_COMMENT_DELETE: + case CONTENT_COMMENT_DELETE: return "commentDelete"; - case PocketTx::ACTION_SCORE_COMMENT: + case ACTION_SCORE_COMMENT: return "cScore"; - case PocketTx::BOOST_CONTENT: + case BOOST_CONTENT: return "contentBoost"; + case MODERATION_FLAG: + return "modFlag"; default: return ""; } @@ -473,6 +494,7 @@ namespace PocketHelpers else if (type == "commentDelete" || type == OR_COMMENT_DELETE) return TxType::CONTENT_COMMENT_DELETE; else if (type == "cScore" || type == OR_COMMENT_SCORE) return TxType::ACTION_SCORE_COMMENT; else if (type == "contentBoost" || type == OR_CONTENT_BOOST) return TxType::BOOST_CONTENT; + else if (type == "modFlag") return TxType::MODERATION_FLAG; else return TxType::NOT_SUPPORTED; } } \ No newline at end of file diff --git a/src/pocketdb/helpers/TransactionHelper.h b/src/pocketdb/helpers/TransactionHelper.h index e404d9df1..8e5ac5c38 100644 --- a/src/pocketdb/helpers/TransactionHelper.h +++ b/src/pocketdb/helpers/TransactionHelper.h @@ -38,6 +38,8 @@ #include "pocketdb/models/dto/ScoreComment.h" #include "pocketdb/models/dto/ContentDelete.h" +#include "pocketdb/models/dto/moderation/Flag.h" + namespace PocketHelpers { using namespace std; diff --git a/src/pocketdb/migrations/main.cpp b/src/pocketdb/migrations/main.cpp index b473b2fbf..105a3ead3 100644 --- a/src/pocketdb/migrations/main.cpp +++ b/src/pocketdb/migrations/main.cpp @@ -52,29 +52,31 @@ namespace PocketDb -- ContentVideo.RootTxHash -- ContentDelete.RootTxHash -- Comment.RootTxHash - -- ScorePost.PostTxHash - -- ScoreComment.CommentTxHash + -- ScorePost.ContentRootTxHash + -- ScoreComment.CommentRootTxHash -- Subscribe.AddressToHash -- Blocking.AddressToHash - -- Complain.PostTxHash - -- Boost.ContentTxHash + -- Complain.ContentRootTxHash + -- Boost.ContentRootTxHash + -- ModerationFlag.ContentTxHash String2 text null, - -- ContentPost.RelayTxHash - -- ContentVideo.RelayTxHash - -- Comment.PostTxHash + -- ContentPost.RelayRootTxHash + -- ContentVideo.RelayRootTxHash + -- Comment.ContentRootTxHash String3 text null, - -- Comment.ParentTxHash + -- Comment.ParentRootTxHash String4 text null, - -- Comment.AnswerTxHash + -- Comment.AnswerRootTxHash String5 text null, -- ScoreContent.Value -- ScoreComment.Value -- Complain.Reason -- Boost.Amount + -- ModerationFlag.Reason Int1 int null ); )sql"); @@ -121,7 +123,6 @@ namespace PocketDb -- ContentVideo.Url String7 text null, - -- Comment.Donate Int1 int null ); )sql"); @@ -173,23 +174,18 @@ namespace PocketDb ); )sql"); - - _preProcessing = R"sql( - - insert into TxInputs + _tables.emplace_back(R"sql( + create table if not exists System ( - SpentTxHash, - TxHash, - Number - ) - select - o.SpentTxHash, - o.TxHash, - o.Number - from TxOutputs o indexed by TxOutputs_SpentTxHash - where o.SpentTxHash is not null - and not exists (select i.ROWID from TxInputs i) + Db text not null, + Version int not null, + primary key (Db) + ); + )sql"); + + _preProcessing = R"sql( + insert or ignore into System (Db, Version) values ('main', 0); )sql"; @@ -213,6 +209,7 @@ namespace PocketDb create index if not exists Transactions_Type_Last_Height_String5_String1 on Transactions (Type, Last, Height, String5, String1); create index if not exists Transactions_Type_Last_Height_Id on Transactions (Type, Last, Height, Id); create index if not exists Transactions_Type_String1_String2_Height on Transactions (Type, String1, String2, Height); + create index if not exists Transactions_Type_String1_String3_Height on Transactions (Type, String1, String3, Height); create index if not exists Transactions_Type_String1_Height_Time_Int1 on Transactions (Type, String1, Height, Time, Int1); create index if not exists Transactions_String1_Last_Height on Transactions (String1, Last, Height); create index if not exists Transactions_Last_Id_Height on Transactions (Last, Id, Height); diff --git a/src/pocketdb/models/base/Base.cpp b/src/pocketdb/models/base/Base.cpp index f73308bc6..32176a0f8 100644 --- a/src/pocketdb/models/base/Base.cpp +++ b/src/pocketdb/models/base/Base.cpp @@ -60,4 +60,13 @@ namespace PocketTx return make_tuple(false, 0); } + + tuple Base::TryGetObj(const UniValue& o, const string& key) + { + auto exists = o.exists(key); + if (exists && o[key].isObject() && !o[key].empty()) + return make_tuple(true, o[key]); + + return make_tuple(false, NullUniValue); + } } \ No newline at end of file diff --git a/src/pocketdb/models/base/Base.h b/src/pocketdb/models/base/Base.h index 9f56325fb..202dc78a8 100644 --- a/src/pocketdb/models/base/Base.h +++ b/src/pocketdb/models/base/Base.h @@ -22,6 +22,7 @@ namespace PocketTx tuple TryGetStr(const UniValue& o, const string& key); tuple TryGetInt(const UniValue& o, const string& key); tuple TryGetInt64(const UniValue& o, const string& key); + tuple TryGetObj(const UniValue& o, const string& key); }; } diff --git a/src/pocketdb/models/base/Payload.cpp b/src/pocketdb/models/base/Payload.cpp index bc929b4ae..010b31510 100644 --- a/src/pocketdb/models/base/Payload.cpp +++ b/src/pocketdb/models/base/Payload.cpp @@ -8,31 +8,31 @@ namespace PocketTx { Payload::Payload() {} - shared_ptr Payload::GetTxHash() const { return m_txHash; } + shared_ptr Payload::GetTxHash() const { return m_txHash; } void Payload::SetTxHash(string value) { m_txHash = make_shared(value); } - shared_ptr Payload::GetString1() const { return m_string1; } + shared_ptr Payload::GetString1() const { return m_string1; } void Payload::SetString1(string value) { m_string1 = make_shared(value); } - shared_ptr Payload::GetString2() const { return m_string2; } + shared_ptr Payload::GetString2() const { return m_string2; } void Payload::SetString2(string value) { m_string2 = make_shared(value); } - shared_ptr Payload::GetString3() const { return m_string3; } + shared_ptr Payload::GetString3() const { return m_string3; } void Payload::SetString3(string value) { m_string3 = make_shared(value); } - shared_ptr Payload::GetString4() const { return m_string4; } + shared_ptr Payload::GetString4() const { return m_string4; } void Payload::SetString4(string value) { m_string4 = make_shared(value); } - shared_ptr Payload::GetString5() const { return m_string5; } + shared_ptr Payload::GetString5() const { return m_string5; } void Payload::SetString5(string value) { m_string5 = make_shared(value); } - shared_ptr Payload::GetString6() const { return m_string6; } + shared_ptr Payload::GetString6() const { return m_string6; } void Payload::SetString6(string value) { m_string6 = make_shared(value); } - shared_ptr Payload::GetString7() const { return m_string7; } + shared_ptr Payload::GetString7() const { return m_string7; } void Payload::SetString7(string value) { m_string7 = make_shared(value); } - shared_ptr Payload::GetInt1() const { return m_int1; } - void Payload::SetInt1(int value) { m_int1 = make_shared(value); } + shared_ptr Payload::GetInt1() const { return m_int1; } + void Payload::SetInt1(int64_t value) { m_int1 = make_shared(value); } } // namespace PocketTx \ No newline at end of file diff --git a/src/pocketdb/models/base/Payload.h b/src/pocketdb/models/base/Payload.h index 24bc88e02..fe9f3e4b2 100644 --- a/src/pocketdb/models/base/Payload.h +++ b/src/pocketdb/models/base/Payload.h @@ -40,8 +40,8 @@ namespace PocketTx shared_ptr GetString7() const; void SetString7(string value); - shared_ptr GetInt1() const; - void SetInt1(int value); + shared_ptr GetInt1() const; + void SetInt1(int64_t value); protected: @@ -53,7 +53,7 @@ namespace PocketTx shared_ptr m_string5 = nullptr; shared_ptr m_string6 = nullptr; shared_ptr m_string7 = nullptr; - shared_ptr m_int1 = nullptr; + shared_ptr m_int1 = nullptr; }; diff --git a/src/pocketdb/models/base/PocketTypes.h b/src/pocketdb/models/base/PocketTypes.h index e05c51144..2aa5b27bd 100644 --- a/src/pocketdb/models/base/PocketTypes.h +++ b/src/pocketdb/models/base/PocketTypes.h @@ -42,16 +42,17 @@ namespace PocketTx #define OR_SERVER_PING "73657276657250696e67" // Server ping over Posts #define OR_CONTENT_DELETE "636f6e74656e7444656c657465" // Deleting content - #define OR_CONTENT_BOOST "636f6e74656e74426f6f7374" // Boost content - #define OR_ACCOUNT_SETTING "616363536574" // Public account settings (accSet) + #define OR_MODERATION_FLAG "6d6f64466c6167" // Flag for moderation + + // Int tx type enum TxType { NOT_SUPPORTED = 0, - + TX_DEFAULT = 1, TX_COINBASE = 2, TX_COINSTAKE = 3, @@ -85,6 +86,11 @@ namespace PocketTx ACTION_BLOCKING_CANCEL = 306, ACTION_COMPLAIN = 307, + + MODERATOR_REQUEST = 400, // Some users have the right to choose a moderator + MODERATOR_REGISTER = 401, // Each moderator must define a list of public key hashes for voting + MODERATION_FLAG = 410, // Flags are used to mark content that needs moderation + MODERATION_VOTE = 420, // Votes is used by moderators in the jury process }; // Rating types diff --git a/src/pocketdb/models/base/SocialTransaction.cpp b/src/pocketdb/models/base/SocialTransaction.cpp new file mode 100644 index 000000000..a99ace7f7 --- /dev/null +++ b/src/pocketdb/models/base/SocialTransaction.cpp @@ -0,0 +1,86 @@ +// Copyright (c) 2018-2022 The Pocketnet developers +// Distributed under the Apache 2.0 software license, see the accompanying +// https://www.apache.org/licenses/LICENSE-2.0 + +#include "pocketdb/models/base/SocialTransaction.h" + +namespace PocketTx +{ + SocialTransaction::SocialTransaction() : Transaction() + { + } + + SocialTransaction::SocialTransaction(const CTransactionRef& tx) : Transaction(tx) + { + } + + shared_ptr SocialTransaction::Serialize() const + { + auto result = Transaction::Serialize(); + + if (GetString1()) result->pushKV("s1", *GetString1()); + if (GetString2()) result->pushKV("s2", *GetString2()); + if (GetString3()) result->pushKV("s3", *GetString3()); + if (GetString4()) result->pushKV("s4", *GetString4()); + if (GetString5()) result->pushKV("s5", *GetString5()); + if (GetInt1()) result->pushKV("i1", *GetInt1()); + + if (m_payload) + { + UniValue payload(UniValue::VOBJ); + + if (m_payload->GetTxHash()) payload.pushKV("h", *m_payload->GetTxHash()); + if (m_payload->GetString1()) payload.pushKV("s1", *m_payload->GetString1()); + if (m_payload->GetString2()) payload.pushKV("s2", *m_payload->GetString2()); + if (m_payload->GetString3()) payload.pushKV("s3", *m_payload->GetString3()); + if (m_payload->GetString4()) payload.pushKV("s4", *m_payload->GetString4()); + if (m_payload->GetString5()) payload.pushKV("s5", *m_payload->GetString5()); + if (m_payload->GetString6()) payload.pushKV("s6", *m_payload->GetString6()); + if (m_payload->GetString7()) payload.pushKV("s7", *m_payload->GetString7()); + if (m_payload->GetInt1()) payload.pushKV("i1", *m_payload->GetInt1()); + + if (!payload.empty()) + result->pushKV("p", payload); + } + + return result; + } + + void SocialTransaction::Deserialize(const UniValue& src) + { + Transaction::Deserialize(src); + + // Deserialize all general fields + if (auto[ok, val] = TryGetStr(src, "s1"); ok) SetString1(val); + if (auto[ok, val] = TryGetStr(src, "s2"); ok) SetString2(val); + if (auto[ok, val] = TryGetStr(src, "s3"); ok) SetString3(val); + if (auto[ok, val] = TryGetStr(src, "s4"); ok) SetString4(val); + if (auto[ok, val] = TryGetStr(src, "s5"); ok) SetString5(val); + if (auto[ok, val] = TryGetInt64(src, "i1"); ok) SetInt1(val); + + // Deserialize payload part if exists non-empty "p" object + if (auto[pOk, pVal] = TryGetObj(src, "p"); pOk) + { + m_payload = make_shared(); + if (auto[ok, val] = TryGetStr(pVal, "h"); ok) m_payload->SetTxHash(val); + if (auto[ok, val] = TryGetStr(pVal, "s1"); ok) m_payload->SetString1(val); + if (auto[ok, val] = TryGetStr(pVal, "s2"); ok) m_payload->SetString2(val); + if (auto[ok, val] = TryGetStr(pVal, "s3"); ok) m_payload->SetString3(val); + if (auto[ok, val] = TryGetStr(pVal, "s4"); ok) m_payload->SetString4(val); + if (auto[ok, val] = TryGetStr(pVal, "s5"); ok) m_payload->SetString5(val); + if (auto[ok, val] = TryGetStr(pVal, "s6"); ok) m_payload->SetString6(val); + if (auto[ok, val] = TryGetStr(pVal, "s7"); ok) m_payload->SetString7(val); + if (auto[ok, val] = TryGetInt64(pVal, "i1"); ok) m_payload->SetInt1(val); + } + } + + void SocialTransaction::DeserializeRpc(const UniValue& src) + { + Deserialize(src); + } + + shared_ptr SocialTransaction::GetAddress() const { return m_string1; } + void SocialTransaction::SetAddress(const string& value) { m_string1 = make_shared(value); } + +} // namespace PocketTx + diff --git a/src/pocketdb/models/base/SocialTransaction.h b/src/pocketdb/models/base/SocialTransaction.h new file mode 100644 index 000000000..3f002ec51 --- /dev/null +++ b/src/pocketdb/models/base/SocialTransaction.h @@ -0,0 +1,29 @@ +// Copyright (c) 2018-2022 The Pocketnet developers +// Distributed under the Apache 2.0 software license, see the accompanying +// https://www.apache.org/licenses/LICENSE-2.0 + +#ifndef POCKETTX_SOCIAL_TRANSACTION_H +#define POCKETTX_SOCIAL_TRANSACTION_H + +#include "pocketdb/models/base/Transaction.h" + +namespace PocketTx +{ + class SocialTransaction : public Transaction + { + public: + SocialTransaction(); + SocialTransaction(const CTransactionRef& tx); + + shared_ptr Serialize() const override; + void Deserialize(const UniValue& src) override; + void DeserializeRpc(const UniValue& src) override; + + shared_ptr GetAddress() const; + void SetAddress(const string& value); + + }; // class SocialTransaction + +} // namespace PocketTx + +#endif // POCKETTX_SOCIAL_TRANSACTION_H diff --git a/src/pocketdb/models/base/Transaction.cpp b/src/pocketdb/models/base/Transaction.cpp index 71cbea683..d659e3662 100644 --- a/src/pocketdb/models/base/Transaction.cpp +++ b/src/pocketdb/models/base/Transaction.cpp @@ -2,7 +2,6 @@ // Distributed under the Apache 2.0 software license, see the accompanying // https://www.apache.org/licenses/LICENSE-2.0 -#include #include "pocketdb/models/base/Transaction.h" namespace PocketTx @@ -12,16 +11,17 @@ namespace PocketTx { } - Transaction::Transaction(const std::shared_ptr& tx) : Base() + Transaction::Transaction(const CTransactionRef& tx) : Base() { SetHash(tx->GetHash().GetHex()); SetTime(tx->nTime); } - shared_ptr Transaction::Serialize() const + shared_ptr Transaction::Serialize() const { auto result = make_shared(UniValue(UniValue::VOBJ)); + // TODO (brangr): remove safe? result->pushKV("txid", *GetHash()); result->pushKV("time", *GetTime()); result->pushKV("block", 0); @@ -39,14 +39,14 @@ namespace PocketTx GeneratePayload(); } - shared_ptr Transaction::GetHash() const { return m_hash; } + shared_ptr Transaction::GetHash() const { return m_hash; } void Transaction::SetHash(string value) { m_hash = make_shared(value); } bool Transaction::operator==(const string& hash) const { return *m_hash == hash; } - shared_ptr Transaction::GetType() const { return m_type; } + shared_ptr Transaction::GetType() const { return m_type; } void Transaction::SetType(TxType value) { m_type = make_shared(value); } - shared_ptr Transaction::GetTime() const { return m_time; } + shared_ptr Transaction::GetTime() const { return m_time; } void Transaction::SetTime(int64_t value) { m_time = make_shared(value); } shared_ptr Transaction::GetHeight() const { return m_height; } @@ -58,32 +58,32 @@ namespace PocketTx shared_ptr Transaction::GetLast() const { return m_last; } void Transaction::SetLast(bool value) { m_last = make_shared(value); } - shared_ptr Transaction::GetString1() const { return m_string1; } + shared_ptr Transaction::GetString1() const { return m_string1; } void Transaction::SetString1(string value) { m_string1 = make_shared(value); } - shared_ptr Transaction::GetString2() const { return m_string2; } + shared_ptr Transaction::GetString2() const { return m_string2; } void Transaction::SetString2(string value) { m_string2 = make_shared(value); } - shared_ptr Transaction::GetString3() const { return m_string3; } + shared_ptr Transaction::GetString3() const { return m_string3; } void Transaction::SetString3(string value) { m_string3 = make_shared(value); } - shared_ptr Transaction::GetString4() const { return m_string4; } + shared_ptr Transaction::GetString4() const { return m_string4; } void Transaction::SetString4(string value) { m_string4 = make_shared(value); } - shared_ptr Transaction::GetString5() const { return m_string5; } + shared_ptr Transaction::GetString5() const { return m_string5; } void Transaction::SetString5(string value) { m_string5 = make_shared(value); } - shared_ptr Transaction::GetInt1() const { return m_int1; } + shared_ptr Transaction::GetInt1() const { return m_int1; } void Transaction::SetInt1(int64_t value) { m_int1 = make_shared(value); } - shared_ptr Transaction::GetId() const { return m_id; } + shared_ptr Transaction::GetId() const { return m_id; } void Transaction::SetId(int64_t value) { m_id = make_shared(value); } vector >& Transaction::Inputs() { return m_inputs; } vector >& Transaction::Outputs() { return m_outputs; } const vector >& Transaction::OutputsConst() const { return m_outputs; } - shared_ptr Transaction::GetPayload() const { return m_payload; } + shared_ptr Transaction::GetPayload() const { return m_payload; } void Transaction::SetPayload(Payload value) { m_payload = make_shared(value); } bool Transaction::HasPayload() const { return m_payload != nullptr; }; diff --git a/src/pocketdb/models/base/Transaction.h b/src/pocketdb/models/base/Transaction.h index f561c53cf..41917a725 100644 --- a/src/pocketdb/models/base/Transaction.h +++ b/src/pocketdb/models/base/Transaction.h @@ -24,8 +24,7 @@ namespace PocketTx { public: Transaction(); - - explicit Transaction(const std::shared_ptr& tx); + Transaction(const CTransactionRef& tx); virtual shared_ptr Serialize() const; @@ -34,7 +33,6 @@ namespace PocketTx virtual void DeserializePayload(const UniValue& src); virtual string BuildHash() = 0; - virtual void SetAddress(const string& value) {} shared_ptr GetHash() const; void SetHash(string value); diff --git a/src/pocketdb/models/dto/AccountSetting.h b/src/pocketdb/models/dto/AccountSetting.h index 274d8689b..ce3faa3ae 100644 --- a/src/pocketdb/models/dto/AccountSetting.h +++ b/src/pocketdb/models/dto/AccountSetting.h @@ -22,7 +22,7 @@ namespace PocketTx void DeserializePayload(const UniValue& src) override; shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetPayloadData() const; diff --git a/src/pocketdb/models/dto/Blocking.h b/src/pocketdb/models/dto/Blocking.h index 680e301db..3d6d96db4 100644 --- a/src/pocketdb/models/dto/Blocking.h +++ b/src/pocketdb/models/dto/Blocking.h @@ -23,7 +23,7 @@ namespace PocketTx void DeserializePayload(const UniValue& src) override; shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetAddressTo() const; void SetAddressTo(const string& value); diff --git a/src/pocketdb/models/dto/BoostContent.h b/src/pocketdb/models/dto/BoostContent.h index 9f6044b95..a535828e7 100644 --- a/src/pocketdb/models/dto/BoostContent.h +++ b/src/pocketdb/models/dto/BoostContent.h @@ -23,7 +23,7 @@ namespace PocketTx void DeserializePayload(const UniValue& src) override; shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetContentTxHash() const; void SetContentTxHash(const string& value); diff --git a/src/pocketdb/models/dto/Comment.h b/src/pocketdb/models/dto/Comment.h index 9e87a6370..b5aaec3b1 100644 --- a/src/pocketdb/models/dto/Comment.h +++ b/src/pocketdb/models/dto/Comment.h @@ -22,7 +22,7 @@ namespace PocketTx void DeserializePayload(const UniValue& src) override; shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetRootTxHash() const; void SetRootTxHash(const string& value); diff --git a/src/pocketdb/models/dto/Complain.h b/src/pocketdb/models/dto/Complain.h index b8e312349..5884f38b1 100644 --- a/src/pocketdb/models/dto/Complain.h +++ b/src/pocketdb/models/dto/Complain.h @@ -23,7 +23,7 @@ namespace PocketTx void DeserializePayload(const UniValue& src) override; shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetPostTxHash() const; void SetPostTxHash(const string& value); diff --git a/src/pocketdb/models/dto/Content.h b/src/pocketdb/models/dto/Content.h index dd1b7dc3c..371ac0b29 100644 --- a/src/pocketdb/models/dto/Content.h +++ b/src/pocketdb/models/dto/Content.h @@ -18,7 +18,7 @@ namespace PocketTx Content(const CTransactionRef& tx); shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetRootTxHash() const; void SetRootTxHash(const string& value); diff --git a/src/pocketdb/models/dto/ScoreComment.h b/src/pocketdb/models/dto/ScoreComment.h index f6ca73957..5bf7ad9f3 100644 --- a/src/pocketdb/models/dto/ScoreComment.h +++ b/src/pocketdb/models/dto/ScoreComment.h @@ -23,7 +23,7 @@ namespace PocketTx void DeserializePayload(const UniValue& src) override; shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetCommentTxHash() const; void SetCommentTxHash(const string& value); diff --git a/src/pocketdb/models/dto/ScoreContent.h b/src/pocketdb/models/dto/ScoreContent.h index 827a5f7c3..9862a2bb4 100644 --- a/src/pocketdb/models/dto/ScoreContent.h +++ b/src/pocketdb/models/dto/ScoreContent.h @@ -23,7 +23,7 @@ namespace PocketTx void DeserializePayload(const UniValue& src) override; shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetContentTxHash() const; void SetContentTxHash(const string& value); diff --git a/src/pocketdb/models/dto/Subscribe.h b/src/pocketdb/models/dto/Subscribe.h index 00da0927c..301b68b6a 100644 --- a/src/pocketdb/models/dto/Subscribe.h +++ b/src/pocketdb/models/dto/Subscribe.h @@ -23,7 +23,7 @@ namespace PocketTx void DeserializePayload(const UniValue& src) override; shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetAddressTo() const; void SetAddressTo(const string& value); diff --git a/src/pocketdb/models/dto/User.h b/src/pocketdb/models/dto/User.h index dd1be59ab..238a338a6 100644 --- a/src/pocketdb/models/dto/User.h +++ b/src/pocketdb/models/dto/User.h @@ -22,7 +22,7 @@ namespace PocketTx void DeserializePayload(const UniValue& src) override; shared_ptr GetAddress() const; - void SetAddress(const string& value) override; + void SetAddress(const string& value); shared_ptr GetReferrerAddress() const; void SetReferrerAddress(const string& value); diff --git a/src/pocketdb/models/dto/moderation/Flag.cpp b/src/pocketdb/models/dto/moderation/Flag.cpp new file mode 100644 index 000000000..99726040d --- /dev/null +++ b/src/pocketdb/models/dto/moderation/Flag.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2018-2022 The Pocketnet developers +// Distributed under the Apache 2.0 software license, see the accompanying +// https://www.apache.org/licenses/LICENSE-2.0 + +#include "pocketdb/models/dto/moderation/Flag.h" + +namespace PocketTx +{ + ModerationFlag::ModerationFlag() : SocialTransaction() + { + SetType(TxType::MODERATION_FLAG); + } + + ModerationFlag::ModerationFlag(const CTransactionRef& tx) : SocialTransaction(tx) + { + SetType(TxType::MODERATION_FLAG); + } + + string ModerationFlag::BuildHash() + { + string data; + + data += GetContentTxHash() ? *GetContentTxHash() : ""; + data += GetContentAddressHash() ? *GetContentAddressHash() : ""; + data += GetReason() ? to_string(*GetReason()) : ""; + + return SocialTransaction::GenerateHash(data); + } + + + shared_ptr ModerationFlag::GetContentTxHash() const { return m_string2; } + void ModerationFlag::SetContentTxHash(const string& value) { m_string2 = make_shared(value); } + + shared_ptr ModerationFlag::GetContentAddressHash() const { return m_string3; } + void ModerationFlag::SetContentAddressHash(const string& value) { m_string3 = make_shared(value); } + + shared_ptr ModerationFlag::GetReason() const { return m_int1; } + void ModerationFlag::SetReason(int64_t value) { m_int1 = make_shared(value); } + + +} // namespace PocketTx + diff --git a/src/pocketdb/models/dto/moderation/Flag.h b/src/pocketdb/models/dto/moderation/Flag.h new file mode 100644 index 000000000..e64a50d2b --- /dev/null +++ b/src/pocketdb/models/dto/moderation/Flag.h @@ -0,0 +1,33 @@ +// Copyright (c) 2018-2022 The Pocketnet developers +// Distributed under the Apache 2.0 software license, see the accompanying +// https://www.apache.org/licenses/LICENSE-2.0 + +#ifndef POCKETTX_MODERATION_FLAG_H +#define POCKETTX_MODERATION_FLAG_H + +#include "pocketdb/models/base/SocialTransaction.h" + +namespace PocketTx +{ + class ModerationFlag : public SocialTransaction + { + public: + ModerationFlag(); + ModerationFlag(const CTransactionRef& tx); + + string BuildHash() override; + + shared_ptr GetContentTxHash() const; + void SetContentTxHash(const string& value); + + shared_ptr GetContentAddressHash() const; + void SetContentAddressHash(const string& value); + + shared_ptr GetReason() const; + void SetReason(int64_t value); + + }; // class ModerationFlag + +} // namespace PocketTx + +#endif // POCKETTX_MODERATION_FLAG_H diff --git a/src/pocketdb/pocketnet.cpp b/src/pocketdb/pocketnet.cpp index 5737b9a71..40c7bcd5a 100644 --- a/src/pocketdb/pocketnet.cpp +++ b/src/pocketdb/pocketnet.cpp @@ -13,6 +13,7 @@ namespace PocketDb ConsensusRepository ConsensusRepoInst(SQLiteDbInst); NotifierRepository NotifierRepoInst(SQLiteDbInst); ExplorerRepository ExplorerRepoInst(SQLiteDbInst); + SystemRepository SystemRepoInst(SQLiteDbInst); SQLiteDatabase SQLiteDbCheckpointInst(true); CheckpointRepository CheckpointRepoInst(SQLiteDbCheckpointInst); diff --git a/src/pocketdb/pocketnet.h b/src/pocketdb/pocketnet.h index 4c407aaaa..cc37c0204 100644 --- a/src/pocketdb/pocketnet.h +++ b/src/pocketdb/pocketnet.h @@ -17,10 +17,13 @@ #include "pocketdb/repositories/RatingsRepository.h" #include "pocketdb/repositories/TransactionRepository.h" #include "pocketdb/repositories/ConsensusRepository.h" +#include "pocketdb/repositories/SystemRepository.h" #include "pocketdb/repositories/CheckpointRepository.h" + #include "pocketdb/repositories/web/WebRpcRepository.h" #include "pocketdb/repositories/web/ExplorerRepository.h" #include "pocketdb/repositories/web/NotifierRepository.h" + #include "pocketdb/web/PocketFrontend.h" #include "pocketdb/services/WebPostProcessing.h" @@ -33,6 +36,7 @@ namespace PocketDb extern ConsensusRepository ConsensusRepoInst; extern NotifierRepository NotifierRepoInst; extern ExplorerRepository ExplorerRepoInst; + extern SystemRepository SystemRepoInst; extern SQLiteDatabase SQLiteDbCheckpointInst; extern CheckpointRepository CheckpointRepoInst; diff --git a/src/pocketdb/repositories/ChainRepository.cpp b/src/pocketdb/repositories/ChainRepository.cpp index 1a0a3dd29..db0512457 100644 --- a/src/pocketdb/repositories/ChainRepository.cpp +++ b/src/pocketdb/repositories/ChainRepository.cpp @@ -94,7 +94,6 @@ namespace PocketDb } } - tuple ChainRepository::ExistsBlock(const string& blockHash, int height) { bool exists = false; @@ -135,7 +134,7 @@ namespace PocketDb BlockHash = ?, BlockNum = ?, Height = ? - WHERE Hash = ? + WHERE Hash = ? and BlockHash is null )sql"); TryBindStatementText(stmt, 1, blockHash); TryBindStatementInt(stmt, 2, blockNumber); @@ -146,7 +145,7 @@ namespace PocketDb auto stmtOuts = SetupSqlStatement(R"sql( UPDATE TxOutputs SET TxHeight = ? - WHERE TxHash = ? + WHERE TxHash = ? and TxHeight is null )sql"); TryBindStatementInt(stmtOuts, 1, height); TryBindStatementText(stmtOuts, 2, txHash); diff --git a/src/pocketdb/repositories/ConsensusRepository.cpp b/src/pocketdb/repositories/ConsensusRepository.cpp index ea84e85dc..fbb675fd4 100644 --- a/src/pocketdb/repositories/ConsensusRepository.cpp +++ b/src/pocketdb/repositories/ConsensusRepository.cpp @@ -300,8 +300,7 @@ namespace PocketDb } - bool ConsensusRepository::ExistsScore(const string& address, const string& contentHash, - TxType type, bool mempool) + bool ConsensusRepository::ExistsScore(const string& address, const string& contentHash, TxType type, bool mempool) { bool result = false; @@ -333,6 +332,72 @@ namespace PocketDb return result; } + bool ConsensusRepository::Exists(const string& txHash, const vector& types, bool inChain = true) + { + bool result = false; + + string sql = R"sql( + select 1 + from Transactions + where Hash = ? + and Type in ( )sql" + join(vector(types.size(), "?"), ",") + R"sql( ) + )sql"; + + if (inChain) + sql += " and Height is not null"; + + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(sql); + + int i = 1; + TryBindStatementText(stmt, i, txHash); + for (const auto& type: types) + TryBindStatementInt(stmt, i++, type); + + if (sqlite3_step(*stmt) == SQLITE_ROW) + result = true; + + FinalizeSqlStatement(*stmt); + }); + + return result; + } + + bool ConsensusRepository::ExistsNotDeleted(const string& txHash, const string& address, const vector& types) + { + bool result = false; + + string sql = R"sql( + select 1 + from Transactions t + where t.Hash = ? + and t.Type in ( )sql" + join(vector(types.size(), "?"), ",") + R"sql( ) + and t.String1 = ? + and t.Height > 0 + and not exists (select 1 from Transactions d indexed by Transactions_Id_Last where d.Id = t.Id and d.Last = 1 and d.Type in (207,206)) + )sql"; + + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(sql); + + int i = 1; + TryBindStatementText(stmt, i++, txHash); + for (const auto& type: types) + TryBindStatementInt(stmt, i++, type); + TryBindStatementText(stmt, i++, address); + + if (sqlite3_step(*stmt) == SQLITE_ROW) + result = true; + + FinalizeSqlStatement(*stmt); + }); + + return result; + } + + int64_t ConsensusRepository::GetUserBalance(const string& address) { int64_t result = 0; @@ -470,6 +535,41 @@ namespace PocketDb return result; } + AccountData ConsensusRepository::GetAccountData(const string& address) + { + AccountData result = {-1, 0, 0, 0}; + + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(R"sql( + select (u.Id)AddressId, + ifnull(r.Value, 0)Reputation, + (select min(uf.Height) from Transactions uf where uf.Id = u.Id)RegistrationBlock, + (select count() from Ratings l where l.Type = 1 and l.Id = u.Id)LikersCount + from Transactions u indexed by Transactions_Type_Last_String1_Height_Id + left join Ratings r indexed by Ratings_Type_Id_Last_Value on r.Type = 0 and r.Id = u.Id and r.Last = 1 + where u.Type in (100) + and u.Last = 1 + and u.String1 = ? + and u.Height > 0 + limit 1 + )sql"); + TryBindStatementText(stmt, 1, address); + + if (sqlite3_step(*stmt) == SQLITE_ROW) + { + if (auto[ok, value] = TryGetColumnInt64(*stmt, 0); ok) result.AddressId = value; + if (auto[ok, value] = TryGetColumnInt64(*stmt, 1); ok) result.Reputation = value; + if (auto[ok, value] = TryGetColumnInt64(*stmt, 2); ok) result.RegistrationHeight = value; + if (auto[ok, value] = TryGetColumnInt64(*stmt, 3); ok) result.LikersCount = value; + } + + FinalizeSqlStatement(*stmt); + }); + + return result; + } + // Selects for get models data ScoreDataDtoRef ConsensusRepository::GetScoreData(const string& txHash) { @@ -1749,7 +1849,7 @@ namespace PocketDb TryTransactionStep(__func__, [&]() { auto stmt = SetupSqlStatement(R"sql( - select count(*) + select count() from Transactions indexed by Transactions_Type_String1_String2_Height where Type in (200,201,202,207) and Height is null @@ -1770,4 +1870,60 @@ namespace PocketDb return result; } + /* MODERATION */ + + int ConsensusRepository::CountModerationFlag(const string& address, int height, bool includeMempool) + { + int result = 0; + string whereMempool = includeMempool ? " or Height is null " : ""; + + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(R"sql( + select count() + from Transactions indexed by Transactions_Type_String1_Height_Time_Int1 + where Type = 410 + and String1 = ? + and ( Height >= ? )sql" + whereMempool + R"sql( ) + )sql"); + TryBindStatementText(stmt, 1, address); + TryBindStatementInt64(stmt, 2, height); + + if (sqlite3_step(*stmt) == SQLITE_ROW) + if (auto[ok, value] = TryGetColumnInt(*stmt, 0); ok) + result = value; + + FinalizeSqlStatement(*stmt); + }); + + return result; + } + + int ConsensusRepository::CountModerationFlag(const string& address, const string& addressTo, bool includeMempool) + { + int result = 0; + string whereMempool = includeMempool ? " or Height is null " : ""; + + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(R"sql( + select count() + from Transactions indexed by Transactions_Type_String1_String3_Height + where Type = 410 + and String1 = ? + and String3 = ? + and ( Height > 0 )sql" + whereMempool + R"sql( ) + )sql"); + TryBindStatementText(stmt, 1, address); + TryBindStatementText(stmt, 2, addressTo); + + if (sqlite3_step(*stmt) == SQLITE_ROW) + if (auto[ok, value] = TryGetColumnInt(*stmt, 0); ok) + result = value; + + FinalizeSqlStatement(*stmt); + }); + + return result; + } } \ No newline at end of file diff --git a/src/pocketdb/repositories/ConsensusRepository.h b/src/pocketdb/repositories/ConsensusRepository.h index 1a724c014..dbd19cc86 100644 --- a/src/pocketdb/repositories/ConsensusRepository.h +++ b/src/pocketdb/repositories/ConsensusRepository.h @@ -24,6 +24,14 @@ namespace PocketDb using namespace PocketTx; using namespace PocketHelpers; + struct AccountData + { + int64_t AddressId; + int64_t Reputation; + int64_t RegistrationHeight; + int64_t LikersCount; + }; + class ConsensusRepository : public TransactionRepository { public: @@ -49,6 +57,8 @@ namespace PocketDb int GetAccountRegistrationHeight(int addressId); int64_t GetAccountRegistrationTime(int addressId); + AccountData GetAccountData(const string& address); + ScoreDataDtoRef GetScoreData(const string& txHash); shared_ptr> GetReferrers(const vector& addresses, int minHeight); tuple GetReferrer(const string& address); @@ -71,6 +81,8 @@ namespace PocketDb bool ExistsScore(const string& address, const string& contentHash, TxType type, bool mempool); bool ExistsUserRegistrations(vector& addresses, bool mempool); bool ExistsAnotherByName(const string& address, const string& name); + bool Exists(const string& txHash, const vector& types, bool inChain); + bool ExistsNotDeleted(const string& txHash, const string& address, const vector& types); // get counts in "mempool" - Height is null int CountMempoolBlocking(const string& address, const string& addressTo); @@ -122,6 +134,11 @@ namespace PocketDb int CountChainArticleEdit(const string& address, const string& rootTxHash); int CountMempoolContentDelete(const string& address, const string& rootTxHash); + + /* MODERATION */ + int CountModerationFlag(const string& address, int height, bool includeMempool); + int CountModerationFlag(const string& address, const string& addressTo, bool includeMempool); + }; } // namespace PocketDb diff --git a/src/pocketdb/repositories/SystemRepository.cpp b/src/pocketdb/repositories/SystemRepository.cpp new file mode 100644 index 000000000..cea719491 --- /dev/null +++ b/src/pocketdb/repositories/SystemRepository.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2018-2022 The Pocketnet developers +// Distributed under the Apache 2.0 software license, see the accompanying +// https://www.apache.org/licenses/LICENSE-2.0 + +#include "pocketdb/repositories/SystemRepository.h" + +namespace PocketDb +{ + int SystemRepository::GetDbVersion(const string& db) + { + int result = -1; + + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(R"sql( + select Version + from System + where Db = ? + )sql"); + + TryBindStatementText(stmt, 1, db); + + if (sqlite3_step(*stmt) == SQLITE_ROW) + if (auto[ok, value] = TryGetColumnInt(*stmt, 0); ok) + result = value; + + FinalizeSqlStatement(*stmt); + }); + + return result; + } + + void SystemRepository::SetDbVersion(const string& db, int version) + { + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(R"sql( + update System + set Version = ? + where Db = ? + )sql"); + + TryBindStatementInt(stmt, 1, version); + TryBindStatementText(stmt, 2, db); + TryStepStatement(stmt); + }); + } + +} diff --git a/src/pocketdb/repositories/SystemRepository.h b/src/pocketdb/repositories/SystemRepository.h new file mode 100644 index 000000000..140313ace --- /dev/null +++ b/src/pocketdb/repositories/SystemRepository.h @@ -0,0 +1,26 @@ +// Copyright (c) 2018-2022 The Pocketnet developers +// Distributed under the Apache 2.0 software license, see the accompanying +// https://www.apache.org/licenses/LICENSE-2.0 + +#ifndef SRC_SYSTEM_REPOSITORY_H +#define SRC_SYSTEM_REPOSITORY_H + +#include +#include "pocketdb/repositories/BaseRepository.h" + +namespace PocketDb +{ + class SystemRepository : public BaseRepository + { + public: + explicit SystemRepository(SQLiteDatabase& db) : BaseRepository(db) {} + + void Init() override {} + void Destroy() override {} + + int GetDbVersion(const string& db); + void SetDbVersion(const string& db, int version); + + }; // namespace PocketDb +} +#endif //SRC_SYSTEM_REPOSITORY_H diff --git a/src/pocketdb/repositories/TransactionRepository.cpp b/src/pocketdb/repositories/TransactionRepository.cpp index 941cec1ca..9074a16d2 100644 --- a/src/pocketdb/repositories/TransactionRepository.cpp +++ b/src/pocketdb/repositories/TransactionRepository.cpp @@ -356,7 +356,7 @@ namespace PocketDb bool result = false; string sql = R"sql( - select count(*) + select 1 from Transactions where Hash = ? and Height is not null @@ -369,8 +369,7 @@ namespace PocketDb TryBindStatementText(stmt, 1, hash); if (sqlite3_step(*stmt) == SQLITE_ROW) - if (auto[ok, value] = TryGetColumnInt(*stmt, 0); ok) - result = (value >= 1); + result = true; FinalizeSqlStatement(*stmt); }); diff --git a/src/pocketdb/repositories/web/ExplorerRepository.cpp b/src/pocketdb/repositories/web/ExplorerRepository.cpp index cce3e1167..9691f6245 100644 --- a/src/pocketdb/repositories/web/ExplorerRepository.cpp +++ b/src/pocketdb/repositories/web/ExplorerRepository.cpp @@ -323,7 +323,7 @@ namespace PocketDb { select t.Hash from Transactions t indexed by Transactions_BlockHash where t.BlockHash = ? - order by t.BlockNum desc + order by t.BlockNum asc limit ?, ? )sql"); diff --git a/src/pocketdb/repositories/web/SearchRepository.cpp b/src/pocketdb/repositories/web/SearchRepository.cpp index b3f660881..c447ce988 100644 --- a/src/pocketdb/repositories/web/SearchRepository.cpp +++ b/src/pocketdb/repositories/web/SearchRepository.cpp @@ -231,55 +231,59 @@ namespace PocketDb return result; } - UniValue SearchRepository::GetRecomendedAccountsBySubscriptions(const string& address, int cntOut) + //TODO (o1q): remove it + vector SearchRepository::GetRecommendedAccountByAddressSubscriptionsOld(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth, int cntSubscriptions) { auto func = __func__; - UniValue result(UniValue::VARR); + vector ids; if (address.empty()) - return result; + return ids; - string sql = R"sql( - select - recommendation.address, - p.String2 as name, - p.String3 as avatar - - , ifnull(( - select r.Value - from Ratings r indexed by Ratings_Type_Id_Last_Height - where r.Type=0 and r.Id=u.Id and r.Last=1) - ,0) as Reputation - - , ( - select count(*) - from Transactions subs indexed by Transactions_Type_Last_String2_Height - where subs.Type in (302,303) and subs.Height is not null and subs.Last = 1 and subs.String2 = u.String1 - ) as SubscribersCount - from ( - select - t.String2 address - from Transactions t indexed by Transactions_Type_Last_String1_String2_Height - where t.Last = 1 - and t.Type in (302,303) - and t.Height is not null - and t.String2 != ? - and t.String1 in (select s.String1 - from Transactions s indexed by Transactions_Type_Last_String2_Height - where s.Type in (302,303) - and s.Last = 1 - and s.Height is not null - and s.String2 = ?) - group by t.String2 - order by count(*) desc - limit ? - )recommendation - cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id on u.String1 = recommendation.address - and u.Type in (100,101,102) - and u.Last=1 - and u.Height is not null - cross join Payload p on p.TxHash = u.Hash + string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); + + string excludeAddressFilter = "?"; + if (!addressExclude.empty()) + excludeAddressFilter += ", ?"; + string langFilter = ""; + if (!lang.empty()) + langFilter = "cross join Payload lang on lang.TxHash = u.Hash and lang.String1 = ?"; + + int minReputation = 300; + + string sql = R"sql( + select Contents.String1 + from Transactions Rates indexed by Transactions_Type_Last_String1_Height_Id + cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height + on Contents.String2 = Rates.String2 + and Contents.Last = 1 + and Contents.Height > 0 + and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) + and Contents.String1 not in ( ? ) + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.String1 = Contents.String1 + and u.Type in (100) + and u.Last = 1 + and u.Height > 0 + )sql" + langFilter + R"sql( + where Rates.Type in (300) + and Rates.Int1 = 5 + and Rates.Height > ? + and Rates.Last in (0, 1) + and Rates.String1 in ( + select subscribes.String2 + from Transactions subscribes indexed by Transactions_Type_Last_String1_Height_Id + where subscribes.Type in (302, 303) + and subscribes.Last = 1 + and subscribes.Height > 0 + and subscribes.String1 = ? + limit ? + ) + group by Contents.String1 + having count(*) > 1 + order by count (*) desc + limit ? )sql"; TryTransactionStep(__func__, [&]() @@ -287,96 +291,100 @@ namespace PocketDb auto stmt = SetupSqlStatement(sql); int i = 1; + for (const auto& contenttype: contentTypes) + TryBindStatementInt(stmt, i++, contenttype); + TryBindStatementText(stmt, i++, address); + if (!addressExclude.empty()) + TryBindStatementText(stmt, i++, addressExclude); + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + + TryBindStatementInt(stmt, i++, nHeight-depth); + TryBindStatementText(stmt, i++, address); + + TryBindStatementInt(stmt, i++, cntSubscriptions); + TryBindStatementInt(stmt, i++, cntOut); while (sqlite3_step(*stmt) == SQLITE_ROW) { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("address", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) record.pushKV("name", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 2); ok) record.pushKV("avatar", value); - if (auto[ok, value] = TryGetColumnInt(*stmt, 3); ok) record.pushKV("reputation", value / 10.0); - if (auto[ok, value] = TryGetColumnInt(*stmt, 4); ok) record.pushKV("subscribers_count", value); - result.push_back(record); + if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) + ids.push_back(value); } FinalizeSqlStatement(*stmt); }); - return result; + return ids; } - UniValue SearchRepository::GetRecomendedAccountsByScoresOnSimilarAccounts(const string& address, const vector& contentTypes, int nHeight, int depth, int cntOut) + //TODO (o1q): remove it + vector SearchRepository::GetRecommendedContentByAddressSubscriptionsOld(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth, int cntSubscriptions) { auto func = __func__; - UniValue result(UniValue::VARR); + vector ids; - if (address.empty()) - return result; + if (contentAddress.empty()) + return ids; string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); + string excludeAddressFilter = "?"; + if (!address.empty()) + excludeAddressFilter += ", ?"; + + string langFilter = ""; + if (!lang.empty()) + langFilter = "cross join Payload lang on lang.TxHash = Contents.Hash and lang.String1 = ?"; + + int minReputation = 300; + string sql = R"sql( - select recommendation.address, - p.String2 as name, - p.String3 as avatar - - , ifnull(( - select r.Value - from Ratings r indexed by Ratings_Type_Id_Last_Height - where r.Type=0 and r.Id=u.Id and r.Last=1) - ,0) as Reputation - - , ( - select count(*) - from Transactions subs indexed by Transactions_Type_Last_String2_Height - where subs.Type in (302,303) and subs.Height is not null and subs.Last = 1 and subs.String2 = u.String1 - ) as SubscribersCount + select recomendations.Id from ( - select - tOtherContents.String1 as address - from Transactions tOtherContents - indexed by Transactions_Type_Last_String1_String2_Height - where tOtherContents.String2 in ( - select tOtherLikes.String2 as OtherLikedContent - from Transactions tOtherlikes - where tOtherLikes.String1 in ( - select tLikes.String1 as Liker - from Transactions tLikes - where tLikes.String2 in ( - select tContents.String2 as BloggerContent - from Transactions tContents - where tContents.Type in ( )sql" + contentTypesFilter + R"sql( ) - and tContents.Last = 1 - and tContents.String1 = ? - and tContents.Height >= ? - ) - and tLikes.Type in (300) - and tLikes.Last in (1, 0) - and tLikes.Int1 > 3 - and tLikes.Height >= ? + select Contents.String1, + Contents.Id, + Rates.String2, + count(*) count + from Transactions Rates indexed by Transactions_Type_Last_String1_Height_Id + cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height + on Contents.String2 = Rates.String2 + and Contents.Last = 1 + and Contents.Height > 0 + and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) + and Contents.String1 not in ( )sql" + excludeAddressFilter + R"sql( ) + )sql" + langFilter + R"sql( + where Rates.Type in (300) + and Rates.Int1 = 5 + and Rates.Height > ? + and Rates.Last in (0, 1) + and Rates.String1 in ( + select subscribers.String2 + from Transactions subscribers indexed by Transactions_Type_Last_String1_Height_Id + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) + and u.Last = 1 and u.Height > 0 + and u.String1 = subscribers.String1 + cross join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id + and r.Type = 0 + and r.Last = 1 + and r.Value > ? + where subscribers.Type in (302, 303) + and subscribers.Last = 1 + and subscribers.Height > 0 + and subscribers.String1 = ? + limit ? ) - and tOtherLikes.Type in (300) - and tOtherLikes.Last in (1, 0) - and tOtherLikes.Int1 > 3 - and tOtherLikes.Height >= ? - ) - and tOtherContents.Type in ( )sql" + contentTypesFilter + R"sql( ) - and tOtherContents.String1 != ? - and tOtherContents.Last = 1 - and tOtherContents.Height >= ? - group by tOtherContents.String1 - order by count(*) desc - limit ? - )recommendation - cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id - on u.String1 = recommendation.address - and u.Type in (100,101,102) - and u.Last=1 - and u.Height is not null - cross join Payload p on p.TxHash = u.Hash + group by Rates.String2 + having count(*) > 1 + order by count(*) desc + ) recomendations + group by recomendations.String1 + limit ? )sql"; TryTransactionStep(__func__, [&]() @@ -386,102 +394,129 @@ namespace PocketDb int i = 1; for (const auto& contenttype: contentTypes) TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - for (const auto& contenttype: contentTypes) - TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); + + TryBindStatementText(stmt, i++, contentAddress); + if (!address.empty()) + TryBindStatementText(stmt, i++, address); + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + + TryBindStatementInt(stmt, i++, nHeight-depth); + + TryBindStatementInt(stmt, i++, minReputation); + TryBindStatementText(stmt, i++, contentAddress); + + TryBindStatementInt(stmt, i++, cntSubscriptions); + TryBindStatementInt(stmt, i++, cntOut); while (sqlite3_step(*stmt) == SQLITE_ROW) { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("address", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) record.pushKV("name", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 2); ok) record.pushKV("avatar", value); - if (auto[ok, value] = TryGetColumnInt(*stmt, 3); ok) record.pushKV("reputation", value / 10.0); - if (auto[ok, value] = TryGetColumnInt(*stmt, 4); ok) record.pushKV("subscribers_count", value); - result.push_back(record); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 0); ok) + ids.push_back(value); } FinalizeSqlStatement(*stmt); }); - return result; + return ids; } - UniValue SearchRepository::GetRecomendedAccountsByScoresFromAddress(const string& address, const vector& contentTypes, int nHeight, int depth, int cntOut) + vector SearchRepository::GetRecommendedAccountByAddressSubscriptions(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth) { auto func = __func__; - UniValue result(UniValue::VARR); + vector ids; if (address.empty()) - return result; + return ids; string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); + string excludeAddressFilter = "?"; + if (!addressExclude.empty()) + excludeAddressFilter += ", ?"; + + string langFilter = ""; + if (!lang.empty()) + langFilter = "cross join Payload lang on lang.TxHash = u.Hash and lang.String1 = ?"; + + int minReputation = 300; + int limitSubscriptions = 30; + int limitSubscriptionsTotal = 30; + int cntRates = 1; + string sql = R"sql( - select recommendation.address, - p.String2 as name, - p.String3 as avatar - - , ifnull(( - select r.Value - from Ratings r indexed by Ratings_Type_Id_Last_Height - where r.Type=0 and r.Id=u.Id and r.Last=1) - ,0) as Reputation - - , ( - select count(*) - from Transactions subs indexed by Transactions_Type_Last_String2_Height - where subs.Type in (302,303) and subs.Height is not null and subs.Last = 1 and subs.String2 = u.String1 - ) as SubscribersCount - from ( - select - tOtherContents.String1 as address - from Transactions tOtherContents - indexed by Transactions_Type_Last_String2_Height - where tOtherContents.String2 in ( - select tOtherLikes.String2 as OtherLikedContent - from Transactions tOtherlikes - where tOtherLikes.String1 in ( - select tLikes.String1 as Liker - from Transactions tLikes - where tLikes.String2 in ( - select tAddressLikes.String2 as ContentsLikedByAddress - from Transactions tAddressLikes - where tAddressLikes.String1 = ? - and tAddressLikes.Type in (300) - and tAddressLikes.Last in (1, 0) - and tAddressLikes.Int1 > 3 - and tAddressLikes.Height >= ? - ) - and tLikes.Type in (300) - and tLikes.Last in (1, 0) - and tLikes.Int1 > 3 - and tLikes.Height >= ? - ) - and tOtherLikes.Type in (300) - and tOtherLikes.Last in (1, 0) - and tOtherLikes.Int1 > 3 - and tOtherLikes.Height >= ? - ) - and tOtherContents.Type in ( )sql" + contentTypesFilter + R"sql( ) - and tOtherContents.String1 != ? - and tOtherContents.Last = 1 - and tOtherContents.Height >= ? - group by tOtherContents.String1 - order by count(*) desc - limit ? - )recommendation - cross join Transactions u on u.String1 = recommendation.address - and u.Type in (100,101,102) - and u.Last=1 - and u.Height is not null - cross join Payload p on p.TxHash = u.Hash + select Contents.String1 + from Transactions Rates indexed by Transactions_Type_Last_String1_Height_Id + cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height + on Contents.String2 = Rates.String2 + and Contents.Last = 1 + and Contents.Height > 0 + and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) + and Contents.String1 not in ( )sql" + excludeAddressFilter + R"sql( ) + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.String1 = Contents.String1 + and u.Type in (100) + and u.Last = 1 + and u.Height > 0 + )sql" + langFilter + R"sql( + where Rates.Type in (300) + and Rates.Int1 = 5 + and Rates.Height > ? + and Rates.Last in (0, 1) + and Rates.String1 in + ( + select address + from ( + select rnk, address + from ( + select 1 as rnk, subscribes.String2 as address + from Transactions subscribes indexed by Transactions_String1_Last_Height + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) + and u.Last = 1 and u.Height > 0 + and u.String1 = subscribes.String2 + cross join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id + and r.Type = 0 + and r.Last = 1 + and r.Value > ? + where subscribes.Type in (302, 303) + and subscribes.Last = 1 + and subscribes.String1 = ? + and subscribes.Height is not null + order by subscribes.Height desc + limit ? + ) + union + select rnk, address + from ( + select 2 as rnk, subscribers.String1 as address + from Transactions subscribers indexed by Transactions_Type_Last_String2_Height + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) + and u.Last = 1 and u.Height > 0 + and u.String1 = subscribers.String1 + cross join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id + and r.Type = 0 + and r.Last = 1 + and r.Value > ? + where subscribers.Type in (302, 303) + and subscribers.Last = 1 + and subscribers.String2 = ? + and subscribers.Height is not null + order by random() + limit ? + )) + order by rnk + limit ? + ) + group by Contents.String1 + having count(*) > ? + order by count (*) desc + limit ? )sql"; TryTransactionStep(__func__, [&]() @@ -489,150 +524,141 @@ namespace PocketDb auto stmt = SetupSqlStatement(sql); int i = 1; - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); for (const auto& contenttype: contentTypes) TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, cntOut); - - while (sqlite3_step(*stmt) == SQLITE_ROW) - { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("address", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) record.pushKV("name", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 2); ok) record.pushKV("avatar", value); - if (auto[ok, value] = TryGetColumnInt(*stmt, 3); ok) record.pushKV("reputation", value / 10.0); - if (auto[ok, value] = TryGetColumnInt(*stmt, 4); ok) record.pushKV("subscribers_count", value); - result.push_back(record); - } - FinalizeSqlStatement(*stmt); - }); + TryBindStatementText(stmt, i++, address); + if (!addressExclude.empty()) + TryBindStatementText(stmt, i++, addressExclude); - return result; - } + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); - UniValue SearchRepository::GetRecomendedAccountsByTags(const vector& tags, int nHeight, int depth, int cntOut) - { - auto func = __func__; - UniValue result(UniValue::VARR); + TryBindStatementInt(stmt, i++, nHeight-depth); - if (tags.empty()) - return result; + TryBindStatementInt(stmt, i++, minReputation); + TryBindStatementText(stmt, i++, address); + TryBindStatementInt(stmt, i++, limitSubscriptions); - string tagsFilter = join(vector(tags.size(), "?"), ","); + TryBindStatementInt(stmt, i++, minReputation); + TryBindStatementText(stmt, i++, address); + TryBindStatementInt(stmt, i++, limitSubscriptions); - string sql = R"sql( - select - recommendation.address, - p.String2 as name, - p.String3 as avatar - - , ifnull(( - select r.Value - from Ratings r indexed by Ratings_Type_Id_Last_Height - where r.Type=0 and r.Id=u.Id and r.Last=1) - ,0) as Reputation - - , ( - select count(*) - from Transactions subs indexed by Transactions_Type_Last_String2_Height - where subs.Type in (302,303) and subs.Height is not null and subs.Last = 1 and subs.String2 = u.String1 - ) as SubscribersCount - from ( - select authors.string1 address - from ( - select c.String1 - from Transactions sc indexed by Transactions_Type_Last_Height_Id - cross join Transactions c indexed by Transactions_Type_Last_String2_Height - on c.String2 = sc.String2 and c.Type in (200, 201, 202) and c.Height > 0 and c.Last = 1 - and c.id in (select tm.ContentId - from web.Tags tag indexed by Tags_Lang_Value_Id - join web.TagsMap tm indexed by TagsMap_TagId_ContentId - on tag.Id = tm.TagId - where tag.Value in ( )sql" + join(vector(tags.size(), "?"), ",") + R"sql( )) - where sc.Type in (300) - and sc.Last in (0, 1) - and sc.Height > ? - and sc.Int1 = 5 - ) authors - group by authors.string1 - order by count(*) desc - limit ? - )recommendation - cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id on u.String1 = recommendation.address - and u.Type in (100,101,102) - and u.Last=1 - and u.Height is not null - cross join Payload p on p.TxHash = u.Hash + TryBindStatementInt(stmt, i++, limitSubscriptionsTotal); - )sql"; + TryBindStatementInt(stmt, i++, cntRates); - TryTransactionStep(__func__, [&]() - { - auto stmt = SetupSqlStatement(sql); - - int i = 1; - for (const auto& tag: tags) - TryBindStatementText(stmt, i++, tag); - TryBindStatementInt(stmt, i++, nHeight - depth); TryBindStatementInt(stmt, i++, cntOut); while (sqlite3_step(*stmt) == SQLITE_ROW) { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("address", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) record.pushKV("name", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 2); ok) record.pushKV("avatar", value); - if (auto[ok, value] = TryGetColumnInt(*stmt, 3); ok) record.pushKV("reputation", value / 10.0); - if (auto[ok, value] = TryGetColumnInt(*stmt, 4); ok) record.pushKV("subscribers_count", value); - result.push_back(record); + if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) + ids.push_back(value); } FinalizeSqlStatement(*stmt); }); - return result; + return ids; } - UniValue SearchRepository::GetRecomendedContentsByScoresOnSimilarContents(const string& contentid, const vector& contentTypes, int depth, int cntOut) + vector SearchRepository::GetRecommendedContentByAddressSubscriptions(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth) { auto func = __func__; - UniValue result(UniValue::VARR); + vector ids; - if (contentid.empty()) - return result; + if (contentAddress.empty()) + return ids; string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); + string excludeAddressFilter = "?"; + if (!address.empty()) + excludeAddressFilter += ", ?"; + + string langFilter = ""; + if (!lang.empty()) + langFilter = "cross join Payload lang indexed by Payload_String1_TxHash on lang.TxHash = Contents.Hash and lang.String1 = ?"; + + int minReputation = 300; + int limitSubscriptions = 50; + int limitSubscriptionsTotal = 30; + int cntRates = 1; + string sql = R"sql( - select OtherRaters.String2 OtherScoredContent, count(*) cnt - from Transactions OtherRaters indexed by Transactions_Type_Last_String1_Height_Id - cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height - on OtherRaters.String2 = Contents.String2 and Contents.Last = 1 and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) and Contents.Height > 0 - where OtherRaters.Type in (300) - and OtherRaters.Int1 > 3 - and OtherRaters.Last in (1, 0) - and OtherRaters.Height >= (select Height - from Transactions indexed by Transactions_Type_Last_String2_Height - where Type in ( )sql" + contentTypesFilter + R"sql( ) - and String2 = ? - and Last = 1) - ? - and OtherRaters.String1 in ( - select String1 as Rater - from Transactions Raters indexed by Transactions_Type_Last_String2_Height - where Raters.Type in (300) - and Raters.Int1 > 3 - and Raters.String2 = ? - and Raters.Last in (1, 0) - ) - and OtherRaters.String2 != ? - group by OtherRaters.String2 - order by count(*) desc + select recomendations.Id + from ( + select Contents.String1, + Contents.Id, + --Rates.String2, + count(*) count + from Transactions Rates indexed by Transactions_Type_Last_String1_Height_Id + cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height + on Contents.String2 = Rates.String2 + and Contents.Last = 1 + and Contents.Height > 0 + and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) + and Contents.String1 not in ( )sql" + excludeAddressFilter + R"sql( ) + )sql" + langFilter + R"sql( + where Rates.Type in (300) + and Rates.Int1 = 5 + and Rates.Height > ? + and Rates.Last in (0, 1) + and Rates.String1 in + ( + select address + from ( + select rnk, address + from ( + select 1 as rnk, subscribes.String2 as address + from Transactions subscribes indexed by Transactions_String1_Last_Height + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) + and u.Last = 1 and u.Height > 0 + and u.String1 = subscribes.String2 + cross join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id + and r.Type = 0 + and r.Last = 1 + and r.Value > ? + where subscribes.Type in (302, 303) + and subscribes.Last = 1 + and subscribes.String1 = ? + and subscribes.Height is not null + order by subscribes.Height desc + limit ? + ) + union + select rnk, address + from ( + select 2 as rnk, subscribers.String1 as address + from Transactions subscribers indexed by Transactions_Type_Last_String2_Height + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) + and u.Last = 1 and u.Height > 0 + and u.String1 = subscribers.String1 + cross join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id + and r.Type = 0 + and r.Last = 1 + and r.Value > ? + where subscribers.Type in (302, 303) + and subscribers.Last = 1 + and subscribers.String2 = ? + and subscribers.Height is not null + order by random() + limit ? + )) + order by rnk + limit ? + ) + --group by Rates.String2 + group by Contents.Id + having count(*) > ? + order by count(*) desc + ) recomendations + group by recomendations.String1 + order by recomendations.count desc limit ? )sql"; @@ -643,65 +669,65 @@ namespace PocketDb int i = 1; for (const auto& contenttype: contentTypes) TryBindStatementInt(stmt, i++, contenttype); - for (const auto& contenttype: contentTypes) - TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, contentid); - TryBindStatementInt(stmt, i++, depth); - TryBindStatementText(stmt, i++, contentid); - TryBindStatementText(stmt, i++, contentid); + + TryBindStatementText(stmt, i++, contentAddress); + if (!address.empty()) + TryBindStatementText(stmt, i++, address); + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + + TryBindStatementInt(stmt, i++, nHeight-depth); + + TryBindStatementInt(stmt, i++, minReputation); + TryBindStatementText(stmt, i++, contentAddress); + TryBindStatementInt(stmt, i++, limitSubscriptions); + + TryBindStatementInt(stmt, i++, minReputation); + TryBindStatementText(stmt, i++, contentAddress); + TryBindStatementInt(stmt, i++, limitSubscriptions); + + TryBindStatementInt(stmt, i++, limitSubscriptionsTotal); + + TryBindStatementInt(stmt, i++, cntRates); + TryBindStatementInt(stmt, i++, cntOut); while (sqlite3_step(*stmt) == SQLITE_ROW) { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("contentid", value); - result.push_back(record); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 0); ok) + ids.push_back(value); } FinalizeSqlStatement(*stmt); }); - return result; + return ids; } - UniValue SearchRepository::GetRecomendedContentsByScoresFromAddress(const string& address, const vector& contentTypes, int nHeight, int depth, int cntOut) + vector SearchRepository::GetRandomContentByAddress(const string& contentAddress, const vector& contentTypes, const string& lang, int cntOut) { auto func = __func__; - UniValue result(UniValue::VARR); + vector ids; - if (address.empty()) - return result; + if (contentAddress.empty()) + return ids; string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); + string langFilter = ""; + if (!lang.empty()) + langFilter = "cross join Payload lang on lang.TxHash = Contents.Hash and lang.String1 = ?"; + string sql = R"sql( - select OtherRaters.String2 as OtherScoredContent, count(*) cnt - from Transactions OtherRaters indexed by Transactions_Type_Last_String1_Height_Id - cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height - on OtherRaters.String2 = Contents.String2 and Contents.Last = 1 and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) and Contents.Height > 0 - where OtherRaters.String1 in ( - select Scores.String1 as Rater - from Transactions Scores indexed by Transactions_Type_Last_String2_Height - where Scores.String2 in ( - select addressScores.String2 as ContentsScoredByAddress - from Transactions addressScores indexed by Transactions_Type_Last_String1_Height_Id - where addressScores.String1 = ? - and addressScores.Type in (300) - and addressScores.Last in (1, 0) - and addressScores.Int1 > 3 - and addressScores.Height >= ? - ) - and Scores.Type in (300) - and Scores.Last in (1, 0) - and Scores.Int1 > 3 - and Scores.Height >= ? - ) - and OtherRaters.Type in (300) - and OtherRaters.Last in (1, 0) - and OtherRaters.Int1 > 3 - and OtherRaters.Height >= ? - group by OtherRaters.String2 - order by count(*) desc + select Contents.Id + from Transactions Contents indexed by Transactions_Type_Last_String1_Height_Id + )sql" + langFilter + R"sql( + where Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) + and Contents.Last = 1 + and Contents.String1 = ? + and Contents.Height > 0 + order by random() limit ? )sql"; @@ -710,24 +736,28 @@ namespace PocketDb auto stmt = SetupSqlStatement(sql); int i = 1; + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + for (const auto& contenttype: contentTypes) - TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); + TryBindStatementInt(stmt, i++, contenttype); + + TryBindStatementText(stmt, i++, contentAddress); + TryBindStatementInt(stmt, i++, cntOut); while (sqlite3_step(*stmt) == SQLITE_ROW) { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("contentid", value); - result.push_back(record); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 0); ok) + ids.push_back(value); } FinalizeSqlStatement(*stmt); }); - return result; + return ids; + + } } \ No newline at end of file diff --git a/src/pocketdb/repositories/web/SearchRepository.h b/src/pocketdb/repositories/web/SearchRepository.h index aa5c772d2..18ccf9083 100644 --- a/src/pocketdb/repositories/web/SearchRepository.h +++ b/src/pocketdb/repositories/web/SearchRepository.h @@ -34,12 +34,13 @@ namespace PocketDb vector SearchUsersOld(const SearchRequest& request); vector SearchUsers(const string& keyword); - UniValue GetRecomendedAccountsBySubscriptions(const string& address, int cntOut = 10); - UniValue GetRecomendedAccountsByScoresOnSimilarAccounts(const string& address, const vector& contentTypes, int nHeight, int depth = 1000, int cntOut = 10); - UniValue GetRecomendedAccountsByScoresFromAddress(const string& address, const vector& contentTypes, int nHeight, int depth = 1000, int cntOut = 10); - UniValue GetRecomendedAccountsByTags(const vector& tags, int nHeight, int depth = 1000, int cntOut = 10); - UniValue GetRecomendedContentsByScoresOnSimilarContents(const string& contentid, const vector& contentTypes, int depth = 1000, int cntOut = 10); - UniValue GetRecomendedContentsByScoresFromAddress(const string& address, const vector& contentTypes, int nHeight, int depth = 1000, int cntOut = 10); + //TODO (o1q): remove it + vector GetRecommendedAccountByAddressSubscriptionsOld(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); + vector GetRecommendedContentByAddressSubscriptionsOld(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); + + vector GetRecommendedAccountByAddressSubscriptions(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */); + vector GetRecommendedContentByAddressSubscriptions(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */); + vector GetRandomContentByAddress(const string& contentAddress, const vector& contentTypes, const string& lang, int cntOut); }; typedef shared_ptr SearchRepositoryRef; diff --git a/src/pocketdb/repositories/web/WebRpcRepository.cpp b/src/pocketdb/repositories/web/WebRpcRepository.cpp index e1f9e3478..505d54870 100644 --- a/src/pocketdb/repositories/web/WebRpcRepository.cpp +++ b/src/pocketdb/repositories/web/WebRpcRepository.cpp @@ -190,10 +190,11 @@ namespace PocketDb string sql = R"sql( select + u.Id as AddressId, u.String1 as Address, - (select reg.Time from Transactions reg indexed by Transactions_Id - where reg.Id=u.Id and reg.Height=(select min(reg1.Height) from Transactions reg1 indexed by Transactions_Id where reg1.Id=reg.Id)) as RegistrationDate, + reg.Time as RegistrationDate, + reg.Height as RegistrationHeight, ifnull((select r.Value from Ratings r indexed by Ratings_Type_Id_Last_Height where r.Type=0 and r.Id=u.Id and r.Last=1),0) as Reputation, @@ -223,10 +224,16 @@ namespace PocketDb where p.Type in (301) and p.String1=u.String1 and (p.Height>=? or p.Height isnull)) as ScoreCommentSpent, (select count(1) from Transactions p indexed by Transactions_Type_String1_Height_Time_Int1 - where p.Type in (307) and p.String1=u.String1 and (p.Height>=? or p.Height isnull)) as ComplainSpent + where p.Type in (307) and p.String1=u.String1 and (p.Height>=? or p.Height isnull)) as ComplainSpent, + + (select count(1) from Transactions p indexed by Transactions_Type_String1_Height_Time_Int1 + where p.Type in (410) and p.String1=u.String1 and (p.Height>=? or p.Height isnull)) as FlagsSpent from Transactions u indexed by Transactions_Type_Last_String1_Height_Id + cross join Transactions reg indexed by Transactions_Id + on reg.Id = u.Id and reg.Height = (select min(reg1.Height) from Transactions reg1 indexed by Transactions_Id where reg1.Id = reg.Id) + where u.Type in (100, 101, 102) and u.Height is not null and u.String1 = ? @@ -248,19 +255,23 @@ namespace PocketDb if (sqlite3_step(*stmt) == SQLITE_ROW) { - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) result.pushKV("address", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 1); ok) result.pushKV("user_reg_date", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 2); ok) result.pushKV("reputation", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 3); ok) result.pushKV("balance", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 4); ok) result.pushKV("likers", value); - - if (auto[ok, value] = TryGetColumnInt64(*stmt, 5); ok) result.pushKV("post_spent", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 6); ok) result.pushKV("video_spent", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 7); ok) result.pushKV("article_spent", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 8); ok) result.pushKV("comment_spent", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 9); ok) result.pushKV("score_spent", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 10); ok) result.pushKV("comment_score_spent", value); - if (auto[ok, value] = TryGetColumnInt64(*stmt, 11); ok) result.pushKV("complain_spent", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 0); ok) result.pushKV("address_id", value); + if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) result.pushKV("address", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 2); ok) result.pushKV("user_reg_date", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 3); ok) result.pushKV("user_reg_height", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 4); ok) result.pushKV("reputation", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 5); ok) result.pushKV("balance", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 6); ok) result.pushKV("likers", value); + + if (auto[ok, value] = TryGetColumnInt64(*stmt, 7); ok) result.pushKV("post_spent", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 8); ok) result.pushKV("video_spent", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 9); ok) result.pushKV("article_spent", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 10); ok) result.pushKV("comment_spent", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 11); ok) result.pushKV("score_spent", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 12); ok) result.pushKV("comment_score_spent", value); + if (auto[ok, value] = TryGetColumnInt64(*stmt, 13); ok) result.pushKV("complain_spent", value); + + if (auto[ok, value] = TryGetColumnInt64(*stmt, 14); ok) result.pushKV("mod_flag_spent", value); } FinalizeSqlStatement(*stmt); @@ -417,6 +428,20 @@ namespace PocketDb ) ),0) as ReferralsCount + , u.Hash as AccountHash + + , ( + select json_group_object(gr.Type, gr.Cnt) + from ( + select (f.Int1)Type, (count())Cnt + from Transactions f indexed by Transactions_Type_Last_String3_Height + where f.Type in ( 410 ) + and f.Last = 0 + and f.String3 = u.String1 + group by f.Int1 + )gr + ) as FlagsJson + )sql"; } @@ -492,12 +517,14 @@ namespace PocketDb { auto stmt = SetupSqlStatement(sql); + // Bind parameters int i = 1; for (const string& address : addresses) TryBindStatementText(stmt, i++, address); for (int64_t id : ids) TryBindStatementInt64(stmt, i++, id); + // Fetch data while (sqlite3_step(*stmt) == SQLITE_ROW) { auto[ok0, address] = TryGetColumnString(*stmt, 0); @@ -551,6 +578,14 @@ namespace PocketDb } if (auto[ok, value] = TryGetColumnInt(*stmt, 21); ok) record.pushKV("rc", value); + if (auto[ok, value] = TryGetColumnString(*stmt, 22); ok) record.pushKV("hash", value); + + if (auto[ok, value] = TryGetColumnString(*stmt, 23); ok) + { + UniValue flags(UniValue::VOBJ); + flags.read(value); + record.pushKV("flags", flags); + } } result.emplace_back(address, id, record); @@ -1429,6 +1464,136 @@ namespace PocketDb return UniValue(UniValue::VARR); } + vector WebRpcRepository::GetTopAccounts(int topHeight, int countOut, const string& lang, + const vector& tags, const vector& contentTypes, + const vector& adrsExcluded, const vector& tagsExcluded, int depth, + int badReputationLimit) + { + auto func = __func__; + vector result; + + if (contentTypes.empty()) + return result; + + // -------------------------------------------- + + string contentTypesWhere = " ( " + join(vector(contentTypes.size(), "?"), ",") + " ) "; + + string langFilter; + if (!lang.empty()) + langFilter += " cross join Payload p indexed by Payload_String1_TxHash on p.TxHash = u.Hash and p.String1 = ? "; + + string sql = R"sql( + select t.String1 + + from Transactions t indexed by Transactions_Last_Id_Height + + cross join Ratings cr indexed by Ratings_Type_Id_Last_Value + on cr.Type = 2 and cr.Last = 1 and cr.Id = t.Id and cr.Value > 0 + + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) and u.Last = 1 and u.Height > 0 and u.String1 = t.String1 + + )sql" + langFilter + R"sql( + + left join Ratings ur indexed by Ratings_Type_Id_Last_Height + on ur.Type = 0 and ur.Last = 1 and ur.Id = u.Id + + where t.Type in )sql" + contentTypesWhere + R"sql( + and t.Last = 1 + and t.String3 is null + and t.Height > ? + and t.Height <= ? + + -- Do not show posts from users with low reputation + and ifnull(ur.Value,0) > ? + )sql"; + + if (!tags.empty()) + { + sql += R"sql( + and t.id in ( + select tm.ContentId + from web.Tags tag indexed by Tags_Lang_Value_Id + join web.TagsMap tm indexed by TagsMap_TagId_ContentId + on tag.Id = tm.TagId + where tag.Value in ( )sql" + join(vector(tags.size(), "?"), ",") + R"sql( ) + )sql" + (!lang.empty() ? " and tag.Lang = ? " : "") + R"sql( + ) + )sql"; + } + + if (!adrsExcluded.empty()) sql += " and t.String1 not in ( " + join(vector(adrsExcluded.size(), "?"), ",") + " ) "; + if (!tagsExcluded.empty()) + { + sql += R"sql( and t.Id not in ( + select tmEx.ContentId + from web.Tags tagEx indexed by Tags_Lang_Value_Id + join web.TagsMap tmEx indexed by TagsMap_TagId_ContentId + on tagEx.Id=tmEx.TagId + where tagEx.Value in ( )sql" + join(vector(tagsExcluded.size(), "?"), ",") + R"sql( ) + )sql" + (!lang.empty() ? " and tagEx.Lang = ? " : "") + R"sql( + ) )sql"; + } + + sql += " group by t.String1 "; + sql += " order by count(*) desc "; + sql += " limit ? "; + + // --------------------------------------------- + + TryTransactionStep(func, [&]() + { + int i = 1; + auto stmt = SetupSqlStatement(sql); + + if (!lang.empty()) TryBindStatementText(stmt, i++, lang); + + for (const auto& contenttype: contentTypes) + TryBindStatementInt(stmt, i++, contenttype); + + TryBindStatementInt(stmt, i++, topHeight - depth); + TryBindStatementInt(stmt, i++, topHeight); + + TryBindStatementInt(stmt, i++, badReputationLimit); + + if (!tags.empty()) + { + for (const auto& tag: tags) + TryBindStatementText(stmt, i++, tag); + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + } + + if (!adrsExcluded.empty()) + for (const auto& exadr: adrsExcluded) + TryBindStatementText(stmt, i++, exadr); + + if (!tagsExcluded.empty()) + { + for (const auto& extag: tagsExcluded) + TryBindStatementText(stmt, i++, extag); + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + } + + TryBindStatementInt(stmt, i++, countOut); + + // --------------------------------------------- + while (sqlite3_step(*stmt) == SQLITE_ROW) + { + if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) result.push_back(value); + } + + FinalizeSqlStatement(*stmt); + }); + + // Complete! + return result; + } + UniValue WebRpcRepository::GetTags(const string& lang, int pageSize, int pageStart) { UniValue result(UniValue::VARR); @@ -1483,7 +1648,7 @@ namespace PocketDb string sql = R"sql( select Id - from Transactions + from Transactions indexed by Transactions_Hash_Height where Hash in ( )sql" + join(vector(txHashes.size(), "?"), ",") + R"sql( ) and Height is not null )sql"; @@ -1508,6 +1673,42 @@ namespace PocketDb return result; } + map WebRpcRepository::GetContentsAddresses(const vector& txHashes) + { + map result; + + if (txHashes.empty()) + return result; + + string sql = R"sql( + select Hash, String1 + from Transactions + where Hash in ( )sql" + join(vector(txHashes.size(), "?"), ",") + R"sql( ) + and Height is not null + )sql"; + + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(sql); + + int i = 1; + for (const string& txHash : txHashes) + TryBindStatementText(stmt, i++, txHash); + + while (sqlite3_step(*stmt) == SQLITE_ROW) + { + auto[ok0, contenthash] = TryGetColumnString(*stmt, 0); + auto[ok1, contentaddress] = TryGetColumnString(*stmt, 1); + if(ok0 && ok1) + result.emplace(contenthash,contentaddress); + } + + FinalizeSqlStatement(*stmt); + }); + + return result; + } + UniValue WebRpcRepository::GetUnspents(const vector& addresses, int height, vector>& mempoolInputs) { @@ -2008,13 +2209,13 @@ namespace PocketDb string sql = R"sql( select - c.String2 as RootTxHash, - c.Time, - c.Height, - c.String1 as addrFrom, - c.String3 as posttxid, - c.String4 as parentid, - c.String5 as answerid + a.String2 as RootTxHash, + a.Time, + a.Height, + a.String1 as addrFrom, + a.String3 as posttxid, + a.String4 as parentid, + a.String5 as answerid from Transactions c indexed by Transactions_Type_Last_String1_String2_Height join Transactions a indexed by Transactions_Type_Last_Height_String5_String1 on a.Type in (204, 205) and a.Height > ? and a.Last = 1 and a.String5 = c.String2 and a.String1 != c.String1 @@ -2604,6 +2805,160 @@ namespace PocketDb return result; } + UniValue WebRpcRepository::GetTopFeed(int countOut, const int64_t& topContentId, int topHeight, + const string& lang, const vector& tags, const vector& contentTypes, + const vector& txidsExcluded, const vector& adrsExcluded, const vector& tagsExcluded, + const string& address, int depth, int badReputationLimit) + { + auto func = __func__; + UniValue result(UniValue::VARR); + + if (contentTypes.empty()) + return result; + + // -------------------------------------------- + + string contentTypesWhere = " ( " + join(vector(contentTypes.size(), "?"), ",") + " ) "; + + string contentIdWhere; + if (topContentId > 0) + contentIdWhere = " and t.Id < ? "; + + string langFilter; + if (!lang.empty()) + langFilter += " cross join Payload p indexed by Payload_String1_TxHash on p.TxHash = t.Hash and p.String1 = ? "; + + string sql = R"sql( + select t.Id + + from Transactions t indexed by Transactions_Type_Last_Height_Id + + cross join Ratings cr indexed by Ratings_Type_Id_Last_Value + on cr.Type = 2 and cr.Last = 1 and cr.Id = t.Id and cr.Value > 0 + + )sql" + langFilter + R"sql( + + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) and u.Last = 1 and u.Height > 0 and u.String1 = t.String1 + + left join Ratings ur indexed by Ratings_Type_Id_Last_Height + on ur.Type = 0 and ur.Last = 1 and ur.Id = u.Id + + where t.Type in )sql" + contentTypesWhere + R"sql( + and t.Last = 1 + --and t.String3 is null + and t.Height > ? + and t.Height <= ? + + -- Do not show posts from users with low reputation + and ifnull(ur.Value,0) > ? + + )sql" + contentIdWhere + R"sql( + )sql"; + + if (!tags.empty()) + { + sql += R"sql( + and t.id in ( + select tm.ContentId + from web.Tags tag indexed by Tags_Lang_Value_Id + join web.TagsMap tm indexed by TagsMap_TagId_ContentId + on tag.Id = tm.TagId + where tag.Value in ( )sql" + join(vector(tags.size(), "?"), ",") + R"sql( ) + )sql" + (!lang.empty() ? " and tag.Lang = ? " : "") + R"sql( + ) + )sql"; + } + + if (!txidsExcluded.empty()) sql += " and t.String2 not in ( " + join(vector(txidsExcluded.size(), "?"), ",") + " ) "; + if (!adrsExcluded.empty()) sql += " and t.String1 not in ( " + join(vector(adrsExcluded.size(), "?"), ",") + " ) "; + if (!tagsExcluded.empty()) + { + sql += R"sql( and t.Id not in ( + select tmEx.ContentId + from web.Tags tagEx indexed by Tags_Lang_Value_Id + join web.TagsMap tmEx indexed by TagsMap_TagId_ContentId + on tagEx.Id=tmEx.TagId + where tagEx.Value in ( )sql" + join(vector(tagsExcluded.size(), "?"), ",") + R"sql( ) + )sql" + (!lang.empty() ? " and tagEx.Lang = ? " : "") + R"sql( + ) )sql"; + } + + sql += " order by cr.Value desc "; + sql += " limit ? "; + + // --------------------------------------------- + + vector ids; + + TryTransactionStep(func, [&]() + { + int i = 1; + auto stmt = SetupSqlStatement(sql); + + if (!lang.empty()) TryBindStatementText(stmt, i++, lang); + + for (const auto& contenttype: contentTypes) + TryBindStatementInt(stmt, i++, contenttype); + + TryBindStatementInt(stmt, i++, topHeight - depth); + TryBindStatementInt(stmt, i++, topHeight); + + TryBindStatementInt(stmt, i++, badReputationLimit); + + if (topContentId > 0) + TryBindStatementInt64(stmt, i++, topContentId); + + if (!tags.empty()) + { + for (const auto& tag: tags) + TryBindStatementText(stmt, i++, tag); + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + } + + if (!txidsExcluded.empty()) + for (const auto& extxid: txidsExcluded) + TryBindStatementText(stmt, i++, extxid); + + if (!adrsExcluded.empty()) + for (const auto& exadr: adrsExcluded) + TryBindStatementText(stmt, i++, exadr); + + if (!tagsExcluded.empty()) + { + for (const auto& extag: tagsExcluded) + TryBindStatementText(stmt, i++, extag); + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + } + + TryBindStatementInt(stmt, i++, countOut); + + // --------------------------------------------- + + while (sqlite3_step(*stmt) == SQLITE_ROW) + { + auto[ok0, contentId] = TryGetColumnInt64(*stmt, 0); + ids.push_back(contentId); + } + + FinalizeSqlStatement(*stmt); + }); + + // Get content data + if (!ids.empty()) + { + auto contents = GetContentsData(ids, address); + result.push_backV(contents); + } + + // Complete! + return result; + } + UniValue WebRpcRepository::GetProfileFeed(const string& addressFeed, int countOut, const int64_t& topContentId, int topHeight, const string& lang, const vector& tags, const vector& contentTypes, const vector& txidsExcluded, const vector& adrsExcluded, const vector& tagsExcluded, @@ -3410,7 +3765,6 @@ namespace PocketDb } // --------------------------------------------- - LogPrintf(sqlite3_expanded_sql(*stmt)); while (sqlite3_step(*stmt) == SQLITE_ROW) { @@ -3670,4 +4024,154 @@ namespace PocketDb return result; } + UniValue WebRpcRepository::GetContentActions(const string& postTxHash) + { + auto func = __func__; + UniValue resultScores(UniValue::VARR); + UniValue resultBoosts(UniValue::VARR); + UniValue resultDonations(UniValue::VARR); + UniValue result(UniValue::VOBJ); + + string sql = R"sql( + --scores + select + s.String2 as ContentTxHash, + s.String1 as AddressHash, + p.String2 as AccountName, + p.String3 as AccountAvatar, + r.Value as AccountReputation, + s.Int1 as ScoreValue, + 0 as sumBoost, + 0 as sumDonation + from Transactions s indexed by Transactions_Type_Last_String2_Height + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.String1 = s.String1 and u.Type in (100) and u.Last = 1 and u.Height > 0 + left join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id and r.Type = 0 and r.Last = 1 + cross join Payload p on p.TxHash = u.Hash + where s.Type in (300) + and s.Last in (0,1) + and s.Height > 0 + and s.String2 = ? + + --boosts + union + + select + tb.String2 as ContentTxHash, + tb.String1 as AddressHash, + p.String2 as AccountName, + p.String3 as AccountAvatar, + r.Value as AccountReputation, + 0 as ScoreValue, + tb.sumBoost as sumBoost, + 0 as sumDonation + from + ( + select + b.String1, + b.String2, + sum(b.Int1) as sumBoost + from Transactions b indexed by Transactions_Type_Last_String2_Height + where b.Type in (208) + and b.Last in (0,1) + and b.Height > 0 + and b.String2 = ? + group by + b.String1, + b.String2 + )tb + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.String1 = tb.String1 and u.Type in (100) and u.Last = 1 and u.Height > 0 + left join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id and r.Type = 0 and r.Last = 1 + cross join Payload p on p.TxHash = u.Hash + + --donations + union + + select + td.String3 as ContentTxHash, + td.String1 as AddressHash, + p.String2 as AccountName, + p.String3 as AccountAvatar, + r.Value as AccountReputation, + 0 as ScoreValue, + 0 as sumBoost, + td.sumDonation as sumDonation + from + ( + select + comment.String1, + comment.String3, + sum(o.Value) as sumDonation + from Transactions comment indexed by Transactions_Type_Last_String3_Height + join Transactions content indexed by Transactions_Type_Last_String2_Height + on content.String2 = comment.String3 + and content.Type in (200,201,202) + and content.Last = 1 + and content.Height is not null + join TxOutputs o indexed by TxOutputs_TxHash_AddressHash_Value + on o.TxHash = comment.Hash + and o.AddressHash = content.String1 + and o.AddressHash != comment.String1 + and o.Value > 0 + where comment.Type in (204, 205, 206) + and comment.Height is not null + and comment.Last = 1 + and comment.String3 = ? + group by + comment.String1, + comment.String3 + )td + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.String1 = td.String1 and u.Type in (100) and u.Last = 1 and u.Height > 0 + left join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id and r.Type = 0 and r.Last = 1 + cross join Payload p on p.TxHash = u.Hash + )sql"; + + TryTransactionStep(func, [&]() + { + auto stmt = SetupSqlStatement(sql); + + int i = 1; + TryBindStatementText(stmt, i++, postTxHash); + TryBindStatementText(stmt, i++, postTxHash); + TryBindStatementText(stmt, i++, postTxHash); + + // --------------------------------------------- + + while (sqlite3_step(*stmt) == SQLITE_ROW) + { + UniValue record(UniValue::VOBJ); + if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("posttxid", value); + if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) record.pushKV("address", value); + if (auto[ok, value] = TryGetColumnString(*stmt, 2); ok) record.pushKV("name", value); + if (auto[ok, value] = TryGetColumnString(*stmt, 3); ok) record.pushKV("avatar", value); + if (auto[ok, value] = TryGetColumnString(*stmt, 4); ok) record.pushKV("reputation", value); + if (auto[ok, value] = TryGetColumnInt(*stmt, 5); ok && value > 0) { + record.pushKV("value", value); + resultScores.push_back(record); + } + if (auto[ok, value] = TryGetColumnInt(*stmt, 6); ok && value > 0) { + record.pushKV("value", value); + resultBoosts.push_back(record); + } + if (auto[ok, value] = TryGetColumnInt(*stmt, 7); ok && value > 0) { + record.pushKV("value", value); + resultDonations.push_back(record); + } + } + + FinalizeSqlStatement(*stmt); + }); + + result.pushKV("scores",resultScores); + result.pushKV("boosts",resultBoosts); + result.pushKV("donations",resultDonations); + + return result; + } + } \ No newline at end of file diff --git a/src/pocketdb/repositories/web/WebRpcRepository.h b/src/pocketdb/repositories/web/WebRpcRepository.h index 6ec0126ed..39c52df8b 100644 --- a/src/pocketdb/repositories/web/WebRpcRepository.h +++ b/src/pocketdb/repositories/web/WebRpcRepository.h @@ -84,10 +84,15 @@ namespace PocketDb UniValue GetSubscribesAddresses(const string& address, const vector& types = {ACTION_SUBSCRIBE, ACTION_SUBSCRIBE_PRIVATE }); UniValue GetSubscribersAddresses(const string& address, const vector& types = {ACTION_SUBSCRIBE, ACTION_SUBSCRIBE_PRIVATE }); UniValue GetBlockingToAddresses(const string& address); + vector GetTopAccounts(int topHeight, int countOut, const string& lang, + const vector& tags, const vector& contentTypes, + const vector& adrsExcluded, const vector& tagsExcluded, int depth, + int badReputationLimit); UniValue GetTags(const string& lang, int pageSize, int pageStart); vector GetContentIds(const vector& txHashes); + map GetContentsAddresses(const vector& txHashes); UniValue GetUnspents(const vector& addresses, int height, vector>& mempoolInputs); @@ -109,6 +114,11 @@ namespace PocketDb vector GetContentsData(const vector& ids, const string& address); UniValue GetHotPosts(int countOut, const int depth, const int nHeight, const string& lang, const vector& contentTypes, const string& address, int badReputationLimit); + + UniValue GetTopFeed(int countOut, const int64_t& topContentId, int topHeight, const string& lang, + const vector& tags, const vector& contentTypes, const vector& txidsExcluded, + const vector& adrsExcluded, const vector& tagsExcluded, const string& address, int depth, + int badReputationLimit); UniValue GetProfileFeed(const string& addressFeed, int countOut, const int64_t& topContentId, int topHeight, const string& lang, const vector& tags, const vector& contentTypes, const vector& txidsExcluded, @@ -137,6 +147,8 @@ namespace PocketDb vector GetRandomContentIds(const string& lang, int count, int height); + UniValue GetContentActions(const string& postTxHash); + // TODO (o1q): Remove this two methods when the client gui switches to new methods UniValue GetProfileFeedOld(const string& addressFrom, const string& addressTo, int64_t topContentId, int count, const string& lang, const vector& tags, const vector& contentTypes); UniValue GetSubscribesFeedOld(const string& addressFrom, int64_t topContentId, int count, const string& lang, const vector& tags, const vector& contentTypes); diff --git a/src/pocketdb/services/Accessor.cpp b/src/pocketdb/services/Accessor.cpp index c6722adbe..0240ed07c 100644 --- a/src/pocketdb/services/Accessor.cpp +++ b/src/pocketdb/services/Accessor.cpp @@ -39,6 +39,9 @@ namespace PocketServices if (!GetBlock(block, pocketBlock)) return false; + if (!pocketBlock) + return true; + auto dataPtr = PocketServices::Serializer::SerializeBlock(*pocketBlock); if (dataPtr) data = dataPtr->write(); @@ -48,6 +51,9 @@ namespace PocketServices bool Accessor::GetTransaction(const CTransaction& tx, PTransactionRef& pocketTx) { + if (!PocketHelpers::TransactionHelper::IsPocketSupportedTransaction(tx)) + return true; + pocketTx = PocketDb::TransRepoInst.Get(tx.GetHash().GetHex(), true); return pocketTx != nullptr; } @@ -55,12 +61,12 @@ namespace PocketServices // Read transaction data for send via network bool Accessor::GetTransaction(const CTransaction& tx, string& data) { - if (!PocketHelpers::TransactionHelper::IsPocketSupportedTransaction(tx)) - return true; - PTransactionRef pocketTx; - if (!GetTransaction(tx, pocketTx) || !pocketTx) + if (!GetTransaction(tx, pocketTx)) return false; + + if (!pocketTx) + return true; auto dataPtr = PocketServices::Serializer::SerializeTransaction(*pocketTx); if (dataPtr) diff --git a/src/pocketdb/services/ChainPostProcessing.cpp b/src/pocketdb/services/ChainPostProcessing.cpp index 287357471..32094c8f8 100644 --- a/src/pocketdb/services/ChainPostProcessing.cpp +++ b/src/pocketdb/services/ChainPostProcessing.cpp @@ -37,22 +37,19 @@ namespace PocketServices auto& tx = block.vtx[i]; auto txType = PocketHelpers::TransactionHelper::ParseType(tx); - if (txType != TxType::NOT_SUPPORTED) + TransactionIndexingInfo txInfo; + txInfo.Hash = tx->GetHash().GetHex(); + txInfo.BlockNumber = (int) i; + txInfo.Time = tx->nTime; + txInfo.Type = txType; + + if (!tx->IsCoinBase()) { - TransactionIndexingInfo txInfo; - txInfo.Hash = tx->GetHash().GetHex(); - txInfo.BlockNumber = (int) i; - txInfo.Time = tx->nTime; - txInfo.Type = txType; - - if (!tx->IsCoinBase()) - { - for (const auto& inp : tx->vin) - txInfo.Inputs.emplace_back(inp.prevout.hash.GetHex(), inp.prevout.n); - } - - txs.emplace_back(txInfo); + for (const auto& inp : tx->vin) + txInfo.Inputs.emplace_back(inp.prevout.hash.GetHex(), inp.prevout.n); } + + txs.emplace_back(txInfo); } } @@ -100,15 +97,15 @@ namespace PocketServices continue; // Calculate ratings values - // Rating for users over posts = equals -20 and 20 - saved in int 21 = 2.1 + // Rating for users over posts = equals -0.2 and 20 - saved in int 20 = 2.0 // Rating for users over comments = equals -0.1 or 0.1 - // Rating for posts equals between -2 and 2 + // Rating for posts equals between -2 and 2 - as is // Rating for comments equals between -1 and 2 - as is switch (scoreData->ScoreType) { case PocketTx::ACTION_SCORE_CONTENT: ratingValues[RatingType::RATING_ACCOUNT][scoreData->ContentAddressId] += - (scoreData->ScoreValue - 3) * 10; + reputationConsensus->GetScoreContentAuthorValue(scoreData->ScoreValue); ratingValues[RatingType::RATING_CONTENT][scoreData->ContentId] += scoreData->ScoreValue - 3; @@ -120,7 +117,7 @@ namespace PocketServices case PocketTx::ACTION_SCORE_COMMENT: ratingValues[RatingType::RATING_ACCOUNT][scoreData->ContentAddressId] += - scoreData->ScoreValue; + reputationConsensus->GetScoreCommentAuthorValue(scoreData->ScoreValue); ratingValues[RatingType::RATING_COMMENT][scoreData->ContentId] += scoreData->ScoreValue; diff --git a/src/pocketdb/services/Serializer.cpp b/src/pocketdb/services/Serializer.cpp index 1cd0d1e70..79f6fae76 100644 --- a/src/pocketdb/services/Serializer.cpp +++ b/src/pocketdb/services/Serializer.cpp @@ -39,7 +39,7 @@ namespace PocketServices // Serialize protocol compatible with Reindexer // It makes sense to serialize only Pocket transactions that contain a payload. - shared_ptr Serializer::SerializeBlock(const PocketBlock& block) + shared_ptr Serializer::SerializeBlock(const PocketBlock& block) { auto result = make_shared(UniValue(UniValue::VOBJ)); for (const auto& transaction : block) @@ -56,7 +56,7 @@ namespace PocketServices // Serialize protocol compatible with Reindexer // It makes sense to serialize only Pocket transactions that contain a payload. - shared_ptr Serializer::SerializeTransaction(const Transaction& transaction) + shared_ptr Serializer::SerializeTransaction(const Transaction& transaction) { if (!PocketHelpers::TransactionHelper::IsPocketTransaction(*transaction.GetType())) return nullptr; @@ -72,8 +72,7 @@ namespace PocketServices return result; } - - shared_ptr Serializer::buildInstance(const CTransactionRef& tx, const UniValue& src) + shared_ptr Serializer::buildInstance(const CTransactionRef& tx, const UniValue& src) { TxType txType; if (!PocketHelpers::TransactionHelper::IsPocketSupportedTransaction(tx, txType)) @@ -113,7 +112,7 @@ namespace PocketServices return ptx; } - shared_ptr Serializer::buildInstanceRpc(const CTransactionRef& tx, const UniValue& src) + shared_ptr Serializer::buildInstanceRpc(const CTransactionRef& tx, const UniValue& src) { TxType txType; if (!PocketHelpers::TransactionHelper::IsPocketSupportedTransaction(tx, txType)) @@ -135,7 +134,7 @@ namespace PocketServices return ptx; } - bool Serializer::buildInputs(const CTransactionRef& tx, shared_ptr & ptx) + bool Serializer::buildInputs(const CTransactionRef& tx, shared_ptr& ptx) { string spentTxHash = tx->GetHash().GetHex(); @@ -154,7 +153,7 @@ namespace PocketServices return !ptx->Inputs().empty(); } - bool Serializer::buildOutputs(const CTransactionRef& tx, shared_ptr & ptx) + bool Serializer::buildOutputs(const CTransactionRef& tx, shared_ptr& ptx) { string txHash = tx->GetHash().GetHex(); diff --git a/src/pocketdb/web/PocketAccountRpc.cpp b/src/pocketdb/web/PocketAccountRpc.cpp index 7cc92013d..e51c00b22 100644 --- a/src/pocketdb/web/PocketAccountRpc.cpp +++ b/src/pocketdb/web/PocketAccountRpc.cpp @@ -51,14 +51,14 @@ namespace PocketWeb::PocketWebRpc "\nReturn Pocketnet user profile.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, ""}, - {"shortForm", /* TODO (losty-rpc): is this really string? */RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""} + {"shortForm", /* TODO (rpc): is this really string? */RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""} }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("getuserprofile", "123123abd123 1") + HelpExampleRpc("getuserprofile", "123123abd123 1") + HelpExampleCli("getuserprofile", "123123abd123") + @@ -108,10 +108,10 @@ namespace PocketWeb::PocketWebRpc {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, ""} }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("getuseraddress", "") + HelpExampleRpc("getuseraddress", "") }, @@ -151,7 +151,7 @@ namespace PocketWeb::PocketWebRpc }, }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("getaddressregistration", "[\"addresses\",...]") + HelpExampleRpc("getaddressregistration", "[\"addresses\",...]") }, @@ -191,10 +191,10 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::NO, ""} }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("getuserstate", "ad123ab123fd") + HelpExampleRpc("getuserstate", "ad123ab123fd") }, @@ -217,8 +217,10 @@ namespace PocketWeb::PocketWebRpc if (result["address"].isNull()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pocketcoin address not found : " + address); - // Calculate additional fields + // Cechk account permissions + AccountData accountData = { result["address_id"].get_int64(), result["reputation"].get_int64(), result["user_reg_height"].get_int64(), result["likers"].get_int64() }; auto accountMode = reputationConsensus->GetAccountMode(result["reputation"].get_int(), result["balance"].get_int64()); + auto accountIsShark = reputationConsensus->IsShark(accountData); result.pushKV("mode", accountMode); result.pushKV("trial", accountMode == AccountMode_Trial); @@ -283,6 +285,16 @@ namespace PocketWeb::PocketWebRpc if (!result["score_spent"].isNull()) result.pushKV("score_unspent", scoreLimit - result["score_spent"].get_int()); + if (!result["mod_flag_spent"].isNull()) + result.pushKV("mod_flag_unspent", reputationConsensus->GetConsensusLimit(ConsensusLimit_moderation_flag_count) - result["mod_flag_spent"].get_int()); + + if (accountIsShark) + { + UniValue badges(UniValue::VARR); + badges.push_back("shark"); + result.pushKV("badges", badges); + } + return result; }, }; @@ -305,10 +317,10 @@ namespace PocketWeb::PocketWebRpc }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("txunspent", "") + HelpExampleRpc("txunspent", "") }, @@ -401,10 +413,10 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::NO, ""} }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("getaccountsetting", "123abacf12") + HelpExampleRpc("getaccountsetting", "123abacf12") }, @@ -433,10 +445,10 @@ namespace PocketWeb::PocketWebRpc {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Depth of statistic. Default - whole history"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("getuserstatistic", "[\"addresses\", ...], height, depth") + HelpExampleRpc("getuserstatistic", "[\"addresses\", ...], height, depth") }, @@ -501,10 +513,10 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::NO, ""}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("GetAccountSubscribes", "\"address\"") + HelpExampleRpc("GetAccountSubscribes", "\"address\"") }, @@ -527,10 +539,10 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::NO, ""}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("GetAccountSubscribers", "\"address\"") + HelpExampleRpc("GetAccountSubscribers", "\"address\"") }, @@ -553,10 +565,10 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::NO, ""}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("GetAccountBlockings", "\"address\"") + HelpExampleRpc("GetAccountBlockings", "\"address\"") }, @@ -571,4 +583,92 @@ namespace PocketWeb::PocketWebRpc }; } + RPCHelpMan GetTopAccounts() + { + return RPCHelpMan{"GetTopAccounts", + "\nReturn top accounts based on their content ratings\n", + { + // TODO (rpc): provide inputs description + }, + { + // TODO (rpc): provide return description + }, + RPCExamples{ + // TODO (rpc): provide correct examples + HelpExampleCli("GetTopAccounts", "\"address\"") + + HelpExampleRpc("GetTopAccounts", "\"address\"") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + { + int topHeight = ::ChainActive().Height(); + if (request.params.size() > 0 && request.params[0].isNum() && request.params[0].get_int() > 0) + topHeight = request.params[0].get_int(); + + int countOut = 15; + if (request.params.size() > 1 && request.params[1].isNum()) + countOut = request.params[1].get_int(); + + string lang = ""; + if (request.params.size() > 2 && request.params[2].isStr()) + lang = request.params[2].get_str(); + + vector tags; + if (request.params.size() > 3) + ParseRequestTags(request.params[3], tags); + + vector contentTypes; + if (request.params.size() > 4) + ParseRequestContentTypes(request.params[4], contentTypes); + + vector adrsExcluded; + if (request.params.size() > 5) + { + if (request.params[5].isStr() && !request.params[5].get_str().empty()) + { + adrsExcluded.push_back(request.params[5].get_str()); + } + else if (request.params[5].isArray()) + { + UniValue adrs = request.params[5].get_array(); + for (unsigned int idx = 0; idx < adrs.size(); idx++) + { + string adrEx = boost::trim_copy(adrs[idx].get_str()); + if (!adrEx.empty()) + adrsExcluded.push_back(adrEx); + + if (adrsExcluded.size() > 100) + break; + } + } + } + + vector tagsExcluded; + if (request.params.size() > 6) + ParseRequestTags(request.params[6], tagsExcluded); + + int depth = 60 * 24 * 30 * 12; // about 1 year + if (request.params.size() > 7) + { + RPCTypeCheckArgument(request.params[7], UniValue::VNUM); + depth = std::min(depth, request.params[7].get_int()); + } + + auto reputationConsensus = ReputationConsensusFactoryInst.Instance(::ChainActive().Height()); + auto badReputationLimit = reputationConsensus->GetConsensusLimit(ConsensusLimit_bad_reputation); + + UniValue result(UniValue::VARR); + auto ids = request.DbConnection()->WebRpcRepoInst->GetTopAccounts(topHeight, countOut, lang, tags, contentTypes, + adrsExcluded, tagsExcluded, depth, badReputationLimit); + if (!ids.empty()) + { + auto profiles = request.DbConnection()->WebRpcRepoInst->GetAccountProfiles(ids, true); + for (const auto[id, record] : profiles) + result.push_back(record); + } + + return result; + }, + }; + } + } \ No newline at end of file diff --git a/src/pocketdb/web/PocketAccountRpc.h b/src/pocketdb/web/PocketAccountRpc.h index f3d795de4..c588f29a8 100644 --- a/src/pocketdb/web/PocketAccountRpc.h +++ b/src/pocketdb/web/PocketAccountRpc.h @@ -7,6 +7,7 @@ #include "rpc/server.h" // #include "rpc/rawtransaction.h" +#include "pocketdb/web/WebRpcUtils.h" #include "pocketdb/consensus/Reputation.h" namespace PocketWeb::PocketWebRpc @@ -25,6 +26,7 @@ namespace PocketWeb::PocketWebRpc RPCHelpMan GetAccountSubscribes(); RPCHelpMan GetAccountSubscribers(); RPCHelpMan GetAccountBlockings(); + RPCHelpMan GetTopAccounts(); } diff --git a/src/pocketdb/web/PocketCommentsRpc.cpp b/src/pocketdb/web/PocketCommentsRpc.cpp index 2ce677a36..738e10014 100644 --- a/src/pocketdb/web/PocketCommentsRpc.cpp +++ b/src/pocketdb/web/PocketCommentsRpc.cpp @@ -21,7 +21,7 @@ namespace PocketWeb::PocketWebRpc }, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getcomments", "\"postid\", \"parentid\", \"address\", [\"commend_id\",\"commend_id\",...]") + @@ -75,7 +75,7 @@ namespace PocketWeb::PocketWebRpc {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, ""} }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getlastcomments", "") + diff --git a/src/pocketdb/web/PocketContentRpc.cpp b/src/pocketdb/web/PocketContentRpc.cpp index 7902728bc..7ce041f68 100644 --- a/src/pocketdb/web/PocketContentRpc.cpp +++ b/src/pocketdb/web/PocketContentRpc.cpp @@ -100,17 +100,19 @@ namespace PocketWeb::PocketWebRpc } } - // feed's address if (request.params.size() > 10) { - RPCTypeCheckArgument(request.params[10], UniValue::VSTR); - address_feed = request.params[10].get_str(); - if (!address_feed.empty()) + // feed's address + if (request.params[10].isStr()) { - CTxDestination dest = DecodeDestination(address_feed); + address_feed = request.params[10].get_str(); + if (!address_feed.empty()) + { + CTxDestination dest = DecodeDestination(address_feed); - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address_feed); + if (!IsValidDestination(dest)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address_feed); + } } } } @@ -134,7 +136,7 @@ namespace PocketWeb::PocketWebRpc } }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getcontent", "ids[]") + @@ -186,7 +188,7 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "A pocketcoin addresses to filter"} }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description // {RPCResult::Type::ARR, "", "", {}} }, RPCExamples{ @@ -214,7 +216,7 @@ namespace PocketWeb::PocketWebRpc {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, ""} }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getprofilefeed", "") + @@ -281,7 +283,7 @@ namespace PocketWeb::PocketWebRpc "", {}, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ "" @@ -392,10 +394,10 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): more examples + // TODO (rpc): more examples HelpExampleCli("GetHistoricalFeed", "123123123123") + HelpExampleRpc("GetHistoricalFeed", "123123123123") }, @@ -476,10 +478,10 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): more examples + // TODO (rpc): more examples HelpExampleCli("GetHierarchicalFeed", "1231231414") + HelpExampleRpc("GetHierarchicalFeed", "1231231414") }, @@ -522,6 +524,81 @@ namespace PocketWeb::PocketWebRpc }; } + RPCHelpMan GetTopFeed() + { + return RPCHelpMan{"gettopfeed", + "\nReturns top contents\n", + { + // TODO (team): provide arguments description + }, + { + // TODO (rpc): provide return description + }, + RPCExamples{ + HelpExampleCli("getsubscribesfeed", "") + + HelpExampleRpc("getsubscribesfeed", "") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + { + // if (request.fHelp) + // throw runtime_error( + // "GetTopFeed\n" + // "topHeight (int) - ???\n" + // "topContentHash (string, optional) - ???\n" + // "countOut (int, optional) - ???\n" + // "lang (string, optional) - ???\n" + // "tags (vector, optional) - ???\n" + // "contentTypes (vector, optional) - ???\n" + // "txIdsExcluded (vector, optional) - ???\n" + // "adrsExcluded (vector, optional) - ???\n" + // "tagsExcluded (vector, optional) - ???\n" + // "address (string, optional) - ???\n" + // "depth (int, optional) - ???\n" + // ); + + int topHeight; + string topContentHash; + int countOut; + string lang; + vector tags; + vector contentTypes; + vector txIdsExcluded; + vector adrsExcluded; + vector tagsExcluded; + string address; + int depth = 60 * 24 * 30 * 12; // about 1 year + ParseFeedRequest(request, topHeight, topContentHash, countOut, lang, tags, contentTypes, txIdsExcluded, + adrsExcluded, tagsExcluded, address); + // depth + if (request.params.size() > 10) + { + RPCTypeCheckArgument(request.params[10], UniValue::VNUM); + depth = std::min(depth, request.params[10].get_int()); + } + + int64_t topContentId = 0; + if (!topContentHash.empty()) + { + auto ids = request.DbConnection()->WebRpcRepoInst->GetContentIds({topContentHash}); + if (!ids.empty()) + topContentId = ids[0]; + } + + auto reputationConsensus = ReputationConsensusFactoryInst.Instance(::ChainActive().Height()); + auto badReputationLimit = reputationConsensus->GetConsensusLimit(ConsensusLimit_bad_reputation); + + UniValue result(UniValue::VOBJ); + UniValue content = request.DbConnection()->WebRpcRepoInst->GetTopFeed( + countOut, topContentId, topHeight, lang, tags, contentTypes, + txIdsExcluded, adrsExcluded, tagsExcluded, + address, depth, badReputationLimit); + + result.pushKV("height", topHeight); + result.pushKV("contents", content); + return result; + }}; + } + RPCHelpMan GetSubscribesFeed() { return RPCHelpMan{"getsubscribesfeed", @@ -530,7 +607,7 @@ namespace PocketWeb::PocketWebRpc // TODO (team): provide arguments description }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getsubscribesfeed", "") + @@ -594,12 +671,12 @@ namespace PocketWeb::PocketWebRpc RPCHelpMan GetBoostFeed() { return RPCHelpMan{"GetHierarchicalFeed", - "\n\n", // TODO (losty-rpc): description + "\n\n", // TODO (rpc): description { // TODO (team): provide arguments description }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getsubscribesfeed", "") + @@ -737,7 +814,7 @@ namespace PocketWeb::PocketWebRpc {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Depth of content history for statistics. Default is all history"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getcontentsstatistic", "") + @@ -786,13 +863,13 @@ namespace PocketWeb::PocketWebRpc return RPCHelpMan{"GetRandomPost", "\nGet contents statistic.\n", { - // TODO (losty-rpc): provide args description + // TODO (rpc): provide args description }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc) + // TODO (rpc) HelpExampleCli("GetRandomPost", "") + HelpExampleRpc("GetRandomPost", "") }, @@ -834,4 +911,33 @@ namespace PocketWeb::PocketWebRpc }, }; } + + RPCHelpMan GetContentActions() + { + return RPCHelpMan{"GetContentActions", + "\nGet profiles that performed actions(score/boos/donate) on content.\n", + { + // TODO (rpc): provide args description + }, + { + // TODO (rpc): provide return description + }, + RPCExamples{ + // TODO (rpc) + HelpExampleCli("GetRandomPost", "") + + HelpExampleRpc("GetRandomPost", "") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + { + // if (request.fHelp) + // { + // } + + RPCTypeCheck(request.params, {UniValue::VSTR}); + + auto contentHash = request.params[0].get_str(); + return request.DbConnection()->WebRpcRepoInst->GetContentActions(contentHash); + }, + }; + } } \ No newline at end of file diff --git a/src/pocketdb/web/PocketContentRpc.h b/src/pocketdb/web/PocketContentRpc.h index ac888ea59..a1da96a32 100644 --- a/src/pocketdb/web/PocketContentRpc.h +++ b/src/pocketdb/web/PocketContentRpc.h @@ -22,11 +22,13 @@ namespace PocketWeb::PocketWebRpc RPCHelpMan GetHistoricalFeed(); RPCHelpMan GetHierarchicalFeed(); RPCHelpMan GetBoostFeed(); + RPCHelpMan GetTopFeed(); RPCHelpMan GetProfileFeed(); RPCHelpMan GetSubscribesFeed(); RPCHelpMan FeedSelector(); RPCHelpMan GetContentsStatistic(); RPCHelpMan GetRandomContents(); + RPCHelpMan GetContentActions(); } diff --git a/src/pocketdb/web/PocketExplorerRpc.cpp b/src/pocketdb/web/PocketExplorerRpc.cpp index 7a26b4202..0c6dd3f2a 100644 --- a/src/pocketdb/web/PocketExplorerRpc.cpp +++ b/src/pocketdb/web/PocketExplorerRpc.cpp @@ -17,10 +17,10 @@ namespace PocketWeb::PocketWebRpc {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Depth hours (Maximum: 24 hours)"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples // HelpExampleCli("getstatisticbyhours", "") + // HelpExampleRpc("getstatisticbyhours", "") "" @@ -50,10 +50,10 @@ namespace PocketWeb::PocketWebRpc {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Depth days (Maximum: 30 days)"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples // HelpExampleCli("getstatisticbydays", "") + // HelpExampleRpc("getstatisticbydays", "") "" @@ -81,10 +81,10 @@ namespace PocketWeb::PocketWebRpc "\nGet statistics for content transactions grouped by hours\n", {}, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): examples + // TODO (rpc): examples HelpExampleCli("getstatisticcontentbyhours", "") + HelpExampleRpc("getstatisticcontentbyhours", "") }, @@ -110,10 +110,10 @@ namespace PocketWeb::PocketWebRpc "\nGet statistics for content transactions grouped by days\n", {}, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - // TODO (losty-rpc): examples + // TODO (rpc): examples HelpExampleCli("getstatisticcontentbydays", "") + HelpExampleRpc("getstatisticcontentbydays", "") }, @@ -143,7 +143,7 @@ namespace PocketWeb::PocketWebRpc {"verbosity", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Verbosity output."}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getlastblocks", "") + @@ -225,7 +225,7 @@ namespace PocketWeb::PocketWebRpc {"blocknumber", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "The block by number"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getcompactblock", "123acbadbcca") + @@ -287,7 +287,7 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "Address"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getaddressinfo", "1bd123c12f123a123b") + @@ -335,7 +335,7 @@ namespace PocketWeb::PocketWebRpc {"count", RPCArg::Type::NUM, RPCArg::Optional::NO, "Count of records"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description // "[ [height, amount], [1000, 500], [999,495], ... ]" }, RPCExamples{ @@ -397,7 +397,7 @@ namespace PocketWeb::PocketWebRpc {"string", RPCArg::Type::STR, RPCArg::Optional::NO, "Input string"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("checkstringtype", "123123123123") + @@ -450,7 +450,7 @@ namespace PocketWeb::PocketWebRpc {"pageSize", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Page size"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getaddresstransactions", "abaa1231bca1231") + @@ -510,7 +510,7 @@ namespace PocketWeb::PocketWebRpc {"pageSize", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Page size"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("getblocktransactions", "abaa1231bca1231") + @@ -560,14 +560,14 @@ namespace PocketWeb::PocketWebRpc return RPCHelpMan{"getrawtransaction", "\nGet transaction data.\n", { - // TODO (losty-rpc) + // TODO (rpc) }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ "" - // TODO (losty-rpc) + // TODO (rpc) }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -598,7 +598,7 @@ namespace PocketWeb::PocketWebRpc }, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ // TODO (team): provide examples diff --git a/src/pocketdb/web/PocketFrontend.cpp b/src/pocketdb/web/PocketFrontend.cpp index 81fd9ae5e..861108c3f 100644 --- a/src/pocketdb/web/PocketFrontend.cpp +++ b/src/pocketdb/web/PocketFrontend.cpp @@ -5,6 +5,7 @@ // https://www.apache.org/licenses/LICENSE-2.0 #include "pocketdb/web/PocketFrontend.h" +#include "fs.h" namespace PocketWeb { @@ -74,7 +75,20 @@ namespace PocketWeb void PocketFrontend::Init() { - _rootPath = GetDataDir() / "static_files"; + string _argPath = gArgs.GetArg("-staticpath", "wwwroot"); + _rootPath = (_argPath == "wwwroot") ? GetDataDir() / "wwwroot" : _argPath; + + // Create directory structure + try + { + if (!_rootPath.empty()) + fs::create_directories(_rootPath); + } + catch (const fs::filesystem_error&) + { + if (!fs::exists(_rootPath) || !fs::is_directory(_rootPath)) + throw; + } auto testContent = shared_ptr(new StaticFile{ "/404.html", @@ -156,12 +170,7 @@ namespace PocketWeb if (!readOk) { if (!stopRecurse) - { - if (_path.find("explorer") == 0) - return GetFile("/explorer/index.html", true); - return GetFile("/index.html", true); - } return NotFound(); } diff --git a/src/pocketdb/web/PocketRpc.cpp b/src/pocketdb/web/PocketRpc.cpp index d63561ae6..6636e54f1 100644 --- a/src/pocketdb/web/PocketRpc.cpp +++ b/src/pocketdb/web/PocketRpc.cpp @@ -45,12 +45,8 @@ static const CRPCCommand commands[] = {"search", "searchusers", &SearchUsers, {"keyword", "fieldtypes", "orderbyrank"}}, // Recomendations - {"search", "getrecomendedaccountsbysubscriptions", &GetRecomendedAccountsBySubscriptions, {"address", "count"}}, - {"search", "getrecomendedaccountsbyscoresonsimilaraccounts", &GetRecomendedAccountsByScoresOnSimilarAccounts, {"address", "contenttypes", "height", "depth", "count"}}, - {"search", "getrecomendedaccountsbyscoresfromaddress", &GetRecomendedAccountsByScoresFromAddress, {"address", "contenttypes", "height", "depth", "count"}}, - {"search", "getrecomendedaccountsbytags", &GetRecomendedAccountsByTags, {"tags", "count"}}, - {"search", "getrecomendedcontentsbyscoresonsimilarcontents", &GetRecomendedContentsByScoresOnSimilarContents, {"contentid", "contenttypes", "depth", "count"}}, - {"search", "getrecomendedcontentsbyscoresfromaddress", &GetRecomendedContentsByScoresFromAddress, {"address", "contenttypes", "height", "depth", "count"}}, + {"search", "getrecommendedcontentbyaddress", &GetRecommendedContentByAddress, {"address", "addressExclude", "contenttypes", "lang", "count"}}, + {"search", "getrecommendedaccountbyaddress", &GetRecommendedAccountByAddress, {"address", "addressExclude", "contenttypes", "lang", "count"}}, // WebSocket {"websocket", "getmissedinfo", &GetMissedInfo, {"address", "blocknumber"}}, @@ -62,14 +58,16 @@ static const CRPCCommand commands[] = {"contents", "gethierarchicalfeed", &GetHierarchicalFeed, {"topHeight","topContentHash","countOut","lang","tags","contentTypes","txIdsExcluded","adrsExcluded","tagsExcluded","address"}}, {"contents", "gethierarchicalstrip", &GetHierarchicalFeed, {"topHeight","topContentHash","countOut","lang","tags","contentTypes","txIdsExcluded","adrsExcluded","tagsExcluded","address"}}, {"contents", "getboostfeed", &GetBoostFeed, {"topHeight","topContentHash","countOut","lang","tags","contentTypes","txIdsExcluded","adrsExcluded","tagsExcluded","address"}}, - {"contents", "getprofilefeed", &GetProfileFeed, {"topHeight","topContentHash","countOut","lang","tags","contentTypes","txIdsExcluded","adrsExcluded","tagsExcluded","address", "address_feed"}}, - {"contents", "getsubscribesfeed", &GetSubscribesFeed, {"topHeight","topContentHash","countOut","lang","tags","contentTypes","txIdsExcluded","adrsExcluded","tagsExcluded","address", "address_feed"}}, + {"contents", "gettopfeed", &GetTopFeed, {"topHeight","topContentHash","countOut","lang","tags","contentTypes","txIdsExcluded","adrsExcluded","tagsExcluded","address","depth"}}, + {"contents", "getprofilefeed", &GetProfileFeed, {"topHeight","topContentHash","countOut","lang","tags","contentTypes","txIdsExcluded","adrsExcluded","tagsExcluded","address","address_feed"}}, + {"contents", "getsubscribesfeed", &GetSubscribesFeed, {"topHeight","topContentHash","countOut","lang","tags","contentTypes","txIdsExcluded","adrsExcluded","tagsExcluded","address","address_feed"}}, {"contents", "getrawtransactionwithmessage", &FeedSelector, {"address_from", "address_to", "start_txid", "count", "lang", "tags", "contenttypes"}}, {"contents", "getrawtransactionwithmessagebyid", &GetContent, {"ids", "address"}}, {"contents", "getcontent", &GetContent, {"ids", "address"}}, {"contents", "getcontentsstatistic", &GetContentsStatistic, {"addresses", "contentTypes", "height", "depth"}}, {"contents", "getcontents", &GetContents, {"address"}}, {"contents", "getrandomcontents", &GetRandomContents, {}}, + {"contents", "getcontentactions", &GetContentActions, {"contentHash"}}, // Tags // {"artifacts", "searchtags", &gettemplate, {"search_string", "count"}}, @@ -91,6 +89,7 @@ static const CRPCCommand commands[] = {"accounts", "getusersubscribes", &GetAccountSubscribes, {"address", "height", "depth"}}, {"accounts", "getusersubscribers", &GetAccountSubscribers, {"address", "height", "depth"}}, {"accounts", "getuserblockings", &GetAccountBlockings, {"address", "height", "depth"}}, + {"accounts", "gettopaccounts", &GetTopAccounts, {"topHeight","countOut","lang","tags","contentTypes","adrsExcluded","tagsExcluded","depth"}}, // Scores {"scores", "getaddressscores", &GetAddressScores, {"address", "txs"}}, diff --git a/src/pocketdb/web/PocketScoresRpc.cpp b/src/pocketdb/web/PocketScoresRpc.cpp index 4ba1292c4..a1b87d804 100644 --- a/src/pocketdb/web/PocketScoresRpc.cpp +++ b/src/pocketdb/web/PocketScoresRpc.cpp @@ -13,7 +13,7 @@ namespace PocketWeb::PocketWebRpc return RPCHelpMan{"getaddressscores", "\nGet scores from address.\n", { - // TODO (losty-rpc): provide arguments description + // TODO (rpc): provide arguments description }, RPCResult{ RPCResult::Type::ARR, "", "", @@ -32,7 +32,7 @@ namespace PocketWeb::PocketWebRpc }, }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("getaddressscores", "") + HelpExampleRpc("getaddressscores", "") }, @@ -84,7 +84,7 @@ namespace PocketWeb::PocketWebRpc return RPCHelpMan{"getpostscores", "\nGet scores from address.\n", { - // TODO (losty-rpc): provide arguments description + // TODO (rpc): provide arguments description }, RPCResult{ RPCResult::Type::ARR, "", "", @@ -99,7 +99,7 @@ namespace PocketWeb::PocketWebRpc }, }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples HelpExampleCli("getpostscores", "") + HelpExampleRpc("getpostscores", "") }, @@ -141,7 +141,7 @@ namespace PocketWeb::PocketWebRpc { RPCResult::Type::OBJ, "", "", { - // TODO (losty-rpc): may be change above. The reason everything is optional is + // TODO (rpc): may be change above. The reason everything is optional is // that there are two types of objects in array (post or comment) // Comment scores {RPCResult::Type::STR, "cmntid", /* optional */ true, ""}, @@ -157,7 +157,7 @@ namespace PocketWeb::PocketWebRpc }, }, RPCExamples{ - // TODO (losty-rpc): provide correct examples + // TODO (rpc): provide correct examples // HelpExampleCli("getpagescores", "1231") + // HelpExampleRpc("getpagescores", "1231") "" diff --git a/src/pocketdb/web/PocketSystemRpc.cpp b/src/pocketdb/web/PocketSystemRpc.cpp index 3eae1bd9c..3def706fe 100644 --- a/src/pocketdb/web/PocketSystemRpc.cpp +++ b/src/pocketdb/web/PocketSystemRpc.cpp @@ -93,7 +93,7 @@ namespace PocketWeb::PocketWebRpc // Mutex guarded node statistic CNodeStateStats nodeState; - if (GetNodeStateStats(stats.nodeid, nodeState)) + if (GetNodeStateStatsView(stats.nodeid, nodeState)) { obj.pushKV("banscore", nodeState.m_misbehavior_score); obj.pushKV("synced_headers", nodeState.nSyncHeight); diff --git a/src/pocketdb/web/PocketTransactionRpc.cpp b/src/pocketdb/web/PocketTransactionRpc.cpp index c02d10a82..f5c7e2be9 100644 --- a/src/pocketdb/web/PocketTransactionRpc.cpp +++ b/src/pocketdb/web/PocketTransactionRpc.cpp @@ -20,13 +20,13 @@ namespace PocketWeb::PocketWebRpc "\nGet transaction data.\n" "in BIP 141 (witness data is discounted).\n", { - // TODO (losty-rpc): provide arguments description + // TODO (rpc): provide arguments description }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - "" // TODO (losty-rpc): provide examples + "" // TODO (rpc): provide examples }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -51,7 +51,7 @@ namespace PocketWeb::PocketWebRpc throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX deserialize failed"); // Set required fields - ptx->SetAddress(address); + ptx->SetString1(address); // TODO (team): TEMPORARY // Temporary check for UserConsensus_checkpoint_login_limitation checkpoint @@ -181,13 +181,13 @@ namespace PocketWeb::PocketWebRpc return RPCHelpMan{"generatetransaction", "\nAdd new pocketnet transaction.\n", { - // TODO (losty-rpc): provide arguments description + // TODO (rpc): provide arguments description }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - "" // TODO (losty-rpc): provide examples + "" // TODO (rpc): provide examples }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -303,7 +303,7 @@ namespace PocketWeb::PocketWebRpc throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX deserialize failed"); // Set required fields - ptx->SetAddress(address); + ptx->SetString1(address); // TODO (losty-fur): possible null mempool and connman // Insert into mempool @@ -319,13 +319,13 @@ namespace PocketWeb::PocketWebRpc return RPCHelpMan{"generateaddress", "\nCreate new pocketnet address.\n", { - // TODO (losty-rpc): provide arguments description + // TODO (rpc): provide arguments description }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ - "" // TODO (losty-rpc): provide examples + "" // TODO (rpc): provide examples }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -378,7 +378,7 @@ namespace PocketWeb::PocketWebRpc UniValue _accept_transaction(const CTransactionRef& tx, const PTransactionRef& ptx, CTxMemPool& mempool, CConnman& connman) { promise promise; - // CAmount nMaxRawTxFee = maxTxFee; // TODO (losty-fur): validate corresponding check is performed in wallet by using walletInstance->m_default_max_tx_fee + // CAmount nMaxRawTxFee = maxTxFee; // TODO (losty-critical): validate corresponding check is performed in wallet by using walletInstance->m_default_max_tx_fee // if (ptx && *ptx->GetType() == PocketTx::BOOST_CONTENT) // nMaxRawTxFee = 0; const uint256& txid = tx->GetHash(); diff --git a/src/pocketdb/web/SearchRpc.cpp b/src/pocketdb/web/SearchRpc.cpp index f8cbe64b8..276f5b241 100644 --- a/src/pocketdb/web/SearchRpc.cpp +++ b/src/pocketdb/web/SearchRpc.cpp @@ -21,7 +21,7 @@ namespace PocketWeb::PocketWebRpc {"address", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Filter by address"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("search", "\"keyword\", \"type\", topBlock, pageStart, pageSize, \"address\"") + @@ -177,13 +177,13 @@ namespace PocketWeb::PocketWebRpc return RPCHelpMan{"SearchUsers", "\nSearch users in DB.\n", { - // TODO (losty-rpc): update argumants probably? + // TODO (rpc): update argumants probably? {"keyword", RPCArg::Type::STR, RPCArg::Optional::NO, "String for search"}, {"fieldtype", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, {"orderbyrank", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("SearchUsers", "\"keyword\", \"fieldtype\", orderbyrank") + @@ -225,7 +225,7 @@ namespace PocketWeb::PocketWebRpc {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Number of resulting records. Default 10"}, }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ HelpExampleCli("searchlinks", "[\"links\", ...], \"contenttypes\", height, count") + @@ -275,7 +275,7 @@ namespace PocketWeb::PocketWebRpc // TODO (team): args }, { - // TODO (losty-rpc): provide return description + // TODO (rpc): provide return description }, RPCExamples{ // TODO (team): examples @@ -322,280 +322,185 @@ namespace PocketWeb::PocketWebRpc }; } - RPCHelpMan GetRecomendedAccountsBySubscriptions() + RPCHelpMan GetRecommendedContentByAddress() { - return RPCHelpMan{"getrecomendedaccountsbysubscriptions", - "\nAccounts recommendations by subscriptions.\n", - { - {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "Address for recommendations"}, - {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Number of resulting records. Default 10"}, - }, - { - // TODO (losty-rpc): provide return description - }, - RPCExamples{ - // TODO (team): examples - HelpExampleCli("getrecomendedaccountsbysubscriptions", "") + - HelpExampleRpc("getrecomendedaccountsbysubscriptions", "") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + return RPCHelpMan{"GetRecommendedContentByAddress", + "\n\n", // TODO (rpc): provide description + { + // TODO (rpc): args + }, + { + // TODO (rpc): provide return description + }, + RPCExamples{ + // TODO (team): examples + HelpExampleCli("GetRecommendedContentByAddress", "") + + HelpExampleRpc("GetRecommendedContentByAddress", "") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string address = request.params[0].get_str(); - CTxDestination dest = DecodeDestination(address); + // if (request.fHelp) + // throw runtime_error( + // "getrecommendedcontentbyaddress \"address\", \"addressExclude\", \"contenttypes\", \"lang\", count\n" + // "\nContents recommendations by content address.\n" + // "\nArguments:\n" + // "1. \"address\" (string) Address for recommendations\n" + // "2. \"addressExclude\" (string, optional) Address for exclude from recommendations\n" + // "3. \"contenttypes\" (string or array of strings, optional) type(s) of content posts/videos/articles\n" + // "3. \"lang\" (string, optional) Language for recommendations\n" + // "4. \"count\" (int, optional) Number of recommendations records and number of other contents from addres. Default 15\n" + // ); - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address); - - int cntOut = 10; - if (request.params.size() > 1 && request.params[1].isNum()) - cntOut = request.params[1].get_int(); - - return request.DbConnection()->SearchRepoInst->GetRecomendedAccountsBySubscriptions(address, cntOut); - }, - }; - } - - RPCHelpMan GetRecomendedAccountsByScoresOnSimilarAccounts() - { - return RPCHelpMan{"getrecomendedaccountsbyscoresonsimilaraccounts", - "\nAccounts recommendations by likes based on address.\n", - { - {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "Address for recommendations" }, - {"contenttypes", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "type(s) of content posts/video", - { - {"contenttype", RPCArg::Type::STR, RPCArg::Optional::NO, "" }, - } - }, - {"height", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Maximum search height. Default is current chain height" }, - {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Depth of statistic. Default 1000 blocks" }, - {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Number of resulting records. Default 10" }, - }, - { - // TODO (losty-rpc): provide return description - }, - RPCExamples{ - // TODO (team): examples - HelpExampleCli("getrecomendedaccountsbyscoresonsimilaraccounts", "\"address\", \"contenttypes\", height, depth, count") + - HelpExampleRpc("getrecomendedaccountsbyscoresonsimilaraccounts", "\"address\", \"contenttypes\", height, depth, count") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue - { RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string address = request.params[0].get_str(); - CTxDestination dest = DecodeDestination(address); - - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address); - - vector contentTypes; - ParseRequestContentTypes(request.params[1], contentTypes); - - int nHeight = ChainActive().Height(); - int depth = 1000; - int cntOut = 10; - - if (request.params.size() > 2 && request.params[2].isNum() && request.params[2].get_int() > 0) - nHeight = request.params[2].get_int(); - - if (request.params.size() > 3 && request.params[3].isNum()) - depth = request.params[3].get_int(); - - if (request.params.size() > 4 && request.params[4].isNum()) - cntOut = request.params[4].get_int(); + string address = ""; + if (request.params.size() > 0 && request.params[0].isStr()) { + address = request.params[0].get_str(); + + if(!address.empty()) { + CTxDestination dest = DecodeDestination(address); + if (!IsValidDestination(dest)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid address: ") + address); + } + } - return request.DbConnection()->SearchRepoInst->GetRecomendedAccountsByScoresOnSimilarAccounts(address, contentTypes, nHeight, depth, cntOut); - }, - }; - } + string addressExclude = ""; + if (request.params.size() > 1 && request.params[1].isStr()) { + addressExclude = request.params[1].get_str(); - RPCHelpMan GetRecomendedAccountsByScoresFromAddress() - { - return RPCHelpMan{"getrecomendedaccountsbyscoresfromaddress", - "\nAccounts recommendations by likes.\n", - { - {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "Address for recommendations" }, - {"contenttypes", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "type(s) of content posts/video", - { - {"contenttype", RPCArg::Type::STR, RPCArg::Optional::NO, "" } - } - }, - {"height", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Maximum search height. Default is current chain height" }, - {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Depth of statistic. Default 1000 blocks" }, - {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Number of resulting records. Default 10" }, - }, - { - // TODO (losty-rpc): provide return description - }, - RPCExamples{ - // TODO (team): examples - HelpExampleCli("getrecomendedaccountsbyscoresfromaddress", "\"address\", \"contenttypes\", height, depth, count") + - HelpExampleRpc("getrecomendedaccountsbyscoresfromaddress", "\"address\", \"contenttypes\", height, depth, count") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue - { - RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string address = request.params[0].get_str(); - CTxDestination dest = DecodeDestination(address); - - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address); + if(!addressExclude.empty()) { + CTxDestination dest = DecodeDestination(addressExclude); + if (!IsValidDestination(dest)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid address: ") + addressExclude); + } + } vector contentTypes; - ParseRequestContentTypes(request.params[1], contentTypes); - - int nHeight = ChainActive().Height(); - int depth = 1000; - int cntOut = 10; - - if (request.params.size() > 2 && request.params[2].isNum() && request.params[2].get_int() > 0) - nHeight = request.params[2].get_int(); + if(request.params.size()>2) + ParseRequestContentTypes(request.params[2], contentTypes); - if (request.params.size() > 3 && request.params[3].isNum()) - depth = request.params[3].get_int(); + string lang = ""; + if (request.params.size() > 3 && request.params[3].isStr()) + lang = request.params[3].get_str(); + int cntOut = 15; if (request.params.size() > 4 && request.params[4].isNum()) cntOut = request.params[4].get_int(); - return request.DbConnection()->SearchRepoInst->GetRecomendedAccountsByScoresFromAddress(address, contentTypes, nHeight, depth, cntOut); - }, - }; - } - - RPCHelpMan GetRecomendedAccountsByTags() - { - return RPCHelpMan{"getrecomendedaccountsbytags", - "\nAccounts recommendations by tags.\n", - { - {"tags", RPCArg::Type::ARR, RPCArg::Optional::NO, "Tags for recommendations", - { - {"tag", RPCArg::Type::STR, RPCArg::Optional::NO, "" } - } - }, - {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Number of resulting records. Default 10" }, - }, - { - // TODO (losty-rpc): provide return description - }, - RPCExamples{ - // TODO (team): examples - HelpExampleCli("getrecomendedaccountsbytags", "\"tags\", count") + - HelpExampleRpc("getrecomendedaccountsbytags", "\"tags\", count") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue - { - vector tags; - if (request.params.size() > 0) - ParseRequestTags(request.params[0], tags); + int nHeight = ChainActive().Height(); + if (request.params.size() > 5 && request.params[5].isNum() && request.params[5].get_int() > 0) + nHeight = request.params[5].get_int(); - if (tags.empty()) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("There are no tags in the input parameters.")); + int depth = (60 * 24 * 30 * 3); //about 3 month as default + if (request.params.size() > 6 && request.params[6].isNum()) + { + depth = std::max(request.params[6].get_int(), (60 * 24 * 30 * 6)); // not greater than about 6 month + } - int nHeight = ChainActive().Height(); - int depth = 60 * 24 * 30; // about 1 month + UniValue resultContent(UniValue::VARR); + auto ids = request.DbConnection()->SearchRepoInst->GetRecommendedContentByAddressSubscriptions(address, addressExclude, contentTypes, lang, cntOut, nHeight, depth); + if (!ids.empty()) + { + auto contents = request.DbConnection()->WebRpcRepoInst->GetContentsData(ids, ""); + resultContent.push_backV(contents); + } - int cntOut = 10; - if (request.params.size() > 1 && request.params[1].isNum()) - cntOut = request.params[1].get_int(); + ids = request.DbConnection()->SearchRepoInst->GetRandomContentByAddress(address, contentTypes, lang, cntOut); + if (!ids.empty()) + { + auto contents = request.DbConnection()->WebRpcRepoInst->GetContentsData(ids, ""); + resultContent.push_backV(contents); + } - return request.DbConnection()->SearchRepoInst->GetRecomendedAccountsByTags(tags, nHeight, depth, cntOut); + UniValue result(UniValue::VOBJ); + result.pushKV("contents", resultContent); + return result; }, }; } - RPCHelpMan GetRecomendedContentsByScoresOnSimilarContents() + RPCHelpMan GetRecommendedAccountByAddress() { - return RPCHelpMan{"getrecomendedcontentsbyscoresonsimilarcontents", - "\n\n", // TODO (team): provide description - { - {"contentid", RPCArg::Type::STR, RPCArg::Optional::NO, "Content hash for recommendations" }, - {"contenttypes", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "type(s) of content posts/video", - { - {"contenttype", RPCArg::Type::STR, RPCArg::Optional::NO, "" } - } - }, - {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Depth of statistic. Default 1000 blocks" }, - {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Number of resulting records. Default 10" }, - }, - { - // TODO (losty-rpc): provide return description - }, - RPCExamples{ - // TODO (team): examples - HelpExampleCli("getrecomendedcontentsbyscoresonsimilarcontents", "\"contentid\", \"contenttypes\", depth, count") + - HelpExampleRpc("getrecomendedcontentsbyscoresonsimilarcontents", "\"contentid\", \"contenttypes\", depth, count") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + return RPCHelpMan{"GetRecommendedContentByAddress", + "\n\n", // TODO (rpc): provide description + { + // TODO (rpc): args + }, + { + // TODO (rpc): provide return description + }, + RPCExamples{ + // TODO (team): examples + HelpExampleCli("GetRecommendedContentByAddress", "") + + HelpExampleRpc("GetRecommendedContentByAddress", "") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + // if (request.fHelp) + // throw runtime_error( + // "getrecommendedaccountbyaddress \"address\", \"addressExclude\", \"contenttypes\", \"lang\", count\n" + // "\nAccounts recommendations by address.\n" + // "\nArguments:\n" + // "1. \"address\" (string) Address for recommendations\n" + // "2. \"addressExclude\" (string, optional) Address for exclude from recommendations\n" + // "3. \"contenttypes\" (string or array of strings, optional) type(s) of content posts/videos/articles\n" + // "3. \"lang\" (string, optional) Language for recommendations\n" + // "4. \"count\" (int, optional) Number of recommendations records and number of other contents from addres. Default 15\n" + // ); RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string contentid = request.params[0].get_str(); - - vector contentTypes; - ParseRequestContentTypes(request.params[1], contentTypes); - - int depth = 1000; - int cntOut = 10; - - if (request.params.size() > 2 && request.params[2].isNum()) - depth = request.params[2].get_int(); + string address = ""; + if (request.params.size() > 0 && request.params[0].isStr()) { + address = request.params[0].get_str(); + + if(!address.empty()) { + CTxDestination dest = DecodeDestination(address); + if (!IsValidDestination(dest)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid address: ") + address); + } + } - if (request.params.size() > 3 && request.params[3].isNum()) - cntOut = request.params[3].get_int(); + string addressExclude = ""; + if (request.params.size() > 1 && request.params[1].isStr()) { + addressExclude = request.params[1].get_str(); - return request.DbConnection()->SearchRepoInst->GetRecomendedContentsByScoresOnSimilarContents(contentid, contentTypes, depth, cntOut); - }, - }; - } + if(!addressExclude.empty()) { + CTxDestination dest = DecodeDestination(addressExclude); + if (!IsValidDestination(dest)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid address: ") + addressExclude); + } + } - RPCHelpMan GetRecomendedContentsByScoresFromAddress() - { - return RPCHelpMan{"getrecomendedcontentsbyscoresfromaddress", - "\nContents recommendations for address by likes.\n", // TODO (team): provide description - { - {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "Address for recommendations" }, - {"contenttypes", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "type(s) of content posts/video", - { - {"contenttype", RPCArg::Type::STR, RPCArg::Optional::NO, "" } - } - }, - {"height", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Maximum search height. Default is current chain height" }, - {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Depth of statistic. Default 1000 blocks" }, - {"count", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Number of resulting records. Default 10" }, - }, - { - // TODO (losty-rpc): provide return description - }, - RPCExamples{ - // TODO (team): examples - HelpExampleCli("getrecomendedcontentsbyscoresfromaddress", "\"address\", \"contenttypes\", height, depth, count") + - HelpExampleRpc("getrecomendedcontentsbyscoresfromaddress", "\"address\", \"contenttypes\", height, depth, count") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue - { - RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string address = request.params[0].get_str(); - CTxDestination dest = DecodeDestination(address); + vector contentTypes; + if(request.params.size()>2) + ParseRequestContentTypes(request.params[2], contentTypes); - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address); + string lang = ""; + if (request.params.size() > 3 && request.params[3].isStr()) + lang = request.params[3].get_str(); - vector contentTypes; - ParseRequestContentTypes(request.params[1], contentTypes); + int cntOut = 15; + if (request.params.size() > 4 && request.params[4].isNum()) + cntOut = request.params[4].get_int(); int nHeight = ChainActive().Height(); - int depth = 1000; - int cntOut = 10; + if (request.params.size() > 5 && request.params[5].isNum() && request.params[5].get_int() > 0) + nHeight = request.params[5].get_int(); - if (request.params.size() > 2 && request.params[2].isNum() && request.params[2].get_int() > 0) - nHeight = request.params[2].get_int(); - - if (request.params.size() > 3 && request.params[3].isNum()) - depth = request.params[3].get_int(); + int depth = (60 * 24 * 30 * 3); //about 3 month as default + if (request.params.size() > 6 && request.params[6].isNum()) + { + depth = std::max(request.params[6].get_int(), (60 * 24 * 30 * 6)); // not greater than about 6 month + } - if (request.params.size() > 4 && request.params[4].isNum()) - cntOut = request.params[4].get_int(); + UniValue result(UniValue::VARR); + auto ids = request.DbConnection()->SearchRepoInst->GetRecommendedAccountByAddressSubscriptions(address, addressExclude, contentTypes, lang, cntOut, nHeight, depth); + if (!ids.empty()) + { + auto profiles = request.DbConnection()->WebRpcRepoInst->GetAccountProfiles(ids, true); + for (const auto[id, record] : profiles) + result.push_back(record); + } - return request.DbConnection()->SearchRepoInst->GetRecomendedContentsByScoresFromAddress(address, contentTypes, nHeight, depth, cntOut); + return result; }, }; } diff --git a/src/pocketdb/web/SearchRpc.h b/src/pocketdb/web/SearchRpc.h index 3d8706c5f..656bc160b 100644 --- a/src/pocketdb/web/SearchRpc.h +++ b/src/pocketdb/web/SearchRpc.h @@ -23,31 +23,8 @@ namespace PocketWeb::PocketWebRpc RPCHelpMan SearchContents(); #pragma region Recomendations - // Accounts recommendations based on subscriptions - // Get some accounts that were followed by people who've followed this Account - // This should be run only if Account already has followers - RPCHelpMan GetRecomendedAccountsBySubscriptions(); - - // Accounts recommendations based on scores on other Account - // Get some Accounts that were scored by people who've scored this Account (not long ago - several blocks ago) - RPCHelpMan GetRecomendedAccountsByScoresOnSimilarAccounts(); - - // Accounts recommendations based on address scores - // Get some Accounts that were scored by people who've scored like address (not long ago - several blocks ago) - // Get address scores -> Get scored contents -> Get Scores to these contents -> Get scores accounts -> Get their scores -> Get their scored contents -> Get these contents Authors - RPCHelpMan GetRecomendedAccountsByScoresFromAddress(); - - // Accounts recommendations based on tags - RPCHelpMan GetRecomendedAccountsByTags(); - - // Contents recommendations by others contents - // Get some contents that were liked by people who've seen this content (not long ago - several blocks ago) - // This should be run only if Content already has >XXXX likes - RPCHelpMan GetRecomendedContentsByScoresOnSimilarContents(); - - // Contents recommendations by address scores - // Get some contents that were liked by people who've scored like address (not long ago - several blocks ago) - RPCHelpMan GetRecomendedContentsByScoresFromAddress(); + RPCHelpMan GetRecommendedContentByAddress(); + RPCHelpMan GetRecommendedAccountByAddress(); #pragma endregion } diff --git a/src/pos.cpp b/src/pos.cpp index f097aae3a..8731b6773 100644 --- a/src/pos.cpp +++ b/src/pos.cpp @@ -151,9 +151,6 @@ bool CheckStake(const std::shared_ptr pblock, const PocketBlockRef& pock { return error("CheckStake() : generated block is stale"); } - - // TODO (losty-fur): idk what it is doing here because BlockFound signal is never connected to anything (see validationinterface.cpp) - // GetMainSignals().BlockFound(pblock->GetHash()); } // Process this block the same as if we had received it from another node @@ -202,9 +199,8 @@ bool CheckProofOfStake(CBlockIndex *pindexPrev, CTransactionRef const &tx, unsig const CTransaction &txn = *tx; PrecomputedTransactionData txdata(txn); const COutPoint &prevout = tx->vin[0].prevout; - // TODO (losty-fur): do we really need pointer here? Moreover below "assert" will never be triggered. + const Coin *coins = &::ChainstateActive().CoinsTip().AccessCoin(prevout); - assert(coins); // Verify signature CScriptCheck check(coins->out, *tx, 0, SCRIPT_VERIFY_NONE, false, &txdata); @@ -329,39 +325,9 @@ bool CheckStakeKernelHash(CBlockIndex *pindexPrev, unsigned int nBits, CBlockInd hashProofOfStakeSource = ss; hashProofOfStake = UintToArith256(Hash(ss)); - if (fPrintProofOfStake) - { - LogPrint(BCLog::WALLET, "CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n", - nStakeModifier, nStakeModifierHeight, - FormatISO8601DateTime(nStakeModifierTime), - FormatISO8601DateTime(nTimeBlockFrom)); - - LogPrint(BCLog::WALLET, "CheckStakeKernelHash() : check modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s bnTarget=%s nBits=%08x nValueIn=%d bnWeight=%s\n", - nStakeModifier, - nTimeBlockFrom, *txPrev.GetTime(), prevout.n, nTimeTx, - hashProofOfStake.ToString(), bnTarget.ToString(), nBits, nValueIn, bnWeight.ToString()); - } - // Now check if proof-of-stake hash meets target protocol if (hashProofOfStake > bnTarget) - { return false; - } - - if (!fPrintProofOfStake) - { - LogPrint(BCLog::WALLET, - "CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n", - nStakeModifier, nStakeModifierHeight, - FormatISO8601DateTime(nStakeModifierTime), - FormatISO8601DateTime(nTimeBlockFrom)); - - LogPrint(BCLog::WALLET, - "CheckStakeKernelHash() : pass modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", - nStakeModifier, - nTimeBlockFrom, txPrev.GetTime(), prevout.n, nTimeTx, - hashProofOfStake.ToString()); - } return true; } @@ -370,12 +336,9 @@ bool CheckStakeKernelHash(CBlockIndex *pindexPrev, unsigned int nBits, CBlockInd bool CheckCoinStakeTimestamp(int nHeight, int64_t nTimeBlock, int64_t nTimeTx) { if (nHeight > 0) - { return (nTimeBlock == nTimeTx) && ((nTimeTx & STAKE_TIMESTAMP_MASK) == 0); - } else - { + else return (nTimeBlock == nTimeTx); - } } // Stake Modifier (hash modifier of proof-of-stake): diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index be45ef9a4..5c636da6f 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -11,7 +11,6 @@ #include