From ddcecd9f5ea2f252fb93d9cfb9df17c457d4bc74 Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 19 Aug 2026 22:21:29 -0500 Subject: [PATCH 1/7] build(depends): add pinned Rust toolchain packages and crate vendoring native_rust installs the pinned prebuilt Rust toolchain as a native package and rust_stdlib provides the precompiled standard library for every supported cross target; contrib/devtools/update-rust-hashes.py maintains both pins together. funcs.mk gains a cargo environment wired to the depends cross toolchain and a per-package crate-vendoring template: any package that declares a vendored archive name and a cargo manifest gets its vendored-crate archive modeled as a real make target, created by cargo vendor when absent and required by the package's preprocess stamp and by make download, so a clean build can never reach the offline cargo build without vendored sources. Preprocessing extracts the archive and generates a rustc linker wrapper that preserves the full configured compiler command (target and sysroot flags, and any env prefix), since -C linker= takes a single executable. --- contrib/devtools/update-rust-hashes.py | 125 ++++++++++++++++++ depends/funcs.mk | 82 ++++++++++++ depends/packages/native_rust.mk | 55 ++++++++ depends/packages/rust_stdlib.mk | 70 ++++++++++ .../native_rust/fix-elf-interpreter.sh | 91 +++++++++++++ 5 files changed, 423 insertions(+) create mode 100755 contrib/devtools/update-rust-hashes.py create mode 100644 depends/packages/native_rust.mk create mode 100644 depends/packages/rust_stdlib.mk create mode 100755 depends/patches/native_rust/fix-elf-interpreter.sh diff --git a/contrib/devtools/update-rust-hashes.py b/contrib/devtools/update-rust-hashes.py new file mode 100755 index 000000000000..41afe9c4f039 --- /dev/null +++ b/contrib/devtools/update-rust-hashes.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2021-2022 The Zcash developers +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import hashlib +import re +import sys +import urllib.request +from pathlib import Path + +# Rust standard libraries provisioned in rust_stdlib.mk. Confined to the +# hosts we validate (the Guix release set); see rust_stdlib.mk. +CROSS_TARGETS = [ + # Linux + "aarch64-unknown-linux-musl", + "riscv64gc-unknown-linux-musl", + "x86_64-unknown-linux-musl", + # Windows + "x86_64-pc-windows-gnu", + # macOS + "aarch64-apple-darwin", + "x86_64-apple-darwin", +] + +# Native compilers provisioned in native_rust.mk (build hosts for depends) +NATIVE_TARGETS = [ + # Linux + ("aarch64-unknown-linux-gnu", "aarch64_linux"), + ("x86_64-unknown-linux-gnu", "x86_64_linux"), + # macOS + ("aarch64-apple-darwin", "aarch64_darwin"), + ("x86_64-apple-darwin", "x86_64_darwin"), +] + + +def get_rust_version(makefile_path: Path) -> str: + content = makefile_path.read_text() + match = re.search(r"\$\(package\)_version:=(.+)", content) + if not match: + raise RuntimeError("Could not find Rust version in makefile") + return match.group(1).strip() + + +def compute_sha256(url: str) -> str: + hasher = hashlib.sha256() + with urllib.request.urlopen(url) as response: + while chunk := response.read(8192): + hasher.update(chunk) + return hasher.hexdigest() + + +def update_hash_in_file(makefile_path: Path, pattern: str, new_hash: str) -> None: + content = makefile_path.read_text() + regex = re.compile(rf"^(\$\(package\)_{pattern}:=).*$", re.MULTILINE) + if not regex.search(content): + raise RuntimeError(f"Could not find pattern {pattern} in makefile") + new_content = regex.sub(rf"\g<1>{new_hash}", content) + makefile_path.write_text(new_content) + + +def update_version_in_file(path: Path, pattern: str, version: str) -> None: + content = path.read_text() + regex = re.compile(pattern, re.MULTILINE) + new_content, replacements = regex.subn( + lambda match: f"{match.group(1)}{version}{match.group(2) if match.lastindex == 2 else ''}", content + ) + if replacements != 1: + raise RuntimeError(f"Expected one version pin in {path}, found {replacements}") + path.write_text(new_content) + + +def compute_rust_hash(rust_version: str, rust_target: str) -> str: + url = f"https://static.rust-lang.org/dist/rust-{rust_version}-{rust_target}.tar.gz" + return compute_sha256(url) + + +def compute_stdlib_hash(rust_version: str, rust_target: str) -> str: + url = f"https://static.rust-lang.org/dist/rust-std-{rust_version}-{rust_target}.tar.gz" + return compute_sha256(url) + + +def main() -> int: + script_dir = Path(__file__).resolve().parent + native_rust_path = script_dir / "../../depends/packages/native_rust.mk" + native_rust_path = native_rust_path.resolve() + rust_stdlib_path = script_dir / "../../depends/packages/rust_stdlib.mk" + rust_stdlib_path = rust_stdlib_path.resolve() + for path in (native_rust_path, rust_stdlib_path): + if not path.exists(): + print(f"Error: {path} not found", file=sys.stderr) + return 1 + + rust_version = get_rust_version(native_rust_path) + + print(f"Rust version: {rust_version}\n") + print("Downloading native compiler hashes:") + + native_hashes = {} + for rust_target, makefile_id in NATIVE_TARGETS: + native_hashes[makefile_id] = compute_rust_hash(rust_version, rust_target) + print(f" Downloaded sha256_hash_{makefile_id}") + + print("\nDownloading stdlib hashes:") + stdlib_hashes = {} + for rust_target in CROSS_TARGETS: + stdlib_hashes[rust_target] = compute_stdlib_hash(rust_version, rust_target) + print(f" Downloaded sha256_hash_{rust_target}") + + for makefile_id, hash_value in native_hashes.items(): + update_hash_in_file(native_rust_path, f"sha256_hash_{makefile_id}", hash_value) + for rust_target, hash_value in stdlib_hashes.items(): + update_hash_in_file(rust_stdlib_path, f"sha256_hash_{rust_target}", hash_value) + + update_version_in_file(rust_stdlib_path, r"^(\$\(package\)_version:=).*$", rust_version) + print("\nSynchronized rust_stdlib.mk to the native_rust.mk version") + + print("\nDone!") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/depends/funcs.mk b/depends/funcs.mk index 566f83a9868e..a0caa3665386 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -197,6 +197,22 @@ $(1)_cmake += -DCMAKE_C_COMPILER_TARGET=$(host) $(1)_cmake += -DCMAKE_CXX_COMPILER_TARGET=$(host) endif endif + +$(1)_cargo=env CC="$$($(1)_cc)" \ + CXX="$$($(1)_cxx)" \ + AR="$$($(1)_ar)" \ + CFLAGS="$$($(1)_cppflags) $$($(1)_cflags)" \ + CXXFLAGS="$$($(1)_cppflags) $$($(1)_cxxflags)" \ + LDFLAGS="$$($(1)_ldflags)" \ + RUSTFLAGS="-C linker=$$($(1)_extract_dir)/rustc-linker.sh" \ + LD_LIBRARY_PATH="$$($($(1)_type)_prefix)/lib" +ifeq ($(host_os),darwin) +$(1)_cargo += MACOSX_DEPLOYMENT_TARGET="$(OSX_MIN_VERSION)" +ifneq ($(host),$(build)) +$(1)_cargo += SDKROOT="$(OSX_SDK)" +endif +endif +$(1)_cargo += cargo endef define int_add_cmds @@ -269,6 +285,50 @@ $(foreach stage,$(stages), .PHONY: $(1)_$(stage)) endef +# Template for vendoring a package's Rust crate dependencies +# Packages opt-in by defining $(package)_vendored_file_name and $(package)_cargo_manifest +# +# The archive is a real file target and a hard prerequisite of the +# package's preprocess stamp, so a clean build (or `make download`, +# which lists it as a prerequisite) vendors the crates before the +# offline cargo build can run; its absence is never silently skipped. +# vendor-$(1)-crates remains as a phony alias; delete the archive from +# SOURCES_PATH to force a re-vendor. +define int_vendor_crates +ifneq ($($(1)_vendored_file_name),) +$(1)_vendored_archive = $(SOURCES_PATH)/$($(1)_vendored_file_name) + +$$($(1)_vendored_archive): $(native_rust_cached) $($(1)_fetched) + @rm -rf $(WORK_PATH)/vendor-$(1) + @mkdir -p $(WORK_PATH)/vendor-$(1) + @$(build_TAR) --no-same-owner -xf $(native_rust_cached) -C $(WORK_PATH)/vendor-$(1) + @echo "Vendoring $(1) crates..." + @mkdir -p $(WORK_PATH)/vendor-$(1)/src + @cd $(WORK_PATH)/vendor-$(1)/src && $(build_TAR) --no-same-owner --strip-components=1 -xf $(SOURCES_PATH)/$($(1)_file_name) + @if test -f $(PATCHES_PATH)/$(1)/Cargo.lock; then \ + cp $(PATCHES_PATH)/$(1)/Cargo.lock $(WORK_PATH)/vendor-$(1)/src/$($(1)_cargo_lock_path); \ + fi + @$(WORK_PATH)/vendor-$(1)/native/bin/cargo vendor --locked --manifest-path $(WORK_PATH)/vendor-$(1)/src/$($(1)_cargo_manifest) $(WORK_PATH)/vendor-$(1)/src/vendored + @cd $(WORK_PATH)/vendor-$(1)/src; find vendored | sort | $(build_TAR) --no-recursion -czf $$($(1)_vendored_archive) -T - + @rm -rf $(WORK_PATH)/vendor-$(1) + @echo "Created $$($(1)_vendored_archive)" + +vendor-$(1)-crates: $$($(1)_vendored_archive) +.PHONY: vendor-$(1)-crates + +$($(1)_preprocessed): $$($(1)_vendored_archive) +endif +endef + +define download_rust_std_target +([ -f "$(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" ] && \ + echo "Already have rust-std-$(rust_stdlib_version)-$(1).tar.gz" || \ + (echo "Downloading rust-std-$(rust_stdlib_version)-$(1).tar.gz..." && \ + $(build_DOWNLOAD) "$(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" "$(rust_stdlib_download_path)/rust-std-$(rust_stdlib_version)-$(1).tar.gz")) && \ +echo "$(rust_stdlib_sha256_hash_$(1)) $(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" | $(build_SHA256SUM) -c - && \ +echo "$(rust_stdlib_sha256_hash_$(1)) rust-std-$(rust_stdlib_version)-$(1).tar.gz" > "$(SOURCES_PATH)/download-stamps/.stamp_fetched-rust_stdlib-$(rust_stdlib_version)-$(rust_stdlib_sha256_hash_$(1)).hash" +endef + # These functions create the build targets for each package. They must be # broken down into small steps so that each part is done for all packages # before moving on to the next step. Otherwise, a package's info @@ -286,6 +346,25 @@ $(foreach package,$(all_packages),$(eval $(call int_vars,$(package)))) $(foreach native_package,$(native_packages),$(eval include packages/$(native_package).mk)) $(foreach package,$(packages),$(eval include packages/$(package).mk)) +# Extend preprocess_cmds for cargo packages: extract the vendored +# crates (the archive is a hard prerequisite of the preprocess stamp, +# wired up in int_vendor_crates, so it is always present here) and +# install the rustc linker wrapper from the package's patches. rustc's +# `-C linker=` takes a single executable, but the configured compiler +# is a full command line (target/sysroot flags; under Guix an +# `env -u ...` prefix), so the wrapper execs $$CC from cargo's +# environment instead of the command's first word. +define int_cargo_preprocess_ext +$(1)_preprocess_cmds += && \ + echo "Extracting vendored crates for $(1)..." && \ + $(build_TAR) --no-same-owner -xf $(SOURCES_PATH)/$($(1)_vendored_file_name) && \ + mkdir -p .cargo && \ + cp $(PATCHES_PATH)/$(1)/cargo-config.toml .cargo/config.toml && \ + cp $(PATCHES_PATH)/$(1)/rustc-linker.sh rustc-linker.sh && \ + chmod +x rustc-linker.sh +endef +$(foreach cargo_package,$(cargo_packages),$(eval $(call int_cargo_preprocess_ext,$(cargo_package)))) + #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)))) @@ -297,3 +376,6 @@ $(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$ #create build targets $(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package)))) + +#create vendor targets for cargo packages +$(foreach cargo_package,$(cargo_packages),$(eval $(call int_vendor_crates,$(cargo_package)))) diff --git a/depends/packages/native_rust.mk b/depends/packages/native_rust.mk new file mode 100644 index 000000000000..b474a0971ae3 --- /dev/null +++ b/depends/packages/native_rust.mk @@ -0,0 +1,55 @@ +# Copyright (c) 2016-2025 The Zcash developers +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# To update the Rust compiler, change the version below and then run the script +# ./contrib/devtools/update-rust-hashes.py + +package:=native_rust +$(package)_version:=1.92.0 +$(package)_download_path:=https://static.rust-lang.org/dist +$(package)_patches:=fix-elf-interpreter.sh + +# Linux (ARMv8) +$(package)_file_name_aarch64_linux:=rust-$($(package)_version)-aarch64-unknown-linux-gnu.tar.gz +$(package)_sha256_hash_aarch64_linux:=c812028423c3d7dd7ba99f66101e9e1aa3f66eab44a1285f41c363825d49dca4 + +# Linux (x86_64) +$(package)_file_name_x86_64_linux:=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz +$(package)_sha256_hash_x86_64_linux:=6e5efd6c25953b2732d4e6b1842512536650c68cf72a8b99a0fc566012dd6ca5 + +# macOS (ARMv8) +$(package)_file_name_aarch64_darwin:=rust-$($(package)_version)-aarch64-apple-darwin.tar.gz +$(package)_sha256_hash_aarch64_darwin:=235a6cca2dd4881130a9ae61ad1149bbf28bba184dd4621700f0c98c97457716 + +# macOS (x86_64) +$(package)_file_name_x86_64_darwin:=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz +$(package)_sha256_hash_x86_64_darwin:=fc6868991e61e9262272effbb8956b23428430f5f4300c1b48eaae3969f8af2a + +$(package)_file_name=$($(package)_file_name_$(build_arch)_$(build_os)) +$(package)_sha256_hash=$($(package)_sha256_hash_$(build_arch)_$(build_os)) + +define $(package)_set_vars +$(package)_stage_opts=--disable-ldconfig +$(package)_stage_build_opts=--without=rust-docs-json-preview,rust-docs +endef + +define $(package)_fetch_cmds +$(call fetch_file,$(package),$($(package)_download_path),$($(package)_file_name),$($(package)_file_name),$($(package)_sha256_hash)) +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_dir)/$(host_prefix)/native/bin && \ + mkdir -p $($(package)_staging_dir)/$(host_prefix)/native/lib/rustlib && \ + cp cargo/bin/cargo $($(package)_staging_dir)/$(host_prefix)/native/bin/ && \ + cp rustc/bin/rustc $($(package)_staging_dir)/$(host_prefix)/native/bin/ && \ + cp rustc/bin/rustdoc $($(package)_staging_dir)/$(host_prefix)/native/bin/ && \ + cp -r rustc/lib/* $($(package)_staging_dir)/$(host_prefix)/native/lib/ && \ + cp -r rust-std-*/lib/rustlib/* $($(package)_staging_dir)/$(host_prefix)/native/lib/rustlib/ && \ + bash $($(package)_patch_dir)/fix-elf-interpreter.sh \ + $($(package)_staging_dir)/$(host_prefix)/native/lib \ + $($(package)_staging_dir)/$(host_prefix)/native/bin/cargo \ + $($(package)_staging_dir)/$(host_prefix)/native/bin/rustc \ + $($(package)_staging_dir)/$(host_prefix)/native/bin/rustdoc +endef diff --git a/depends/packages/rust_stdlib.mk b/depends/packages/rust_stdlib.mk new file mode 100644 index 000000000000..99395326ebad --- /dev/null +++ b/depends/packages/rust_stdlib.mk @@ -0,0 +1,70 @@ +# Copyright (c) 2016-2025 The Zcash developers +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# This version is synchronized from native_rust.mk by update-rust-hashes.py. + +package:=rust_stdlib +$(package)_version:=1.92.0 +$(package)_download_path:=https://static.rust-lang.org/dist +$(package)_dependencies:=native_rust + +# Rust support is deliberately confined to the hosts we actually validate +# (the Guix release set plus native development hosts). RUST=1 on any other +# host fails explicitly below rather than fetching a stdlib we never test. + +# Linux (ARMv8) +$(package)_targets += aarch64-unknown-linux-musl +$(package)_target_aarch64-unknown-linux-gnu:=aarch64-unknown-linux-musl +$(package)_sha256_hash_aarch64-unknown-linux-musl:=715fbcfd8712c723947a020d0371c8a1a21f7531f2b696aeaed50ac23ba675c9 + +# Linux (RISCV64GC) +$(package)_targets += riscv64gc-unknown-linux-musl +$(package)_target_riscv64-unknown-linux-gnu:=riscv64gc-unknown-linux-musl +$(package)_target_riscv64gc-unknown-linux-gnu:=riscv64gc-unknown-linux-musl +$(package)_sha256_hash_riscv64gc-unknown-linux-musl:=34f5722ff2a0940bcd7ff6603a7748d2b963de72f6f713579c39c74ead06a7a0 + +# Linux (x86_64) +$(package)_targets += x86_64-unknown-linux-musl +$(package)_target_x86_64-unknown-linux-gnu:=x86_64-unknown-linux-musl +$(package)_sha256_hash_x86_64-unknown-linux-musl:=8bfd9a42c8295949d556587201acdb35d2bfb8b7ce55223845f337aa5614f9a3 + +# macOS (ARMv8) +$(package)_targets += aarch64-apple-darwin +$(package)_target_aarch64-apple-darwin:=aarch64-apple-darwin +$(package)_target_arm64-apple-darwin:=aarch64-apple-darwin +$(package)_sha256_hash_aarch64-apple-darwin:=b1f55aac4bc982ea67b68b262b711263005e470d31cab5d09d534bc1866d455a + +# macOS (x86_64) +$(package)_targets += x86_64-apple-darwin +$(package)_target_x86_64-apple-darwin:=x86_64-apple-darwin +$(package)_sha256_hash_x86_64-apple-darwin:=1e5a8fee4e038ea2d35d82a680e2b9bf44ffccb3746aaf9dbdc56cb14152dcb8 + +# Windows (x86_64) +$(package)_targets += x86_64-pc-windows-gnu +$(package)_target_x86_64-w64-mingw32:=x86_64-pc-windows-gnu +$(package)_sha256_hash_x86_64-pc-windows-gnu:=6256f3497e3b14b6650511e84fdfb51fc632db1908ae5a173dffcdc96c80b7ce + +$(package)_target:=$(or \ + $($(package)_target_$(canonical_host)),\ + $($(package)_target_$(subst -pc-,-unknown-,$(canonical_host))),\ + $($(package)_target_$(subst -unknown-,-pc-,$(canonical_host))),\ + $($(package)_target_$(subst -linux-,-unknown-linux-,$(canonical_host))),\ + $(if $(findstring -apple-darwin,$(canonical_host)),$(host_arch)-apple-darwin)) + +ifeq ($($(package)_target),) +$(error Unsupported Rust standard library target: $(canonical_host)) +endif + +$(package)_file_name=rust-std-$($(package)_version)-$($(package)_target).tar.gz +$(package)_sha256_hash=$($(package)_sha256_hash_$($(package)_target)) + +define $(package)_fetch_cmds + $(call fetch_file,$(package),$($(package)_download_path),$($(package)_file_name),$($(package)_file_name),$($(package)_sha256_hash)) +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_dir)/$(host_prefix)/native/lib/rustlib && \ + cp -r rust-std-$($(package)_target)/lib/rustlib/$($(package)_target) $($(package)_staging_dir)/$(host_prefix)/native/lib/rustlib/ +endef diff --git a/depends/patches/native_rust/fix-elf-interpreter.sh b/depends/patches/native_rust/fix-elf-interpreter.sh new file mode 100755 index 000000000000..ccf05f8ecc05 --- /dev/null +++ b/depends/patches/native_rust/fix-elf-interpreter.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +export LC_ALL=C + +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +LIBDIR="$1" +shift + +if ! command -v patchelf >/dev/null 2>&1; then + # Inside a Guix environment the prebuilt binaries cannot run without + # having their interpreter patched, so a missing patchelf is fatal there. + case "$(command -v ls)" in + /gnu/store/*) + echo "ERROR: patchelf is required inside the Guix environment but was not found" >&2 + exit 1 + ;; + esac + echo "patchelf not found, skipping ELF fix" + exit 0 +fi + +# Get the interpreter from a known working binary (ls) +LS_PATH=$(command -v ls) +GUIX_INTERP=$(patchelf --print-interpreter "$LS_PATH" 2>/dev/null) + +if [ -z "$GUIX_INTERP" ]; then + echo "Could not detect interpreter, skipping" + exit 0 +fi + +echo "Detected interpreter: $GUIX_INTERP" + +# Find and copy runtime libraries the prebuilt binaries need into our lib +# directory so the $ORIGIN-based RPATH can resolve them. +for libname in libgcc_s.so.1 libz.so.1; do + LIB_SRC="" + + # Method 1: Use gcc to find it + if command -v gcc >/dev/null 2>&1; then + CANDIDATE=$(gcc -print-file-name="$libname" 2>/dev/null) + if [ -f "$CANDIDATE" ]; then + LIB_SRC="$CANDIDATE" + else + GCC_PATH=$(command -v gcc) + GCC_PREFIX=$(dirname "$(dirname "$GCC_PATH")") + if [ -f "$GCC_PREFIX/lib/$libname" ]; then + LIB_SRC="$GCC_PREFIX/lib/$libname" + fi + fi + fi + + # Method 2: Search LIBRARY_PATH + if [ -z "$LIB_SRC" ] && [ -n "$LIBRARY_PATH" ]; then + IFS=':' read -ra LIB_PATHS <<< "$LIBRARY_PATH" + for libpath in "${LIB_PATHS[@]}"; do + if [ -f "$libpath/$libname" ]; then + LIB_SRC="$libpath/$libname" + break + fi + done + fi + + if [ -n "$LIB_SRC" ]; then + # Resolve symlinks and copy the actual file + LIB_REAL=$(readlink -f "$LIB_SRC") + echo "Copying $libname from: $LIB_REAL" + cp "$LIB_REAL" "$LIBDIR/$libname" + else + echo "WARNING: Could not find $libname to copy" + fi +done + +# RPATH just needs $ORIGIN/../lib - everything is self-contained +GUIX_RPATH="\$ORIGIN/../lib" +echo "Using RPATH: $GUIX_RPATH" + +for binary in "$@"; do + if [ -f "$binary" ]; then + echo "Patching: $binary" + patchelf --set-interpreter "$GUIX_INTERP" "$binary" + patchelf --set-rpath "$GUIX_RPATH" "$binary" + fi +done + +if [ -n "$1" ]; then + echo "Verifying first binary:" + patchelf --print-interpreter "$1" + patchelf --print-rpath "$1" +fi From 104da7d3afe2cc53089f9423ddb2276a715384bd Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 19 Aug 2026 22:21:29 -0500 Subject: [PATCH 2/7] build(depends): build Dash Platform CXX bindings behind a PLATFORM_GUI knob PLATFORM_GUI=1 adds mbedtls, native_protobuf, tenderdash_sources and platform_cxx to the package set. platform_cxx builds libdash_platform_cxx.a and its installed headers from a pinned dashpay/platform commit (packages/rs-platform-cxx), offline via the per-package vendored crates. config.site.in exports enable_platform_gui and PLATFORM_CXX_{CFLAGS,LIBS} discovery for the configure flag that arrives with the first C++ consumer. --- depends/Makefile | 33 +++++++++++--- depends/README.md | 2 + depends/config.site.in | 11 +++++ depends/packages/mbedtls.mk | 27 ++++++++++++ depends/packages/native_protobuf.mk | 43 +++++++++++++++++++ depends/packages/packages.mk | 3 ++ depends/packages/platform_cxx.mk | 37 ++++++++++++++++ depends/packages/tenderdash_sources.mk | 36 ++++++++++++++++ .../patches/platform_cxx/cargo-config.toml | 30 +++++++++++++ depends/patches/platform_cxx/rustc-linker.sh | 6 +++ 10 files changed, 221 insertions(+), 7 deletions(-) create mode 100644 depends/packages/mbedtls.mk create mode 100644 depends/packages/native_protobuf.mk create mode 100644 depends/packages/platform_cxx.mk create mode 100644 depends/packages/tenderdash_sources.mk create mode 100644 depends/patches/platform_cxx/cargo-config.toml create mode 100644 depends/patches/platform_cxx/rustc-linker.sh diff --git a/depends/Makefile b/depends/Makefile index c8510f4cc010..bae0ec6932a4 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -44,6 +44,7 @@ NO_UPNP ?= NO_USDT ?= NO_NATPMP ?= MULTIPROCESS ?= +PLATFORM_GUI ?= LTO ?= NO_HARDEN ?= FALLBACK_DOWNLOAD_PATH ?= http://dash-depends-sources.s3-website-us-west-2.amazonaws.com @@ -175,6 +176,7 @@ natpmp_packages_$(NO_NATPMP) = $(natpmp_packages) zmq_packages_$(NO_ZMQ) = $(zmq_packages) multiprocess_packages_$(MULTIPROCESS) = $(multiprocess_packages) +platform_packages_$(PLATFORM_GUI) = $(platform_packages) usdt_packages_$(NO_USDT) = $(usdt_$(host_os)_packages) packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(boost_packages_) $(libevent_packages_) $(qt_packages_) $(wallet_packages_) $(upnp_packages_) $(natpmp_packages_) $(usdt_packages_) @@ -189,6 +191,14 @@ packages += $(multiprocess_packages) native_packages += $(multiprocess_native_packages) endif +ifeq ($(platform_packages_),) +packages += $(platform_packages) +native_packages += $(platform_native_packages) +rust_download_targets = download-rust-std +endif + +cargo_packages = $(filter platform_cxx,$(packages)) + all_packages = $(packages) $(native_packages) meta_depends = Makefile config.guess config.sub funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk @@ -202,9 +212,13 @@ $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) mkdir -p $(@D) echo copying packages: $^ echo to: $(@D) - cd $(@D); $(foreach package,$^, $(build_TAR) xf $($(package)_cached); ) + cd $(@D); $(foreach package,$^, $(build_TAR) --no-same-owner -xf $($(package)_cached); ) touch $@ +# Vendors crate dependencies for cargo-built packages +vendor-dep-crates: $(foreach package,$(cargo_packages),vendor-$(package)-crates) +.PHONY: vendor-dep-crates + # $PATH is not preserved between ./configure and make by convention. Its # modification and overriding at ./configure time is (as I understand it) # supposed to be captured by the AC_{PROG_{,OBJ}CXX,PATH_{PROG,TOOL}} macros, @@ -257,6 +271,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@no_usdt@|$(NO_USDT)|' \ -e 's|@no_natpmp@|$(NO_NATPMP)|' \ -e 's|@multiprocess@|$(MULTIPROCESS)|' \ + -e 's|@platform_gui@|$(PLATFORM_GUI)|' \ -e 's|@lto@|$(LTO)|' \ -e 's|@no_harden@|$(NO_HARDEN)|' \ -e 's|@debug@|$(DEBUG)|' \ @@ -296,18 +311,22 @@ clean: install: check-packages $(host_prefix)/share/config.site -download-one: check-sources $(all_sources) +download-one: check-sources $(all_sources) $(foreach package,$(cargo_packages),$($(package)_vendored_archive)) download-osx: - @$(MAKE) -s HOST=x86_64-apple-darwin download-one + @$(MAKE) -s PLATFORM_GUI=$(PLATFORM_GUI) HOST=x86_64-apple-darwin download-one download-linux: - @$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one + @$(MAKE) -s PLATFORM_GUI=$(PLATFORM_GUI) HOST=x86_64-unknown-linux-gnu download-one download-win: - @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one -download: download-osx download-linux download-win + @$(MAKE) -s PLATFORM_GUI=$(PLATFORM_GUI) HOST=x86_64-w64-mingw32 download-one +download-rust-std: + @mkdir -p $(SOURCES_PATH) + @mkdir -p $(SOURCES_PATH)/download-stamps + @$(foreach target,$(rust_stdlib_targets),$(call download_rust_std_target,$(target)) && ) true +download: download-osx download-linux download-win $(rust_download_targets) $(foreach package,$(all_packages),$(eval $(call ext_add_stages,$(package)))) -.PHONY: install cached clean clean-all download-one download-osx download-linux download-win download check-packages check-sources +.PHONY: install cached clean clean-all download-one download-osx download-linux download-win download download-rust-std check-packages check-sources .PHONY: FORCE $(V).SILENT: diff --git a/depends/README.md b/depends/README.md index f504627729f0..f4e5f744b5bc 100644 --- a/depends/README.md +++ b/depends/README.md @@ -92,6 +92,8 @@ The following can be set when running make: `make FOO=bar` build script logic) are searched for among the host system packages using `pkg-config`. It allows building with packages of other (newer) versions - `MULTIPROCESS`: build libmultiprocess (experimental, requires cmake) +- `PLATFORM_GUI`: Download/build/cache the Rust toolchain, target standard library and + the Dash Platform CXX bindings needed for `--enable-platform-gui` - `DEBUG`: Disable some optimizations and enable more runtime checking - `HOST_ID_SALT`: Optional salt to use when generating host package ids - `BUILD_ID_SALT`: Optional salt to use when generating build package ids diff --git a/depends/config.site.in b/depends/config.site.in index 398a09b74c63..ef4af20ff1cd 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -50,6 +50,17 @@ if test -z "$enable_multiprocess" && test -n "@multiprocess@"; then enable_multiprocess=yes fi +if test -z "$enable_platform_gui" && test -n "@platform_gui@"; then + enable_platform_gui=yes +fi + +if test -z "$PLATFORM_CXX_CFLAGS" && test -f "${depends_prefix}/include/dash/platform/ffi.h"; then + PLATFORM_CXX_CFLAGS="-I${depends_prefix}/include" +fi +if test -z "$PLATFORM_CXX_LIBS" && test -f "${depends_prefix}/lib/libdash_platform_cxx.a"; then + PLATFORM_CXX_LIBS="${depends_prefix}/lib/libdash_platform_cxx.a" +fi + if test -z "$with_miniupnpc" && test -n "@no_upnp@"; then with_miniupnpc=no fi diff --git a/depends/packages/mbedtls.mk b/depends/packages/mbedtls.mk new file mode 100644 index 000000000000..cea4466c167d --- /dev/null +++ b/depends/packages/mbedtls.mk @@ -0,0 +1,27 @@ +package=mbedtls +$(package)_version=3.6.3.1 +$(package)_download_path=https://github.com/Mbed-TLS/mbedtls/releases/download/v$($(package)_version)/ +$(package)_file_name=$(package)-$($(package)_version).tar.bz2 +$(package)_sha256_hash=243ed496d5f88a5b3791021be2800aac821b9a4cc16e7134aa413c58b4c20e0c + +define $(package)_set_vars +$(package)_config_opts := -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF +$(package)_config_opts += -DUSE_SHARED_MBEDTLS_LIBRARY=OFF -DUSE_STATIC_MBEDTLS_LIBRARY=ON +$(package)_config_opts += -DMBEDTLS_FATAL_WARNINGS=OFF -DGEN_FILES=OFF +endef + +define $(package)_config_cmds + $($(package)_cmake) -S . -B . +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf lib/cmake +endef diff --git a/depends/packages/native_protobuf.mk b/depends/packages/native_protobuf.mk new file mode 100644 index 000000000000..52c3745ee279 --- /dev/null +++ b/depends/packages/native_protobuf.mk @@ -0,0 +1,43 @@ +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +package=native_protobuf +$(package)_version=32.0 +$(package)_download_path=https://github.com/protocolbuffers/protobuf/releases/download/v$($(package)_version) + +# Linux (ARMv8) +$(package)_file_name_aarch64_linux=protoc-$($(package)_version)-linux-aarch_64.zip +$(package)_sha256_hash_aarch64_linux=56af3fc2e43a0230802e6fadb621d890ba506c5c17a1ae1070f685fe79ba12d0 + +# Linux (x86_64) +$(package)_file_name_x86_64_linux=protoc-$($(package)_version)-linux-x86_64.zip +$(package)_sha256_hash_x86_64_linux=7ca037bfe5e5cabd4255ccd21dd265f79eb82d3c010117994f5dc81d2140ee88 + +# macOS (ARMv8) +$(package)_file_name_aarch64_darwin=protoc-$($(package)_version)-osx-aarch_64.zip +$(package)_sha256_hash_aarch64_darwin=09a2c729cc821215cc0d4c564b761760961fe338c52f24b302fd7e18e7b675d1 + +# macOS (x86_64) +$(package)_file_name_x86_64_darwin=protoc-$($(package)_version)-osx-x86_64.zip +$(package)_sha256_hash_x86_64_darwin=63eeba15ddc12ab11b0a8bce81fb2d46cc69022c3e6ad21fecde90d52139bff6 + +$(package)_file_name=$($(package)_file_name_$(build_arch)_$(build_os)) +$(package)_sha256_hash=$($(package)_sha256_hash_$(build_arch)_$(build_os)) + +ifeq ($($(package)_file_name),) +$(error native_protobuf has no prebuilt protoc $($(package)_version) for $(build_arch)-$(build_os)) +endif + +define $(package)_extract_cmds + echo "$($(package)_sha256_hash) $($(package)_source)" > .$($(package)_file_name).hash && \ + $(build_SHA256SUM) -c .$($(package)_file_name).hash && \ + python3 -m zipfile -e $($(package)_source) . +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \ + cp bin/protoc $($(package)_staging_prefix_dir)/bin/ && \ + chmod 0755 $($(package)_staging_prefix_dir)/bin/protoc && \ + cp -R include/google $($(package)_staging_prefix_dir)/include/ +endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 7e0bb2633219..38f0d38a8373 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -26,4 +26,7 @@ natpmp_packages=libnatpmp multiprocess_packages = libmultiprocess capnp multiprocess_native_packages = native_libmultiprocess native_capnp +platform_packages = mbedtls rust_stdlib tenderdash_sources platform_cxx +platform_native_packages = native_protobuf native_rust + usdt_linux_packages=systemtap diff --git a/depends/packages/platform_cxx.mk b/depends/packages/platform_cxx.mk new file mode 100644 index 000000000000..d8f200c0a2e0 --- /dev/null +++ b/depends/packages/platform_cxx.mk @@ -0,0 +1,37 @@ +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +package=platform_cxx +$(package)_version=df4fdb68559ef57d50624b7f0841594aef8647e5 +$(package)_download_path=https://github.com/dashpay/platform/archive +$(package)_download_file=$($(package)_version).tar.gz +$(package)_file_name=platform-$($(package)_version).tar.gz +$(package)_sha256_hash=935b64a4f3acf48840706d573acc4c43ce4ac44272265ea96af45e35c47d829a +$(package)_build_subdir=packages/rs-platform-cxx/standalone +$(package)_dependencies=native_rust rust_stdlib native_protobuf tenderdash_sources +$(package)_patches=cargo-config.toml rustc-linker.sh +$(package)_vendored_file_name=platform-cxx-$($(package)_version)-vendored.tar.gz +$(package)_cargo_manifest=packages/rs-platform-cxx/standalone/Cargo.toml +$(package)_cargo_lock_path=packages/rs-platform-cxx/standalone/Cargo.lock + +define $(package)_preprocess_cmds + true +endef + +define $(package)_build_cmds + mkdir -p target && \ + cp $(host_prefix)/tenderdash-sources/tenderdash-*.zip target/ && \ + CARGO_BUILD_TARGET=$(rust_stdlib_target) \ + CARGO_TARGET_DIR=$($(package)_build_dir)/target \ + PROTOC=$(build_prefix)/bin/protoc \ + PROTOC_INCLUDE=$(build_prefix)/include \ + $($(package)_cargo) build --locked --offline --release --target $(rust_stdlib_target) +endef + +define $(package)_stage_cmds + CARGO_BUILD_TARGET=$(rust_stdlib_target) \ + CARGO_PROFILE=release \ + CARGO_TARGET_DIR=$($(package)_build_dir)/target \ + bash ../install.sh $($(package)_staging_prefix_dir) +endef diff --git a/depends/packages/tenderdash_sources.mk b/depends/packages/tenderdash_sources.mk new file mode 100644 index 000000000000..057abbf6048b --- /dev/null +++ b/depends/packages/tenderdash_sources.mk @@ -0,0 +1,36 @@ +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Source-only package: the tenderdash source archive that tenderdash-proto's +# build.rs (rs-tenderdash-abci, a dependency of the Platform CXX package) +# compiles its protobuf definitions from. +# Online builds download this zip themselves at cargo build time; depends +# builds must not touch the network, so the sha256-pinned archive is staged +# verbatim into the prefix and platform_cxx copies it into the Cargo target +# directory, where build.rs treats it as a pre-populated download +# cache (cache file name: tenderdash-$(TENDERDASH_COMMITISH).zip). +# +# The version must match TENDERDASH_COMMITISH default of the pinned +# tenderdash-proto crate (rs-tenderdash-abci proto/build.rs). + +package=tenderdash_sources +$(package)_version=1.5.1 +$(package)_download_path=https://github.com/dashpay/tenderdash/archive +$(package)_download_file=v$($(package)_version).zip +$(package)_file_name=tenderdash-v$($(package)_version).zip +$(package)_sha256_hash=7a8844899a4635a6c2f55057e0c0f7cec357907d0cfeb2900e035760cf187f9a + +# Keep the archive as-is: the consumer (tenderdash-proto build.rs) unzips it +# from its own cache directory, so extraction here would only be discarded. +define $(package)_extract_cmds + mkdir -p $($(package)_extract_dir) && \ + echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + cp $($(package)_source) $($(package)_file_name) +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_dir)/$(host_prefix)/tenderdash-sources && \ + cp $($(package)_file_name) $($(package)_staging_dir)/$(host_prefix)/tenderdash-sources/ +endef diff --git a/depends/patches/platform_cxx/cargo-config.toml b/depends/patches/platform_cxx/cargo-config.toml new file mode 100644 index 000000000000..1f46305c8c3f --- /dev/null +++ b/depends/patches/platform_cxx/cargo-config.toml @@ -0,0 +1,30 @@ +[source.crates-io] +replace-with = "vendored-sources" + +[source.vendored-sources] +directory = "vendored" + +[source."git+https://github.com/dashpay/agora-blsful?rev=0c34a7a488a0bd1c9a9a2196e793b303ad35c900"] +git = "https://github.com/dashpay/agora-blsful" +rev = "0c34a7a488a0bd1c9a9a2196e793b303ad35c900" +replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/grovedb?rev=a2791bbdca756d6a6113024aec48f09f7a33faa9"] +git = "https://github.com/dashpay/grovedb" +rev = "a2791bbdca756d6a6113024aec48f09f7a33faa9" +replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/rs-tenderdash-abci?tag=v1.5.1"] +git = "https://github.com/dashpay/rs-tenderdash-abci" +tag = "v1.5.1" +replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/rust-dashcore?rev=173ffac0fdc0c73dda0626cf385bbcfcf2437aeb"] +git = "https://github.com/dashpay/rust-dashcore" +rev = "173ffac0fdc0c73dda0626cf385bbcfcf2437aeb" +replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/vsss-rs?branch=main"] +git = "https://github.com/dashpay/vsss-rs" +branch = "main" +replace-with = "vendored-sources" diff --git a/depends/patches/platform_cxx/rustc-linker.sh b/depends/patches/platform_cxx/rustc-linker.sh new file mode 100644 index 000000000000..a2f99d543930 --- /dev/null +++ b/depends/patches/platform_cxx/rustc-linker.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# rustc's `-C linker=` takes a single executable, but the configured +# compiler is a full command line (target/sysroot flags; under Guix an +# `env -u ...` prefix). CC carries that command in cargo's environment; +# word-splitting it here preserves every part of it. +exec $CC "$@" From fab4d10bb905c7bbf2735735734ebe059baadb21 Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 19 Aug 2026 23:49:44 -0500 Subject: [PATCH 3/7] ci: exercise the PLATFORM_GUI depends knob in a linux64_platform_gui lane The new lane builds depends with PLATFORM_GUI=1 (producing and hash-verifying the Platform CXX archive offline from vendored crates), then builds dash-qt against that prefix and runs the unit tests. The cache-sources producer generates and caches the platform-cxx vendored-crates archive, handing it to same-run consumers as an artifact on cache miss. The --enable-platform-gui configure flag is added to this lane's BITCOIN_CONFIG by the Platform client library PR; until then the lane proves the depends knob and prefix link-compatibility. build.yml runs PR validation from the base branch (pull_request_target), so the lane first runs on push CI for this branch and takes effect for PRs after merge. --- .github/workflows/build-depends.yml | 27 ++++++++++++++ .github/workflows/build.yml | 37 +++++++++++++++++++ .github/workflows/cache-depends-sources.yml | 40 +++++++++++++++++++-- ci/dash/matrix.sh | 2 ++ ci/test/00_setup_env_native_platform_gui.sh | 25 +++++++++++++ 5 files changed, 129 insertions(+), 2 deletions(-) create mode 100755 ci/test/00_setup_env_native_platform_gui.sh diff --git a/.github/workflows/build-depends.yml b/.github/workflows/build-depends.yml index e79c5fa4248e..4d941b9fc666 100644 --- a/.github/workflows/build-depends.yml +++ b/.github/workflows/build-depends.yml @@ -15,6 +15,11 @@ on: description: "Short hash of the CI base image manifest for cache busting" required: true type: string + rust-vendor-artifact: + description: "Artifact holding freshly generated Rust vendor archives" + required: false + type: string + default: "" runs-on: description: "Runner label to use (e.g., ubuntu-24.04 or ubuntu-24.04-arm)" required: true @@ -144,6 +149,28 @@ jobs: key: depends-sources-${{ hashFiles('depends/packages/*') }} restore-keys: depends-sources- + - name: Restore Rust vendor sources + id: rust-vendor-cache + if: inputs.build-target == 'linux64_platform_gui' + uses: actions/cache/restore@v5 + with: + path: depends/sources/platform-cxx-*-vendored.tar.gz + key: depends-rust-vendor-sources-${{ hashFiles('depends/Makefile', 'depends/funcs.mk', 'depends/packages/native_rust.mk', 'depends/packages/platform_cxx.mk', 'depends/patches/platform_cxx/cargo-config.toml') }} + + - name: Download Rust vendor sources + if: inputs.build-target == 'linux64_platform_gui' && steps.rust-vendor-cache.outputs.cache-hit != 'true' && inputs.rust-vendor-artifact != '' + uses: actions/download-artifact@v8 + with: + name: ${{ inputs.rust-vendor-artifact }} + path: depends/sources + + - name: Check Rust vendor sources are present + if: inputs.build-target == 'linux64_platform_gui' && steps.rust-vendor-cache.outputs.cache-hit != 'true' && inputs.rust-vendor-artifact == '' + run: | + echo "::error::Rust vendor source cache missed and no same-run artifact was provided" + exit 1 + shell: bash + - name: Restore SDKs cache id: sdk-cache uses: actions/cache/restore@v5 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ce8191dc99ea..74de8337be81 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -165,6 +165,18 @@ jobs: base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + depends-linux64_platform_gui: + name: x86_64-pc-linux-gnu_platform_gui + uses: ./.github/workflows/build-depends.yml + needs: [check-skip, container, cache-sources] + if: ${{ vars.SKIP_LINUX64_PLATFORM_GUI == '' }} + with: + build-target: linux64_platform_gui + container-path: ${{ needs.container.outputs.path }} + base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }} + rust-vendor-artifact: ${{ needs.cache-sources.outputs.rust-vendor-artifact }} + runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + depends-mac: name: x86_64-apple-darwin uses: ./.github/workflows/build-depends.yml @@ -277,6 +289,20 @@ jobs: depends-artifact: ${{ needs.depends-linux64_nowallet.outputs.built-artifact }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + src-linux64_platform_gui: + name: linux64_platform_gui-build + uses: ./.github/workflows/build-src.yml + needs: [check-skip, container, depends-linux64_platform_gui] + if: ${{ vars.SKIP_LINUX64_PLATFORM_GUI == '' }} + with: + build-target: linux64_platform_gui + container-path: ${{ needs.container.outputs.path }} + depends-key: ${{ needs.depends-linux64_platform_gui.outputs.key }} + depends-host: ${{ needs.depends-linux64_platform_gui.outputs.host }} + depends-dep-opts: ${{ needs.depends-linux64_platform_gui.outputs.dep-opts }} + depends-artifact: ${{ needs.depends-linux64_platform_gui.outputs.built-artifact }} + runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + src-linux64_sqlite: name: linux64_sqlite-build uses: ./.github/workflows/build-src.yml @@ -372,6 +398,17 @@ jobs: container-path: ${{ needs.container-slim.outputs.path }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + test-linux64_platform_gui: + name: linux64_platform_gui-test + uses: ./.github/workflows/test-src.yml + needs: [check-skip, container-slim, src-linux64_platform_gui, lint] + if: ${{ vars.SKIP_LINUX64_PLATFORM_GUI == '' }} + with: + bundle-key: ${{ needs.src-linux64_platform_gui.outputs.key }} + build-target: linux64_platform_gui + container-path: ${{ needs.container-slim.outputs.path }} + runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + test-linux64_sqlite: name: linux64_sqlite-test uses: ./.github/workflows/test-src.yml diff --git a/.github/workflows/cache-depends-sources.yml b/.github/workflows/cache-depends-sources.yml index 122851d8cd72..5e163b94c776 100644 --- a/.github/workflows/cache-depends-sources.yml +++ b/.github/workflows/cache-depends-sources.yml @@ -8,6 +8,10 @@ on: required: false type: string default: ubuntu-24.04-arm + outputs: + rust-vendor-artifact: + description: "Artifact holding freshly generated Rust vendor archives" + value: ${{ jobs.cache-sources.outputs.rust-vendor-artifact }} schedule: # Run daily at 6 AM UTC on the default branch to keep cache warm - cron: '0 6 * * *' @@ -18,6 +22,8 @@ jobs: # Intentionally keep scheduled cache warming on GitHub-hosted ARM runners. # Blacksmith caches are expected to persist long enough without a warmup cron. runs-on: ${{ inputs.runs-on || 'ubuntu-24.04-arm' }} + outputs: + rust-vendor-artifact: ${{ steps.vendor-artifact.outputs.name }} steps: - name: Checkout code uses: actions/checkout@v6 @@ -35,6 +41,36 @@ jobs: restore-keys: depends-sources- lookup-only: true + - name: Cache Rust vendor sources + id: rust-vendor-cache + uses: actions/cache@v5 + with: + path: depends/sources/platform-cxx-*-vendored.tar.gz + key: depends-rust-vendor-sources-${{ hashFiles('depends/Makefile', 'depends/funcs.mk', 'depends/packages/native_rust.mk', 'depends/packages/platform_cxx.mk', 'depends/patches/platform_cxx/cargo-config.toml') }} + - name: Download sources - if: steps.cache-check.outputs.cache-hit != 'true' - run: make -C depends download + if: | + steps.cache-check.outputs.cache-hit != 'true' || + steps.rust-vendor-cache.outputs.cache-hit != 'true' + run: | + make -C depends PLATFORM_GUI=1 download + make -C depends PLATFORM_GUI=1 vendor-platform_cxx-crates + # The cache producer normally runs on ARM, while the platform_gui + # consumer runs on x86_64. Native Rust is selected from the build + # architecture, so fetch the x86_64 compiler archive explicitly too. + make -C depends BUILD=x86_64-pc-linux-gnu PLATFORM_GUI=1 download-one + + - name: Select Rust vendor artifact + id: vendor-artifact + if: github.event_name != 'schedule' && steps.rust-vendor-cache.outputs.cache-hit != 'true' + run: echo "name=depends-rust-vendor-sources-${{ github.run_id }}" >> "$GITHUB_OUTPUT" + + - name: Upload Rust vendor sources + if: steps.vendor-artifact.outputs.name != '' + uses: actions/upload-artifact@v6 + with: + name: ${{ steps.vendor-artifact.outputs.name }} + path: depends/sources/platform-cxx-*-vendored.tar.gz + compression-level: 0 + retention-days: 1 + overwrite: true diff --git a/ci/dash/matrix.sh b/ci/dash/matrix.sh index e54e279422c4..e76379120b7c 100755 --- a/ci/dash/matrix.sh +++ b/ci/dash/matrix.sh @@ -28,6 +28,8 @@ elif [ "$BUILD_TARGET" = "linux64_multiprocess" ]; then source ./ci/test/00_setup_env_native_multiprocess.sh elif [ "$BUILD_TARGET" = "linux64_nowallet" ]; then source ./ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh +elif [ "$BUILD_TARGET" = "linux64_platform_gui" ]; then + source ./ci/test/00_setup_env_native_platform_gui.sh elif [ "$BUILD_TARGET" = "linux64_sqlite" ]; then source ./ci/test/00_setup_env_native_sqlite.sh elif [ "$BUILD_TARGET" = "linux64_tsan" ]; then diff --git a/ci/test/00_setup_env_native_platform_gui.sh b/ci/test/00_setup_env_native_platform_gui.sh new file mode 100755 index 000000000000..76af827df3f1 --- /dev/null +++ b/ci/test/00_setup_env_native_platform_gui.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2026 The Dash Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +export LC_ALL=C.UTF-8 + +# Builds depends with PLATFORM_GUI=1 so mbedtls and the Platform-owned CXX +# binding archive (libdash_platform_cxx.a, built offline from vendored crates) +# are produced, hash-verified and installed into the depends prefix, then +# builds dash-qt against that prefix. The --enable-platform-gui configure flag +# and the platform_* unit-test suites arrive with the Platform client library +# and are added to BITCOIN_CONFIG there; until then this lane proves the +# depends knob end to end and that the enriched prefix stays link-compatible. +# Functional tests are skipped: there is no dashd-only surface to drive. +export CONTAINER_NAME=ci_native_platform_gui +export HOST=x86_64-pc-linux-gnu +export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev" +export DEP_OPTS="PLATFORM_GUI=1" +export RUN_UNIT_TESTS="true" +export RUN_UNIT_TESTS_SEQUENTIAL="false" +export RUN_FUNCTIONAL_TESTS="false" +export GOAL="install" +export BITCOIN_CONFIG="--with-gui=qt5 --enable-zmq --with-libs=no --enable-reduce-exports LDFLAGS=-static-libstdc++" From 82c62a050e0ba941b91d63256d14140f6da7b5fc Mon Sep 17 00:00:00 2001 From: pasta Date: Mon, 31 Aug 2026 11:51:24 +0200 Subject: [PATCH 4/7] build(depends): redownload rust-std archives that fail hash verification The all-target rust-std downloader wrote directly to the final source-cache path and treated any existing file as complete, so a partial file left behind by an interrupted download made every subsequent 'make PLATFORM_GUI=1 download' fail on the same archive until it was removed by hand. Verify an existing archive against the pinned hash and re-fetch it when it does not match, downloading to a temp path and only moving a verified archive into place, matching fetch_file_inner. --- depends/funcs.mk | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index a0caa3665386..2d334ac243fa 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -320,12 +320,17 @@ $($(1)_preprocessed): $$($(1)_vendored_archive) endif endef +# A cached archive is trusted only if it matches the pinned hash; anything +# else (including a partial file from an interrupted download) is re-fetched. +# Like fetch_file_inner, download to a temp path and only move a verified +# archive into the source cache so a bad download can never wedge it. define download_rust_std_target -([ -f "$(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" ] && \ - echo "Already have rust-std-$(rust_stdlib_version)-$(1).tar.gz" || \ +((echo "$(rust_stdlib_sha256_hash_$(1)) $(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" | $(build_SHA256SUM) -c - >/dev/null 2>&1 && \ + echo "Already have rust-std-$(rust_stdlib_version)-$(1).tar.gz") || \ (echo "Downloading rust-std-$(rust_stdlib_version)-$(1).tar.gz..." && \ - $(build_DOWNLOAD) "$(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" "$(rust_stdlib_download_path)/rust-std-$(rust_stdlib_version)-$(1).tar.gz")) && \ -echo "$(rust_stdlib_sha256_hash_$(1)) $(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" | $(build_SHA256SUM) -c - && \ + $(build_DOWNLOAD) "$(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz.temp" "$(rust_stdlib_download_path)/rust-std-$(rust_stdlib_version)-$(1).tar.gz" && \ + echo "$(rust_stdlib_sha256_hash_$(1)) $(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz.temp" | $(build_SHA256SUM) -c - && \ + mv "$(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz.temp" "$(SOURCES_PATH)/rust-std-$(rust_stdlib_version)-$(1).tar.gz")) && \ echo "$(rust_stdlib_sha256_hash_$(1)) rust-std-$(rust_stdlib_version)-$(1).tar.gz" > "$(SOURCES_PATH)/download-stamps/.stamp_fetched-rust_stdlib-$(rust_stdlib_version)-$(rust_stdlib_sha256_hash_$(1)).hash" endef From 978a0d2e76009adb5a43b01f490042bb25169dba Mon Sep 17 00:00:00 2001 From: pasta Date: Mon, 31 Aug 2026 11:51:24 +0200 Subject: [PATCH 5/7] build(depends): fail native_rust staging in Guix when a runtime library is missing Inside a Guix environment there are no default loader search paths, so a toolchain staged without libgcc_s/libz next to it is nonfunctional and would be cached in that state. Treat a missing required runtime library as a staging failure there, consistent with the existing fatal patchelf check; outside Guix it remains a warning since the system loader can still resolve the libraries. --- .../native_rust/fix-elf-interpreter.sh | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/depends/patches/native_rust/fix-elf-interpreter.sh b/depends/patches/native_rust/fix-elf-interpreter.sh index ccf05f8ecc05..805f9ac06110 100755 --- a/depends/patches/native_rust/fix-elf-interpreter.sh +++ b/depends/patches/native_rust/fix-elf-interpreter.sh @@ -8,15 +8,20 @@ export LC_ALL=C LIBDIR="$1" shift +in_guix_env() { + case "$(command -v ls)" in + /gnu/store/*) return 0 ;; + esac + return 1 +} + if ! command -v patchelf >/dev/null 2>&1; then # Inside a Guix environment the prebuilt binaries cannot run without # having their interpreter patched, so a missing patchelf is fatal there. - case "$(command -v ls)" in - /gnu/store/*) - echo "ERROR: patchelf is required inside the Guix environment but was not found" >&2 - exit 1 - ;; - esac + if in_guix_env; then + echo "ERROR: patchelf is required inside the Guix environment but was not found" >&2 + exit 1 + fi echo "patchelf not found, skipping ELF fix" exit 0 fi @@ -68,6 +73,14 @@ for libname in libgcc_s.so.1 libz.so.1; do echo "Copying $libname from: $LIB_REAL" cp "$LIB_REAL" "$LIBDIR/$libname" else + # Outside Guix the loader can still resolve these from the default + # system search paths; inside Guix there are none, so a toolchain + # missing one of these libraries is nonfunctional and must not be + # staged and cached. + if in_guix_env; then + echo "ERROR: $libname is required inside the Guix environment but was not found" >&2 + exit 1 + fi echo "WARNING: Could not find $libname to copy" fi done From 092453f58c887c3891b0d5bb8b9d0103b5760ed6 Mon Sep 17 00:00:00 2001 From: pasta Date: Tue, 8 Sep 2026 14:56:59 -0500 Subject: [PATCH 6/7] build(depends): make rustc-linker.sh executable The linker wrapper carries a shebang, so the lint-files check requires the executable bit; cargo invokes it through the RUSTFLAGS -C linker= path either way. --- depends/patches/platform_cxx/rustc-linker.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 depends/patches/platform_cxx/rustc-linker.sh diff --git a/depends/patches/platform_cxx/rustc-linker.sh b/depends/patches/platform_cxx/rustc-linker.sh old mode 100644 new mode 100755 From bece6652be29646f608e2763eeeee1a4a20e5746 Mon Sep 17 00:00:00 2001 From: pasta Date: Tue, 8 Sep 2026 14:39:23 -0500 Subject: [PATCH 7/7] build(depends): pin platform_cxx to the SDK-backed dash-platform-cxx crate dashpay/platform#4633 rebuilds the Platform CXX bindings as a thin bridge over dash-sdk: the SDK owns DAPI transport, retries and proof verification, and Core supplies endpoints, quorum keys, its ChainLock height and wallet signatures. The crate is an ordinary workspace member now, so the package vendors from the workspace root (the lockfile made vendorable by dashpay/platform#4631), builds with -p dash-platform-cxx, and installs the header tree the crate's build.rs stages plus the static archive; the nested standalone manifest and install.sh are gone with the old design. mbedtls leaves depends: the SDK carries its own TLS stack (rustls with the system trust store), so Core no longer links a TLS library for Platform. The vendoring config gains the workspace's git sources. Validated on aarch64-apple-darwin: make -C depends PLATFORM_GUI=1 platform_cxx vendors 840 crates (150 MB archive) and builds the crate offline in 3 minutes; the staged prefix carries include/dash/platform/{ffi.h,signer.h}, include/rust/cxx.h and lib/libdash_platform_cxx.a. The knob-off package set is unchanged. --- ci/test/00_setup_env_native_platform_gui.sh | 17 +++--- depends/packages/mbedtls.mk | 27 ---------- depends/packages/packages.mk | 2 +- depends/packages/platform_cxx.mk | 21 ++++---- .../patches/platform_cxx/cargo-config.toml | 52 ++++++++++++++++--- 5 files changed, 67 insertions(+), 52 deletions(-) delete mode 100644 depends/packages/mbedtls.mk diff --git a/ci/test/00_setup_env_native_platform_gui.sh b/ci/test/00_setup_env_native_platform_gui.sh index 76af827df3f1..13fb49be63bc 100755 --- a/ci/test/00_setup_env_native_platform_gui.sh +++ b/ci/test/00_setup_env_native_platform_gui.sh @@ -6,14 +6,15 @@ export LC_ALL=C.UTF-8 -# Builds depends with PLATFORM_GUI=1 so mbedtls and the Platform-owned CXX -# binding archive (libdash_platform_cxx.a, built offline from vendored crates) -# are produced, hash-verified and installed into the depends prefix, then -# builds dash-qt against that prefix. The --enable-platform-gui configure flag -# and the platform_* unit-test suites arrive with the Platform client library -# and are added to BITCOIN_CONFIG there; until then this lane proves the -# depends knob end to end and that the enriched prefix stays link-compatible. -# Functional tests are skipped: there is no dashd-only surface to drive. +# Builds depends with PLATFORM_GUI=1 so the Platform-owned CXX binding +# archive (libdash_platform_cxx.a, dash-sdk built offline from vendored +# crates) is produced, hash-verified and installed into the depends prefix, +# then builds dash-qt against that prefix. The --enable-platform-gui configure +# flag and the platform_* unit-test suites arrive with the Platform client +# library and are added to BITCOIN_CONFIG there; until then this lane proves +# the depends knob end to end and that the enriched prefix stays +# link-compatible. Functional tests are skipped: there is no dashd-only +# surface to drive. export CONTAINER_NAME=ci_native_platform_gui export HOST=x86_64-pc-linux-gnu export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev" diff --git a/depends/packages/mbedtls.mk b/depends/packages/mbedtls.mk deleted file mode 100644 index cea4466c167d..000000000000 --- a/depends/packages/mbedtls.mk +++ /dev/null @@ -1,27 +0,0 @@ -package=mbedtls -$(package)_version=3.6.3.1 -$(package)_download_path=https://github.com/Mbed-TLS/mbedtls/releases/download/v$($(package)_version)/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=243ed496d5f88a5b3791021be2800aac821b9a4cc16e7134aa413c58b4c20e0c - -define $(package)_set_vars -$(package)_config_opts := -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF -$(package)_config_opts += -DUSE_SHARED_MBEDTLS_LIBRARY=OFF -DUSE_STATIC_MBEDTLS_LIBRARY=ON -$(package)_config_opts += -DMBEDTLS_FATAL_WARNINGS=OFF -DGEN_FILES=OFF -endef - -define $(package)_config_cmds - $($(package)_cmake) -S . -B . -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm -rf lib/cmake -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 38f0d38a8373..a49caa9c755e 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -26,7 +26,7 @@ natpmp_packages=libnatpmp multiprocess_packages = libmultiprocess capnp multiprocess_native_packages = native_libmultiprocess native_capnp -platform_packages = mbedtls rust_stdlib tenderdash_sources platform_cxx +platform_packages = rust_stdlib tenderdash_sources platform_cxx platform_native_packages = native_protobuf native_rust usdt_linux_packages=systemtap diff --git a/depends/packages/platform_cxx.mk b/depends/packages/platform_cxx.mk index d8f200c0a2e0..e1f5505bf2ae 100644 --- a/depends/packages/platform_cxx.mk +++ b/depends/packages/platform_cxx.mk @@ -3,17 +3,16 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. package=platform_cxx -$(package)_version=df4fdb68559ef57d50624b7f0841594aef8647e5 +$(package)_version=b283a5f71644b592f86cd6a1ddf16834ac0edd43 $(package)_download_path=https://github.com/dashpay/platform/archive $(package)_download_file=$($(package)_version).tar.gz $(package)_file_name=platform-$($(package)_version).tar.gz -$(package)_sha256_hash=935b64a4f3acf48840706d573acc4c43ce4ac44272265ea96af45e35c47d829a -$(package)_build_subdir=packages/rs-platform-cxx/standalone +$(package)_sha256_hash=86fe5a3f8cfa96e0d92509b6987ac9c8ba99efdc70ba37929c4fb68f7c5250b8 $(package)_dependencies=native_rust rust_stdlib native_protobuf tenderdash_sources $(package)_patches=cargo-config.toml rustc-linker.sh $(package)_vendored_file_name=platform-cxx-$($(package)_version)-vendored.tar.gz -$(package)_cargo_manifest=packages/rs-platform-cxx/standalone/Cargo.toml -$(package)_cargo_lock_path=packages/rs-platform-cxx/standalone/Cargo.lock +$(package)_cargo_manifest=Cargo.toml +$(package)_cargo_lock_path=Cargo.lock define $(package)_preprocess_cmds true @@ -26,12 +25,14 @@ define $(package)_build_cmds CARGO_TARGET_DIR=$($(package)_build_dir)/target \ PROTOC=$(build_prefix)/bin/protoc \ PROTOC_INCLUDE=$(build_prefix)/include \ - $($(package)_cargo) build --locked --offline --release --target $(rust_stdlib_target) + $($(package)_cargo) build --locked --offline --release --target $(rust_stdlib_target) -p dash-platform-cxx endef +# The crate's build.rs stages the generated bridge header, the cxx runtime +# header and signer.h under target//release/include; that tree plus +# the static archive is the whole installed interface. define $(package)_stage_cmds - CARGO_BUILD_TARGET=$(rust_stdlib_target) \ - CARGO_PROFILE=release \ - CARGO_TARGET_DIR=$($(package)_build_dir)/target \ - bash ../install.sh $($(package)_staging_prefix_dir) + mkdir -p $($(package)_staging_prefix_dir)/include $($(package)_staging_prefix_dir)/lib && \ + cp -R target/$(rust_stdlib_target)/release/include/. $($(package)_staging_prefix_dir)/include/ && \ + cp target/$(rust_stdlib_target)/release/libdash_platform_cxx.a $($(package)_staging_prefix_dir)/lib/ endef diff --git a/depends/patches/platform_cxx/cargo-config.toml b/depends/patches/platform_cxx/cargo-config.toml index 1f46305c8c3f..aa2657e50c6b 100644 --- a/depends/patches/platform_cxx/cargo-config.toml +++ b/depends/patches/platform_cxx/cargo-config.toml @@ -1,17 +1,39 @@ [source.crates-io] replace-with = "vendored-sources" -[source.vendored-sources] -directory = "vendored" +[source."git+https://github.com/QuantumExplorer/rust-rocksdb.git?rev=52772eea7bcd214d1d07d80aa538b1d24e5015b7"] +git = "https://github.com/QuantumExplorer/rust-rocksdb.git" +rev = "52772eea7bcd214d1d07d80aa538b1d24e5015b7" +replace-with = "vendored-sources" [source."git+https://github.com/dashpay/agora-blsful?rev=0c34a7a488a0bd1c9a9a2196e793b303ad35c900"] git = "https://github.com/dashpay/agora-blsful" rev = "0c34a7a488a0bd1c9a9a2196e793b303ad35c900" replace-with = "vendored-sources" -[source."git+https://github.com/dashpay/grovedb?rev=a2791bbdca756d6a6113024aec48f09f7a33faa9"] +[source."git+https://github.com/dashpay/bls-signatures?rev=0842b17583888e8f46c252a4ee84cdfd58e0546f"] +git = "https://github.com/dashpay/bls-signatures" +rev = "0842b17583888e8f46c252a4ee84cdfd58e0546f" +replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/grovedb?rev=6fc7e1e82de27a56c3428c0d5dd15b5f6a0ea23e"] git = "https://github.com/dashpay/grovedb" -rev = "a2791bbdca756d6a6113024aec48f09f7a33faa9" +rev = "6fc7e1e82de27a56c3428c0d5dd15b5f6a0ea23e" +replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/jsonschema-rs?branch=configure_regexp"] +git = "https://github.com/dashpay/jsonschema-rs" +branch = "configure_regexp" +replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/orchard.git?tag=dashified-0.14.1"] +git = "https://github.com/dashpay/orchard.git" +tag = "dashified-0.14.1" +replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/rs-bip37-bloom-filter?branch=develop"] +git = "https://github.com/dashpay/rs-bip37-bloom-filter" +branch = "develop" replace-with = "vendored-sources" [source."git+https://github.com/dashpay/rs-tenderdash-abci?tag=v1.5.1"] @@ -19,12 +41,30 @@ git = "https://github.com/dashpay/rs-tenderdash-abci" tag = "v1.5.1" replace-with = "vendored-sources" -[source."git+https://github.com/dashpay/rust-dashcore?rev=173ffac0fdc0c73dda0626cf385bbcfcf2437aeb"] +[source."git+https://github.com/dashpay/rust-dashcore?rev=93260bf39bac5d9d09e89bfb45e9ea3ff7fdcbcd"] git = "https://github.com/dashpay/rust-dashcore" -rev = "173ffac0fdc0c73dda0626cf385bbcfcf2437aeb" +rev = "93260bf39bac5d9d09e89bfb45e9ea3ff7fdcbcd" +replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/serde-wasm-bindgen?branch=fix/uint8array-to-bytes"] +git = "https://github.com/dashpay/serde-wasm-bindgen" +branch = "fix/uint8array-to-bytes" replace-with = "vendored-sources" [source."git+https://github.com/dashpay/vsss-rs?branch=main"] git = "https://github.com/dashpay/vsss-rs" branch = "main" replace-with = "vendored-sources" + +[source."git+https://github.com/dashpay/zcash_note_encryption?rev=9f7e93d"] +git = "https://github.com/dashpay/zcash_note_encryption" +rev = "9f7e93d" +replace-with = "vendored-sources" + +[source."git+https://github.com/gvz/zmq.rs?rev=b0787de310befaedd1f762e3b9bc711612d8137f"] +git = "https://github.com/gvz/zmq.rs" +rev = "b0787de310befaedd1f762e3b9bc711612d8137f" +replace-with = "vendored-sources" + +[source.vendored-sources] +directory = "vendored"