diff --git a/README.md b/README.md index b23ff681e6..1304e41610 100644 --- a/README.md +++ b/README.md @@ -7,18 +7,13 @@ [![GitHub commits-per-month](https://img.shields.io/github/commit-activity/m/firoorg/firo)](https://github.com/firoorg/firo/graphs/code-frequency) [![GitHub last-commit](https://img.shields.io/github/last-commit/firoorg/firo)](https://github.com/firoorg/firo/commits/master) -[Firo](https://firo.org) formerly known as Zcoin, is a privacy focused cryptocurrency that utilizes zero-knowledge proofs which allows users to destroy coins and then redeem them later for brand new ones with no transaction history. +[Firo](https://firo.org) formerly known as Zcoin, is a privacy focused cryptocurrency that utilizes the [Lelantus Spark protocol](https://eprint.iacr.org/2021/1173) which supports high anonymity sets without requiring trusted setup and relying on standard cryptographic assumptions. -Our research created the [Lelantus privacy protocol](https://eprint.iacr.org/2019/373) which supports high anonymity sets without requiring trusted setup and relying only on standard cryptographic assumptions. The Lelantus cryptographic library was audited by [Trail of Bits](https://github.com/trailofbits/publications/blob/master/reviews/zcoin-lelantus-summary.pdf) and funded by Firo's CCS. Lelantus' cryptography was also audited by [ABDK Consulting](https://www.abdk.consulting/). +The Lelantus Spark cryptographic library and implementation was audited by [HashCloak](https://firo.org/about/research/papers/lelantus_spark_code_audit_report.pdf). The Lelantus Spark cryptography paper has undergone two separate audits by [HashCloak](https://firo.org/about/research/papers/Lelantus_Spark_Audit_Report.pdf) and [Daniel (Linfeng) Zhao](https://firo.org/about/research/papers/LinfengSparkAudit.pdf). Firo also utilises [Dandelion++](https://arxiv.org/abs/1805.11060) to obscure the originating IP of transactions without relying on any external services such as Tor/i2P. -Firo uses FiroPoW (a ProgPoW variant) as its Proof-of-Work GPU focused algorithm which is FPGA/ASIC resistant. - -# How Firo’s Privacy Technology Compares to the Competition - -![A comparison chart of Firo’s solutions with other leading privacy technologies can be found below](https://firo.org/guide/assets/privacy-technology-comparison/comparison-table-firo-updated.png) -read more https://firo.org/guide/privacy-technology-comparison.html +Firo uses a hybrid PoW and LLMQ Chainlocks system combining fair distribution of supply with protection against 51% attacks and quick finality of blocks and transactions. FiroPOW (a ProgPOW variant) is used as its Proof-of-Work algorithm which targets GPUs and is FPGA/ASIC resistant. # Running with Docker @@ -202,6 +197,8 @@ This project exists thanks to all the people who contribute. Would you like to h Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/firo/contribute)] +You can also donate to the [MAGIC Firo Fund](https://magicgrants.org/funds/firo/) which allows some US entities to claim a charitable deduction. + ## Individuals diff --git a/configure.ac b/configure.ac index e632b04787..fc02a295d7 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 14) define(_CLIENT_VERSION_REVISION, 13) -define(_CLIENT_VERSION_BUILD, 1) +define(_CLIENT_VERSION_BUILD, 2) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2024) define(_COPYRIGHT_HOLDERS,[The %s developers]) diff --git a/contrib/debian/bitcoin-qt.desktop b/contrib/debian/bitcoin-qt.desktop deleted file mode 100644 index 593d7584ab..0000000000 --- a/contrib/debian/bitcoin-qt.desktop +++ /dev/null @@ -1,13 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Name=Bitcoin Core -Comment=Connect to the Bitcoin P2P Network -Comment[de]=Verbinde mit dem Bitcoin peer-to-peer Netzwerk -Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair -Comment[tr]=Bitcoin, eşten eşe kriptografik sanal para birimi -Exec=bitcoin-qt %u -Terminal=false -Type=Application -Icon=bitcoin128 -MimeType=x-scheme-handler/bitcoin; -Categories=Office;Finance; diff --git a/contrib/debian/firo-qt.desktop b/contrib/debian/firo-qt.desktop new file mode 100644 index 0000000000..0d610ac4c3 --- /dev/null +++ b/contrib/debian/firo-qt.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Firo +Comment=Connect to Firo +Exec=firo-qt %u +Terminal=false +Type=Application +Icon=/app/share/icons/hicolor/scalable/apps/org.firo.firo-qt.svg +Categories=Office;Finance; diff --git a/contrib/debian/qt-screenshot.jpg b/contrib/debian/qt-screenshot.jpg new file mode 100644 index 0000000000..135ff4acba Binary files /dev/null and b/contrib/debian/qt-screenshot.jpg differ diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index 001c928424..8ed82b276d 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -6,6 +6,7 @@ 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_DSYMUTIL:=$(shell xcrun -f dsymutil) build_darwin_SHA256SUM=shasum -a 256 build_darwin_DOWNLOAD=curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o @@ -19,5 +20,11 @@ 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_DSYMUTIL:=$(shell xcrun -f dsymutil) darwin_native_binutils= darwin_native_toolchain= + +x86_64_darwin_CFLAGS += -arch x86_64 +x86_64_darwin_CXXFLAGS += -arch x86_64 +aarch64_darwin_CFLAGS += -arch arm64 +aarch64_darwin_CXXFLAGS += -arch arm64 diff --git a/depends/builders/default.mk b/depends/builders/default.mk index f097db65d6..cc6dec66c2 100644 --- a/depends/builders/default.mk +++ b/depends/builders/default.mk @@ -1,18 +1,17 @@ default_build_CC = gcc default_build_CXX = g++ default_build_AR = ar +default_build_TAR = tar default_build_RANLIB = ranlib default_build_STRIP = strip default_build_NM = nm -default_build_OTOOL = otool -default_build_INSTALL_NAME_TOOL = install_name_tool define add_build_tool_func build_$(build_os)_$1 ?= $$(default_build_$1) build_$(build_arch)_$(build_os)_$1 ?= $$(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) endef -$(foreach var,CC CXX AR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL,$(eval $(call add_build_tool_func,$(var)))) +$(foreach var,CC CXX AR TAR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL DSYMUTIL,$(eval $(call add_build_tool_func,$(var)))) define add_build_flags_func build_$(build_arch)_$(build_os)_$1 += $(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) diff --git a/depends/funcs.mk b/depends/funcs.mk index 24585240c5..1dd3fd6923 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -38,7 +38,7 @@ define fetch_file ( test -f $$($(1)_source_dir)/$(4) || \ ( $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5)) || \ $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(3),$(4),$(5)) || \ - $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH_ALTERNATIVE),$(3),$(4),$(5)))) + $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH_ALTERNATIVE),$(3),$(4),$(5)))) endef define int_get_build_recipe_hash @@ -68,6 +68,7 @@ $(1)_cached_checksum:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_bui $(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id) $(1)_prefixbin:=$($($(1)_type)_prefix)/bin/ $(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz +$(1)_build_log:=$(BASEDIR)/$(1)-$($(1)_version)-$($(1)_build_id).log $(1)_all_sources=$($(1)_file_name) $($(1)_extra_sources) #stamps @@ -76,7 +77,7 @@ $(1)_extracted=$$($(1)_extract_dir)/.stamp_extracted $(1)_preprocessed=$$($(1)_extract_dir)/.stamp_preprocessed $(1)_cleaned=$$($(1)_extract_dir)/.stamp_cleaned $(1)_built=$$($(1)_build_dir)/.stamp_built -$(1)_configured=$$($(1)_build_dir)/.stamp_configured +$(1)_configured=$(host_prefix)/.$(1)_stamp_configured $(1)_staged=$$($(1)_staging_dir)/.stamp_staged $(1)_postprocessed=$$($(1)_staging_prefix_dir)/.stamp_postprocessed $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path)) @@ -85,11 +86,11 @@ $(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 --no-same-owner --strip-components=1 -xf $$($(1)_source) -$(1)_preprocess_cmds ?= -$(1)_build_cmds ?= -$(1)_config_cmds ?= -$(1)_stage_cmds ?= +$(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 && $(build_TAR) --no-same-owner --strip-components=1 -xf $$($(1)_source) +$(1)_preprocess_cmds ?= true +$(1)_build_cmds ?= true +$(1)_config_cmds ?= true +$(1)_stage_cmds ?= true $(1)_set_vars ?= @@ -137,6 +138,7 @@ $(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+=PKG_CONFIG_SYSROOT_DIR=/ $(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) @@ -175,7 +177,7 @@ $(1)_cmake=env CC="$$($(1)_cc)" \ CXX="$$($(1)_cxx)" \ CXXFLAGS="$$($(1)_cppflags) $$($(1)_cxxflags)" \ LDFLAGS="$$($(1)_ldflags)" \ - cmake -DCMAKE_INSTALL_PREFIX:PATH="$$($($(1)_type)_prefix)" + cmake -DCMAKE_INSTALL_PREFIX:PATH="$$($($(1)_type)_prefix)" $$($(1)_config_opts) ifeq ($($(1)_type),build) $(1)_cmake += -DCMAKE_INSTALL_RPATH:PATH="$$($($(1)_type)_prefix)/lib" else @@ -188,54 +190,61 @@ endif endef define int_add_cmds +ifneq ($(LOG),) +$(1)_logging = >>$$($(1)_build_log) 2>&1 || { if test -f $$($(1)_build_log); then cat $$($(1)_build_log); fi; exit 1; } +endif + $($(1)_fetched): - $(AT)mkdir -p $$(@D) $(SOURCES_PATH) - $(AT)rm -f $$@ - $(AT)touch $$@ - $(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1)) - $(AT)cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);) - $(AT)touch $$@ + mkdir -p $$(@D) $(SOURCES_PATH) + rm -f $$@ + touch $$@ + cd $$(@D); $($(1)_fetch_cmds) + cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);) + touch $$@ $($(1)_extracted): | $($(1)_fetched) - $(AT)echo Extracting $(1)... - $(AT)mkdir -p $$(@D) - $(AT)cd $$(@D); $(call $(1)_extract_cmds,$(1)) - $(AT)touch $$@ + echo Extracting $(1)... + mkdir -p $$(@D) + cd $$(@D); $($(1)_extract_cmds) + touch $$@ $($(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 $$@ + echo Preprocessing $(1)... + mkdir -p $$(@D) $($(1)_patch_dir) + $(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) + { cd $$(@D); $($(1)_preprocess_cmds); } $$($(1)_logging) + touch $$@ $($(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 --no-same-owner -xf $($(package)_cached); ) - $(AT)mkdir -p $$(@D) - $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) - $(AT)touch $$@ + echo Configuring $(1)... + rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), $(build_TAR) --no-same-owner -xf $($(package)_cached); ) + mkdir -p $$($(1)_build_dir) + +{ cd $$($(1)_build_dir); export $($(1)_config_env); $($(1)_config_cmds); } $$($(1)_logging) + touch $$@ $($(1)_built): | $($(1)_configured) - $(AT)echo Building $(1)... - $(AT)mkdir -p $$(@D) - $(AT)+cd $$(@D); $($(1)_build_env) $(call $(1)_build_cmds, $(1)) - $(AT)touch $$@ + echo Building $(1)... + mkdir -p $$(@D) + +{ cd $$(@D); export $($(1)_build_env); $($(1)_build_cmds); } $$($(1)_logging) + touch $$@ $($(1)_staged): | $($(1)_built) - $(AT)echo Staging $(1)... - $(AT)mkdir -p $($(1)_staging_dir)/$(host_prefix) - $(AT)cd $($(1)_build_dir); $($(1)_stage_env) $(call $(1)_stage_cmds, $(1)) - $(AT)rm -rf $($(1)_extract_dir) - $(AT)touch $$@ + echo Staging $(1)... + mkdir -p $($(1)_staging_dir)/$(host_prefix) + +{ cd $($(1)_build_dir); export $($(1)_stage_env); $($(1)_stage_cmds); } $$($(1)_logging) + rm -rf $($(1)_extract_dir) + touch $$@ $($(1)_postprocessed): | $($(1)_staged) - $(AT)echo Postprocessing $(1)... - $(AT)cd $($(1)_staging_prefix_dir); $(call $(1)_postprocess_cmds) - $(AT)touch $$@ + echo Postprocessing $(1)... + cd $($(1)_staging_prefix_dir); $($(1)_postprocess_cmds) + touch $$@ $($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed) - $(AT)echo Caching $(1)... - $(AT)cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | tar --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - - $(AT)mkdir -p $$(@D) - $(AT)rm -rf $$(@D) && mkdir -p $$(@D) - $(AT)mv $$($(1)_staging_dir)/$$(@F) $$(@) - $(AT)rm -rf $($(1)_staging_dir) + echo Caching $(1)... + cd $$($(1)_staging_dir)/$(host_prefix); \ + find . ! -name '.stamp_postprocessed' -print0 | TZ=UTC xargs -0r touch -h -m -t 200001011200; \ + find . ! -name '.stamp_postprocessed' | LC_ALL=C sort | $(build_TAR) --numeric-owner --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - + mkdir -p $$(@D) + rm -rf $$(@D) && mkdir -p $$(@D) + mv $$($(1)_staging_dir)/$$(@F) $$(@) + rm -rf $($(1)_staging_dir) + if test -f $($(1)_build_log); then mv $($(1)_build_log) $$(@D); fi $($(1)_cached_checksum): $($(1)_cached) - $(AT)cd $$(@D); $(build_SHA256SUM) $$( $$(@) + cd $$(@D); $(build_SHA256SUM) $$( $$(@) .PHONY: $(1) $(1): | $($(1)_cached_checksum) @@ -265,7 +274,8 @@ $(foreach package,$(packages),$(eval $(package)_type=$(host_arch)_$(host_os))) $(foreach package,$(all_packages),$(eval $(call int_vars,$(package)))) #include package files -$(foreach package,$(all_packages),$(eval include packages/$(package).mk)) +$(foreach native_package,$(native_packages),$(eval include packages/$(native_package).mk)) +$(foreach package,$(packages),$(eval include packages/$(package).mk)) #compute a hash of all files that comprise this package's build recipe $(foreach package,$(all_packages),$(eval $(call int_get_build_recipe_hash,$(package)))) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index ac9e85546a..3166f2cc52 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,7 +1,7 @@ package=boost -$(package)_version=1_81_0 -$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/ -$(package)_file_name=boost_$($(package)_version).tar.bz2 +$(package)_version=1.81.0 +$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$($(package)_version)/source/ +$(package)_file_name=boost_$(subst .,_,$($(package)_version)).tar.bz2 $(package)_sha256_hash=71feeed900fbccca04a3b4f2f84a7c217186f28a940ed8b7ed4725986baf99fa $(package)_dependencies=native_b2 diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 28f2bd6f25..036eaf6560 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -1,25 +1,31 @@ package=libxcb -$(package)_version=1.10 -$(package)_download_path=http://xcb.freedesktop.org/dist -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c3f2d5b5 -$(package)_dependencies=xcb_proto libXau xproto +$(package)_version=1.14 +$(package)_download_path=https://xcb.freedesktop.org/dist +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=a55ed6db98d43469801262d81dc2572ed124edc3db31059d4e9916eb9f844c34 +$(package)_dependencies=xcb_proto libXau +$(package)_patches = remove_pthread_stubs.patch define $(package)_set_vars -$(package)_config_opts=--disable-static +$(package)_config_opts=--disable-static --disable-devel-docs --without-doxygen --without-launchd +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking +# Disable unneeded extensions. +# More info is available from: https://doc.qt.io/qt-5.15/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-record --disable-resource +$(package)_config_opts += --disable-screensaver --disable-xevie --disable-xfree86-dri +$(package)_config_opts += --disable-xinput --disable-xprint --disable-selinux +$(package)_config_opts += --disable-xtest --disable-xv --disable-xvmc endef define $(package)_preprocess_cmds - sed "s/pthread-stubs//" -i configure + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux && \ + patch -p1 -i $($(package)_patch_dir)/remove_pthread_stubs.patch endef -# Don't install xcb headers to the default path in order to work around a qt -# build issue: https://bugreports.qt.io/browse/QTBUG-34748 -# When using qt's internal libxcb, it may end up finding the real headers in -# depends staging. Use a non-default path to avoid that. - define $(package)_config_cmds - $($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared + $($(package)_autoconf) endef define $(package)_build_cmds @@ -31,5 +37,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf share/man share/doc + rm -rf share lib/*.la endef diff --git a/depends/packages/libxcb_util.mk b/depends/packages/libxcb_util.mk new file mode 100644 index 0000000000..6f1b9cd7c6 --- /dev/null +++ b/depends/packages/libxcb_util.mk @@ -0,0 +1,32 @@ +package=libxcb_util +$(package)_version=0.4.0 +$(package)_download_path=https://xcb.freedesktop.org/dist +$(package)_file_name=xcb-util-$($(package)_version).tar.bz2 +$(package)_sha256_hash=46e49469cb3b594af1d33176cd7565def2be3fa8be4371d62271fabb5eae50e9 +$(package)_dependencies=libxcb + +define $(package)_set_vars +$(package)_config_opts = --disable-shared --disable-devel-docs --without-doxygen +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking +$(package)_config_opts += --with-pic +endef + +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf share/man share/doc lib/*.la +endef diff --git a/depends/packages/libxcb_util_image.mk b/depends/packages/libxcb_util_image.mk new file mode 100644 index 0000000000..d12d67e8e8 --- /dev/null +++ b/depends/packages/libxcb_util_image.mk @@ -0,0 +1,31 @@ +package=libxcb_util_image +$(package)_version=0.4.0 +$(package)_download_path=https://xcb.freedesktop.org/dist +$(package)_file_name=xcb-util-image-$($(package)_version).tar.bz2 +$(package)_sha256_hash=2db96a37d78831d643538dd1b595d7d712e04bdccf8896a5e18ce0f398ea2ffc +$(package)_dependencies=libxcb libxcb_util + +define $(package)_set_vars +$(package)_config_opts=--disable-static --disable-devel-docs --without-doxygen +$(package)_config_opts+= --disable-dependency-tracking --enable-option-checking +endef + +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf share/man share/doc lib/*.la +endef diff --git a/depends/packages/libxcb_util_keysyms.mk b/depends/packages/libxcb_util_keysyms.mk new file mode 100644 index 0000000000..d4f72dedbe --- /dev/null +++ b/depends/packages/libxcb_util_keysyms.mk @@ -0,0 +1,31 @@ +package=libxcb_util_keysyms +$(package)_version=0.4.0 +$(package)_download_path=https://xcb.freedesktop.org/dist +$(package)_file_name=xcb-util-keysyms-$($(package)_version).tar.bz2 +$(package)_sha256_hash=0ef8490ff1dede52b7de533158547f8b454b241aa3e4dcca369507f66f216dd9 +$(package)_dependencies=libxcb xproto + +define $(package)_set_vars +$(package)_config_opts=--disable-static --disable-devel-docs --without-doxygen +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking +endef + +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf share/man share/doc lib/*.la +endef diff --git a/depends/packages/libxcb_util_render.mk b/depends/packages/libxcb_util_render.mk new file mode 100644 index 0000000000..28f1fb073c --- /dev/null +++ b/depends/packages/libxcb_util_render.mk @@ -0,0 +1,31 @@ +package=libxcb_util_render +$(package)_version=0.3.9 +$(package)_download_path=https://xcb.freedesktop.org/dist +$(package)_file_name=xcb-util-renderutil-$($(package)_version).tar.bz2 +$(package)_sha256_hash=c6e97e48fb1286d6394dddb1c1732f00227c70bd1bedb7d1acabefdd340bea5b +$(package)_dependencies=libxcb + +define $(package)_set_vars +$(package)_config_opts=--disable-static --disable-devel-docs --without-doxygen +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking +endef + +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf share/man share/doc lib/*.la +endef diff --git a/depends/packages/libxcb_util_wm.mk b/depends/packages/libxcb_util_wm.mk new file mode 100644 index 0000000000..3b905ba4ec --- /dev/null +++ b/depends/packages/libxcb_util_wm.mk @@ -0,0 +1,31 @@ +package=libxcb_util_wm +$(package)_version=0.4.1 +$(package)_download_path=https://xcb.freedesktop.org/dist +$(package)_file_name=xcb-util-wm-$($(package)_version).tar.bz2 +$(package)_sha256_hash=28bf8179640eaa89276d2b0f1ce4285103d136be6c98262b6151aaee1d3c2a3f +$(package)_dependencies=libxcb + +define $(package)_set_vars +$(package)_config_opts=--disable-static --disable-devel-docs --without-doxygen +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking +endef + +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf share/man share/doc lib/*.la +endef diff --git a/depends/packages/native_comparisontool.mk b/depends/packages/native_comparisontool.mk deleted file mode 100644 index e0ae0cec70..0000000000 --- a/depends/packages/native_comparisontool.mk +++ /dev/null @@ -1,21 +0,0 @@ -package=native_comparisontool -$(package)_version=8c6666f -$(package)_download_path=https://github.com/theuni/bitcoind-comparisontool/raw/master -$(package)_file_name=pull-tests-$($(package)_version).jar -$(package)_sha256_hash=a865332b3827abcde684ab79f5f43c083b0b6a4c97ff5508c79f29fee24f11cd -$(package)_install_dirname=BitcoindComparisonTool_jar -$(package)_install_filename=BitcoindComparisonTool.jar - -define $(package)_extract_cmds -endef - -define $(package)_configure_cmds -endef - -define $(package)_build_cmds -endef - -define $(package)_stage_cmds - mkdir -p $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname) && \ - cp $($(package)_source) $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname)/$($(package)_install_filename) -endef diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index 8380c98879..46414f5740 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -34,7 +34,7 @@ $(package)_config_opts+=no-weak-ssl-ciphers $(package)_config_opts+=no-whirlpool $(package)_config_opts+=no-zlib $(package)_config_opts+=no-zlib-dynamic -$(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags) +#$(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags) $(package)_config_opts_linux=-fPIC -Wa,--noexecstack $(package)_config_opts_x86_64_linux=linux-x86_64 $(package)_config_opts_i686_linux=linux-generic32 diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index cbd0ad2b32..574bf3b276 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,7 +1,9 @@ -packages:=boost openssl libevent gmp zlib backtrace tor bls-dash zeromq -native_packages := native_ccache native_comparisontool native_cmake +packages:=boost openssl libevent gmp zlib backtrace tor bls-dash +darwin_packages:=zeromq +linux_packages:=zeromq +native_packages := native_ccache native_cmake -qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon +qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon libxcb_util libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm qt_darwin_packages=qt qt_mingw32_packages=qt @@ -23,3 +25,4 @@ darwin_native_packages+= native_clang endif endif + diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index d67ebdb164..86109aef18 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,44 +1,54 @@ -PACKAGE=qt -$(package)_version=5.12.11 -$(package)_download_path=https://download.qt.io/official_releases/qt/5.12/$($(package)_version)/submodules -$(package)_suffix=everywhere-src-$($(package)_version).tar.xz +package=qt +$(package)_version=5.15.11 +$(package)_download_path=https://download.qt.io/official_releases/qt/5.15/$($(package)_version)/submodules +$(package)_suffix=everywhere-opensource-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=1c1b4e33137ca77881074c140d54c3c9747e845a31338cfe8680f171f0bc3a39 +$(package)_sha256_hash=425ad301acd91ca66c10c0dabee0704e2d0cd2801a6b670115800cbb95f84846 $(package)_dependencies=zlib -$(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon +$(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon libxcb_util libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm $(package)_qt_libs=corelib network widgets gui plugins testlib $(package)_linguist_tools = lrelease lupdate lconvert -$(package)_patches = qt.pro qttools_src.pro -$(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch -$(package)_patches += support_new_android_ndks.patch fix_android_jni_static.patch dont_hardcode_pwd.patch -$(package)_patches += dont_hardcode_x86_64.patch no_sdk_version_check.patch fix_sonoma_qmake.patch -$(package)_patches+= fix_lib_paths.patch fix_android_pch.patch -$(package)_patches+= qtbase-moc-ignore-gcc-macro.patch fix_limits_header.patch -$(package)_patches+= fix_montery_include.patch +$(package)_patches = qt.pro +$(package)_patches += qttools_src.pro +$(package)_patches += mac-qmake.conf +$(package)_patches += fix_qt_pkgconfig.patch +$(package)_patches += no-xlib.patch +$(package)_patches += fix_android_jni_static.patch +$(package)_patches += dont_hardcode_pwd.patch +$(package)_patches += qtbase-moc-ignore-gcc-macro.patch +$(package)_patches += use_android_ndk23.patch +$(package)_patches += rcc_hardcode_timestamp.patch +$(package)_patches += duplicate_lcqpafonts.patch +$(package)_patches += fast_fixed_dtoa_no_optimize.patch +$(package)_patches += guix_cross_lib_path.patch +$(package)_patches += fix-macos-linker.patch +$(package)_patches += memory_resource.patch +$(package)_patches += windows_lto.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=577b0668a777eb2b451c61e8d026d79285371597ce9df06b6dee6c814164b7c3 +$(package)_qttranslations_sha256_hash=a31785948c640b7c66d9fe2db4993728ca07f64e41c560b3625ad191b276ff20 $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=98b2aaca230458f65996f3534fd471d2ffd038dd58ac997c0589c06dc2385b4f +$(package)_qttools_sha256_hash=7cd847ae6ff09416df617136eadcaf0eb98e3bc9b89979219a3ea8111fb8d339 $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) define $(package)_set_vars +$(package)_config_env = QT_MAC_SDK_NO_VERSION_CHECK=1 $(package)_config_opts_release = -release $(package)_config_opts_release += -silent $(package)_config_opts_debug = -debug $(package)_config_opts_debug += -optimized-tools $(package)_config_opts += -bindir $(build_prefix)/bin -$(package)_config_opts += -c++std c++1z +$(package)_config_opts += -c++std c++17 $(package)_config_opts += -confirm-license $(package)_config_opts += -hostprefix $(build_prefix) $(package)_config_opts += -no-compile-examples $(package)_config_opts += -no-cups $(package)_config_opts += -no-egl $(package)_config_opts += -no-eglfs -$(package)_config_opts += -no-freetype +$(package)_config_opts += -no-evdev $(package)_config_opts += -no-gif $(package)_config_opts += -no-glib $(package)_config_opts += -no-icu @@ -104,6 +114,7 @@ $(package)_config_opts += -no-feature-sqlmodel $(package)_config_opts += -no-feature-statemachine $(package)_config_opts += -no-feature-syntaxhighlighter $(package)_config_opts += -no-feature-textbrowser +$(package)_config_opts += -no-feature-textmarkdownwriter $(package)_config_opts += -no-feature-textodfwriter $(package)_config_opts += -no-feature-topleveldomain $(package)_config_opts += -no-feature-undocommand @@ -117,6 +128,7 @@ $(package)_config_opts_darwin = -no-dbus $(package)_config_opts_darwin += -no-opengl $(package)_config_opts_darwin += -pch $(package)_config_opts_darwin += -no-feature-corewlan +$(package)_config_opts_darwin += -no-freetype $(package)_config_opts_darwin += QMAKE_MACOSX_DEPLOYMENT_TARGET=$(OSX_MIN_VERSION) ifneq ($(build_os),darwin) @@ -133,7 +145,7 @@ $(package)_config_opts_aarch64_darwin += -device-option QMAKE_APPLE_DEVICE_ARCHS $(package)_config_opts_x86_64_darwin += -device-option QMAKE_APPLE_DEVICE_ARCHS=x86_64 endif -$(package)_config_opts_linux = -qt-xcb +$(package)_config_opts_linux = -xcb $(package)_config_opts_linux += -no-xcb-xlib $(package)_config_opts_linux += -no-feature-xlib $(package)_config_opts_linux += -system-freetype @@ -141,32 +153,40 @@ $(package)_config_opts_linux += -fontconfig $(package)_config_opts_linux += -no-opengl $(package)_config_opts_linux += -no-feature-vulkan $(package)_config_opts_linux += -dbus-runtime -$(package)_config_opts_arm_linux += -platform linux-g++ -xplatform bitcoin-linux-g++ -$(package)_config_opts_i686_linux = -xplatform linux-g++-32 -$(package)_config_opts_x86_64_linux = -xplatform linux-g++-64 -$(package)_config_opts_aarch64_linux = -xplatform linux-aarch64-gnu-g++ -$(package)_config_opts_powerpc64_linux = -platform linux-g++ -xplatform bitcoin-linux-g++ -$(package)_config_opts_powerpc64le_linux = -platform linux-g++ -xplatform bitcoin-linux-g++ -$(package)_config_opts_riscv64_linux = -platform linux-g++ -xplatform bitcoin-linux-g++ -$(package)_config_opts_s390x_linux = -platform linux-g++ -xplatform bitcoin-linux-g++ +ifneq ($(LTO),) +$(package)_config_opts_linux += -ltcg +endif + +ifneq (,$(findstring clang,$($(package)_cxx))) + ifneq (,$(findstring -stdlib=libc++,$($(package)_cxx))) + $(package)_config_opts_linux += -platform linux-clang-libc++ -xplatform linux-clang-libc++ + else + $(package)_config_opts_linux += -platform linux-clang -xplatform linux-clang + endif +else + $(package)_config_opts_linux += -platform linux-g++ -xplatform bitcoin-linux-g++ +endif $(package)_config_opts_mingw32 = -no-opengl $(package)_config_opts_mingw32 += -no-dbus +$(package)_config_opts_mingw32 += -no-freetype $(package)_config_opts_mingw32 += -xplatform win32-g++ $(package)_config_opts_mingw32 += "QMAKE_CFLAGS = '$($(package)_cflags) $($(package)_cppflags)'" -$(package)_config_opts_mingw32 += "QMAKE_CXXFLAGS = '$($(package)_cflags) $($(package)_cppflags)'" +$(package)_config_opts_mingw32 += "QMAKE_CXX = '$($(package)_cxx)'" +$(package)_config_opts_mingw32 += "QMAKE_CXXFLAGS = '$($(package)_cxxflags) $($(package)_cppflags)'" $(package)_config_opts_mingw32 += "QMAKE_LFLAGS = '$($(package)_ldflags)'" +$(package)_config_opts_mingw32 += "QMAKE_LIB = '$($(package)_ar) rc'" $(package)_config_opts_mingw32 += -device-option CROSS_COMPILE="$(host)-" $(package)_config_opts_mingw32 += -pch +ifneq ($(LTO),) +$(package)_config_opts_mingw32 += -ltcg +endif $(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 @@ -179,7 +199,6 @@ $(package)_config_opts_android += -no-feature-vulkan $(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 endef define $(package)_fetch_cmds @@ -195,11 +214,11 @@ 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 --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ + $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ mkdir qttranslations && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ + $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ mkdir qttools && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools + $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools endef # Preprocessing steps work as follows: @@ -209,46 +228,42 @@ endef # 2. Create a macOS-Clang-Linux mkspec using our mac-qmake.conf. # # 3. After making a copy of the mkspec for the linux-arm-gnueabi host, named -# bitcoin-linux-g++, replace instances of linux-arm-gnueabi with $(host). This -# way we can generically support hosts like riscv64-linux-gnu, which Qt doesn't -# ship a mkspec for. See it's usage in config_opts_* above. +# bitcoin-linux-g++, replace tool names with $($($(package)_type)_TOOL). # # 4. Put our C, CXX and LD FLAGS into gcc-base.conf. Only used for non-host builds. # -# 5. Do similar for the win32-g++ mkspec. -# -# 6. In clang.conf, swap out clang & clang++, for our compiler + flags. See #17466. -# -# 7. Adjust a regex in toolchain.prf, to accommodate Guix's usage of -# CROSS_LIBRARY_PATH. See #15277. +# 5. In clang.conf, swap out clang & clang++, for our compiler + flags. See #17466. define $(package)_preprocess_cmds cp $($(package)_patch_dir)/qt.pro qt.pro && \ cp $($(package)_patch_dir)/qttools_src.pro qttools/src/src.pro && \ + patch -p1 -i $($(package)_patch_dir)/fix-macos-linker.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \ - patch -p1 -i $($(package)_patch_dir)/support_new_android_ndks.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_android_pch.patch && \ patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ - patch -p1 -i $($(package)_patch_dir)/dont_hardcode_x86_64.patch && \ - patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase-moc-ignore-gcc-macro.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_limits_header.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_montery_include.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_sonoma_qmake.patch && \ + patch -p1 -i $($(package)_patch_dir)/use_android_ndk23.patch && \ + patch -p1 -i $($(package)_patch_dir)/memory_resource.patch && \ + patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \ + patch -p1 -i $($(package)_patch_dir)/duplicate_lcqpafonts.patch && \ + patch -p1 -i $($(package)_patch_dir)/fast_fixed_dtoa_no_optimize.patch && \ + patch -p1 -i $($(package)_patch_dir)/guix_cross_lib_path.patch && \ + patch -p1 -i $($(package)_patch_dir)/windows_lto.patch && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ cp -r qtbase/mkspecs/linux-arm-gnueabi-g++ qtbase/mkspecs/bitcoin-linux-g++ && \ - sed -i.old "s/arm-linux-gnueabi-/$(host)-/g" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \ + sed -i.old "s|arm-linux-gnueabi-gcc|$($($(package)_type)_CC)|" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \ + sed -i.old "s|arm-linux-gnueabi-g++|$($($(package)_type)_CXX)|" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \ + sed -i.old "s|arm-linux-gnueabi-ar|$($($(package)_type)_AR)|" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \ + sed -i.old "s|arm-linux-gnueabi-objcopy|$($($(package)_type)_OBJCOPY)|" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \ + sed -i.old "s|arm-linux-gnueabi-nm|$($($(package)_type)_NM)|" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \ + sed -i.old "s|arm-linux-gnueabi-strip|$($($(package)_type)_STRIP)|" qtbase/mkspecs/bitcoin-linux-g++/qmake.conf && \ 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 && \ sed -i.old "s|QMAKE_CC = \$$$$\$$$${CROSS_COMPILE}clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ - sed -i.old "s|QMAKE_CXX = \$$$$\$$$${CROSS_COMPILE}clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \ - sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf + sed -i.old "s|QMAKE_CXX = \$$$$\$$$${CROSS_COMPILE}clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf endef define $(package)_config_cmds @@ -271,4 +286,4 @@ endef define $(package)_postprocess_cmds rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \ rm -f lib/lib*.la -endef +endef \ No newline at end of file diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk index 0c7c958d62..6e1c5a10a8 100644 --- a/depends/packages/xcb_proto.mk +++ b/depends/packages/xcb_proto.mk @@ -1,13 +1,8 @@ package=xcb_proto -$(package)_version=1.10 -$(package)_download_path=http://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 +$(package)_version=1.15.2 +$(package)_download_path=https://xorg.freedesktop.org/archive/individual/proto +$(package)_file_name=xcb-proto-$($(package)_version).tar.xz +$(package)_sha256_hash=7072beb1f680a2fe3f9e535b797c146d22528990c72f63ddb49d2f350a3653ed define $(package)_config_cmds $($(package)_autoconf) @@ -22,6 +17,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - find -name "*.pyc" -delete && \ - find -name "*.pyo" -delete + rm -rf lib/python*/site-packages/xcbgen/__pycache__ endef diff --git a/depends/patches/libxcb/remove_pthread_stubs.patch b/depends/patches/libxcb/remove_pthread_stubs.patch new file mode 100644 index 0000000000..1f32dea527 --- /dev/null +++ b/depends/patches/libxcb/remove_pthread_stubs.patch @@ -0,0 +1,12 @@ +Remove uneeded pthread-stubs dependency +--- a/configure ++++ b/configure +@@ -19695,7 +19695,7 @@ fi + NEEDED="xau >= 0.99.2" + case $host_os in + linux*) ;; +- *) NEEDED="$NEEDED pthread-stubs" ;; ++ *) NEEDED="$NEEDED" ;; + esac + + pkg_failed=no diff --git a/depends/patches/qt/dont_hardcode_x86_64.patch b/depends/patches/qt/dont_hardcode_x86_64.patch deleted file mode 100644 index 0e1ca6acda..0000000000 --- a/depends/patches/qt/dont_hardcode_x86_64.patch +++ /dev/null @@ -1,123 +0,0 @@ -macOS: Don't hard-code x86_64 as the architecture when using qmake - -Upstream commit: - - Qt 6.1: 9082cc8e8d5a6441dabe5e7a95bc0cd9085b95fe - -For other Qt branches see -https://codereview.qt-project.org/q/I70db7e4c27f0d3da5d0af33cb491d72c312d3fa8 - - ---- old/qtbase/configure.json -+++ new/qtbase/configure.json -@@ -208,11 +208,18 @@ - - "testTypeDependencies": { - "linkerSupportsFlag": [ "use_gold_linker" ], -- "verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "qmakeargs", "commit" ], -+ "verifySpec": [ -+ "shared", -+ "use_gold_linker", -+ "compiler-flags", "qmakeargs", -+ "simulator_and_device", -+ "thread", -+ "commit" ], - "compile": [ "verifyspec" ], - "detectPkgConfig": [ "cross_compile", "machineTuple" ], - "library": [ "pkg-config", "compiler-flags" ], -- "getPkgConfigVariable": [ "pkg-config" ] -+ "getPkgConfigVariable": [ "pkg-config" ], -+ "architecture" : [ "verifyspec" ] - }, - - "testTypeAliases": { -@@ -653,7 +660,7 @@ - }, - "architecture": { - "label": "Architecture", -- "output": [ "architecture" ] -+ "output": [ "architecture", "commitConfig" ] - }, - "pkg-config": { - "label": "Using pkg-config", -diff --git a/configure.pri b/configure.pri -index 33c90a8c2f..71767e29d6 100644 - ---- old/qtbase/configure.pri -+++ new/qtbase/configure.pri -@@ -642,6 +642,13 @@ defineTest(qtConfOutput_commitOptions) { - write_file($$QT_BUILD_TREE/mkspecs/qdevice.pri, $${currentConfig}.output.devicePro)|error() - } - -+# Output is written after configuring each Qt module, -+# but some tests within a module might depend on the -+# configuration output of previous tests. -+defineTest(qtConfOutput_commitConfig) { -+ qtConfProcessOutput() -+} -+ - # type (empty or 'host'), option name, default value - defineTest(processQtPath) { - out_var = config.rel_input.$${2} -diff --git a/mkspecs/common/macx.conf b/mkspecs/common/macx.conf -index 7d4a406134..de96c12fc9 100644 - ---- old/qtbase/mkspecs/common/macx.conf -+++ new/qtbase/mkspecs/common/macx.conf -@@ -6,7 +6,6 @@ QMAKE_PLATFORM += macos osx macx - QMAKE_MAC_SDK = macosx - - QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12 --QMAKE_APPLE_DEVICE_ARCHS = x86_64 - - QT_MAC_SDK_VERSION_MIN = 10.13 - QT_MAC_SDK_VERSION_MAX = 11.0 -diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf -index d052808c14..0a89effe87 100644 - ---- old/qtbase/mkspecs/features/mac/default_post.prf -+++ new/qtbase/mkspecs/features/mac/default_post.prf -@@ -89,6 +89,11 @@ app_extension_api_only { - QMAKE_LFLAGS += $$QMAKE_CFLAGS_APPLICATION_EXTENSION - } - -+# Non-universal builds do not set QMAKE_APPLE_DEVICE_ARCHS, -+# so we pick it up from what the arch test resolved instead. -+isEmpty(QMAKE_APPLE_DEVICE_ARCHS): \ -+ QMAKE_APPLE_DEVICE_ARCHS = $$QT_ARCH -+ - macx-xcode { - qmake_pkginfo_typeinfo.name = QMAKE_PKGINFO_TYPEINFO - !isEmpty(QMAKE_PKGINFO_TYPEINFO): \ -@@ -144,9 +149,6 @@ macx-xcode { - simulator: VALID_SIMULATOR_ARCHS = $$QMAKE_APPLE_SIMULATOR_ARCHS - VALID_ARCHS = $$VALID_DEVICE_ARCHS $$VALID_SIMULATOR_ARCHS - -- isEmpty(VALID_ARCHS): \ -- error("QMAKE_APPLE_DEVICE_ARCHS or QMAKE_APPLE_SIMULATOR_ARCHS must contain at least one architecture") -- - single_arch: VALID_ARCHS = $$first(VALID_ARCHS) - - ACTIVE_ARCHS = $(filter $(EXPORT_VALID_ARCHS), $(ARCHS)) -diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf -index 5003679bd0..c7c080cb07 100644 - ---- old/qtbase/mkspecs/features/toolchain.prf -+++ new/qtbase/mkspecs/features/toolchain.prf -@@ -182,9 +182,14 @@ isEmpty($${target_prefix}.INCDIRS) { - # UIKit simulator platforms will see the device SDK's sysroot in - # QMAKE_DEFAULT_*DIRS, because they're handled in a single build pass. - darwin { -- # Clang doesn't pick up the architecture from the sysroot, and will -- # default to the host architecture, so we need to manually set it. -- cxx_flags += -arch $$QMAKE_APPLE_DEVICE_ARCHS -+ uikit { -+ # Clang doesn't automatically pick up the architecture, just because -+ # we're passing the iOS sysroot below, and we will end up building the -+ # test for the host architecture, resulting in linker errors when -+ # linking against the iOS libraries. We work around this by passing -+ # the architecture explicitly. -+ cxx_flags += -arch $$first(QMAKE_APPLE_DEVICE_ARCHS) -+ } - - uikit:macx-xcode: \ - cxx_flags += -isysroot $$sdk_path_device.value diff --git a/depends/patches/qt/duplicate_lcqpafonts.patch b/depends/patches/qt/duplicate_lcqpafonts.patch new file mode 100644 index 0000000000..c460b51dcf --- /dev/null +++ b/depends/patches/qt/duplicate_lcqpafonts.patch @@ -0,0 +1,104 @@ +QtGui: Fix duplication of logging category lcQpaFonts + +Move it to qplatformfontdatabase.h. + +Upstream commit: + - Qt 6.0: ab01885e48873fb2ad71841a3f1627fe4d9cd835 + +--- a/qtbase/src/gui/text/qplatformfontdatabase.cpp ++++ b/qtbase/src/gui/text/qplatformfontdatabase.cpp +@@ -52,6 +52,8 @@ + + QT_BEGIN_NAMESPACE + ++Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts") ++ + void qt_registerFont(const QString &familyname, const QString &stylename, + const QString &foundryname, int weight, + QFont::Style style, int stretch, bool antialiased, + +--- a/qtbase/src/gui/text/qplatformfontdatabase.h ++++ b/qtbase/src/gui/text/qplatformfontdatabase.h +@@ -50,6 +50,7 @@ + // + + #include ++#include + #include + #include + #include +@@ -62,6 +63,7 @@ + + QT_BEGIN_NAMESPACE + ++Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) + + class QWritingSystemsPrivate; + + +--- a/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm ++++ b/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +@@ -86,8 +86,6 @@ + + QT_BEGIN_NAMESPACE + +-Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts") +- + static float SYNTHETIC_ITALIC_SKEW = std::tan(14.f * std::acos(0.f) / 90.f); + + bool QCoreTextFontEngine::ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length) + +--- a/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h ++++ b/qtbase/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +@@ -64,8 +64,6 @@ + + QT_BEGIN_NAMESPACE + +-Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) +- + class QCoreTextFontEngine : public QFontEngine + { + Q_GADGET + +--- a/qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp ++++ b/qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +@@ -68,8 +68,6 @@ + + QT_BEGIN_NAMESPACE + +-Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts") +- + #ifndef QT_NO_DIRECTWRITE + // ### fixme: Consider direct linking of dwrite.dll once Windows Vista pre SP2 is dropped (QTBUG-49711) + + +--- a/qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h ++++ b/qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h +@@ -63,8 +63,6 @@ + + QT_BEGIN_NAMESPACE + +-Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) +- + class QWindowsFontEngineData + { + Q_DISABLE_COPY_MOVE(QWindowsFontEngineData) + +--- a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp ++++ b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +@@ -40,6 +40,7 @@ + #include "qgenericunixthemes_p.h" + + #include "qpa/qplatformtheme_p.h" ++#include "qpa/qplatformfontdatabase.h" + + #include + #include +@@ -76,7 +77,6 @@ + QT_BEGIN_NAMESPACE + + Q_DECLARE_LOGGING_CATEGORY(qLcTray) +-Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts") + + ResourceHelper::ResourceHelper() + { diff --git a/depends/patches/qt/fast_fixed_dtoa_no_optimize.patch b/depends/patches/qt/fast_fixed_dtoa_no_optimize.patch new file mode 100644 index 0000000000..d4d6539f56 --- /dev/null +++ b/depends/patches/qt/fast_fixed_dtoa_no_optimize.patch @@ -0,0 +1,20 @@ +Modify the optimisation flags for FastFixedDtoa. +This fixes a non-determinism issue in the asm produced for +this function when cross-compiling on x86_64 and aarch64 for +the arm-linux-gnueabihf HOST. + +--- a/qtbase/src/3rdparty/double-conversion/fixed-dtoa.h ++++ b/qtbase/src/3rdparty/double-conversion/fixed-dtoa.h +@@ -48,9 +48,12 @@ namespace double_conversion { + // + // This method only works for some parameters. If it can't handle the input it + // returns false. The output is null-terminated when the function succeeds. ++#pragma GCC push_options ++#pragma GCC optimize ("-O1") + bool FastFixedDtoa(double v, int fractional_count, + Vector buffer, int* length, int* decimal_point); + ++#pragma GCC pop_options + } // namespace double_conversion + + #endif // DOUBLE_CONVERSION_FIXED_DTOA_H_ diff --git a/depends/patches/qt/fix-macos-linker.patch b/depends/patches/qt/fix-macos-linker.patch new file mode 100644 index 0000000000..e439685656 --- /dev/null +++ b/depends/patches/qt/fix-macos-linker.patch @@ -0,0 +1,55 @@ +qmake: Don't error out if QMAKE_DEFAULT_LIBDIRS is empty on macOS + +The new linker in Xcode 15 doesn't provide any default linker or +framework paths when requested via -v, but still seems to use the +default paths documented in the ld man page. + +We trust that linker will do the right thing, even if we don't +know of its default linker paths. + +We also need to opt out of the default fallback logic to +set the libdirs to /lib and /usr/lib. + +This may result in UnixMakefileGenerator::findLibraries finding +different libraries than expected, if additional paths are +passed with -L, which will then take precedence for qmake, +even if the linker itself will use the library from the +SDK's default paths. This should hopefully not be an issue +in practice, as we don't turn -lFoo into absolute paths in +qmake, so the only risk is that we're picking up the wrong +prl files and adding additional dependencies that the lib +in the SDK doesn't have. + +Upstream commits: + - Qt 5.15.16: Not yet publicly available. + - Qt dev: cdf64b0e47115cc473e1afd1472b4b09e130b2a5 + +For other Qt branches see +https://codereview.qt-project.org/q/I2347b26e2df0828471373b0e15b8c9089274c65d + +--- old/qtbase/mkspecs/features/toolchain.prf ++++ new/qtbase/mkspecs/features/toolchain.prf +@@ -288,9 +288,12 @@ isEmpty($${target_prefix}.INCDIRS) { + } + } + } +- isEmpty(QMAKE_DEFAULT_LIBDIRS)|isEmpty(QMAKE_DEFAULT_INCDIRS): \ ++ isEmpty(QMAKE_DEFAULT_INCDIRS): \ + !integrity: \ +- error("failed to parse default search paths from compiler output") ++ error("failed to parse default include paths from compiler output") ++ isEmpty(QMAKE_DEFAULT_LIBDIRS): \ ++ !integrity:!darwin: \ ++ error("failed to parse default library paths from compiler output") + QMAKE_DEFAULT_LIBDIRS = $$unique(QMAKE_DEFAULT_LIBDIRS) + } else: ghs { + cmd = $$QMAKE_CXX $$QMAKE_CXXFLAGS -$${LITERAL_HASH} -o /tmp/fake_output /tmp/fake_input.cpp +@@ -412,7 +415,7 @@ isEmpty($${target_prefix}.INCDIRS) { + QMAKE_DEFAULT_INCDIRS = $$split(INCLUDE, $$QMAKE_DIRLIST_SEP) + } + +- unix:if(!cross_compile|host_build) { ++ unix:!darwin:if(!cross_compile|host_build) { + isEmpty(QMAKE_DEFAULT_INCDIRS): QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include + isEmpty(QMAKE_DEFAULT_LIBDIRS): QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib + } diff --git a/depends/patches/qt/fix_android_jni_static.patch b/depends/patches/qt/fix_android_jni_static.patch index a186aeb8f6..89c96026fb 100644 --- a/depends/patches/qt/fix_android_jni_static.patch +++ b/depends/patches/qt/fix_android_jni_static.patch @@ -1,6 +1,6 @@ --- old/qtbase/src/plugins/platforms/android/androidjnimain.cpp +++ new/qtbase/src/plugins/platforms/android/androidjnimain.cpp -@@ -898,6 +898,14 @@ +@@ -979,6 +979,14 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } diff --git a/depends/patches/qt/fix_android_pch.patch b/depends/patches/qt/fix_android_pch.patch deleted file mode 100644 index 195e1c5e59..0000000000 --- a/depends/patches/qt/fix_android_pch.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- old/qtbase/mkspecs/common/android-base-head.conf -+++ new/qtbase/mkspecs/common/android-base-head.conf -@@ -72,6 +72,6 @@ CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX- - QMAKE_PCH_OUTPUT_EXT = .gch - - QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} --QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE} -+QMAKE_CFLAGS_USE_PRECOMPILE = -include-pch ${QMAKE_PCH_OUTPUT} - QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} - QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE diff --git a/depends/patches/qt/fix_lib_paths.patch b/depends/patches/qt/fix_lib_paths.patch deleted file mode 100644 index d1a15373f4..0000000000 --- a/depends/patches/qt/fix_lib_paths.patch +++ /dev/null @@ -1,193 +0,0 @@ ---- old/qtbase/mkspecs/common/mac.conf -+++ new/qtbase/mkspecs/common/mac.conf -@@ -14,7 +14,6 @@ - - QMAKE_RESOURCE = /Developer/Tools/Rez - QMAKE_EXTENSION_SHLIB = dylib --QMAKE_EXTENSIONS_AUX_SHLIB = tbd - QMAKE_LIBDIR = - - # sdk.prf will prefix the proper SDK sysroot - ---- old/qtbase/mkspecs/features/qmake_use.prf -+++ new/qtbase/mkspecs/features/qmake_use.prf -@@ -22,6 +22,8 @@ - !defined(QMAKE_LIBS_$$nu, var): \ - error("Library '$$lower($$replace(nu, _, -))' is not defined.") - -+ QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu) -+ - debug: \ - LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu) - else: \ - ---- old/qtbase/mkspecs/features/qt_configure.prf -+++ new/qtbase/mkspecs/features/qt_configure.prf -@@ -526,98 +526,23 @@ - return($$sysrootified) - } - --# libs-var, libs, in-paths, out-paths-var -+# libs-var, libs, in-paths - defineTest(qtConfResolveLibs) { -- ret = true -- paths = $$3 -- out = -- copy = false -- for (l, 2) { -- $$copy { -- copy = false -- out += $$l -- } else: equals(l, "-s") { -- # em++ flag to link libraries from emscripten-ports; passed on literally. -- copy = true -- out += $$l -- } else: contains(l, "^-L.*") { -- lp = $$replace(l, "^-L", ) -- gcc: lp = $$qtGccSysrootifiedPath($$lp) -- !exists($$lp/.) { -- qtLog("Library path $$val_escape(lp) is invalid.") -- ret = false -- } else { -- paths += $$lp -- } -- } else: contains(l, "^-l.*") { -- lib = $$replace(l, "^-l", ) -- lcan = -- integrity:contains(lib, "^.*\\.a") { -- # INTEGRITY compiler searches for exact filename -- # if -l argument has .a suffix -- lcan += $${lib} -- } else: contains(lib, "^:.*") { -- # Use exact filename when -l:filename syntax is used. -- lib ~= s/^:// -- lcan += $${lib} -- } else: unix { -- # Under UNIX, we look for actual shared libraries, in addition -- # to static ones. -- shexts = $$QMAKE_EXTENSION_SHLIB $$QMAKE_EXTENSIONS_AUX_SHLIB -- for (ext, shexts) { -- lcan += $${QMAKE_PREFIX_SHLIB}$${lib}.$${ext} -- } -- lcan += \ -- $${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB} -- } else { -- # Under Windows, we look only for static libraries, as even for DLLs -- # one actually links against a static import library. -- mingw { -- lcan += \ -- # MinGW supports UNIX-style library naming in addition to -- # the MSVC style. -- lib$${lib}.dll.a lib$${lib}.a \ -- # Fun fact: prefix-less libraries are also supported. -- $${lib}.dll.a $${lib}.a -- } -- lcan += $${lib}.lib -- } -- l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS) -- isEmpty(l) { -- qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.") -- ret = false -- } else { -- out += $$l -- } -- } else { -- out += $$l -- } -- } -- $$1 = $$out -+ for (path, 3): \ -+ pre_lflags += -L$$path -+ $$1 = $$pre_lflags $$2 - export($$1) -- !isEmpty(4) { -- $$4 = $$paths -- export($$4) -- } -- return($$ret) --} -- --# source-var --defineTest(qtConfResolveAllLibs) { -- ret = true -- !qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \ -- ret = false -- for (b, $${1}.builds._KEYS_): \ -- !qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \ -- ret = false -- return($$ret) -+ return(true) - } - - # libs-var, in-paths, libs - defineTest(qtConfResolvePathLibs) { - ret = true -- gcc: 2 = $$qtGccSysrootifiedPaths($$2) -- for (libdir, 2) { -+ gcc: \ -+ local_paths = $$qtGccSysrootifiedPaths($$2) -+ else: \ -+ local_paths = $$2 -+ for (libdir, local_paths) { - !exists($$libdir/.) { - qtLog("Library path $$val_escape(libdir) is invalid.") - ret = false -@@ -667,8 +592,11 @@ - # includes-var, in-paths, test-object-var - defineTest(qtConfResolvePathIncs) { - ret = true -- gcc: 2 = $$qtGccSysrootifiedPaths($$2) -- for (incdir, 2) { -+ gcc: \ -+ local_paths = $$qtGccSysrootifiedPaths($$2) -+ else: \ -+ local_paths = $$2 -+ for (incdir, local_paths) { - !exists($$incdir/.) { - qtLog("Include path $$val_escape(incdir) is invalid.") - ret = false -@@ -727,6 +655,7 @@ - vars += $$eval(config.commandline.rev_assignments.$${iv}) - defined(config.input.$${iv}, var) { - eval($${1}.builds.$${b} = $$eval(config.input.$${iv})) -+ export($${1}.builds.$${b}) - $${1}.builds._KEYS_ *= $${b} - any = true - } else { -@@ -741,11 +670,14 @@ - export($${1}.builds._KEYS_) - # we also reset the generic libs, to avoid surprises. - $${1}.libs = -+ export($${1}.libs) - } - - # direct libs. overwrites inline libs. -- defined(config.input.$${input}.libs, var): \ -+ defined(config.input.$${input}.libs, var) { - eval($${1}.libs = $$eval(config.input.$${input}.libs)) -+ export($${1}.libs) -+ } - - includes = $$eval(config.input.$${input}.incdir) - -@@ -754,6 +686,7 @@ - !isEmpty(prefix) { - includes += $$prefix/include - $${1}.libs = -L$$prefix/lib $$eval($${1}.libs) -+ export($${1}.libs) - } - - libdir = $$eval(config.input.$${input}.libdir) -@@ -762,11 +695,9 @@ - for (ld, libdir): \ - libs += -L$$ld - $${1}.libs = $$libs $$eval($${1}.libs) -+ export($${1}.libs) - } - -- !qtConfResolveAllLibs($$1): \ -- return(false) -- - !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \ - return(false) - diff --git a/depends/patches/qt/fix_limits_header.patch b/depends/patches/qt/fix_limits_header.patch deleted file mode 100644 index e4313770e5..0000000000 --- a/depends/patches/qt/fix_limits_header.patch +++ /dev/null @@ -1,44 +0,0 @@ -Fix compiling with GCC 11 - -See: https://bugreports.qt.io/browse/QTBUG-90395. - -Upstream commits: - - Qt 5.15 -- unavailable as open source - - Qt 6.0: b2af6332ea37e45ab230a7a5d2d278f86d961b83 - - Qt 6.1: 9c56d4da2ff631a8c1c30475bd792f6c86bda53c - ---- old/qtbase/src/corelib/global/qendian.h -+++ new/qtbase/src/corelib/global/qendian.h -@@ -44,6 +44,8 @@ - #include - #include - -+#include -+ - // include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems - #include - #include - ---- old/qtbase/src/corelib/tools/qbytearraymatcher.h -+++ new/qtbase/src/corelib/tools/qbytearraymatcher.h -@@ -42,6 +42,8 @@ - - #include - -+#include -+ - QT_BEGIN_NAMESPACE - - - ---- old/qtbase/src/tools/moc/generator.cpp -+++ new/qtbase/src/tools/moc/generator.cpp -@@ -40,6 +40,8 @@ - #include - #include - -+#include -+ - #include - #include - diff --git a/depends/patches/qt/fix_montery_include.patch b/depends/patches/qt/fix_montery_include.patch deleted file mode 100644 index 38b700addf..0000000000 --- a/depends/patches/qt/fix_montery_include.patch +++ /dev/null @@ -1,21 +0,0 @@ -From dece6f5840463ae2ddf927d65eb1b3680e34a547 -From: Øystein Heskestad -Date: Wed, 27 Oct 2021 13:07:46 +0200 -Subject: [PATCH] Add missing macOS header file that was indirectly included before - -See: https://bugreports.qt.io/browse/QTBUG-97855 - -Upstream Commits: - - Qt 6.2: c884bf138a21dd7320e35cef34d24e22e74d7ce0 - -diff --git a/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h b/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h -index e070ba97..07c75b04 100644 ---- a/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h -+++ b/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h -@@ -40,6 +40,7 @@ - #ifndef QIOSURFACEGRAPHICSBUFFER_H - #define QIOSURFACEGRAPHICSBUFFER_H - -+#include - #include - #include diff --git a/depends/patches/qt/fix_no_printer.patch b/depends/patches/qt/fix_no_printer.patch deleted file mode 100644 index 1372356138..0000000000 --- a/depends/patches/qt/fix_no_printer.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- x/qtbase/src/plugins/platforms/cocoa/qprintengine_mac_p.h -+++ y/qtbase/src/plugins/platforms/cocoa/qprintengine_mac_p.h -@@ -52,6 +52,7 @@ - // - - #include -+#include - - #ifndef QT_NO_PRINTER - ---- x/qtbase/src/plugins/plugins.pro -+++ y/qtbase/src/plugins/plugins.pro -@@ -9,6 +9,3 @@ qtHaveModule(gui) { - !android:qtConfig(library): SUBDIRS *= generic - } - qtHaveModule(widgets): SUBDIRS += styles -- --!winrt:qtHaveModule(printsupport): \ -- SUBDIRS += printsupport diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch index a5de2b4b9e..73f4d89f73 100644 --- a/depends/patches/qt/fix_qt_pkgconfig.patch +++ b/depends/patches/qt/fix_qt_pkgconfig.patch @@ -4,20 +4,8 @@ load(qt_targets) # this builds on top of qt_common --!internal_module:if(unix|mingw) { +-!internal_module:if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) { +if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) { CONFIG += create_pc QMAKE_PKGCONFIG_DESTDIR = pkgconfig host_build: \ -@@ -284,9 +284,9 @@ load(qt_targets) - QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -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 - !isEmpty(lib_replace0.match) { diff --git a/depends/patches/qt/guix_cross_lib_path.patch b/depends/patches/qt/guix_cross_lib_path.patch new file mode 100644 index 0000000000..7911dc21d7 --- /dev/null +++ b/depends/patches/qt/guix_cross_lib_path.patch @@ -0,0 +1,17 @@ +Facilitate guix building with CROSS_LIBRARY_PATH + +See discussion in https://github.com/bitcoin/bitcoin/pull/15277. + +--- a/qtbase/mkspecs/features/toolchain.prf ++++ b/qtbase/mkspecs/features/toolchain.prf +@@ -236,8 +236,8 @@ isEmpty($${target_prefix}.INCDIRS) { + add_libraries = false + for (line, output) { + line ~= s/^[ \\t]*// # remove leading spaces +- contains(line, "LIBRARY_PATH=.*") { +- line ~= s/^LIBRARY_PATH=// # remove leading LIBRARY_PATH= ++ contains(line, "(CROSS_)?LIBRARY_PATH=.*") { ++ line ~= s/^(CROSS_)?LIBRARY_PATH=// # remove leading (CROSS_)?LIBRARY_PATH= + equals(QMAKE_HOST.os, Windows): \ + paths = $$split(line, ;) + else: \ diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf index e4bfaa1463..cb94bf07b4 100644 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -15,10 +15,8 @@ QMAKE_MAC_SDK.macosx.SDKVersion = $${MAC_SDK_VERSION} QMAKE_MAC_SDK.macosx.PlatformPath = /phony !host_build: QMAKE_CFLAGS += -target $${MAC_TARGET} !host_build: QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS -!host_build: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS +!host_build: QMAKE_CXXFLAGS += -target $${MAC_TARGET} !host_build: QMAKE_LFLAGS += -target $${MAC_TARGET} QMAKE_AR = $${CROSS_COMPILE}ar cq QMAKE_RANLIB=$${CROSS_COMPILE}ranlib -QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool -QMAKE_INSTALL_NAME_TOOL=$${CROSS_COMPILE}install_name_tool load(qt_config) diff --git a/depends/patches/qt/memory_resource.patch b/depends/patches/qt/memory_resource.patch new file mode 100644 index 0000000000..650c328528 --- /dev/null +++ b/depends/patches/qt/memory_resource.patch @@ -0,0 +1,49 @@ +Fix unusable memory_resource on macos + +See https://bugreports.qt.io/browse/QTBUG-117484 +and https://bugreports.qt.io/browse/QTBUG-114316 + +--- a/qtbase/src/corelib/tools/qduplicatetracker_p.h ++++ b/qtbase/src/corelib/tools/qduplicatetracker_p.h +@@ -52,7 +52,7 @@ + + #include + +-#if QT_HAS_INCLUDE() && __cplusplus > 201402L ++#ifdef __cpp_lib_memory_resource + # include + # include + #else + +--- a/qtbase/src/corelib/global/qcompilerdetection.h ++++ b/qtbase/src/corelib/global/qcompilerdetection.h +@@ -1050,16 +1050,22 @@ + # endif // !_HAS_CONSTEXPR + # endif // !__GLIBCXX__ && !_LIBCPP_VERSION + # endif // Q_OS_QNX +-# if (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) && defined(Q_OS_MAC) && defined(__GNUC_LIBSTD__) \ +- && ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402) ++# if (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) && defined(Q_OS_MAC) ++# if defined(__GNUC_LIBSTD__) && ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402) + // Apple has not updated libstdc++ since 2007, which means it does not have + // or std::move. Let's disable these features +-# undef Q_COMPILER_INITIALIZER_LISTS +-# undef Q_COMPILER_RVALUE_REFS +-# undef Q_COMPILER_REF_QUALIFIERS ++# undef Q_COMPILER_INITIALIZER_LISTS ++# undef Q_COMPILER_RVALUE_REFS ++# undef Q_COMPILER_REF_QUALIFIERS + // Also disable , since it's clearly not there +-# undef Q_COMPILER_ATOMICS +-# endif ++# undef Q_COMPILER_ATOMICS ++# endif ++# if defined(__cpp_lib_memory_resource) \ ++ && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 140000) \ ++ || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 170000)) ++# undef __cpp_lib_memory_resource // Only supported on macOS 14 and iOS 17 ++# endif ++# endif // (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) && defined(Q_OS_MAC) + # if defined(Q_CC_CLANG) && defined(Q_CC_INTEL) && Q_CC_INTEL >= 1500 + // ICC 15.x and 16.0 have their own implementation of std::atomic, which is activated when in Clang mode + // (probably because libc++'s on OS X failed to compile), but they're missing some diff --git a/depends/patches/qt/no-xlib.patch b/depends/patches/qt/no-xlib.patch index f4a6f09ee4..0f7965d2ea 100644 --- a/depends/patches/qt/no-xlib.patch +++ b/depends/patches/qt/no-xlib.patch @@ -4,12 +4,7 @@ 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 @@ @@ -38,7 +33,7 @@ index 7c62c2e2b3..c05c6c0a07 100644 xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape) { -@@ -556,7 +560,9 @@ static xcb_cursor_t loadCursor(void *dpy, 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(); @@ -47,17 +42,16 @@ index 7c62c2e2b3..c05c6c0a07 100644 +#endif xcb_cursor_t cursor = XCB_NONE; - // Try Xcursor first -@@ -585,7 +591,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) - + #if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) +@@ -590,6 +596,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); -@@ -593,6 +599,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) +@@ -597,6 +604,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) cursorId, cursorId + 1, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0); } @@ -65,6 +59,3 @@ index 7c62c2e2b3..c05c6c0a07 100644 if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) { const char *name = cursorNames[cshape].front(); --- -2.22.0 - diff --git a/depends/patches/qt/no_sdk_version_check.patch b/depends/patches/qt/no_sdk_version_check.patch deleted file mode 100644 index b16635b572..0000000000 --- a/depends/patches/qt/no_sdk_version_check.patch +++ /dev/null @@ -1,20 +0,0 @@ -commit f5eb142cd04be2bc4ca610ed3b5b7e8ce3520ee3 -Author: fanquake -Date: Tue Jan 5 16:08:49 2021 +0800 - - Don't invoke macOS SDK version checking - - This tries to use xcrun which is not available when cross-compiling. - -diff --git a/qtbase/mkspecs/features/mac/default_post.prf b/qtbase/mkspecs/features/mac/default_post.prf -index 92a9112bca6..447e186eb26 100644 ---- a/qtbase/mkspecs/features/mac/default_post.prf -+++ b/qtbase/mkspecs/features/mac/default_post.prf -@@ -8,7 +8,6 @@ contains(TEMPLATE, .*app) { - !macx-xcode:if(isEmpty(BUILDS)|build_pass) { - # Detect changes to the platform SDK - QMAKE_EXTRA_VARIABLES += QMAKE_MAC_SDK QMAKE_MAC_SDK_VERSION QMAKE_XCODE_DEVELOPER_PATH -- QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/sdk.mk) - } - - # Detect incompatible SDK versions diff --git a/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch b/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch index 0358bea6e9..f0c14a9400 100644 --- a/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch +++ b/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch @@ -7,7 +7,7 @@ Upstream report: https://bugreports.qt.io/browse/QTBUG-83160 diff --git a/qtbase/src/tools/moc/main.cpp b/qtbase/src/tools/moc/main.cpp --- a/qtbase/src/tools/moc/main.cpp +++ b/qtbase/src/tools/moc/main.cpp -@@ -188,6 +188,7 @@ int runMoc(int argc, char **argv) +@@ -238,6 +238,7 @@ int runMoc(int argc, char **argv) dummyVariadicFunctionMacro.arguments += Symbol(0, PP_IDENTIFIER, "__VA_ARGS__"); pp.macros["__attribute__"] = dummyVariadicFunctionMacro; pp.macros["__declspec"] = dummyVariadicFunctionMacro; diff --git a/depends/patches/qt/rcc_hardcode_timestamp.patch b/depends/patches/qt/rcc_hardcode_timestamp.patch new file mode 100644 index 0000000000..03f3897975 --- /dev/null +++ b/depends/patches/qt/rcc_hardcode_timestamp.patch @@ -0,0 +1,24 @@ +Hardcode last modified timestamp in Qt RCC + +This change allows the already built qt package to be reused even with +the SOURCE_DATE_EPOCH variable set, e.g., for Guix builds. + + +--- old/qtbase/src/tools/rcc/rcc.cpp ++++ new/qtbase/src/tools/rcc/rcc.cpp +@@ -227,14 +227,7 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib) + + if (lib.formatVersion() >= 2) { + // last modified time stamp +- const QDateTime lastModified = m_fileInfo.lastModified(); +- quint64 lastmod = quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0); +- static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong(); +- if (sourceDate != 0) +- lastmod = sourceDate; +- static const quint64 sourceDate2 = 1000 * qgetenv("SOURCE_DATE_EPOCH").toULongLong(); +- if (sourceDate2 != 0) +- lastmod = sourceDate2; ++ quint64 lastmod = quint64(1); + lib.writeNumber8(lastmod); + if (text || pass1) + lib.writeChar('\n'); diff --git a/depends/patches/qt/support_new_android_ndks.patch b/depends/patches/qt/support_new_android_ndks.patch deleted file mode 100644 index 85c8ae2132..0000000000 --- a/depends/patches/qt/support_new_android_ndks.patch +++ /dev/null @@ -1,122 +0,0 @@ -Follow Google's BuildSystemMaintainers doc to support future NDK releases. - -Upstream commit: - - Qt 5.14: 9b14950ff600a4ce5a8698b67ab38907c50417f1 - ---- old/qtbase/mkspecs/android-clang/qmake.conf -+++ new/qtbase/mkspecs/android-clang/qmake.conf -@@ -14,43 +14,29 @@ - QMAKE_CC = $$NDK_LLVM_PATH/bin/clang - QMAKE_CXX = $$NDK_LLVM_PATH/bin/clang++ - -+# Follow https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md -+ - equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ -- QMAKE_CFLAGS += -target armv7-none-linux-androideabi --else: equals(ANDROID_TARGET_ARCH, armeabi): \ -- QMAKE_CFLAGS += -target armv5te-none-linux-androideabi -+ QMAKE_CFLAGS = -target armv7a-linux-androideabi$$replace(ANDROID_PLATFORM, "android-", "") - else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \ -- QMAKE_CFLAGS += -target aarch64-none-linux-android -+ QMAKE_CFLAGS = -target aarch64-linux-android$$replace(ANDROID_PLATFORM, "android-", "") - else: equals(ANDROID_TARGET_ARCH, x86): \ -- QMAKE_CFLAGS += -target i686-none-linux-android -mstackrealign -+ QMAKE_CFLAGS = -target i686-linux-android$$replace(ANDROID_PLATFORM, "android-", "") -mstackrealign - else: equals(ANDROID_TARGET_ARCH, x86_64): \ -- QMAKE_CFLAGS += -target x86_64-none-linux-android --else: equals(ANDROID_TARGET_ARCH, mips): \ -- QMAKE_CFLAGS += -target mipsel-none-linux-android --else: equals(ANDROID_TARGET_ARCH, mips64): \ -- QMAKE_CFLAGS += -target mips64el-none-linux-android -- --QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH -fno-limit-debug-info -- --QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ --equals(ANDROID_TARGET_ARCH, armeabi-v7a): QMAKE_LINK += -Wl,--exclude-libs,libunwind.a -- --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 \ -- -isystem $$NDK_ROOT/sources/android/support/include \ -- -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include -+ QMAKE_CFLAGS = -target x86_64-linux-android$$replace(ANDROID_PLATFORM, "android-", "") - --ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH -+QMAKE_CFLAGS += -fno-limit-debug-info - --ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so -+QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS - --ANDROID_USE_LLVM = true -+ANDROID_STDCPP_PATH = $$NDK_LLVM_PATH/sysroot/usr/lib/$$NDK_TOOLS_PREFIX/libc++_shared.so - --exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \ -- ANDROID_CXX_STL_LIBS = -lc++ --else: \ -- ANDROID_CXX_STL_LIBS = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so.$$replace(ANDROID_PLATFORM, "android-", "") -+ANDROID_USE_LLVM = true - --QMAKE_CFLAGS_OPTIMIZE_SIZE = -Oz -+QMAKE_CFLAGS_OPTIMIZE_SIZE = -Oz -+QMAKE_LIBDIR_POST = -+QMAKE_LFLAGS = -+QMAKE_LIBS_PRIVATE = -+ANDROID_CXX_STL_LIBS = - - include(../common/android-base-tail.conf) - ---- old/qtbase/mkspecs/common/android-base-head.conf -+++ new/qtbase/mkspecs/common/android-base-head.conf -@@ -64,7 +58,6 @@ - } - - CONFIG += $$ANDROID_PLATFORM --QMAKE_CFLAGS = -D__ANDROID_API__=$$replace(ANDROID_PLATFORM, "android-", "") - - ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ - ---- old/qtbase/mkspecs/common/android-base-tail.conf -+++ new/qtbase/mkspecs/common/android-base-tail.conf -@@ -6,22 +6,17 @@ - QMAKE_CFLAGS += -fstack-protector-strong -DANDROID - - equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ -- QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove -+ QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp - else: equals(ANDROID_TARGET_ARCH, armeabi): \ -- QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float -fno-builtin-memmove --# -fno-builtin-memmove is used to workaround https://code.google.com/p/android/issues/detail?id=81692 -+ QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float - - QMAKE_CFLAGS_WARN_ON = -Wall -W - QMAKE_CFLAGS_WARN_OFF = - equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) { - CONFIG += optimize_size - QMAKE_CFLAGS_DEBUG = -g -marm -O0 -- equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) { -- DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND -- } else { -- QMAKE_CFLAGS_RELEASE += -mthumb -- QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb -- } -+ QMAKE_CFLAGS_RELEASE += -mthumb -+ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb - } - - QMAKE_CFLAGS_SHLIB = -fPIC -@@ -61,15 +56,12 @@ - QMAKE_RANLIB = $${CROSS_COMPILE}ranlib - - QMAKE_INCDIR_POST = --QMAKE_LIBDIR_POST = $$ANDROID_SOURCES_CXX_STL_LIBDIR - QMAKE_INCDIR_X11 = - QMAKE_LIBDIR_X11 = - QMAKE_INCDIR_OPENGL = - QMAKE_LIBDIR_OPENGL = - - QMAKE_LINK_SHLIB = $$QMAKE_LINK --QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH --equals(ANDROID_TARGET_ARCH, x86_64) QMAKE_LFLAGS += -L$$ANDROID_PLATFORM_ROOT_PATH/usr/lib64 - QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared - QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared - QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB diff --git a/depends/patches/qt/use_android_ndk23.patch b/depends/patches/qt/use_android_ndk23.patch new file mode 100644 index 0000000000..f22367d527 --- /dev/null +++ b/depends/patches/qt/use_android_ndk23.patch @@ -0,0 +1,13 @@ +Use Android NDK r23 LTS + +--- old/qtbase/mkspecs/features/android/default_pre.prf ++++ new/qtbase/mkspecs/features/android/default_pre.prf +@@ -76,7 +76,7 @@ else: equals(QT_ARCH, x86_64): CROSS_COMPILE = $$NDK_LLVM_PATH/bin/x86_64-linux- + else: equals(QT_ARCH, arm64-v8a): CROSS_COMPILE = $$NDK_LLVM_PATH/bin/aarch64-linux-android- + else: CROSS_COMPILE = $$NDK_LLVM_PATH/bin/arm-linux-androideabi- + +-QMAKE_RANLIB = $${CROSS_COMPILE}ranlib ++QMAKE_RANLIB = $$NDK_LLVM_PATH/bin/llvm-ranlib + QMAKE_LINK_SHLIB = $$QMAKE_LINK + QMAKE_LFLAGS = + diff --git a/depends/patches/qt/windows_lto.patch b/depends/patches/qt/windows_lto.patch new file mode 100644 index 0000000000..ea379a60f1 --- /dev/null +++ b/depends/patches/qt/windows_lto.patch @@ -0,0 +1,31 @@ +Qt (for Windows) fails to build under LTO, due to multiple definition issues, i.e + +multiple definition of `QAccessibleLineEdit::~QAccessibleLineEdit()'; + +Possibly related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94156. + +diff --git a/qtbase/src/widgets/accessible/simplewidgets.cpp b/qtbase/src/widgets/accessible/simplewidgets.cpp +index 107fd729fe..0e61878f39 100644 +--- a/qtbase/src/widgets/accessible/simplewidgets.cpp ++++ b/qtbase/src/widgets/accessible/simplewidgets.cpp +@@ -109,6 +109,8 @@ QString qt_accHotKey(const QString &text); + \ingroup accessibility + */ + ++QAccessibleLineEdit::~QAccessibleLineEdit(){}; ++ + /*! + Creates a QAccessibleButton object for \a w. + */ +diff --git a/qtbase/src/widgets/accessible/simplewidgets_p.h b/qtbase/src/widgets/accessible/simplewidgets_p.h +index 73572e3059..658da86143 100644 +--- a/qtbase/src/widgets/accessible/simplewidgets_p.h ++++ b/qtbase/src/widgets/accessible/simplewidgets_p.h +@@ -155,6 +155,7 @@ class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInte + public: + explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString()); + ++ ~QAccessibleLineEdit(); + QString text(QAccessible::Text t) const override; + void setText(QAccessible::Text t, const QString &text) override; + QAccessible::State state() const override; diff --git a/src/addresstype.h b/src/addresstype.h index 155508a131..9b0083f7c4 100644 --- a/src/addresstype.h +++ b/src/addresstype.h @@ -17,6 +17,7 @@ enum struct AddressType , sparkMint = 11 , sparksMint = 12 , sparkSpend = 13 + , payToExchangeAddress = 14 }; namespace zerocoin { namespace utils { diff --git a/src/base58.cpp b/src/base58.cpp index 005eed6d35..47fc8e12c2 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -297,6 +297,10 @@ bool CBitcoinAddress::GetIndexKey(uint160& hashBytes, AddressType & type) const memcpy(&hashBytes, &vchData[0], 20); type = AddressType::payToPubKeyHash; return true; + } else if (vchVersion == Params().Base58Prefix(CChainParams::EXCHANGE_PUBKEY_ADDRESS)) { + memcpy(&hashBytes, &vchData[0], 20); + type = AddressType::payToExchangeAddress; + return true; } else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS)) { memcpy(&hashBytes, &vchData[0], 20); type = AddressType::payToScriptHash; @@ -316,6 +320,17 @@ bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const return true; } +bool CBitcoinAddress::GetKeyIDExt(CKeyID& keyID) const +{ + if (!IsValid() || !(vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) || + vchVersion == Params().Base58Prefix(CChainParams::EXCHANGE_PUBKEY_ADDRESS))) + return false; + uint160 id; + memcpy(&id, &vchData[0], 20); + keyID = CKeyID(id); + return true; +} + bool CBitcoinAddress::IsScript() const { return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); diff --git a/src/base58.h b/src/base58.h index 1ea609ae40..4f2789c0c1 100644 --- a/src/base58.h +++ b/src/base58.h @@ -127,6 +127,7 @@ class CBitcoinAddress : public CBase58Data { CTxDestination Get() const; bool GetIndexKey(uint160& hashBytes, AddressType & type) const; bool GetKeyID(CKeyID &keyID) const; + bool GetKeyIDExt(CKeyID &keyID) const; // same as GetKeyID() but also works in case of exchange address bool IsScript() const; }; diff --git a/src/clientversion.h b/src/clientversion.h index d71a0b7e5e..6f9956da0d 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -17,7 +17,7 @@ #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 14 #define CLIENT_VERSION_REVISION 13 -#define CLIENT_VERSION_BUILD 1 +#define CLIENT_VERSION_BUILD 2 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/evo/spork.cpp b/src/evo/spork.cpp index 01f3a88543..1ce4f740b0 100644 --- a/src/evo/spork.cpp +++ b/src/evo/spork.cpp @@ -69,6 +69,18 @@ static bool IsTransactionAllowed(const CTransaction &tx, const ActiveSporkMap &s } } } + else if (tx.IsSparkTransaction()) { + if (sporkMap.count(CSporkAction::featureSpark) > 0) + return state.DoS(100, false, REJECT_CONFLICT, "txn-spark-disabled", false, "Spark transactions are disabled at the moment"); + + if (tx.IsSparkSpend()) { + const auto &limitSpork = sporkMap.find(CSporkAction::featureSparkTransparentLimit); + if (limitSpork != sporkMap.cend()) { + if (spark::GetSpendTransparentAmount(tx) > (CAmount)limitSpork->second.second) + return state.DoS(100, false, REJECT_CONFLICT, "txn-spark-disabled", false, "Spark transaction is over the transparent limit"); + } + } + } return true; } @@ -186,8 +198,24 @@ bool CSporkManager::IsBlockAllowed(const CBlock &block, const CBlockIndex *pinde totalTransparentOutput += lelantus::GetSpendTransparentAmount(*tx); } - return totalTransparentOutput <= CAmount(limit) ? true : - state.DoS(100, false, REJECT_CONFLICT, "txn-lelantus-disabled", false, "Block is over the transparent output limit because of existing spork"); + if (totalTransparentOutput > CAmount(limit)) + return state.DoS(100, false, REJECT_CONFLICT, "txn-lelantus-disabled", false, "Block is over the transparent output limit because of existing spork"); + } + + if (pindex->activeDisablingSporks.count(CSporkAction::featureSparkTransparentLimit) > 0) { + // limit total transparent output of lelantus joinsplit + int64_t limit = pindex->activeDisablingSporks.at(CSporkAction::featureSparkTransparentLimit).second; + CAmount totalTransparentOutput = 0; + + for (const auto &tx: block.vtx) { + if (!tx->IsSparkSpend()) + continue; + + totalTransparentOutput += spark::GetSpendTransparentAmount(*tx); + } + + if (totalTransparentOutput > CAmount(limit)) + return state.DoS(100, false, REJECT_CONFLICT, "txn-spark-disabled", false, "Block is over the transparent output limit because of existing spork"); } return true; diff --git a/src/evo/spork.h b/src/evo/spork.h index 4087513813..4b4d67fc67 100644 --- a/src/evo/spork.h +++ b/src/evo/spork.h @@ -17,6 +17,8 @@ struct CSporkAction static constexpr const char *featureLelantusTransparentLimit = "lelantustransparentlimit"; static constexpr const char *featureChainlocks = "chainlocks"; static constexpr const char *featureInstantSend = "instantsend"; + static constexpr const char *featureSpark = "spark"; + static constexpr const char *featureSparkTransparentLimit = "sparktransparentlimit"; enum ActionType { sporkDisable = 1, diff --git a/src/libspark/grootle.cpp b/src/libspark/grootle.cpp index 7fd11135e2..26c8085641 100644 --- a/src/libspark/grootle.cpp +++ b/src/libspark/grootle.cpp @@ -413,16 +413,6 @@ bool Grootle::verify( return false; } - // Check for zero inputs - for (std::size_t t = 0; t < S1.size(); t++) { - for (std::size_t i = 0; i < S.size(); i++) { - if (S[i] == S1[t] || V[i] == V1[t]) { - LogPrintf("Invalid offset commitment"); - return false; - } - } - } - // Check proof semantics for (std::size_t t = 0; t < M; t++) { GrootleProof proof = proofs[t]; diff --git a/src/libspark/spend_transaction.cpp b/src/libspark/spend_transaction.cpp index b2d3561e79..d98dc67a15 100644 --- a/src/libspark/spend_transaction.cpp +++ b/src/libspark/spend_transaction.cpp @@ -178,7 +178,9 @@ SpendTransaction::SpendTransaction( Scalar mu = hash_bind( hash_bind_inner( this->cover_set_representations, + this->S1, this->C1, + this->T, this->grootle_proofs, this->balance_proof, this->range_proof @@ -293,9 +295,11 @@ bool SpendTransaction::verify( // Compute the binding hash Scalar mu = hash_bind( - tx.hash_bind_inner( + hash_bind_inner( tx.cover_set_representations, + tx.S1, tx.C1, + tx.T, tx.grootle_proofs, tx.balance_proof, tx.range_proof @@ -405,9 +409,13 @@ bool SpendTransaction::verify( // Hash function H_bind_inner // This function pre-hashes auxiliary data that makes things easier for a limited signer who cannot process the data directly // Its value is then used as part of the binding hash, which a limited signer can verify as part of the signing process +// +// Note that transparent components of the transaction are bound into `cover_set_representation`, so they don't appear separately. std::vector SpendTransaction::hash_bind_inner( - const std::unordered_map>& cover_set_representations, + const std::map>& cover_set_representations, + const std::vector& S1, const std::vector& C1, + const std::vector& T, const std::vector& grootle_proofs, const SchnorrProof& balance_proof, const BPPlusProof& range_proof @@ -451,4 +459,4 @@ const std::map& SpendTransaction::getBlockHashes() { return set_id_blockHash; } -} +} \ No newline at end of file diff --git a/src/libspark/spend_transaction.h b/src/libspark/spend_transaction.h index 6b2803da5a..24da12bea2 100644 --- a/src/libspark/spend_transaction.h +++ b/src/libspark/spend_transaction.h @@ -60,9 +60,11 @@ class SpendTransaction { static bool verify(const Params* params, const std::vector& transactions, const std::unordered_map>& cover_sets); static bool verify(const SpendTransaction& transaction, const std::unordered_map>& cover_sets); - std::vector hash_bind_inner( - const std::unordered_map>& cover_set_representations, + static std::vector hash_bind_inner( + const std::map>& cover_set_representations, + const std::vector& S1, const std::vector& C1, + const std::vector& T, const std::vector& grootle_proofs, const SchnorrProof& balance_proof, const BPPlusProof& range_proof @@ -111,7 +113,7 @@ class SpendTransaction { const Params* params; // We need to construct and pass this data before running verification std::unordered_map cover_set_sizes; - std::unordered_map> cover_set_representations; + std::map> cover_set_representations; std::vector out_coins; // All this data we need to serialize diff --git a/src/miner.cpp b/src/miner.cpp index fee39aaff0..492cb3477b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1003,34 +1003,49 @@ void BlockAssembler::FillBlackListForBlockTemplate() { // Now if we have limit on lelantus transparent outputs scan mempool and drop all the transactions exceeding the limit if (sporkMap.count(CSporkAction::featureLelantusTransparentLimit) > 0) { - CAmount limit = sporkMap[CSporkAction::featureLelantusTransparentLimit].second; + BlacklistTxsExceedingLimit(sporkMap[CSporkAction::featureLelantusTransparentLimit].second, + [](const CTransaction &tx)->bool { return tx.IsLelantusJoinSplit(); }, + [](const CTransaction &tx)->CAmount { return lelantus::GetSpendTransparentAmount(tx); }); + } - std::vector joinSplitTxs; - for (CTxMemPool::txiter mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) { - if (txBlackList.count(mi) == 0 && mi->GetTx().IsLelantusJoinSplit()) - joinSplitTxs.push_back(mi); - } + // Same for spark spends + if (sporkMap.count(CSporkAction::featureSparkTransparentLimit) > 0) { + BlacklistTxsExceedingLimit(sporkMap[CSporkAction::featureSparkTransparentLimit].second, + [](const CTransaction &tx)->bool { return tx.IsSparkSpend(); }, + [](const CTransaction &tx)->CAmount { return spark::GetSpendTransparentAmount(tx); }); + } +} - // sort join splits in order of their transparent outputs so large txs won't block smaller ones - // from getting into the mempool - std::sort(joinSplitTxs.begin(), joinSplitTxs.end(), - [](CTxMemPool::txiter a, CTxMemPool::txiter b) -> bool { - return lelantus::GetSpendTransparentAmount(a->GetTx()) < lelantus::GetSpendTransparentAmount(b->GetTx()); - }); - - CAmount transparentAmount = 0; - std::vector::const_iterator it; - for (it = joinSplitTxs.cbegin(); it != joinSplitTxs.cend(); ++it) { - CAmount output = lelantus::GetSpendTransparentAmount((*it)->GetTx()); - if (transparentAmount + output > limit) - break; - transparentAmount += output; - } +void BlockAssembler::BlacklistTxsExceedingLimit(CAmount limit, + std::function txTypeFilter, + std::function txAmount) { + + std::vector txList; + for (CTxMemPool::txiter mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) { + if (txBlackList.count(mi) == 0 && txTypeFilter(mi->GetTx())) + txList.push_back(mi); + } - // found all the joinsplit transaction fitting in the limit, blacklist the rest - while (it != joinSplitTxs.cend()) - mempool.CalculateDescendants(*it++, txBlackList); + // sort transactions in order of their transparent outputs so large txs won't block smaller ones + // from getting into the mempool + std::sort(txList.begin(), txList.end(), + [=](CTxMemPool::txiter a, CTxMemPool::txiter b) -> bool { + return txAmount(a->GetTx()) < txAmount(b->GetTx()); + }); + + CAmount transparentAmount = 0; + std::vector::const_iterator it; + for (it = txList.cbegin(); it != txList.cend(); ++it) { + CAmount output = txAmount((*it)->GetTx()); + if (transparentAmount + output > limit) + break; + transparentAmount += output; } + + // found all the private transaction fitting in the limit, blacklist the rest + while (it != txList.cend()) + mempool.CalculateDescendants(*it++, txBlackList); + } ////////////////////////////////////////////////////////////////////////////// diff --git a/src/miner.h b/src/miner.h index b6348ab94e..cd55d640eb 100644 --- a/src/miner.h +++ b/src/miner.h @@ -232,6 +232,11 @@ class BlockAssembler /** Fill txBlackList set */ void FillBlackListForBlockTemplate(); + + /** Ensure spark/lelantus txs don't exceed specific limit */ + void BlacklistTxsExceedingLimit(CAmount limit, + std::function txTypeFilter, + std::function txAmount); }; /** Modify the extranonce in a block */ diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index bd08df359d..f8588235ce 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -319,7 +319,7 @@ void AddressBookPage::done(int retval) // Figure out which address was selected, and return it QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); - Q_FOREACH (const QModelIndex& index, indexes) { + for (const QModelIndex& index : indexes) { QVariant address = table->model()->data(index); returnValue = address.toString(); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index c66e62947c..749cce4e40 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -581,7 +582,7 @@ bool BitcoinApplication::migrateSettings(const QString &oldOrganizationName, con QSettings oldSettings(oldOrganizationName, oldApplicationName); QList keys = oldSettings.allKeys(); if (!keys.empty()) { - Q_FOREACH(const QString &key, keys) { + for (const QString &key : keys) { newSettings.setValue(key, oldSettings.value(key)); } newSettings.sync(); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 3b0cb09ab0..b1ac1c059c 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1191,7 +1191,7 @@ void BitcoinGUI::dropEvent(QDropEvent *event) { if(event->mimeData()->hasUrls()) { - Q_FOREACH(const QUrl &uri, event->mimeData()->urls()) + for (const QUrl &uri : event->mimeData()->urls()) { Q_EMIT receivedURI(uri.toString()); } @@ -1439,7 +1439,7 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *pl QList units = BitcoinUnits::availableUnits(); int max_width = 0; const QFontMetrics fm(font()); - Q_FOREACH (const BitcoinUnits::Unit unit, units) + for (const BitcoinUnits::Unit unit : units) { max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit))); } @@ -1457,7 +1457,7 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event) void UnitDisplayStatusBarControl::createContextMenu() { menu = new QMenu(this); - Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) + for (BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) { QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this); menuAction->setData(QVariant(u)); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 332774e688..2963acd958 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -426,7 +426,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog, bool a CAmount nPayAmount = 0; bool fDust = false; CMutableTransaction txDummy; - Q_FOREACH(const CAmount &amount, CoinControlDialog::payAmounts) + for (const CAmount &amount : CoinControlDialog::payAmounts) { nPayAmount += amount; diff --git a/src/qt/lelantuscoincontroldialog.cpp b/src/qt/lelantuscoincontroldialog.cpp index 930268ca39..6837cf8f04 100644 --- a/src/qt/lelantuscoincontroldialog.cpp +++ b/src/qt/lelantuscoincontroldialog.cpp @@ -43,7 +43,7 @@ void CoinControlStorage::updateLabels(WalletModel *model, QDialog* dialog) CAmount nPayAmount = 0; bool fDust = false; CMutableTransaction txDummy; - Q_FOREACH(const CAmount &amount, payAmounts) + for (const CAmount &amount : payAmounts) { nPayAmount += amount; diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 6b94d1cc7a..6017558d4f 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -84,7 +84,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : ui->lang->setToolTip(ui->lang->toolTip().arg(tr(PACKAGE_NAME))); ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant("")); - Q_FOREACH(const QString &langStr, translations.entryList()) + for (const QString &langStr : translations.entryList()) { QLocale locale(langStr); diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 1e95277093..9bbd3e465b 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -117,7 +117,7 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) bool PaymentServer::ipcSendCommandLine() { bool fResult = false; - Q_FOREACH (const QString& r, savedPaymentRequests) + for (const QString& r : savedPaymentRequests) { QLocalSocket* socket = new QLocalSocket(); socket->connectToServer(ipcServerName(), QIODevice::WriteOnly); diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 088be1a150..35fe0bc16a 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -62,7 +62,7 @@ class PeerTablePriv #if QT_VERSION >= 0x040700 cachedNodeStats.reserve(vstats.size()); #endif - Q_FOREACH (const CNodeStats& nodestats, vstats) + for (const CNodeStats& nodestats : vstats) { CNodeCombinedStats stats; stats.nodeStateStats.nMisbehavior = 0; @@ -91,7 +91,7 @@ class PeerTablePriv // build index map mapNodeRows.clear(); int row = 0; - Q_FOREACH (const CNodeCombinedStats& stats, cachedNodeStats) + for (const CNodeCombinedStats& stats : cachedNodeStats) mapNodeRows.insert(std::pair(stats.nodeStats.nodeid, row++)); } diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp index dc8084b256..f098d9b3a6 100644 --- a/src/qt/platformstyle.cpp +++ b/src/qt/platformstyle.cpp @@ -62,8 +62,7 @@ void MakeLockColorImage(QImage& img, const QColor& colorbase) QIcon ColorizeIcon(const QIcon& ico, const QColor& colorbase) { QIcon new_ico; - QSize sz; - Q_FOREACH(sz, ico.availableSizes()) + for (QSize sz : ico.availableSizes()) { QImage img(ico.pixmap(sz).toImage()); MakeSingleColorImage(img, colorbase); diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 87a95bf84e..963a11f4dd 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -222,7 +222,7 @@ void ReceiveCoinsDialog::on_showRequestButton_clicked() return; QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); - Q_FOREACH (const QModelIndex& index, selection) { + for (const QModelIndex& index : selection) { on_recentRequestsView_doubleClicked(index); } } diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 1bfe3e3c27..8880bf0af7 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -434,7 +434,7 @@ void SendCoinsDialog::on_sendButton_clicked() formatted.append(recipientElement); } } else { - Q_FOREACH(const SendCoinsRecipient &rcp, currentTransaction.getRecipients()) + for (const SendCoinsRecipient &rcp : currentTransaction.getRecipients()) { // generate bold amount string QString amount = "" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); @@ -461,14 +461,17 @@ void SendCoinsDialog::on_sendButton_clicked() } QString questionString = tr("Are you sure you want to send?"); questionString.append("

%1"); + double txSize; if ((fAnonymousMode == false) && (recipients.size() == sparkAddressCount) && spark::IsSparkAllowed()) { for (auto &transaction : transactions) { txFee += transaction.getTransactionFee(); mintSparkAmount += transaction.getTotalTransactionAmount(); + txSize += (double)transaction.getTransactionSize(); } } else { - txFee= currentTransaction.getTransactionFee(); + txFee = currentTransaction.getTransactionFee(); + txSize = (double)currentTransaction.getTransactionSize(); } if(txFee > 0) @@ -480,7 +483,7 @@ void SendCoinsDialog::on_sendButton_clicked() questionString.append(tr("added as transaction fee")); // append transaction size - questionString.append(" (" + QString::number((double)currentTransaction.getTransactionSize() / 1000) + " kB)"); + questionString.append(" (" + QString::number(txSize / 1000) + " kB)"); } // add total amount in all subdivision units @@ -499,7 +502,7 @@ void SendCoinsDialog::on_sendButton_clicked() } QStringList alternativeUnits; - Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) + for (BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) { if(u != model->getOptionsModel()->getDisplayUnit()) alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount)); diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 8f0276f063..16a6ae820f 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -235,7 +235,7 @@ void SplashScreen::unsubscribeFromCoreSignals() uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, _1)); uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); #ifdef ENABLE_WALLET - Q_FOREACH(CWallet* const & pwallet, connectedWallets) { + for (CWallet* const & pwallet : connectedWallets) { pwallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); } #endif diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 78e4fc4d99..796112d5f0 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -141,10 +141,10 @@ void TrafficGraphWidget::updateRates() } float tmax = 0.0f; - Q_FOREACH(float f, vSamplesIn) { + for (float f : vSamplesIn) { if(f > tmax) tmax = f; } - Q_FOREACH(float f, vSamplesOut) { + for (float f : vSamplesOut) { if(f > tmax) tmax = f; } fMax = tmax; diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 899f438b2c..a13eb7e347 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -312,7 +312,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += "" + tr("Output index") + ": " + QString::number(rec->getOutputIndex()) + "
"; // Message from normal firo:URI (firo:123...?message=example) - Q_FOREACH (const PAIRTYPE(std::string, std::string)& r, wtx.vOrderForm) + for (const PAIRTYPE(std::string, std::string)& r : wtx.vOrderForm) if (r.first == "Message") strHTML += "
" + tr("Message") + ":
" + GUIUtil::HtmlEscape(r.second, true) + "
"; diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 4ef5fe269f..d65f7577f7 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -146,7 +146,7 @@ class TransactionTablePriv { parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); int insert_idx = lowerIndex; - Q_FOREACH(const TransactionRecord &rec, toInsert) + for (const TransactionRecord &rec : toInsert) { cachedWallet.insert(insert_idx, rec); insert_idx += 1; diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 0f468a65fe..27cdb40da8 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -102,7 +102,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : QTextCharFormat bold; bold.setFontWeight(QFont::Bold); - Q_FOREACH (const QString &line, coreOptions.split("\n")) { + for (const QString &line : coreOptions.split("\n")) { if (line.startsWith(" -")) { cursor.currentTable()->appendRows(1); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 6db696c214..e6908f973d 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -288,7 +288,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact int nAddresses = 0; // Pre-check input data for validity - Q_FOREACH(const SendCoinsRecipient &rcp, recipients) + for (const SendCoinsRecipient &rcp : recipients) { if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true; @@ -379,7 +379,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareJoinSplitTransaction( int nAddresses = 0; // Pre-check input data for validity - Q_FOREACH(const SendCoinsRecipient &rcp, recipients) + for (const SendCoinsRecipient &rcp : recipients) { if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true; @@ -564,7 +564,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran LOCK2(cs_main, wallet->cs_wallet); CWalletTx *newTx = transaction.getTransaction(); - Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients()) + for (const SendCoinsRecipient &rcp : transaction.getRecipients()) { if (!rcp.message.isEmpty()) // Message from normal firo:URI (firo:123...?message=example) newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString())); @@ -582,7 +582,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran // Add addresses / update labels that we've sent to to the address book, // and emit coinsSent signal for each recipient - Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients()) + for (const SendCoinsRecipient &rcp : transaction.getRecipients()) { { std::string strAddress = rcp.address.toStdString(); @@ -619,7 +619,7 @@ WalletModel::SendCoinsReturn WalletModel::sendPrivateCoins(WalletModelTransactio LOCK2(cs_main, wallet->cs_wallet); CWalletTx *newTx = transaction.getTransaction(); - Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients()) + for (const SendCoinsRecipient &rcp : transaction.getRecipients()) { if (!rcp.message.isEmpty()) // Message from normal firo:URI (firo:123...?message=example) newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString())); @@ -639,7 +639,7 @@ WalletModel::SendCoinsReturn WalletModel::sendPrivateCoins(WalletModelTransactio // Add addresses / update labels that we've sent to to the address book, // and emit coinsSent signal for each recipient - Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients()) + for (const SendCoinsRecipient &rcp : transaction.getRecipients()) { { std::string strAddress = rcp.address.toStdString(); @@ -1547,18 +1547,19 @@ WalletModel::SendCoinsReturn WalletModel::mintSparkCoins(std::vectorCommitTransaction(wtxAndFee[i].first, *reservekey++, g_connman.get(), state)) + return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason())); + Q_FOREACH(const SendCoinsRecipient &rcp, transactions[i].getRecipients()) { // CWalletTx* newTx = transactions[i].getTransaction(); if (!rcp.message.isEmpty()) // Message from normal firo:URI (firo:123...?message=example) wtxAndFee[i].first.vOrderForm.push_back(make_pair("Message", rcp.message.toStdString())); - if (!wallet->CommitTransaction(wtxAndFee[i].first, *reservekey++, g_connman.get(), state)) - return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason())); - + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << *wtxAndFee[i].first.tx; transaction_array.append(&(ssTx[0]), ssTx.size()); - + { std::string strAddress = rcp.address.toStdString(); std::string strLabel = rcp.label.toStdString(); diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 855e721f59..c9109b9a12 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -83,7 +83,7 @@ void WalletModelTransaction::reassignAmounts(int nChangePosRet) CAmount WalletModelTransaction::getTotalTransactionAmount() { CAmount totalTransactionAmount = 0; - Q_FOREACH(const SendCoinsRecipient &rcp, recipients) + for (const SendCoinsRecipient &rcp : recipients) { totalTransactionAmount += rcp.amount; } diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index fbe12bcd5f..7ad2f71bb4 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -212,8 +212,26 @@ UniValue validateaddress(const JSONRPCRequest& request) CBitcoinAddress address(request.params[0].get_str()); bool isValid = address.IsValid(); + bool isvalidSpark = false; + const spark::Params* params = spark::Params::get_default(); + unsigned char network = spark::GetNetworkType(); + spark::Address sAddress(params); + + if (!isValid) { + try { + unsigned char coinNetwork = sAddress.decode(request.params[0].get_str()); + isvalidSpark = coinNetwork == network; + } catch (const std::exception &) { + isvalidSpark = false; + } + } + UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("isvalid", isValid)); + if (isvalidSpark) + ret.push_back(Pair("isvalidSpark", isvalidSpark)); + else + ret.push_back(Pair("isvalid", isValid)); + if (isValid) { CTxDestination dest = address.Get(); @@ -235,7 +253,7 @@ UniValue validateaddress(const JSONRPCRequest& request) CKeyID keyID; if (pwallet) { const auto& meta = pwallet->mapKeyMetadata; - auto it = address.GetKeyID(keyID) ? meta.find(keyID) : meta.end(); + auto it = address.GetKeyIDExt(keyID) ? meta.find(keyID) : meta.end(); if (it == meta.end()) { it = meta.find(CScriptID(scriptPubKey)); } @@ -247,6 +265,18 @@ UniValue validateaddress(const JSONRPCRequest& request) } } } +#endif + } else if (isvalidSpark) { + std::string currentAddress = sAddress.encode(network); + ret.push_back(Pair("address", currentAddress)); + +#ifdef ENABLE_WALLET + bool ismine = false; + if (pwallet && pwallet->sparkWallet) { + ismine = pwallet->sparkWallet->isAddressMine(currentAddress); + } + + ret.push_back(Pair("ismine", ismine)); #endif } return ret; @@ -568,7 +598,7 @@ bool getAddressFromIndex(AddressType const & type, const uint160 &hash, std::str { if (type == AddressType::payToScriptHash) { address = CBitcoinAddress(CScriptID(hash)).ToString(); - } else if (type == AddressType::payToPubKeyHash) { + } else if (type == AddressType::payToPubKeyHash || type == AddressType::payToExchangeAddress) { address = CBitcoinAddress(CKeyID(hash)).ToString(); } else { return false; diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 53139b1db3..a27449884b 100644 --- a/src/rpc/rpcevo.cpp +++ b/src/rpc/rpcevo.cpp @@ -1407,7 +1407,9 @@ UniValue spork(const JSONRPCRequest& request) CSporkAction::featureLelantus, CSporkAction::featureChainlocks, CSporkAction::featureInstantSend, - CSporkAction::featureLelantusTransparentLimit + CSporkAction::featureLelantusTransparentLimit, + CSporkAction::featureSpark, + CSporkAction::featureSparkTransparentLimit }; for (const CSporkAction &action: sporkTx.actions) { diff --git a/src/spark/sparkwallet.cpp b/src/spark/sparkwallet.cpp index 6069417378..197fd5e6f4 100644 --- a/src/spark/sparkwallet.cpp +++ b/src/spark/sparkwallet.cpp @@ -1153,6 +1153,14 @@ bool CSparkWallet::CreateSparkMintTransactions( nIn++; } + { + CValidationState state; + if (!mempool.IsTransactionAllowed(*wtx.tx, state)) { + strFailReason = _("Signing transaction failed"); + return false; + } + } + wtx.SetTx(MakeTransactionRef(std::move(tx))); wtxAndFee.push_back(std::make_pair(wtx, nFeeRet)); @@ -1528,9 +1536,6 @@ CWalletTx CSparkWallet::CreateSparkSpendTransaction( i++; } - // check fee - wtxNew.SetTx(MakeTransactionRef(std::move(tx))); - if (GetTransactionWeight(tx) >= MAX_NEW_TX_WEIGHT) { throw std::runtime_error(_("Transaction too large")); } @@ -1549,10 +1554,18 @@ CWalletTx CSparkWallet::CreateSparkSpendTransaction( throw std::invalid_argument(_("Not enough fee estimated")); } + wtxNew.SetTx(MakeTransactionRef(std::move(tx))); + result.push_back(wtxNew); } } - + { + CValidationState state; + for (CWalletTx& wtx : result) { + if (!mempool.IsTransactionAllowed(*wtx.tx, state)) + throw std::invalid_argument(_("Spark transactions are disabled at the moment")); + } + } if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) { // Lastly, ensure this tx will pass the mempool's chain limits size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); diff --git a/src/sync.cpp b/src/sync.cpp index d65f4cc601..b58009989a 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -4,6 +4,16 @@ #include "sync.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "util.h" #include "utilstrencodings.h" diff --git a/src/test/evospork_tests.cpp b/src/test/evospork_tests.cpp index 775a1ae581..fb01ac97bc 100644 --- a/src/test/evospork_tests.cpp +++ b/src/test/evospork_tests.cpp @@ -432,4 +432,255 @@ BOOST_AUTO_TEST_CASE(startstopblock) } +BOOST_AUTO_TEST_SUITE_END() + +// Extend spork stop block to 2000 +struct SparkSporkTestingSetup : public SparkTestingSetup +{ + Consensus::Params &mutableParams; + Consensus::Params originalParams; + + SparkSporkTestingSetup() : SparkTestingSetup(), mutableParams(const_cast(Params().GetConsensus())) + { + spark::CSparkState::GetState()->Reset(); + mempool.clear(); + originalParams = mutableParams; + mutableParams.nEvoSporkStopBlock = 2000; + } + + ~SparkSporkTestingSetup() { + mutableParams = originalParams; + spark::CSparkState::GetState()->Reset(); + mempool.clear(); + } + +}; + +BOOST_FIXTURE_TEST_SUITE(evospork_spark_tests, SparkSporkTestingSetup) + +BOOST_AUTO_TEST_CASE(general) +{ + int prevHeight; + pwalletMain->SetBroadcastTransactions(true); + + for (int n=chainActive.Height(); n<1000; n++) + GenerateBlock({}); + + auto utxos = BuildSimpleUtxoMap(coinbaseTxns); + CMutableTransaction sporkTx1 = CreateSporkTx(utxos, coinbaseKey, { + {CSporkAction::sporkDisable, CSporkAction::featureSpark, 0, 1075} + }); + CMutableTransaction sporkTx2 = CreateSporkTx(utxos, coinbaseKey, { + {CSporkAction::sporkDisable, CSporkAction::featureSpark, 0, 1085} + }); + CMutableTransaction sporkTx3 = CreateSporkTx(utxos, coinbaseKey, { + {CSporkAction::sporkEnable, CSporkAction::featureSpark, 0, 0} + }); + + prevHeight = chainActive.Height(); + GenerateBlock({sporkTx1}); + // spork should be accepted + BOOST_ASSERT(chainActive.Height() == prevHeight+1); + + std::vector sparkMints; + GenerateMints({1*COIN, 2*COIN}, sparkMints); + + prevHeight = chainActive.Height(); + GenerateBlock(sparkMints); + // can't accept spark tx after spark + BOOST_ASSERT(chainActive.Height() == prevHeight); + + // wait until the spork expires + for (int n=chainActive.Height(); n<1075; n++) + GenerateBlock({}); + prevHeight = chainActive.Height(); + GenerateBlock({sparkMints[0]}); + BOOST_ASSERT(chainActive.Height() == prevHeight+1); + + // another disabling spork + GenerateBlock({sporkTx2}); + // ensure lelantus is disabled + prevHeight = chainActive.Height(); + GenerateBlock({sparkMints[1]}); + BOOST_ASSERT(chainActive.Height() == prevHeight); + + // block with enabling spork + GenerateBlock({sporkTx3}); + // ensure lelantus is enabled now + prevHeight = chainActive.Height(); + GenerateBlock({sparkMints[1]}); + BOOST_ASSERT(chainActive.Height() == prevHeight+1); +} + +BOOST_AUTO_TEST_CASE(mempool) +{ + int prevHeight; + pwalletMain->SetBroadcastTransactions(true); + + for (int n=chainActive.Height(); n<1000; n++) + GenerateBlock({}); + + auto utxos = BuildSimpleUtxoMap(coinbaseTxns); + CMutableTransaction sporkTx1 = CreateSporkTx(utxos, coinbaseKey, { + {CSporkAction::sporkDisable, CSporkAction::featureSpark, 0, 1075} + }); + CMutableTransaction sporkTx2 = CreateSporkTx(utxos, coinbaseKey, { + {CSporkAction::sporkDisable, CSporkAction::featureSpark, 0, 1085} + }); + + std::vector sparkMints; + GenerateMints({1*COIN, 2*COIN}, sparkMints); + ::mempool.removeRecursive(sparkMints[0]); + ::mempool.removeRecursive(sparkMints[1]); + + CBlock blockWithSparkMint = CreateBlock({sparkMints[0]}, coinbaseKey); + + // put one mint into the mempool + CommitToMempool(sparkMints[0]); + BOOST_ASSERT(::mempool.size() == 1); + + // push spork to mempool + CommitToMempool(sporkTx1); + // spork should be in the mempool, spark mint should be pushed out of it + BOOST_ASSERT(::mempool.size() == 1); + BOOST_ASSERT(::mempool.exists(sporkTx1.GetHash()) && !::mempool.exists(sparkMints[0].GetHash())); + + // another spark tx shouldn't get to the mempool + CommitToMempool(sparkMints[1]); + BOOST_ASSERT(::mempool.size() == 1); + + // but should be accepted in block + prevHeight = chainActive.Height(); + ProcessNewBlock(Params(), std::make_shared(blockWithSparkMint), true, nullptr); + BOOST_ASSERT(chainActive.Height() == prevHeight+1); + + // mine spork into the block + CreateAndProcessBlock({sporkTx1}, coinbaseKey); + // mempool should clear + BOOST_ASSERT(::mempool.size() == 0); + + // because there is active spork at the tip spark mint shouldn't get into the mempool + BOOST_ASSERT(!CommitToMempool(sparkMints[1])); + + for (int n=chainActive.Height(); n<1075; n++) + CreateAndProcessBlock({}, coinbaseKey); + + // spork expired, should accept now + BOOST_ASSERT(CommitToMempool(sparkMints[1])); + // try and generate a block with second spork without it ever entering the mempool + CreateAndProcessBlock({sporkTx2}, coinbaseKey); + // now we have a mint in the mempool and active spork. Verify that miner correctly blocks the mint + // from being mined + fAllowMempoolTxsInCreateBlock = true; + CBlock block = CreateBlock({}, coinbaseKey); + for (CTransactionRef tx: block.vtx) { + BOOST_ASSERT(!tx->IsSparkTransaction()); + } + BOOST_ASSERT(::mempool.exists(sparkMints[1].GetHash())); + prevHeight = chainActive.Height(); + ProcessNewBlock(Params(), std::make_shared(block), true, nullptr); + BOOST_CHECK_EQUAL(chainActive.Height(), prevHeight+1); +} + +BOOST_AUTO_TEST_CASE(limit) +{ + int prevHeight; + pwalletMain->SetBroadcastTransactions(true); + + for (int n=chainActive.Height(); n<1000; n++) + GenerateBlock({}); + + auto utxos = BuildSimpleUtxoMap(coinbaseTxns); + CMutableTransaction sporkTx1 = CreateSporkTx(utxos, coinbaseKey, { + {CSporkAction::sporkLimit, CSporkAction::featureSparkTransparentLimit, 100*COIN, 1050} + }); + + auto params = spark::Params::get_default(); + + BOOST_ASSERT(pwalletMain->sparkWallet); + spark::Address address = pwalletMain->sparkWallet->generateNewAddress(); + + std::vector sparkMints; + for (int i=0; i<10; i++) { + std::vector> wtxAndFee; + std::vector mints{{address, 50*COIN, ""}}; + std::string error = pwalletMain->MintAndStoreSpark(mints, wtxAndFee, false); + BOOST_ASSERT(error.empty()); + for (auto &w: wtxAndFee) + sparkMints.emplace_back(*w.first.tx); + } + + GenerateBlock(sparkMints); + + for (int i=0; i<10; i++) + GenerateBlock({}); + + CAmount fee = 0; + CWalletTx spendWalletTx = pwalletMain->SpendAndStoreSpark({{script, 120*COIN, false, ""}}, {}, fee); + + CMutableTransaction spendTx = *spendWalletTx.tx; + + ::mempool.removeRecursive(spendWalletTx); + + auto sparkSpend = spark::ParseSparkSpend(spendTx); + std::vector lTags = sparkSpend.getUsedLTags(); + + // generate two smaller spark spend txs + CWalletTx smallSparkWalletTxs[2] = { + pwalletMain->SpendAndStoreSpark({{script, 70*COIN, false, ""}}, {}, fee), + pwalletMain->SpendAndStoreSpark({{script, 70*COIN, false, ""}}, {}, fee), + }; + + CMutableTransaction smallSparkTxs[2] = {*smallSparkWalletTxs[0].tx, *smallSparkWalletTxs[1].tx}; + + CommitToMempool(sporkTx1); + BOOST_ASSERT(::mempool.size() == 3); // two small spark spends and spork + + fAllowMempoolTxsInCreateBlock = true; + CBlock block = CreateBlock({}, script); + // should only have one spark spend transaction in the block + int nSparkSpends = 0; + for (CTransactionRef ptx: block.vtx) { + if (ptx->IsSparkSpend()) + nSparkSpends++; + } + BOOST_ASSERT(nSparkSpends == 1); + prevHeight = chainActive.Height(); + ProcessNewBlock(Params(), std::make_shared(block), true, nullptr); + BOOST_ASSERT(chainActive.Height() == prevHeight+1); + // one spark spend should be left at the mempool + BOOST_ASSERT(::mempool.size() == 1); + + // mine remaining spark spend into the block + prevHeight = chainActive.Height(); + GenerateBlock({}); + BOOST_ASSERT(chainActive.Height() == prevHeight+1); + BOOST_ASSERT(::mempool.size() == 0); + fAllowMempoolTxsInCreateBlock = false; + + // large spark spend tx is out of range, should fail now + BOOST_ASSERT(!CommitToMempool(spendTx)); + // should fail in block as well + prevHeight = chainActive.Height(); + GenerateBlock({spendTx}); + BOOST_ASSERT(chainActive.Height() == prevHeight); + + // skip to 1050 (spork expiration block) + for (int n=chainActive.Height(); n<1050; n++) + GenerateBlock({}); + + // should be accepted into the mempool + BOOST_ASSERT(CommitToMempool(spendTx)); + // and be mined into the block + prevHeight = chainActive.Height(); + GenerateBlock({spendTx}); + BOOST_ASSERT(chainActive.Height() == prevHeight+1); + // mempool should be clear + BOOST_ASSERT(::mempool.size() == 0); + // lTags should go into the state + spark::CSparkState *sparkState = spark::CSparkState::GetState(); + for (const GroupElement &lTag : lTags) + BOOST_ASSERT(sparkState->IsUsedLTag(lTag)); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 072d843455..850f148eed 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -202,10 +202,12 @@ CBlock TestChain100Setup::CreateBlock(const std::vector& tx } // Replace mempool-selected txns with just coinbase plus passed-in txns: - if (!fAllowMempoolTxsInCreateBlock) + if (!fAllowMempoolTxsInCreateBlock) { block.vtx.resize(1); - // Re-add quorum commitments - block.vtx.insert(block.vtx.end(), llmqCommitments.begin(), llmqCommitments.end()); + // Re-add quorum commitments + block.vtx.insert(block.vtx.end(), llmqCommitments.begin(), llmqCommitments.end()); + } + BOOST_FOREACH(const CMutableTransaction& tx, txns) block.vtx.push_back(MakeTransactionRef(tx)); diff --git a/src/txdb.cpp b/src/txdb.cpp index 78f325d38b..6cdf249d1c 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -510,6 +510,9 @@ std::pair classifyAddress(txnouttype type, std::vector(addresses.front().begin(), addresses.front().end())); + } else if(type == TX_EXCHANGEADDRESS) { + result.first = AddressType::payToExchangeAddress; + result.second = uint160(std::vector(addresses.front().begin(), addresses.front().end())); } return result; } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a21edd2f3f..2d3c92cc07 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -677,6 +677,12 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n); mapAddress.insert(std::make_pair(key, delta)); inserted.push_back(key); + } else if (prevout.scriptPubKey.IsPayToExchangeAddress()) { + std::vector hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23); + CMempoolAddressDeltaKey key(AddressType::payToExchangeAddress, uint160(hashBytes), txhash, j, 1); + CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n); + mapAddress.insert(std::make_pair(key, delta)); + inserted.push_back(key); } } @@ -693,6 +699,12 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC CMempoolAddressDeltaKey key(AddressType::payToPubKeyHash, uint160(hashBytes), txhash, k, 0); mapAddress.insert(std::make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); inserted.push_back(key); + } else if (out.scriptPubKey.IsPayToExchangeAddress()) { + std::vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); + std::pair ret; + CMempoolAddressDeltaKey key(AddressType::payToExchangeAddress, uint160(hashBytes), txhash, k, 0); + mapAddress.insert(std::make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); + inserted.push_back(key); } } @@ -753,6 +765,9 @@ void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCac } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { addressHash = uint160(std::vector (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); addressType = AddressType::payToPubKeyHash; + } else if (prevout.scriptPubKey.IsPayToExchangeAddress()) { + addressHash = uint160(std::vector (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); + addressType = AddressType::payToExchangeAddress; } else { addressHash.SetNull(); addressType = AddressType::unknown; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 7216be91c2..72d9e0cc3e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3950,7 +3950,7 @@ UniValue identifysparkcoins(const JSONRPCRequest& request) if (request.fHelp || request.params.size() != 1) throw std::runtime_error( - "identifysparkcoin \"txHash\"\n" + "identifysparkcoins \"txHash\"\n" "Identifies coins in transaction, and adds into wallet if yours"); EnsureSparkWalletIsAvailable(); @@ -3981,6 +3981,48 @@ UniValue identifysparkcoins(const JSONRPCRequest& request) return results; } +UniValue getsparkcoinaddr(const JSONRPCRequest& request) +{ + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { + return NullUniValue; + } + + if (request.fHelp || request.params.size() != 1) + throw std::runtime_error( + "getsparkcoinaddr \"txHash\"\n" + "Returns all spark outputs to you, address memo and amount for each"); + + EnsureSparkWalletIsAvailable(); + + uint256 txHash; + txHash.SetHex(request.params[0].get_str()); + + CTransactionRef tx; + uint256 hashBlock; + GetTransaction(txHash, tx, Params().GetConsensus(), hashBlock); + + UniValue results(UniValue::VARR);; + assert(pwallet != NULL); + + std::unordered_map coins = pwallet->sparkWallet->getMintMap(); + unsigned char network = spark::GetNetworkType(); + + for (const auto& coin : coins) + { + if (txHash == coin.second.txid) { + spark::Address address = pwallet->sparkWallet->getAddress(coin.second.i); + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("address", address.encode(network))); + entry.push_back(Pair("memo", SanitizeString(coin.second.memo))); + entry.push_back(Pair("amount", ValueFromAmount(coin.second.v))); + results.push_back(entry); + } + } + + return results; +} + UniValue mint(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); @@ -5733,6 +5775,7 @@ static const CRPCCommand rpcCommands[] = { "wallet", "spendspark", &spendspark, false }, { "wallet", "lelantustospark", &lelantustospark, false }, { "wallet", "identifysparkcoins", &identifysparkcoins, false }, + { "wallet", "getsparkcoinaddr", &getsparkcoinaddr, false }, //bip47 diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4c51712a9c..61dfbb1de9 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1961,7 +1961,7 @@ bool CWallet::IsMine(const CTransaction& tx) const { if (tx.IsSparkTransaction()) { if (!sparkWallet) - false; + return false; std::vector serialContext = spark::getSerialContext(tx); for (const auto& txout : tx.vout) { if (txout.scriptPubKey.IsSparkMint() || txout.scriptPubKey.IsSparkSMint()) {