diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock index f235ffe1..a694819f 100644 --- a/Cargo-minimal.lock +++ b/Cargo-minimal.lock @@ -209,6 +209,7 @@ dependencies = [ "bitcoin", "bitcoinkernel", "env_logger", + "hex", "log", "secp256k1", "silentpayments", diff --git a/Cargo-recent.lock b/Cargo-recent.lock index 319459d5..0732c065 100644 --- a/Cargo-recent.lock +++ b/Cargo-recent.lock @@ -229,6 +229,7 @@ dependencies = [ "bitcoin", "bitcoinkernel", "env_logger", + "hex", "log", "secp256k1", "silentpayments", diff --git a/Cargo.toml b/Cargo.toml index 3dc60614..aff20ced 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,3 +26,10 @@ members = [ "fuzz", "libbitcoinkernel-sys" ] + +[features] +script-trace = ["libbitcoinkernel-sys/script-trace"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 8fc0bf81..5ef77802 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -8,6 +8,11 @@ publish = false name = "silentpaymentscanner" path = "src/silentpaymentscanner.rs" +[[bin]] +name = "scripttrace" +path = "src/scripttrace.rs" +required-features = ["script-trace"] + [dependencies] silentpayments = "0.1" bitcoin = "0.31" @@ -15,3 +20,7 @@ secp256k1 = "0.28" env_logger = "0.11" log = "0.4" bitcoinkernel = { path = ".." } +hex = "0.4" + +[features] +script-trace = ["bitcoinkernel/script-trace"] diff --git a/examples/src/scripttrace.rs b/examples/src/scripttrace.rs new file mode 100644 index 00000000..b557442c --- /dev/null +++ b/examples/src/scripttrace.rs @@ -0,0 +1,82 @@ +use bitcoin::Opcode; +use bitcoinkernel::{ + verify, KernelError, PrecomputedTransactionData, ScriptPubkey, ScriptTraceFrameKind, + ScriptTraceFrameRef, ScriptTracer, Transaction, TxOut, VERIFY_ALL_PRE_TAPROOT, +}; + +fn main() { + let _tracer = ScriptTracer::new(trace).expect("failed to register the script tracer"); + + // A plain old-style P2PKH spend. + verify_test( + "76a9144bfbaf6afb76cc5771bc6404810d1cc041a6933988ac", + "02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700", + 0, + 0, + ) + .expect("verification failed"); + + verify_test( + // last hash byte changed 39 -> 38, so OP_EQUALVERIFY will fail + "76a9144bfbaf6afb76cc5771bc6404810d1cc041a6933888ac", + "02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700", + 0, + 0, + ) + .expect_err("expected a script verification error"); +} + +fn trace(frame: ScriptTraceFrameRef<'_>) { + match frame.kind() { + ScriptTraceFrameKind::Begin => { + let script_len = frame.script().map(|script| script.len()).unwrap_or(0); + println!( + "== begin: {} byte script, sig_version {:?} ==", + script_len, + frame.sig_version() + ); + } + ScriptTraceFrameKind::Step => { + println!( + "[step {}] opcode=0x{:02x} ({:?}) exec={} op_count={} stack_depth={}", + frame.opcode_pos(), + frame.opcode(), + Opcode::from(frame.opcode()), + frame.exec(), + frame.op_count(), + frame.stack().len() + ); + + for (i, item) in frame.stack().iter().enumerate() { + match item.to_bytes() { + Ok(bytes) if bytes.is_empty() => println!(" stack[{i}]: "), + Ok(bytes) => println!(" stack[{i}]: {}", hex::encode(bytes)), + Err(err) => println!(" stack[{i}]: "), + } + } + } + ScriptTraceFrameKind::End => { + println!("== end: script_error={} ==", frame.script_error()); + } + } +} + +fn verify_test( + spent: &str, + spending: &str, + amount: i64, + input_index: usize, +) -> Result<(), KernelError> { + let spent_script_pubkey = + ScriptPubkey::try_from(hex::decode(spent).unwrap().as_slice()).unwrap(); + let spending_tx = Transaction::new(hex::decode(spending).unwrap().as_slice()).unwrap(); + let tx_data = PrecomputedTransactionData::new(&spending_tx, &Vec::::new()).unwrap(); + verify( + &spent_script_pubkey, + Some(amount), + &spending_tx, + input_index, + Some(VERIFY_ALL_PRE_TAPROOT), + &tx_data, + ) +} diff --git a/libbitcoinkernel-sys/Cargo.toml b/libbitcoinkernel-sys/Cargo.toml index 58053641..08bd6de6 100644 --- a/libbitcoinkernel-sys/Cargo.toml +++ b/libbitcoinkernel-sys/Cargo.toml @@ -51,3 +51,6 @@ publish = true [build-dependencies] cc = "1.2" + +[features] +script-trace = [] diff --git a/libbitcoinkernel-sys/bitcoin/.github/actions/configure-environment/action.yml b/libbitcoinkernel-sys/bitcoin/.github/actions/configure-environment/action.yml index e2a26b71..d3c928cf 100644 --- a/libbitcoinkernel-sys/bitcoin/.github/actions/configure-environment/action.yml +++ b/libbitcoinkernel-sys/bitcoin/.github/actions/configure-environment/action.yml @@ -7,7 +7,9 @@ runs: shell: bash run: | echo "BASE_ROOT_DIR=${{ runner.temp }}" >> "$GITHUB_ENV" - echo "BASE_BUILD_DIR=${{ runner.temp }}/build" >> "$GITHUB_ENV" + # Space and non-ASCII symbols mimic BASE_SCRATCH_DIR in ci/test/00_setup_env.sh, + # to test word-splitting and UTF-8 path handling on CI. + echo "BASE_BUILD_DIR=${{ runner.temp }}/build_ ₿🧪_" >> "$GITHUB_ENV" echo "CCACHE_DIR=${{ runner.temp }}/ccache_dir" >> $GITHUB_ENV echo "DEPENDS_DIR=${{ runner.temp }}/depends" >> "$GITHUB_ENV" echo "BASE_CACHE=${{ runner.temp }}/depends/built" >> $GITHUB_ENV diff --git a/libbitcoinkernel-sys/bitcoin/.github/ci-windows-cross.py b/libbitcoinkernel-sys/bitcoin/.github/ci-windows-cross.py index bf13f81a..355d8fb7 100755 --- a/libbitcoinkernel-sys/bitcoin/.github/ci-windows-cross.py +++ b/libbitcoinkernel-sys/bitcoin/.github/ci-windows-cross.py @@ -5,6 +5,7 @@ import argparse import os +import re import shlex import subprocess import sys @@ -28,6 +29,31 @@ def print_version(): run([str(bitcoind), "-version"]) +def check_imports(): + bitcoind = Path.cwd() / "bin" / "bitcoind.exe" + output = run( + ["dumpbin.exe", "/imports", str(bitcoind)], + capture_output=True, + text=True, + ).stdout + dlls = re.findall(r"^\s*(\S+\.dll)\s*$", output, re.IGNORECASE | re.MULTILINE) + print("\n".join(dlls)) + + # Ensure the executable is linked against the expected C runtime. + dlls = {name.lower() for name in dlls} + uses_msvcrt = "msvcrt.dll" in dlls + uses_ucrt = any(name.startswith("api-ms-win-crt-") for name in dlls) + crt = os.environ["CRT"] + if crt == "msvcrt": + crt_ok = uses_msvcrt and not uses_ucrt + elif crt == "ucrt": + crt_ok = uses_ucrt and not uses_msvcrt + else: + sys.exit(f"Unexpected CRT value: {crt!r}") + if not crt_ok: + sys.exit(f"Imported DLLs do not match the expected {crt!r} C runtime.") + + def check_manifests(): release_dir = Path.cwd() / "bin" manifest_path = release_dir / "bitcoind.manifest" @@ -99,23 +125,26 @@ def run_functional_tests(): f"--tmpdirprefix={workspace / '_ _'}", "--combinedlogslen=99999999", *shlex.split(os.environ.get("TEST_RUNNER_EXTRA", "").strip()), - # feature_unsupported_utxo_db.py fails on Windows because of emojis in the test data directory. + # Tests using ancient releases fail on Windows because of emojis in the test data directory. "--exclude", "feature_unsupported_utxo_db.py", + "--exclude", + "wallet_ancient_migration.py", ] run(test_runner_cmd) - # Run feature_unsupported_utxo_db sequentially in ASCII-only tmp dir, - # because it is excluded above due to lack of UTF-8 support in the + # Run ancient release tests sequentially in ASCII-only tmp dir, + # because they are excluded above due to lack of UTF-8 support in the # ancient release. - cmd_feature_unsupported_db = [ - sys.executable, - str(workspace / "test" / "functional" / "feature_unsupported_utxo_db.py"), - "--previous-releases", - "--tmpdir", - str(Path(workspace) / "test_feature_unsupported_utxo_db"), - ] - run(cmd_feature_unsupported_db) + for test_name in ["feature_unsupported_utxo_db", "wallet_ancient_migration"]: + cmd = [ + sys.executable, + str(workspace / "test" / "functional" / f"{test_name}.py"), + "--previous-releases", + "--tmpdir", + str(workspace / f"test_{test_name}"), + ] + run(cmd) def run_unit_tests(): @@ -140,6 +169,7 @@ def main(): parser = argparse.ArgumentParser(description="Utility to run Windows CI steps.") steps = list(map(lambda f: f.__name__, [ print_version, + check_imports, check_manifests, prepare_tests, run_unit_tests, diff --git a/libbitcoinkernel-sys/bitcoin/.github/workflows/ci.yml b/libbitcoinkernel-sys/bitcoin/.github/workflows/ci.yml index bce9c603..d8d48eec 100644 --- a/libbitcoinkernel-sys/bitcoin/.github/workflows/ci.yml +++ b/libbitcoinkernel-sys/bitcoin/.github/workflows/ci.yml @@ -403,6 +403,11 @@ jobs: - *IMPORT_VS_ENV + - name: Check imported DLLs + env: + CRT: ${{ matrix.crt }} + run: py -3 .github/ci-windows-cross.py check_imports + - name: Check executable manifests run: py -3 .github/ci-windows-cross.py check_manifests diff --git a/libbitcoinkernel-sys/bitcoin/.tx/config b/libbitcoinkernel-sys/bitcoin/.tx/config index 41051254..a43890a3 100644 --- a/libbitcoinkernel-sys/bitcoin/.tx/config +++ b/libbitcoinkernel-sys/bitcoin/.tx/config @@ -1,7 +1,7 @@ [main] host = https://www.transifex.com -[o:bitcoin:p:bitcoin:r:qt-translation-031x] -file_filter = src/qt/locale/bitcoin_.xlf -source_file = src/qt/locale/bitcoin_en.xlf +[o:bitcoin:p:bitcoin:r:qt-translation-032x] +file_filter = src/qt/locale/bitcoin_.ts +source_file = src/qt/locale/bitcoin_en.ts source_lang = en diff --git a/libbitcoinkernel-sys/bitcoin/CMakeLists.txt b/libbitcoinkernel-sys/bitcoin/CMakeLists.txt index ffd2da14..f36c4cd4 100644 --- a/libbitcoinkernel-sys/bitcoin/CMakeLists.txt +++ b/libbitcoinkernel-sys/bitcoin/CMakeLists.txt @@ -330,10 +330,6 @@ if(WIN32) /Zc:__cplusplus /sdl ) - target_link_options(core_interface INTERFACE - # We embed our own manifests. - /MANIFEST:NO - ) # Improve parallelism in MSBuild. # See: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/. list(APPEND CMAKE_VS_GLOBALS "UseMultiToolTask=true") @@ -471,7 +467,6 @@ if(MSVC) try_append_cxx_flags("/wd4805" TARGET warn_interface SKIP_LINK) target_compile_definitions(warn_interface INTERFACE _CRT_SECURE_NO_WARNINGS - _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING ) else() try_append_cxx_flags("-Wall" TARGET warn_interface SKIP_LINK) @@ -601,6 +596,7 @@ endif() if(REDUCE_EXPORTS) set(CMAKE_CXX_VISIBILITY_PRESET hidden) + set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) try_append_linker_flag("-Wl,--exclude-libs,ALL" TARGET core_interface) try_append_linker_flag("-Wl,-no_exported_symbols" VAR CMAKE_EXE_LINKER_FLAGS) endif() diff --git a/libbitcoinkernel-sys/bitcoin/CONTRIBUTING.md b/libbitcoinkernel-sys/bitcoin/CONTRIBUTING.md index bcf0815d..93be1099 100644 --- a/libbitcoinkernel-sys/bitcoin/CONTRIBUTING.md +++ b/libbitcoinkernel-sys/bitcoin/CONTRIBUTING.md @@ -106,7 +106,8 @@ fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures. -This means tests must be updated in the same commit that changes the behavior. +See the [developer notes](doc/developer-notes.md#commit-structure-for-tests) +for guidance on where test coverage belongs in a commit stack. Commit messages should be verbose by default consisting of a short subject line (50 chars max), a blank line and detailed explanatory text as separate diff --git a/libbitcoinkernel-sys/bitcoin/ci/lint/requirements.txt b/libbitcoinkernel-sys/bitcoin/ci/lint/requirements.txt index e9459225..5a6b7624 100644 --- a/libbitcoinkernel-sys/bitcoin/ci/lint/requirements.txt +++ b/libbitcoinkernel-sys/bitcoin/ci/lint/requirements.txt @@ -1,3 +1,4 @@ +# lief version should match the version used in Guix lief==0.17.5 -mypy==2.3.0 -pyzmq==27.1.0 +mypy==2.3.1 +pyzmq==27.2.0 diff --git a/libbitcoinkernel-sys/bitcoin/ci/lint_imagefile b/libbitcoinkernel-sys/bitcoin/ci/lint_imagefile index cc4986a7..45bfe11e 100644 --- a/libbitcoinkernel-sys/bitcoin/ci/lint_imagefile +++ b/libbitcoinkernel-sys/bitcoin/ci/lint_imagefile @@ -10,7 +10,7 @@ FROM mirror.gcr.io/ubuntu:26.04 # https://docs.astral.sh/uv/reference/policies/versioning/ # https://docs.astral.sh/ruff/versioning/ COPY --from=ghcr.io/astral-sh/uv:0.11 /uv /uvx /bin/ -COPY --from=ghcr.io/astral-sh/ruff:0.15 /ruff /bin/ +COPY --from=ghcr.io/astral-sh/ruff:0.16 /ruff /bin/ COPY ./ci/retry/retry /ci_retry COPY ./.python-version /.python-version diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env.sh b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env.sh index 4ca660a5..fc8f2d98 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env.sh @@ -14,7 +14,9 @@ BASE_READ_ONLY_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../../ >/dev/null 2> export BASE_READ_ONLY_DIR # The destination root dir inside the container. # This folder will also hold any SDKs. -# This folder only exists on the ci guest and will be a copy of BASE_READ_ONLY_DIR +# This folder only exists on the ci guest and will be a copy of BASE_READ_ONLY_DIR. +# This value is embedded in the CI image at build time; changing it requires +# rebuilding the image. export BASE_ROOT_DIR="${BASE_ROOT_DIR:-/ci_container_base}" # The depends dir. # This folder exists only on the ci guest, and on the ci host as a volume. diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_freebsd_cross.sh b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_freebsd_cross.sh index 29602ae2..9a22cb6f 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_freebsd_cross.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_freebsd_cross.sh @@ -12,6 +12,7 @@ export APT_LLVM_V="22" export HOST=x86_64-unknown-freebsd export FREEBSD_VERSION=15.1 export FREEBSD_SDK_BASENAME="freebsd-${HOST}-${FREEBSD_VERSION}" +export FREEBSD_SDK_SHA256=3768988b151c20f965679062b065c63a977d6bbb9f47fd83695ec2c40790c18f export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} lld-${APT_LLVM_V}" export SYSROOT="--sysroot=${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" export DEP_OPTS="build_CC=clang build_CXX=clang++ \ diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_i686_no_ipc.sh b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_i686_no_ipc.sh index d8df8100..f8943a00 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_i686_no_ipc.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_i686_no_ipc.sh @@ -6,12 +6,13 @@ export LC_ALL=C.UTF-8 -export HOST=i686-pc-linux-gnu +export HOST=i686-linux-gnu +export DPKG_ADD_ARCH="i386" export CONTAINER_NAME=ci_i686_no_multiprocess export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export CI_IMAGE_PLATFORM="linux/amd64" export CI_CONTAINER_CAP="--security-opt seccomp=unconfined" -export PACKAGES="g++-multilib" +export PACKAGES="g++-i686-linux-gnu binutils-i686-linux-gnu libstdc++6:i386 libatomic1:i386" export DEP_OPTS="DEBUG=1 NO_IPC=1" export GOAL="install" export CI_LIMIT_STACK_SIZE=1 diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_mac_cross.sh b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_mac_cross.sh index 63d89fb9..80c6f878 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_mac_cross.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_mac_cross.sh @@ -14,6 +14,7 @@ export HOST=arm64-apple-darwin export PACKAGES="clang lld llvm zip" export XCODE_VERSION=26.1.1 export XCODE_BUILD_ID=17B100 +export OSX_SDK_SHA256=9600fa93644df674ee916b5e2c8a6ba8dacf631996a65dc922d003b98b5ea3b1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_mac_cross_intel.sh b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_mac_cross_intel.sh index 4b07e14b..e679c957 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_mac_cross_intel.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_mac_cross_intel.sh @@ -14,6 +14,7 @@ export HOST=x86_64-apple-darwin export PACKAGES="clang lld llvm zip" export XCODE_VERSION=26.1.1 export XCODE_BUILD_ID=17B100 +export OSX_SDK_SHA256=9600fa93644df674ee916b5e2c8a6ba8dacf631996a65dc922d003b98b5ea3b1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_netbsd_cross.sh b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_netbsd_cross.sh index 9fb4c18a..e817473f 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_netbsd_cross.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_netbsd_cross.sh @@ -10,8 +10,11 @@ export CONTAINER_NAME=ci_netbsd_cross export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export APT_LLVM_V="22" export HOST=x86_64-unknown-netbsd -export NETBSD_VERSION=11.0_RC6 +export NETBSD_VERSION=11.0 export NETBSD_SDK_BASENAME="netbsd-${HOST}-${NETBSD_VERSION}" +export NETBSD_SDK_SHA512SUMS="\ +e8871bbedb8c3e0f696cc2596ced0c1e6497939f725fb3495b8d2c168430325907550f5f840f4dd0e3c73e6090394747c5e54762f2737de81177b984403522a8 base.tar.xz\n\ +d8df6c07e9142dd8189292b769ac312f86185a6a278a752c18c840f7cd3a8dd3c535f9b0c8e06b62d556b2c75b97a01d786184e8a18f5e080ccd213591c8628f comp.tar.xz" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} lld-${APT_LLVM_V}" export SYSROOT="--sysroot=${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" export DEP_OPTS="build_CC=clang build_CXX=clang++ \ diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_openbsd_cross.sh b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_openbsd_cross.sh index 1732aef3..f9d75e47 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_openbsd_cross.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_openbsd_cross.sh @@ -12,6 +12,9 @@ export APT_LLVM_V="22" export HOST=x86_64-unknown-openbsd export OPENBSD_VERSION=7.9 export OPENBSD_SDK_BASENAME="openbsd-${HOST}-${OPENBSD_VERSION}" +export OPENBSD_SDK_SHA256SUMS="\ +923d2e03f06408d50d4848334398c6d04b5514dcac7917badfc178a0eef248de base79.tgz\n\ +21a67af20aebcabf85b09f4206fc95b4cae0a35d42b154b976f0159f457724f9 comp79.tgz" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} lld-${APT_LLVM_V}" export SYSROOT="--sysroot=${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" export DEP_OPTS="NO_QT=1 build_CC=clang build_CXX=clang++ \ diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_win64.sh b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_win64.sh index dbbf55c1..74891889 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_win64.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_win64.sh @@ -7,9 +7,9 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_win64 -export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-mingw-w64-ucrt64 can cross-compile +export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export HOST=x86_64-w64-mingw32ucrt -export PACKAGES="g++-mingw-w64-ucrt64 nsis" +export PACKAGES="nix-bin nix-setup-systemd" export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_win64_msvcrt.sh b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_win64_msvcrt.sh index 6c948aeb..d1c1aa8a 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_win64_msvcrt.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/00_setup_env_win64_msvcrt.sh @@ -7,9 +7,9 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_win64_msvcrt -export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-mingw-w64-x86-64-posix (version 14.x, similar to guix) can cross-compile +export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export HOST=x86_64-w64-mingw32 -export PACKAGES="g++-mingw-w64-x86-64-posix nsis" +export PACKAGES="nix-bin nix-setup-systemd" export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/01_base_install.sh b/libbitcoinkernel-sys/bitcoin/ci/test/01_base_install.sh index f619a088..057916e2 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/01_base_install.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/01_base_install.sh @@ -50,6 +50,11 @@ elif [ "$CI_OS_NAME" != "macos" ]; then ${CI_RETRY_EXE} apt-get install --no-install-recommends --no-upgrade -y $PACKAGES $CI_BASE_PACKAGES fi +if [[ ${HOST:-} == x86_64-w64-mingw32* ]]; then + # Install Nix packages. + NIX_BUILD_SHELL=bash nix-shell "${BASE_ROOT_DIR}/contrib/devtools/shell-win64-cross.nix" --run true +fi + if [ -n "${APT_LLVM_V}" ]; then update-alternatives --install /usr/bin/clang++ clang++ "/usr/bin/clang++-${APT_LLVM_V}" 100 update-alternatives --install /usr/bin/clang clang "/usr/bin/clang-${APT_LLVM_V}" 100 @@ -88,18 +93,18 @@ if [[ -n "${USE_INSTRUMENTED_LIBCPP}" ]]; then fi if [[ ${BARE_METAL_RISCV} == "true" ]]; then - ${CI_RETRY_EXE} git clone --depth=1 https://github.com/riscv-collab/riscv-gnu-toolchain -b 2026.06.06 /riscv/gcc - ( cd /riscv/gcc; - ./configure --prefix=/opt/riscv-ilp32 --with-arch=rv32gc --with-abi=ilp32 --disable-gdb; - make "$MAKEJOBS"; ) + ${CI_RETRY_EXE} git clone --depth=1 https://github.com/riscv-collab/riscv-gnu-toolchain -b 2026.08.25 /riscv/gcc + ( cd /riscv/gcc + ./configure --prefix=/opt/riscv-ilp32 --with-arch=rv32gc --with-abi=ilp32 --disable-gdb + make "$MAKEJOBS" ) rm -rf /riscv/gcc fi if [[ "${RUN_IWYU}" == true ]]; then ${CI_RETRY_EXE} git clone --depth=1 https://github.com/include-what-you-use/include-what-you-use -b clang_"${IWYU_LLVM_V}" /include-what-you-use pushd /include-what-you-use - patch -p1 < /ci_container_base/ci/test/01_iwyu.patch - patch -p1 < /ci_container_base/ci/test/02_iwyu_hash.patch + patch -p1 < "${BASE_ROOT_DIR}/ci/test/01_iwyu.patch" + patch -p1 < "${BASE_ROOT_DIR}/ci/test/02_iwyu_hash.patch" popd cmake -B /iwyu-build/ -G 'Unix Makefiles' -DCMAKE_PREFIX_PATH=/usr/lib/llvm-"${IWYU_LLVM_V}" -S /include-what-you-use make -C /iwyu-build/ install "$MAKEJOBS" @@ -115,18 +120,20 @@ if [ -n "$XCODE_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OSX_SDK_BASENAME}" ] if [ ! -f "$OSX_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "${SDK_URL}/${OSX_SDK_FILENAME}" -o "$OSX_SDK_PATH" fi + sha256sum -c <<<"${OSX_SDK_SHA256} ${OSX_SDK_PATH}" tar -C "${DEPENDS_DIR}/SDKs" -xf "$OSX_SDK_PATH" fi if [ -n "$NETBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" ]; then mkdir -p "${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" - for NETBSD_SDK_FILENAME in base.tar.xz comp.tar.xz; do + while read -r NETBSD_SDK_SHA512 NETBSD_SDK_FILENAME; do NETBSD_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${NETBSD_SDK_FILENAME}" if [ ! -f "$NETBSD_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "https://cdn.netbsd.org/pub/NetBSD/NetBSD-${NETBSD_VERSION}/amd64/binary/sets/${NETBSD_SDK_FILENAME}" -o "$NETBSD_SDK_PATH" fi + sha512sum -c <<<"${NETBSD_SDK_SHA512} ${NETBSD_SDK_PATH}" tar -C "${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" -xf "$NETBSD_SDK_PATH" - done + done < <(printf '%b\n' "${NETBSD_SDK_SHA512SUMS}") fi if [ -n "$FREEBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" ]; then @@ -135,27 +142,29 @@ if [ -n "$FREEBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENA if [ ! -f "$FREEBSD_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "https://download.freebsd.org/releases/amd64/${FREEBSD_VERSION}-RELEASE/base.txz" -o "$FREEBSD_SDK_PATH" fi + sha256sum -c <<<"${FREEBSD_SDK_SHA256} ${FREEBSD_SDK_PATH}" mkdir -p "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" tar -C "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" -xf "$FREEBSD_SDK_PATH" fi if [ -n "$OPENBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" ]; then mkdir -p "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" - for OPENBSD_SDK_FILENAME in base79.tgz comp79.tgz; do + while read -r OPENBSD_SDK_SHA256 OPENBSD_SDK_FILENAME; do OPENBSD_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${OPENBSD_SDK_FILENAME}" if [ ! -f "$OPENBSD_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "https://cdn.openbsd.org/pub/OpenBSD/${OPENBSD_VERSION}/amd64/${OPENBSD_SDK_FILENAME}" -o "$OPENBSD_SDK_PATH" fi + sha256sum -c <<<"${OPENBSD_SDK_SHA256} ${OPENBSD_SDK_PATH}" tar -C "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" -xf "$OPENBSD_SDK_PATH" - ( - # The SDK has versioned shared libs, but no unversioned libfoo.so symlink, - # which breaks linking the kernel with lld. Create the symlinks. - cd "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}/usr/lib" - ln -sf libc++abi.so.*.* libc++abi.so - ln -sf libc++.so.*.* libc++.so - ln -sf libpthread.so.*.* libpthread.so - ) - done + done < <(printf '%b\n' "${OPENBSD_SDK_SHA256SUMS}") + ( + # The SDK has versioned shared libs, but no unversioned libfoo.so symlink, + # which breaks linking the kernel with lld. Create the symlinks. + cd "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}/usr/lib" + ln -sf libc++abi.so.*.* libc++abi.so + ln -sf libc++.so.*.* libc++.so + ln -sf libpthread.so.*.* libpthread.so + ) fi echo -n "done" > "${CFG_DONE}" diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/02_run_container.py b/libbitcoinkernel-sys/bitcoin/ci/test/02_run_container.py index 05887000..d726b36a 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/02_run_container.py +++ b/libbitcoinkernel-sys/bitcoin/ci/test/02_run_container.py @@ -183,7 +183,18 @@ def ci_exec(cmd_inner, **kwargs): f"{os.environ['BASE_ROOT_DIR']}", ]) ci_exec([f"{os.environ['BASE_ROOT_DIR']}/ci/test/01_base_install.sh"]) - ci_exec([f"{os.environ['BASE_ROOT_DIR']}/ci/test/03_test_script.sh"]) + test_script = f"{os.environ['BASE_ROOT_DIR']}/ci/test/03_test_script.sh" + if os.environ.get("HOST", "").startswith("x86_64-w64-mingw32"): + ci_exec([ + "env", + "NIX_BUILD_SHELL=bash", + "nix-shell", + f"{os.environ['BASE_ROOT_DIR']}/contrib/devtools/shell-win64-cross.nix", + "--run", + f"exec bash {shlex.quote(test_script)}", + ]) + else: + ci_exec([test_script]) if not os.getenv("DANGER_RUN_CI_ON_HOST"): print("Stop and remove CI container by ID") diff --git a/libbitcoinkernel-sys/bitcoin/ci/test/03_test_script.sh b/libbitcoinkernel-sys/bitcoin/ci/test/03_test_script.sh index 7650ab7d..cffd87af 100755 --- a/libbitcoinkernel-sys/bitcoin/ci/test/03_test_script.sh +++ b/libbitcoinkernel-sys/bitcoin/ci/test/03_test_script.sh @@ -17,7 +17,7 @@ cd "${BASE_ROOT_DIR}" export PATH="/path_with space:${PATH}" export ASAN_OPTIONS="detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1" -export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan" +export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan:print_suppressions=0" export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1:second_deadlock_stack=1" export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" @@ -234,7 +234,7 @@ fi if [[ "${RUN_IWYU}" == true ]]; then # TODO: Consider enforcing IWYU across the entire codebase. - FILES_WITH_ENFORCED_IWYU="/src/(((bench|crypto|index|kernel|primitives|script|univalue/(lib|test)|util|zmq)/.*|common/license_info|node/(blockstorage|interfaces|miner|mining_args|utxo_snapshot)|rpc/mining|clientversion|core_io|signet|init)\\.cpp)" + FILES_WITH_ENFORCED_IWYU='/src/((bench|common|consensus|crypto|index|kernel|primitives|script|univalue/(lib|test)|util|zmq)/.*|node/(blockstorage|interfaces|miner|mining_args|utxo_snapshot)|rpc/mining|clientversion|core_io|signet|init)\.cpp' jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns)))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_errors.json" jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns) | not))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_warnings.json" @@ -247,7 +247,10 @@ if [[ "${RUN_IWYU}" == true ]]; then -p "${BASE_BUILD_DIR}" "${MAKEJOBS}" \ -- -Xiwyu --cxx17ns -Xiwyu --mapping_file="${BASE_ROOT_DIR}/contrib/devtools/iwyu/bitcoin.core.imp" \ -Xiwyu --max_line_length=160 \ - -Xiwyu --check_also="*/primitives/*.h" \ + -Xiwyu --check_also='*/common/types\.h' \ + -Xiwyu --check_also='*/consensus/*\.h' \ + -Xiwyu --check_also='*/interfaces/*\.h' \ + -Xiwyu --check_also='*/primitives/transaction_identifier\.h' \ 2>&1 || true } | tee /tmp/iwyu_ci.out python3 "/include-what-you-use/fix_includes.py" --nosafe_headers < /tmp/iwyu_ci.out diff --git a/libbitcoinkernel-sys/bitcoin/ci/test_imagefile b/libbitcoinkernel-sys/bitcoin/ci/test_imagefile index dac6b553..7cb88ddb 100644 --- a/libbitcoinkernel-sys/bitcoin/ci/test_imagefile +++ b/libbitcoinkernel-sys/bitcoin/ci/test_imagefile @@ -16,10 +16,11 @@ ENV BASE_ROOT_DIR=${BASE_ROOT_DIR} # Make retry available in PATH, needed for CI_RETRY_EXE COPY ./ci/retry/retry /usr/bin/retry -COPY ./ci/test/00_setup_env.sh ./${FILE_ENV} ./ci/test/01_base_install.sh /ci_container_base/ci/test/ -COPY ./ci/test/*.patch /ci_container_base/ci/test/ +COPY ./ci/test/00_setup_env.sh ./${FILE_ENV} ./ci/test/01_base_install.sh ${BASE_ROOT_DIR}/ci/test/ +COPY ./contrib/devtools/shell-win64-cross.nix ${BASE_ROOT_DIR}/contrib/devtools/ +COPY ./ci/test/*.patch ${BASE_ROOT_DIR}/ci/test/ # Bash is required, so install it when missing RUN sh -c "bash -c 'true' || ( apk update && apk add --no-cache bash )" -RUN ["bash", "-c", "cd /ci_container_base/ && set -o errexit && source ./ci/test/00_setup_env.sh && DANGER_RUN_CI_ON_HOST=1 ./ci/test/01_base_install.sh"] +RUN ["bash", "-c", "cd ${BASE_ROOT_DIR}/ && set -o errexit && source ./ci/test/00_setup_env.sh && DANGER_RUN_CI_ON_HOST=1 ./ci/test/01_base_install.sh"] diff --git a/libbitcoinkernel-sys/bitcoin/cmake/bitcoin-build-config.h.in b/libbitcoinkernel-sys/bitcoin/cmake/bitcoin-build-config.h.in index bf3ddcd7..5e1c1008 100644 --- a/libbitcoinkernel-sys/bitcoin/cmake/bitcoin-build-config.h.in +++ b/libbitcoinkernel-sys/bitcoin/cmake/bitcoin-build-config.h.in @@ -76,6 +76,9 @@ /* Define this symbol if you have posix_fallocate */ #cmakedefine HAVE_POSIX_FALLOCATE 1 +/* Define this symbol if you have SetThreadDescription */ +#cmakedefine HAVE_SETTHREADDESCRIPTION 1 + /* Define this symbol if platform supports unix domain sockets */ #cmakedefine HAVE_SOCKADDR_UN 1 @@ -88,7 +91,7 @@ /* Define this symbol if the BSD sysctl(KERN_ARND) is available */ #cmakedefine HAVE_SYSCTL_ARND 1 -/* Define to 1 if std::system or ::wsystem is available. */ +/* Define to 1 if std::system is available. */ #cmakedefine HAVE_SYSTEM 1 /* Define to the address where bug reports for this package should be sent. */ diff --git a/libbitcoinkernel-sys/bitcoin/cmake/introspection.cmake b/libbitcoinkernel-sys/bitcoin/cmake/introspection.cmake index d6083f52..a99a7660 100644 --- a/libbitcoinkernel-sys/bitcoin/cmake/introspection.cmake +++ b/libbitcoinkernel-sys/bitcoin/cmake/introspection.cmake @@ -24,8 +24,7 @@ endif() # Even though ::system is part of the standard library, we still check # for it, to support building targets that don't have it, such as iOS. check_cxx_symbol_exists(std::system "cstdlib" HAVE_STD_SYSTEM) -check_cxx_symbol_exists(::_wsystem "stdlib.h" HAVE__WSYSTEM) -if(HAVE_STD_SYSTEM OR HAVE__WSYSTEM) +if(HAVE_STD_SYSTEM) set(HAVE_SYSTEM 1) endif() @@ -77,6 +76,10 @@ check_cxx_source_compiles(" " HAVE_STRONG_GETAUXVAL ) +# Check for SetThreadDescription(), which is missing from mingw-w64 headers +# before 12.0.0. +check_cxx_symbol_exists(SetThreadDescription "windows.h" HAVE_SETTHREADDESCRIPTION) + # Check for UNIX sockets. check_cxx_source_compiles(" #include diff --git a/libbitcoinkernel-sys/bitcoin/cmake/module/AddWindowsResources.cmake b/libbitcoinkernel-sys/bitcoin/cmake/module/AddWindowsResources.cmake index 84c1ba85..8fad425a 100644 --- a/libbitcoinkernel-sys/bitcoin/cmake/module/AddWindowsResources.cmake +++ b/libbitcoinkernel-sys/bitcoin/cmake/module/AddWindowsResources.cmake @@ -4,21 +4,19 @@ include_guard(GLOBAL) -function(add_windows_resources target rc_file) - if(WIN32) - target_sources(${target} PRIVATE ${rc_file}) - endif() -endfunction() - # Add a fusion manifest to Windows executables. # See: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests function(add_windows_application_manifest target) - if(WIN32) - configure_file(${PROJECT_SOURCE_DIR}/cmake/windows-app.manifest.in ${target}.manifest USE_SOURCE_PERMISSIONS) + configure_file(${PROJECT_SOURCE_DIR}/cmake/windows-app.manifest.in ${target}.manifest USE_SOURCE_PERMISSIONS) + if(MSVC) + target_sources(${target} PRIVATE ${target}.manifest) + else() + # TODO: Remove when upstream issue is fixed: + # https://gitlab.kitware.com/cmake/cmake/-/issues/23244 file(CONFIGURE OUTPUT ${target}-manifest.rc CONTENT "1 /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ \"${target}.manifest\"" ) - add_windows_resources(${target} ${CMAKE_CURRENT_BINARY_DIR}/${target}-manifest.rc) + target_sources(${target} PRIVATE ${target}-manifest.rc) endif() endfunction() diff --git a/libbitcoinkernel-sys/bitcoin/cmake/module/GenerateSetupNsi.cmake b/libbitcoinkernel-sys/bitcoin/cmake/module/GenerateSetupNsi.cmake deleted file mode 100644 index c8d5bd67..00000000 --- a/libbitcoinkernel-sys/bitcoin/cmake/module/GenerateSetupNsi.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2023-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -function(generate_setup_nsi) - set(abs_top_srcdir ${PROJECT_SOURCE_DIR}) - set(abs_top_builddir ${PROJECT_BINARY_DIR}) - set(CLIENT_URL ${PROJECT_HOMEPAGE_URL}) - set(CLIENT_TARNAME "bitcoin") - set(BITCOIN_WRAPPER_NAME "bitcoin") - set(BITCOIN_GUI_NAME "bitcoin-qt") - set(BITCOIN_DAEMON_NAME "bitcoind") - set(BITCOIN_CLI_NAME "bitcoin-cli") - set(BITCOIN_TX_NAME "bitcoin-tx") - set(BITCOIN_WALLET_TOOL_NAME "bitcoin-wallet") - set(BITCOIN_TEST_NAME "test_bitcoin") - set(EXEEXT ${CMAKE_EXECUTABLE_SUFFIX}) - configure_file(${PROJECT_SOURCE_DIR}/share/setup.nsi.in ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.nsi USE_SOURCE_PERMISSIONS @ONLY) -endfunction() diff --git a/libbitcoinkernel-sys/bitcoin/cmake/module/Maintenance.cmake b/libbitcoinkernel-sys/bitcoin/cmake/module/Maintenance.cmake index 15fbf2be..43e145d6 100644 --- a/libbitcoinkernel-sys/bitcoin/cmake/module/Maintenance.cmake +++ b/libbitcoinkernel-sys/bitcoin/cmake/module/Maintenance.cmake @@ -19,32 +19,21 @@ function(setup_split_debug_script) endfunction() function(add_windows_deploy_target) + configure_file(${PROJECT_SOURCE_DIR}/cmake/script/GenerateWindowsInstaller.cmake.in ${PROJECT_BINARY_DIR}/GenerateWindowsInstaller.cmake USE_SOURCE_PERMISSIONS @ONLY) if(MINGW AND TARGET bitcoin AND TARGET bitcoin-qt AND TARGET bitcoind AND TARGET bitcoin-cli AND TARGET bitcoin-tx AND TARGET bitcoin-wallet AND TARGET bitcoin-util AND TARGET test_bitcoin) - find_program(MAKENSIS_EXECUTABLE makensis) - if(NOT MAKENSIS_EXECUTABLE) - add_custom_target(deploy - COMMAND ${CMAKE_COMMAND} -E echo "Error: NSIS not found" - ) - return() - endif() - - # TODO: Consider replacing this code with the CPack NSIS Generator. - # See https://cmake.org/cmake/help/latest/cpack_gen/nsis.html - include(GenerateSetupNsi) - generate_setup_nsi() add_custom_command( OUTPUT ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.exe - COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/release - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${MAKENSIS_EXECUTABLE} -V2 ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.nsi - VERBATIM + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory release + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_COMMAND} -D BIN_DIR=release -D LIBEXEC_DIR=release -P GenerateWindowsInstaller.cmake ) add_custom_target(deploy DEPENDS ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.exe) endif() diff --git a/libbitcoinkernel-sys/bitcoin/cmake/script/GenerateWindowsInstaller.cmake.in b/libbitcoinkernel-sys/bitcoin/cmake/script/GenerateWindowsInstaller.cmake.in new file mode 100644 index 00000000..16ebdd49 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/cmake/script/GenerateWindowsInstaller.cmake.in @@ -0,0 +1,40 @@ +# Copyright (c) 2026-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +find_program(MAKENSIS_EXECUTABLE makensis REQUIRED) + +# Project variables. +set(CLIENT_NAME "@CLIENT_NAME@") +set(CLIENT_VERSION_MAJOR @CLIENT_VERSION_MAJOR@) +set(CLIENT_VERSION_MINOR @CLIENT_VERSION_MINOR@) +set(CLIENT_VERSION_BUILD @CLIENT_VERSION_BUILD@) +set(CLIENT_VERSION_STRING "@CLIENT_VERSION_STRING@") +set(CLIENT_URL "@PROJECT_HOMEPAGE_URL@") +set(COPYRIGHT_YEAR "@COPYRIGHT_YEAR@") +set(COPYRIGHT_HOLDERS_FINAL "@COPYRIGHT_HOLDERS_FINAL@") +set(abs_top_srcdir @PROJECT_SOURCE_DIR@) +set(EXEEXT @CMAKE_EXECUTABLE_SUFFIX@) + +# Script variables. +cmake_path(ABSOLUTE_PATH BIN_DIR NORMALIZE) +cmake_path(ABSOLUTE_PATH LIBEXEC_DIR NORMALIZE) + +# Other variables required by the `setup.nsi.in` template. +set(CLIENT_TARNAME "bitcoin") +set(BITCOIN_WRAPPER_NAME "bitcoin") +set(BITCOIN_GUI_NAME "bitcoin-qt") +set(BITCOIN_DAEMON_NAME "bitcoind") +set(BITCOIN_CLI_NAME "bitcoin-cli") +set(BITCOIN_TX_NAME "bitcoin-tx") +set(BITCOIN_WALLET_TOOL_NAME "bitcoin-wallet") +set(BITCOIN_TEST_NAME "test_bitcoin") +configure_file(@PROJECT_SOURCE_DIR@/share/setup.nsi.in ${CMAKE_CURRENT_LIST_DIR}/bitcoin-win64-setup.nsi + USE_SOURCE_PERMISSIONS @ONLY +) + +execute_process( + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + COMMAND ${MAKENSIS_EXECUTABLE} -V2 bitcoin-win64-setup.nsi + COMMAND_ERROR_IS_FATAL ANY +) diff --git a/libbitcoinkernel-sys/bitcoin/contrib/devtools/iwyu/bitcoin.core.imp b/libbitcoinkernel-sys/bitcoin/contrib/devtools/iwyu/bitcoin.core.imp index 9b471cb8..ca7e2750 100644 --- a/libbitcoinkernel-sys/bitcoin/contrib/devtools/iwyu/bitcoin.core.imp +++ b/libbitcoinkernel-sys/bitcoin/contrib/devtools/iwyu/bitcoin.core.imp @@ -5,4 +5,8 @@ { "include": [ "", "private", "", "public" ] }, { "include": [ "", "private", "", "public" ] }, { "include": [ "", "private", "", "public" ] }, + + # Workaround for IWYU issue. + # See: https://github.com/include-what-you-use/include-what-you-use/issues/2084. + { "symbol": ["std::tuple", "private", "", "public"] }, ] diff --git a/libbitcoinkernel-sys/bitcoin/contrib/devtools/shell-win64-cross.nix b/libbitcoinkernel-sys/bitcoin/contrib/devtools/shell-win64-cross.nix new file mode 100644 index 00000000..4fd83b0d --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/contrib/devtools/shell-win64-cross.nix @@ -0,0 +1,45 @@ +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +{ pkgs ? import (builtins.fetchTarball { + # Pin, to keep the versions of the toolchain aligned with the versions used by Guix. + url = "https://github.com/NixOS/nixpkgs/archive/531670d871c0e29724a02f3cbcac170adc65b58c.tar.gz"; + }) {} }: + +let + host = builtins.getEnv "HOST"; + crossPkgs = if host == "x86_64-w64-mingw32ucrt" + then pkgs.pkgsCross.ucrt64 + else if host == "x86_64-w64-mingw32" + then pkgs.pkgsCross.mingwW64 + else throw "Unsupported HOST: ${host}"; + toolchain = crossPkgs.stdenv.cc.targetPrefix; + pthreads = crossPkgs.windows.pthreads; +in + +pkgs.mkShellNoCC { + packages = [ + crossPkgs.gcc14 + pkgs.nsis + ]; + + shellHook = '' + export NIX_CFLAGS_COMPILE="-isystem ${pthreads}/include $NIX_CFLAGS_COMPILE" + export NIX_LDFLAGS="-L${pthreads}/lib $NIX_LDFLAGS" + export CC=$(command -v ${toolchain}gcc) + export CXX=$(command -v ${toolchain}g++) + export LD=$(command -v ${toolchain}ld) + export AR=$(command -v ${toolchain}ar) + export AS=$(command -v ${toolchain}as) + export RANLIB=$(command -v ${toolchain}ranlib) + export NM=$(command -v ${toolchain}nm) + export STRIP=$(command -v ${toolchain}strip) + export OBJCOPY=$(command -v ${toolchain}objcopy) + export OBJDUMP=$(command -v ${toolchain}objdump) + export READELF=$(command -v ${toolchain}readelf) + export SIZE=$(command -v ${toolchain}size) + export WINDRES=$(command -v ${toolchain}windres) + export RC=$(command -v ${toolchain}windres) + ''; +} diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-attest b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-attest index 3d70731c..06925ffb 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-attest +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-attest @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-build b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-build index 1ab9cc7e..9afe00a0 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-build +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-build @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository @@ -337,8 +340,8 @@ INFO: Building ${VERSION:?not set} for platform triple ${HOST:?not set}: ADDITIONAL_GUIX_TIMEMACHINE_FLAGS: ${ADDITIONAL_GUIX_TIMEMACHINE_FLAGS} EOF - # Run the build script 'contrib/guix/libexec/build.sh' in the build - # container specified by 'contrib/guix/manifest.scm'. + # Run the build scripts 'contrib/guix/libexec/*.sh' in the build + # containers specified by 'contrib/guix/manifest*.scm'. # # Explanation of `guix shell` flags: # @@ -403,39 +406,73 @@ EOF # substitutes (pre-built packages) from servers that the user trusts. # Please read the README.md in the same directory as this file for # more information. - # - # shellcheck disable=SC2086 - time-machine shell --manifest="${PWD}/contrib/guix/manifest_build.scm" \ - --container \ - --writable-root \ - --pure \ - --no-cwd \ - --share="$PWD"=/bitcoin \ - --share="$DISTSRC_BASE"=/distsrc-base \ - --share="$OUTDIR_BASE"=/outdir-base \ - --expose="$(git rev-parse --git-common-dir)" \ - ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ - ${BASE_CACHE:+--share="$BASE_CACHE"} \ - ${SDK_PATH:+--share="$SDK_PATH"} \ - --cores="$JOBS" \ - --keep-failed \ - --fallback \ - --link-profile \ - --root="$(profiledir_for_host "${HOST}")" \ - ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} \ - ${ADDITIONAL_GUIX_COMMON_FLAGS} ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ - -- env HOST="$host" \ - DISTNAME="$DISTNAME" \ - JOBS="$JOBS" \ - SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ - ${V:+V=1} \ - ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ - ${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"} \ - ${SDK_PATH:+SDK_PATH="$SDK_PATH"} \ - DISTSRC="$(distsrc_for_host "$HOST" "" /distsrc-base)" \ - OUTDIR="$(outdir_for_host "$HOST" "" /outdir-base)" \ - DIST_ARCHIVE_BASE=/outdir-base/dist-archive \ - bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh" + read -ra _guix_common_flags <<< "$ADDITIONAL_GUIX_COMMON_FLAGS" + read -ra _guix_env_flags <<< "$ADDITIONAL_GUIX_ENVIRONMENT_FLAGS" + + shell_opts=( + --manifest="${PWD}/contrib/guix/manifest_build.scm" + --container + --writable-root + --pure + --no-cwd + --share="$PWD=/bitcoin" + --share="$DISTSRC_BASE=/distsrc-base" + --share="$OUTDIR_BASE=/outdir-base" + --expose="$(git rev-parse --git-common-dir)" + ${SOURCES_PATH:+--share="$SOURCES_PATH"} + ${BASE_CACHE:+--share="$BASE_CACHE"} + ${SDK_PATH:+--share="$SDK_PATH"} + --cores="$JOBS" + --keep-failed + --fallback + --link-profile + ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} + "${_guix_common_flags[@]}" "${_guix_env_flags[@]}" + -- env HOST="$host" \ + DISTNAME="$DISTNAME" + JOBS="$JOBS" + SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" + ${V:+V=1} + ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} + ${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"} + ${SDK_PATH:+SDK_PATH="$SDK_PATH"} + DISTSRC="$(distsrc_for_host "$HOST" "" /distsrc-base)" + OUTDIR="$(outdir_for_host "$HOST" "" /outdir-base)" + DIST_ARCHIVE_BASE=/outdir-base/dist-archive + ) + + case "$HOST" in + *linux*) + time-machine shell --root="$(profiledir_for_host "${HOST}")" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_linux.sh" + + time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \ + --root="$(profiledir_for_host "${HOST}"_gui)" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_linux_gui.sh" + ;; + *darwin*) + time-machine shell --root="$(profiledir_for_host "${HOST}")" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_macos.sh" + + time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \ + --root="$(profiledir_for_host "${HOST}"_gui)" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_macos_gui.sh" + ;; + *mingw*) + time-machine shell --root="$(profiledir_for_host "${HOST}")" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_win.sh" + + time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \ + --root="$(profiledir_for_host "${HOST}"_gui)" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_win_gui.sh" + ;; + esac ) done diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-clean b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-clean index 32258cd7..a72a2644 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-clean +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-clean @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-codesign b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-codesign index 8cc6993b..179041c1 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-codesign +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-codesign @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-verify b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-verify index 02ae0227..82e74003 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-verify +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/guix-verify @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build.sh deleted file mode 100755 index 0ec058b8..00000000 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2019-present The Bitcoin 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 -set -e -o pipefail - -# shellcheck source=setup.sh -source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" - -# Set environment variables to point the NATIVE toolchain to the right -# includes/libs -NATIVE_GCC="$(store_path gcc-toolchain)" - -# Set native toolchain -build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" -build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" - -case "$HOST" in - *darwin*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;; # Required for native packages - *mingw*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;; - *) - NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)" - export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib" - ;; -esac - -# Set environment variables to point the CROSS toolchain to the right -# includes/libs for $HOST -case "$HOST" in - *mingw*) - # Determine output paths to use in CROSS_* environment variables - CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" - CROSS_GCC="$(store_path "gcc-cross-${HOST}")" - CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" - CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... - CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) - - # The search path ordering is generally: - # 1. gcc-related search paths - # 2. libc-related search paths - # 2. kernel-header-related search paths (not applicable to mingw-w64 hosts) - export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" - export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" - export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" - ;; - *darwin*) - # The CROSS toolchain for darwin uses the SDK and ignores environment variables. - # See depends/hosts/darwin.mk for more details. - ;; - *linux*) - CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")" - CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)" - CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")" - CROSS_GCC="$(store_path "gcc-cross-${HOST}")" - CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" - CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... - CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) - - export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" - export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" - export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" - ;; - *) - exit 1 ;; -esac - -# Sanity check CROSS_*_PATH directories -IFS=':' read -ra PATHS <<< "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" -for p in "${PATHS[@]}"; do - if [ -n "$p" ] && [ ! -d "$p" ]; then - echo "'$p' doesn't exist or isn't a directory... Aborting..." - exit 1 - fi -done - -# Determine the correct value for -Wl,--dynamic-linker for the current $HOST -case "$HOST" in - *linux*) - glibc_dynamic_linker=$( - case "$HOST" in - x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; - arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; - aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; - riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; - powerpc64-linux-gnu) echo /lib64/ld64.so.1;; - powerpc64le-linux-gnu) echo /lib64/ld64.so.2;; - *) exit 1 ;; - esac - ) - ;; -esac - -#################### -# Depends Building # -#################### - -# Build the depends tree, overriding variables that assume multilib gcc -make -C depends --jobs="$JOBS" HOST="$HOST" \ - ${V:+V=1} \ - ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ - ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ - ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ - ${build_CC+build_CC="$build_CC"} \ - ${build_CXX+build_CXX="$build_CXX"} \ - x86_64_linux_CC=x86_64-linux-gnu-gcc \ - x86_64_linux_CXX=x86_64-linux-gnu-g++ \ - x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \ - x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \ - x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \ - x86_64_linux_STRIP=x86_64-linux-gnu-strip - -case "$HOST" in - *darwin*) - # Unset now that Qt is built - unset LIBRARY_PATH - ;; -esac - -########################### -# Binary Tarball Building # -########################### - -# CONFIGFLAGS -CONFIGFLAGS="-DREDUCE_EXPORTS=ON -DBUILD_BENCH=OFF -DBUILD_GUI_TESTS=OFF -DBUILD_FUZZ_BINARY=OFF -DCMAKE_SKIP_RPATH=TRUE" - -# CFLAGS -HOST_CFLAGS="-O2 -g" -HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) -HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." -case "$HOST" in - *mingw*) HOST_CFLAGS+=" -fno-ident" ;; - *darwin*) unset HOST_CFLAGS ;; -esac - -# CXXFLAGS -HOST_CXXFLAGS="$HOST_CFLAGS" - -case "$HOST" in - arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;; -esac - -# LDFLAGS -case "$HOST" in - *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -Wl,-O2" ;; - *mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;; -esac - -# EXE FLAGS -case "$HOST" in - *linux*) CMAKE_EXE_LINKER_FLAGS="-DCMAKE_EXE_LINKER_FLAGS=${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" ;; -esac - -mkdir -p "$DISTSRC" -( - cd "$DISTSRC" - - # Extract the source tarball - tar --strip-components=1 -xf "${GIT_ARCHIVE}" - - # Configure this DISTSRC for $HOST - # shellcheck disable=SC2086 - env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ - cmake -S . -B build \ - --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ - -DWITH_CCACHE=OFF \ - -Werror=dev \ - ${CONFIGFLAGS} \ - ${CMAKE_EXE_LINKER_FLAGS+"$CMAKE_EXE_LINKER_FLAGS"} - - # Build Bitcoin Core - cmake --build build -j "$JOBS" - - mkdir -p "$OUTDIR" - - # Make the os-specific installers - case "$HOST" in - *mingw*) - cmake --build build -j "$JOBS" -t deploy - mv build/bitcoin-win64-setup.exe "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" - ;; - esac - - # Setup the directory where our Bitcoin Core build for HOST will be - # installed. This directory will also later serve as the input for our - # binary tarballs. - mkdir -p "${INSTALLPATH}" - # Install built Bitcoin Core to $INSTALLPATH - case "$HOST" in - *darwin*) - cmake --install build --strip --prefix "${INSTALLPATH}" - ;; - *) - cmake --install build --prefix "${INSTALLPATH}" - ;; - esac - - # Perform basic security checks on installed executables. - echo "Checking binary security on installed executables..." - python3 "${DISTSRC}/contrib/guix/security-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* - # Check that executables only contain allowed version symbols. - echo "Running symbol and dynamic library checks on installed executables..." - python3 "${DISTSRC}/contrib/guix/symbol-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* -) # $DISTSRC - -# shellcheck source=package.sh -source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_linux.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_linux.sh new file mode 100755 index 00000000..bf3296a5 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_linux.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup gcc toolchain +gcc_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + NO_QT=1 + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +case "$HOST" in + arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;; +esac + +# LDFLAGS +HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$(glibc_dynamic_linker "$HOST") -Wl,-O2" + +# Use LINK_WARNING_AS_ERROR when using CMake 4.x +case "$HOST" in + riscv64-linux-gnu) ;; # https://github.com/boostorg/test/issues/345 + *) HOST_LDFLAGS="${HOST_LDFLAGS} -Wl,--fatal-warnings" ;; +esac + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF + + # Build Bitcoin Core + cmake --build build -j "$JOBS" + + # Install built Bitcoin Core + cmake --install build +) + +rm -rf "$DISTSRC"/build + +exit 0 diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_linux_gui.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_linux_gui.sh new file mode 100755 index 00000000..b9665c25 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_linux_gui.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup gcc toolchain +gcc_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +case "$HOST" in + arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;; +esac + +# LDFLAGS +HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$(glibc_dynamic_linker "$HOST") -Wl,-O2" + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_BITCOIN_BIN=OFF \ + -DBUILD_CLI=OFF \ + -DBUILD_DAEMON=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TX=OFF \ + -DBUILD_UTIL=OFF \ + -DBUILD_WALLET_TOOL=OFF \ + -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF \ + -Werror=dev + + # Build Bitcoin Core + cmake --build build -j "$JOBS" --target bitcoin-gui bitcoin-qt + + # Install built Bitcoin Core + cmake --install build --component bitcoin-gui + cmake --install build --component bitcoin-qt +) # $DISTSRC + +# shellcheck source=package.sh +source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_macos.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_macos.sh new file mode 100755 index 00000000..a782d80e --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_macos.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# Setup toolchain +llvm_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + ${build_LDFLAGS+build_LDFLAGS="$build_LDFLAGS"} \ + ${build_AR+build_AR="$build_AR"} \ + ${build_RANLIB+build_RANLIB="$build_RANLIB"} \ + ${build_OBJDUMP+build_OBJDUMP="$build_OBJDUMP"} \ + ${build_NM+build_NM="$build_NM"} \ + ${build_STRIP+build_STRIP="$build_STRIP"} \ + NO_QT=1 + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF + + # Build Bitcoin Core + cmake --build build -j "$JOBS" + + # Install built Bitcoin Core + cmake --install build --strip +) + +rm -rf "$DISTSRC"/build + +exit 0 diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_macos_gui.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_macos_gui.sh new file mode 100755 index 00000000..1f2dbc64 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_macos_gui.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# Setup toolchain +llvm_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + ${build_LDFLAGS+build_LDFLAGS="$build_LDFLAGS"} \ + ${build_AR+build_AR="$build_AR"} \ + ${build_RANLIB+build_RANLIB="$build_RANLIB"} \ + ${build_OBJDUMP+build_OBJDUMP="$build_OBJDUMP"} \ + ${build_NM+build_NM="$build_NM"} \ + ${build_STRIP+build_STRIP="$build_STRIP"} + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_BITCOIN_BIN=OFF \ + -DBUILD_CLI=OFF \ + -DBUILD_DAEMON=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TX=OFF \ + -DBUILD_UTIL=OFF \ + -DBUILD_WALLET_TOOL=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF \ + -Werror=dev + + # Build Bitcoin Core + cmake --build build -j "$JOBS" --target bitcoin-gui bitcoin-qt + + # Install built Bitcoin Core + cmake --install build --strip --component bitcoin-gui + cmake --install build --strip --component bitcoin-qt +) + +# shellcheck source=package.sh +source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_win.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_win.sh new file mode 100755 index 00000000..7dd6e9fc --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_win.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup mingw-w64 toolchain +mingw_w64_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + NO_QT=1 + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." +HOST_CFLAGS+=" -fno-ident" + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +# LDFLAGS +HOST_LDFLAGS="-Wl,--no-insert-timestamp -Wl,--fatal-warnings" + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF + + # Build Bitcoin Core + cmake --build build -j "$JOBS" + + # Install built Bitcoin Core + cmake --install build +) + +rm -rf "$DISTSRC"/build + +exit 0 diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_win_gui.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_win_gui.sh new file mode 100755 index 00000000..65696a2f --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/build_win_gui.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup mingw-w64 toolchain +mingw_w64_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." +HOST_CFLAGS+=" -fno-ident" + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +# LDFLAGS +HOST_LDFLAGS="-Wl,--no-insert-timestamp -Wl,--fatal-warnings" + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_BITCOIN_BIN=OFF \ + -DBUILD_CLI=OFF \ + -DBUILD_DAEMON=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TX=OFF \ + -DBUILD_UTIL=OFF \ + -DBUILD_WALLET_TOOL=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF \ + -Werror=dev + + # Build Bitcoin Core + cmake --build build -j "$JOBS" --target bitcoin-qt + + # Install built Bitcoin Core + cmake --install build --component bitcoin-qt +) + +# shellcheck source=package.sh +source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/codesign.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/codesign.sh index 9b7f085d..21f4c110 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/codesign.sh +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/codesign.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Copyright (c) 2021-present The Bitcoin Core developers +# Copyright (c) The Bitcoin 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 -set -e -o pipefail +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Environment variables for determinism export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/package.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/package.sh index 7228346a..05f5e61f 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/package.sh +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/package.sh @@ -2,12 +2,19 @@ # Copyright (c) The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit. -export LC_ALL=C -set -e -o pipefail +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail ( cd "$DISTSRC" + # Perform basic security checks on installed executables. + echo "Checking binary security on installed executables..." + python3 "${DISTSRC}/contrib/guix/security-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* + # Check that executables only contain allowed version symbols. + echo "Running symbol and dynamic library checks on installed executables..." + python3 "${DISTSRC}/contrib/guix/symbol-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* + ( cd installed @@ -32,7 +39,7 @@ set -e -o pipefail esac # copy over the example bitcoin.conf file. if contrib/devtools/gen-bitcoin-conf.sh - # has not been run before buildling, this file will be a stub + # has not been run before building, this file will be a stub cp "${DISTSRC}/share/examples/bitcoin.conf" "${DISTNAME}/" cp -r "${DISTSRC}/share/rpcauth" "${DISTNAME}/share/" @@ -79,6 +86,10 @@ set -e -o pipefail # Finally make tarballs for codesigning case "$HOST" in *mingw*) + # Make the installer + cmake -D BIN_DIR="${INSTALLPATH}/bin" -D LIBEXEC_DIR="${INSTALLPATH}/libexec" -P build/GenerateWindowsInstaller.cmake + mv build/bitcoin-win64-setup.exe "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" + cp -rf --target-directory=. contrib/windeploy ( cd ./windeploy diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/prelude.bash b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/prelude.bash index 23852767..2fe5c738 100644 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/prelude.bash +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/prelude.bash @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail source contrib/shell/realpath.bash source contrib/shell/git-utils.bash diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/setup.sh b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/setup.sh index 37388f98..2e3eb159 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/setup.sh +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/libexec/setup.sh @@ -2,8 +2,8 @@ # Copyright (c) The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit. -export LC_ALL=C -set -e -o pipefail +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Environment variables for determinism export TAR_OPTIONS="--no-same-owner --owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" @@ -61,6 +61,109 @@ store_path() { --expression='s|"[[:space:]]*$||' } +# Sanity check CROSS_*_PATH directories +check_cross_paths() { + local p paths + IFS=':' read -ra paths <<< "$1" + for p in "${paths[@]}"; do + if [ -n "$p" ] && [ ! -d "$p" ]; then + echo "'$p' doesn't exist or isn't a directory... Aborting..." >&2 + return 1 + fi + done +} + +# Given a hostname, determine the correct value for -Wl,--dynamic-linker. +glibc_dynamic_linker() { + case "$1" in + x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; + arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; + aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; + riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; + powerpc64-linux-gnu) echo /lib64/ld64.so.1 ;; + powerpc64le-linux-gnu) echo /lib64/ld64.so.2 ;; + *) exit 1 ;; + esac +} + +gcc_toolchain() { + # Set environment variables to point the NATIVE toolchain to the right + # includes/libs + local NATIVE_GCC NATIVE_GCC_STATIC CROSS_GLIBC CROSS_GLIBC_STATIC CROSS_KERNEL CROSS_GCC CROSS_GCC_LIB_STORE CROSS_GCC_LIBS CROSS_GCC_LIB + + NATIVE_GCC="$(store_path gcc-toolchain)" + + # Set native toolchain + export build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" + export build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" + + NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)" + export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib" + + # Set environment variables to point the CROSS toolchain to the right + # includes/libs for $HOST + CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")" + CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)" + CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" + CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" + + check_cross_paths "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" +} + +llvm_toolchain() { + local CLANG_TOOLCHAIN LIB_CXX + + CLANG_TOOLCHAIN="$(store_path clang-toolchain)" + LIB_CXX="$(store_path libcxx)" + + export build_CC="${CLANG_TOOLCHAIN}/bin/clang -isystem ${CLANG_TOOLCHAIN}/include" + export build_CXX="${CLANG_TOOLCHAIN}/bin/clang++ -stdlib=libc++ -isystem ${LIB_CXX}/include/c++/v1 -isystem ${CLANG_TOOLCHAIN}/include" + export build_LDFLAGS="-fuse-ld=lld -rtlib=compiler-rt -unwindlib=libunwind -L${LIB_CXX}/lib -Wl,-rpath,${LIB_CXX}/lib" + export build_AR="${CLANG_TOOLCHAIN}/bin/llvm-ar" + export build_RANLIB="${CLANG_TOOLCHAIN}/bin/llvm-ranlib" + export build_OBJDUMP="${CLANG_TOOLCHAIN}/bin/llvm-objdump" + export build_NM="${CLANG_TOOLCHAIN}/bin/llvm-nm" + export build_STRIP="${CLANG_TOOLCHAIN}/bin/llvm-strip" +} + +mingw_w64_toolchain() { + # Set environment variables to point the NATIVE toolchain to the right + # includes/libs + local NATIVE_GCC CROSS_GLIBC CROSS_GCC CROSS_GCC_LIB_STORE CROSS_GCC_LIBS CROSS_GCC_LIB + + NATIVE_GCC="$(store_path gcc-toolchain)" + + # Set native toolchain + export build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" + export build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" + + # Set environment variables to point the CROSS toolchain to the right + # includes/libs for $HOST + # Determine output paths to use in CROSS_* environment variables + CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" + CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + # The search path ordering is generally: + # 1. gcc-related search paths + # 2. libc-related search paths + # 2. kernel-header-related search paths (not applicable to mingw-w64 hosts) + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" + + check_cross_paths "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" +} + # Disable Guix ld auto-rpath behavior export GUIX_LD_WRAPPER_DISABLE_RPATH=yes diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/manifest_build.scm b/libbitcoinkernel-sys/bitcoin/contrib/guix/manifest_build.scm index 576021e6..8e8df90a 100644 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/manifest_build.scm +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/manifest_build.scm @@ -1,26 +1,18 @@ (use-modules (gnu packages) ((gnu packages bash) #:select (bash-minimal)) - (gnu packages bison) ((gnu packages cmake) #:select (cmake-minimal)) (gnu packages commencement) - ((gnu packages compression) #:select (gzip xz zip)) + ((gnu packages compression) #:select (gzip)) (gnu packages cross-base) - (gnu packages gawk) (gnu packages gcc) - ((gnu packages installers) #:select (nsis-x86_64)) ((gnu packages linux) #:select (linux-libre-headers-6.1)) (gnu packages llvm) (gnu packages mingw) - (gnu packages ninja) - (gnu packages pkg-config) - ((gnu packages python) #:select (python-minimal)) - ((gnu packages python-xyz) #:select (python-lief)) ((gnu packages version-control) #:select (git-minimal)) (guix build-system trivial) (guix download) (guix gexp) (guix git-download) - ((guix licenses) #:prefix license:) (guix packages) ((guix utils) #:select (substitute-keyword-arguments))) @@ -171,14 +163,18 @@ chain for " target " development.")) (arguments (substitute-keyword-arguments (package-arguments base-gcc) ((#:configure-flags flags) - `(append ,flags + #~(append #$flags ;; https://gcc.gnu.org/install/configure.html - (list "--enable-threads=posix", - "--enable-default-ssp=yes", - "--enable-host-bind-now=yes", - "--disable-gcov", - "--disable-libgomp", - building-on))))))) + (list "--enable-default-ssp=yes" + "--enable-gprofng=no" + "--enable-host-bind-now=yes" + "--enable-threads=posix" + "--disable-gcov" + "--disable-libgomp" + "--disable-libsanitizer" + "--disable-lto" + "--disable-nls" + #$building-on))))))) (define-public linux-base-gcc (package @@ -186,22 +182,25 @@ chain for " target " development.")) (arguments (substitute-keyword-arguments (package-arguments base-gcc) ((#:configure-flags flags) - `(append ,flags + #~(append #$flags ;; https://gcc.gnu.org/install/configure.html - (list "--enable-initfini-array=yes", - "--enable-default-ssp=yes", - "--enable-default-pie=yes", - "--enable-host-bind-now=yes", - "--enable-standard-branch-protection=yes", - "--enable-cet=yes", - "--enable-gprofng=no", - "--disable-gcov", - "--disable-libgomp", - "--disable-libquadmath", - "--disable-libsanitizer", - building-on))) + (list "--enable-cet=yes" + "--enable-default-ssp=yes" + "--enable-default-pie=yes" + "--enable-gprofng=no" + "--enable-host-bind-now=yes" + "--enable-initfini-array=yes" + "--enable-standard-branch-protection=yes" + "--disable-gcov" + "--disable-libgomp" + "--disable-libquadmath" + "--disable-libsanitizer" + "--disable-lto" + "--disable-nls" + "--disable-tm-clone-registry" + #$building-on))) ((#:phases phases) - `(modify-phases ,phases + #~(modify-phases #$phases ;; Given a XGCC package, return a modified package that replace each instance of ;; -rpath in the default system spec that's inserted by Guix with -rpath-link (add-after 'pre-configure 'replace-rpath-with-rpath-link @@ -215,7 +214,7 @@ chain for " target " development.")) (define-public glibc-2.31 (let ((commit "28eb5caf895ced5d895cb02757e109004a2d33e5")) (package - (inherit glibc) ;; 2.39 + (inherit glibc) ;; 2.41 (version "2.31") (source (origin (method git-fetch) @@ -233,12 +232,13 @@ chain for " target " development.")) ((#:configure-flags flags) `(append ,flags ;; https://www.gnu.org/software/libc/manual/html_node/Configuring-and-compiling.html - (list "--enable-stack-protector=all", + (list "--enable-bind-now", "--enable-cet", - "--enable-bind-now", - "--disable-werror", - "--disable-timezone-tools", + "--enable-kernel=3.17.0", + "--enable-stack-protector=all", "--disable-profile", + "--disable-timezone-tools", + "--disable-werror", building-on))) ((#:phases phases) `(modify-phases ,phases @@ -262,40 +262,28 @@ chain for " target " development.")) coreutils-minimal ;; File(system) inspection grep - diffutils findutils ;; File transformation patch - gawk sed ;; Compression and archiving tar gzip - xz ;; Build tools - gcc-toolchain-14 cmake-minimal gnu-make - ninja - ;; Scripting - python-minimal ;; (3.11) ;; Git - git-minimal - ;; Tests - python-lief) + git-minimal) (let ((target (getenv "HOST"))) (cond ((string-suffix? "-mingw32" target) - (list (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32") - nsis-x86_64 - zip)) + (list gcc-toolchain-14 + (make-mingw-pthreads-cross-toolchain target))) ((string-contains target "-linux-") - (list bison - pkg-config + (list gcc-toolchain-14 (list gcc-toolchain-14 "static") (make-bitcoin-cross-toolchain target))) ((string-contains target "darwin") (list clang-toolchain-19 - lld-19 - (make-lld-wrapper lld-19 #:lld-as-ld? #t) - zip)) + libcxx ;; 19.1.7 + lld-19)) (else '()))))) diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/manifest_gui.scm b/libbitcoinkernel-sys/bitcoin/contrib/guix/manifest_gui.scm new file mode 100644 index 00000000..1754af90 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/manifest_gui.scm @@ -0,0 +1,30 @@ +(use-modules (gnu packages bison) + ((gnu packages compression) #:select (xz zip)) + (gnu packages gawk) + ((gnu packages installers) #:select (nsis-x86_64)) + (gnu packages ninja) + (gnu packages pkg-config) + ((gnu packages python) #:select (python-minimal)) + ((gnu packages python-xyz) #:select (python-lief))) + +(packages->manifest + (append + (list ;; Compression and archiving + xz + ;; Build tools + ninja + ;; Packaging scripts + python-minimal ;; (3.11) + ;; Tests + python-lief) + (let ((target (getenv "HOST"))) + (cond ((string-suffix? "-mingw32" target) + (list zip + nsis-x86_64)) + ((string-contains target "-linux-") + (list bison + gawk + pkg-config)) + ((string-contains target "darwin") + (list zip)) + (else '()))))) diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/security-check.py b/libbitcoinkernel-sys/bitcoin/contrib/guix/security-check.py index 2a6e26b6..87aafcb9 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/security-check.py +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/security-check.py @@ -280,8 +280,8 @@ def check_MACHO_BRANCH_PROTECTION(binary) -> bool: for filename in sys.argv[1:]: binary = lief.parse(filename) - etype = binary.format - arch = binary.abstract.header.architecture + etype = binary.format # type: ignore[union-attr] + arch = binary.abstract.header.architecture # type: ignore[union-attr] failed: list[str] = [] for (name, func) in CHECKS[etype][arch]: diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/symbol-check.py b/libbitcoinkernel-sys/bitcoin/contrib/guix/symbol-check.py index 86b79652..b1f326d3 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/symbol-check.py +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/symbol-check.py @@ -72,17 +72,17 @@ ELF_ABIS: dict[lief.ELF.ARCH, dict[lief.Header.ENDIANNESS, list[int]]] = { lief.ELF.ARCH.X86_64: { - lief.Header.ENDIANNESS.LITTLE: [3,2,0], + lief.Header.ENDIANNESS.LITTLE: [3,17,0], }, lief.ELF.ARCH.ARM: { - lief.Header.ENDIANNESS.LITTLE: [3,2,0], + lief.Header.ENDIANNESS.LITTLE: [3,17,0], }, lief.ELF.ARCH.AARCH64: { - lief.Header.ENDIANNESS.LITTLE: [3,7,0], + lief.Header.ENDIANNESS.LITTLE: [3,17,0], }, lief.ELF.ARCH.PPC64: { - lief.Header.ENDIANNESS.LITTLE: [3,10,0], - lief.Header.ENDIANNESS.BIG: [3,2,0], + lief.Header.ENDIANNESS.LITTLE: [3,17,0], + lief.Header.ENDIANNESS.BIG: [3,17,0], }, lief.ELF.ARCH.RISCV: { lief.Header.ENDIANNESS.LITTLE: [4,15,0], @@ -306,7 +306,7 @@ def check_ELF_ABI(binary) -> bool: for filename in sys.argv[1:]: binary = lief.parse(filename) - etype = binary.format + etype = binary.format # type: ignore[union-attr] failed: list[str] = [] for (name, func) in CHECKS[etype]: diff --git a/libbitcoinkernel-sys/bitcoin/contrib/init/bitcoind.openrc b/libbitcoinkernel-sys/bitcoin/contrib/init/bitcoind.openrc index 30e7be36..ae9dbf46 100644 --- a/libbitcoinkernel-sys/bitcoin/contrib/init/bitcoind.openrc +++ b/libbitcoinkernel-sys/bitcoin/contrib/init/bitcoind.openrc @@ -21,7 +21,7 @@ BITCOIND_OPTS="${BITCOIND_OPTS:-${BITCOIN_OPTS}}" name="Bitcoin Core Daemon" description="Bitcoin cryptocurrency P2P network daemon" -command="/usr/bin/bitcoind" +command="${BITCOIND_BIN}" command_args="-pid=\"${BITCOIND_PIDFILE}\" \ -conf=\"${BITCOIND_CONFIGFILE}\" \ -datadir=\"${BITCOIND_DATADIR}\" \ @@ -30,6 +30,7 @@ command_args="-pid=\"${BITCOIND_PIDFILE}\" \ required_files="${BITCOIND_CONFIGFILE}" start_stop_daemon_args="-u ${BITCOIND_USER} \ + -g ${BITCOIND_GROUP} \ -N ${BITCOIND_NICE} -w 2000" pidfile="${BITCOIND_PIDFILE}" diff --git a/libbitcoinkernel-sys/bitcoin/contrib/seeds/generate-seeds.py b/libbitcoinkernel-sys/bitcoin/contrib/seeds/generate-seeds.py index 2dfad0c7..ff2b4028 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/seeds/generate-seeds.py +++ b/libbitcoinkernel-sys/bitcoin/contrib/seeds/generate-seeds.py @@ -22,9 +22,9 @@ The output will be several data structures with the peers in binary format: - static const uint8_t chainparams_seed_{main,signet,test,testnet4}[]={ - ... - } + inline constexpr uint8_t chainparams_seed_{main,signet,test,testnet4}[]{ + ... + }; These should be pasted into `src/chainparamsseeds.h`. ''' @@ -137,7 +137,7 @@ def bip155_serialize(spec): return r def process_nodes(g, f, structname): - g.write('static const uint8_t %s[] = {\n' % structname) + g.write("inline constexpr uint8_t %s[]{\n" % structname) for line in f: comment = line.find('#') if comment != -1: diff --git a/libbitcoinkernel-sys/bitcoin/contrib/verify-commits/verify-commits.py b/libbitcoinkernel-sys/bitcoin/contrib/verify-commits/verify-commits.py index b053fbd1..12c01019 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/verify-commits/verify-commits.py +++ b/libbitcoinkernel-sys/bitcoin/contrib/verify-commits/verify-commits.py @@ -14,6 +14,23 @@ GIT = os.getenv('GIT', 'git') +def is_ancestor(older, newer, root_name): + """Return whether older is an ancestor of newer, rejecting Git errors.""" + result = subprocess.run([GIT, "merge-base", "--is-ancestor", older, newer]) + if result.returncode not in (0, 1): + print(f'Failed to determine ancestry between "{older}" and "{newer}" for the {root_name} (git merge-base exited with {result.returncode}).', file=sys.stderr) + sys.exit(1) + return result.returncode == 0 + +def predates(commit, root, root_name): + """Return whether commit is provably older than root, rejecting divergent history.""" + if is_ancestor(root, commit, root_name): + return False + elif is_ancestor(commit, root, root_name): + return True + print(f'"{commit}" diverges from the {root_name} "{root}", refusing to verify.', file=sys.stderr) + sys.exit(1) + def tree_sha512sum(commit='HEAD'): """Calculate the Tree-sha512 for the commit. @@ -107,27 +124,23 @@ def main(): logging.debug("verify-commits: [in-progress] processing commit {}".format(current_commit[:8])) if current_commit == verified_root: + # Ensure the trusted root identifies an existing commit. + is_ancestor(verified_root, current_commit, "trusted Git root") print('There is a valid path from "{}" to {} where all commits are signed!'.format(initial_commit, verified_root)) sys.exit(0) - else: - # Make sure this commit isn't older than trusted roots - check_root_older_res = subprocess.run([GIT, "merge-base", "--is-ancestor", verified_root, current_commit]) - if check_root_older_res.returncode != 0: - print(f"\"{current_commit}\" predates the trusted root, stopping!") - sys.exit(0) + elif predates(current_commit, verified_root, "trusted Git root"): + print(f"\"{current_commit}\" predates the trusted root, stopping!") + sys.exit(0) if verify_tree: if current_commit == verified_sha512_root: print("All Tree-SHA512s matched up to {}".format(verified_sha512_root), file=sys.stderr) verify_tree = False no_sha1 = False - else: - # Skip the tree check if we are older than the trusted root - check_root_older_res = subprocess.run([GIT, "merge-base", "--is-ancestor", verified_sha512_root, current_commit]) - if check_root_older_res.returncode != 0: - print(f"\"{current_commit}\" predates the trusted SHA512 root, disabling tree verification.") - verify_tree = False - no_sha1 = False + elif predates(current_commit, verified_sha512_root, "trusted Tree-SHA512 root"): + print(f"\"{current_commit}\" predates the trusted SHA512 root, disabling tree verification.") + verify_tree = False + no_sha1 = False os.environ['BITCOIN_VERIFY_COMMITS_ALLOW_SHA1'] = "0" if no_sha1 else "1" diff --git a/libbitcoinkernel-sys/bitcoin/depends/README.md b/libbitcoinkernel-sys/bitcoin/depends/README.md index 83ebf8e2..9018fc12 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/README.md +++ b/libbitcoinkernel-sys/bitcoin/depends/README.md @@ -125,7 +125,7 @@ without gcc/g++), you could use the following to build all packages using clang: ## Cross compilation -To build for another arch/OS: +To build for another arch+OS: make HOST=host-platform-triplet @@ -135,18 +135,18 @@ For example: Common `host-platform-triplet`s for cross compilation are: -- `i686-pc-linux-gnu` for Linux x86 32 bit -- `x86_64-pc-linux-gnu` for Linux x86 64 bit +- `i686-linux-gnu` for Linux x86 32-bit +- `x86_64-linux-gnu` for Linux x86 64-bit - `x86_64-w64-mingw32` for Windows using MSVCRT - `x86_64-w64-mingw32ucrt` for Windows using UCRT - `x86_64-apple-darwin` for Intel macOS - `arm64-apple-darwin` for ARM macOS -- `arm-linux-gnueabihf` for Linux ARM 32 bit -- `aarch64-linux-gnu` for Linux ARM 64 bit -- `powerpc64-linux-gnu` for Linux POWER 64 bit (big endian) -- `powerpc64le-linux-gnu` for Linux POWER 64 bit (little endian) -- `riscv32-linux-gnu` for Linux RISC-V 32 bit -- `riscv64-linux-gnu` for Linux RISC-V 64 bit +- `arm-linux-gnueabihf` for Linux ARM 32-bit +- `aarch64-linux-gnu` for Linux ARM 64-bit +- `powerpc64-linux-gnu` for Linux POWER 64-bit (big endian) +- `powerpc64le-linux-gnu` for Linux POWER 64-bit (little endian) +- `riscv32-linux-gnu` for Linux RISC-V 32-bit +- `riscv64-linux-gnu` for Linux RISC-V 64-bit - `s390x-linux-gnu` for Linux S390X The paths are automatically configured and no other options are needed. @@ -160,37 +160,52 @@ proceeding with a cross-compile. Under the depends directory, create a subdirectory named `SDKs`. Then, place the extracted SDK under this new directory. For more information, see [SDK Extraction](../contrib/macdeploy/README.md#sdk-extraction). -#### For Windows cross compilation using MSVCRT +#### For Windows cross compilation + +Using MSVCRT: apt install g++-mingw-w64-x86-64-posix -#### For Windows cross compilation using UCRT +Using UCRT: apt install g++-mingw-w64-ucrt64 -#### For linux (including i386, ARM) cross compilation +Some Ubuntu or Debian versions may not offer a working package. In this case, +you may install `nix-bin` and use the Nix shell from the repository root: + + apt install nix-bin + NIX_BUILD_SHELL=bash HOST=x86_64-w64-mingw32 nix-shell contrib/devtools/shell-win64-cross.nix # MSVCRT + NIX_BUILD_SHELL=bash HOST=x86_64-w64-mingw32ucrt nix-shell contrib/devtools/shell-win64-cross.nix # UCRT + +#### For Linux cross compilation + +Please note that package availability might depend on the arch+OS you are building on. + +For Linux x86 32-bit cross compilation: + + sudo apt-get install g++-i686-linux-gnu binutils-i686-linux-gnu -Common linux dependencies: +For Linux x86 64-bit cross compilation: - sudo apt-get install g++-multilib binutils + sudo apt-get install g++-x86-64-linux-gnu binutils-x86-64-linux-gnu -For linux ARM cross compilation: +For Linux ARM 32-bit cross compilation: sudo apt-get install g++-arm-linux-gnueabihf binutils-arm-linux-gnueabihf -For linux AARCH64 cross compilation: +For Linux ARM 64-bit cross compilation: sudo apt-get install g++-aarch64-linux-gnu binutils-aarch64-linux-gnu -For linux POWER 64-bit cross compilation (there are no packages for 32-bit): +For Linux POWER 64-bit cross compilation (there are no packages for 32-bit): sudo apt-get install g++-powerpc64-linux-gnu binutils-powerpc64-linux-gnu g++-powerpc64le-linux-gnu binutils-powerpc64le-linux-gnu -For linux RISC-V 64-bit cross compilation (there are no packages for 32-bit): +For Linux RISC-V 64-bit cross compilation (there are no packages for 32-bit): sudo apt-get install g++-riscv64-linux-gnu binutils-riscv64-linux-gnu -For linux S390X cross compilation: +For Linux S390X cross compilation: sudo apt-get install g++-s390x-linux-gnu binutils-s390x-linux-gnu diff --git a/libbitcoinkernel-sys/bitcoin/depends/funcs.mk b/libbitcoinkernel-sys/bitcoin/depends/funcs.mk index f6221ef1..11b6337d 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/funcs.mk +++ b/libbitcoinkernel-sys/bitcoin/depends/funcs.mk @@ -47,7 +47,11 @@ endef define fetch_local_dir_sha256 if ! [ -f $($(1)_source) ] || [ -n "$$(find $($(1)_local_dir) -newer $($(1)_source) | head -n1)" ]; then \ mkdir -p $(dir $($(1)_source)) && \ - $(build_TAR) -c -f $($(1)_source) -C $($(1)_local_dir) . && \ + ( \ + cd $($(1)_local_dir) && \ + find . -print0 | TZ=UTC xargs -0r $(build_TOUCH) && \ + find . | LC_ALL=C sort | $(build_TAR) --no-recursion -c -f $($(1)_source) -T - \ + ) && \ rm -f $($(1)_fetched); \ fi && \ if ! [ -f $($(1)_fetched) ] || [ -n "$$(find $($(1)_source) -newer $($(1)_fetched))" ]; then \ @@ -60,7 +64,7 @@ endef define int_get_build_recipe_hash $(eval $(1)_patches_path?=$(PATCHES_PATH)/$(1)) -$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $($(1)_patches_path)/,$($(1)_patches)) | cut -d" " -f1)) +$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $$(grep "^include " packages/$(1).mk | cut -d' ' -f2 | xargs) $(addprefix $($(1)_patches_path)/,$($(1)_patches)) | cut -d" " -f1)) # If $(1)_local_dir is set, create a tarball of the local directory contents to # use as the source of the package, and include a hash of the tarball in the # package id, so if directory contents change, the package and packages diff --git a/libbitcoinkernel-sys/bitcoin/depends/hosts/linux.mk b/libbitcoinkernel-sys/bitcoin/depends/hosts/linux.mk index 41958f99..be899507 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/hosts/linux.mk +++ b/libbitcoinkernel-sys/bitcoin/depends/hosts/linux.mk @@ -19,27 +19,6 @@ linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC # https://libcxx.llvm.org/Hardening.html linux_debug_CPPFLAGS+=-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG -ifeq (86,$(findstring 86,$(build_arch))) -i686_linux_CC=gcc -m32 -i686_linux_CXX=g++ -m32 -i686_linux_AR=ar -i686_linux_RANLIB=ranlib -i686_linux_NM=nm -i686_linux_STRIP=strip - -x86_64_linux_CC=gcc -m64 -x86_64_linux_CXX=g++ -m64 -x86_64_linux_AR=ar -x86_64_linux_RANLIB=ranlib -x86_64_linux_NM=nm -x86_64_linux_STRIP=strip -else -i686_linux_CC=$(default_host_CC) -m32 -i686_linux_CXX=$(default_host_CXX) -m32 -x86_64_linux_CC=$(default_host_CC) -m64 -x86_64_linux_CXX=$(default_host_CXX) -m64 -endif - linux_cmake_system_name=Linux # Refer to doc/dependencies.md for the minimum required kernel. linux_cmake_system_version=3.17.0 diff --git a/libbitcoinkernel-sys/bitcoin/depends/packages/native_qt.mk b/libbitcoinkernel-sys/bitcoin/depends/packages/native_qt.mk index 2bf088c1..913d0fc4 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/packages/native_qt.mk +++ b/libbitcoinkernel-sys/bitcoin/depends/packages/native_qt.mk @@ -10,6 +10,7 @@ $(package)_patches += qtbase_skip_tools.patch $(package)_patches += rcc_hardcode_timestamp.patch $(package)_patches += qttools_skip_dependencies.patch $(package)_patches += fix-macos26-qyield.patch +$(package)_patches += fix_missed_headers.patch $(package)_qttranslations_file_name=$(qt_details_qttranslations_file_name) $(package)_qttranslations_sha256_hash=$(qt_details_qttranslations_sha256_hash) @@ -94,6 +95,7 @@ $(package)_config_env += OBJCXX="$$(build_CXX)" endif $(package)_cmake_opts := -DCMAKE_EXE_LINKER_FLAGS="$$(build_LDFLAGS)" +$(package)_cmake_opts += -DCMAKE_AR="$$(build_AR)" ifneq ($(V),) $(package)_cmake_opts += --log-level=STATUS endif @@ -139,7 +141,8 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/qtbase_skip_tools.patch && \ patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \ patch -p1 -i $($(package)_patch_dir)/qttools_skip_dependencies.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix-macos26-qyield.patch + patch -p1 -i $($(package)_patch_dir)/fix-macos26-qyield.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_missed_headers.patch endef define $(package)_config_cmds diff --git a/libbitcoinkernel-sys/bitcoin/depends/packages/qt.mk b/libbitcoinkernel-sys/bitcoin/depends/packages/qt.mk index 500a2729..cd4c3cc7 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/packages/qt.mk +++ b/libbitcoinkernel-sys/bitcoin/depends/packages/qt.mk @@ -14,7 +14,6 @@ $(package)_patches_path := $(qt_details_patches_path) $(package)_patches := cocoa_compat.patch $(package)_patches += dont_hardcode_pwd.patch $(package)_patches += qtbase_avoid_qmain.patch -$(package)_patches += qtbase_platformsupport.patch $(package)_patches += qtbase_plugins_cocoa.patch $(package)_patches += qtbase_skip_tools.patch $(package)_patches += rcc_hardcode_timestamp.patch @@ -29,6 +28,7 @@ $(package)_patches += fix-macos26-qyield.patch $(package)_patches += fix-qbytearray-include.patch $(package)_patches += fix_openbsd_network_kernel.patch $(package)_patches += fix_openbsd_plugin_qelfparser.patch +$(package)_patches += fix_missed_headers.patch $(package)_qttranslations_file_name=$(qt_details_qttranslations_file_name) $(package)_qttranslations_sha256_hash=$(qt_details_qttranslations_sha256_hash) @@ -181,7 +181,11 @@ $(package)_cmake_opts += --log-level=STATUS endif $(package)_cmake_opts += -DQT_USE_DEFAULT_CMAKE_OPTIMIZATION_FLAGS=ON -$(package)_cmake_opts += -DCMAKE_C_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" +# The bundled libpng 1.6.49 in Qt 6.8.4 introduced support for +# the RISC-V Vector Extension (RVV). However, the resulting library +# fails to link when cross-compiling for riscv64-linux-gnu. +# Disable this feature for now. +$(package)_cmake_opts += -DCMAKE_C_FLAGS="$$($(package)_cppflags) -DPNG_RISCV_RVV_OPT=0 $$($$($(package)_type)_CFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" $(package)_cmake_opts += -DCMAKE_C_FLAGS_RELEASE="$$($$($(package)_type)_release_CFLAGS)" $(package)_cmake_opts += -DCMAKE_C_FLAGS_DEBUG="$$($$($(package)_type)_debug_CFLAGS)" $(package)_cmake_opts += -DCMAKE_CXX_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CXXFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" @@ -198,6 +202,7 @@ endif $(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS="$$($$($(package)_type)_LDFLAGS)" $(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS_RELEASE="$$($$($(package)_type)_release_LDFLAGS)" $(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS_DEBUG="$$($$($(package)_type)_debug_LDFLAGS)" +$(package)_cmake_opts += -DCMAKE_AR="$$($(package)_ar)" ifneq ($(host),$(build)) $(package)_cmake_opts += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system_name) @@ -277,7 +282,6 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/cocoa_compat.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase_avoid_qmain.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase_platformsupport.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase_plugins_cocoa.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase_skip_tools.patch && \ patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \ @@ -290,7 +294,8 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix-macos26-qyield.patch && \ patch -p1 -i $($(package)_patch_dir)/fix-qbytearray-include.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_openbsd_network_kernel.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_openbsd_plugin_qelfparser.patch + patch -p1 -i $($(package)_patch_dir)/fix_openbsd_plugin_qelfparser.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_missed_headers.patch endef ifeq ($(host),$(build)) $(package)_preprocess_cmds += && patch -p1 -i $($(package)_patch_dir)/qttools_skip_dependencies.patch diff --git a/libbitcoinkernel-sys/bitcoin/depends/packages/qt_details.mk b/libbitcoinkernel-sys/bitcoin/depends/packages/qt_details.mk index e49ac6a2..1808f342 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/packages/qt_details.mk +++ b/libbitcoinkernel-sys/bitcoin/depends/packages/qt_details.mk @@ -1,19 +1,19 @@ -qt_details_version := 6.8.3 +qt_details_version := 6.8.4 qt_details_download_path := https://download.qt.io/archive/qt/6.8/$(qt_details_version)/submodules -qt_details_suffix := everywhere-src-$(qt_details_version).tar.xz +qt_details_suffix := everywhere-opensource-src-$(qt_details_version).tar.xz qt_details_qtbase_file_name := qtbase-$(qt_details_suffix) -qt_details_qtbase_sha256_hash := 56001b905601bb9023d399f3ba780d7fa940f3e4861e496a7c490331f49e0b80 +qt_details_qtbase_sha256_hash := 532dfbf3fa3cbc68fa37441ea9e81c5009da044eaecda78ffaeafd8bd125532f qt_details_qttranslations_file_name := qttranslations-$(qt_details_suffix) -qt_details_qttranslations_sha256_hash := c3c61d79c3d8fe316a20b3617c64673ce5b5519b2e45535f49bee313152fa531 +qt_details_qttranslations_sha256_hash := 33b1fd1d75598cbf54da12263957f18292c9fb01e42fcc3ab9bd2f8ac79763b7 qt_details_qttools_file_name := qttools-$(qt_details_suffix) -qt_details_qttools_sha256_hash := 02a4e219248b94f1333df843d25763f35251c1074cdc4fb5bda67d340f8c8b3a +qt_details_qttools_sha256_hash := c6030ea66d7be1ca7e3b40578beb35b0f4ff4014277d8e051d3219759f6ab399 qt_details_patches_path := $(PATCHES_PATH)/qt -qt_details_top_download_path := https://raw.githubusercontent.com/qt/qt5/refs/heads/$(qt_details_version) +qt_details_top_download_path := https://raw.githubusercontent.com/qt/qt5/refs/tags/v$(qt_details_version)-lts-lgpl qt_details_top_cmakelists_file_name := CMakeLists.txt qt_details_top_cmakelists_download_file := $(qt_details_top_cmakelists_file_name) qt_details_top_cmakelists_sha256_hash := 54e9a4e554da37792446dda4f52bc308407b01a34bcc3afbad58e4e0f71fac9b diff --git a/libbitcoinkernel-sys/bitcoin/depends/packages/zeromq.mk b/libbitcoinkernel-sys/bitcoin/depends/packages/zeromq.mk index 8bf84b1f..ab10e6c2 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/packages/zeromq.mk +++ b/libbitcoinkernel-sys/bitcoin/depends/packages/zeromq.mk @@ -11,6 +11,7 @@ $(package)_patches += openbsd_kqueue_headers.patch $(package)_patches += cmake_minimum.patch $(package)_patches += cacheline_undefined.patch $(package)_patches += no_librt.patch +$(package)_patches += add_new_include.patch define $(package)_set_vars $(package)_config_opts := -DCMAKE_BUILD_TYPE=None -DWITH_DOCS=OFF -DWITH_LIBSODIUM=OFF @@ -28,7 +29,8 @@ define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/fix_have_windows.patch && \ patch -p1 < $($(package)_patch_dir)/openbsd_kqueue_headers.patch && \ patch -p1 < $($(package)_patch_dir)/cmake_minimum.patch && \ - patch -p1 < $($(package)_patch_dir)/no_librt.patch + patch -p1 < $($(package)_patch_dir)/no_librt.patch && \ + patch -p1 < $($(package)_patch_dir)/add_new_include.patch endef define $(package)_config_cmds diff --git a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-qcompare.patch b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-qcompare.patch index e56f610a..c2c1100a 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-qcompare.patch +++ b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-qcompare.patch @@ -105,7 +105,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 namespace Qt { class weak_ordering; -@@ -157,12 +183,18 @@ public: +@@ -156,12 +182,18 @@ public: constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept { static_assert(sizeof(*this) == sizeof(std::partial_ordering)); @@ -127,7 +127,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 switch (m_order) { case qToUnderlying(O::Less): return R::less; case qToUnderlying(O::Greater): return R::greater; -@@ -170,7 +202,6 @@ public: +@@ -169,7 +201,6 @@ public: case qToUnderlying(U::Unordered): return R::unordered; } Q_UNREACHABLE_RETURN(R::unordered); @@ -135,7 +135,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 } friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept -@@ -349,18 +380,18 @@ public: +@@ -347,18 +378,18 @@ public: constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept { static_assert(sizeof(*this) == sizeof(std::weak_ordering)); @@ -158,7 +158,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 } friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept -@@ -547,18 +578,18 @@ public: +@@ -542,18 +573,18 @@ public: constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept { static_assert(sizeof(*this) == sizeof(std::strong_ordering)); @@ -181,7 +181,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 } friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept -@@ -625,6 +656,8 @@ inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::G +@@ -620,6 +651,8 @@ inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::G } // namespace Qt diff --git a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch index 11c27949..42f13ebb 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch +++ b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch @@ -19,7 +19,7 @@ diff --git a/qtbase/src/corelib/text/qanystringview.cpp b/qtbase/src/corelib/tex index 7bf8a3fa1fd..3c993ff1da0 100644 --- a/qtbase/src/corelib/text/qanystringview.cpp +++ b/qtbase/src/corelib/text/qanystringview.cpp -@@ -243,6 +243,10 @@ QT_BEGIN_NAMESPACE +@@ -355,6 +355,10 @@ QT_BEGIN_NAMESPACE \sa isNull(), isEmpty() */ diff --git a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-sfinae-qchar.patch b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-sfinae-qchar.patch index 888e128c..e8afea81 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-sfinae-qchar.patch +++ b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix-gcc16-sfinae-qchar.patch @@ -37,7 +37,7 @@ diff --git a/qtbase/src/corelib/kernel/qmetatype.cpp b/qtbase/src/corelib/kernel index e70583404a46..54a0fe671fe0 100644 --- a/qtbase/src/corelib/kernel/qmetatype.cpp +++ b/qtbase/src/corelib/kernel/qmetatype.cpp -@@ -1212,7 +1212,7 @@ QT_WARNING_DISABLE_CLANG("-Wtautological-compare") +@@ -1230,7 +1230,7 @@ QT_WARNING_DISABLE_CLANG("-Wtautological-compare") return true; ); QMETATYPE_CONVERTER(QString, Char32, diff --git a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix_missed_headers.patch b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix_missed_headers.patch new file mode 100644 index 00000000..1fda902c --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/fix_missed_headers.patch @@ -0,0 +1,32 @@ +QXcbAtom: add missing #include + +Clang 21 complained about free() being an undefined identifier. + +See: https://codereview.qt-project.org/c/qt/qtbase/+/686891 + +--- a/qtbase/src/plugins/platforms/xcb/qxcbatom.cpp ++++ b/qtbase/src/plugins/platforms/xcb/qxcbatom.cpp +@@ -7,6 +7,7 @@ + #include + + #include ++#include + + static const char *xcb_atomnames = { + // window-manager <-> client protocols + + +syncqt.cpp: Include for std::transform + +See: https://codereview.qt-project.org/c/qt/qtbase/+/673183 + +--- a/qtbase/src/tools/syncqt/main.cpp ++++ b/qtbase/src/tools/syncqt/main.cpp +@@ -15,6 +15,7 @@ + * pre-defined list of header files. + */ + ++#include + #include + #include + #include diff --git a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_platformsupport.patch b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_platformsupport.patch deleted file mode 100644 index 45ccaea5..00000000 --- a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_platformsupport.patch +++ /dev/null @@ -1,34 +0,0 @@ -CMake: Prevent creation of empty InputSupportPrivate module - -The combination of - -no-feature-evdev - -no-feature-tslib - -no-feature-libinput -led to the creation of the InputSupportPrivate module without source -files. - -This triggered CMake upstream issue 23464 when using CMake < 3.25. - -Fix this by adjusting the inexact condition that decides whether to -build InputSupportPrivate. - - -See: https://codereview.qt-project.org/c/qt/qtbase/+/633612 - - ---- a/qtbase/src/platformsupport/CMakeLists.txt -+++ b/qtbase/src/platformsupport/CMakeLists.txt -@@ -3,7 +3,12 @@ - - add_subdirectory(devicediscovery) - add_subdirectory(fbconvenience) --if(QT_FEATURE_evdev OR QT_FEATURE_integrityhid OR QT_FEATURE_libinput OR QT_FEATURE_tslib OR QT_FEATURE_xkbcommon) -+if(QT_FEATURE_evdev -+ OR QT_FEATURE_vxworksevdev -+ OR QT_FEATURE_integrityhid -+ OR QT_FEATURE_libinput -+ OR QT_FEATURE_tslib -+ OR (QT_FEATURE_libinput AND QT_FEATURE_xkbcommon)) - add_subdirectory(input) - endif() - if(QT_FEATURE_kms) diff --git a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_plugins_cocoa.patch b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_plugins_cocoa.patch index 2b0cc509..1f055353 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_plugins_cocoa.patch +++ b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_plugins_cocoa.patch @@ -8,7 +8,7 @@ See: https://codereview.qt-project.org/c/qt/qtbase/+/634002 --- a/qtbase/src/plugins/platforms/cocoa/CMakeLists.txt +++ b/qtbase/src/plugins/platforms/cocoa/CMakeLists.txt -@@ -107,3 +107,10 @@ qt_internal_extend_target(QCocoaIntegrationPlugin CONDITION QT_FEATURE_sessionma +@@ -108,3 +108,10 @@ qt_internal_extend_target(QCocoaIntegrationPlugin CONDITION QT_FEATURE_sessionma SOURCES qcocoasessionmanager.cpp qcocoasessionmanager.h ) diff --git a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_skip_tools.patch b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_skip_tools.patch index eef65425..77cb3e3f 100644 --- a/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_skip_tools.patch +++ b/libbitcoinkernel-sys/bitcoin/depends/patches/qt/qtbase_skip_tools.patch @@ -9,7 +9,7 @@ Skip building/installing unneeded tools: --- a/qtbase/cmake/QtBaseGlobalTargets.cmake +++ b/qtbase/cmake/QtBaseGlobalTargets.cmake -@@ -118,9 +118,6 @@ qt_generate_global_module_pri_file() +@@ -128,9 +128,6 @@ qt_generate_global_module_pri_file() qt_generate_global_device_pri_file() qt_generate_qmake_and_qtpaths_wrapper_for_target() @@ -19,7 +19,7 @@ Skip building/installing unneeded tools: qt_internal_add_platform_internal_target(GlobalConfigPrivate) target_link_libraries(GlobalConfigPrivate INTERFACE GlobalConfig) -@@ -390,12 +387,3 @@ elseif(WASM) +@@ -400,12 +397,3 @@ elseif(WASM) qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" DESTINATION "${INSTALL_LIBEXECDIR}") endif() diff --git a/libbitcoinkernel-sys/bitcoin/depends/patches/zeromq/add_new_include.patch b/libbitcoinkernel-sys/bitcoin/depends/patches/zeromq/add_new_include.patch new file mode 100644 index 00000000..0bf987f6 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/depends/patches/zeromq/add_new_include.patch @@ -0,0 +1,123 @@ +commit 2e8a6ccb414ca79636392604893c79c3b0d00dc4 +Author: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> +Date: Sat Jul 4 09:11:11 2026 +0200 + + Add missing includes for std::nothrow + + Without the include, compilation may fail: + + ``` + src/polling_util.hpp:28:30: error: no member named 'nothrow' in namespace 'std' + 28 | _buf = new (std::nothrow) T[nitems_]; + | ^~~~~~~ + ``` + +diff --git a/src/norm_engine.cpp b/src/norm_engine.cpp +index 1e3ae179..02483f0b 100644 +--- a/src/norm_engine.cpp ++++ b/src/norm_engine.cpp +@@ -1,6 +1,7 @@ + + #include "precompiled.hpp" + ++#include + #include "platform.hpp" + + #if defined ZMQ_HAVE_NORM +diff --git a/src/polling_util.hpp b/src/polling_util.hpp +index 13a4911f..3536be9a 100644 +--- a/src/polling_util.hpp ++++ b/src/polling_util.hpp +@@ -4,6 +4,7 @@ + #define __ZMQ_SOCKET_POLLING_UTIL_HPP_INCLUDED__ + + #include ++#include + #include + + #if defined ZMQ_HAVE_WINDOWS +diff --git a/src/proxy.cpp b/src/proxy.cpp +index 78d6ba61..85e4db4a 100644 +--- a/src/proxy.cpp ++++ b/src/proxy.cpp +@@ -3,6 +3,7 @@ + #include "precompiled.hpp" + + #include ++#include + #include "poller.hpp" + #include "proxy.hpp" + #include "likely.hpp" +diff --git a/src/reaper.cpp b/src/reaper.cpp +index 4361a7e9..1484a926 100644 +--- a/src/reaper.cpp ++++ b/src/reaper.cpp +@@ -2,6 +2,7 @@ + + #include "precompiled.hpp" + #include "macros.hpp" ++#include + #include "reaper.hpp" + #include "socket_base.hpp" + #include "err.hpp" +diff --git a/src/session_base.cpp b/src/session_base.cpp +index 5a81b076..618443d5 100644 +--- a/src/session_base.cpp ++++ b/src/session_base.cpp +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: MPL-2.0 */ + + #include "precompiled.hpp" ++#include + #include "macros.hpp" + #include "session_base.hpp" + #include "i_engine.hpp" +diff --git a/src/socket_poller.cpp b/src/socket_poller.cpp +index b5c330e8..3feb452e 100644 +--- a/src/socket_poller.cpp ++++ b/src/socket_poller.cpp +@@ -7,6 +7,7 @@ + #include "macros.hpp" + + #include ++#include + + static bool is_thread_safe (const zmq::socket_base_t &socket_) + { +diff --git a/src/stream_connecter_base.cpp b/src/stream_connecter_base.cpp +index 8dd9a6d6..6b733b4d 100644 +--- a/src/stream_connecter_base.cpp ++++ b/src/stream_connecter_base.cpp +@@ -15,6 +15,7 @@ + #endif + + #include ++#include + + zmq::stream_connecter_base_t::stream_connecter_base_t ( + zmq::io_thread_t *io_thread_, +diff --git a/src/stream_listener_base.cpp b/src/stream_listener_base.cpp +index 350093ad..b4e02027 100644 +--- a/src/stream_listener_base.cpp ++++ b/src/stream_listener_base.cpp +@@ -13,6 +13,8 @@ + #include + #endif + ++#include ++ + zmq::stream_listener_base_t::stream_listener_base_t ( + zmq::io_thread_t *io_thread_, + zmq::socket_base_t *socket_, +diff --git a/src/ws_engine.cpp b/src/ws_engine.cpp +index 9eec0d92..55590cdc 100644 +--- a/src/ws_engine.cpp ++++ b/src/ws_engine.cpp +@@ -26,6 +26,7 @@ + #endif + + #include ++#include + + #include "compat.hpp" + #include "tcp.hpp" diff --git a/libbitcoinkernel-sys/bitcoin/doc/AI_POLICY.md b/libbitcoinkernel-sys/bitcoin/doc/AI_POLICY.md index 6238c790..fde44c48 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/AI_POLICY.md +++ b/libbitcoinkernel-sys/bitcoin/doc/AI_POLICY.md @@ -23,6 +23,7 @@ This includes the pull request body and responses to questions. This project requires a human author in the loop who understands the work produced by AI. **Pull requests should not be opened or driven by autonomous agents**. A human author must choose the work, understand the change, and be responsible for the contribution. +Do not include agents as authors or co-authors of your commits for these reasons. Pull requests that appear in violation of this can be closed without notice. If you wish to include context from an interaction with AI in your comments, it must be disclosed as such. diff --git a/libbitcoinkernel-sys/bitcoin/doc/REST-interface.md b/libbitcoinkernel-sys/bitcoin/doc/REST-interface.md index ed46e222..91fa0399 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/REST-interface.md +++ b/libbitcoinkernel-sys/bitcoin/doc/REST-interface.md @@ -12,17 +12,24 @@ REST Interface consistency guarantees The [same guarantees as for the RPC Interface](/doc/JSON-RPC-interface.md#rpc-consistency-guarantees) apply. -Limitations ------------ - -There is a known issue in the REST interface that can cause a node to crash if -too many http connections are being opened at the same time because the system runs -out of available file descriptors. To prevent this from happening you might -want to increase the number of maximum allowed file descriptors in your system -and try to prevent opening too many connections to your rest interface at the -same time if this is under your control. It is hard to give general advice -since this depends on your system but if you make several hundred requests at -once you are definitely at risk of encountering this issue. +Default HTTP caching +-------------------- + +REST responses include `Cache-Control` headers by default: + +* `public, immutable, max-age=86400` for `/block` and `/block/notxdetails` + binary and hex responses, `/blockpart`, `/blockfilter` and `/spenttxouts` in + all formats, and `/deploymentinfo/.json`. The TTL is deliberately + short so caches do not hold older response shapes across software upgrades. +* `no-store` for `/block` and `/block/notxdetails` JSON, `/tx`, `/headers`, + `/blockfilterheaders`, `/blockhashbyheight`, `/chaininfo`, `/mempool`, + `/getutxos`, `/deploymentinfo.json`, and all error responses. These responses + can change with active chain or node state and do not currently provide cache + validators such as `ETag` or `Last-Modified`. + +If you front `bitcoind` with a reverse proxy or CDN such as Caddy or nginx with +the headers-more module, you can override these defaults there. Keep overrides +scoped to responses you know are safe to cache more aggressively. Supported API ------------- diff --git a/libbitcoinkernel-sys/bitcoin/doc/build-freebsd.md b/libbitcoinkernel-sys/bitcoin/doc/build-freebsd.md index ffb8ecfe..8189fe0b 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/build-freebsd.md +++ b/libbitcoinkernel-sys/bitcoin/doc/build-freebsd.md @@ -74,7 +74,7 @@ There is an included test suite that is useful for testing code changes when dev To run the test suite (recommended), you will need to have Python 3 installed: ```bash -pkg install python3 databases/py-sqlite3 net/py-pyzmq +pkg install python3 databases/py-sqlite3 net/py-pyzmq lsof ``` --- diff --git a/libbitcoinkernel-sys/bitcoin/doc/build-netbsd.md b/libbitcoinkernel-sys/bitcoin/doc/build-netbsd.md index d4d031d3..fc3096bb 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/build-netbsd.md +++ b/libbitcoinkernel-sys/bitcoin/doc/build-netbsd.md @@ -15,22 +15,6 @@ The example commands below use `pkgin`. pkgin install git cmake boost ``` -NetBSD currently ships with an older version of `gcc` than is needed to build. You should upgrade your `gcc` and then pass this new version to the CMake configuration. - -For example, grab `gcc12`: -``` -pkgin install gcc12 -``` - -Then, when configuring, pass the following: -```bash -cmake -B build - ... - -DCMAKE_C_COMPILER="/usr/pkg/gcc12/bin/gcc" \ - -DCMAKE_CXX_COMPILER="/usr/pkg/gcc12/bin/g++" \ - ... -``` - SQLite is required for the wallet: ```bash @@ -42,7 +26,7 @@ To build Bitcoin Core without the wallet, use `-DENABLE_WALLET=OFF`. Cap'n Proto is needed for IPC functionality (see [multiprocess.md](multiprocess.md)): ```bash -pkgin install capnproto +pkgin install capnproto pkgconf ``` Compile with `-DENABLE_IPC=OFF` if you do not need IPC functionality. @@ -84,7 +68,7 @@ Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` Bitcoin Core can provide notifications via ZeroMQ. To compile ZMQ support, install the following dependency and pass `-DWITH_ZMQ=ON` when configuring. ```bash -pkgin install zeromq pkg-config +pkgin install zeromq pkgconf ``` #### Test Suite Dependencies @@ -93,7 +77,14 @@ There is an included test suite that is useful for testing code changes when dev To run the test suite (recommended), you will need to have Python 3 installed: ```bash -pkgin install python313 py313-zmq +pkgin install python313 py313-zmq lsof +``` + +When the `lsof` binary package was built for a different point release, it might be necessary to force its installation as follows: + +```bash +echo "CHECK_OSABI=no" >> /etc/pkg_install.conf +pkgin install lsof ``` ## Building Bitcoin Core diff --git a/libbitcoinkernel-sys/bitcoin/doc/build-osx.md b/libbitcoinkernel-sys/bitcoin/doc/build-osx.md index bf55fda3..4cdb4834 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/build-osx.md +++ b/libbitcoinkernel-sys/bitcoin/doc/build-osx.md @@ -106,7 +106,7 @@ Otherwise, if you don't need QR encoding support, you can pass `-DWITH_QRENCODE= #### ZMQ Dependencies -Support for ZMQ notifications requires the following dependency. +Bitcoin Core can provide notifications via ZeroMQ. To compile ZMQ support, install the following dependency and pass `-DWITH_ZMQ=ON` when configuring. Skip if you do not need ZMQ functionality. ``` bash diff --git a/libbitcoinkernel-sys/bitcoin/doc/build-windows.md b/libbitcoinkernel-sys/bitcoin/doc/build-windows.md index 449dd4be..0af73681 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/build-windows.md +++ b/libbitcoinkernel-sys/bitcoin/doc/build-windows.md @@ -9,7 +9,7 @@ The options known to work for building Bitcoin Core on Windows are: * On Windows, using [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/about) and Mingw-w64. * On Windows, using [Microsoft Visual Studio](https://visualstudio.microsoft.com). See [`build-windows-msvc.md`](./build-windows-msvc.md). -Other options which may work, but which have not been extensively tested are (please contribute instructions): +Other options may work, but are not officially tested: * On Windows, using a POSIX compatibility layer application such as [cygwin](https://www.cygwin.com/) or [msys2](https://www.msys2.org/). diff --git a/libbitcoinkernel-sys/bitcoin/doc/cjdns.md b/libbitcoinkernel-sys/bitcoin/doc/cjdns.md index 9bdcec73..22849282 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/cjdns.md +++ b/libbitcoinkernel-sys/bitcoin/doc/cjdns.md @@ -73,7 +73,11 @@ connections are not affected by this option. It can be specified multiple times to allow multiple networks, e.g. onlynet=cjdns, onlynet=i2p, onlynet=onion. CJDNS support was added to Bitcoin Core in version 23.0 and there may be fewer -CJDNS peers than Tor or IP ones. You can use `bitcoin-cli -addrinfo` to see the +CJDNS peers than Tor or IP ones. Therefore, using CJDNS alone without other +networks is discouraged: a node may be unable to fill its outbound connection slots +but will repeatedly try the few addresses it knows and is more susceptible to +[Sybil attacks](https://en.bitcoin.it/wiki/Weaknesses#Sybil_attack). +You can use `bitcoin-cli -addrinfo` to see the number of CJDNS addresses known to your node. In general, a node can be run with both an onion service and CJDNS (or any/all diff --git a/libbitcoinkernel-sys/bitcoin/doc/developer-notes.md b/libbitcoinkernel-sys/bitcoin/doc/developer-notes.md index 0bc1bd25..b31d42a1 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/developer-notes.md +++ b/libbitcoinkernel-sys/bitcoin/doc/developer-notes.md @@ -673,6 +673,35 @@ Additional resources: A few non-style-related recommendations for developers, as well as points to pay attention to for reviewers of Bitcoin Core code. +## General Testing + +As a rule of thumb, an externally observable change (new feature, bug fix, or +changed default) should be accompanied by an automated test. +New tests are usually not needed for behavior-preserving work that is easy to +validate, such as moving code, renaming, or mechanical refactors. +When an automated test would be brittle or have limited long-term value, +a manual testing guide in the commit message or PR description is an +acceptable alternative. + +### Commit Structure for Tests + +Test placement depends on existing coverage and the type of change: + +* When existing tests already cover the behavior being changed, update them in + the same commit as the change. The diff records the old and new expectations + together and shows the change was intentional. +* For a simple feature or bug fix without existing coverage, the change and its + test can often be in the same commit. +* For a non-trivial refactor, if the relevant invariant is not already covered + by automated tests, first add that coverage in a separate test commit. The + refactor commit should not need to update test expectations. +* For a non-trivial change to existing behavior without coverage, consider + adding a preceding commit with a [characterization test](https://en.wikipedia.org/wiki/Characterization_test) + to document the current behavior. Mark assertions whose expected values will + change with `TODO` comments so they are not mistaken for intended behavior. + Remove the comments when updating those assertions in the behavior-changing + commit. + ## Locking/mutex usage notes The code is multi-threaded and uses mutexes and the diff --git a/libbitcoinkernel-sys/bitcoin/doc/files.md b/libbitcoinkernel-sys/bitcoin/doc/files.md index e8f28692..7176b5c6 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/files.md +++ b/libbitcoinkernel-sys/bitcoin/doc/files.md @@ -54,6 +54,7 @@ Subdirectory | File(s) | Description `blocks/` | `revNNNNN.dat`[\[2\]](#note2) | Block undo data (custom format) `blocks/` | `xor.dat` | Rolling XOR pattern for block and undo data files `chainstate/` | LevelDB database | Blockchain state (a compact representation of all currently unspent transaction outputs (UTXOs) and metadata about the transactions they are from) +`fees/` | `block_policy_estimates.dat` and `mempool_policy_estimator.dat` | Stores block policy and mempool policy estimator data `indexes/txindex/` | LevelDB database | Transaction index; *optional*, used if `-txindex=1` `indexes/txospenderindex/` | LevelDB database | Transaction spender index; *optional*, used if `-txospenderindex=1` `indexes/blockfilter/basic/db/` | LevelDB database | Blockfilter index LevelDB database for the basic filtertype; *optional*, used if `-blockfilterindex=basic` @@ -65,7 +66,6 @@ Subdirectory | File(s) | Description `./` | `bitcoin.conf` | User-defined [configuration settings](bitcoin-conf.md) for `bitcoind` or `bitcoin-qt`. File is not written to by the software and must be created manually. Path can be specified by `-conf` option `./` | `bitcoind.pid` | Stores the process ID (PID) of `bitcoind` or `bitcoin-qt` while running; created at start and deleted on shutdown; can be specified by `-pid` option `./` | `debug.log` | Contains debug information and general logging generated by `bitcoind` or `bitcoin-qt`; can be specified by `-debuglogfile` option -`./` | `fee_estimates.dat` | Stores statistics used to estimate minimum transaction fees required for confirmation `./` | `guisettings.ini.bak` | Backup of former [GUI settings](#gui-settings) after `-resetguisettings` option is used `./` | `mempool.dat` | Dump of the mempool's transactions `./` | `onion_v3_private_key` | Cached Tor onion service private key for `-listenonion` option diff --git a/libbitcoinkernel-sys/bitcoin/doc/i2p.md b/libbitcoinkernel-sys/bitcoin/doc/i2p.md index 2877c1e5..6bf427ea 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/i2p.md +++ b/libbitcoinkernel-sys/bitcoin/doc/i2p.md @@ -4,20 +4,20 @@ It is possible to run Bitcoin Core as an [I2P (Invisible Internet Project)](https://en.wikipedia.org/wiki/I2P) service and connect to such services. -This [glossary](https://geti2p.net/en/about/glossary) may be useful to get +This [glossary](https://i2p.net/en/docs/overview/glossary) may be useful to get started with I2P terminology. ## Run Bitcoin Core with an I2P router (proxy) -A running I2P router (proxy) is required with the [SAM](https://geti2p.net/en/docs/api/samv3) +A running I2P router (proxy) is required with the [SAM](https://i2p.net/en/docs/api/samv3) application bridge enabled. The following routers are recommended for use with Bitcoin Core: -- [i2prouter (I2P Router)](https://geti2p.net), the official implementation in +- [i2prouter (I2P Router)](https://i2p.net), the official implementation in Java. The SAM bridge is not enabled by default; it must be started manually, or configured to start automatically, in the Clients page in the router console (`http://127.0.0.1:7657/configclients`) or in the `clients.config` file. - [i2pd (I2P Daemon)](https://github.com/PurpleI2P/i2pd) - ([documentation](https://i2pd.readthedocs.io/en/latest)), a lighter + ([documentation](https://docs.i2pd.website/en/latest)), a lighter alternative in C++. It enables the SAM bridge by default. Note the IP address and port the SAM proxy is listening to; usually, it is @@ -113,7 +113,7 @@ You can use the `getnodeaddresses` RPC to fetch a number of I2P peers known to y ## Compatibility -Bitcoin Core uses the [SAM v3.1](https://geti2p.net/en/docs/api/samv3) protocol +Bitcoin Core uses the [SAM v3.1](https://i2p.net/en/docs/api/samv3) protocol to connect to the I2P network. Any I2P router that supports it can be used. ## Ports in I2P and Bitcoin Core @@ -158,13 +158,13 @@ Similar bandwidth configuration options for the Java I2P router can be found in `http://127.0.0.1:7657/config` under the "Bandwidth" tab. Before doing this, please see the "Participating Traffic Considerations" section -in [Embedding I2P in your Application](https://geti2p.net/en/docs/applications/embedding). +in [Embedding I2P in your Application](https://i2p.net/en/docs/applications/embedding). In most cases, the default router settings should work fine. ## Bundling I2P in a Bitcoin application -Please see the "General Guidance for Developers" section in https://geti2p.net/en/docs/api/samv3 +Please see the "General Guidance for Developers" section in https://i2p.net/en/docs/api/samv3 if you are developing a downstream application that may be bundling I2P with Bitcoin. ## Privacy recommendations diff --git a/libbitcoinkernel-sys/bitcoin/doc/multisig-tutorial.md b/libbitcoinkernel-sys/bitcoin/doc/multisig-tutorial.md index b6f496a3..fd74e62e 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/multisig-tutorial.md +++ b/libbitcoinkernel-sys/bitcoin/doc/multisig-tutorial.md @@ -9,18 +9,16 @@ This tutorial uses [jq](https://github.com/stedolan/jq) JSON processor to proces Before starting this tutorial, start the bitcoin node on the signet network. ```bash -./build/bin/bitcoind -signet -daemon +./build/bin/bitcoin node -signet -daemon ``` -This tutorial also uses the default WPKH derivation path to get the xpubs and does not conform to [BIP 45](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) or [BIP 87](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki). - -At the time of writing, there is no way to extract a specific path from wallets in Bitcoin Core. For this, an external signer/xpub can be used. +This tutorial also uses the default PKH derivation path to get the xpubs and does not conform to [BIP 45](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) or [BIP 87](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki). ## 1.1 Basic Multisig Workflow ### 1.1 Create the Descriptor Wallets -For a 2-of-3 multisig, create 3 descriptor wallets. It is important that they are of the descriptor type in order to retrieve the wallet descriptors. These wallets contain HD seed and private keys, which will be used to sign the PSBTs and derive the xpub. +For a 2-of-3 multisig, create 3 wallets. These wallets contain HD seed and private keys, which will be used to sign the PSBTs and derive the xpub. These three wallets should not be used directly for privacy reasons (public key reuse). They should only be used to sign transactions for the (watch-only) multisig wallet. @@ -31,16 +29,7 @@ do done ``` -Extract the xpub of each wallet. To do this, the `listdescriptors` RPC is used. By default, Bitcoin Core single-sig wallets are created using path `m/44'/1'/0'` for PKH, `m/84'/1'/0'` for WPKH, `m/49'/1'/0'` for P2WPKH-nested-in-P2SH and `m/86'/1'/0'` for P2TR based accounts. Each of them uses the chain 0 for external addresses and chain 1 for internal ones, as shown in the example below. - -``` -wpkh([1004658e/84'/1'/0']tpubDCBEcmVKbfC9KfdydyLbJ2gfNL88grZu1XcWSW9ytTM6fitvaRmVyr8Ddf7SjZ2ZfMx9RicjYAXhuh3fmLiVLPodPEqnQQURUfrBKiiVZc8/0/*)#g8l47ngv - -wpkh([1004658e/84'/1'/0']tpubDCBEcmVKbfC9KfdydyLbJ2gfNL88grZu1XcWSW9ytTM6fitvaRmVyr8Ddf7SjZ2ZfMx9RicjYAXhuh3fmLiVLPodPEqnQQURUfrBKiiVZc8/1/*)#en65rxc5 -``` - -The suffix (after #) is the checksum. Descriptors can optionally be suffixed with a checksum to protect against typos or copy-paste errors. -All RPCs in Bitcoin Core will include the checksum in their output. +Extract the xpub of each wallet. To do this, the `derivehdkey` RPC is used. Note that previously at least two descriptors were usually used, one for external derivation paths and one for internal ones. Since https://github.com/bitcoin/bitcoin/pull/22838 this redundancy has been eliminated by a multipath descriptor with <0;1> at the [BIP-44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#change) change level expanding to external and internal descriptors when imported. @@ -49,49 +38,44 @@ declare -A xpubs for ((n=1;n<=3;n++)) do - xpubs["xpub_${n}"]=$(./build/bin/bitcoin rpc -signet -rpcwallet="participant_${n}" listdescriptors | jq '.descriptors | [.[] | select(.desc | startswith("wpkh") and contains("/0/*") )][0] | .desc' | grep -Po '(?<=\().*(?=\))' | sed 's /0/\* /<0;1>/* ') + xpubs["xpub_${n}"]=$(./build/bin/bitcoin rpc -signet -rpcwallet="participant_${n}" derivehdkey "m/44h/1h/0h" | jq -r '.origin + .xpub') done ``` -`jq` is used to extract the xpub from the `wpkh` descriptor. - -The following command can be used to verify if the xpub was generated correctly. +The following command can be used to verify if the xpubs were obtained successfully: ```bash for x in "${!xpubs[@]}"; do printf "[%s]=%s\n" "$x" "${xpubs[$x]}" ; done ``` -As previously mentioned, this step extracts the `m/84'/1'/0'` account instead of the path defined in [BIP 45](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) or [BIP 87](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki), since there is no way to extract a specific path in Bitcoin Core at the time of writing. +As previously mentioned, this step extracts the `m/44'/1'/0'` account instead of the path defined in [BIP 45](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) or [BIP 87](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki), because the wallet currently can't sign for a derivation path that's not used in one of its descriptors. ### 1.2 Define the Multisig Descriptor -Define the multisig descriptor, add the checksum and then, wrap it in a JSON array. +Define the multisig descriptors. + +All RPCs in Bitcoin Core will include the checksum in their output. ```bash -desc="wsh(sortedmulti(2,${xpubs["xpub_1"]},${xpubs["xpub_2"]},${xpubs["xpub_3"]}))" +desc="wsh(sortedmulti(2,${xpubs["xpub_1"]}/<0;1>/*,${xpubs["xpub_2"]}/<0;1>/*,${xpubs["xpub_3"]}/<0;1>/*))" -checksum=$(./build/bin/bitcoin rpc -signet getdescriptorinfo $desc | jq -r '.checksum') +desc_sum=$(./build/bin/bitcoin rpc -signet getdescriptorinfo $desc | jq -r '.checksum') -multisig_desc="[{\"desc\": \"${desc}#${checksum}\", \"active\": true, \"timestamp\": \"now\"}]" +multisig_desc="[{\"desc\": \"$desc#$desc_sum\", \"active\": true, \"timestamp\": \"now\"}]" ``` `desc` specifies the output type (`wsh`, in this case) and the xpubs involved. It also uses BIP 67 (`sortedmulti`), so the wallet can be recreated without worrying about the order of xpubs. Conceptually, descriptors describe a list of scriptPubKey (along with information for spending from it) [[source](https://github.com/bitcoin/bitcoin/issues/21199#issuecomment-780772418)]. -After creating the descriptor, it is necessary to add the checksum, which is required by the `importdescriptors` RPC. +The checksum for a descriptor without one can be computed using the `getdescriptorinfo` RPC. The response has a `checksum` field, which is appended to the descriptor after `#` to protect against typos or copy-paste errors. -The checksum for a descriptor without one can be computed using the `getdescriptorinfo` RPC. The response has the `checksum` field, which is the checksum for the input descriptor, append "#" and this checksum to the input descriptor. - -There are other fields that can be added to the descriptor: +There are other fields that can be added to the descriptors: * `active`: Sets the descriptor to be the active one for the corresponding output type (`wsh`, in this case). -* `internal`: Indicates whether matching outputs should be treated as something other than incoming payments (e.g. change). * `timestamp`: Sets the time from which to start rescanning the blockchain for the descriptor, in UNIX epoch time. -Note: when a multipath descriptor is imported, it is expanded into two descriptors which are imported separately, with the second implicitly used for internal (change) addresses. - Documentation for these and other parameters can be found by typing `./build/bin/bitcoin rpc -signet help importdescriptors`. -`multisig_desc` wraps the descriptor in a JSON array and will be used to create the multisig wallet. +`multisig_desc` concatenates the descriptor in a JSON array and then it will be used to create the multisig wallet. ### 1.3 Create the Multisig Wallet @@ -99,16 +83,18 @@ To create the multisig wallet, first create an empty one (no keys, HD seed and p Then import the descriptor created in the previous step using the `importdescriptors` RPC. -After that, `getwalletinfo` can be used to check if the wallet was created successfully. +After that, `listdescriptors` can be used to check if the wallet was created successfully. ```bash -./build/bin/bitcoin rpc -signet createwallet "multisig_wallet_01" disable_private_keys=true blank=true +./build/bin/bitcoin rpc -signet -named createwallet wallet_name="multisig_wallet_01" disable_private_keys=true blank=true ./build/bin/bitcoin rpc -signet -rpcwallet="multisig_wallet_01" importdescriptors "$multisig_desc" -./build/bin/bitcoin rpc -signet -rpcwallet="multisig_wallet_01" getwalletinfo +./build/bin/bitcoin rpc -signet -rpcwallet="multisig_wallet_01" listdescriptors ``` +The `<0;1>` notation in `desc` caused the creation of two descriptors. One uses the chain 0 for external addresses, and the other uses chain 1 for internal ones (change). + Once the wallets have already been created and this tutorial needs to be repeated or resumed, it is not necessary to recreate them, just load them with the command below: ```bash @@ -199,7 +185,7 @@ psbt_2=$(./build/bin/bitcoin rpc -signet -rpcwallet="participant_2" walletproces The PSBT, if signed separately by the co-signers, must be combined into one transaction before being finalized. This is done by `combinepsbt` RPC. ```bash -combined_psbt=$(./build/bin/bitcoin rpc -signet combinepsbt "[$psbt_1, $psbt_2]") +combined_psbt=$(./build/bin/bitcoin rpc -signet combinepsbt txs="[$psbt_1, $psbt_2]") ``` There is an RPC called `joinpsbts`, but it has a different purpose than `combinepsbt`. `joinpsbts` joins the inputs from multiple distinct PSBTs into one PSBT. diff --git a/libbitcoinkernel-sys/bitcoin/doc/reduce-memory.md b/libbitcoinkernel-sys/bitcoin/doc/reduce-memory.md index 348d98bd..6729ab66 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/reduce-memory.md +++ b/libbitcoinkernel-sys/bitcoin/doc/reduce-memory.md @@ -33,7 +33,7 @@ The size of some in-memory caches can be reduced. As caches trade off memory usa ## Number of peers -- `-maxconnections=` - the maximum number of connections, which defaults to 125. Each active connection takes up some +- `-maxconnections=` - the maximum number of connections, which defaults to 200. Each active connection takes up some memory. This option applies only if inbound connections are enabled; otherwise, the number of connections will not be more than 11. Of the 11 outbound peers, there can be 8 full-relay connections, 2 block-relay-only ones, and occasionally 1 short-lived feeler or extra outbound block-relay-only connection. diff --git a/libbitcoinkernel-sys/bitcoin/doc/reduce-traffic.md b/libbitcoinkernel-sys/bitcoin/doc/reduce-traffic.md index 8926a836..315de214 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/reduce-traffic.md +++ b/libbitcoinkernel-sys/bitcoin/doc/reduce-traffic.md @@ -3,8 +3,9 @@ Reduce Traffic Some node operators need to deal with bandwidth caps imposed by their ISPs. -By default, Bitcoin Core allows up to 125 connections to different peers, 11 of -which are outbound. You can therefore, have at most 114 inbound connections. +By default, Bitcoin Core allows up to 200 connections to different peers, 11 of +which are outbound. You can therefore, have at most 189 inbound connections, half of +which can only be taken up by low-traffic block-relay-only peers. Of the 11 outbound peers, there can be 8 full-relay connections, 2 block-relay-only ones and occasionally 1 short-lived feeler or an extra block-relay-only connection. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-32784.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-32784.md new file mode 100644 index 00000000..6312165f --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-32784.md @@ -0,0 +1,9 @@ +Wallet +------ + +- A new `derivehdkey` RPC is available to obtain an xpub or xprv for a + derivation path with at least one hardened step from an HD key known to the + wallet. This can be used to coordinate a multisig setup, where each signer + shares an xpub using a + different derivation path than the default single-signature descriptors. The + example in `doc/multisig-tutorial.md` is updated to use this RPC. (#32784) diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-32800.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-32800.md new file mode 100644 index 00000000..de7a427e --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-32800.md @@ -0,0 +1,9 @@ +- Mempool RPCs (`getrawmempool`, `getmempoolentry`, `testmempoolaccept`, `submitpackage`) +now include an additional field `vsize_adjusted` (which is the sigop-adjusted virtual size +used for policy) and `vsize_bip141` (which represents the raw BIP141 virtual size). +While `vsize` is marked as DEPRECATED, it was previously erroneously described as the BIP 141 +vsize, but is actually sigops-adjusted vsize. Use `vsize_bip141` to actually get that behavior +or switch to the explicit `vsize_adjusted` for retained behavior. + +- `getrawtransaction` RPC now includes an additional field `vsize_adjusted`, which is the +sigop-adjusted virtual size if the transaction is in the mempool. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-34075.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-34075.md new file mode 100644 index 00000000..3d42b0de --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-34075.md @@ -0,0 +1,52 @@ +Updated RPCs +------------ + +- The `estimatesmartfee` RPC now combines two fee rate estimators: the existing + block policy fee rate estimator and a new mempool fee rate estimator. + +- The new mempool fee rate estimator produces conservative and economical fee + rate estimates from the current contents of the mempool. It only produces a + fee rate estimate when recent blocks indicate a healthy mempool, and falls + back to the higher of the minimum relay fee rate and the current mempool + minimum fee rate when the mempool is too sparse. Its statistics are persisted + to `fees/mempool_policy_estimator.dat` and reloaded on startup. + + `estimatesmartfee` returns the lower of the two fee rate estimators' results, + so the mempool fee rate estimator can only lower the block policy fee rate + estimate. + +- The combined estimate requires both estimators to succeed. If the mempool fee + rate estimator cannot produce an estimate, for example, while the mempool is + still loading, when too few recent blocks have been observed, or when the + mempool is suspected to be unhealthy, an error is returned. + +- `estimatesmartfee` accepts an `options` object with `fee_rate_estimator`. + Recognized values are `"none"` (the default, combined behavior described + above), `"block_policy"` (use only the block policy fee rate estimator), + and `"mempool_policy"` (use only the mempool fee rate estimator). + All unknown values are treated as `"none"`. + Users who want the previous behavior can select the block policy fee rate + estimator explicitly. + +- The options object also accepts `verbosity`. A verbosity of `2` or higher + also returns `mempool_health_statistics`. + +- When `fee_rate_estimator` is `"none"` and the estimate succeeds, the response + also includes an `estimator` field identifying which fee rate estimator produced + the result. + +- Block policy fee estimator data is now stored in + `fees/block_policy_estimates.dat`. If the new file does not exist, the + legacy `fee_estimates.dat` file is moved to the new path during startup. If + both files exist, the legacy file is removed. + +- Wallet fee rate estimation uses the default combined estimate. + +Wallet +------ + +- The `fee_reason` field returned by wallet transaction creation RPCs now + reports the reason the wallet selected the fee rate (fee rate estimator, + mempool minimum, fallback, or minimum required) instead of the block policy + fee rate estimator's internal threshold details. Those details remain + available in the block policy fee rate estimator debug log. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-34628.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-34628.md new file mode 100644 index 00000000..884ac073 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-34628.md @@ -0,0 +1,13 @@ +P2P and network changes +----------------------- + +- To reduce memory and CPU usage during periods of high transaction + volume, rate-limiting of outgoing transaction relay has been changed + to use a global backlog instead of being done on a per-peer basis. The + default rate-limit remains as 14 tx/s (boosted by 2.5x for outbound + peers), though this can be changed via the `-txsendrate` configuration + option. An additional bandwidth rate-limit has also been introduced + at 12MB of transactions per 10 minutes, with a high burst rate. The + size of the global backlog and the token bucket values for the rate + limits can be queried via the `getnetworkinfo` RPC. (#34628) + diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-34672.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-34672.md new file mode 100644 index 00000000..060d9142 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-34672.md @@ -0,0 +1,11 @@ +IPC Interface +------------- + +- `BlockTemplate.submitSolution` now returns `reason` and `debug` rejection + details in addition to the boolean result. Clients must regenerate IPC + bindings from the updated `mining.capnp` schema to use the new method. The + previous `@7` method now returns an error directing clients to update. (#34672) + +- `BlockTemplate.submitSolution` now reports duplicate blocks as failures with + `reason="duplicate"`, matching `Mining.submitBlock`, instead of returning + success for duplicate submissions. (#34672) diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-34794.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-34794.md new file mode 100644 index 00000000..befafa94 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-34794.md @@ -0,0 +1,8 @@ +REST API +-------- + +- REST responses now include `Cache-Control` headers to guide intermediary + caches. Immutable responses such as block binary and hex data, block parts, + block filters, spent transaction outputs, and block-specific deployment info + are marked cacheable for one day. Responses that can change with active chain + or node state, as well as errors, are marked `no-store`. (#34794) diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35182.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35182.md index 8d2b6918..d095d2fb 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35182.md +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35182.md @@ -14,3 +14,8 @@ Certain HTTP edge cases will observe different behavior to be more RFC-compliant - "Line Folding" is rejected (whitespace at start of a header line) - Tolerate `%` at the end of requested URLs - Multiple "Content-Length" headers with different values are rejected + +A new configuration option `-rpcmaxconnections` (default `16`) limits the +number of simultaneously connected HTTP clients to the server. The application +will now attempt to reserve file descriptors for the HTTP server sockets. If your +system has limited resources, consider using a lower setting. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35501.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35501.md new file mode 100644 index 00000000..2399ca1e --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35501.md @@ -0,0 +1,4 @@ +RPC +--- + +- `gettransaction`, `listtransactions`, and `listsinceblock` now have an `alternate_wtxids` field which lists the wtxids of all transactions that have the same txid. When there is only one known witness variant the field is an empty array, analogous to `walletconflicts` and `mempoolconflicts`. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35531.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35531.md new file mode 100644 index 00000000..90e6014c --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35531.md @@ -0,0 +1,12 @@ +## Index + +- The transaction index (`-txindex`) now stores less data on disk; a fully + rebuilt index takes less than half the space. The index is backwards compatible, + so existing users will not see the space saving unless the index is recreated. + To do so, stop the node, delete the `/indexes/txindex` directory, and + restart; rebuilding can take up to a few hours depending on hardware. Progress + can be monitored using the `getindexinfo` RPC. Once rebuilt, the index can no + longer be read by previous releases, so downgrading will rebuild it again in + the old format. When downgrading permanently, delete the + `/indexes/txindex` directory first, since previous releases do not + reclaim the space used by entries in the new format. (#35531) diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35592.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35592.md new file mode 100644 index 00000000..e24eec31 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35592.md @@ -0,0 +1,6 @@ +HTTP: RPC / REST +---------------- + +Clients attempting to connect from addresses not allowed by the `-rpcallowip` +option (or its default, `localhost`) will now be immediately disconnected +instead of receiving a `403 Forbidden`. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35610.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35610.md index 8e0dd208..1f80677e 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35610.md +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35610.md @@ -1,6 +1,6 @@ Tools and Utilities ------------------- -- A new `bitcoin-util netmagic` command returns the network magic of the - selected chain. +- A new `bitcoin-util getchainparams` command returns hardcoded details + about the selected chain. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35680.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35680.md new file mode 100644 index 00000000..c5d19b15 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35680.md @@ -0,0 +1,13 @@ +P2P and network changes +----------------------- + +- Each transaction sent via private broadcast (`-privatebroadcast`) is limited + to 1,000 send attempts. After reaching the limit, broadcasting stops; call + `sendrawtransaction` again to retry. Transactions that reach the limit remain + available through `getprivatebroadcastinfo` and `abortprivatebroadcast`. (#35680) + +Updated RPCs +------------ + +- `getprivatebroadcastinfo` now reports an `attempts_remaining` field for each + transaction. (#35680) diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35696.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35696.md new file mode 100644 index 00000000..393c2b05 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35696.md @@ -0,0 +1,8 @@ +### P2P and Network Changes + +Support for the legacy ElGamal (type 0) encryption type when creating I2P +sessions is being sunset by the I2P network and will be removed from bitcoind on +or before v34. Nodes using I2P with versions of Bitcoin Core earlier than v26.1 +(PRs #29200, #29209) will soon only be able to connect to other legacy ElGamal +I2P peers and will be increasingly isolated from the rest of the network, with a +reduced anonymity set. See #35696 for details. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-35836.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35836.md new file mode 100644 index 00000000..851e48d4 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-35836.md @@ -0,0 +1,5 @@ +# RPC (wallet) + +* The `fundrawtransaction` RPC no longer accepts a boolean as the second + positional argument. This silent no-op fallback was removed and the argument + is now fully type checked. Passing a boolean will raise an error. (#35836) diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-953.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-953.md new file mode 100644 index 00000000..a4d03975 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-953.md @@ -0,0 +1,5 @@ +GUI Changes +--- + +The migrate wallet option now allows to disable wallet loading after migrating. +It is useful in case the node is pruned and the wallet was created before the pruned height. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-gui-872.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-gui-872.md new file mode 100644 index 00000000..5ea70345 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-gui-872.md @@ -0,0 +1,7 @@ +GUI +--- + +* A menu action has been added to allow creating a watchonly wallet file from + an existing descriptor wallet. This option mirrors the `exportwatchonlywallet` + RPC - the exported file can be imported to another node using the Restore + Wallet menu action. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-removeprunedfunds.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-removeprunedfunds.md new file mode 100644 index 00000000..0e0d0ceb --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-removeprunedfunds.md @@ -0,0 +1,6 @@ +Updated RPCs +------------ + +- The `removeprunedfunds` RPC has been deprecated and will be removed in the +next major release. In order to continue using it, `bitcoind` must be started +with the `-deprecatedrpc=removeprunedfunds` option. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-process.md b/libbitcoinkernel-sys/bitcoin/doc/release-process.md index 28bcfe83..c02ada5a 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/release-process.md +++ b/libbitcoinkernel-sys/bitcoin/doc/release-process.md @@ -59,11 +59,11 @@ Release Process - Clear the release notes and move them to the wiki (see "Write the release notes" below). - Translations on Transifex: - Pull translations from Transifex into the master branch. - - Create [a new resource](https://app.transifex.com/bitcoin/bitcoin/content/) named after the major version with the slug `qt-translation-x`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/bitcoin_en.xlf` to create it. + - Create [a new resource](https://app.transifex.com/bitcoin/bitcoin/content/) named after the major version with the slug `qt-translation-x`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/bitcoin_en.ts` to create it. - In the project workflow settings, ensure that [Translation Memory Fill-up](https://help.transifex.com/en/articles/6224817-setting-up-translation-memory-fill-up) is enabled and that [Translation Memory Context Matching](https://help.transifex.com/en/articles/6224753-translation-memory-with-context) is disabled. - Update the Transifex slug in [`.tx/config`](/.tx/config) to the slug of the resource created in the first step. This identifies which resource the translations will be synchronized from. - Make an announcement that translators can start translating for the new version. You can use one of the [previous announcements](https://app.transifex.com/bitcoin/communication/) as a template. - - Change the auto-update URL for the resource to `master`, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin/master/src/qt/locale/bitcoin_en.xlf`. (Do this only after the previous steps, to prevent an auto-update from interfering.) + - Change the auto-update URL for the resource to `master`, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin/master/src/qt/locale/bitcoin_en.ts`. (Do this only after the previous steps, to prevent an auto-update from interfering.) #### After branch-off (on the major release branch) @@ -72,7 +72,7 @@ Release Process - Clear the release notes: `cp doc/release-notes-empty-template.md doc/release-notes.md` - Create a pinned meta-issue for testing the release candidate (see [this issue](https://github.com/bitcoin/bitcoin/issues/27621) for an example) and provide a link to it in the release announcements where useful. - Translations on Transifex - - Change the auto-update URL for the new major version's resource away from `master` and to the branch, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin//src/qt/locale/bitcoin_en.xlf`. Do not forget this or it will keep tracking the translations on master instead, drifting away from the specific major release. + - Change the auto-update URL for the new major version's resource away from `master` and to the branch, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin//src/qt/locale/bitcoin_en.ts`. Do not forget this or it will keep tracking the translations on master instead, drifting away from the specific major release. - Prune inputs from the qa-assets repo (See [pruning inputs](https://github.com/bitcoin-core/qa-assets#pruning-inputs)). diff --git a/libbitcoinkernel-sys/bitcoin/ruff.toml b/libbitcoinkernel-sys/bitcoin/ruff.toml index d379dde1..61cf6d24 100644 --- a/libbitcoinkernel-sys/bitcoin/ruff.toml +++ b/libbitcoinkernel-sys/bitcoin/ruff.toml @@ -12,7 +12,5 @@ select = [ ] ignore = [ "E501", # line too long - "E712", # true-false comparison - "E731", # lambda assignment "E741", # ambiguous-variable-name ] diff --git a/libbitcoinkernel-sys/bitcoin/share/qt/translate.cmake b/libbitcoinkernel-sys/bitcoin/share/qt/translate.cmake index 2ac8c7f0..a8f54a91 100644 --- a/libbitcoinkernel-sys/bitcoin/share/qt/translate.cmake +++ b/libbitcoinkernel-sys/bitcoin/share/qt/translate.cmake @@ -7,7 +7,6 @@ cmake_minimum_required(VERSION 3.22) set(input_variables PROJECT_SOURCE_DIR COPYRIGHT_HOLDERS - LCONVERT_EXECUTABLE LUPDATE_EXECUTABLE XGETTEXT_EXECUTABLE ) @@ -103,28 +102,13 @@ extract_strings("${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp" execute_process( COMMAND ${LUPDATE_EXECUTABLE} -no-obsolete + -sort-messages -I ${PROJECT_SOURCE_DIR}/src - -locations relative + -locations none + -target-language en ${ui_files} ${qt_translatable_sources} ${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp -ts ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts COMMAND_ERROR_IS_FATAL ANY ) - -execute_process( - COMMAND ${LCONVERT_EXECUTABLE} - -drop-translations - -o ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf - -i ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts - COMMAND_ERROR_IS_FATAL ANY -) - -file(READ "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" bitcoin_en) -string(REPLACE "source-language=\"en\" target-language=\"en\"" - "source-language=\"en\"" bitcoin_en "${bitcoin_en}" -) -string(REGEX REPLACE " *\n" - "" bitcoin_en "${bitcoin_en}" -) -file(WRITE "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" "${bitcoin_en}") diff --git a/libbitcoinkernel-sys/bitcoin/share/setup.nsi.in b/libbitcoinkernel-sys/bitcoin/share/setup.nsi.in index 387d7811..33baa477 100644 --- a/libbitcoinkernel-sys/bitcoin/share/setup.nsi.in +++ b/libbitcoinkernel-sys/bitcoin/share/setup.nsi.in @@ -72,19 +72,19 @@ ShowUninstDetails show Section -Main SEC0000 SetOutPath $INSTDIR SetOverwrite on - File @abs_top_builddir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_WRAPPER_NAME@@EXEEXT@ - File /oname=COPYING.txt @abs_top_srcdir@/COPYING - File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt - File @abs_top_srcdir@/share/examples/bitcoin.conf + File "@BIN_DIR@/@BITCOIN_GUI_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_WRAPPER_NAME@@EXEEXT@" + File /oname=COPYING.txt "@abs_top_srcdir@/COPYING" + File /oname=readme.txt "@abs_top_srcdir@/doc/README_windows.txt" + File "@abs_top_srcdir@/share/examples/bitcoin.conf" SetOutPath $INSTDIR\share\rpcauth - File @abs_top_srcdir@/share/rpcauth/*.* + File "@abs_top_srcdir@/share/rpcauth/*.*" SetOutPath $INSTDIR\daemon - File @abs_top_builddir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_TX_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_WALLET_TOOL_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_TEST_NAME@@EXEEXT@ + File "@BIN_DIR@/@BITCOIN_DAEMON_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_CLI_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_TX_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_WALLET_TOOL_NAME@@EXEEXT@" + File "@LIBEXEC_DIR@/@BITCOIN_TEST_NAME@@EXEEXT@" SetOutPath $INSTDIR WriteRegStr HKCU "${REGKEY}\Components" Main 1 SectionEnd diff --git a/libbitcoinkernel-sys/bitcoin/src/.clang-tidy b/libbitcoinkernel-sys/bitcoin/src/.clang-tidy index 9bdcc03f..4e0af3f3 100644 --- a/libbitcoinkernel-sys/bitcoin/src/.clang-tidy +++ b/libbitcoinkernel-sys/bitcoin/src/.clang-tidy @@ -8,8 +8,10 @@ bugprone-use-after-move, bugprone-lambda-function-name, bugprone-unhandled-self-assignment, bugprone-unused-return-value, -misc-unused-using-decls, +fuchsia-header-anon-namespaces, +misc-definitions-in-headers, misc-no-recursion, +misc-unused-using-decls, modernize-avoid-bind, modernize-deprecated-headers, modernize-use-default-member-init, diff --git a/libbitcoinkernel-sys/bitcoin/src/CMakeLists.txt b/libbitcoinkernel-sys/bitcoin/src/CMakeLists.txt index 47266dcf..15b60ef9 100644 --- a/libbitcoinkernel-sys/bitcoin/src/CMakeLists.txt +++ b/libbitcoinkernel-sys/bitcoin/src/CMakeLists.txt @@ -164,10 +164,10 @@ if(ENABLE_WALLET) if(BUILD_WALLET_TOOL) add_executable(bitcoin-wallet bitcoin-wallet.cpp + bitcoin-wallet-res.rc init/bitcoin-wallet.cpp wallet/wallettool.cpp ) - add_windows_resources(bitcoin-wallet bitcoin-wallet-res.rc) add_windows_application_manifest(bitcoin-wallet) target_link_libraries(bitcoin-wallet core_interface @@ -247,7 +247,9 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL noui.cpp policy/ephemeral_policy.cpp policy/fees/block_policy_estimator.cpp - policy/fees/block_policy_estimator_args.cpp + policy/fees/estimator_args.cpp + policy/fees/estimator_man.cpp + policy/fees/mempool_estimator.cpp policy/packages.cpp policy/rbf.cpp policy/settings.cpp @@ -302,8 +304,10 @@ endif() # Bitcoin wrapper executable that can call other executables. if(BUILD_BITCOIN_BIN) - add_executable(bitcoin bitcoin.cpp) - add_windows_resources(bitcoin bitcoin-res.rc) + add_executable(bitcoin + bitcoin.cpp + bitcoin-res.rc + ) add_windows_application_manifest(bitcoin) target_link_libraries(bitcoin core_interface bitcoin_common bitcoin_util) install_binary_component(bitcoin HAS_MANPAGE) @@ -313,9 +317,9 @@ endif() if(BUILD_DAEMON) add_executable(bitcoind bitcoind.cpp + bitcoind-res.rc init/bitcoind.cpp ) - add_windows_resources(bitcoind bitcoind-res.rc) add_windows_application_manifest(bitcoind) target_link_libraries(bitcoind core_interface @@ -352,8 +356,11 @@ target_link_libraries(bitcoin_cli # Bitcoin Core RPC client if(BUILD_CLI) - add_executable(bitcoin-cli bitcoin-cli.cpp init/basic.cpp) - add_windows_resources(bitcoin-cli bitcoin-cli-res.rc) + add_executable(bitcoin-cli + bitcoin-cli.cpp + bitcoin-cli-res.rc + init/basic.cpp + ) add_windows_application_manifest(bitcoin-cli) target_link_libraries(bitcoin-cli core_interface @@ -367,8 +374,10 @@ endif() if(BUILD_TX) - add_executable(bitcoin-tx bitcoin-tx.cpp) - add_windows_resources(bitcoin-tx bitcoin-tx-res.rc) + add_executable(bitcoin-tx + bitcoin-tx.cpp + bitcoin-tx-res.rc + ) add_windows_application_manifest(bitcoin-tx) target_link_libraries(bitcoin-tx core_interface @@ -381,13 +390,16 @@ endif() if(BUILD_UTIL) - add_executable(bitcoin-util bitcoin-util.cpp) - add_windows_resources(bitcoin-util bitcoin-util-res.rc) + add_executable(bitcoin-util + bitcoin-util.cpp + bitcoin-util-res.rc + ) add_windows_application_manifest(bitcoin-util) target_link_libraries(bitcoin-util core_interface bitcoin_common bitcoin_util + univalue ) install_binary_component(bitcoin-util HAS_MANPAGE) endif() diff --git a/libbitcoinkernel-sys/bitcoin/src/addresstype.h b/libbitcoinkernel-sys/bitcoin/src/addresstype.h index 862049de..79fcf3d1 100644 --- a/libbitcoinkernel-sys/bitcoin/src/addresstype.h +++ b/libbitcoinkernel-sys/bitcoin/src/addresstype.h @@ -118,7 +118,7 @@ struct WitnessUnknown }; /** Witness program for Pay-to-Anchor output script type */ -static const std::vector ANCHOR_BYTES{0x4e, 0x73}; +inline const std::vector ANCHOR_BYTES{0x4e, 0x73}; struct PayToAnchor : public WitnessUnknown { diff --git a/libbitcoinkernel-sys/bitcoin/src/addrman.cpp b/libbitcoinkernel-sys/bitcoin/src/addrman.cpp index 3050beb7..554e5ad0 100644 --- a/libbitcoinkernel-sys/bitcoin/src/addrman.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/addrman.cpp @@ -910,7 +910,10 @@ void AddrManImpl::ResolveCollisions_() int tried_bucket_pos = info_new.GetBucketPosition(nKey, false, tried_bucket); if (!info_new.IsValid()) { // id_new may no longer map to a valid address erase_collision = true; - } else if (vvTried[tried_bucket][tried_bucket_pos] != -1) { // The position in the tried bucket is not empty + } else { + // A pending tried collision implies that the destination tried slot + // remains occupied until we resolve it. + Assume(vvTried[tried_bucket][tried_bucket_pos] != -1); // Get the to-be-evicted address that is being tested nid_type id_old = vvTried[tried_bucket][tried_bucket_pos]; @@ -939,9 +942,6 @@ void AddrManImpl::ResolveCollisions_() Good_(info_new, false, current_time); erase_collision = true; } - } else { // Collision is not actually a collision anymore - Good_(info_new, false, Now()); - erase_collision = true; } } @@ -977,6 +977,7 @@ std::pair AddrManImpl::SelectTriedCollision_() int tried_bucket = newInfo.GetTriedBucket(nKey, m_netgroupman); int tried_bucket_pos = newInfo.GetBucketPosition(nKey, false, tried_bucket); + Assume(vvTried[tried_bucket][tried_bucket_pos] != -1); const AddrInfo& info_old = mapInfo[vvTried[tried_bucket][tried_bucket_pos]]; return {info_old, info_old.m_last_try}; } diff --git a/libbitcoinkernel-sys/bitcoin/src/addrman.h b/libbitcoinkernel-sys/bitcoin/src/addrman.h index f7143386..70697f76 100644 --- a/libbitcoinkernel-sys/bitcoin/src/addrman.h +++ b/libbitcoinkernel-sys/bitcoin/src/addrman.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -24,25 +23,25 @@ class NetGroupManager; /** Over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread */ -static constexpr uint32_t ADDRMAN_TRIED_BUCKETS_PER_GROUP{8}; +inline constexpr uint32_t ADDRMAN_TRIED_BUCKETS_PER_GROUP{8}; /** Over how many buckets entries with new addresses originating from a single group are spread */ -static constexpr uint32_t ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP{64}; +inline constexpr uint32_t ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP{64}; /** Maximum number of times an address can occur in the new table */ -static constexpr int32_t ADDRMAN_NEW_BUCKETS_PER_ADDRESS{8}; +inline constexpr int32_t ADDRMAN_NEW_BUCKETS_PER_ADDRESS{8}; /** How old addresses can maximally be */ -static constexpr auto ADDRMAN_HORIZON{30 * 24h}; +inline constexpr auto ADDRMAN_HORIZON{30 * 24h}; /** After how many failed attempts we give up on a new node */ -static constexpr int32_t ADDRMAN_RETRIES{3}; +inline constexpr int32_t ADDRMAN_RETRIES{3}; /** How many successive failures are allowed ... */ -static constexpr int32_t ADDRMAN_MAX_FAILURES{10}; +inline constexpr int32_t ADDRMAN_MAX_FAILURES{10}; /** ... in at least this duration */ -static constexpr auto ADDRMAN_MIN_FAIL{7 * 24h}; +inline constexpr auto ADDRMAN_MIN_FAIL{7 * 24h}; /** How recent a successful connection should be before we allow an address to be evicted from tried */ -static constexpr auto ADDRMAN_REPLACEMENT{4h}; +inline constexpr auto ADDRMAN_REPLACEMENT{4h}; /** The maximum number of tried addr collisions to store */ -static constexpr size_t ADDRMAN_SET_TRIED_COLLISION_SIZE{10}; +inline constexpr size_t ADDRMAN_SET_TRIED_COLLISION_SIZE{10}; /** The maximum time we'll spend trying to resolve a tried table collision */ -static constexpr auto ADDRMAN_TEST_WINDOW{40min}; +inline constexpr auto ADDRMAN_TEST_WINDOW{40min}; class InvalidAddrManVersionError : public std::ios_base::failure { @@ -54,7 +53,7 @@ class AddrManImpl; class AddrInfo; /** Default for -checkaddrman */ -static constexpr int32_t DEFAULT_ADDRMAN_CONSISTENCY_CHECKS{0}; +inline constexpr int32_t DEFAULT_ADDRMAN_CONSISTENCY_CHECKS{0}; /** Location information for an address in AddrMan */ struct AddressPosition { @@ -73,10 +72,7 @@ struct AddressPosition { const int bucket; const int position; - bool operator==(AddressPosition other) { - return std::tie(tried, multiplicity, bucket, position) == - std::tie(other.tried, other.multiplicity, other.bucket, other.position); - } + bool operator==(const AddressPosition&) const = default; explicit AddressPosition(bool tried_in, int multiplicity_in, int bucket_in, int position_in) : tried{tried_in}, multiplicity{multiplicity_in}, bucket{bucket_in}, position{position_in} {} }; diff --git a/libbitcoinkernel-sys/bitcoin/src/addrman_impl.h b/libbitcoinkernel-sys/bitcoin/src/addrman_impl.h index 88ee92e1..e6e2cab8 100644 --- a/libbitcoinkernel-sys/bitcoin/src/addrman_impl.h +++ b/libbitcoinkernel-sys/bitcoin/src/addrman_impl.h @@ -23,14 +23,14 @@ #include /** Total number of buckets for tried addresses */ -static constexpr int32_t ADDRMAN_TRIED_BUCKET_COUNT_LOG2{8}; -static constexpr int ADDRMAN_TRIED_BUCKET_COUNT{1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2}; +inline constexpr int32_t ADDRMAN_TRIED_BUCKET_COUNT_LOG2{8}; +inline constexpr int ADDRMAN_TRIED_BUCKET_COUNT{1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2}; /** Total number of buckets for new addresses */ -static constexpr int32_t ADDRMAN_NEW_BUCKET_COUNT_LOG2{10}; -static constexpr int ADDRMAN_NEW_BUCKET_COUNT{1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2}; +inline constexpr int32_t ADDRMAN_NEW_BUCKET_COUNT_LOG2{10}; +inline constexpr int ADDRMAN_NEW_BUCKET_COUNT{1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2}; /** Maximum allowed number of entries in buckets for new and tried addresses */ -static constexpr int32_t ADDRMAN_BUCKET_SIZE_LOG2{6}; -static constexpr int ADDRMAN_BUCKET_SIZE{1 << ADDRMAN_BUCKET_SIZE_LOG2}; +inline constexpr int32_t ADDRMAN_BUCKET_SIZE_LOG2{6}; +inline constexpr int ADDRMAN_BUCKET_SIZE{1 << ADDRMAN_BUCKET_SIZE_LOG2}; /** * User-defined type for the internally used nIds diff --git a/libbitcoinkernel-sys/bitcoin/src/banman.h b/libbitcoinkernel-sys/bitcoin/src/banman.h index 93149e63..815e2438 100644 --- a/libbitcoinkernel-sys/bitcoin/src/banman.h +++ b/libbitcoinkernel-sys/bitcoin/src/banman.h @@ -16,10 +16,10 @@ #include // NOTE: When adjusting this, update rpcnet:setban's help ("24h") -static constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban +inline constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban /// How often to dump banned addresses/subnets to disk. -static constexpr std::chrono::minutes DUMP_BANS_INTERVAL{15}; +inline constexpr std::chrono::minutes DUMP_BANS_INTERVAL{15}; class CClientUIInterface; class CNetAddr; diff --git a/libbitcoinkernel-sys/bitcoin/src/bech32.h b/libbitcoinkernel-sys/bitcoin/src/bech32.h index 9a43a58f..f16aa855 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bech32.h +++ b/libbitcoinkernel-sys/bitcoin/src/bech32.h @@ -23,8 +23,8 @@ namespace bech32 { -static constexpr size_t CHECKSUM_SIZE = 6; -static constexpr char SEPARATOR = '1'; +inline constexpr size_t CHECKSUM_SIZE = 6; +inline constexpr char SEPARATOR = '1'; enum class Encoding { INVALID, //!< Failed decoding diff --git a/libbitcoinkernel-sys/bitcoin/src/bench/CMakeLists.txt b/libbitcoinkernel-sys/bitcoin/src/bench/CMakeLists.txt index 3c81e798..45ba7c40 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bench/CMakeLists.txt +++ b/libbitcoinkernel-sys/bitcoin/src/bench/CMakeLists.txt @@ -52,6 +52,7 @@ add_executable(bench_bitcoin strencodings.cpp txgraph.cpp txorphanage.cpp + uint256_blob.cpp util_time.cpp verify_script.cpp ) diff --git a/libbitcoinkernel-sys/bitcoin/src/bench/blockencodings.cpp b/libbitcoinkernel-sys/bitcoin/src/bench/blockencodings.cpp index 274474d4..9759dd58 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bench/blockencodings.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/bench/blockencodings.cpp @@ -88,9 +88,7 @@ static void BlockEncodingBench(benchmark::Bench& bench, size_t n_pool, size_t n_ tx.vin.resize(1); tx.vin[0].scriptSig = CScript() << sigspam; tx.vin[0].scriptWitness.stack.push_back({1}); - tx.vout.resize(1); - tx.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; - tx.vout[0].nValue = i; + tx.vout = {CTxOut{CAmount(i), CScript() << OP_1 << OP_EQUAL}}; refs.push_back(MakeTransactionRef(tx)); } diff --git a/libbitcoinkernel-sys/bitcoin/src/bench/coin_selection.cpp b/libbitcoinkernel-sys/bitcoin/src/bench/coin_selection.cpp index 5c54cafc..396d21d4 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bench/coin_selection.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/bench/coin_selection.cpp @@ -76,7 +76,7 @@ static void CoinSelection(benchmark::Bench& bench) // Create coins from the amounts assigning them various output types wallet::CoinsResult available_coins; for (const auto& wtx : wtxs) { - const auto txout = wtx->tx->vout.at(0); + const auto txout = wtx->GetTx()->vout.at(0); OutputType outtype; int input_bytes; int y{det_rand.randrange(100)}; diff --git a/libbitcoinkernel-sys/bitcoin/src/bench/crypto_hash.cpp b/libbitcoinkernel-sys/bitcoin/src/bench/crypto_hash.cpp index 4d0660db..82744897 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bench/crypto_hash.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/bench/crypto_hash.cpp @@ -190,10 +190,10 @@ static void SHA512(benchmark::Bench& bench) }); } -static void SipHash_32b(benchmark::Bench& bench) +static void SipHash24_32b(benchmark::Bench& bench) { FastRandomContext rng{/*fDeterministic=*/true}; - PresaltedSipHasher presalted_sip_hasher(rng.rand64(), rng.rand64()); + PresaltedSipHasher presalted_sip_hasher{rng.rand64(), rng.rand64()}; auto val{rng.rand256()}; auto i{0U}; bench.run([&] { @@ -203,6 +203,49 @@ static void SipHash_32b(benchmark::Bench& bench) }); } +static void SipHash24_36b(benchmark::Bench& bench) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + PresaltedSipHasher presalted_sip_hasher{rng.rand64(), rng.rand64()}; + auto val{rng.rand256()}; + uint32_t extra{rng.rand32()}; + auto i{0U}; + bench.run([&] { + ankerl::nanobench::doNotOptimizeAway(presalted_sip_hasher(val, extra)); + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; + extra += i; + }); +} + +static void SipHash13UJ_32b(benchmark::Bench& bench) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + SipHasher13UJ sip_hasher{rng.rand64(), rng.rand64()}; + auto val{rng.rand256()}; + auto i{0U}; + bench.run([&] { + ankerl::nanobench::doNotOptimizeAway(sip_hasher.Hash(val)); + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; + }); +} + +static void SipHash13UJ_36b(benchmark::Bench& bench) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + SipHasher13UJ sip_hasher{rng.rand64(), rng.rand64()}; + auto val{rng.rand256()}; + uint32_t extra{rng.rand32()}; + auto i{0U}; + bench.run([&] { + ankerl::nanobench::doNotOptimizeAway(sip_hasher.Hash(val, uint64_t{extra})); + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; + extra += i; + }); +} + static void MuHash(benchmark::Bench& bench) { MuHash3072 acc; @@ -273,7 +316,10 @@ BENCHMARK(SHA256_32b_STANDARD); BENCHMARK(SHA256_32b_SSE4); BENCHMARK(SHA256_32b_AVX2); BENCHMARK(SHA256_32b_SHANI); -BENCHMARK(SipHash_32b); +BENCHMARK(SipHash24_32b); +BENCHMARK(SipHash24_36b); +BENCHMARK(SipHash13UJ_32b); +BENCHMARK(SipHash13UJ_36b); BENCHMARK(SHA256D64_1024_STANDARD); BENCHMARK(SHA256D64_1024_SSE4); BENCHMARK(SHA256D64_1024_AVX2); diff --git a/libbitcoinkernel-sys/bitcoin/src/bench/mempool_ephemeral_spends.cpp b/libbitcoinkernel-sys/bitcoin/src/bench/mempool_ephemeral_spends.cpp index f88643c5..d7c08724 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bench/mempool_ephemeral_spends.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/bench/mempool_ephemeral_spends.cpp @@ -50,9 +50,8 @@ static void MempoolCheckEphemeralSpends(benchmark::Bench& bench) tx1.vin.resize(1); tx1.vout.resize(number_outputs); for (size_t i = 0; i < tx1.vout.size(); i++) { - tx1.vout[i].scriptPubKey = CScript(); // Each output progressively larger - tx1.vout[i].nValue = i * CENT; + tx1.vout[i] = CTxOut{CAmount(i) * CENT, CScript()}; } const auto& parent_txid = tx1.GetHash(); @@ -60,9 +59,8 @@ static void MempoolCheckEphemeralSpends(benchmark::Bench& bench) // Spends all outputs of tx1, other details don't matter CMutableTransaction tx2; tx2.vin.resize(tx1.vout.size()); - for (size_t i = 0; i < tx2.vin.size(); i++) { - tx2.vin[i].prevout.hash = parent_txid; - tx2.vin[i].prevout.n = i; + for (uint32_t i{0}; i < tx2.vin.size(); ++i) { + tx2.vin[i].prevout = COutPoint{parent_txid, i}; } tx2.vout.resize(1); diff --git a/libbitcoinkernel-sys/bitcoin/src/bench/mempool_stress.cpp b/libbitcoinkernel-sys/bitcoin/src/bench/mempool_stress.cpp index ab1146e1..1d227070 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bench/mempool_stress.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/bench/mempool_stress.cpp @@ -156,7 +156,7 @@ static void ComplexMemPool(benchmark::Bench& bench) // in the same state at the end of the function, so we benchmark both // mining a block and reorging the block's contents back into the mempool. bench.run([&]() NO_THREAD_SAFETY_ANALYSIS { - pool.removeForBlock(tx_remove_for_block, /*nBlockHeight=*/100); + pool.removeForBlock(tx_remove_for_block); for (auto& tx: tx_remove_for_block) { AddTx(tx, pool, det_rand); } diff --git a/libbitcoinkernel-sys/bitcoin/src/bench/nanobench.h b/libbitcoinkernel-sys/bitcoin/src/bench/nanobench.h index a66e92a4..ffcc4802 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bench/nanobench.h +++ b/libbitcoinkernel-sys/bitcoin/src/bench/nanobench.h @@ -1369,6 +1369,7 @@ void doNotOptimizeAway(T const& val) { } // namespace ankerl #if defined(ANKERL_NANOBENCH_IMPLEMENT) +// NOLINTBEGIN(misc-definitions-in-headers) /////////////////////////////////////////////////////////////////////////////////////////////////// // implementation part - only visible in .cpp @@ -3563,5 +3564,6 @@ std::ostream& operator<<(std::ostream& os, std::vector } // namespace nanobench } // namespace ankerl +// NOLINTEND(misc-definitions-in-headers) #endif // ANKERL_NANOBENCH_IMPLEMENT #endif // ANKERL_NANOBENCH_H_INCLUDED diff --git a/libbitcoinkernel-sys/bitcoin/src/bench/uint256_blob.cpp b/libbitcoinkernel-sys/bitcoin/src/bench/uint256_blob.cpp new file mode 100644 index 00000000..fba0a0e8 --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/src/bench/uint256_blob.cpp @@ -0,0 +1,91 @@ +// Copyright (c) The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://opensource.org/license/mit. + +#include +#include +#include + +#include +#include +#include +#include + +namespace { + +enum class Difference { + NONE, + FIRST_BYTE, + LAST_BYTE, +}; + +constexpr size_t NUM_PAIRS{4'096}; + +std::vector> MakePairs(Difference difference) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + std::vector> pairs; + pairs.reserve(NUM_PAIRS); + + for (size_t i{0}; i < NUM_PAIRS; ++i) { + uint256 lhs{rng.rand256()}; + uint256 rhs{lhs}; + if (difference != Difference::NONE) { + const size_t position{difference == Difference::FIRST_BYTE ? 0 : uint256::size() - 1}; + lhs.begin()[position] = i % 2 == 0 ? 0 : 255; + rhs.begin()[position] = i % 2 == 0 ? 255 : 0; + } + pairs.emplace_back(lhs, rhs); + } + return pairs; +} + +template +void Comparison(benchmark::Bench& bench, Difference difference, Comparator comparator) +{ + const auto pairs{MakePairs(difference)}; + bench.batch(pairs.size()).unit("comparison").run([&] { + for (const auto& [lhs, rhs] : pairs) { + ankerl::nanobench::doNotOptimizeAway(comparator(lhs, rhs)); + } + }); +} + +void Uint256EqualIdentical(benchmark::Bench& bench) +{ + Comparison(bench, Difference::NONE, [](const uint256& lhs, const uint256& rhs) { return lhs == rhs; }); +} + +void Uint256EqualFirstByteDifferent(benchmark::Bench& bench) +{ + Comparison(bench, Difference::FIRST_BYTE, [](const uint256& lhs, const uint256& rhs) { return lhs == rhs; }); +} + +void Uint256EqualLastByteDifferent(benchmark::Bench& bench) +{ + Comparison(bench, Difference::LAST_BYTE, [](const uint256& lhs, const uint256& rhs) { return lhs == rhs; }); +} + +void Uint256LessIdentical(benchmark::Bench& bench) +{ + Comparison(bench, Difference::NONE, [](const uint256& lhs, const uint256& rhs) { return lhs < rhs; }); +} + +void Uint256LessFirstByteDifferent(benchmark::Bench& bench) +{ + Comparison(bench, Difference::FIRST_BYTE, [](const uint256& lhs, const uint256& rhs) { return lhs < rhs; }); +} + +void Uint256LessLastByteDifferent(benchmark::Bench& bench) +{ + Comparison(bench, Difference::LAST_BYTE, [](const uint256& lhs, const uint256& rhs) { return lhs < rhs; }); +} + +} // namespace + +BENCHMARK(Uint256EqualIdentical); +BENCHMARK(Uint256EqualFirstByteDifferent); +BENCHMARK(Uint256EqualLastByteDifferent); +BENCHMARK(Uint256LessIdentical); +BENCHMARK(Uint256LessFirstByteDifferent); +BENCHMARK(Uint256LessLastByteDifferent); diff --git a/libbitcoinkernel-sys/bitcoin/src/bip324.h b/libbitcoinkernel-sys/bitcoin/src/bip324.h index 821cc3f7..276f71e4 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bip324.h +++ b/libbitcoinkernel-sys/bitcoin/src/bip324.h @@ -15,7 +15,7 @@ #include #include -static constexpr unsigned BIP324_SHORTIDS_IMPLEMENTED{38}; +inline constexpr unsigned BIP324_SHORTIDS_IMPLEMENTED{38}; /** The BIP324 packet cipher, encapsulating its key derivation, stream cipher, and AEAD. */ class BIP324Cipher diff --git a/libbitcoinkernel-sys/bitcoin/src/bitcoin-util.cpp b/libbitcoinkernel-sys/bitcoin/src/bitcoin-util.cpp index f17c7a0d..7e774685 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bitcoin-util.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/bitcoin-util.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,7 @@ static void SetupBitcoinUtilArgs(ArgsManager &argsman) argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddCommand("grind", "Perform proof of work on hex header string"); - argsman.AddCommand("netmagic", "Get the network magic bytes of the selected chain"); + argsman.AddCommand("getchainparams", "Get hardcoded parameters for the selected chain"); SetupChainParamsBaseOptions(argsman); } @@ -151,14 +152,60 @@ static int Grind(const std::vector& args, std::string& strPrint) return EXIT_SUCCESS; } -static int NetMagic(const std::vector& args, std::string& strPrint) +static int GetChainParams(const std::vector& args, std::string& strPrint) { if (!args.empty()) { - strPrint = "netmagic does not take arguments"; + strPrint = "getchainparams does not take arguments"; return EXIT_FAILURE; } - strPrint = HexStr(Params().MessageStart()); + const auto& params = Params(); + const auto& consensus = params.GetConsensus(); + + UniValue result{UniValue::VOBJ}; + result.pushKV("chain", params.GetChainTypeString()); + result.pushKV("test_chain", params.IsTestChain()); + result.pushKV("genesis", HexStr(consensus.hashGenesisBlock)); + result.pushKV("subsidy_halving_interval", consensus.nSubsidyHalvingInterval); + + if (consensus.signet_blocks) { + UniValue signet{UniValue::VOBJ}; + signet.pushKV("challenge", HexStr(consensus.signet_challenge)); + result.pushKV("signet", signet); + } + + { + UniValue pow{UniValue::VOBJ}; + pow.pushKV("limit", consensus.powLimit.ToString()); + if (!consensus.fPowNoRetargeting) { + pow.pushKV("target_spacing", TicksSeconds(consensus.PowTargetSpacing())); + pow.pushKV("difficulty_retarget_interval", consensus.DifficultyAdjustmentInterval()); + std::string mindiff_blocks = (consensus.fPowAllowMinDifficultyBlocks ? + (consensus.enforce_BIP94 ? "bip94" : "yes") : "no"); + pow.pushKV("mindiff_blocks", mindiff_blocks); + } + result.pushKV("pow", pow); + } + + { + UniValue net{UniValue::VOBJ}; + net.pushKV("default_port", params.GetDefaultPort()); + net.pushKV("magic", HexStr(params.MessageStart())); + UniValue dns{UniValue::VARR}; + for (const auto& seed : params.DNSSeeds()) { + dns.push_back(seed); + } + net.pushKV("dns_seeds", dns); + result.pushKV("net", net); + } + + { + UniValue addr{UniValue::VOBJ}; + addr.pushKV("bech32_hrp", params.Bech32HRP()); + result.pushKV("addresses", addr); + } + + strPrint = result.write(/*prettyIndent=*/2); return EXIT_SUCCESS; } @@ -191,8 +238,8 @@ MAIN_FUNCTION try { if (cmd->command == "grind") { ret = Grind(cmd->args, strPrint); - } else if (cmd->command == "netmagic") { - ret = NetMagic(cmd->args, strPrint); + } else if (cmd->command == "getchainparams") { + ret = GetChainParams(cmd->args, strPrint); } else { assert(false); // unknown command should be caught earlier } diff --git a/libbitcoinkernel-sys/bitcoin/src/blockencodings.cpp b/libbitcoinkernel-sys/bitcoin/src/blockencodings.cpp index c2846539..afa9df4f 100644 --- a/libbitcoinkernel-sys/bitcoin/src/blockencodings.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/blockencodings.cpp @@ -113,25 +113,25 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c if (shorttxids.size() != cmpctblock.shorttxids.size()) return READ_STATUS_FAILED; // Short ID collision - std::vector have_txn(txn_available.size()); + enum class TxSource : uint8_t { NONE, MEMPOOL, EXTRA, COLLIDED }; + std::vector tx_source(txn_available.size(), TxSource::NONE); { LOCK(pool->cs); for (const auto& [wtxid, txit] : pool->txns_randomized) { uint64_t shortid = cmpctblock.GetShortID(wtxid); std::unordered_map::iterator idit = shorttxids.find(shortid); if (idit != shorttxids.end()) { - if (!have_txn[idit->second]) { + if (tx_source[idit->second] == TxSource::NONE) { txn_available[idit->second] = txit->GetSharedTx(); - have_txn[idit->second] = true; + tx_source[idit->second] = TxSource::MEMPOOL; mempool_count++; - } else { + } else if (tx_source[idit->second] != TxSource::COLLIDED) { // If we find two mempool txn that match the short id, just request it. // This should be rare enough that the extra bandwidth doesn't matter, // but eating a round-trip due to FillBlock failure would be annoying - if (txn_available[idit->second]) { - txn_available[idit->second].reset(); - mempool_count--; - } + txn_available[idit->second].reset(); + mempool_count--; + tx_source[idit->second] = TxSource::COLLIDED; } } // Though ideally we'd continue scanning for the two-txn-match-shortid case, @@ -146,24 +146,23 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c uint64_t shortid = cmpctblock.GetShortID(extra_txn[i].first); std::unordered_map::iterator idit = shorttxids.find(shortid); if (idit != shorttxids.end()) { - if (!have_txn[idit->second]) { + if (tx_source[idit->second] == TxSource::NONE) { txn_available[idit->second] = extra_txn[i].second; - have_txn[idit->second] = true; + tx_source[idit->second] = TxSource::EXTRA; mempool_count++; extra_count++; - } else { + } else if (tx_source[idit->second] != TxSource::COLLIDED && + txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) { // If we find two mempool/extra txn that match the short id, just // request it. // This should be rare enough that the extra bandwidth doesn't matter, // but eating a round-trip due to FillBlock failure would be annoying // Note that we don't want duplication between extra_txn and mempool to // trigger this case, so we compare witness hashes first - if (txn_available[idit->second] && - txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) { - txn_available[idit->second].reset(); - mempool_count--; - extra_count--; - } + txn_available[idit->second].reset(); + mempool_count--; + extra_count -= (tx_source[idit->second] == TxSource::EXTRA); + tx_source[idit->second] = TxSource::COLLIDED; } } // Though ideally we'd continue scanning for the two-txn-match-shortid case, diff --git a/libbitcoinkernel-sys/bitcoin/src/blockfilter.h b/libbitcoinkernel-sys/bitcoin/src/blockfilter.h index 225d3b16..26ddfb61 100644 --- a/libbitcoinkernel-sys/bitcoin/src/blockfilter.h +++ b/libbitcoinkernel-sys/bitcoin/src/blockfilter.h @@ -87,8 +87,8 @@ class GCSFilter bool MatchAny(const ElementSet& elements) const; }; -constexpr uint8_t BASIC_FILTER_P = 19; -constexpr uint32_t BASIC_FILTER_M = 784931; +inline constexpr uint8_t BASIC_FILTER_P = 19; +inline constexpr uint32_t BASIC_FILTER_M = 784931; enum class BlockFilterType : uint8_t { diff --git a/libbitcoinkernel-sys/bitcoin/src/chain.h b/libbitcoinkernel-sys/bitcoin/src/chain.h index 7701e926..1ca21845 100644 --- a/libbitcoinkernel-sys/bitcoin/src/chain.h +++ b/libbitcoinkernel-sys/bitcoin/src/chain.h @@ -26,7 +26,7 @@ * Maximum amount of time that a block timestamp is allowed to exceed the * current time before the block will be accepted. */ -static constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; +inline constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; /** * Timestamp window used as a grace period by code that compares external @@ -34,10 +34,10 @@ static constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; * to block timestamps. This should be set at least as high as * MAX_FUTURE_BLOCK_TIME. */ -static constexpr int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; +inline constexpr int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; //! Init values for CBlockIndex nSequenceId when loaded from disk -static constexpr int32_t SEQ_ID_BEST_CHAIN_FROM_DISK = 0; -static constexpr int32_t SEQ_ID_INIT_FROM_DISK = 1; +inline constexpr int32_t SEQ_ID_BEST_CHAIN_FROM_DISK = 0; +inline constexpr int32_t SEQ_ID_INIT_FROM_DISK = 1; enum BlockStatus : uint32_t { //! Unused. diff --git a/libbitcoinkernel-sys/bitcoin/src/chainparamsseeds.h b/libbitcoinkernel-sys/bitcoin/src/chainparamsseeds.h index 5cf8d6ba..729d7050 100644 --- a/libbitcoinkernel-sys/bitcoin/src/chainparamsseeds.h +++ b/libbitcoinkernel-sys/bitcoin/src/chainparamsseeds.h @@ -10,7 +10,7 @@ * * Each line contains a BIP155 serialized (networkID, addr, port) tuple. */ -static const uint8_t chainparams_seed_main[] = { +inline constexpr uint8_t chainparams_seed_main[] = { 0x06,0x10,0xfc,0x11,0xf7,0x69,0x16,0xe6,0x36,0x11,0x58,0xae,0x1d,0x4a,0xfc,0xf7,0x57,0xa4,0x20,0x8d, 0x06,0x10,0xfc,0x17,0x43,0x69,0x54,0x14,0x4b,0x1f,0x56,0x89,0xd3,0xed,0x40,0x39,0x33,0x5c,0x20,0x8d, 0x06,0x10,0xfc,0x1f,0x22,0xc3,0x95,0xdc,0xa3,0xaf,0x4a,0x93,0x82,0x51,0xbe,0xb9,0x18,0x58,0x20,0x8d, @@ -2072,7 +2072,7 @@ static const uint8_t chainparams_seed_main[] = { 0x04,0x20,0xce,0x07,0x95,0xf3,0xa5,0xc1,0x90,0xc4,0x50,0xd5,0x22,0x86,0xa7,0x26,0x37,0x08,0xa2,0x31,0x1e,0x0d,0x77,0x48,0x0d,0x46,0xe0,0xfb,0x3d,0x71,0x60,0xe7,0x1d,0xce,0x20,0x8d, }; -static const uint8_t chainparams_seed_signet[] = { +inline constexpr uint8_t chainparams_seed_signet[] = { 0x06,0x10,0xfc,0x1f,0x22,0xc3,0x95,0xdc,0xa3,0xaf,0x4a,0x93,0x82,0x51,0xbe,0xb9,0x18,0x58,0x95,0xbd, 0x05,0x20,0xd7,0x4d,0xd9,0xc4,0x7c,0x80,0x24,0x1d,0x48,0x2f,0x52,0xba,0x2a,0xaf,0x5d,0xf2,0xfc,0x04,0x58,0x56,0x4a,0x61,0x0f,0xde,0x4e,0xd8,0x13,0x55,0x98,0x55,0x53,0xc1,0x00,0x00, 0x05,0x20,0xd8,0xaf,0x32,0x40,0x0d,0x25,0x72,0x91,0xf5,0x14,0x2a,0xa7,0x7b,0x9f,0x6b,0xe8,0x02,0x9f,0x16,0x5e,0xa0,0xe0,0x6d,0x85,0xcc,0x79,0xf2,0xe2,0xc1,0x2b,0xe0,0x20,0x00,0x00, @@ -2245,7 +2245,7 @@ static const uint8_t chainparams_seed_signet[] = { 0x04,0x20,0xc9,0x95,0x5a,0xf7,0x9a,0x27,0x09,0x6a,0xa2,0x24,0x65,0xb7,0x07,0xf0,0x28,0xee,0x8b,0xa9,0x5e,0x7c,0x37,0x19,0x14,0xc4,0x36,0x73,0x42,0xd2,0x87,0xae,0xa2,0x47,0x95,0xbd, }; -static const uint8_t chainparams_seed_test[] = { +inline constexpr uint8_t chainparams_seed_test[] = { 0x06,0x10,0xfc,0x1f,0x22,0xc3,0x95,0xdc,0xa3,0xaf,0x4a,0x93,0x82,0x51,0xbe,0xb9,0x18,0x58,0x47,0x9d, 0x05,0x20,0x39,0x06,0xc0,0x95,0x12,0xe1,0xf8,0x86,0xc2,0x36,0x76,0xa9,0x96,0x2a,0x9d,0xbd,0x3d,0x70,0x43,0xfc,0x99,0xbf,0x27,0x15,0xa4,0x9c,0x10,0xa1,0xd5,0xa3,0x9d,0x52,0x00,0x00, 0x05,0x20,0x40,0x81,0xae,0x55,0xb2,0x9d,0xd0,0xff,0x99,0x51,0xd8,0xbc,0x35,0xb2,0x06,0xb7,0x1c,0xf6,0x16,0x35,0xae,0xc6,0xf7,0xa4,0x72,0xf8,0x37,0x41,0x8e,0x91,0x7b,0x2e,0x00,0x00, @@ -2429,7 +2429,7 @@ static const uint8_t chainparams_seed_test[] = { 0x04,0x20,0xcc,0x99,0x76,0x52,0x43,0xcc,0x45,0x0a,0x49,0x5d,0x3f,0xa5,0x82,0xc3,0xc0,0xdb,0xcf,0xe5,0xda,0xfb,0xb3,0xd0,0xb9,0xd1,0xbc,0x1b,0x15,0x19,0xed,0xe0,0xd1,0x5f,0x47,0x9d, }; -static const uint8_t chainparams_seed_testnet4[] = { +inline constexpr uint8_t chainparams_seed_testnet4[] = { 0x06,0x10,0xfc,0x1f,0x22,0xc3,0x95,0xdc,0xa3,0xaf,0x4a,0x93,0x82,0x51,0xbe,0xb9,0x18,0x58,0xbc,0xcd, 0x05,0x20,0xd3,0xbc,0x25,0x95,0x63,0x7f,0x34,0x02,0x18,0x69,0x91,0x9a,0x79,0x57,0x10,0xc0,0xe0,0xf5,0xcd,0x84,0x56,0x95,0xec,0x43,0xa4,0x9d,0xba,0x1b,0xb3,0xea,0x34,0x60,0x00,0x00, 0x05,0x20,0xd8,0xee,0x64,0x35,0x6c,0x53,0xe7,0x40,0xb8,0xc3,0x15,0x60,0x5b,0x9c,0x66,0x3d,0xbb,0xd9,0x7c,0x99,0xcc,0x3a,0x3a,0xf6,0xcb,0xd5,0xd4,0x51,0x98,0x04,0x68,0xad,0x00,0x00, diff --git a/libbitcoinkernel-sys/bitcoin/src/clientversion.h b/libbitcoinkernel-sys/bitcoin/src/clientversion.h index f4822a12..cbdb62b2 100644 --- a/libbitcoinkernel-sys/bitcoin/src/clientversion.h +++ b/libbitcoinkernel-sys/bitcoin/src/clientversion.h @@ -23,7 +23,7 @@ #include #include -static const int CLIENT_VERSION = +inline constexpr int CLIENT_VERSION = 10000 * CLIENT_VERSION_MAJOR + 100 * CLIENT_VERSION_MINOR + 1 * CLIENT_VERSION_BUILD; diff --git a/libbitcoinkernel-sys/bitcoin/src/cluster_linearize.h b/libbitcoinkernel-sys/bitcoin/src/cluster_linearize.h index 23cb98f4..7b262edb 100644 --- a/libbitcoinkernel-sys/bitcoin/src/cluster_linearize.h +++ b/libbitcoinkernel-sys/bitcoin/src/cluster_linearize.h @@ -954,11 +954,16 @@ class SpanningForestState Assume(m_chunk_idxs[bottom_idx]); auto& top_chunk_info = m_set_info[top_idx]; auto& bottom_chunk_info = m_set_info[bottom_idx]; - // Count the number of dependencies between bottom_chunk and top_chunk. + // Count the number of dependencies between bottom_chunk and top_chunk, remembering the + // per-transaction counts so the picking loop below does not need to recompute the + // intersections. unsigned num_deps{0}; + std::array counts; for (auto tx_idx : top_chunk_info.transactions) { auto& tx_data = m_tx_data[tx_idx]; - num_deps += (tx_data.children & bottom_chunk_info.transactions).Count(); + auto count = (tx_data.children & bottom_chunk_info.transactions).Count(); + counts[tx_idx] = count; + num_deps += count; } m_cost.MergeChunksMid(/*num_txns=*/top_chunk_info.transactions.Count()); Assume(num_deps > 0); @@ -967,10 +972,10 @@ class SpanningForestState unsigned num_steps = 0; for (auto tx_idx : top_chunk_info.transactions) { ++num_steps; - auto& tx_data = m_tx_data[tx_idx]; - auto intersect = tx_data.children & bottom_chunk_info.transactions; - auto count = intersect.Count(); + auto count = counts[tx_idx]; if (pick < count) { + auto& tx_data = m_tx_data[tx_idx]; + auto intersect = tx_data.children & bottom_chunk_info.transactions; for (auto child_idx : intersect) { if (pick == 0) { m_cost.MergeChunksEnd(/*num_steps=*/num_steps); @@ -1183,6 +1188,7 @@ class SpanningForestState m_tx_data.resize(depgraph.PositionRange()); m_set_info.resize(num_transactions); m_reachable.resize(num_transactions); + m_suboptimal_chunks.reserve(num_transactions); size_t num_chunks = 0; size_t num_deps = 0; for (auto tx_idx : m_transaction_idxs) { @@ -1471,16 +1477,22 @@ class SpanningForestState /** A heap with all chunks (by set index) that can currently be included, sorted by * chunk feerate (high to low), chunk size (small to large), and by least maximum element * according to the fallback order (which is the second pair element). */ - std::vector> ready_chunks; + std::array, SetType::Size()> ready_chunks; + /** The number of entries of ready_chunks in use. */ + unsigned num_ready_chunks{0}; /** For every chunk, indexed by SetIdx, the number of unmet dependencies the chunk has on * other chunks (not including dependencies within the chunk itself). */ - std::vector chunk_deps(m_set_info.size(), 0); + std::array chunk_deps; + std::fill_n(chunk_deps.begin(), m_set_info.size(), TxIdx{0}); /** For every transaction, indexed by TxIdx, the number of unmet dependencies the * transaction has. */ - std::vector tx_deps(m_tx_data.size(), 0); + std::array tx_deps; + std::fill_n(tx_deps.begin(), m_tx_data.size(), TxIdx{0}); /** A heap with all transactions within the current chunk that can be included, sorted by * tx feerate (high to low), tx size (small to large), and fallback order. */ - std::vector ready_tx; + std::array ready_tx; + /** The number of entries of ready_tx in use. */ + unsigned num_ready_tx{0}; // Populate chunk_deps and tx_deps. unsigned num_deps{0}; for (TxIdx chl_idx : m_transaction_idxs) { @@ -1549,31 +1561,31 @@ class SpanningForestState // Construct a heap with all chunks that have no out-of-chunk dependencies. for (SetIdx chunk_idx : m_chunk_idxs) { if (chunk_deps[chunk_idx] == 0) { - ready_chunks.emplace_back(chunk_idx, max_fallback_fn(chunk_idx)); + ready_chunks[num_ready_chunks++] = {chunk_idx, max_fallback_fn(chunk_idx)}; } } - std::make_heap(ready_chunks.begin(), ready_chunks.end(), chunk_cmp_fn); + std::make_heap(ready_chunks.begin(), ready_chunks.begin() + num_ready_chunks, chunk_cmp_fn); // Pop chunks off the heap. - while (!ready_chunks.empty()) { + while (num_ready_chunks > 0) { auto [chunk_idx, _rnd] = ready_chunks.front(); - std::pop_heap(ready_chunks.begin(), ready_chunks.end(), chunk_cmp_fn); - ready_chunks.pop_back(); + std::pop_heap(ready_chunks.begin(), ready_chunks.begin() + num_ready_chunks, chunk_cmp_fn); + --num_ready_chunks; Assume(chunk_deps[chunk_idx] == 0); const auto& chunk_txn = m_set_info[chunk_idx].transactions; // Build heap of all includable transactions in chunk. - Assume(ready_tx.empty()); + Assume(num_ready_tx == 0); for (TxIdx tx_idx : chunk_txn) { - if (tx_deps[tx_idx] == 0) ready_tx.push_back(tx_idx); + if (tx_deps[tx_idx] == 0) ready_tx[num_ready_tx++] = tx_idx; } - Assume(!ready_tx.empty()); - std::make_heap(ready_tx.begin(), ready_tx.end(), tx_cmp_fn); + Assume(num_ready_tx > 0); + std::make_heap(ready_tx.begin(), ready_tx.begin() + num_ready_tx, tx_cmp_fn); // Pick transactions from the ready heap, append them to linearization, and decrement // dependency counts. - while (!ready_tx.empty()) { + while (num_ready_tx > 0) { // Pop an element from the tx_ready heap. auto tx_idx = ready_tx.front(); - std::pop_heap(ready_tx.begin(), ready_tx.end(), tx_cmp_fn); - ready_tx.pop_back(); + std::pop_heap(ready_tx.begin(), ready_tx.begin() + num_ready_tx, tx_cmp_fn); + --num_ready_tx; // Append to linearization. ret.push_back(tx_idx); // Decrement dependency counts. @@ -1584,16 +1596,16 @@ class SpanningForestState Assume(tx_deps[chl_idx] > 0); if (--tx_deps[chl_idx] == 0 && chunk_txn[chl_idx]) { // Child tx has no dependencies left, and is in this chunk. Add it to the tx heap. - ready_tx.push_back(chl_idx); - std::push_heap(ready_tx.begin(), ready_tx.end(), tx_cmp_fn); + ready_tx[num_ready_tx++] = chl_idx; + std::push_heap(ready_tx.begin(), ready_tx.begin() + num_ready_tx, tx_cmp_fn); } // Decrement chunk dependency count if this is out-of-chunk dependency. if (chl_data.chunk_idx != chunk_idx) { Assume(chunk_deps[chl_data.chunk_idx] > 0); if (--chunk_deps[chl_data.chunk_idx] == 0) { // Child chunk has no dependencies left. Add it to the chunk heap. - ready_chunks.emplace_back(chl_data.chunk_idx, max_fallback_fn(chl_data.chunk_idx)); - std::push_heap(ready_chunks.begin(), ready_chunks.end(), chunk_cmp_fn); + ready_chunks[num_ready_chunks++] = {chl_data.chunk_idx, max_fallback_fn(chl_data.chunk_idx)}; + std::push_heap(ready_chunks.begin(), ready_chunks.begin() + num_ready_chunks, chunk_cmp_fn); } } } diff --git a/libbitcoinkernel-sys/bitcoin/src/coins.cpp b/libbitcoinkernel-sys/bitcoin/src/coins.cpp index 7bb05f68..3d3e63fa 100644 --- a/libbitcoinkernel-sys/bitcoin/src/coins.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/coins.cpp @@ -19,6 +19,13 @@ TRACEPOINT_SEMAPHORE(utxocache, add); TRACEPOINT_SEMAPHORE(utxocache, spent); TRACEPOINT_SEMAPHORE(utxocache, uncache); +SaltedCoinsCacheHasher::SaltedCoinsCacheHasher(bool deterministic) + : m_hasher{ + deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64(), + deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()} +{ +} + CoinsViewEmpty& CoinsViewEmpty::Get() { static CoinsViewEmpty instance; @@ -35,7 +42,7 @@ std::optional CCoinsViewCache::PeekCoin(const COutPoint& outpoint) const CCoinsViewCache::CCoinsViewCache(CCoinsView* in_base, bool deterministic) : CCoinsViewBacked(in_base), m_deterministic(deterministic), - cacheCoins(0, SaltedOutpointHasher(/*deterministic=*/deterministic), CCoinsMap::key_equal{}, &m_cache_coins_memory_resource) + cacheCoins(0, SaltedCoinsCacheHasher{/*deterministic=*/deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource) { m_sentinel.second.SelfRef(m_sentinel); } @@ -113,9 +120,9 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi (bool)it->second.coin.IsCoinBase()); } -void CCoinsViewCache::EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coin) { +void CCoinsViewCache::EmplaceCoinInternalDANGER(const COutPoint& outpoint, Coin&& coin) { const auto mem_usage{coin.DynamicMemoryUsage()}; - auto [it, inserted] = cacheCoins.try_emplace(std::move(outpoint), std::move(coin)); + auto [it, inserted] = cacheCoins.try_emplace(outpoint, std::move(coin)); if (inserted) { CCoinsCacheEntry::SetDirty(*it, m_sentinel); ++m_dirty_count; @@ -331,7 +338,7 @@ void CCoinsViewCache::ReallocateCache() cacheCoins.~CCoinsMap(); m_cache_coins_memory_resource.~CCoinsMapMemoryResource(); ::new (&m_cache_coins_memory_resource) CCoinsMapMemoryResource{}; - ::new (&cacheCoins) CCoinsMap{0, SaltedOutpointHasher{/*deterministic=*/m_deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource}; + ::new (&cacheCoins) CCoinsMap{0, SaltedCoinsCacheHasher{/*deterministic=*/m_deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource}; } void CCoinsViewCache::SanityCheck() const @@ -376,7 +383,7 @@ CCoinsViewCache::ResetGuard CoinsViewOverlay::StartFetching(const CBlock& block // Loop through the block inputs and set their prevouts in the queue. // Filter inputs that spend outputs created earlier in the same block. These outputs will be created // directly in the cache from the tx that creates them, so they will not be requested from a base view. - std::unordered_set earlier_txids; + std::unordered_set earlier_txids; earlier_txids.reserve(block.vtx.size()); for (const auto& tx : block.vtx | std::views::drop(1)) { for (const auto& input : tx->vin) { diff --git a/libbitcoinkernel-sys/bitcoin/src/coins.h b/libbitcoinkernel-sys/bitcoin/src/coins.h index 6e8643cc..6fcf1092 100644 --- a/libbitcoinkernel-sys/bitcoin/src/coins.h +++ b/libbitcoinkernel-sys/bitcoin/src/coins.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,6 @@ #include #include #include -#include #include #include @@ -219,6 +219,43 @@ struct CCoinsCacheEntry } }; +/** + * SipHash-1-3-UJ based hasher for the coins cache and related coins containers. + * + * Retained entries identify real transaction outputs, so their keys contain computed txids. + * Missing-input lookups may contain arbitrary claimed prevouts, but FetchCoin() immediately + * erases their temporary entries when the backend lookup fails, so non-hash keys cannot + * accumulate. + * + * The assumeutxo loader assumes snapshot txids are valid while loading and verifies the + * complete snapshot's content hash before activation. + * + * Hash values are process-local and must not be persisted, serialized, or compared across + * processes. + * + * Having the hash noexcept lets libstdc++ recalculate it during rehash instead of storing it in + * each node. + */ +class SaltedCoinsCacheHasher +{ + const SipHasher13UJ m_hasher; + +public: + SaltedCoinsCacheHasher(bool deterministic = false); + + /** Hash a transaction ID, itself a cryptographic hash, as one jumbo block. */ + size_t operator()(const Txid& id) const noexcept + { + return m_hasher.Hash(id.ToUint256()); + } + + /** Hash an outpoint as its txid jumbo block followed by the zero-extended index as one normal block. */ + size_t operator()(const COutPoint& id) const noexcept + { + return m_hasher.Hash(id.hash.ToUint256(), uint64_t{id.n}); + } +}; + /** * PoolAllocator's MAX_BLOCK_SIZE_BYTES parameter here uses sizeof the data, and adds the size * of 4 pointers. We do not know the exact node size used in the std::unordered_node implementation @@ -229,7 +266,7 @@ struct CCoinsCacheEntry */ using CCoinsMap = std::unordered_map, PoolAllocator>; @@ -401,6 +438,19 @@ class CCoinsViewCache : public CCoinsViewBacked private: const bool m_deterministic; + //! Force a reallocation of the cache map. This is required when downsizing + //! the cache because the map's allocator may be hanging onto a lot of + //! memory despite having called .clear(). + //! + //! See: https://stackoverflow.com/questions/42114044/how-to-release-unordered-map-memory + void ReallocateCache(); + + /** + * @note this is marked const, but may actually append to `cacheCoins`, increasing + * memory usage. + */ + CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const; + protected: /** * Make mutable so that we can "fill the cache" even from Get-methods @@ -474,7 +524,7 @@ class CCoinsViewCache : public CCoinsViewBacked * NOT FOR GENERAL USE. Used only when loading coins from a UTXO snapshot. * @sa ChainstateManager::PopulateAndValidateSnapshot() */ - void EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coin); + void EmplaceCoinInternalDANGER(const COutPoint& outpoint, Coin&& coin); /** * Spend a coin. Pass moveto in order to get the deleted data. @@ -518,13 +568,6 @@ class CCoinsViewCache : public CCoinsViewBacked //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; - //! Force a reallocation of the cache map. This is required when downsizing - //! the cache because the map's allocator may be hanging onto a lot of - //! memory despite having called .clear(). - //! - //! See: https://stackoverflow.com/questions/42114044/how-to-release-unordered-map-memory - void ReallocateCache(); - //! Run an internal sanity check on the cache data structure. */ void SanityCheck() const; @@ -546,13 +589,6 @@ class CCoinsViewCache : public CCoinsViewBacked //! Create a scoped guard that will call `Reset()` on this cache when it goes out of scope. [[nodiscard]] ResetGuard CreateResetGuard() noexcept { return ResetGuard{*this}; } - -private: - /** - * @note this is marked const, but may actually append to `cacheCoins`, increasing - * memory usage. - */ - CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const; }; /** diff --git a/libbitcoinkernel-sys/bitcoin/src/common/args.cpp b/libbitcoinkernel-sys/bitcoin/src/common/args.cpp index cfd36e1f..97b37eb4 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/args.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/args.cpp @@ -23,8 +23,6 @@ #endif #include -#include -#include #include #include #include diff --git a/libbitcoinkernel-sys/bitcoin/src/common/args.h b/libbitcoinkernel-sys/bitcoin/src/common/args.h index 0a3195f8..0a83e143 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/args.h +++ b/libbitcoinkernel-sys/bitcoin/src/common/args.h @@ -6,7 +6,6 @@ #define BITCOIN_COMMON_ARGS_H #include -#include #include #include #include diff --git a/libbitcoinkernel-sys/bitcoin/src/common/bloom.cpp b/libbitcoinkernel-sys/bitcoin/src/common/bloom.cpp index 3ee78994..c15c8f78 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/bloom.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/bloom.cpp @@ -16,8 +16,7 @@ #include #include -#include -#include +#include #include static constexpr double LN2SQUARED = 0.4804530139182014246671025263266649717305529515945455; diff --git a/libbitcoinkernel-sys/bitcoin/src/common/bloom.h b/libbitcoinkernel-sys/bitcoin/src/common/bloom.h index 97007e1f..18399bd8 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/bloom.h +++ b/libbitcoinkernel-sys/bitcoin/src/common/bloom.h @@ -6,16 +6,17 @@ #define BITCOIN_COMMON_BLOOM_H #include -#include +#include +#include #include class COutPoint; class CTransaction; //! 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001% -static constexpr unsigned int MAX_BLOOM_FILTER_SIZE = 36000; // bytes -static constexpr unsigned int MAX_HASH_FUNCS = 50; +inline constexpr unsigned int MAX_BLOOM_FILTER_SIZE{36'000}; // bytes +inline constexpr unsigned int MAX_HASH_FUNCS = 50; /** * First two bits of nFlags control how much IsRelevantAndUpdate actually updates diff --git a/libbitcoinkernel-sys/bitcoin/src/common/config.cpp b/libbitcoinkernel-sys/bitcoin/src/common/config.cpp index cc7ffd59..8cf324ca 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/config.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/config.cpp @@ -2,28 +2,25 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include // IWYU pragma: associated #include #include #include #include -#include +#include #include #include #include #include -#include #include -#include #include #include -#include #include #include -#include #include +#include #include #include #include diff --git a/libbitcoinkernel-sys/bitcoin/src/common/init.cpp b/libbitcoinkernel-sys/bitcoin/src/common/init.cpp index 5c9742be..091b8d81 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/init.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/init.cpp @@ -2,15 +2,15 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include + #include #include -#include #include #include #include #include -#include #include #include diff --git a/libbitcoinkernel-sys/bitcoin/src/common/interfaces.cpp b/libbitcoinkernel-sys/bitcoin/src/common/interfaces.cpp index b501493d..3873ca2e 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/interfaces.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/interfaces.cpp @@ -2,8 +2,9 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include -#include +#include // IWYU pragma: associated +#include // IWYU pragma: associated + #include #include diff --git a/libbitcoinkernel-sys/bitcoin/src/common/messages.cpp b/libbitcoinkernel-sys/bitcoin/src/common/messages.cpp index 82ad310b..716512be 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/messages.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/messages.cpp @@ -4,16 +4,16 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include + #include #include -#include #include +#include #include #include #include #include -#include #include #include #include @@ -27,12 +27,9 @@ namespace common { std::string StringForFeeReason(FeeReason reason) { static const std::map fee_reason_strings = { - {FeeReason::NONE, "None"}, - {FeeReason::HALF_ESTIMATE, "Half Target 60% Threshold"}, - {FeeReason::FULL_ESTIMATE, "Target 85% Threshold"}, - {FeeReason::DOUBLE_ESTIMATE, "Double Target 95% Threshold"}, - {FeeReason::CONSERVATIVE, "Conservative Double Target longer horizon"}, + {FeeReason::FEE_RATE_ESTIMATOR, "Fee Rate Estimator"}, {FeeReason::MEMPOOL_MIN, "Mempool Min Fee"}, + {FeeReason::USER_SPECIFIED, "User Specified Fee"}, {FeeReason::FALLBACK, "Fallback fee"}, {FeeReason::REQUIRED, "Minimum Required Fee"}, }; @@ -59,13 +56,9 @@ std::string FeeModeInfo(const std::pair& mode, std case FeeEstimateMode::UNSET: return strprintf("%s means no mode set (%s). \n", mode.first, default_info); case FeeEstimateMode::ECONOMICAL: - return strprintf("%s estimates use a shorter time horizon, making them more\n" - "responsive to short-term drops in the prevailing fee market. This mode\n" - "potentially returns a lower fee rate estimate.\n", mode.first); + return strprintf("%s mode potentially returns a lower fee rate estimate.\n", mode.first); case FeeEstimateMode::CONSERVATIVE: - return strprintf("%s estimates use a longer time horizon, making them\n" - "less responsive to short-term drops in the prevailing fee market. This mode\n" - "potentially returns a higher fee rate estimate.\n", mode.first); + return strprintf("%s potentially returns a higher fee rate estimate.\n", mode.first); } // no default case, so the compiler can warn about missing cases assert(false); } @@ -118,8 +111,6 @@ bilingual_str PSBTErrorString(PSBTError err) return Untranslated("Input needs additional signatures or other data"); case PSBTError::INVALID_TX: return Untranslated("The transaction cannot be valid"); - case PSBTError::OK: - return Untranslated("No errors"); } // no default case, so the compiler can warn about missing cases assert(false); } diff --git a/libbitcoinkernel-sys/bitcoin/src/common/messages.h b/libbitcoinkernel-sys/bitcoin/src/common/messages.h index 60fdaa18..d6f26ccd 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/messages.h +++ b/libbitcoinkernel-sys/bitcoin/src/common/messages.h @@ -13,9 +13,9 @@ #include #include +#include struct bilingual_str; - enum class FeeEstimateMode; enum class FeeReason; namespace node { @@ -24,6 +24,7 @@ enum class TransactionError; namespace common { enum class PSBTError; + bool FeeModeFromString(std::string_view mode_string, FeeEstimateMode& fee_estimate_mode); std::string StringForFeeReason(FeeReason reason); std::string FeeModes(const std::string& delimiter); diff --git a/libbitcoinkernel-sys/bitcoin/src/common/netif.cpp b/libbitcoinkernel-sys/bitcoin/src/common/netif.cpp index 997db7d5..1120ee60 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/netif.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/netif.cpp @@ -6,12 +6,22 @@ #include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include + #if defined(__linux__) +#include #include #elif defined(__FreeBSD__) #include @@ -27,8 +37,6 @@ #include #endif -#include - namespace { //! Return CNetAddr for the specified OS-level network address. diff --git a/libbitcoinkernel-sys/bitcoin/src/common/netif.h b/libbitcoinkernel-sys/bitcoin/src/common/netif.h index 769bcbcc..84df00a2 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/netif.h +++ b/libbitcoinkernel-sys/bitcoin/src/common/netif.h @@ -8,6 +8,7 @@ #include #include +#include //! Query the OS for the default gateway for `network`. This only makes sense for NET_IPV4 and NET_IPV6. //! Returns std::nullopt if it cannot be found, or there is no support for this OS. diff --git a/libbitcoinkernel-sys/bitcoin/src/common/pcp.cpp b/libbitcoinkernel-sys/bitcoin/src/common/pcp.cpp index 7b22e82e..96a85821 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/pcp.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/pcp.cpp @@ -4,19 +4,30 @@ #include -#include -#include +#include #include +#include #include #include -#include -#include +#include #include #include -#include #include -#include +#include #include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace { diff --git a/libbitcoinkernel-sys/bitcoin/src/common/pcp.h b/libbitcoinkernel-sys/bitcoin/src/common/pcp.h index 121349b0..2c6b776f 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/pcp.h +++ b/libbitcoinkernel-sys/bitcoin/src/common/pcp.h @@ -6,15 +6,21 @@ #define BITCOIN_COMMON_PCP_H #include -#include +#include +#include +#include +#include +#include #include +class CThreadInterrupt; + // RFC6886 NAT-PMP and RFC6887 Port Control Protocol (PCP) implementation. // NAT-PMP and PCP use network byte order (big-endian). //! Mapping nonce size in bytes (see RFC6887 section 11.1). -constexpr size_t PCP_MAP_NONCE_SIZE = 12; +inline constexpr size_t PCP_MAP_NONCE_SIZE = 12; //! PCP mapping nonce. Arbitrary data chosen by the client to identify a mapping. typedef std::array PCPMappingNonce; diff --git a/libbitcoinkernel-sys/bitcoin/src/common/run_command.cpp b/libbitcoinkernel-sys/bitcoin/src/common/run_command.cpp index 86f89e17..b4e81c40 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/run_command.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/run_command.cpp @@ -2,21 +2,19 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include // IWYU pragma: keep - #include #include #include #include - -#ifdef ENABLE_EXTERNAL_SIGNER #include -#endif // ENABLE_EXTERNAL_SIGNER + +#include +#include +#include UniValue RunCommandParseJSON(const std::vector& cmd_args, const std::string& str_std_in) { -#ifdef ENABLE_EXTERNAL_SIGNER namespace sp = subprocess; UniValue result_json; @@ -43,7 +41,4 @@ UniValue RunCommandParseJSON(const std::vector& cmd_args, const std if (!result_json.read(result)) throw std::runtime_error("Unable to parse JSON: " + result); return result_json; -#else - throw std::runtime_error("Compiled without external signing support (required for external signing)."); -#endif // ENABLE_EXTERNAL_SIGNER } diff --git a/libbitcoinkernel-sys/bitcoin/src/common/settings.cpp b/libbitcoinkernel-sys/bitcoin/src/common/settings.cpp index 7d511b57..eca29bec 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/settings.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/settings.cpp @@ -2,15 +2,14 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include - #include // IWYU pragma: keep +#include + #include #include #include -#include #include #include #include diff --git a/libbitcoinkernel-sys/bitcoin/src/common/settings.h b/libbitcoinkernel-sys/bitcoin/src/common/settings.h index bc7b89a9..6f2579b1 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/settings.h +++ b/libbitcoinkernel-sys/bitcoin/src/common/settings.h @@ -12,7 +12,9 @@ #include #include -class UniValue; +// Users of this header need to explicitly #include +// IWYU pragma: no_include +class UniValue; // IWYU pragma: keep namespace common { diff --git a/libbitcoinkernel-sys/bitcoin/src/common/signmessage.cpp b/libbitcoinkernel-sys/bitcoin/src/common/signmessage.cpp index 0f9e1f5e..b45951f6 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/signmessage.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/signmessage.cpp @@ -4,15 +4,18 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include + +#include #include #include #include #include #include +#include #include -#include #include +#include #include #include #include diff --git a/libbitcoinkernel-sys/bitcoin/src/common/system.cpp b/libbitcoinkernel-sys/bitcoin/src/common/system.cpp index ca7b857d..33918dd8 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/system.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/system.cpp @@ -12,12 +12,12 @@ #include #ifdef WIN32 -#include -#include #include +#include #include #else #include +#include #include #endif @@ -25,8 +25,6 @@ #include #endif -#include -#include #include #include #include @@ -50,11 +48,7 @@ std::string ShellEscape(const std::string& arg) void runCommand(const std::string& strCommand) { if (strCommand.empty()) return; -#ifndef WIN32 int nErr = ::system(strCommand.c_str()); -#else - int nErr = ::_wsystem(std::wstring_convert,wchar_t>().from_bytes(strCommand).c_str()); -#endif if (nErr) { LogWarning("runCommand error: system(%s) returned %d", strCommand, nErr); } @@ -111,20 +105,17 @@ int GetNumCores() return std::thread::hardware_concurrency(); } -std::optional GetTotalRAM() +std::optional TryGetTotalRam() { - [[maybe_unused]] auto clamp{[](uint64_t v) { return size_t(std::min(v, uint64_t{std::numeric_limits::max()})); }}; + static const auto total_ram{[]() -> std::optional { #ifdef WIN32 - if (MEMORYSTATUSEX m{}; (m.dwLength = sizeof(m), GlobalMemoryStatusEx(&m))) return clamp(m.ullTotalPhys); -#elif defined(__APPLE__) || \ - defined(__FreeBSD__) || \ - defined(__NetBSD__) || \ - defined(__OpenBSD__) || \ - defined(__illumos__) || \ - defined(__linux__) - if (long p{sysconf(_SC_PHYS_PAGES)}, s{sysconf(_SC_PAGESIZE)}; p > 0 && s > 0) return clamp(1ULL * p * s); + if (MEMORYSTATUSEX m{}; (m.dwLength = sizeof(m), GlobalMemoryStatusEx(&m))) return m.ullTotalPhys; +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__illumos__) || defined(__linux__) + if (long p{sysconf(_SC_PHYS_PAGES)}, s{sysconf(_SC_PAGESIZE)}; p > 0 && s > 0) return 1ULL * p * s; #endif - return std::nullopt; + return std::nullopt; + }()}; + return total_ram; } namespace { diff --git a/libbitcoinkernel-sys/bitcoin/src/common/system.h b/libbitcoinkernel-sys/bitcoin/src/common/system.h index a3100fec..ad217e0d 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/system.h +++ b/libbitcoinkernel-sys/bitcoin/src/common/system.h @@ -7,9 +7,9 @@ #define BITCOIN_COMMON_SYSTEM_H #include // IWYU pragma: keep + #include -#include #include #include #include @@ -35,6 +35,6 @@ int GetNumCores(); /** * Return the total RAM available on the current system, if detectable. */ -std::optional GetTotalRAM(); +std::optional TryGetTotalRam(); #endif // BITCOIN_COMMON_SYSTEM_H diff --git a/libbitcoinkernel-sys/bitcoin/src/common/types.h b/libbitcoinkernel-sys/bitcoin/src/common/types.h index b9ebca15..1ffcd392 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/types.h +++ b/libbitcoinkernel-sys/bitcoin/src/common/types.h @@ -24,7 +24,6 @@ enum class PSBTError { UNSUPPORTED, INCOMPLETE, INVALID_TX, - OK, }; /** * Instructions for how a PSBT should be signed or filled with information. diff --git a/libbitcoinkernel-sys/bitcoin/src/common/url.cpp b/libbitcoinkernel-sys/bitcoin/src/common/url.cpp index 19db4e99..a186c512 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/url.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/url.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/libbitcoinkernel-sys/bitcoin/src/compressor.h b/libbitcoinkernel-sys/bitcoin/src/compressor.h index 95490b7b..b6b738f6 100644 --- a/libbitcoinkernel-sys/bitcoin/src/compressor.h +++ b/libbitcoinkernel-sys/bitcoin/src/compressor.h @@ -59,7 +59,7 @@ struct ScriptCompression * transactions, in which case this value becomes dependent on version * and nHeight of the enclosing transaction. */ - static const unsigned int nSpecialScripts = 6; + static constexpr unsigned int nSpecialScripts{6}; template void Ser(Stream &s, const CScript& script) { diff --git a/libbitcoinkernel-sys/bitcoin/src/consensus/amount.h b/libbitcoinkernel-sys/bitcoin/src/consensus/amount.h index 2a65a831..a2a383cc 100644 --- a/libbitcoinkernel-sys/bitcoin/src/consensus/amount.h +++ b/libbitcoinkernel-sys/bitcoin/src/consensus/amount.h @@ -12,7 +12,7 @@ typedef int64_t CAmount; /** The amount of satoshis in one BTC. */ -static constexpr CAmount COIN = 100000000; +inline constexpr CAmount COIN{100'000'000}; /** No amount larger than this (in satoshi) is valid. * @@ -23,7 +23,7 @@ static constexpr CAmount COIN = 100000000; * critical; in unusual circumstances like a(nother) overflow bug that allowed * for the creation of coins out of thin air modification could lead to a fork. * */ -static constexpr CAmount MAX_MONEY = 21000000 * COIN; +inline constexpr CAmount MAX_MONEY{21'000'000 * COIN}; inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } #endif // BITCOIN_CONSENSUS_AMOUNT_H diff --git a/libbitcoinkernel-sys/bitcoin/src/consensus/consensus.h b/libbitcoinkernel-sys/bitcoin/src/consensus/consensus.h index 71b5fe24..96195e28 100644 --- a/libbitcoinkernel-sys/bitcoin/src/consensus/consensus.h +++ b/libbitcoinkernel-sys/bitcoin/src/consensus/consensus.h @@ -6,32 +6,32 @@ #ifndef BITCOIN_CONSENSUS_CONSENSUS_H #define BITCOIN_CONSENSUS_CONSENSUS_H +#include #include -#include /** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */ -static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000; +inline constexpr unsigned int MAX_BLOCK_SERIALIZED_SIZE{4'000'000}; /** The maximum allowed weight for a block, see BIP 141 (network rule) */ -static const unsigned int MAX_BLOCK_WEIGHT = 4000000; +inline constexpr unsigned int MAX_BLOCK_WEIGHT{4'000'000}; /** The maximum allowed number of signature check operations in a block (network rule) */ -static const int64_t MAX_BLOCK_SIGOPS_COST = 80000; +inline constexpr int64_t MAX_BLOCK_SIGOPS_COST{80'000}; /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ -static const int COINBASE_MATURITY = 100; +inline constexpr int COINBASE_MATURITY = 100; -static const int WITNESS_SCALE_FACTOR = 4; +inline constexpr int WITNESS_SCALE_FACTOR = 4; -static const size_t MIN_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 60; // 60 is the lower bound for the size of a valid serialized CTransaction -static const size_t MIN_SERIALIZABLE_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 10; // 10 is the lower bound for the size of a serialized CTransaction +inline constexpr size_t MIN_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 60; // 60 is the lower bound for the size of a valid serialized CTransaction +inline constexpr size_t MIN_SERIALIZABLE_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 10; // 10 is the lower bound for the size of a serialized CTransaction /** Flags for nSequence and nLockTime locks */ /** Interpret sequence numbers as relative lock-time constraints. */ -static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE = (1 << 0); +inline constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE = (1 << 0); /** * Maximum number of seconds that the timestamp of the first * block of a difficulty adjustment period is allowed to * be earlier than the last block of the previous period (BIP94). */ -static constexpr int64_t MAX_TIMEWARP = 600; +inline constexpr int64_t MAX_TIMEWARP = 600; #endif // BITCOIN_CONSENSUS_CONSENSUS_H diff --git a/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.cpp b/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.cpp index c6ae81c6..df5f95e7 100644 --- a/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.cpp @@ -3,9 +3,17 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include + +#include #include +#include +#include #include +#include +#include +#include + /* WARNING! If you're reading this because you're learning about crypto and/or designing a new system that will use merkle trees, keep in mind that the following merkle tree algorithm has a serious flaw related to @@ -41,12 +49,15 @@ known ways of changing the transactions without affecting the merkle root. */ - - uint256 ComputeMerkleRoot(std::vector hashes, bool* mutated) { bool mutation = false; while (hashes.size() > 1) { if (mutated) { + // Check every level because equal pairs can appear above the leaves, + // as in the [1,2,3,4,5,6,5,6] construction described above. + // Continuing after finding one is redundant, but mutated blocks should + // not propagate through the network anyway, and the total number of + // comparisons is the same as for an unmutated input of the same length. for (size_t pos = 0; pos + 1 < hashes.size(); pos += 2) { if (hashes[pos] == hashes[pos + 1]) mutation = true; } diff --git a/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.h b/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.h index 03b5a1b5..dc8866bb 100644 --- a/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.h +++ b/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.h @@ -5,11 +5,18 @@ #ifndef BITCOIN_CONSENSUS_MERKLE_H #define BITCOIN_CONSENSUS_MERKLE_H +#include + +#include #include -#include -#include +class CBlock; +/** + * Compute a Merkle root from the provided leaf hashes. + * If non-null, `*mutated` is set to true if two identical hashes are paired at + * any tree level before the odd-count hash duplication step, and false otherwise. + */ uint256 ComputeMerkleRoot(std::vector hashes, bool* mutated = nullptr); /* diff --git a/libbitcoinkernel-sys/bitcoin/src/consensus/params.h b/libbitcoinkernel-sys/bitcoin/src/consensus/params.h index 7f567294..99096e06 100644 --- a/libbitcoinkernel-sys/bitcoin/src/consensus/params.h +++ b/libbitcoinkernel-sys/bitcoin/src/consensus/params.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/libbitcoinkernel-sys/bitcoin/src/consensus/tx_check.cpp b/libbitcoinkernel-sys/bitcoin/src/consensus/tx_check.cpp index 251417c8..473538e4 100644 --- a/libbitcoinkernel-sys/bitcoin/src/consensus/tx_check.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/consensus/tx_check.cpp @@ -5,8 +5,16 @@ #include #include -#include +#include #include +#include +#include