mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-22 16:14:50 +01:00
Compare commits
171 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d70e9c5d13 | ||
|
|
44d05b2fb2 | ||
|
|
201221b750 | ||
|
|
e2e1138350 | ||
|
|
9c911f7e2d | ||
|
|
ae8605825f | ||
|
|
42c4c6b6dd | ||
|
|
2cd432dc6d | ||
|
|
e9dd94abcc | ||
|
|
06fe49dc88 | ||
|
|
11da80fe6a | ||
|
|
05f4aa7662 | ||
|
|
ffffdc4e97 | ||
|
|
ed730c5674 | ||
|
|
9968b15937 | ||
|
|
dcac36271f | ||
|
|
df7412803d | ||
|
|
d3194cb8cd | ||
|
|
18f6430b4a | ||
|
|
6ede736da1 | ||
|
|
66559d1a4a | ||
|
|
a02e0a401c | ||
|
|
f25fc092ab | ||
|
|
4d809efeb9 | ||
|
|
f7dde40c70 | ||
|
|
a60281526b | ||
|
|
08eeb0d342 | ||
|
|
b7ba016707 | ||
|
|
27b775586e | ||
|
|
e3273e03b1 | ||
|
|
cf875f1559 | ||
|
|
308778b7b6 | ||
|
|
e779d59eca | ||
|
|
a0b5730f85 | ||
|
|
a5e4fec494 | ||
|
|
4598dfcfde | ||
|
|
9e56d8889a | ||
|
|
a381de750d | ||
|
|
f9043af2ee | ||
|
|
ea4e0aa8c4 | ||
|
|
48761444e2 | ||
|
|
12eada012b | ||
|
|
189bb39922 | ||
|
|
e4493b15df | ||
|
|
a0b6e2ae6b | ||
|
|
1bfe9f56c3 | ||
|
|
abaa128095 | ||
|
|
8ab684eeb7 | ||
|
|
99411458b4 | ||
|
|
4b3468389b | ||
|
|
cf18a500d7 | ||
|
|
49ff9d7e6e | ||
|
|
c2c69cd6ec | ||
|
|
fa259b4e72 | ||
|
|
96cd28f146 | ||
|
|
0fc3fd1eb5 | ||
|
|
f61cb6be58 | ||
|
|
6237cd537d | ||
|
|
8c9048f4fc | ||
|
|
61bb5180d5 | ||
|
|
bb455c9594 | ||
|
|
5538ce4f32 | ||
|
|
82cfddbc9a | ||
|
|
30efc95aec | ||
|
|
f6ccd895df | ||
|
|
f8cb31d064 | ||
|
|
270191c3c0 | ||
|
|
8d6d70f555 | ||
|
|
d8ad667f94 | ||
|
|
6e62b70532 | ||
|
|
9f1b89a1c7 | ||
|
|
2a46f220ca | ||
|
|
5492e1be3b | ||
|
|
4d145f9f20 | ||
|
|
8782e6ce38 | ||
|
|
c09d82f0dd | ||
|
|
41fa1e0ee5 | ||
|
|
a828e64b7d | ||
|
|
a6d0159518 | ||
|
|
a9a71b840d | ||
|
|
792ee20318 | ||
|
|
3c56d36bec | ||
|
|
44b07b2d5a | ||
|
|
c77e250a98 | ||
|
|
d19a8e0c06 | ||
|
|
907772d709 | ||
|
|
d235d5b77d | ||
|
|
e44d72b648 | ||
|
|
7135d7536c | ||
|
|
90f78c74a0 | ||
|
|
3cd4fdb008 | ||
|
|
e5a9e2435f | ||
|
|
2437d93989 | ||
|
|
a6aca67214 | ||
|
|
9082498589 | ||
|
|
cb13264169 | ||
|
|
fb62393277 | ||
|
|
c2b2942415 | ||
|
|
b64faa54c2 | ||
|
|
a6cbd33d1a | ||
|
|
7f1da76269 | ||
|
|
b1f694fce2 | ||
|
|
52f09633d0 | ||
|
|
744b1c8581 | ||
|
|
812cadefa2 | ||
|
|
c60055c637 | ||
|
|
0bd5cb7ac4 | ||
|
|
2b279a2138 | ||
|
|
ac2b6083ba | ||
|
|
2c21db657f | ||
|
|
9f0ee1cc9b | ||
|
|
00b401c648 | ||
|
|
59c19a5416 | ||
|
|
5c2ba9f583 | ||
|
|
ac637458ef | ||
|
|
186e3f1fb6 | ||
|
|
bbfb994fc1 | ||
|
|
fdc629fa73 | ||
|
|
a124b91339 | ||
|
|
812e637521 | ||
|
|
2ccdfa424c | ||
|
|
3df2624ee9 | ||
|
|
e65676216c | ||
|
|
2d6c14efba | ||
|
|
9b15b20cb1 | ||
|
|
dbc450c1b5 | ||
|
|
e57359c7dd | ||
|
|
51fbcba682 | ||
|
|
2829588882 | ||
|
|
f676da82fa | ||
|
|
4e7dd0ac20 | ||
|
|
32efe85043 | ||
|
|
36314b8da2 | ||
|
|
58910279dc | ||
|
|
6a68ef9bfb | ||
|
|
5b368f88a9 | ||
|
|
05cd448e33 | ||
|
|
621c634b7f | ||
|
|
6db725662d | ||
|
|
5576618152 | ||
|
|
01fe07a2ce | ||
|
|
7ddfcf32da | ||
|
|
e0b27b234c | ||
|
|
bdc6b3e531 | ||
|
|
a0585b6087 | ||
|
|
bbde830b97 | ||
|
|
227642d5af | ||
|
|
b8112cf422 | ||
|
|
2835158be0 | ||
|
|
d6b225f165 | ||
|
|
8fef83a0a0 | ||
|
|
df7764621e | ||
|
|
9add853b65 | ||
|
|
1025090fbe | ||
|
|
446f5d20d6 | ||
|
|
9976162a0e | ||
|
|
1d0411dc8f | ||
|
|
7fec638222 | ||
|
|
f998ac6286 | ||
|
|
0773560abf | ||
|
|
b917334208 | ||
|
|
f072721181 | ||
|
|
6643fd2145 | ||
|
|
89522379d1 | ||
|
|
89d34cffed | ||
|
|
1101837461 | ||
|
|
5de225f5c1 | ||
|
|
98745e03ff | ||
|
|
5feef9ce7e | ||
|
|
7fcd7b85c6 | ||
|
|
e24a25d882 |
217
.cirrus.yml
217
.cirrus.yml
@@ -1,217 +0,0 @@
|
||||
env: # Global defaults
|
||||
CIRRUS_CLONE_DEPTH: 1
|
||||
PACKAGE_MANAGER_INSTALL: "apt-get update && apt-get install -y"
|
||||
MAKEJOBS: "-j10"
|
||||
TEST_RUNNER_PORT_MIN: "14000" # Must be larger than 12321, which is used for the http cache. See https://cirrus-ci.org/guide/writing-tasks/#http-cache
|
||||
CI_FAILFAST_TEST_LEAVE_DANGLING: "1" # Cirrus CI does not care about dangling processes and setting this variable avoids killing the CI script itself on error
|
||||
CCACHE_MAXSIZE: "200M"
|
||||
CCACHE_DIR: "/tmp/ccache_dir"
|
||||
CCACHE_NOHASHDIR: "1" # Debug info might contain a stale path if the build dir changes, but this is fine
|
||||
|
||||
# A self-hosted machine(s) can be used via Cirrus CI. It can be configured with
|
||||
# multiple users to run tasks in parallel. No sudo permission is required.
|
||||
#
|
||||
# https://cirrus-ci.org/guide/persistent-workers/
|
||||
#
|
||||
# Generally, a persistent worker must run Ubuntu 23.04+ or Debian 12+.
|
||||
#
|
||||
# The following specific types should exist, with the following requirements:
|
||||
# - small: For an x86_64 machine, recommended to have 2 CPUs and 8 GB of memory.
|
||||
# - medium: For an x86_64 machine, recommended to have 4 CPUs and 16 GB of memory.
|
||||
# - arm64: For an aarch64 machine, recommended to have 2 CPUs and 8 GB of memory.
|
||||
#
|
||||
# CI jobs for the latter configuration can be run on x86_64 hardware
|
||||
# by installing qemu-user-static, which works out of the box with
|
||||
# podman or docker. Background: https://stackoverflow.com/a/72890225/313633
|
||||
#
|
||||
# The above machine types are matched to each task by their label. Refer to the
|
||||
# Cirrus CI docs for more details.
|
||||
#
|
||||
# When a contributor maintains a fork of the repo, any pull request they make
|
||||
# to their own fork, or to the main repository, will trigger two CI runs:
|
||||
# one for the branch push and one for the pull request.
|
||||
# This can be avoided by setting SKIP_BRANCH_PUSH=true as a custom env variable
|
||||
# in Cirrus repository settings, accessible from
|
||||
# https://cirrus-ci.com/github/my-organization/my-repository
|
||||
#
|
||||
# On machines that are persisted between CI jobs, RESTART_CI_DOCKER_BEFORE_RUN=1
|
||||
# ensures that previous containers and artifacts are cleared before each run.
|
||||
# This requires installing Podman instead of Docker.
|
||||
#
|
||||
# Futhermore:
|
||||
# - apt-get is required due to PACKAGE_MANAGER_INSTALL
|
||||
# - podman-docker-4.1+ is required due to the bugfix in 4.1
|
||||
# (https://github.com/bitcoin/bitcoin/pull/21652#issuecomment-1657098200)
|
||||
# - The ./ci/ dependencies (with cirrus-cli) should be installed. One-liner example
|
||||
# for a single user setup with sudo permission:
|
||||
#
|
||||
# ```
|
||||
# apt update && apt install git screen python3 bash podman-docker curl -y && curl -L -o cirrus "https://github.com/cirruslabs/cirrus-cli/releases/latest/download/cirrus-linux-$(dpkg --print-architecture)" && mv cirrus /usr/local/bin/cirrus && chmod +x /usr/local/bin/cirrus
|
||||
# ```
|
||||
#
|
||||
# - There are no strict requirements on the hardware. Having fewer CPU threads
|
||||
# than recommended merely causes the CI script to run slower.
|
||||
# To avoid rare and intermittent OOM due to short memory usage spikes,
|
||||
# it is recommended to add (and persist) swap:
|
||||
#
|
||||
# ```
|
||||
# fallocate -l 16G /swapfile_ci && chmod 600 /swapfile_ci && mkswap /swapfile_ci && swapon /swapfile_ci && ( echo '/swapfile_ci none swap sw 0 0' | tee -a /etc/fstab )
|
||||
# ```
|
||||
#
|
||||
# - To register the persistent worker, open a `screen` session and run:
|
||||
#
|
||||
# ```
|
||||
# RESTART_CI_DOCKER_BEFORE_RUN=1 screen cirrus worker run --labels type=todo_fill_in_type --token todo_fill_in_token
|
||||
# ```
|
||||
|
||||
# https://cirrus-ci.org/guide/tips-and-tricks/#sharing-configuration-between-tasks
|
||||
filter_template: &FILTER_TEMPLATE
|
||||
# Allow forks to specify SKIP_BRANCH_PUSH=true and skip CI runs when a branch is pushed,
|
||||
# but still run CI when a PR is created.
|
||||
# https://cirrus-ci.org/guide/writing-tasks/#conditional-task-execution
|
||||
skip: $SKIP_BRANCH_PUSH == "true" && $CIRRUS_PR == ""
|
||||
stateful: false # https://cirrus-ci.org/guide/writing-tasks/#stateful-tasks
|
||||
|
||||
base_template: &BASE_TEMPLATE
|
||||
<< : *FILTER_TEMPLATE
|
||||
merge_base_script:
|
||||
# Unconditionally install git (used in fingerprint_script).
|
||||
- git --version || bash -c "$PACKAGE_MANAGER_INSTALL git"
|
||||
- if [ "$CIRRUS_PR" = "" ]; then exit 0; fi
|
||||
- git fetch --depth=1 $CIRRUS_REPO_CLONE_URL "pull/${CIRRUS_PR}/merge"
|
||||
- git checkout FETCH_HEAD # Use merged changes to detect silent merge conflicts
|
||||
# Also, the merge commit is used to lint COMMIT_RANGE="HEAD~..HEAD"
|
||||
|
||||
main_template: &MAIN_TEMPLATE
|
||||
timeout_in: 120m # https://cirrus-ci.org/faq/#instance-timed-out
|
||||
ci_script:
|
||||
- ./ci/test_run_all.sh
|
||||
|
||||
global_task_template: &GLOBAL_TASK_TEMPLATE
|
||||
<< : *BASE_TEMPLATE
|
||||
<< : *MAIN_TEMPLATE
|
||||
|
||||
compute_credits_template: &CREDITS_TEMPLATE
|
||||
# https://cirrus-ci.org/pricing/#compute-credits
|
||||
# Only use credits for pull requests to the main repo
|
||||
use_compute_credits: $CIRRUS_REPO_FULL_NAME == 'bitcoin/bitcoin' && $CIRRUS_PR != ""
|
||||
|
||||
task:
|
||||
name: 'lint'
|
||||
<< : *BASE_TEMPLATE
|
||||
container:
|
||||
image: debian:bookworm
|
||||
cpu: 1
|
||||
memory: 1G
|
||||
# For faster CI feedback, immediately schedule the linters
|
||||
<< : *CREDITS_TEMPLATE
|
||||
test_runner_cache:
|
||||
folder: "/lint_test_runner"
|
||||
fingerprint_script: echo $CIRRUS_TASK_NAME $(git rev-parse HEAD:test/lint/test_runner)
|
||||
python_cache:
|
||||
folder: "/python_build"
|
||||
fingerprint_script: cat .python-version /etc/os-release
|
||||
unshallow_script:
|
||||
- git fetch --unshallow --no-tags
|
||||
lint_script:
|
||||
- ./ci/lint_run_all.sh
|
||||
|
||||
task:
|
||||
name: 'tidy'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: medium
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_native_tidy.sh"
|
||||
|
||||
task:
|
||||
name: 'ARM, unit tests, no functional tests'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: arm64 # Use arm64 worker to sidestep qemu and avoid a slow CI: https://github.com/bitcoin/bitcoin/pull/28087#issuecomment-1649399453
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_arm.sh"
|
||||
|
||||
task:
|
||||
name: 'Win64, unit tests, no gui tests, no functional tests'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: small
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_win64.sh"
|
||||
|
||||
task:
|
||||
name: '32-bit CentOS, dash, gui'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: small
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_i686_centos.sh"
|
||||
|
||||
task:
|
||||
name: 'previous releases, depends DEBUG'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: small
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_native_previous_releases.sh"
|
||||
|
||||
task:
|
||||
name: 'TSan, depends, gui'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: medium
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_native_tsan.sh"
|
||||
|
||||
task:
|
||||
name: 'MSan, depends'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: small
|
||||
timeout_in: 300m # Use longer timeout for the *rare* case where a full build (llvm + msan + depends + ...) needs to be done.
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_native_msan.sh"
|
||||
|
||||
task:
|
||||
name: 'fuzzer,address,undefined,integer, no depends'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: medium
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_native_fuzz.sh"
|
||||
|
||||
task:
|
||||
name: 'multiprocess, i686, DEBUG'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: medium
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_i686_multiprocess.sh"
|
||||
|
||||
task:
|
||||
name: 'no wallet, libbitcoinkernel'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: small
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh"
|
||||
|
||||
task:
|
||||
name: 'macOS-cross, gui, no tests'
|
||||
<< : *GLOBAL_TASK_TEMPLATE
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: small
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_mac_cross.sh"
|
||||
52
.github/actions/configure-docker/action.yml
vendored
Normal file
52
.github/actions/configure-docker/action.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
name: 'Configure Docker'
|
||||
description: 'Set up Docker build driver and configure build cache args'
|
||||
inputs:
|
||||
use-cirrus:
|
||||
description: 'Use cirrus cache'
|
||||
required: true
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
# Use host network to allow access to cirrus gha cache running on the host
|
||||
driver-opts: |
|
||||
network=host
|
||||
|
||||
# This is required to allow buildkit to access the actions cache
|
||||
- name: Expose actions cache variables
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env['ACTIONS_CACHE_URL'])
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env['ACTIONS_RUNTIME_TOKEN'])
|
||||
|
||||
- name: Construct docker build cache args
|
||||
shell: bash
|
||||
run: |
|
||||
# Configure docker build cache backend
|
||||
#
|
||||
# On forks the gha cache will work but will use Github's cache backend.
|
||||
# Docker will check for variables $ACTIONS_CACHE_URL, $ACTIONS_RESULTS_URL and $ACTIONS_RUNTIME_TOKEN
|
||||
# which are set automatically when running on GitHub infra: https://docs.docker.com/build/cache/backends/gha/#synopsis
|
||||
|
||||
# Use cirrus cache host
|
||||
if [[ ${{ inputs.use-cirrus }} == 'true' ]]; then
|
||||
url_args="url=${CIRRUS_CACHE_HOST},url_v2=${CIRRUS_CACHE_HOST}"
|
||||
else
|
||||
url_args=""
|
||||
fi
|
||||
|
||||
# Always optimistically --cache‑from in case a cache blob exists
|
||||
args=(--cache-from "type=gha${url_args:+,${url_args}},scope=${CONTAINER_NAME}")
|
||||
|
||||
# If this is a push to the default branch, also add --cache‑to to save the cache
|
||||
if [[ ${{ github.event_name }} == "push" && ${{ github.ref_name }} == ${{ github.event.repository.default_branch }} ]]; then
|
||||
args+=(--cache-to "type=gha${url_args:+,${url_args}},mode=max,ignore-error=true,scope=${CONTAINER_NAME}")
|
||||
fi
|
||||
|
||||
# Always `--load` into docker images (needed when using the `docker-container` build driver).
|
||||
args+=(--load)
|
||||
|
||||
echo "DOCKER_BUILD_CACHE_ARG=${args[*]}" >> $GITHUB_ENV
|
||||
27
.github/actions/configure-environment/action.yml
vendored
Normal file
27
.github/actions/configure-environment/action.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: 'Configure environment'
|
||||
description: 'Configure CI, cache and container name environment variables'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Set CI and cache directories
|
||||
shell: bash
|
||||
run: |
|
||||
echo "BASE_ROOT_DIR=${{ runner.temp }}" >> "$GITHUB_ENV"
|
||||
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
|
||||
echo "SOURCES_PATH=${{ runner.temp }}/depends/sources" >> $GITHUB_ENV
|
||||
echo "PREVIOUS_RELEASES_DIR=${{ runner.temp }}/previous_releases" >> $GITHUB_ENV
|
||||
|
||||
- name: Set cache hashes
|
||||
shell: bash
|
||||
run: |
|
||||
echo "DEPENDS_HASH=$(git ls-tree HEAD depends "ci/test/$FILE_ENV" | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
|
||||
echo "PREVIOUS_RELEASES_HASH=$(git ls-tree HEAD test/get_previous_releases.py | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
|
||||
|
||||
- name: Get container name
|
||||
shell: bash
|
||||
run: |
|
||||
source $FILE_ENV
|
||||
echo "CONTAINER_NAME=$CONTAINER_NAME" >> "$GITHUB_ENV"
|
||||
47
.github/actions/restore-caches/action.yml
vendored
Normal file
47
.github/actions/restore-caches/action.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
name: 'Restore Caches'
|
||||
description: 'Restore ccache, depends sources, and built depends caches'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Restore Ccache cache
|
||||
id: ccache-cache
|
||||
uses: cirruslabs/cache/restore@v4
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ccache-${{ env.CONTAINER_NAME }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
ccache-${{ env.CONTAINER_NAME }}-
|
||||
|
||||
- name: Restore depends sources cache
|
||||
id: depends-sources
|
||||
uses: cirruslabs/cache/restore@v4
|
||||
with:
|
||||
path: ${{ env.SOURCES_PATH }}
|
||||
key: depends-sources-${{ env.CONTAINER_NAME }}-${{ env.DEPENDS_HASH }}
|
||||
restore-keys: |
|
||||
depends-sources-${{ env.CONTAINER_NAME }}-
|
||||
|
||||
- name: Restore built depends cache
|
||||
id: depends-built
|
||||
uses: cirruslabs/cache/restore@v4
|
||||
with:
|
||||
path: ${{ env.BASE_CACHE }}
|
||||
key: depends-built-${{ env.CONTAINER_NAME }}-${{ env.DEPENDS_HASH }}
|
||||
restore-keys: |
|
||||
depends-built-${{ env.CONTAINER_NAME }}-
|
||||
|
||||
- name: Restore previous releases cache
|
||||
id: previous-releases
|
||||
uses: cirruslabs/cache/restore@v4
|
||||
with:
|
||||
path: ${{ env.PREVIOUS_RELEASES_DIR }}
|
||||
key: previous-releases-${{ env.CONTAINER_NAME }}-${{ env.PREVIOUS_RELEASES_HASH }}
|
||||
restore-keys: |
|
||||
previous-releases-${{ env.CONTAINER_NAME }}-
|
||||
|
||||
- name: export cache hits
|
||||
shell: bash
|
||||
run: |
|
||||
echo "depends-sources-cache-hit=${{ steps.depends-sources.outputs.cache-hit }}" >> $GITHUB_ENV
|
||||
echo "depends-built-cache-hit=${{ steps.depends-built.outputs.cache-hit }}" >> $GITHUB_ENV
|
||||
echo "previous-releases-cache-hit=${{ steps.previous-releases.outputs.cache-hit }}" >> $GITHUB_ENV
|
||||
39
.github/actions/save-caches/action.yml
vendored
Normal file
39
.github/actions/save-caches/action.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: 'Save Caches'
|
||||
description: 'Save ccache, depends sources, and built depends caches'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: debug cache hit inputs
|
||||
shell: bash
|
||||
run: |
|
||||
echo "depends sources direct cache hit to primary key: ${{ env.depends-sources-cache-hit }}"
|
||||
echo "depends built direct cache hit to primary key: ${{ env.depends-built-cache-hit }}"
|
||||
echo "previous releases direct cache hit to primary key: ${{ env.previous-releases-cache-hit }}"
|
||||
|
||||
- name: Save Ccache cache
|
||||
uses: cirruslabs/cache/save@v4
|
||||
if: ${{ (github.event_name == 'push') && (github.ref_name == github.event.repository.default_branch) }}
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ccache-${{ env.CONTAINER_NAME }}-${{ github.run_id }}
|
||||
|
||||
- name: Save depends sources cache
|
||||
uses: cirruslabs/cache/save@v4
|
||||
if: ${{ (github.event_name == 'push') && (github.ref_name == github.event.repository.default_branch) && (env.depends-sources-cache-hit != 'true') }}
|
||||
with:
|
||||
path: ${{ env.SOURCES_PATH }}
|
||||
key: depends-sources-${{ env.CONTAINER_NAME }}-${{ env.DEPENDS_HASH }}
|
||||
|
||||
- name: Save built depends cache
|
||||
uses: cirruslabs/cache/save@v4
|
||||
if: ${{ (github.event_name == 'push') && (github.ref_name == github.event.repository.default_branch) && (env.depends-built-cache-hit != 'true' )}}
|
||||
with:
|
||||
path: ${{ env.BASE_CACHE }}
|
||||
key: depends-built-${{ env.CONTAINER_NAME }}-${{ env.DEPENDS_HASH }}
|
||||
|
||||
- name: Save previous releases cache
|
||||
uses: cirruslabs/cache/save@v4
|
||||
if: ${{ (github.event_name == 'push') && (github.ref_name == github.event.repository.default_branch) && (env.previous-releases-cache-hit != 'true' )}}
|
||||
with:
|
||||
path: ${{ env.PREVIOUS_RELEASES_DIR }}
|
||||
key: previous-releases-${{ env.CONTAINER_NAME }}-${{ env.PREVIOUS_RELEASES_HASH }}
|
||||
193
.github/workflows/ci.yml
vendored
193
.github/workflows/ci.yml
vendored
@@ -19,9 +19,26 @@ concurrency:
|
||||
|
||||
env:
|
||||
CI_FAILFAST_TEST_LEAVE_DANGLING: 1 # GHA does not care about dangling processes and setting this variable avoids killing the CI script itself on error
|
||||
MAKEJOBS: '-j10'
|
||||
CIRRUS_CACHE_HOST: http://127.0.0.1:12321/ # When using Cirrus Runners this host can be used by the docker `gha` build cache type.
|
||||
REPO_USE_CIRRUS_RUNNERS: 'bitcoin/bitcoin' # Use cirrus runners and cache for this repo, instead of falling back to the slow GHA runners
|
||||
|
||||
jobs:
|
||||
runners:
|
||||
name: 'determine runners'
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
use-cirrus-runners: ${{ steps.runners.outputs.use-cirrus-runners }}
|
||||
steps:
|
||||
- id: runners
|
||||
run: |
|
||||
if [[ "${REPO_USE_CIRRUS_RUNNERS}" == "${{ github.repository }}" ]]; then
|
||||
echo "use-cirrus-runners=true" >> "$GITHUB_OUTPUT"
|
||||
echo "::notice title=Runner Selection::Using Cirrus Runners"
|
||||
else
|
||||
echo "use-cirrus-runners=false" >> "$GITHUB_OUTPUT"
|
||||
echo "::notice title=Runner Selection::Using GitHub-hosted runners"
|
||||
fi
|
||||
|
||||
test-each-commit:
|
||||
name: 'test each commit'
|
||||
runs-on: ubuntu-24.04
|
||||
@@ -91,8 +108,12 @@ jobs:
|
||||
BASE_ROOT_DIR: ${{ github.workspace }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- &CHECKOUT
|
||||
name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
# Ensure the latest merged pull request state is used, even on re-runs.
|
||||
ref: &CHECKOUT_REF_TMPL ${{ github.event_name == 'pull_request' && github.ref || '' }}
|
||||
|
||||
- name: Clang version
|
||||
run: |
|
||||
@@ -143,13 +164,12 @@ jobs:
|
||||
CI_CCACHE_VERSION: '4.7.5'
|
||||
CI_QT_CONF: '-release -silent -opensource -confirm-license -opengl desktop -static -static-runtime -mp -qt-zlib -qt-pcre -qt-libpng -nomake examples -nomake tests -nomake tools -no-angle -no-dbus -no-gif -no-gtk -no-ico -no-icu -no-libjpeg -no-libudev -no-sql-sqlite -no-sql-odbc -no-sqlite -no-vulkan -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip doc -skip qtdoc -skip qtgamepad -skip qtgraphicaleffects -skip qtimageformats -skip qtlocation -skip qtlottie -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquick3d -skip qtquickcontrols -skip qtquickcontrols2 -skip qtquicktimeline -skip qtremoteobjects -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtspeech -skip qtsvg -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebglplugin -skip qtwebsockets -skip qtwebview -skip qtx11extras -skip qtxmlpatterns -no-openssl -no-feature-bearermanagement -no-feature-printdialog -no-feature-printer -no-feature-printpreviewdialog -no-feature-printpreviewwidget -no-feature-sql -no-feature-sqlmodel -no-feature-textbrowser -no-feature-textmarkdownwriter -no-feature-textodfwriter -no-feature-xml'
|
||||
CI_QT_DIR: 'qt-everywhere-src-5.15.11'
|
||||
CI_QT_URL: 'https://download.qt.io/official_releases/qt/5.15/5.15.11/single/qt-everywhere-opensource-src-5.15.11.zip'
|
||||
CI_QT_URL: 'https://download.qt.io/archive/qt/5.15/5.15.11/single/qt-everywhere-opensource-src-5.15.11.zip'
|
||||
PYTHONUTF8: 1
|
||||
TEST_RUNNER_TIMEOUT_FACTOR: 40
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- *CHECKOUT
|
||||
|
||||
- name: Configure Developer Command Prompt for Microsoft Visual C++
|
||||
# Using microsoft/setup-msbuild is not enough.
|
||||
@@ -311,45 +331,154 @@ jobs:
|
||||
shell: cmd
|
||||
run: py -3 test\fuzz\test_runner.py --par %NUMBER_OF_PROCESSORS% --loglevel DEBUG %RUNNER_TEMP%\qa-assets\fuzz_seed_corpus
|
||||
|
||||
asan-lsan-ubsan-integer-no-depends-usdt:
|
||||
name: 'ASan + LSan + UBSan + integer, no depends, USDT'
|
||||
runs-on: ubuntu-24.04 # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools
|
||||
# No need to run on the read-only mirror, unless it is a PR.
|
||||
if: github.repository != 'bitcoin-core/gui' || github.event_name == 'pull_request'
|
||||
timeout-minutes: 120
|
||||
- name: CI script
|
||||
run: ./ci/test_run_all.sh
|
||||
|
||||
ci-matrix:
|
||||
name: ${{ matrix.name }}
|
||||
needs: runners
|
||||
runs-on: ${{ needs.runners.outputs.use-cirrus-runners == 'true' && matrix.cirrus-runner || matrix.fallback-runner }}
|
||||
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
|
||||
timeout-minutes: ${{ matrix.timeout-minutes }}
|
||||
|
||||
env:
|
||||
FILE_ENV: "./ci/test/00_setup_env_native_asan.sh"
|
||||
DANGER_CI_ON_HOST_CACHE_FOLDERS: 1
|
||||
DANGER_CI_ON_HOST_FOLDERS: 1
|
||||
FILE_ENV: ${{ matrix.file-env }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: 'ARM, unit tests, no functional tests'
|
||||
cirrus-runner: 'ubuntu-24.04-arm' # Cirrus' Arm runners are Apple (with virtual Linux aarch64), which doesn't support 32-bit mode
|
||||
fallback-runner: 'ubuntu-24.04-arm'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_arm.sh'
|
||||
|
||||
- name: 'Win64, unit tests, no gui tests, no functional tests'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_win64.sh'
|
||||
|
||||
- name: 'ASan + LSan + UBSan + integer, no depends, USDT'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_native_asan.sh'
|
||||
|
||||
- name: 'macOS-cross, gui, no tests'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_mac_cross.sh'
|
||||
|
||||
- name: 'No wallet, libbitcoinkernel'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh'
|
||||
|
||||
- name: 'i686, multiprocess, DEBUG'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_i686_multiprocess.sh'
|
||||
|
||||
- name: 'fuzzer,address,undefined,integer, no depends'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 240
|
||||
file-env: './ci/test/00_setup_env_native_fuzz.sh'
|
||||
|
||||
- name: 'previous releases, depends DEBUG'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_native_previous_releases.sh'
|
||||
|
||||
- name: '32bit CentOS, dash, gui'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_i686_centos.sh'
|
||||
|
||||
- name: 'tidy'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_native_tidy.sh'
|
||||
|
||||
- name: 'TSan, depends, gui'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_native_tsan.sh'
|
||||
|
||||
- name: 'MSan, depends'
|
||||
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg'
|
||||
fallback-runner: 'ubuntu-24.04'
|
||||
timeout-minutes: 120
|
||||
file-env: './ci/test/00_setup_env_native_msan.sh'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- *CHECKOUT
|
||||
|
||||
- name: Set Ccache directory
|
||||
run: echo "CCACHE_DIR=${RUNNER_TEMP}/ccache_dir" >> "$GITHUB_ENV"
|
||||
- name: Configure environment
|
||||
uses: ./.github/actions/configure-environment
|
||||
|
||||
- name: Set base root directory
|
||||
run: echo "BASE_ROOT_DIR=${RUNNER_TEMP}" >> "$GITHUB_ENV"
|
||||
- name: Restore caches
|
||||
id: restore-cache
|
||||
uses: ./.github/actions/restore-caches
|
||||
|
||||
- name: Restore Ccache cache
|
||||
id: ccache-cache
|
||||
uses: actions/cache/restore@v4
|
||||
- name: Configure Docker
|
||||
uses: ./.github/actions/configure-docker
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ github.job }}-ccache-${{ github.run_id }}
|
||||
restore-keys: ${{ github.job }}-ccache-
|
||||
use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }}
|
||||
|
||||
- name: Enable bpfcc script
|
||||
if: ${{ env.CONTAINER_NAME == 'ci_native_asan' }}
|
||||
# In the image build step, no external environment variables are available,
|
||||
# so any settings will need to be written to the settings env file:
|
||||
run: sed -i "s|\${INSTALL_BCC_TRACING_TOOLS}|true|g" ./ci/test/00_setup_env_native_asan.sh
|
||||
|
||||
- name: Set mmap_rnd_bits
|
||||
if: ${{ env.CONTAINER_NAME == 'ci_native_tsan' || env.CONTAINER_NAME == 'ci_native_msan' }}
|
||||
# Prevents crashes due to high ASLR entropy
|
||||
run: sudo sysctl -w vm.mmap_rnd_bits=28
|
||||
|
||||
- name: CI script
|
||||
run: ./ci/test_run_all.sh
|
||||
|
||||
- name: Save Ccache cache
|
||||
uses: actions/cache/save@v4
|
||||
if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true'
|
||||
- name: Save caches
|
||||
uses: ./.github/actions/save-caches
|
||||
|
||||
lint:
|
||||
name: 'lint'
|
||||
needs: runners
|
||||
runs-on: ${{ needs.runners.outputs.use-cirrus-runners == 'true' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-xs' || 'ubuntu-24.04' }}
|
||||
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
CONTAINER_NAME: "bitcoin-linter"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
|
||||
key: ${{ github.job }}-ccache-${{ github.run_id }}
|
||||
ref: *CHECKOUT_REF_TMPL
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Configure Docker
|
||||
uses: ./.github/actions/configure-docker
|
||||
with:
|
||||
use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }}
|
||||
|
||||
- name: CI script
|
||||
run: |
|
||||
set -o xtrace
|
||||
docker buildx build -t "$CONTAINER_NAME" $DOCKER_BUILD_CACHE_ARG --file "./ci/lint_imagefile" .
|
||||
CIRRUS_PR_FLAG=""
|
||||
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||
CIRRUS_PR_FLAG="-e CIRRUS_PR=1"
|
||||
fi
|
||||
docker run --rm $CIRRUS_PR_FLAG -v "$(pwd)":/bitcoin "$CONTAINER_NAME"
|
||||
|
||||
4
COPYING
4
COPYING
@@ -1,7 +1,7 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2009-2024 The Bitcoin Core developers
|
||||
Copyright (c) 2009-2024 Bitcoin Developers
|
||||
Copyright (c) 2009-2025 The Bitcoin Core developers
|
||||
Copyright (c) 2009-2025 Bitcoin Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -69,7 +69,7 @@ Translations
|
||||
------------
|
||||
|
||||
Changes to translations as well as new translations can be submitted to
|
||||
[Bitcoin Core's Transifex page](https://www.transifex.com/bitcoin/bitcoin/).
|
||||
[Bitcoin Core's Transifex page](https://explore.transifex.com/bitcoin/bitcoin/).
|
||||
|
||||
Translations are periodically pulled from Transifex and merged into the git repository. See the
|
||||
[translation process](doc/translation_process.md) for details on how this works.
|
||||
|
||||
@@ -32,7 +32,7 @@ Qt
|
||||
---------------------
|
||||
To build Bitcoin Core with the GUI, a static build of Qt is required.
|
||||
|
||||
1. Download a single ZIP archive of Qt source code from https://download.qt.io/official_releases/qt/ (e.g., [`qt-everywhere-opensource-src-5.15.11.zip`](https://download.qt.io/official_releases/qt/5.15/5.15.11/single/qt-everywhere-opensource-src-5.15.11.zip)), and expand it into a dedicated folder. The following instructions assume that this folder is `C:\dev\qt-source`.
|
||||
1. Download a single ZIP archive of Qt source code from https://download.qt.io/archive/qt/ (e.g., [`qt-everywhere-opensource-src-5.15.11.zip`](https://download.qt.io/archive/qt/5.15/5.15.11/single/qt-everywhere-opensource-src-5.15.11.zip)), and expand it into a dedicated folder. The following instructions assume that this folder is `C:\dev\qt-source`.
|
||||
|
||||
> 💡 **Tip:** If you use the default path with "Extract All" for the Qt source code zip file, and end up with something like `C:\dev\qt-everywhere-opensource-src-5.15.11\qt-everywhere-src-5.15.11`, you are likely to encounter a "path too long" error when building. To fix the problem move the source files to a shorter path such as the recommended `C:\dev\qt-source`.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\test\fuzz\*.cpp" />
|
||||
<ClCompile Include="..\..\src\test\fuzz\*.cpp" Exclude="..\..\src\test\fuzz\utxo_snapshot.cpp" />
|
||||
<ClCompile Include="..\..\src\test\fuzz\util\descriptor.cpp">
|
||||
<ObjectFileName>$(IntDir)test_fuzz_util_descriptor.obj</ObjectFileName>
|
||||
</ClCompile>
|
||||
|
||||
32
ci/README.md
32
ci/README.md
@@ -1,8 +1,8 @@
|
||||
## CI Scripts
|
||||
# CI Scripts
|
||||
|
||||
This directory contains scripts for each build step in each build stage.
|
||||
|
||||
### Running a Stage Locally
|
||||
## Running a Stage Locally
|
||||
|
||||
Be aware that the tests will be built and run in-place, so please run at your own risk.
|
||||
If the repository is not a fresh git clone, you might have to clean files from previous builds or test runs first.
|
||||
@@ -27,7 +27,7 @@ with a specific configuration,
|
||||
env -i HOME="$HOME" PATH="$PATH" USER="$USER" bash -c 'FILE_ENV="./ci/test/00_setup_env_arm.sh" ./ci/test_run_all.sh'
|
||||
```
|
||||
|
||||
### Configurations
|
||||
## Configurations
|
||||
|
||||
The test files (`FILE_ENV`) are constructed to test a wide range of
|
||||
configurations, rather than a single pass/fail. This helps to catch build
|
||||
@@ -49,8 +49,32 @@ env -i HOME="$HOME" PATH="$PATH" USER="$USER" bash -c 'MAKEJOBS="-j1" FILE_ENV="
|
||||
The files starting with `0n` (`n` greater than 0) are the scripts that are run
|
||||
in order.
|
||||
|
||||
### Cache
|
||||
## Cache
|
||||
|
||||
In order to avoid rebuilding all dependencies for each build, the binaries are
|
||||
cached and reused when possible. Changes in the dependency-generator will
|
||||
trigger cache-invalidation and rebuilds as necessary.
|
||||
|
||||
## Configuring a repository for CI
|
||||
|
||||
### Primary repository
|
||||
|
||||
To configure the primary repository, follow these steps:
|
||||
|
||||
1. Register with [Cirrus Runners](https://cirrus-runners.app/) and purchase runners.
|
||||
2. Install the Cirrus Runners GitHub app against the GitHub organization.
|
||||
3. Enable organisation-level runners to be used in public repositories:
|
||||
1. `Org settings -> Actions -> Runner Groups -> Default -> Allow public repos`
|
||||
4. Permit the following actions to run:
|
||||
1. cirruslabs/cache/restore@\*
|
||||
1. cirruslabs/cache/save@\*
|
||||
1. docker/setup-buildx-action@\*
|
||||
1. actions/github-script@\*
|
||||
|
||||
### Forked repositories
|
||||
|
||||
When used in a fork the CI will run on GitHub's free hosted runners by default.
|
||||
In this case, due to GitHub's 10GB-per-repo cache size limitations caches will be frequently evicted and missed, but the workflows will run (slowly).
|
||||
|
||||
It is also possible to use your own Cirrus Runners in your own fork with an appropriate patch to the `REPO_USE_CIRRUS_RUNNERS` variable in ../.github/workflows/ci.yml
|
||||
NB that Cirrus Runners only work at an organisation level, therefore in order to use your own Cirrus Runners, *the fork must be within your own organisation*.
|
||||
|
||||
@@ -1,17 +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.UTF-8
|
||||
|
||||
# Only used in .cirrus.yml. Refer to test/lint/README.md on how to run locally.
|
||||
|
||||
cp "./ci/retry/retry" "/ci_retry"
|
||||
cp "./.python-version" "/.python-version"
|
||||
mkdir --parents "/test/lint"
|
||||
cp --recursive "./test/lint/test_runner" "/test/lint/"
|
||||
set -o errexit; source ./ci/lint/04_install.sh
|
||||
set -o errexit
|
||||
./ci/lint/06_script.sh
|
||||
@@ -35,7 +35,7 @@ fi
|
||||
|
||||
echo "Fallback to default values in env (if not yet set)"
|
||||
# The number of parallel jobs to pass down to make and test_runner.py
|
||||
export MAKEJOBS=${MAKEJOBS:--j4}
|
||||
export MAKEJOBS=${MAKEJOBS:--j$(if command -v nproc > /dev/null 2>&1; then nproc; else sysctl -n hw.logicalcpu; fi)}
|
||||
# Whether to prefer BusyBox over GNU utilities
|
||||
export USE_BUSY_BOX=${USE_BUSY_BOX:-false}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ export LC_ALL=C.UTF-8
|
||||
export HOST=x86_64-apple-darwin
|
||||
# Homebrew's python@3.12 is marked as externally managed (PEP 668).
|
||||
# Therefore, `--break-system-packages` is needed.
|
||||
export CONTAINER_NAME="ci_mac_native" # macos does not use a container, but the env var is needed for logging
|
||||
export PIP_PACKAGES="--break-system-packages zmq"
|
||||
export GOAL="install"
|
||||
export BITCOIN_CONFIG="--with-gui --with-miniupnpc --with-natpmp --enable-reduce-exports"
|
||||
|
||||
@@ -17,3 +17,4 @@ export FUZZ_TESTS_CONFIG="--valgrind"
|
||||
export GOAL="install"
|
||||
export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer CC=clang-16 CXX=clang++-16"
|
||||
export CCACHE_MAXSIZE=200M
|
||||
export LLVM_SYMBOLIZER_PATH="/usr/bin/llvm-symbolizer-16"
|
||||
|
||||
@@ -17,11 +17,16 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then
|
||||
docker run --rm "${CI_IMAGE_NAME_TAG}" bash -c "env | grep --extended-regexp '^(HOME|PATH|USER)='" | tee --append "/tmp/env-$USER-$CONTAINER_NAME"
|
||||
echo "Creating $CI_IMAGE_NAME_TAG container to run in"
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
# Use buildx unconditionally
|
||||
# Using buildx is required to properly load the correct driver, for use with registry caching. Neither build, nor BUILDKIT=1 currently do this properly
|
||||
# shellcheck disable=SC2086
|
||||
docker buildx build \
|
||||
--file "${BASE_READ_ONLY_DIR}/ci/test_imagefile" \
|
||||
--build-arg "CI_IMAGE_NAME_TAG=${CI_IMAGE_NAME_TAG}" \
|
||||
--build-arg "FILE_ENV=${FILE_ENV}" \
|
||||
--build-arg "BASE_ROOT_DIR=${BASE_ROOT_DIR}" \
|
||||
--label="${CI_IMAGE_LABEL}" \
|
||||
$DOCKER_BUILD_CACHE_ARG \
|
||||
--tag="${CONTAINER_NAME}" \
|
||||
"${BASE_READ_ONLY_DIR}"
|
||||
|
||||
|
||||
@@ -25,6 +25,14 @@ fi
|
||||
echo "Free disk space:"
|
||||
df -h
|
||||
|
||||
# We force an install of linux-headers again here via $PACKAGES to fix any
|
||||
# kernel mismatch between a cached docker image and the underlying host.
|
||||
# This can happen occasionally on hosted runners if the runner image is updated.
|
||||
if [[ "$CONTAINER_NAME" == "ci_native_asan" ]]; then
|
||||
$CI_RETRY_EXE apt-get update
|
||||
${CI_RETRY_EXE} bash -c "apt-get install --no-install-recommends --no-upgrade -y $PACKAGES"
|
||||
fi
|
||||
|
||||
# What host to compile for. See also ./depends/README.md
|
||||
# Tests that need cross-compilation export the appropriate HOST.
|
||||
# Tests that run natively guess the host
|
||||
@@ -137,6 +145,12 @@ fi
|
||||
bash -c "${MAYBE_BEAR} ${MAYBE_TOKEN} make $MAKEJOBS $GOAL" || ( echo "Build failure. Verbose build follows." && make "$GOAL" V=1 ; false )
|
||||
|
||||
bash -c "${PRINT_CCACHE_STATISTICS}"
|
||||
if [ "$CI" = "true" ]; then
|
||||
hit_rate=$(ccache -s | grep "Hits:" | head -1 | sed 's/.*(\(.*\)%).*/\1/')
|
||||
if [ "${hit_rate%.*}" -lt 75 ]; then
|
||||
echo "::notice title=low ccache hitrate::Ccache hit-rate in $CONTAINER_NAME was $hit_rate%"
|
||||
fi
|
||||
fi
|
||||
du -sh "${DEPENDS_DIR}"/*/
|
||||
du -sh "${PREVIOUS_RELEASES_DIR}"
|
||||
|
||||
|
||||
@@ -4,12 +4,16 @@
|
||||
|
||||
# See ci/README.md for usage.
|
||||
|
||||
ARG CI_IMAGE_NAME_TAG
|
||||
# We never want scratch, but default arg silences a Warning
|
||||
ARG CI_IMAGE_NAME_TAG=scratch
|
||||
FROM ${CI_IMAGE_NAME_TAG}
|
||||
|
||||
ARG FILE_ENV
|
||||
ENV FILE_ENV=${FILE_ENV}
|
||||
|
||||
ARG BASE_ROOT_DIR
|
||||
ENV BASE_ROOT_DIR=${BASE_ROOT_DIR}
|
||||
|
||||
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/
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
AC_PREREQ([2.69])
|
||||
define(_CLIENT_VERSION_MAJOR, 28)
|
||||
define(_CLIENT_VERSION_MINOR, 0)
|
||||
define(_CLIENT_VERSION_MINOR, 3)
|
||||
define(_CLIENT_VERSION_BUILD, 0)
|
||||
define(_CLIENT_VERSION_RC, 2)
|
||||
define(_CLIENT_VERSION_IS_RELEASE, true)
|
||||
define(_COPYRIGHT_YEAR, 2024)
|
||||
define(_COPYRIGHT_YEAR, 2025)
|
||||
define(_COPYRIGHT_HOLDERS,[The %s developers])
|
||||
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin Core]])
|
||||
AC_INIT([Bitcoin Core],m4_join([.], _CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MINOR, _CLIENT_VERSION_BUILD)m4_if(_CLIENT_VERSION_RC, [0], [], [rc]_CLIENT_VERSION_RC),[https://github.com/bitcoin/bitcoin/issues],[bitcoin],[https://bitcoincore.org/])
|
||||
|
||||
@@ -5,7 +5,7 @@ Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com>
|
||||
Source: https://github.com/bitcoin/bitcoin
|
||||
|
||||
Files: *
|
||||
Copyright: 2009-2024, Bitcoin Core Developers
|
||||
Copyright: 2009-2025, Bitcoin Core Developers
|
||||
License: Expat
|
||||
Comment: The Bitcoin Core Developers encompasses all contributors to the
|
||||
project, listed in the release notes or the git log.
|
||||
|
||||
@@ -72,9 +72,12 @@ cat >> "${EXAMPLE_CONF_FILE}" << 'EOF'
|
||||
# Options for mainnet
|
||||
[main]
|
||||
|
||||
# Options for testnet
|
||||
# Options for testnet3
|
||||
[test]
|
||||
|
||||
# Options for testnet4
|
||||
[testnet4]
|
||||
|
||||
# Options for signet
|
||||
[signet]
|
||||
|
||||
|
||||
@@ -319,7 +319,7 @@ Source: https://logs.guix.gnu.org/guix/2020-11-12.log#232527
|
||||
Start by cloning Guix:
|
||||
|
||||
```
|
||||
git clone https://git.savannah.gnu.org/git/guix.git
|
||||
git clone https://codeberg.org/guix/guix.git
|
||||
cd guix
|
||||
```
|
||||
|
||||
@@ -607,7 +607,7 @@ checklist.
|
||||
```
|
||||
Generation 38 Feb 22 2021 16:39:31 (current)
|
||||
guix f350df4
|
||||
repository URL: https://git.savannah.gnu.org/git/guix.git
|
||||
repository URL: https://codeberg.org/guix/guix.git
|
||||
branch: version-1.2.0
|
||||
commit: f350df405fbcd5b9e27e6b6aa500da7f101f41e7
|
||||
```
|
||||
@@ -760,8 +760,8 @@ Please see the following links for more details:
|
||||
|
||||
- An upstream coreutils bug has been filed: [debbugs#47940](https://debbugs.gnu.org/cgi/bugreport.cgi?bug=47940)
|
||||
- A Guix bug detailing the underlying problem has been filed: [guix-issues#47935](https://issues.guix.gnu.org/47935), [guix-issues#49985](https://issues.guix.gnu.org/49985#5)
|
||||
- A commit to skip this test in Guix has been merged into the core-updates branch:
|
||||
[savannah/guix@6ba1058](https://git.savannah.gnu.org/cgit/guix.git/commit/?id=6ba1058df0c4ce5611c2367531ae5c3cdc729ab4)
|
||||
- A commit to skip this test is included since Guix 1.4.0:
|
||||
[codeberg/guix@6ba1058](https://codeberg.org/guix/guix/commit/6ba1058df0c4ce5611c2367531ae5c3cdc729ab4)
|
||||
|
||||
|
||||
[install-script]: #options-1-and-2-using-the-official-shell-installer-script-or-binary-tarball
|
||||
|
||||
@@ -69,6 +69,12 @@ fi
|
||||
|
||||
mkdir -p "$VERSION_BASE"
|
||||
|
||||
################
|
||||
# SOURCE_DATE_EPOCH should not unintentionally be set
|
||||
################
|
||||
|
||||
check_source_date_epoch
|
||||
|
||||
################
|
||||
# Build directories should not exist
|
||||
################
|
||||
|
||||
@@ -67,6 +67,12 @@ EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
################
|
||||
# SOURCE_DATE_EPOCH should not unintentionally be set
|
||||
################
|
||||
|
||||
check_source_date_epoch
|
||||
|
||||
################
|
||||
# The codesignature git worktree should not be dirty
|
||||
################
|
||||
@@ -137,7 +143,7 @@ fi
|
||||
|
||||
|
||||
################
|
||||
# Unsigned tarballs SHOULD exist
|
||||
# Codesigning tarballs SHOULD exist
|
||||
################
|
||||
|
||||
# Usage: outdir_for_host HOST SUFFIX
|
||||
@@ -149,13 +155,13 @@ outdir_for_host() {
|
||||
}
|
||||
|
||||
|
||||
unsigned_tarball_for_host() {
|
||||
codesigning_tarball_for_host() {
|
||||
case "$1" in
|
||||
*mingw*)
|
||||
echo "$(outdir_for_host "$1")/${DISTNAME}-win64-unsigned.tar.gz"
|
||||
echo "$(outdir_for_host "$1")/${DISTNAME}-win64-codesigning.tar.gz"
|
||||
;;
|
||||
*darwin*)
|
||||
echo "$(outdir_for_host "$1")/${DISTNAME}-${1}-unsigned.tar.gz"
|
||||
echo "$(outdir_for_host "$1")/${DISTNAME}-${1}-codesigning.tar.gz"
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
@@ -164,22 +170,22 @@ unsigned_tarball_for_host() {
|
||||
}
|
||||
|
||||
# Accumulate a list of build directories that already exist...
|
||||
hosts_unsigned_tarball_missing=""
|
||||
hosts_codesigning_tarball_missing=""
|
||||
for host in $HOSTS; do
|
||||
if [ ! -e "$(unsigned_tarball_for_host "$host")" ]; then
|
||||
hosts_unsigned_tarball_missing+=" ${host}"
|
||||
if [ ! -e "$(codesigning_tarball_for_host "$host")" ]; then
|
||||
hosts_codesigning_tarball_missing+=" ${host}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$hosts_unsigned_tarball_missing" ]; then
|
||||
if [ -n "$hosts_codesigning_tarball_missing" ]; then
|
||||
# ...so that we can print them out nicely in an error message
|
||||
cat << EOF
|
||||
ERR: Unsigned tarballs do not exist
|
||||
ERR: Codesigning tarballs do not exist
|
||||
...
|
||||
|
||||
EOF
|
||||
for host in $hosts_unsigned_tarball_missing; do
|
||||
echo " ${host} '$(unsigned_tarball_for_host "$host")'"
|
||||
for host in $hosts_codesigning_tarball_missing; do
|
||||
echo " ${host} '$(codesigning_tarball_for_host "$host")'"
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
@@ -371,7 +377,7 @@ EOF
|
||||
OUTDIR="$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST" codesigned)" \
|
||||
DIST_ARCHIVE_BASE=/outdir-base/dist-archive \
|
||||
DETACHED_SIGS_REPO=/detached-sigs \
|
||||
UNSIGNED_TARBALL="$(OUTDIR_BASE=/outdir-base && unsigned_tarball_for_host "$HOST")" \
|
||||
CODESIGNING_TARBALL="$(OUTDIR_BASE=/outdir-base && codesigning_tarball_for_host "$HOST")" \
|
||||
bash -c "cd /bitcoin && bash contrib/guix/libexec/codesign.sh"
|
||||
)
|
||||
|
||||
|
||||
@@ -289,24 +289,6 @@ mkdir -p "$DISTSRC"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$HOST" in
|
||||
*darwin*)
|
||||
make deploydir ${V:+V=1}
|
||||
mkdir -p "unsigned-app-${HOST}"
|
||||
cp --target-directory="unsigned-app-${HOST}" \
|
||||
contrib/macdeploy/detached-sig-create.sh
|
||||
mv --target-directory="unsigned-app-${HOST}" dist
|
||||
(
|
||||
cd "unsigned-app-${HOST}"
|
||||
find . -print0 \
|
||||
| sort --zero-terminated \
|
||||
| tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \
|
||||
| gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-unsigned.tar.gz" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-unsigned.tar.gz" && exit 1 )
|
||||
)
|
||||
make deploy ${V:+V=1} OSX_ZIP="${OUTDIR}/${DISTNAME}-${HOST}-unsigned.zip"
|
||||
;;
|
||||
esac
|
||||
(
|
||||
cd installed
|
||||
|
||||
@@ -339,7 +321,7 @@ mkdir -p "$DISTSRC"
|
||||
|
||||
cp -r "${DISTSRC}/share/rpcauth" "${DISTNAME}/share/"
|
||||
|
||||
# Finally, deterministically produce {non-,}debug binary tarballs ready
|
||||
# Deterministically produce {non-,}debug binary tarballs ready
|
||||
# for release
|
||||
case "$HOST" in
|
||||
*mingw*)
|
||||
@@ -347,8 +329,8 @@ mkdir -p "$DISTSRC"
|
||||
| xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}"
|
||||
find "${DISTNAME}" -not -name "*.dbg" \
|
||||
| sort \
|
||||
| zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" && exit 1 )
|
||||
| zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}-unsigned.zip" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}-unsigned.zip" && exit 1 )
|
||||
find "${DISTNAME}" -name "*.dbg" -print0 \
|
||||
| xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}"
|
||||
find "${DISTNAME}" -name "*.dbg" \
|
||||
@@ -372,12 +354,13 @@ mkdir -p "$DISTSRC"
|
||||
find "${DISTNAME}" -print0 \
|
||||
| sort --zero-terminated \
|
||||
| tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \
|
||||
| gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" && exit 1 )
|
||||
| gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-unsigned.tar.gz" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-unsigned.tar.gz" && exit 1 )
|
||||
;;
|
||||
esac
|
||||
) # $DISTSRC/installed
|
||||
|
||||
# Finally make tarballs for codesigning
|
||||
case "$HOST" in
|
||||
*mingw*)
|
||||
cp -rf --target-directory=. contrib/windeploy
|
||||
@@ -385,13 +368,33 @@ mkdir -p "$DISTSRC"
|
||||
cd ./windeploy
|
||||
mkdir -p unsigned
|
||||
cp --target-directory=unsigned/ "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe"
|
||||
cp -r --target-directory=unsigned/ "${INSTALLPATH}"
|
||||
find unsigned/ -name "*.dbg" -print0 \
|
||||
| xargs -0r rm
|
||||
find . -print0 \
|
||||
| sort --zero-terminated \
|
||||
| tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \
|
||||
| gzip -9n > "${OUTDIR}/${DISTNAME}-win64-unsigned.tar.gz" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-win64-unsigned.tar.gz" && exit 1 )
|
||||
| gzip -9n > "${OUTDIR}/${DISTNAME}-win64-codesigning.tar.gz" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-win64-codesigning.tar.gz" && exit 1 )
|
||||
)
|
||||
;;
|
||||
*darwin*)
|
||||
make deploydir ${V:+V=1}
|
||||
mkdir -p "unsigned-app-${HOST}"
|
||||
cp --target-directory="unsigned-app-${HOST}" \
|
||||
contrib/macdeploy/detached-sig-create.sh
|
||||
mv --target-directory="unsigned-app-${HOST}" dist
|
||||
cp -r --target-directory="unsigned-app-${HOST}" "${INSTALLPATH}"
|
||||
(
|
||||
cd "unsigned-app-${HOST}"
|
||||
find . -print0 \
|
||||
| sort --zero-terminated \
|
||||
| tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \
|
||||
| gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-codesigning.tar.gz" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-codesigning.tar.gz" && exit 1 )
|
||||
)
|
||||
make deploy ${V:+V=1} OSX_ZIP="${OUTDIR}/${DISTNAME}-${HOST}-unsigned.zip"
|
||||
;;
|
||||
esac
|
||||
) # $DISTSRC
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
export LC_ALL=C
|
||||
set -e -o pipefail
|
||||
|
||||
# Environment variables for determinism
|
||||
export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name"
|
||||
export TZ=UTC
|
||||
|
||||
# Although Guix _does_ set umask when building its own packages (in our case,
|
||||
@@ -27,7 +30,7 @@ fi
|
||||
# Check that required environment variables are set
|
||||
cat << EOF
|
||||
Required environment variables as seen inside the container:
|
||||
UNSIGNED_TARBALL: ${UNSIGNED_TARBALL:?not set}
|
||||
CODESIGNING_TARBALL: ${CODESIGNING_TARBALL:?not set}
|
||||
DETACHED_SIGS_REPO: ${DETACHED_SIGS_REPO:?not set}
|
||||
DIST_ARCHIVE_BASE: ${DIST_ARCHIVE_BASE:?not set}
|
||||
DISTNAME: ${DISTNAME:?not set}
|
||||
@@ -63,27 +66,54 @@ mkdir -p "$DISTSRC"
|
||||
(
|
||||
cd "$DISTSRC"
|
||||
|
||||
tar -xf "$UNSIGNED_TARBALL"
|
||||
tar -xf "$CODESIGNING_TARBALL"
|
||||
|
||||
mkdir -p codesignatures
|
||||
tar -C codesignatures -xf "$CODESIGNATURE_GIT_ARCHIVE"
|
||||
|
||||
case "$HOST" in
|
||||
*mingw*)
|
||||
find "$PWD" -name "*-unsigned.exe" | while read -r infile; do
|
||||
infile_base="$(basename "$infile")"
|
||||
|
||||
# Codesigned *-unsigned.exe and output to OUTDIR
|
||||
# Apply detached codesignatures
|
||||
WORKDIR=".tmp"
|
||||
mkdir -p ${WORKDIR}
|
||||
cp -r --target-directory="${WORKDIR}" "unsigned/${DISTNAME}"
|
||||
find "${WORKDIR}/${DISTNAME}" -name "*.exe" -type f -exec rm {} \;
|
||||
find unsigned/ -name "*.exe" -type f | while read -r bin
|
||||
do
|
||||
bin_base="$(realpath --relative-to=unsigned/ "${bin}")"
|
||||
mkdir -p "${WORKDIR}/$(dirname "${bin_base}")"
|
||||
osslsigncode attach-signature \
|
||||
-in "$infile" \
|
||||
-out "${OUTDIR}/${infile_base/-unsigned}" \
|
||||
-in "${bin}" \
|
||||
-out "${WORKDIR}/${bin_base/-unsigned}" \
|
||||
-CAfile "$GUIX_ENVIRONMENT/etc/ssl/certs/ca-certificates.crt" \
|
||||
-sigin codesignatures/win/"$infile_base".pem
|
||||
-sigin codesignatures/win/"${bin_base}".pem
|
||||
done
|
||||
|
||||
# Move installer to outdir
|
||||
cd "${WORKDIR}"
|
||||
find . -name "*setup.exe" -print0 \
|
||||
| xargs -0r mv --target-directory="${OUTDIR}"
|
||||
|
||||
# Make .zip from binaries
|
||||
find "${DISTNAME}" -print0 \
|
||||
| xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}"
|
||||
find "${DISTNAME}" \
|
||||
| sort \
|
||||
| zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" && exit 1 )
|
||||
;;
|
||||
*darwin*)
|
||||
# Apply detached codesignatures to dist/ (in-place)
|
||||
signapple apply dist/Bitcoin-Qt.app codesignatures/osx/dist
|
||||
case "$HOST" in
|
||||
arm64*) ARCH="arm64" ;;
|
||||
x86_64*) ARCH="x86_64" ;;
|
||||
esac
|
||||
|
||||
# Apply detached codesignatures (in-place)
|
||||
signapple apply dist/Bitcoin-Qt.app codesignatures/osx/"${HOST}"/dist/Bitcoin-Qt.app
|
||||
find "${DISTNAME}" -wholename "*/bin/*" -type f | while read -r bin
|
||||
do
|
||||
signapple apply "${bin}" "codesignatures/osx/${HOST}/${bin}.${ARCH}sign"
|
||||
done
|
||||
|
||||
# Make a .zip from dist/
|
||||
cd dist/
|
||||
@@ -91,6 +121,14 @@ mkdir -p "$DISTSRC"
|
||||
| xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}"
|
||||
find . | sort \
|
||||
| zip -X@ "${OUTDIR}/${DISTNAME}-${HOST}.zip"
|
||||
cd ..
|
||||
|
||||
# Make a .tar.gz from bins
|
||||
find "${DISTNAME}" -print0 \
|
||||
| sort --zero-terminated \
|
||||
| tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \
|
||||
| gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" \
|
||||
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" && exit 1 )
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
@@ -105,7 +143,7 @@ mv --no-target-directory "$OUTDIR" "$ACTUAL_OUTDIR" \
|
||||
(
|
||||
cd /outdir-base
|
||||
{
|
||||
echo "$UNSIGNED_TARBALL"
|
||||
echo "$CODESIGNING_TARBALL"
|
||||
echo "$CODESIGNATURE_GIT_ARCHIVE"
|
||||
find "$ACTUAL_OUTDIR" -type f
|
||||
} | xargs realpath --relative-base="$PWD" \
|
||||
|
||||
@@ -21,6 +21,26 @@ check_tools() {
|
||||
done
|
||||
}
|
||||
|
||||
################
|
||||
# SOURCE_DATE_EPOCH should not unintentionally be set
|
||||
################
|
||||
|
||||
check_source_date_epoch() {
|
||||
if [ -n "$SOURCE_DATE_EPOCH" ] && [ -z "$FORCE_SOURCE_DATE_EPOCH" ]; then
|
||||
cat << EOF
|
||||
ERR: Environment variable SOURCE_DATE_EPOCH is set which may break reproducibility.
|
||||
|
||||
Aborting...
|
||||
|
||||
Hint: You may want to:
|
||||
1. Unset this variable: \`unset SOURCE_DATE_EPOCH\` before rebuilding
|
||||
2. Set the 'FORCE_SOURCE_DATE_EPOCH' environment variable if you insist on
|
||||
using your own epoch
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_tools cat env readlink dirname basename git
|
||||
|
||||
################
|
||||
@@ -50,7 +70,7 @@ fi
|
||||
# across time.
|
||||
time-machine() {
|
||||
# shellcheck disable=SC2086
|
||||
guix time-machine --url=https://git.savannah.gnu.org/git/guix.git \
|
||||
guix time-machine --url=https://codeberg.org/guix/guix.git \
|
||||
--commit=7bf1d7aeaffba15c4f680f93ae88fbef25427252 \
|
||||
--cores="$JOBS" \
|
||||
--keep-failed \
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
(gnu packages moreutils)
|
||||
(gnu packages pkg-config)
|
||||
((gnu packages python) #:select (python-minimal))
|
||||
((gnu packages python-build) #:select (python-tomli))
|
||||
((gnu packages python-build) #:select (python-tomli python-poetry-core))
|
||||
((gnu packages python-crypto) #:select (python-asn1crypto))
|
||||
((gnu packages tls) #:select (openssl))
|
||||
((gnu packages version-control) #:select (git-minimal))
|
||||
(guix build-system cmake)
|
||||
(guix build-system gnu)
|
||||
(guix build-system python)
|
||||
(guix build-system pyproject)
|
||||
(guix build-system trivial)
|
||||
(guix download)
|
||||
(guix gexp)
|
||||
@@ -393,10 +394,10 @@ specific moment in time, whitelisting and revocation checks.")
|
||||
(license license:expat))))
|
||||
|
||||
(define-public python-signapple
|
||||
(let ((commit "62155712e7417aba07565c9780a80e452823ae6a"))
|
||||
(let ((commit "85bfcecc33d2773bc09bc318cec0614af2c8e287"))
|
||||
(package
|
||||
(name "python-signapple")
|
||||
(version (git-version "0.1" "1" commit))
|
||||
(version (git-version "0.2.0" "1" commit))
|
||||
(source
|
||||
(origin
|
||||
(method git-fetch)
|
||||
@@ -406,13 +407,14 @@ specific moment in time, whitelisting and revocation checks.")
|
||||
(file-name (git-file-name name commit))
|
||||
(sha256
|
||||
(base32
|
||||
"1nm6rm4h4m7kbq729si4cm8rzild62mk4ni8xr5zja7l33fhv3gb"))))
|
||||
(build-system python-build-system)
|
||||
"17yqjll8nw83q6dhgqhkl7w502z5vy9sln8m6mlx0f1c10isg8yg"))))
|
||||
(build-system pyproject-build-system)
|
||||
(propagated-inputs
|
||||
(list python-asn1crypto
|
||||
python-oscrypto
|
||||
python-certvalidator
|
||||
python-elfesteem))
|
||||
(native-inputs (list python-poetry-core))
|
||||
;; There are no tests, but attempting to run python setup.py test leads to
|
||||
;; problems, just disable the test
|
||||
(arguments '(#:tests? #f))
|
||||
|
||||
@@ -6,26 +6,57 @@
|
||||
export LC_ALL=C
|
||||
set -e
|
||||
|
||||
ROOTDIR=dist
|
||||
BUNDLE="${ROOTDIR}/Bitcoin-Qt.app"
|
||||
BINARY="${BUNDLE}/Contents/MacOS/Bitcoin-Qt"
|
||||
SIGNAPPLE=signapple
|
||||
TEMPDIR=sign.temp
|
||||
ARCH=$(${SIGNAPPLE} info ${BINARY} | head -n 1 | cut -d " " -f 1)
|
||||
OUT="signature-osx-${ARCH}.tar.gz"
|
||||
OUTROOT=osx/dist
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "usage: $0 <signapple args>"
|
||||
echo "example: $0 <path to key>"
|
||||
BUNDLE_ROOT=dist
|
||||
BUNDLE_NAME="Bitcoin-Qt.app"
|
||||
UNSIGNED_BUNDLE="${BUNDLE_ROOT}/${BUNDLE_NAME}"
|
||||
UNSIGNED_BINARY="${UNSIGNED_BUNDLE}/Contents/MacOS/Bitcoin-Qt"
|
||||
|
||||
ARCH=$(${SIGNAPPLE} info ${UNSIGNED_BINARY} | head -n 1 | cut -d " " -f 1)
|
||||
|
||||
OUTDIR="osx/${ARCH}-apple-darwin"
|
||||
OUTROOT="${TEMPDIR}/${OUTDIR}"
|
||||
|
||||
OUT="signature-osx-${ARCH}.tar.gz"
|
||||
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo "usage: $0 <path to key> <path to app store connect key> <apple developer team uuid>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf ${TEMPDIR}
|
||||
mkdir -p ${TEMPDIR}
|
||||
|
||||
${SIGNAPPLE} sign -f --detach "${TEMPDIR}/${OUTROOT}" "$@" "${BUNDLE}" --hardened-runtime
|
||||
stty -echo
|
||||
printf "Enter the passphrase for %s: " "$1"
|
||||
read cs_key_pass
|
||||
printf "\n"
|
||||
printf "Enter the passphrase for %s: " "$2"
|
||||
read api_key_pass
|
||||
printf "\n"
|
||||
stty echo
|
||||
|
||||
tar -C "${TEMPDIR}" -czf "${OUT}" .
|
||||
# Sign and notarize app bundle
|
||||
${SIGNAPPLE} sign -f --hardened-runtime --detach "${OUTROOT}/${BUNDLE_ROOT}" --passphrase "${cs_key_pass}" "$1" "${UNSIGNED_BUNDLE}"
|
||||
${SIGNAPPLE} apply "${UNSIGNED_BUNDLE}" "${OUTROOT}/${BUNDLE_ROOT}/${BUNDLE_NAME}"
|
||||
${SIGNAPPLE} notarize --detach "${OUTROOT}/${BUNDLE_ROOT}" --passphrase "${api_key_pass}" "$2" "$3" "${UNSIGNED_BUNDLE}"
|
||||
|
||||
# Sign each binary
|
||||
find . -maxdepth 3 -wholename "*/bin/*" -type f -exec realpath --relative-to=. {} \; | while read -r bin
|
||||
do
|
||||
bin_dir=$(dirname "${bin}")
|
||||
bin_name=$(basename "${bin}")
|
||||
${SIGNAPPLE} sign -f --hardened-runtime --detach "${OUTROOT}/${bin_dir}" --passphrase "${cs_key_pass}" "$1" "${bin}"
|
||||
${SIGNAPPLE} apply "${bin}" "${OUTROOT}/${bin_dir}/${bin_name}.${ARCH}sign"
|
||||
done
|
||||
|
||||
# Notarize the binaries
|
||||
# Binaries cannot have stapled notarizations so this does not actually generate any output
|
||||
binaries_dir=$(dirname "$(find . -maxdepth 2 -wholename '*/bin' -type d -exec realpath --relative-to=. {} \;)")
|
||||
${SIGNAPPLE} notarize --passphrase "${api_key_pass}" "$2" "$3" "${binaries_dir}"
|
||||
|
||||
tar -C "${TEMPDIR}" -czf "${OUT}" "${OUTDIR}"
|
||||
rm -rf "${TEMPDIR}"
|
||||
echo "Created ${OUT}"
|
||||
|
||||
@@ -465,18 +465,18 @@ if config.translations_dir:
|
||||
sys.stderr.write(f"Error: Could not find translation dir \"{config.translations_dir[0]}\"\n")
|
||||
sys.exit(1)
|
||||
|
||||
print("+ Adding Qt translations +")
|
||||
print("+ Adding Qt translations +")
|
||||
|
||||
translations = Path(config.translations_dir[0])
|
||||
translations = Path(config.translations_dir[0])
|
||||
|
||||
regex = re.compile('qt_[a-z]*(.qm|_[A-Z]*.qm)')
|
||||
regex = re.compile('qt_[a-z]*(.qm|_[A-Z]*.qm)')
|
||||
|
||||
lang_files = [x for x in translations.iterdir() if regex.match(x.name)]
|
||||
lang_files = [x for x in translations.iterdir() if regex.match(x.name)]
|
||||
|
||||
for file in lang_files:
|
||||
if verbose:
|
||||
print(file.as_posix(), "->", os.path.join(applicationBundle.resourcesPath, file.name))
|
||||
shutil.copy2(file.as_posix(), os.path.join(applicationBundle.resourcesPath, file.name))
|
||||
for file in lang_files:
|
||||
if verbose:
|
||||
print(file.as_posix(), "->", os.path.join(applicationBundle.resourcesPath, file.name))
|
||||
shutil.copy2(file.as_posix(), os.path.join(applicationBundle.resourcesPath, file.name))
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
|
||||
@@ -41,7 +41,8 @@ from bcc import BPF, USDT
|
||||
program = """
|
||||
#include <uapi/linux/ptrace.h>
|
||||
|
||||
#define MIN(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
|
||||
// A min() macro. Prefixed with _TRACEPOINT_TEST to avoid collision with other MIN macros.
|
||||
#define _TRACEPOINT_TEST_MIN(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
|
||||
|
||||
// Maximum possible allocation size
|
||||
// from include/linux/percpu.h in the Linux kernel
|
||||
@@ -88,7 +89,7 @@ int trace_inbound_message(struct pt_regs *ctx) {
|
||||
bpf_usdt_readarg_p(3, ctx, &msg->peer_conn_type, MAX_PEER_CONN_TYPE_LENGTH);
|
||||
bpf_usdt_readarg_p(4, ctx, &msg->msg_type, MAX_MSG_TYPE_LENGTH);
|
||||
bpf_usdt_readarg(5, ctx, &msg->msg_size);
|
||||
bpf_usdt_readarg_p(6, ctx, &msg->msg, MIN(msg->msg_size, MAX_MSG_DATA_LENGTH));
|
||||
bpf_usdt_readarg_p(6, ctx, &msg->msg, _TRACEPOINT_TEST_MIN(msg->msg_size, MAX_MSG_DATA_LENGTH));
|
||||
|
||||
inbound_messages.perf_submit(ctx, msg, sizeof(*msg));
|
||||
return 0;
|
||||
@@ -108,7 +109,7 @@ int trace_outbound_message(struct pt_regs *ctx) {
|
||||
bpf_usdt_readarg_p(3, ctx, &msg->peer_conn_type, MAX_PEER_CONN_TYPE_LENGTH);
|
||||
bpf_usdt_readarg_p(4, ctx, &msg->msg_type, MAX_MSG_TYPE_LENGTH);
|
||||
bpf_usdt_readarg(5, ctx, &msg->msg_size);
|
||||
bpf_usdt_readarg_p(6, ctx, &msg->msg, MIN(msg->msg_size, MAX_MSG_DATA_LENGTH));
|
||||
bpf_usdt_readarg_p(6, ctx, &msg->msg, _TRACEPOINT_TEST_MIN(msg->msg_size, MAX_MSG_DATA_LENGTH));
|
||||
|
||||
outbound_messages.perf_submit(ctx, msg, sizeof(*msg));
|
||||
return 0;
|
||||
|
||||
@@ -8,9 +8,9 @@ if [ -z "$OSSLSIGNCODE" ]; then
|
||||
OSSLSIGNCODE=osslsigncode
|
||||
fi
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "usage: $0 <osslcodesign args>"
|
||||
echo "example: $0 -key codesign.key"
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "usage: $0 <path to key>"
|
||||
echo "example: $0 codesign.key"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -22,12 +22,22 @@ OUTSUBDIR="${OUTDIR}/win"
|
||||
TIMESERVER=http://timestamp.comodoca.com
|
||||
CERTFILE="win-codesign.cert"
|
||||
|
||||
stty -echo
|
||||
printf "Enter the passphrase for %s: " "$1"
|
||||
read cs_key_pass
|
||||
printf "\n"
|
||||
stty echo
|
||||
|
||||
|
||||
mkdir -p "${OUTSUBDIR}"
|
||||
# shellcheck disable=SC2046
|
||||
basename -a $(ls -1 "${SRCDIR}"/*-unsigned.exe) | while read UNSIGNED; do
|
||||
echo Signing "${UNSIGNED}"
|
||||
"${OSSLSIGNCODE}" sign -certs "${CERTFILE}" -t "${TIMESERVER}" -h sha256 -in "${SRCDIR}/${UNSIGNED}" -out "${WORKDIR}/${UNSIGNED}" "$@"
|
||||
"${OSSLSIGNCODE}" extract-signature -pem -in "${WORKDIR}/${UNSIGNED}" -out "${OUTSUBDIR}/${UNSIGNED}.pem" && rm "${WORKDIR}/${UNSIGNED}"
|
||||
find ${SRCDIR} -wholename "*.exe" -type f -exec realpath --relative-to=. {} \; | while read -r bin
|
||||
do
|
||||
echo Signing "${bin}"
|
||||
bin_base="$(realpath --relative-to=${SRCDIR} "${bin}")"
|
||||
mkdir -p "$(dirname ${WORKDIR}/"${bin_base}")"
|
||||
"${OSSLSIGNCODE}" sign -certs "${CERTFILE}" -t "${TIMESERVER}" -h sha256 -in "${bin}" -out "${WORKDIR}/${bin_base}" -key "$1" -pass "${cs_key_pass}"
|
||||
mkdir -p "$(dirname ${OUTSUBDIR}/"${bin_base}")"
|
||||
"${OSSLSIGNCODE}" extract-signature -pem -in "${WORKDIR}/${bin_base}" -out "${OUTSUBDIR}/${bin_base}.pem" && rm "${WORKDIR}/${bin_base}"
|
||||
done
|
||||
|
||||
rm -f "${OUT}"
|
||||
|
||||
@@ -143,7 +143,7 @@ include packages/packages.mk
|
||||
# 2. Before including packages/*.mk (excluding packages/packages.mk), since
|
||||
# they rely on the build_id variables
|
||||
#
|
||||
build_id:=$(shell env CC='$(build_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(build_CXX)' CXX_STANDARD='$(CXX_STANDARD)' AR='$(build_AR) 'NM='$(build_NM)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' NO_HARDEN='$(NO_HARDEN)' ./gen_id '$(BUILD_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
|
||||
build_id:=$(shell env CC='$(build_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(build_CXX)' CXX_STANDARD='$(CXX_STANDARD)' AR='$(build_AR)' NM='$(build_NM)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' NO_HARDEN='$(NO_HARDEN)' ./gen_id '$(BUILD_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
|
||||
$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(host_CXX)' CXX_STANDARD='$(CXX_STANDARD)' AR='$(host_AR)' NM='$(host_NM)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' NO_HARDEN='$(NO_HARDEN)' ./gen_id '$(HOST_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
|
||||
|
||||
boost_packages_$(NO_BOOST) = $(boost_packages)
|
||||
|
||||
@@ -186,6 +186,7 @@ $(1)_cmake=env CC="$$($(1)_cc)" \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib/ \
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=$(V) \
|
||||
-DCMAKE_EXPORT_NO_PACKAGE_REGISTRY:BOOL=TRUE \
|
||||
$$($(1)_config_opts)
|
||||
ifeq ($($(1)_type),build)
|
||||
$(1)_cmake += -DCMAKE_INSTALL_RPATH:PATH="$$($($(1)_type)_prefix)/lib"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
ifneq ($(shell $(SHELL) $(.SHELLFLAGS) "command -v $(host)-gcc-posix"),)
|
||||
mingw32_CC := $(host)-gcc-posix
|
||||
endif
|
||||
ifneq ($(shell $(SHELL) $(.SHELLFLAGS) "command -v $(host)-g++-posix"),)
|
||||
mingw32_CXX := $(host)-g++-posix
|
||||
endif
|
||||
|
||||
@@ -7,8 +7,6 @@ netbsd_NM = $(host_toolchain)gcc-nm
|
||||
netbsd_RANLIB = $(host_toolchain)gcc-ranlib
|
||||
endif
|
||||
|
||||
netbsd_CXXFLAGS=$(netbsd_CFLAGS)
|
||||
|
||||
netbsd_release_CFLAGS=-O2
|
||||
netbsd_release_CXXFLAGS=$(netbsd_release_CFLAGS)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ $(package)_download_file=$(native_$(package)_download_file)
|
||||
$(package)_file_name=$(native_$(package)_file_name)
|
||||
$(package)_sha256_hash=$(native_$(package)_sha256_hash)
|
||||
|
||||
define $(package)_set_vars :=
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts := -DBUILD_TESTING=OFF
|
||||
$(package)_config_opts += -DWITH_OPENSSL=OFF
|
||||
$(package)_config_opts += -DWITH_ZLIB=OFF
|
||||
|
||||
@@ -4,6 +4,7 @@ $(package)_download_path=https://download.savannah.gnu.org/releases/$(package)
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.xz
|
||||
$(package)_sha256_hash=8bee39bd3968c4804b70614a0a3ad597299ad0e824bc8aad5ce8aaf48067bde7
|
||||
$(package)_build_subdir=build
|
||||
$(package)_patches += cmake_minimum.patch
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts := -DCMAKE_BUILD_TYPE=None -DBUILD_SHARED_LIBS=TRUE
|
||||
@@ -12,6 +13,10 @@ define $(package)_set_vars
|
||||
$(package)_config_opts += -DCMAKE_DISABLE_FIND_PACKAGE_BrotliDec=TRUE
|
||||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
patch -p1 < $($(package)_patch_dir)/cmake_minimum.patch
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
$($(package)_cmake) -S .. -B .
|
||||
endef
|
||||
|
||||
@@ -5,6 +5,7 @@ $(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb
|
||||
$(package)_patches=cmake_fixups.patch
|
||||
$(package)_patches+=fix_mingw_link.patch
|
||||
$(package)_patches += netbsd_fixup.patch
|
||||
$(package)_build_subdir=build
|
||||
|
||||
# When building for Windows, we set _WIN32_WINNT to target the same Windows
|
||||
@@ -24,7 +25,8 @@ endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
patch -p1 < $($(package)_patch_dir)/cmake_fixups.patch && \
|
||||
patch -p1 < $($(package)_patch_dir)/fix_mingw_link.patch
|
||||
patch -p1 < $($(package)_patch_dir)/fix_mingw_link.patch && \
|
||||
patch -p1 < $($(package)_patch_dir)/netbsd_fixup.patch
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
|
||||
@@ -8,7 +8,7 @@ ifneq ($(host),$(build))
|
||||
$(package)_dependencies += native_capnp
|
||||
endif
|
||||
|
||||
define $(package)_set_vars :=
|
||||
define $(package)_set_vars
|
||||
ifneq ($(host),$(build))
|
||||
$(package)_config_opts := -DCAPNP_EXECUTABLE="$$(native_capnp_prefixbin)/capnp"
|
||||
$(package)_config_opts += -DCAPNPC_CXX_EXECUTABLE="$$(native_capnp_prefixbin)/capnpc-c++"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package=qt
|
||||
$(package)_version=5.15.14
|
||||
$(package)_download_path=https://download.qt.io/official_releases/qt/5.15/$($(package)_version)/submodules
|
||||
$(package)_download_path=https://download.qt.io/archive/qt/5.15/$($(package)_version)/submodules
|
||||
$(package)_suffix=everywhere-opensource-src-$($(package)_version).tar.xz
|
||||
$(package)_file_name=qtbase-$($(package)_suffix)
|
||||
$(package)_sha256_hash=500d3b390048e9538c28b5f523dfea6936f9c2e10d24ab46580ff57d430b98be
|
||||
|
||||
@@ -21,6 +21,8 @@ define $(package)_build_cmds
|
||||
$(MAKE)
|
||||
endef
|
||||
|
||||
# mkdir detection is broken on Alpine. Set MKDIRPROG to ensure we always
|
||||
# use "mkdir -p", and avoid parallelism issues during install.
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
$(MAKE) MKDIRPROG="mkdir -p" DESTDIR=$($(package)_staging_dir) install
|
||||
endef
|
||||
|
||||
13
depends/patches/freetype/cmake_minimum.patch
Normal file
13
depends/patches/freetype/cmake_minimum.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
build: set minimum required CMake to 3.12
|
||||
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -97,7 +97,7 @@
|
||||
# FreeType explicitly marks the API to be exported and relies on the compiler
|
||||
# to hide all other symbols. CMake supports a C_VISBILITY_PRESET property
|
||||
# starting with 2.8.12.
|
||||
-cmake_minimum_required(VERSION 2.8.12)
|
||||
+cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 3.3)
|
||||
# Allow symbol visibility settings also on static libraries. CMake < 3.3
|
||||
23
depends/patches/libevent/netbsd_fixup.patch
Normal file
23
depends/patches/libevent/netbsd_fixup.patch
Normal file
@@ -0,0 +1,23 @@
|
||||
Improve portability on NetBSD
|
||||
|
||||
According to GCC documentation, "the various `-std` options disable
|
||||
certain keywords".
|
||||
This change adheres to GCC's recommendation by replacing the `typeof`
|
||||
keyword with its alternative, `__typeof__`.
|
||||
|
||||
See https://github.com/libevent/libevent/commit/1759485e9a59147a47a674f5132fcfe764e7748c.
|
||||
|
||||
|
||||
--- a/kqueue.c
|
||||
+++ b/kqueue.c
|
||||
@@ -52,8 +52,8 @@
|
||||
* intptr_t, whereas others define it as void*. There doesn't seem to be an
|
||||
* easy way to tell them apart via autoconf, so we need to use OS macros. */
|
||||
#if defined(__NetBSD__)
|
||||
-#define PTR_TO_UDATA(x) ((typeof(((struct kevent *)0)->udata))(x))
|
||||
-#define INT_TO_UDATA(x) ((typeof(((struct kevent *)0)->udata))(intptr_t)(x))
|
||||
+#define PTR_TO_UDATA(x) ((__typeof__(((struct kevent *)0)->udata))(x))
|
||||
+#define INT_TO_UDATA(x) ((__typeof__(((struct kevent *)0)->udata))(intptr_t)(x))
|
||||
#elif defined(EVENT__HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__) && !defined(__CloudABI__)
|
||||
#define PTR_TO_UDATA(x) ((intptr_t)(x))
|
||||
#define INT_TO_UDATA(x) ((intptr_t)(x))
|
||||
@@ -59,7 +59,8 @@ BIPs that are implemented by Bitcoin Core:
|
||||
Validation rules for Taproot (including Schnorr signatures and Tapscript
|
||||
leaves) are implemented as of **v0.21.0** ([PR 19953](https://github.com/bitcoin/bitcoin/pull/19953)),
|
||||
with mainnet activation as of **v0.21.1** ([PR 21377](https://github.com/bitcoin/bitcoin/pull/21377),
|
||||
[PR 21686](https://github.com/bitcoin/bitcoin/pull/21686)).
|
||||
[PR 21686](https://github.com/bitcoin/bitcoin/pull/21686)),
|
||||
always active as of **v24.0** ([PR 23536](https://github.com/bitcoin/bitcoin/pull/23536)).
|
||||
* [`BIP 350`](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki): Addresses for native v1+ segregated Witness outputs use Bech32m instead of Bech32 as of **v22.0** ([PR 20861](https://github.com/bitcoin/bitcoin/pull/20861)).
|
||||
* [`BIP 371`](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki): Taproot fields for PSBT as of **v24.0** ([PR 22558](https://github.com/bitcoin/bitcoin/pull/22558)).
|
||||
* [`BIP 379`](https://github.com/bitcoin/bips/blob/master/bip-0379.md): Miniscript was partially implemented in **v24.0** ([PR 24148](https://github.com/bitcoin/bitcoin/pull/24148)), and fully implemented as of **v26.0** ([PR 27255](https://github.com/bitcoin/bitcoin/pull/27255)).
|
||||
|
||||
@@ -31,7 +31,7 @@ Comments may appear in two ways:
|
||||
### Network specific options
|
||||
|
||||
Network specific options can be:
|
||||
- placed into sections with headers `[main]` (not `[mainnet]`), `[test]` (not `[testnet]`), `[signet]` or `[regtest]`;
|
||||
- placed into sections with headers `[main]` (not `[mainnet]`), `[test]` (not `[testnet]`, for testnet3), `[testnet4]`, `[signet]` or `[regtest]`;
|
||||
- prefixed with a chain name; e.g., `regtest.maxmempool=100`.
|
||||
|
||||
Network specific options take precedence over non-network specific options.
|
||||
|
||||
@@ -30,7 +30,7 @@ You can find installation instructions in the `build-*.md` file for your platfor
|
||||
| [Fontconfig](../depends/packages/fontconfig.mk) | [link](https://www.freedesktop.org/wiki/Software/fontconfig/) | [2.12.6](https://github.com/bitcoin/bitcoin/pull/23495) | 2.6 | Yes |
|
||||
| [FreeType](../depends/packages/freetype.mk) | [link](https://freetype.org) | [2.11.0](https://github.com/bitcoin/bitcoin/commit/01544dd78ccc0b0474571da854e27adef97137fb) | 2.3.0 | Yes |
|
||||
| [qrencode](../depends/packages/qrencode.mk) | [link](https://fukuchi.org/works/qrencode/) | [4.1.1](https://github.com/bitcoin/bitcoin/pull/27312) | | No |
|
||||
| [Qt](../depends/packages/qt.mk) | [link](https://download.qt.io/official_releases/qt/) | [5.15.14](https://github.com/bitcoin/bitcoin/pull/30198) | [5.11.3](https://github.com/bitcoin/bitcoin/pull/24132) | No |
|
||||
| [Qt](../depends/packages/qt.mk) | [link](https://download.qt.io/archive/qt/) | [5.15.14](https://github.com/bitcoin/bitcoin/pull/30198) | [5.11.3](https://github.com/bitcoin/bitcoin/pull/24132) | No |
|
||||
|
||||
### Networking
|
||||
| Dependency | Releases | Version used | Minimum required | Runtime |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-CLI "1" "September 2024" "bitcoin-cli v28.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-CLI "1" "October 2025" "bitcoin-cli v28.3.0rc2" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-cli \- manual page for bitcoin-cli v28.0.0rc2
|
||||
bitcoin-cli \- manual page for bitcoin-cli v28.3.0rc2
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin-cli
|
||||
[\fI\,options\/\fR] \fI\,<command> \/\fR[\fI\,params\/\fR] \fI\,Send command to Bitcoin Core\/\fR
|
||||
@@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v28.0.0rc2
|
||||
.B bitcoin-cli
|
||||
[\fI\,options\/\fR] \fI\,help <command> Get help for a command\/\fR
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core RPC client version v28.0.0rc2
|
||||
Bitcoin Core RPC client version v28.3.0rc2
|
||||
.SH OPTIONS
|
||||
.HP
|
||||
\-?
|
||||
@@ -176,7 +176,7 @@ Consider moving to testnet4 now by using \fB\-testnet4\fR.
|
||||
.IP
|
||||
Use the testnet4 chain. Equivalent to \fB\-chain\fR=\fI\,testnet4\/\fR.
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 2009-2024 The Bitcoin Core developers
|
||||
Copyright (C) 2009-2025 The Bitcoin Core developers
|
||||
|
||||
Please contribute if you find Bitcoin Core useful. Visit
|
||||
<https://bitcoincore.org/> for further information about the software.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-QT "1" "September 2024" "bitcoin-qt v28.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-QT "1" "October 2025" "bitcoin-qt v28.3.0rc2" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-qt \- manual page for bitcoin-qt v28.0.0rc2
|
||||
bitcoin-qt \- manual page for bitcoin-qt v28.3.0rc2
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin-qt
|
||||
[\fI\,command-line options\/\fR] [\fI\,URI\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core version v28.0.0rc2
|
||||
Bitcoin Core version v28.3.0rc2
|
||||
.PP
|
||||
Optional URI is a Bitcoin address in BIP21 URI format.
|
||||
.SH OPTIONS
|
||||
@@ -352,7 +352,8 @@ Support filtering of blocks and transaction with bloom filters (default:
|
||||
.IP
|
||||
Listen for connections on <port> (default: 8333, testnet3: 18333,
|
||||
testnet4: 48333, signet: 38333, regtest: 18444). Not relevant for
|
||||
I2P (see doc/i2p.md).
|
||||
I2P (see doc/i2p.md). If set to a value x, the default onion
|
||||
listening port will be set to x+1.
|
||||
.HP
|
||||
\fB\-proxy=\fR<ip:port|path>
|
||||
.IP
|
||||
@@ -704,7 +705,7 @@ replaceability signaling (default: 1)
|
||||
\fB\-minrelaytxfee=\fR<amt>
|
||||
.IP
|
||||
Fees (in BTC/kvB) smaller than this are considered zero fee for
|
||||
relaying, mining and transaction creation (default: 0.00001)
|
||||
relaying, mining and transaction creation (default: 0.000001)
|
||||
.HP
|
||||
\fB\-permitbaremultisig\fR
|
||||
.IP
|
||||
@@ -731,7 +732,7 @@ Set maximum BIP141 block weight (default: 3996000)
|
||||
\fB\-blockmintxfee=\fR<amt>
|
||||
.IP
|
||||
Set lowest fee rate (in BTC/kvB) for transactions to be included in
|
||||
block creation. (default: 0.00001)
|
||||
block creation. (default: 0.00000001)
|
||||
.PP
|
||||
RPC server options:
|
||||
.HP
|
||||
@@ -835,7 +836,7 @@ Reset all settings changed in the GUI
|
||||
.IP
|
||||
Show splash screen on startup (default: 1)
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 2009-2024 The Bitcoin Core developers
|
||||
Copyright (C) 2009-2025 The Bitcoin Core developers
|
||||
|
||||
Please contribute if you find Bitcoin Core useful. Visit
|
||||
<https://bitcoincore.org/> for further information about the software.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-TX "1" "September 2024" "bitcoin-tx v28.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-TX "1" "October 2025" "bitcoin-tx v28.3.0rc2" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-tx \- manual page for bitcoin-tx v28.0.0rc2
|
||||
bitcoin-tx \- manual page for bitcoin-tx v28.3.0rc2
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin-tx
|
||||
[\fI\,options\/\fR] \fI\,<hex-tx> \/\fR[\fI\,commands\/\fR] \fI\,Update hex-encoded bitcoin transaction\/\fR
|
||||
@@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v28.0.0rc2
|
||||
.B bitcoin-tx
|
||||
[\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] \fI\,Create hex-encoded bitcoin transaction\/\fR
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core bitcoin\-tx utility version v28.0.0rc2
|
||||
Bitcoin Core bitcoin\-tx utility version v28.3.0rc2
|
||||
.SH OPTIONS
|
||||
.HP
|
||||
\-?
|
||||
@@ -142,7 +142,7 @@ set=NAME:JSON\-STRING
|
||||
.IP
|
||||
Set register NAME to given JSON\-STRING
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 2009-2024 The Bitcoin Core developers
|
||||
Copyright (C) 2009-2025 The Bitcoin Core developers
|
||||
|
||||
Please contribute if you find Bitcoin Core useful. Visit
|
||||
<https://bitcoincore.org/> for further information about the software.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-UTIL "1" "September 2024" "bitcoin-util v28.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-UTIL "1" "October 2025" "bitcoin-util v28.3.0rc2" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-util \- manual page for bitcoin-util v28.0.0rc2
|
||||
bitcoin-util \- manual page for bitcoin-util v28.3.0rc2
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin-util
|
||||
[\fI\,options\/\fR] [\fI\,commands\/\fR] \fI\,Do stuff\/\fR
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core bitcoin\-util utility version v28.0.0rc2
|
||||
Bitcoin Core bitcoin\-util utility version v28.3.0rc2
|
||||
.SH OPTIONS
|
||||
.HP
|
||||
\-?
|
||||
@@ -60,7 +60,7 @@ grind
|
||||
.IP
|
||||
Perform proof of work on hex header string
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 2009-2024 The Bitcoin Core developers
|
||||
Copyright (C) 2009-2025 The Bitcoin Core developers
|
||||
|
||||
Please contribute if you find Bitcoin Core useful. Visit
|
||||
<https://bitcoincore.org/> for further information about the software.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-WALLET "1" "September 2024" "bitcoin-wallet v28.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-WALLET "1" "October 2025" "bitcoin-wallet v28.3.0rc2" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-wallet \- manual page for bitcoin-wallet v28.0.0rc2
|
||||
bitcoin-wallet \- manual page for bitcoin-wallet v28.3.0rc2
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core bitcoin\-wallet version v28.0.0rc2
|
||||
Bitcoin Core bitcoin\-wallet version v28.3.0rc2
|
||||
.PP
|
||||
bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files.
|
||||
By default bitcoin\-wallet will act on wallets in the default mainnet wallet directory in the datadir.
|
||||
@@ -121,7 +121,7 @@ salvage
|
||||
Attempt to recover private keys from a corrupt wallet. Warning:
|
||||
\&'salvage' is experimental.
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 2009-2024 The Bitcoin Core developers
|
||||
Copyright (C) 2009-2025 The Bitcoin Core developers
|
||||
|
||||
Please contribute if you find Bitcoin Core useful. Visit
|
||||
<https://bitcoincore.org/> for further information about the software.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIND "1" "September 2024" "bitcoind v28.0.0rc2" "User Commands"
|
||||
.TH BITCOIND "1" "October 2025" "bitcoind v28.3.0rc2" "User Commands"
|
||||
.SH NAME
|
||||
bitcoind \- manual page for bitcoind v28.0.0rc2
|
||||
bitcoind \- manual page for bitcoind v28.3.0rc2
|
||||
.SH SYNOPSIS
|
||||
.B bitcoind
|
||||
[\fI\,options\/\fR] \fI\,Start Bitcoin Core\/\fR
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core version v28.0.0rc2
|
||||
Bitcoin Core version v28.3.0rc2
|
||||
.SH OPTIONS
|
||||
.HP
|
||||
\-?
|
||||
@@ -350,7 +350,8 @@ Support filtering of blocks and transaction with bloom filters (default:
|
||||
.IP
|
||||
Listen for connections on <port> (default: 8333, testnet3: 18333,
|
||||
testnet4: 48333, signet: 38333, regtest: 18444). Not relevant for
|
||||
I2P (see doc/i2p.md).
|
||||
I2P (see doc/i2p.md). If set to a value x, the default onion
|
||||
listening port will be set to x+1.
|
||||
.HP
|
||||
\fB\-proxy=\fR<ip:port|path>
|
||||
.IP
|
||||
@@ -702,7 +703,7 @@ replaceability signaling (default: 1)
|
||||
\fB\-minrelaytxfee=\fR<amt>
|
||||
.IP
|
||||
Fees (in BTC/kvB) smaller than this are considered zero fee for
|
||||
relaying, mining and transaction creation (default: 0.00001)
|
||||
relaying, mining and transaction creation (default: 0.000001)
|
||||
.HP
|
||||
\fB\-permitbaremultisig\fR
|
||||
.IP
|
||||
@@ -729,7 +730,7 @@ Set maximum BIP141 block weight (default: 3996000)
|
||||
\fB\-blockmintxfee=\fR<amt>
|
||||
.IP
|
||||
Set lowest fee rate (in BTC/kvB) for transactions to be included in
|
||||
block creation. (default: 0.00001)
|
||||
block creation. (default: 0.00000001)
|
||||
.PP
|
||||
RPC server options:
|
||||
.HP
|
||||
@@ -811,7 +812,7 @@ subject to empty whitelists.
|
||||
.IP
|
||||
Accept command line and JSON\-RPC commands
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 2009-2024 The Bitcoin Core developers
|
||||
Copyright (C) 2009-2025 The Bitcoin Core developers
|
||||
|
||||
Please contribute if you find Bitcoin Core useful. Visit
|
||||
<https://bitcoincore.org/> for further information about the software.
|
||||
|
||||
@@ -1 +1,108 @@
|
||||
See https://github.com/bitcoin-core/bitcoin-devwiki/wiki/28.0-Release-Notes-Draft
|
||||
Bitcoin Core version 28.3rc2 is now available from:
|
||||
|
||||
<https://bitcoincore.org/bin/bitcoin-core-28.3/test.rc2/>
|
||||
|
||||
This release includes various bug fixes and performance
|
||||
improvements, as well as updated translations.
|
||||
|
||||
Please report bugs using the issue tracker at GitHub:
|
||||
|
||||
<https://github.com/bitcoin/bitcoin/issues>
|
||||
|
||||
To receive security and update notifications, please subscribe to:
|
||||
|
||||
<https://bitcoincore.org/en/list/announcements/join/>
|
||||
|
||||
How to Upgrade
|
||||
==============
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes in some cases), then run the
|
||||
installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on macOS)
|
||||
or `bitcoind`/`bitcoin-qt` (on Linux).
|
||||
|
||||
Upgrading directly from a version of Bitcoin Core that has reached its EOL is
|
||||
possible, but it might take some time if the data directory needs to be migrated. Old
|
||||
wallet versions of Bitcoin Core are generally supported.
|
||||
|
||||
Compatibility
|
||||
==============
|
||||
|
||||
Bitcoin Core is supported and extensively tested on operating systems
|
||||
using the Linux Kernel 3.17+, macOS 11.0+, and Windows 7 and newer. Bitcoin
|
||||
Core should also work on most other UNIX-like systems but is not as
|
||||
frequently tested on them. It is not recommended to use Bitcoin Core on
|
||||
unsupported systems.
|
||||
|
||||
Notable changes
|
||||
===============
|
||||
|
||||
### Mempool & Policy
|
||||
|
||||
The minimum block feerate (`-blockmintxfee`) has been changed to 1 satoshi per kvB. It can still be changed using the
|
||||
configuration option.
|
||||
|
||||
- The default minimum relay feerate (`-minrelaytxfee`) and incremental relay feerate (`-incrementalrelayfee`) have been
|
||||
changed to 100 satoshis per kvB. They can still be changed using their respective configuration options, but it is
|
||||
recommended to change both together if you decide to do so.
|
||||
- Other minimum feerates (e.g. the dust feerate, the minimum returned by the fee estimator, and all feerates used by
|
||||
the wallet) remain unchanged. The mempool minimum feerate still changes in response to high volume.
|
||||
- Note that unless these lower defaults are widely adopted across the network, transactions created with lower fee
|
||||
rates are not guaranteed to propagate or confirm. The wallet feerates remain unchanged; `-mintxfee` must be changed
|
||||
before attempting to create transactions with lower feerates using the wallet.
|
||||
|
||||
- #33106 policy: lower the default blockmintxfee, incrementalrelayfee, minrelaytxfee
|
||||
- #33504 mempool: Do not enforce TRUC checks on reorg
|
||||
|
||||
### P2P
|
||||
|
||||
- #33395 net: do not apply whitelist permissions to onion inbounds
|
||||
|
||||
### Test
|
||||
|
||||
- #32765 test: Fix list index out of range error in feature_bip68_sequence.py
|
||||
- #33001 test: Do not pass tests on unhandled exceptions
|
||||
- #30125 test: improve BDB parser (handle internal/overflow pages, support all page sizes)
|
||||
- #30948 test: Add missing sync_mempools() to fill_mempool()
|
||||
- #30784 test: add BulkTransaction helper to unit test transaction utils
|
||||
|
||||
### Build
|
||||
|
||||
- #32678 guix: warn and abort when SOURCE_DATE_EPOCH is set
|
||||
- #32943 depends: Force CMAKE_EXPORT_NO_PACKAGE_REGISTRY=TRUE
|
||||
- #33073 guix: warn SOURCE_DATE_EPOCH set in guix-codesign
|
||||
- #33563 build: fix depends Qt download link
|
||||
|
||||
### Doc
|
||||
|
||||
- #32776 doc: taproot became always active in v24.0
|
||||
- #32777 doc: fix Transifex 404s
|
||||
- #33070 doc/zmq: fix unix socket path example
|
||||
- #33133 rpc: fix getpeerinfo ping duration unit docs
|
||||
- #33236 doc: Remove wrong and redundant doxygen tag
|
||||
|
||||
### Misc
|
||||
|
||||
- #33340 Fix benchmark CSV output
|
||||
- #33482 contrib: fix macOS deployment with no translations
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Thanks to everyone who directly contributed to this release:
|
||||
- 0xB10C
|
||||
- amisha
|
||||
- fanquake
|
||||
- glozow
|
||||
- Hennadii Stepanov
|
||||
- MarcoFalke
|
||||
- Martin Zumsande
|
||||
- romanz
|
||||
- Sjors Provoost
|
||||
- theStack
|
||||
- Vasil Dimov
|
||||
- willcl-ark
|
||||
- zaidmstrr
|
||||
|
||||
As well as to everyone that helped with translations on
|
||||
[Transifex](https://explore.transifex.com/bitcoin/bitcoin/).
|
||||
|
||||
371
doc/release-notes/release-notes-28.0.md
Normal file
371
doc/release-notes/release-notes-28.0.md
Normal file
@@ -0,0 +1,371 @@
|
||||
Bitcoin Core version 28.0 is now available from:
|
||||
|
||||
<https://bitcoincore.org/bin/bitcoin-core-28.0/>
|
||||
|
||||
This release includes new features, various bug fixes and performance
|
||||
improvements, as well as updated translations.
|
||||
|
||||
Please report bugs using the issue tracker at GitHub:
|
||||
|
||||
<https://github.com/bitcoin/bitcoin/issues>
|
||||
|
||||
To receive security and update notifications, please subscribe to:
|
||||
|
||||
<https://bitcoincore.org/en/list/announcements/join/>
|
||||
|
||||
How to Upgrade
|
||||
==============
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes in some cases), then run the
|
||||
installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on macOS)
|
||||
or `bitcoind`/`bitcoin-qt` (on Linux).
|
||||
|
||||
Upgrading directly from a version of Bitcoin Core that has reached its EOL is
|
||||
possible, but it might take some time if the data directory needs to be migrated. Old
|
||||
wallet versions of Bitcoin Core are generally supported.
|
||||
|
||||
Running Bitcoin Core binaries on macOS requires self signing.
|
||||
```
|
||||
cd /path/to/bitcoin-28.0/bin
|
||||
xattr -d com.apple.quarantine bitcoin-cli bitcoin-qt bitcoin-tx bitcoin-util bitcoin-wallet bitcoind test_bitcoin
|
||||
codesign -s - bitcoin-cli bitcoin-qt bitcoin-tx bitcoin-util bitcoin-wallet bitcoind test_bitcoin
|
||||
```
|
||||
|
||||
Compatibility
|
||||
==============
|
||||
|
||||
Bitcoin Core is supported and extensively tested on operating systems
|
||||
using the Linux Kernel 3.17+, macOS 11.0+, and Windows 7 and newer. Bitcoin
|
||||
Core should also work on most other UNIX-like systems but is not as
|
||||
frequently tested on them. It is not recommended to use Bitcoin Core on
|
||||
unsupported systems.
|
||||
|
||||
Notable changes
|
||||
===============
|
||||
|
||||
Testnet4/BIP94 support
|
||||
-----
|
||||
|
||||
Support for Testnet4 as specified in [BIP94](https://github.com/bitcoin/bips/blob/master/bip-0094.mediawiki)
|
||||
has been added. The network can be selected with the `-testnet4` option and
|
||||
the section header is also named `[testnet4]`.
|
||||
|
||||
While the intention is to phase out support for Testnet3 in an upcoming
|
||||
version, support for it is still available via the known options in this
|
||||
release. (#29775)
|
||||
|
||||
Windows Data Directory
|
||||
----------------------
|
||||
|
||||
The default data directory on Windows has been moved from `C:\Users\Username\AppData\Roaming\Bitcoin`
|
||||
to `C:\Users\Username\AppData\Local\Bitcoin`. Bitcoin Core will check the existence
|
||||
of the old directory first and continue to use that directory for backwards
|
||||
compatibility if it is present. (#27064)
|
||||
|
||||
JSON-RPC 2.0 Support
|
||||
--------------------
|
||||
|
||||
The JSON-RPC server now recognizes JSON-RPC 2.0 requests and responds with
|
||||
strict adherence to the [specification](https://www.jsonrpc.org/specification).
|
||||
See [JSON-RPC-interface.md](https://github.com/bitcoin/bitcoin/blob/master/doc/JSON-RPC-interface.md#json-rpc-11-vs-20) for details. (#27101)
|
||||
|
||||
JSON-RPC clients may need to be updated to be compatible with the JSON-RPC server.
|
||||
Please open an issue on GitHub if any compatibility issues are found.
|
||||
|
||||
libbitcoinconsensus Removal
|
||||
---------------------------
|
||||
|
||||
The libbitcoin-consensus library was deprecated in 27.0 and is now completely removed. (#29648)
|
||||
|
||||
P2P and Network Changes
|
||||
-----------------------
|
||||
|
||||
- Previously if Bitcoin Core was listening for P2P connections, either using
|
||||
default settings or via `bind=addr:port` it would always also bind to
|
||||
`127.0.0.1:8334` to listen for Tor connections. It was not possible to switch
|
||||
this off, even if the node didn't use Tor. This has been changed and now
|
||||
`bind=addr:port` results in binding on `addr:port` only. The default behavior
|
||||
of binding to `0.0.0.0:8333` and `127.0.0.1:8334` has not been changed.
|
||||
|
||||
If you are using a `bind=...` configuration without `bind=...=onion` and rely
|
||||
on the previous implied behavior to accept incoming Tor connections at
|
||||
`127.0.0.1:8334`, you need to now make this explicit by using
|
||||
`bind=... bind=127.0.0.1:8334=onion`. (#22729)
|
||||
|
||||
- Bitcoin Core will now fail to start up if any of its P2P binds fail, rather
|
||||
than the previous behaviour where it would only abort startup if all P2P
|
||||
binds had failed. (#22729)
|
||||
|
||||
- UNIX domain sockets can now be used for proxy connections. Set `-onion` or `-proxy`
|
||||
to the local socket path with the prefix `unix:` (e.g. `-onion=unix:/home/me/torsocket`).
|
||||
(#27375)
|
||||
|
||||
- UNIX socket paths are now accepted for `-zmqpubrawblock` and `-zmqpubrawtx` with
|
||||
the format `-zmqpubrawtx=unix:/path/to/file` (#27679)
|
||||
|
||||
- Additional "in" and "out" flags have been added to `-whitelist` to control whether
|
||||
permissions apply to inbound connections and/or manual ones (default: inbound only). (#27114)
|
||||
|
||||
- Transactions having a feerate that is too low will be opportunistically paired with
|
||||
their child transactions and submitted as a package, thus enabling the node to download
|
||||
1-parent-1-child packages using the existing transaction relay protocol. Combined with
|
||||
other mempool policies, this change allows limited "package relay" when a parent transaction
|
||||
is below the mempool minimum feerate. Topologically Restricted Until Confirmation (TRUC)
|
||||
parents are additionally allowed to be below the minimum relay feerate (i.e., pay 0 fees).
|
||||
Use the `submitpackage` RPC to submit packages directly to the node. Warning: this P2P
|
||||
feature is limited (unlike the `submitpackage` interface, a child with multiple unconfirmed
|
||||
parents is not supported) and not yet reliable under adversarial conditions. (#28970)
|
||||
|
||||
Mempool Policy Changes
|
||||
----------------------
|
||||
|
||||
- Transactions with version number set to 3 are now treated as standard on all networks (#29496),
|
||||
subject to opt-in Topologically Restricted Until Confirmation (TRUC) transaction policy as
|
||||
described in [BIP 431](https://github.com/bitcoin/bips/blob/master/bip-0431.mediawiki). The
|
||||
policy includes limits on spending unconfirmed outputs (#28948), eviction of a previous descendant
|
||||
if a more incentive-compatible one is submitted (#29306), and a maximum transaction size of 10,000vB
|
||||
(#29873). These restrictions simplify the assessment of incentive compatibility of accepting or
|
||||
replacing TRUC transactions, thus ensuring any replacements are more profitable for the node and
|
||||
making fee-bumping more reliable.
|
||||
|
||||
- Pay To Anchor (P2A) is a new standard witness output type for spending,
|
||||
a newly recognised output template. This allows for key-less anchor
|
||||
outputs, with compact spending conditions for additional efficiencies on
|
||||
top of an equivalent `sh(OP_TRUE)` output, in addition to the txid stability
|
||||
of the spending transaction.
|
||||
N.B. propagation of this output spending on the network will be limited
|
||||
until a sufficient number of nodes on the network adopt this upgrade. (#30352)
|
||||
|
||||
- Limited package RBF is now enabled, where the proposed conflicting package would result in
|
||||
a connected component, aka cluster, of size 2 in the mempool. All clusters being conflicted
|
||||
against must be of size 2 or lower. (#28984)
|
||||
|
||||
- The default value of the `-mempoolfullrbf` configuration option has been changed from 0 to 1,
|
||||
i.e. `mempoolfullrbf=1`. (#30493)
|
||||
|
||||
Updated RPCs
|
||||
------------
|
||||
|
||||
- The `dumptxoutset` RPC now returns the UTXO set dump in a new and
|
||||
improved format. Correspondingly, the `loadtxoutset` RPC now expects
|
||||
this new format in the dumps it tries to load. Dumps with the old
|
||||
format are no longer supported and need to be recreated using the
|
||||
new format to be usable. (#29612)
|
||||
|
||||
- AssumeUTXO mainnet parameters have been added for height 840,000.
|
||||
This means the `loadtxoutset` RPC can now be used on mainnet with
|
||||
the matching UTXO set from that height. (#28553)
|
||||
|
||||
- The `warnings` field in `getblockchaininfo`, `getmininginfo` and
|
||||
`getnetworkinfo` now returns all the active node warnings as an array
|
||||
of strings, instead of a single warning. The current behaviour
|
||||
can be temporarily restored by running Bitcoin Core with the configuration
|
||||
option `-deprecatedrpc=warnings`. (#29845)
|
||||
|
||||
- Previously when using the `sendrawtransaction` RPC and specifying outputs
|
||||
that are already in the UTXO set, an RPC error code of `-27` with the
|
||||
message "Transaction already in block chain" was returned in response.
|
||||
The error message has been changed to "Transaction outputs already in utxo set"
|
||||
to more accurately describe the source of the issue. (#30212)
|
||||
|
||||
- The default mode for the `estimatesmartfee` RPC has been updated from `conservative` to `economical`,
|
||||
which is expected to reduce over-estimation for many users, particularly if Replace-by-Fee is an option.
|
||||
For users that require high confidence in their fee estimates at the cost of potentially over-estimating,
|
||||
the `conservative` mode remains available. (#30275)
|
||||
|
||||
- RPC `scantxoutset` now returns 2 new fields in the "unspents" JSON array: `blockhash` and `confirmations`.
|
||||
See the scantxoutset help for details. (#30515)
|
||||
|
||||
- RPC `submitpackage` now allows 2 new arguments to be passed: `maxfeerate` and `maxburnamount`. See the
|
||||
subtmitpackage help for details. (#28950)
|
||||
|
||||
Changes to wallet-related RPCs can be found in the Wallet section below.
|
||||
|
||||
Updated REST APIs
|
||||
-----------------
|
||||
- Parameter validation for `/rest/getutxos` has been improved by rejecting
|
||||
truncated or overly large txids and malformed outpoint indices via raising
|
||||
an HTTP_BAD_REQUEST "Parse error". These requests were previously handled
|
||||
silently. (#30482, #30444)
|
||||
|
||||
Build System
|
||||
------------
|
||||
|
||||
- GCC 11.1 or later, or Clang 16.0 or later,
|
||||
are now required to compile Bitcoin Core. (#29091, #30263)
|
||||
|
||||
- The minimum required glibc to run Bitcoin Core is now
|
||||
2.31. This means that RHEL 8 and Ubuntu 18.04 (Bionic)
|
||||
are no-longer supported. (#29987)
|
||||
|
||||
- `--enable-lcov-branch-coverage` has been removed, given
|
||||
incompatibilities between lcov version 1 & 2. `LCOV_OPTS`
|
||||
should be used to set any options instead. (#30192)
|
||||
|
||||
Updated Settings
|
||||
----------------
|
||||
|
||||
- When running with `-alertnotify`, an alert can now be raised multiple
|
||||
times instead of just once. Previously, it was only raised when unknown
|
||||
new consensus rules were activated. Its scope has now been increased to
|
||||
include all kernel warnings. Specifically, alerts will now also be raised
|
||||
when an invalid chain with a large amount of work has been detected.
|
||||
Additional warnings may be added in the future. (#30058)
|
||||
|
||||
Changes to GUI or wallet related settings can be found in the GUI or Wallet section below.
|
||||
|
||||
Wallet
|
||||
------
|
||||
|
||||
- The wallet now detects when wallet transactions conflict with the mempool. Mempool-conflicting
|
||||
transactions can be seen in the `"mempoolconflicts"` field of `gettransaction`. The inputs
|
||||
of mempool-conflicted transactions can now be respent without manually abandoning the
|
||||
transactions when the parent transaction is dropped from the mempool, which can cause wallet
|
||||
balances to appear higher. (#27307)
|
||||
|
||||
- A new `max_tx_weight` option has been added to the RPCs `fundrawtransaction`, `walletcreatefundedpsbt`, and `send`.
|
||||
It specifies the maximum transaction weight. If the limit is exceeded during funding, the transaction will not be built.
|
||||
The default value is 4,000,000 WU. (#29523)
|
||||
|
||||
- A new `createwalletdescriptor` RPC allows users to add new automatically generated
|
||||
descriptors to their wallet. This can be used to upgrade wallets created prior to the
|
||||
introduction of a new standard descriptor, such as taproot. (#29130)
|
||||
|
||||
- A new RPC `gethdkeys` lists all of the BIP32 HD keys in use by all of the descriptors in the wallet.
|
||||
These keys can be used in conjunction with `createwalletdescriptor` to create and add single key
|
||||
descriptors to the wallet for a particular key that the wallet already knows. (#29130)
|
||||
|
||||
- The `sendall` RPC can now spend unconfirmed change and will include additional fees as necessary
|
||||
for the resulting transaction to bump the unconfirmed transactions' feerates to the specified feerate. (#28979)
|
||||
|
||||
- In RPC `bumpfee`, if a `fee_rate` is specified, the feerate is no longer restricted
|
||||
to following the wallet's incremental feerate of 5 sat/vb. The feerate must still be
|
||||
at least the sum of the original fee and the mempool's incremental feerate. (#27969)
|
||||
|
||||
GUI Changes
|
||||
-----------
|
||||
|
||||
- The "Migrate Wallet" menu allows users to migrate any legacy wallet in their wallet
|
||||
directory, regardless of the wallets loaded. (gui#824)
|
||||
|
||||
- The "Information" window now displays the maximum mempool size along with the
|
||||
mempool usage. (gui#825)
|
||||
|
||||
Low-level Changes
|
||||
=================
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
||||
- The BIP94 timewarp attack mitigation is now active on the `regtest` network. (#30681)
|
||||
|
||||
- A new `-testdatadir` option has been added to `test_bitcoin` to allow specifying the
|
||||
location of unit test data directories. (#26564)
|
||||
|
||||
Blockstorage
|
||||
------------
|
||||
|
||||
- Block files are now XOR'd by default with a key stored in the blocksdir.
|
||||
Previous releases of Bitcoin Core or previous external software will not be able to read the blocksdir with a non-zero XOR-key.
|
||||
Refer to the `-blocksxor` help for more details. (#28052)
|
||||
|
||||
Chainstate
|
||||
----------
|
||||
|
||||
- The chainstate database flushes that occur when blocks are pruned will no longer
|
||||
empty the database cache. The cache will remain populated longer, which significantly
|
||||
reduces the time for initial block download to complete. (#28280)
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
- The dependency on Boost.Process has been replaced with cpp-subprocess, which is contained in source.
|
||||
Builders will no longer need Boost.Process to build with external signer support. (#28981)
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Thanks to everyone who directly contributed to this release:
|
||||
- 0xb10c
|
||||
- Alfonso Roman Zubeldia
|
||||
- Andrew Toth
|
||||
- AngusP
|
||||
- Anthony Towns
|
||||
- Antoine Poinsot
|
||||
- Anton A
|
||||
- Ava Chow
|
||||
- Ayush Singh
|
||||
- Ben Westgate
|
||||
- Brandon Odiwuor
|
||||
- brunoerg
|
||||
- bstin
|
||||
- Charlie
|
||||
- Christopher Bergqvist
|
||||
- Cory Fields
|
||||
- crazeteam
|
||||
- Daniela Brozzoni
|
||||
- David Gumberg
|
||||
- dergoegge
|
||||
- Edil Medeiros
|
||||
- Epic Curious
|
||||
- Fabian Jahr
|
||||
- fanquake
|
||||
- furszy
|
||||
- glozow
|
||||
- Greg Sanders
|
||||
- hanmz
|
||||
- Hennadii Stepanov
|
||||
- Hernan Marino
|
||||
- Hodlinator
|
||||
- ishaanam
|
||||
- ismaelsadeeq
|
||||
- Jadi
|
||||
- Jon Atack
|
||||
- josibake
|
||||
- jrakibi
|
||||
- kevkevin
|
||||
- kevkevinpal
|
||||
- Konstantin Akimov
|
||||
- laanwj
|
||||
- Larry Ruane
|
||||
- Lőrinc
|
||||
- Luis Schwab
|
||||
- Luke Dashjr
|
||||
- MarcoFalke
|
||||
- marcofleon
|
||||
- Marnix
|
||||
- Martin Saposnic
|
||||
- Martin Zumsande
|
||||
- Matt Corallo
|
||||
- Matthew Zipkin
|
||||
- Matt Whitlock
|
||||
- Max Edwards
|
||||
- Michael Dietz
|
||||
- Murch
|
||||
- nanlour
|
||||
- pablomartin4btc
|
||||
- Peter Todd
|
||||
- Pieter Wuille
|
||||
- @RandyMcMillan
|
||||
- RoboSchmied
|
||||
- Roman Zeyde
|
||||
- Ryan Ofsky
|
||||
- Sebastian Falbesoner
|
||||
- Sergi Delgado Segura
|
||||
- Sjors Provoost
|
||||
- spicyzboss
|
||||
- StevenMia
|
||||
- stickies-v
|
||||
- stratospher
|
||||
- Suhas Daftuar
|
||||
- sunerok
|
||||
- tdb3
|
||||
- TheCharlatan
|
||||
- umiumi
|
||||
- Vasil Dimov
|
||||
- virtu
|
||||
- willcl-ark
|
||||
|
||||
As well as to everyone that helped with translations on
|
||||
[Transifex](https://www.transifex.com/bitcoin/bitcoin/).
|
||||
@@ -55,10 +55,10 @@ 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://www.transifex.com/bitcoin/bitcoin/content/) named after the major version with the slug `qt-translation-<RRR>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-<RRR>x`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/bitcoin_en.xlf` 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://www.transifex.com/bitcoin/communication/) as a template.
|
||||
- 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.)
|
||||
|
||||
#### After branch-off (on the major release branch)
|
||||
@@ -164,8 +164,8 @@ Then open a Pull Request to the [guix.sigs repository](https://github.com/bitcoi
|
||||
|
||||
In the `guix-build-${VERSION}/output/x86_64-apple-darwin` and `guix-build-${VERSION}/output/arm64-apple-darwin` directories:
|
||||
|
||||
tar xf bitcoin-osx-unsigned.tar.gz
|
||||
./detached-sig-create.sh /path/to/codesign.p12
|
||||
tar xf bitcoin-${VERSION}-${ARCH}-apple-darwin-codesigning.tar.gz
|
||||
./detached-sig-create.sh /path/to/codesign.p12 /path/to/AuthKey_foo.p8 uuid
|
||||
Enter the keychain password and authorize the signature
|
||||
signature-osx.tar.gz will be created
|
||||
|
||||
@@ -173,8 +173,8 @@ In the `guix-build-${VERSION}/output/x86_64-apple-darwin` and `guix-build-${VERS
|
||||
|
||||
In the `guix-build-${VERSION}/output/x86_64-w64-mingw32` directory:
|
||||
|
||||
tar xf bitcoin-win-unsigned.tar.gz
|
||||
./detached-sig-create.sh -key /path/to/codesign.key
|
||||
tar xf bitcoin-${VERSION}-win64-codesigning.tar.gz
|
||||
./detached-sig-create.sh /path/to/codesign.key
|
||||
Enter the passphrase for the key when prompted
|
||||
signature-win.tar.gz will be created
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ git commit
|
||||
### Creating a Transifex account
|
||||
Visit the [Transifex Signup](https://www.transifex.com/signup/) page to create an account. Take note of your username and password, as they will be required to configure the command-line tool.
|
||||
|
||||
You can find the Bitcoin translation project at [https://www.transifex.com/bitcoin/bitcoin/](https://www.transifex.com/bitcoin/bitcoin/).
|
||||
You can find the Bitcoin translation project at [https://explore.transifex.com/bitcoin/bitcoin/](https://explore.transifex.com/bitcoin/bitcoin/).
|
||||
|
||||
### Installing the Transifex client command-line tool
|
||||
The client is used to fetch updated translations. Please check installation instructions and any other details at https://developers.transifex.com/docs/cli.
|
||||
|
||||
@@ -85,7 +85,7 @@ For instance:
|
||||
$ bitcoind -zmqpubhashtx=tcp://127.0.0.1:28332 \
|
||||
-zmqpubhashtx=tcp://192.168.1.2:28332 \
|
||||
-zmqpubhashblock="tcp://[::1]:28333" \
|
||||
-zmqpubrawtx=ipc:///tmp/bitcoind.tx.raw \
|
||||
-zmqpubrawtx=unix:/tmp/bitcoind.tx.raw \
|
||||
-zmqpubhashtxhwm=10000
|
||||
|
||||
Each PUB notification has a topic and body, where the header
|
||||
|
||||
@@ -290,7 +290,8 @@
|
||||
|
||||
# Listen for connections on <port> (default: 8333, testnet3: 18333,
|
||||
# testnet4: 48333, signet: 38333, regtest: 18444). Not relevant for
|
||||
# I2P (see doc/i2p.md).
|
||||
# I2P (see doc/i2p.md). If set to a value x, the default onion
|
||||
# listening port will be set to x+1.
|
||||
#port=<port>
|
||||
|
||||
# Connect through SOCKS5 proxy, set -noproxy to disable (default:
|
||||
@@ -590,7 +591,7 @@
|
||||
#mempoolfullrbf=1
|
||||
|
||||
# Fees (in BTC/kvB) smaller than this are considered zero fee for
|
||||
# relaying, mining and transaction creation (default: 0.00001)
|
||||
# relaying, mining and transaction creation (default: 0.000001)
|
||||
#minrelaytxfee=<amt>
|
||||
|
||||
# Relay transactions creating non-P2SH multisig outputs (default: 1)
|
||||
@@ -614,7 +615,7 @@
|
||||
#blockmaxweight=<n>
|
||||
|
||||
# Set lowest fee rate (in BTC/kvB) for transactions to be included in
|
||||
# block creation. (default: 0.00001)
|
||||
# block creation. (default: 0.00000001)
|
||||
#blockmintxfee=<amt>
|
||||
|
||||
|
||||
@@ -697,9 +698,12 @@
|
||||
# Options for mainnet
|
||||
[main]
|
||||
|
||||
# Options for testnet
|
||||
# Options for testnet3
|
||||
[test]
|
||||
|
||||
# Options for testnet4
|
||||
[testnet4]
|
||||
|
||||
# Options for signet
|
||||
[signet]
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ void AddrManImpl::Serialize(Stream& s_) const
|
||||
|
||||
int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
|
||||
s << nUBuckets;
|
||||
std::unordered_map<int, int> mapUnkIds;
|
||||
std::unordered_map<nid_type, int> mapUnkIds;
|
||||
int nIds = 0;
|
||||
for (const auto& entry : mapInfo) {
|
||||
mapUnkIds[entry.first] = nIds;
|
||||
@@ -398,7 +398,7 @@ void AddrManImpl::Unserialize(Stream& s_)
|
||||
}
|
||||
}
|
||||
|
||||
AddrInfo* AddrManImpl::Find(const CService& addr, int* pnId)
|
||||
AddrInfo* AddrManImpl::Find(const CService& addr, nid_type* pnId)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
@@ -413,11 +413,11 @@ AddrInfo* AddrManImpl::Find(const CService& addr, int* pnId)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AddrInfo* AddrManImpl::Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId)
|
||||
AddrInfo* AddrManImpl::Create(const CAddress& addr, const CNetAddr& addrSource, nid_type* pnId)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
int nId = nIdCount++;
|
||||
nid_type nId = nIdCount++;
|
||||
mapInfo[nId] = AddrInfo(addr, addrSource);
|
||||
mapAddr[addr] = nId;
|
||||
mapInfo[nId].nRandomPos = vRandom.size();
|
||||
@@ -438,8 +438,8 @@ void AddrManImpl::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) const
|
||||
|
||||
assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size());
|
||||
|
||||
int nId1 = vRandom[nRndPos1];
|
||||
int nId2 = vRandom[nRndPos2];
|
||||
nid_type nId1 = vRandom[nRndPos1];
|
||||
nid_type nId2 = vRandom[nRndPos2];
|
||||
|
||||
const auto it_1{mapInfo.find(nId1)};
|
||||
const auto it_2{mapInfo.find(nId2)};
|
||||
@@ -453,7 +453,7 @@ void AddrManImpl::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) const
|
||||
vRandom[nRndPos2] = nId1;
|
||||
}
|
||||
|
||||
void AddrManImpl::Delete(int nId)
|
||||
void AddrManImpl::Delete(nid_type nId)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
@@ -476,7 +476,7 @@ void AddrManImpl::ClearNew(int nUBucket, int nUBucketPos)
|
||||
|
||||
// if there is an entry in the specified bucket, delete it.
|
||||
if (vvNew[nUBucket][nUBucketPos] != -1) {
|
||||
int nIdDelete = vvNew[nUBucket][nUBucketPos];
|
||||
nid_type nIdDelete = vvNew[nUBucket][nUBucketPos];
|
||||
AddrInfo& infoDelete = mapInfo[nIdDelete];
|
||||
assert(infoDelete.nRefCount > 0);
|
||||
infoDelete.nRefCount--;
|
||||
@@ -488,7 +488,7 @@ void AddrManImpl::ClearNew(int nUBucket, int nUBucketPos)
|
||||
}
|
||||
}
|
||||
|
||||
void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
void AddrManImpl::MakeTried(AddrInfo& info, nid_type nId)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
@@ -515,7 +515,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
// first make space to add it (the existing tried entry there is moved to new, deleting whatever is there).
|
||||
if (vvTried[nKBucket][nKBucketPos] != -1) {
|
||||
// find an item to evict
|
||||
int nIdEvict = vvTried[nKBucket][nKBucketPos];
|
||||
nid_type nIdEvict = vvTried[nKBucket][nKBucketPos];
|
||||
assert(mapInfo.count(nIdEvict) == 1);
|
||||
AddrInfo& infoOld = mapInfo[nIdEvict];
|
||||
|
||||
@@ -554,7 +554,7 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, std::c
|
||||
if (!addr.IsRoutable())
|
||||
return false;
|
||||
|
||||
int nId;
|
||||
nid_type nId;
|
||||
AddrInfo* pinfo = Find(addr, &nId);
|
||||
|
||||
// Do not set a penalty for a source's self-announcement
|
||||
@@ -627,7 +627,7 @@ bool AddrManImpl::Good_(const CService& addr, bool test_before_evict, NodeSecond
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
int nId;
|
||||
nid_type nId;
|
||||
|
||||
m_last_good = time;
|
||||
|
||||
@@ -753,7 +753,8 @@ std::pair<CAddress, NodeSeconds> AddrManImpl::Select_(bool new_only, std::option
|
||||
|
||||
// Iterate over the positions of that bucket, starting at the initial one,
|
||||
// and looping around.
|
||||
int i, position, node_id;
|
||||
int i, position;
|
||||
nid_type node_id;
|
||||
for (i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
|
||||
position = (initial_position + i) % ADDRMAN_BUCKET_SIZE;
|
||||
node_id = GetEntry(search_tried, bucket, position);
|
||||
@@ -786,7 +787,7 @@ std::pair<CAddress, NodeSeconds> AddrManImpl::Select_(bool new_only, std::option
|
||||
}
|
||||
}
|
||||
|
||||
int AddrManImpl::GetEntry(bool use_tried, size_t bucket, size_t position) const
|
||||
nid_type AddrManImpl::GetEntry(bool use_tried, size_t bucket, size_t position) const
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
@@ -849,7 +850,7 @@ std::vector<std::pair<AddrInfo, AddressPosition>> AddrManImpl::GetEntries_(bool
|
||||
std::vector<std::pair<AddrInfo, AddressPosition>> infos;
|
||||
for (int bucket = 0; bucket < bucket_count; ++bucket) {
|
||||
for (int position = 0; position < ADDRMAN_BUCKET_SIZE; ++position) {
|
||||
int id = GetEntry(from_tried, bucket, position);
|
||||
nid_type id = GetEntry(from_tried, bucket, position);
|
||||
if (id >= 0) {
|
||||
AddrInfo info = mapInfo.at(id);
|
||||
AddressPosition location = AddressPosition(
|
||||
@@ -904,8 +905,8 @@ void AddrManImpl::ResolveCollisions_()
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
for (std::set<int>::iterator it = m_tried_collisions.begin(); it != m_tried_collisions.end();) {
|
||||
int id_new = *it;
|
||||
for (std::set<nid_type>::iterator it = m_tried_collisions.begin(); it != m_tried_collisions.end();) {
|
||||
nid_type id_new = *it;
|
||||
|
||||
bool erase_collision = false;
|
||||
|
||||
@@ -923,7 +924,7 @@ void AddrManImpl::ResolveCollisions_()
|
||||
} else if (vvTried[tried_bucket][tried_bucket_pos] != -1) { // The position in the tried bucket is not empty
|
||||
|
||||
// Get the to-be-evicted address that is being tested
|
||||
int id_old = vvTried[tried_bucket][tried_bucket_pos];
|
||||
nid_type id_old = vvTried[tried_bucket][tried_bucket_pos];
|
||||
AddrInfo& info_old = mapInfo[id_old];
|
||||
|
||||
const auto current_time{Now<NodeSeconds>()};
|
||||
@@ -969,11 +970,11 @@ std::pair<CAddress, NodeSeconds> AddrManImpl::SelectTriedCollision_()
|
||||
|
||||
if (m_tried_collisions.size() == 0) return {};
|
||||
|
||||
std::set<int>::iterator it = m_tried_collisions.begin();
|
||||
std::set<nid_type>::iterator it = m_tried_collisions.begin();
|
||||
|
||||
// Selects a random element from m_tried_collisions
|
||||
std::advance(it, insecure_rand.randrange(m_tried_collisions.size()));
|
||||
int id_new = *it;
|
||||
nid_type id_new = *it;
|
||||
|
||||
// If id_new not found in mapInfo remove it from m_tried_collisions
|
||||
if (mapInfo.count(id_new) != 1) {
|
||||
@@ -1058,15 +1059,15 @@ int AddrManImpl::CheckAddrman() const
|
||||
LOG_TIME_MILLIS_WITH_CATEGORY_MSG_ONCE(
|
||||
strprintf("new %i, tried %i, total %u", nNew, nTried, vRandom.size()), BCLog::ADDRMAN);
|
||||
|
||||
std::unordered_set<int> setTried;
|
||||
std::unordered_map<int, int> mapNew;
|
||||
std::unordered_set<nid_type> setTried;
|
||||
std::unordered_map<nid_type, int> mapNew;
|
||||
std::unordered_map<Network, NewTriedCount> local_counts;
|
||||
|
||||
if (vRandom.size() != (size_t)(nTried + nNew))
|
||||
return -7;
|
||||
|
||||
for (const auto& entry : mapInfo) {
|
||||
int n = entry.first;
|
||||
nid_type n = entry.first;
|
||||
const AddrInfo& info = entry.second;
|
||||
if (info.fInTried) {
|
||||
if (!TicksSinceEpoch<std::chrono::seconds>(info.m_last_success)) {
|
||||
|
||||
@@ -32,6 +32,13 @@ static constexpr int ADDRMAN_NEW_BUCKET_COUNT{1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2
|
||||
static constexpr int32_t ADDRMAN_BUCKET_SIZE_LOG2{6};
|
||||
static constexpr int ADDRMAN_BUCKET_SIZE{1 << ADDRMAN_BUCKET_SIZE_LOG2};
|
||||
|
||||
/**
|
||||
* User-defined type for the internally used nIds
|
||||
* This used to be int, making it feasible for attackers to cause an overflow,
|
||||
* see https://bitcoincore.org/en/2024/07/31/disclose-addrman-int-overflow/
|
||||
*/
|
||||
using nid_type = int64_t;
|
||||
|
||||
/**
|
||||
* Extended statistics about a CAddress
|
||||
*/
|
||||
@@ -179,36 +186,36 @@ private:
|
||||
static constexpr uint8_t INCOMPATIBILITY_BASE = 32;
|
||||
|
||||
//! last used nId
|
||||
int nIdCount GUARDED_BY(cs){0};
|
||||
nid_type nIdCount GUARDED_BY(cs){0};
|
||||
|
||||
//! table with information about all nIds
|
||||
std::unordered_map<int, AddrInfo> mapInfo GUARDED_BY(cs);
|
||||
std::unordered_map<nid_type, AddrInfo> mapInfo GUARDED_BY(cs);
|
||||
|
||||
//! find an nId based on its network address and port.
|
||||
std::unordered_map<CService, int, CServiceHash> mapAddr GUARDED_BY(cs);
|
||||
std::unordered_map<CService, nid_type, CServiceHash> mapAddr GUARDED_BY(cs);
|
||||
|
||||
//! randomly-ordered vector of all nIds
|
||||
//! This is mutable because it is unobservable outside the class, so any
|
||||
//! changes to it (even in const methods) are also unobservable.
|
||||
mutable std::vector<int> vRandom GUARDED_BY(cs);
|
||||
mutable std::vector<nid_type> vRandom GUARDED_BY(cs);
|
||||
|
||||
// number of "tried" entries
|
||||
int nTried GUARDED_BY(cs){0};
|
||||
|
||||
//! list of "tried" buckets
|
||||
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);
|
||||
nid_type vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);
|
||||
|
||||
//! number of (unique) "new" entries
|
||||
int nNew GUARDED_BY(cs){0};
|
||||
|
||||
//! list of "new" buckets
|
||||
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);
|
||||
nid_type vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);
|
||||
|
||||
//! last time Good was called (memory only). Initially set to 1 so that "never" is strictly worse.
|
||||
NodeSeconds m_last_good GUARDED_BY(cs){1s};
|
||||
|
||||
//! Holds addrs inserted into tried table that collide with existing entries. Test-before-evict discipline used to resolve these collisions.
|
||||
std::set<int> m_tried_collisions;
|
||||
std::set<nid_type> m_tried_collisions;
|
||||
|
||||
/** Perform consistency checks every m_consistency_check_ratio operations (if non-zero). */
|
||||
const int32_t m_consistency_check_ratio;
|
||||
@@ -225,22 +232,22 @@ private:
|
||||
std::unordered_map<Network, NewTriedCount> m_network_counts GUARDED_BY(cs);
|
||||
|
||||
//! Find an entry.
|
||||
AddrInfo* Find(const CService& addr, int* pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
AddrInfo* Find(const CService& addr, nid_type* pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
//! Create a new entry and add it to the internal data structures mapInfo, mapAddr and vRandom.
|
||||
AddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
AddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, nid_type* pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
//! Swap two elements in vRandom.
|
||||
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
//! Delete an entry. It must not be in tried, and have refcount 0.
|
||||
void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
void Delete(nid_type nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
//! Clear a position in a "new" table. This is the only place where entries are actually deleted.
|
||||
void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
//! Move an entry from the "new" table(s) to the "tried" table
|
||||
void MakeTried(AddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
void MakeTried(AddrInfo& info, nid_type nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
/** Attempt to add a single address to addrman's new table.
|
||||
* @see AddrMan::Add() for parameters. */
|
||||
@@ -256,9 +263,9 @@ private:
|
||||
|
||||
/** Helper to generalize looking up an addrman entry from either table.
|
||||
*
|
||||
* @return int The nid of the entry. If the addrman position is empty or not found, returns -1.
|
||||
* @return nid_type The nid of the entry. If the addrman position is empty or not found, returns -1.
|
||||
* */
|
||||
int GetEntry(bool use_tried, size_t bucket, size_t position) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
nid_type GetEntry(bool use_tried, size_t bucket, size_t position) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
std::vector<CAddress> GetAddr_(size_t max_addresses, size_t max_pct, std::optional<Network> network, const bool filtered = true) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
|
||||
@@ -41,15 +41,15 @@ std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const ChainType chain)
|
||||
{
|
||||
switch (chain) {
|
||||
case ChainType::MAIN:
|
||||
return std::make_unique<CBaseChainParams>("", 8332, 8334);
|
||||
return std::make_unique<CBaseChainParams>("", 8332);
|
||||
case ChainType::TESTNET:
|
||||
return std::make_unique<CBaseChainParams>("testnet3", 18332, 18334);
|
||||
return std::make_unique<CBaseChainParams>("testnet3", 18332);
|
||||
case ChainType::TESTNET4:
|
||||
return std::make_unique<CBaseChainParams>("testnet4", 48332, 48334);
|
||||
return std::make_unique<CBaseChainParams>("testnet4", 48332);
|
||||
case ChainType::SIGNET:
|
||||
return std::make_unique<CBaseChainParams>("signet", 38332, 38334);
|
||||
return std::make_unique<CBaseChainParams>("signet", 38332);
|
||||
case ChainType::REGTEST:
|
||||
return std::make_unique<CBaseChainParams>("regtest", 18443, 18445);
|
||||
return std::make_unique<CBaseChainParams>("regtest", 18443);
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@@ -22,15 +22,13 @@ class CBaseChainParams
|
||||
public:
|
||||
const std::string& DataDir() const { return strDataDir; }
|
||||
uint16_t RPCPort() const { return m_rpc_port; }
|
||||
uint16_t OnionServiceTargetPort() const { return m_onion_service_target_port; }
|
||||
|
||||
CBaseChainParams() = delete;
|
||||
CBaseChainParams(const std::string& data_dir, uint16_t rpc_port, uint16_t onion_service_target_port)
|
||||
: m_rpc_port(rpc_port), m_onion_service_target_port(onion_service_target_port), strDataDir(data_dir) {}
|
||||
CBaseChainParams(const std::string& data_dir, uint16_t rpc_port)
|
||||
: m_rpc_port(rpc_port), strDataDir(data_dir) {}
|
||||
|
||||
private:
|
||||
const uint16_t m_rpc_port;
|
||||
const uint16_t m_onion_service_target_port;
|
||||
std::string strDataDir;
|
||||
};
|
||||
|
||||
|
||||
@@ -627,7 +627,7 @@ std::string SHA256AutoDetect(sha256_implementation::UseImplementation use_implem
|
||||
Transform = sha256_x86_shani::Transform;
|
||||
TransformD64 = TransformD64Wrapper<sha256_x86_shani::Transform>;
|
||||
TransformD64_2way = sha256d64_x86_shani::Transform_2way;
|
||||
ret = "x86_shani(1way,2way)";
|
||||
ret = "x86_shani(1way;2way)";
|
||||
have_sse4 = false; // Disable SSE4/AVX2;
|
||||
have_avx2 = false;
|
||||
}
|
||||
@@ -641,14 +641,14 @@ std::string SHA256AutoDetect(sha256_implementation::UseImplementation use_implem
|
||||
#endif
|
||||
#if defined(ENABLE_SSE41)
|
||||
TransformD64_4way = sha256d64_sse41::Transform_4way;
|
||||
ret += ",sse41(4way)";
|
||||
ret += ";sse41(4way)";
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ENABLE_AVX2)
|
||||
if (have_avx2 && have_avx && enabled_avx) {
|
||||
TransformD64_8way = sha256d64_avx2::Transform_8way;
|
||||
ret += ",avx2(8way)";
|
||||
ret += ";avx2(8way)";
|
||||
}
|
||||
#endif
|
||||
#endif // defined(HAVE_GETCPUID)
|
||||
@@ -682,7 +682,7 @@ std::string SHA256AutoDetect(sha256_implementation::UseImplementation use_implem
|
||||
Transform = sha256_arm_shani::Transform;
|
||||
TransformD64 = TransformD64Wrapper<sha256_arm_shani::Transform>;
|
||||
TransformD64_2way = sha256d64_arm_shani::Transform_2way;
|
||||
ret = "arm_shani(1way,2way)";
|
||||
ret = "arm_shani(1way;2way)";
|
||||
}
|
||||
#endif
|
||||
#endif // DISABLE_OPTIMIZED_SHA256
|
||||
|
||||
10
src/init.cpp
10
src/init.cpp
@@ -524,7 +524,7 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||
argsman.AddArg("-addnode=<ip>", strprintf("Add a node to connect to and attempt to keep the connection open (see the addnode RPC help for more info). This option can be specified multiple times to add multiple nodes; connections are limited to %u at a time and are counted separately from the -maxconnections limit.", MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet3: 127.0.0.1:%u=onion, testnet4: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), testnet4BaseParams->OnionServiceTargetPort(), signetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet3: 127.0.0.1:%u=onion, testnet4: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultChainParams->GetDefaultPort() + 1, testnetChainParams->GetDefaultPort() + 1, testnet4ChainParams->GetDefaultPort() + 1, signetChainParams->GetDefaultPort() + 1, regtestChainParams->GetDefaultPort() + 1), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-cjdnsreachable", "If set, then this host is configured for CJDNS (connecting to fc00::/8 addresses would lead us to the CJDNS network, see doc/cjdns.md) (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
@@ -551,7 +551,7 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||
argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-txreconciliation", strprintf("Enable transaction reconciliations per BIP 330 (default: %d)", DEFAULT_TXRECONCILIATION_ENABLE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet3: %u, testnet4: %u, signet: %u, regtest: %u). Not relevant for I2P (see doc/i2p.md).", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), testnet4ChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet3: %u, testnet4: %u, signet: %u, regtest: %u). Not relevant for I2P (see doc/i2p.md). If set to a value x, the default onion listening port will be set to x+1.", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), testnet4ChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
#ifdef HAVE_SOCKADDR_UN
|
||||
argsman.AddArg("-proxy=<ip:port|path>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled). May be a local file path prefixed with 'unix:' if the proxy supports it.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_ELISION, OptionsCategory::CONNECTION);
|
||||
#else
|
||||
@@ -1852,6 +1852,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||
const uint16_t default_bind_port =
|
||||
static_cast<uint16_t>(args.GetIntArg("-port", Params().GetDefaultPort()));
|
||||
|
||||
const uint16_t default_bind_port_onion = default_bind_port + 1;
|
||||
|
||||
const auto BadPortWarning = [](const char* prefix, uint16_t port) {
|
||||
return strprintf(_("%s request to listen on port %u. This port is considered \"bad\" and "
|
||||
"thus it is unlikely that any peer will connect to it. See "
|
||||
@@ -1876,7 +1878,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||
const std::string network_type = bind_arg.substr(index + 1);
|
||||
if (network_type == "onion") {
|
||||
const std::string truncated_bind_arg = bind_arg.substr(0, index);
|
||||
bind_addr = Lookup(truncated_bind_arg, BaseParams().OnionServiceTargetPort(), false);
|
||||
bind_addr = Lookup(truncated_bind_arg, default_bind_port_onion, false);
|
||||
if (bind_addr.has_value()) {
|
||||
connOptions.onion_binds.push_back(bind_addr.value());
|
||||
continue;
|
||||
@@ -1912,7 +1914,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||
} else if (!connOptions.vBinds.empty()) {
|
||||
onion_service_target = connOptions.vBinds.front();
|
||||
} else {
|
||||
onion_service_target = DefaultOnionServiceTarget();
|
||||
onion_service_target = DefaultOnionServiceTarget(default_bind_port_onion);
|
||||
connOptions.onion_binds.push_back(onion_service_target);
|
||||
}
|
||||
|
||||
|
||||
@@ -274,6 +274,9 @@ CExtKey DecodeExtKey(const std::string& str)
|
||||
key.Decode(data.data() + prefix.size());
|
||||
}
|
||||
}
|
||||
if (!data.empty()) {
|
||||
memory_cleanse(data.data(), data.size());
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
11
src/net.cpp
11
src/net.cpp
@@ -557,9 +557,9 @@ void CNode::CloseSocketDisconnect()
|
||||
m_i2p_sam_session.reset();
|
||||
}
|
||||
|
||||
void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr, const std::vector<NetWhitelistPermissions>& ranges) const {
|
||||
void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, std::optional<CNetAddr> addr, const std::vector<NetWhitelistPermissions>& ranges) const {
|
||||
for (const auto& subnet : ranges) {
|
||||
if (subnet.m_subnet.Match(addr)) {
|
||||
if (addr.has_value() && subnet.m_subnet.Match(addr.value())) {
|
||||
NetPermissions::AddFlag(flags, subnet.m_flags);
|
||||
}
|
||||
}
|
||||
@@ -1731,7 +1731,11 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
|
||||
{
|
||||
int nInbound = 0;
|
||||
|
||||
AddWhitelistPermissionFlags(permission_flags, addr, vWhitelistedRangeIncoming);
|
||||
const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
|
||||
|
||||
// Tor inbound connections do not reveal the peer's actual network address.
|
||||
// Therefore do not apply address-based whitelist permissions to them.
|
||||
AddWhitelistPermissionFlags(permission_flags, inbound_onion ? std::optional<CNetAddr>{} : addr, vWhitelistedRangeIncoming);
|
||||
|
||||
{
|
||||
LOCK(m_nodes_mutex);
|
||||
@@ -1786,7 +1790,6 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
|
||||
NodeId id = GetNewNodeId();
|
||||
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
|
||||
|
||||
const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
|
||||
// The V2Transport transparently falls back to V1 behavior when an incoming V1 connection is
|
||||
// detected, so use it whenever we signal NODE_P2P_V2.
|
||||
ServiceFlags local_services = GetLocalServices();
|
||||
|
||||
@@ -1345,7 +1345,7 @@ private:
|
||||
|
||||
bool AttemptToEvictConnection();
|
||||
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
|
||||
void AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr, const std::vector<NetWhitelistPermissions>& ranges) const;
|
||||
void AddWhitelistPermissionFlags(NetPermissionFlags& flags, std::optional<CNetAddr> addr, const std::vector<NetWhitelistPermissions>& ranges) const;
|
||||
|
||||
void DeleteNode(CNode* pnode);
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& argsman, const CChainP
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(DEFAULT_MIN_RELAY_TX_FEE == DEFAULT_INCREMENTAL_RELAY_FEE);
|
||||
if (argsman.IsArgSet("-minrelaytxfee")) {
|
||||
if (std::optional<CAmount> min_relay_feerate = ParseMoney(argsman.GetArg("-minrelaytxfee", ""))) {
|
||||
// High fee check is done afterward in CWallet::Create()
|
||||
|
||||
@@ -45,8 +45,6 @@ public:
|
||||
/**
|
||||
* Construct a fee rate from a fee in satoshis and a vsize in vB.
|
||||
*
|
||||
* param@[in] nFeePaid The fee paid by a transaction, in satoshis
|
||||
* param@[in] num_bytes The vsize of a transaction, in vbytes
|
||||
*/
|
||||
CFeeRate(const CAmount& nFeePaid, uint32_t num_bytes);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class CScript;
|
||||
/** Default for -blockmaxweight, which controls the range of block weights the mining code will create **/
|
||||
static constexpr unsigned int DEFAULT_BLOCK_MAX_WEIGHT{MAX_BLOCK_WEIGHT - 4000};
|
||||
/** Default for -blockmintxfee, which sets the minimum feerate for a transaction in blocks created by mining code **/
|
||||
static constexpr unsigned int DEFAULT_BLOCK_MIN_TX_FEE{1000};
|
||||
static constexpr unsigned int DEFAULT_BLOCK_MIN_TX_FEE{1};
|
||||
/** The maximum weight for transactions we're willing to relay/mine */
|
||||
static constexpr int32_t MAX_STANDARD_TX_WEIGHT{400000};
|
||||
/** The minimum non-witness size for transactions we're willing to relay/mine: one larger than 64 */
|
||||
@@ -32,7 +32,7 @@ static constexpr unsigned int MAX_P2SH_SIGOPS{15};
|
||||
/** The maximum number of sigops we're willing to relay/mine in a single tx */
|
||||
static constexpr unsigned int MAX_STANDARD_TX_SIGOPS_COST{MAX_BLOCK_SIGOPS_COST/5};
|
||||
/** Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or replacement **/
|
||||
static constexpr unsigned int DEFAULT_INCREMENTAL_RELAY_FEE{1000};
|
||||
static constexpr unsigned int DEFAULT_INCREMENTAL_RELAY_FEE{100};
|
||||
/** Default for -bytespersigop */
|
||||
static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP{20};
|
||||
/** Default for -permitbaremultisig */
|
||||
@@ -54,7 +54,7 @@ static constexpr unsigned int MAX_STANDARD_SCRIPTSIG_SIZE{1650};
|
||||
* outputs below the new threshold */
|
||||
static constexpr unsigned int DUST_RELAY_TX_FEE{3000};
|
||||
/** Default for -minrelaytxfee, minimum relay fee for transactions */
|
||||
static constexpr unsigned int DEFAULT_MIN_RELAY_TX_FEE{1000};
|
||||
static constexpr unsigned int DEFAULT_MIN_RELAY_TX_FEE{100};
|
||||
/** Default for -limitancestorcount, max number of in-mempool ancestors */
|
||||
static constexpr unsigned int DEFAULT_ANCESTOR_LIMIT{25};
|
||||
/** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2022 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
@@ -370,20 +370,21 @@ static RPCHelpMan generateblock()
|
||||
|
||||
ChainstateManager& chainman = EnsureChainman(node);
|
||||
{
|
||||
std::unique_ptr<CBlockTemplate> blocktemplate{miner.createNewBlock(coinbase_script, {.use_mempool = false})};
|
||||
if (!blocktemplate) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
|
||||
LOCK(chainman.GetMutex());
|
||||
{
|
||||
std::unique_ptr<CBlockTemplate> blocktemplate{miner.createNewBlock(coinbase_script, {.use_mempool = false})};
|
||||
if (!blocktemplate) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
|
||||
}
|
||||
block = blocktemplate->block;
|
||||
}
|
||||
block = blocktemplate->block;
|
||||
}
|
||||
|
||||
CHECK_NONFATAL(block.vtx.size() == 1);
|
||||
CHECK_NONFATAL(block.vtx.size() == 1);
|
||||
|
||||
// Add transactions
|
||||
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
|
||||
RegenerateCommitments(block, chainman);
|
||||
// Add transactions
|
||||
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
|
||||
RegenerateCommitments(block, chainman);
|
||||
|
||||
{
|
||||
BlockValidationState state;
|
||||
if (!miner.testBlockValidity(block, /*check_merkle_root=*/false, state)) {
|
||||
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("testBlockValidity failed: %s", state.ToString()));
|
||||
|
||||
@@ -80,7 +80,7 @@ static RPCHelpMan ping()
|
||||
{
|
||||
return RPCHelpMan{"ping",
|
||||
"\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
|
||||
"Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
|
||||
"Results are provided in getpeerinfo.\n"
|
||||
"Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n",
|
||||
{},
|
||||
RPCResult{RPCResult::Type::NONE, "", ""},
|
||||
@@ -145,9 +145,9 @@ static RPCHelpMan getpeerinfo()
|
||||
{RPCResult::Type::NUM, "bytesrecv", "The total bytes received"},
|
||||
{RPCResult::Type::NUM_TIME, "conntime", "The " + UNIX_EPOCH_TIME + " of the connection"},
|
||||
{RPCResult::Type::NUM, "timeoffset", "The time offset in seconds"},
|
||||
{RPCResult::Type::NUM, "pingtime", /*optional=*/true, "The last ping time in milliseconds (ms), if any"},
|
||||
{RPCResult::Type::NUM, "minping", /*optional=*/true, "The minimum observed ping time in milliseconds (ms), if any"},
|
||||
{RPCResult::Type::NUM, "pingwait", /*optional=*/true, "The duration in milliseconds (ms) of an outstanding ping (if non-zero)"},
|
||||
{RPCResult::Type::NUM, "pingtime", /*optional=*/true, "The last ping time in seconds, if any"},
|
||||
{RPCResult::Type::NUM, "minping", /*optional=*/true, "The minimum observed ping time in seconds, if any"},
|
||||
{RPCResult::Type::NUM, "pingwait", /*optional=*/true, "The duration in seconds of an outstanding ping (if non-zero)"},
|
||||
{RPCResult::Type::NUM, "version", "The peer version, such as 70001"},
|
||||
{RPCResult::Type::STR, "subver", "The string version"},
|
||||
{RPCResult::Type::BOOL, "inbound", "Inbound (true) or Outbound (false)"},
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
// Copyright (c) 2019-2022 The Bitcoin Core developers
|
||||
// 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.
|
||||
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include <script/script.h>
|
||||
#include <script/miniscript.h>
|
||||
#include <serialize.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/miniscript.h>
|
||||
#include <script/script.h>
|
||||
#include <script/solver.h>
|
||||
#include <span.h>
|
||||
#include <util/check.h>
|
||||
#include <util/vector.h>
|
||||
|
||||
namespace miniscript {
|
||||
namespace internal {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019-2022 The Bitcoin Core developers
|
||||
// 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.
|
||||
|
||||
@@ -6,20 +6,24 @@
|
||||
#define BITCOIN_SCRIPT_MINISCRIPT_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <assert.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <consensus/consensus.h>
|
||||
#include <policy/policy.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/interpreter.h>
|
||||
#include <script/parsing.h>
|
||||
#include <script/script.h>
|
||||
#include <serialize.h>
|
||||
#include <span.h>
|
||||
#include <util/check.h>
|
||||
#include <util/strencodings.h>
|
||||
@@ -150,7 +154,8 @@ public:
|
||||
};
|
||||
|
||||
//! Literal operator to construct Type objects.
|
||||
inline consteval Type operator"" _mst(const char* c, size_t l) {
|
||||
inline consteval Type operator""_mst(const char* c, size_t l)
|
||||
{
|
||||
Type typ{Type::Make(0)};
|
||||
|
||||
for (const char *p = c; p < c + l; p++) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <initializer_list>
|
||||
#include <limits>
|
||||
|
||||
@@ -186,7 +186,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
auto IdsReferToSameAddress = [&](int id, int other_id) EXCLUSIVE_LOCKS_REQUIRED(m_impl->cs, other.m_impl->cs) {
|
||||
auto IdsReferToSameAddress = [&](nid_type id, nid_type other_id) EXCLUSIVE_LOCKS_REQUIRED(m_impl->cs, other.m_impl->cs) {
|
||||
if (id == -1 && other_id == -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ using NodeRef = miniscript::NodeRef<CPubKey>;
|
||||
using Node = miniscript::Node<CPubKey>;
|
||||
using Type = miniscript::Type;
|
||||
using MsCtx = miniscript::MiniscriptContext;
|
||||
using miniscript::operator"" _mst;
|
||||
using miniscript::operator""_mst;
|
||||
|
||||
//! Some pre-computed data for more efficient string roundtrips and to simulate challenges.
|
||||
struct TestData {
|
||||
|
||||
@@ -292,7 +292,6 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool)
|
||||
std::set<CTransactionRef> added;
|
||||
auto txr = std::make_shared<TransactionsDelta>(removed, added);
|
||||
node.validation_signals->RegisterSharedValidationInterface(txr);
|
||||
const bool bypass_limits = fuzzed_data_provider.ConsumeBool();
|
||||
|
||||
// Make sure ProcessNewPackage on one transaction works.
|
||||
// The result is not guaranteed to be the same as what is returned by ATMP.
|
||||
@@ -307,7 +306,7 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool)
|
||||
it->second.m_result_type == MempoolAcceptResult::ResultType::INVALID);
|
||||
}
|
||||
|
||||
const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false));
|
||||
const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), /*bypass_limits=*/false, /*test_accept=*/false));
|
||||
const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
|
||||
node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||
node.validation_signals->UnregisterSharedValidationInterface(txr);
|
||||
@@ -389,6 +388,9 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool)
|
||||
|
||||
chainstate.SetMempool(&tx_pool);
|
||||
|
||||
// If we ever bypass limits, do not do TRUC invariants checks
|
||||
bool ever_bypassed_limits{false};
|
||||
|
||||
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)
|
||||
{
|
||||
const auto mut_tx = ConsumeTransaction(fuzzed_data_provider, txids);
|
||||
@@ -407,13 +409,17 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool)
|
||||
tx_pool.PrioritiseTransaction(txid.ToUint256(), delta);
|
||||
}
|
||||
|
||||
const bool bypass_limits{fuzzed_data_provider.ConsumeBool()};
|
||||
ever_bypassed_limits |= bypass_limits;
|
||||
|
||||
const auto tx = MakeTransactionRef(mut_tx);
|
||||
const bool bypass_limits = fuzzed_data_provider.ConsumeBool();
|
||||
const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false));
|
||||
const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
|
||||
if (accepted) {
|
||||
txids.push_back(tx->GetHash());
|
||||
CheckMempoolTRUCInvariants(tx_pool);
|
||||
if (!ever_bypassed_limits) {
|
||||
CheckMempoolTRUCInvariants(tx_pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
Finish(fuzzed_data_provider, tx_pool, chainstate);
|
||||
|
||||
@@ -443,7 +443,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
|
||||
tx1.vout.resize(1);
|
||||
tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL;
|
||||
tx1.vout[0].nValue = 10 * COIN;
|
||||
pool.addUnchecked(entry.Fee(10000LL).FromTx(tx1));
|
||||
pool.addUnchecked(entry.Fee(1000LL).FromTx(tx1));
|
||||
|
||||
CMutableTransaction tx2 = CMutableTransaction();
|
||||
tx2.vin.resize(1);
|
||||
@@ -451,7 +451,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
|
||||
tx2.vout.resize(1);
|
||||
tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL;
|
||||
tx2.vout[0].nValue = 10 * COIN;
|
||||
pool.addUnchecked(entry.Fee(5000LL).FromTx(tx2));
|
||||
pool.addUnchecked(entry.Fee(500LL).FromTx(tx2));
|
||||
|
||||
pool.TrimToSize(pool.DynamicMemoryUsage()); // should do nothing
|
||||
BOOST_CHECK(pool.exists(GenTxid::Txid(tx1.GetHash())));
|
||||
@@ -469,7 +469,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
|
||||
tx3.vout.resize(1);
|
||||
tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL;
|
||||
tx3.vout[0].nValue = 10 * COIN;
|
||||
pool.addUnchecked(entry.Fee(20000LL).FromTx(tx3));
|
||||
pool.addUnchecked(entry.Fee(2000LL).FromTx(tx3));
|
||||
|
||||
pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); // tx3 should pay for tx2 (CPFP)
|
||||
BOOST_CHECK(!pool.exists(GenTxid::Txid(tx1.GetHash())));
|
||||
@@ -481,8 +481,8 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
|
||||
BOOST_CHECK(!pool.exists(GenTxid::Txid(tx2.GetHash())));
|
||||
BOOST_CHECK(!pool.exists(GenTxid::Txid(tx3.GetHash())));
|
||||
|
||||
CFeeRate maxFeeRateRemoved(25000, GetVirtualTransactionSize(CTransaction(tx3)) + GetVirtualTransactionSize(CTransaction(tx2)));
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000);
|
||||
CFeeRate maxFeeRateRemoved(2500, GetVirtualTransactionSize(CTransaction(tx3)) + GetVirtualTransactionSize(CTransaction(tx2)));
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE);
|
||||
|
||||
CMutableTransaction tx4 = CMutableTransaction();
|
||||
tx4.vin.resize(2);
|
||||
@@ -532,10 +532,10 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
|
||||
tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL;
|
||||
tx7.vout[1].nValue = 10 * COIN;
|
||||
|
||||
pool.addUnchecked(entry.Fee(7000LL).FromTx(tx4));
|
||||
pool.addUnchecked(entry.Fee(1000LL).FromTx(tx5));
|
||||
pool.addUnchecked(entry.Fee(1100LL).FromTx(tx6));
|
||||
pool.addUnchecked(entry.Fee(9000LL).FromTx(tx7));
|
||||
pool.addUnchecked(entry.Fee(700LL).FromTx(tx4));
|
||||
pool.addUnchecked(entry.Fee(100LL).FromTx(tx5));
|
||||
pool.addUnchecked(entry.Fee(110LL).FromTx(tx6));
|
||||
pool.addUnchecked(entry.Fee(900LL).FromTx(tx7));
|
||||
|
||||
// we only require this to remove, at max, 2 txn, because it's not clear what we're really optimizing for aside from that
|
||||
pool.TrimToSize(pool.DynamicMemoryUsage() - 1);
|
||||
@@ -544,8 +544,8 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
|
||||
BOOST_CHECK(!pool.exists(GenTxid::Txid(tx7.GetHash())));
|
||||
|
||||
if (!pool.exists(GenTxid::Txid(tx5.GetHash())))
|
||||
pool.addUnchecked(entry.Fee(1000LL).FromTx(tx5));
|
||||
pool.addUnchecked(entry.Fee(9000LL).FromTx(tx7));
|
||||
pool.addUnchecked(entry.Fee(100LL).FromTx(tx5));
|
||||
pool.addUnchecked(entry.Fee(900LL).FromTx(tx7));
|
||||
|
||||
pool.TrimToSize(pool.DynamicMemoryUsage() / 2); // should maximize mempool size by only removing 5/7
|
||||
BOOST_CHECK(pool.exists(GenTxid::Txid(tx4.GetHash())));
|
||||
@@ -553,34 +553,34 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
|
||||
BOOST_CHECK(pool.exists(GenTxid::Txid(tx6.GetHash())));
|
||||
BOOST_CHECK(!pool.exists(GenTxid::Txid(tx7.GetHash())));
|
||||
|
||||
pool.addUnchecked(entry.Fee(1000LL).FromTx(tx5));
|
||||
pool.addUnchecked(entry.Fee(9000LL).FromTx(tx7));
|
||||
pool.addUnchecked(entry.Fee(100LL).FromTx(tx5));
|
||||
pool.addUnchecked(entry.Fee(900LL).FromTx(tx7));
|
||||
|
||||
std::vector<CTransactionRef> vtx;
|
||||
SetMockTime(42);
|
||||
SetMockTime(42 + CTxMemPool::ROLLING_FEE_HALFLIFE);
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000);
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE);
|
||||
// ... we should keep the same min fee until we get a block
|
||||
pool.removeForBlock(vtx, 1);
|
||||
SetMockTime(42 + 2*CTxMemPool::ROLLING_FEE_HALFLIFE);
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + 1000)/2.0));
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE)/2.0));
|
||||
// ... then feerate should drop 1/2 each halflife
|
||||
|
||||
SetMockTime(42 + 2*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2);
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 5 / 2).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + 1000)/4.0));
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 5 / 2).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE)/4.0));
|
||||
// ... with a 1/2 halflife when mempool is < 1/2 its target size
|
||||
|
||||
SetMockTime(42 + 2*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4);
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 9 / 2).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + 1000)/8.0));
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 9 / 2).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE)/8.0));
|
||||
// ... with a 1/4 halflife when mempool is < 1/4 its target size
|
||||
|
||||
SetMockTime(42 + 7*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4);
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), 1000);
|
||||
// ... but feerate should never drop below 1000
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), DEFAULT_INCREMENTAL_RELAY_FEE);
|
||||
// ... but feerate should never drop below DEFAULT_INCREMENTAL_RELAY_FEE
|
||||
|
||||
SetMockTime(42 + 8*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4);
|
||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), 0);
|
||||
// ... unless it has gone all the way to 0 (after getting past 1000/2)
|
||||
// ... unless it has gone all the way to 0 (after getting past DEFAULT_INCREMENTAL_RELAY_FEE/2)
|
||||
}
|
||||
|
||||
inline CTransactionRef make_tx(std::vector<CAmount>&& output_values, std::vector<CTransactionRef>&& inputs=std::vector<CTransactionRef>(), std::vector<uint32_t>&& input_indices=std::vector<uint32_t>())
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <node/miner.h>
|
||||
#include <policy/policy.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/transaction_utils.h>
|
||||
#include <test/util/txmempool.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
@@ -183,6 +184,9 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const
|
||||
tx.vout.resize(2);
|
||||
tx.vout[0].nValue = 5000000000LL - 100000000;
|
||||
tx.vout[1].nValue = 100000000; // 1BTC output
|
||||
// Increase size to avoid rounding errors: when the feerate is extremely small (i.e. 1sat/kvB), evaluating the fee
|
||||
// at a smaller transaction size gives us a rounded value of 0.
|
||||
BulkTransaction(tx, 4000);
|
||||
Txid hashFreeTx2 = tx.GetHash();
|
||||
tx_mempool.addUnchecked(entry.Fee(0).SpendsCoinbase(true).FromTx(tx));
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ public:
|
||||
|
||||
using Fragment = miniscript::Fragment;
|
||||
using NodeRef = miniscript::NodeRef<CPubKey>;
|
||||
using miniscript::operator"" _mst;
|
||||
using miniscript::operator""_mst;
|
||||
using Node = miniscript::Node<CPubKey>;
|
||||
|
||||
/** Compute all challenges (pubkeys, hashes, timelocks) that occur in a given Miniscript. */
|
||||
|
||||
@@ -238,10 +238,10 @@ BOOST_FIXTURE_TEST_CASE(rbf_helper_functions, TestChain100Setup)
|
||||
BOOST_CHECK(PaysForRBF(high_fee, high_fee - 1, 1, CFeeRate(0), unused_txid).has_value());
|
||||
BOOST_CHECK(PaysForRBF(high_fee + 1, high_fee, 1, CFeeRate(0), unused_txid).has_value());
|
||||
// Additional fees must cover the replacement's vsize at incremental relay fee
|
||||
BOOST_CHECK(PaysForRBF(high_fee, high_fee + 1, 2, incremental_relay_feerate, unused_txid).has_value());
|
||||
BOOST_CHECK(PaysForRBF(high_fee, high_fee + 2, 2, incremental_relay_feerate, unused_txid) == std::nullopt);
|
||||
BOOST_CHECK(PaysForRBF(high_fee, high_fee + 2, 2, higher_relay_feerate, unused_txid).has_value());
|
||||
BOOST_CHECK(PaysForRBF(high_fee, high_fee + 4, 2, higher_relay_feerate, unused_txid) == std::nullopt);
|
||||
BOOST_CHECK(PaysForRBF(high_fee, high_fee + 1, 11, incremental_relay_feerate, unused_txid).has_value());
|
||||
BOOST_CHECK(PaysForRBF(high_fee, high_fee + 1, 10, incremental_relay_feerate, unused_txid) == std::nullopt);
|
||||
BOOST_CHECK(PaysForRBF(high_fee, high_fee + 2, 11, higher_relay_feerate, unused_txid).has_value());
|
||||
BOOST_CHECK(PaysForRBF(high_fee, high_fee + 4, 20, higher_relay_feerate, unused_txid) == std::nullopt);
|
||||
BOOST_CHECK(PaysForRBF(low_fee, high_fee, 99999999, incremental_relay_feerate, unused_txid).has_value());
|
||||
BOOST_CHECK(PaysForRBF(low_fee, high_fee + 99999999, 99999999, incremental_relay_feerate, unused_txid) == std::nullopt);
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ BOOST_AUTO_TEST_CASE(run_command)
|
||||
}
|
||||
{
|
||||
// Return non-zero exit code, with error message for stderr
|
||||
const std::string command{"python3 -c 'import sys; print(\"err\", file=sys.stderr); sys.exit(2)'"};
|
||||
const std::string command{"sh -c 'echo err 1>&2 && false'"};
|
||||
const std::string expected{"err"};
|
||||
BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) {
|
||||
const std::string what(e.what());
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <streams.h>
|
||||
#include <test/util/net.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/transaction_utils.h>
|
||||
#include <test/util/txmempool.h>
|
||||
#include <txdb.h>
|
||||
#include <txmempool.h>
|
||||
@@ -582,6 +583,9 @@ void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate)
|
||||
CMutableTransaction mtx = CMutableTransaction();
|
||||
mtx.vin.emplace_back(COutPoint{Txid::FromUint256(g_insecure_rand_ctx.rand256()), 0});
|
||||
mtx.vout.emplace_back(1 * COIN, GetScriptForDestination(WitnessV0ScriptHash(CScript() << OP_TRUE)));
|
||||
// Set a large size so that the fee evaluated at target_feerate (which is usually in sats/kvB) is an integer.
|
||||
// Otherwise, GetMinFee() may end up slightly different from target_feerate.
|
||||
BulkTransaction(mtx, 4000);
|
||||
const auto tx{MakeTransactionRef(mtx)};
|
||||
LockPoints lp;
|
||||
// The new mempool min feerate is equal to the removed package's feerate + incremental feerate.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <coins.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <script/signingprovider.h>
|
||||
#include <test/util/transaction_utils.h>
|
||||
|
||||
@@ -69,3 +70,23 @@ std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keyst
|
||||
|
||||
return dummyTransactions;
|
||||
}
|
||||
|
||||
void BulkTransaction(CMutableTransaction& tx, int32_t target_weight)
|
||||
{
|
||||
tx.vout.emplace_back(0, CScript() << OP_RETURN);
|
||||
auto unpadded_weight{GetTransactionWeight(CTransaction(tx))};
|
||||
assert(target_weight >= unpadded_weight);
|
||||
|
||||
// determine number of needed padding bytes by converting weight difference to vbytes
|
||||
auto dummy_vbytes = (target_weight - unpadded_weight + (WITNESS_SCALE_FACTOR - 1)) / WITNESS_SCALE_FACTOR;
|
||||
// compensate for the increase of the compact-size encoded script length
|
||||
// (note that the length encoding of the unpadded output script needs one byte)
|
||||
dummy_vbytes -= GetSizeOfCompactSize(dummy_vbytes) - 1;
|
||||
|
||||
// pad transaction by repeatedly appending a dummy opcode to the output script
|
||||
tx.vout[0].scriptPubKey.insert(tx.vout[0].scriptPubKey.end(), dummy_vbytes, OP_1);
|
||||
|
||||
// actual weight should be at most 3 higher than target weight
|
||||
assert(GetTransactionWeight(CTransaction(tx)) >= target_weight);
|
||||
assert(GetTransactionWeight(CTransaction(tx)) <= target_weight + 3);
|
||||
}
|
||||
|
||||
@@ -26,4 +26,8 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CSc
|
||||
// the second nValues[2] and nValues[3] outputs paid to a TxoutType::PUBKEYHASH.
|
||||
std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keystoreRet, CCoinsViewCache& coinsRet, const std::array<CAmount,4>& nValues);
|
||||
|
||||
// bulk transaction to reach a certain target weight,
|
||||
// by appending a single output with padded output script
|
||||
void BulkTransaction(CMutableTransaction& tx, int32_t target_weight);
|
||||
|
||||
#endif // BITCOIN_TEST_UTIL_TRANSACTION_UTILS_H
|
||||
|
||||
@@ -711,9 +711,9 @@ void StopTorControl()
|
||||
}
|
||||
}
|
||||
|
||||
CService DefaultOnionServiceTarget()
|
||||
CService DefaultOnionServiceTarget(uint16_t port)
|
||||
{
|
||||
struct in_addr onion_service_target;
|
||||
onion_service_target.s_addr = htonl(INADDR_LOOPBACK);
|
||||
return {onion_service_target, BaseParams().OnionServiceTargetPort()};
|
||||
return {onion_service_target, port};
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ void StartTorControl(CService onion_service_target);
|
||||
void InterruptTorControl();
|
||||
void StopTorControl();
|
||||
|
||||
CService DefaultOnionServiceTarget();
|
||||
CService DefaultOnionServiceTarget(uint16_t port);
|
||||
|
||||
/** Reply from Tor, can be single or multi-line */
|
||||
class TorControlReply
|
||||
|
||||
@@ -366,7 +366,7 @@ public:
|
||||
if (count) {
|
||||
unsigned i = 0;
|
||||
while (count > LIMB_BITS) {
|
||||
ret.m_val[i++] = ~I{0};
|
||||
ret.m_val[i++] = I(~I{0});
|
||||
count -= LIMB_BITS;
|
||||
}
|
||||
ret.m_val[i] = I(~I{0}) >> (LIMB_BITS - count);
|
||||
|
||||
@@ -1039,26 +1039,28 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
||||
// Even though just checking direct mempool parents for inheritance would be sufficient, we
|
||||
// check using the full ancestor set here because it's more convenient to use what we have
|
||||
// already calculated.
|
||||
if (const auto err{SingleTRUCChecks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
|
||||
// Single transaction contexts only.
|
||||
if (args.m_allow_sibling_eviction && err->second != nullptr) {
|
||||
// We should only be considering where replacement is considered valid as well.
|
||||
Assume(args.m_allow_replacement);
|
||||
if (!args.m_bypass_limits) {
|
||||
if (const auto err{SingleTRUCChecks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
|
||||
// Single transaction contexts only.
|
||||
if (args.m_allow_sibling_eviction && err->second != nullptr) {
|
||||
// We should only be considering where replacement is considered valid as well.
|
||||
Assume(args.m_allow_replacement);
|
||||
|
||||
// Potential sibling eviction. Add the sibling to our list of mempool conflicts to be
|
||||
// included in RBF checks.
|
||||
ws.m_conflicts.insert(err->second->GetHash());
|
||||
// Adding the sibling to m_iters_conflicting here means that it doesn't count towards
|
||||
// RBF Carve Out above. This is correct, since removing to-be-replaced transactions from
|
||||
// the descendant count is done separately in SingleTRUCChecks for TRUC transactions.
|
||||
ws.m_iters_conflicting.insert(m_pool.GetIter(err->second->GetHash()).value());
|
||||
ws.m_sibling_eviction = true;
|
||||
// The sibling will be treated as part of the to-be-replaced set in ReplacementChecks.
|
||||
// Note that we are not checking whether it opts in to replaceability via BIP125 or TRUC
|
||||
// (which is normally done in PreChecks). However, the only way a TRUC transaction can
|
||||
// have a non-TRUC and non-BIP125 descendant is due to a reorg.
|
||||
} else {
|
||||
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "TRUC-violation", err->first);
|
||||
// Potential sibling eviction. Add the sibling to our list of mempool conflicts to be
|
||||
// included in RBF checks.
|
||||
ws.m_conflicts.insert(err->second->GetHash());
|
||||
// Adding the sibling to m_iters_conflicting here means that it doesn't count towards
|
||||
// RBF Carve Out above. This is correct, since removing to-be-replaced transactions from
|
||||
// the descendant count is done separately in SingleTRUCChecks for TRUC transactions.
|
||||
ws.m_iters_conflicting.insert(m_pool.GetIter(err->second->GetHash()).value());
|
||||
ws.m_sibling_eviction = true;
|
||||
// The sibling will be treated as part of the to-be-replaced set in ReplacementChecks.
|
||||
// Note that we are not checking whether it opts in to replaceability via BIP125 or TRUC
|
||||
// (which is normally done in PreChecks). However, the only way a TRUC transaction can
|
||||
// have a non-TRUC and non-BIP125 descendant is due to a reorg.
|
||||
} else {
|
||||
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "TRUC-violation", err->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2023,7 +2025,8 @@ void Chainstate::CheckForkWarningConditions()
|
||||
|
||||
// Before we get past initial download, we cannot reliably alert about forks
|
||||
// (we assume we don't get stuck on a fork before finishing our initial sync)
|
||||
if (m_chainman.IsInitialBlockDownload()) {
|
||||
// Also not applicable to the background chainstate
|
||||
if (m_chainman.IsInitialBlockDownload() || this->GetRole() == ChainstateRole::BACKGROUND) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -590,15 +590,15 @@ util::Result<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& utx
|
||||
|
||||
/** Find a subset of the OutputGroups that is at least as large as, but as close as possible to, the
|
||||
* target amount; solve subset sum.
|
||||
* param@[in] groups OutputGroups to choose from, sorted by value in descending order.
|
||||
* param@[in] nTotalLower Total (effective) value of the UTXOs in groups.
|
||||
* param@[in] nTargetValue Subset sum target, not including change.
|
||||
* param@[out] vfBest Boolean vector representing the subset chosen that is closest to
|
||||
* @param[in] groups OutputGroups to choose from, sorted by value in descending order.
|
||||
* @param[in] nTotalLower Total (effective) value of the UTXOs in groups.
|
||||
* @param[in] nTargetValue Subset sum target, not including change.
|
||||
* @param[out] vfBest Boolean vector representing the subset chosen that is closest to
|
||||
* nTargetValue, with indices corresponding to groups. If the ith
|
||||
* entry is true, that means the ith group in groups was selected.
|
||||
* param@[out] nBest Total amount of subset chosen that is closest to nTargetValue.
|
||||
* paramp[in] max_selection_weight The maximum allowed weight for a selection result to be valid.
|
||||
* param@[in] iterations Maximum number of tries.
|
||||
* @param[out] nBest Total amount of subset chosen that is closest to nTargetValue.
|
||||
* @param[in] max_selection_weight The maximum allowed weight for a selection result to be valid.
|
||||
* @param[in] iterations Maximum number of tries.
|
||||
*/
|
||||
static void ApproximateBestSubset(FastRandomContext& insecure_rand, const std::vector<OutputGroup>& groups,
|
||||
const CAmount& nTotalLower, const CAmount& nTargetValue,
|
||||
|
||||
@@ -123,14 +123,14 @@ FilteredOutputGroups GroupOutputs(const CWallet& wallet,
|
||||
* the solution (according to the waste metric) will be chosen. If a valid input cannot be found from any
|
||||
* single OutputType, fallback to running `ChooseSelectionResult()` over all available coins.
|
||||
*
|
||||
* param@[in] chain The chain interface to get information on unconfirmed UTXOs bump fees
|
||||
* param@[in] nTargetValue The target value
|
||||
* param@[in] groups The grouped outputs mapped by coin eligibility filters
|
||||
* param@[in] coin_selection_params Parameters for the coin selection
|
||||
* param@[in] allow_mixed_output_types Relax restriction that SelectionResults must be of the same OutputType
|
||||
* @param[in] chain The chain interface to get information on bump fees for unconfirmed UTXOs
|
||||
* @param[in] nTargetValue The target value
|
||||
* @param[in] groups The grouped outputs mapped by coin eligibility filters
|
||||
* @param[in] coin_selection_params Parameters for the coin selection
|
||||
* @param[in] allow_mixed_output_types Relax restriction that SelectionResults must be of the same OutputType
|
||||
* returns If successful, a SelectionResult containing the input set
|
||||
* If failed, returns (1) an empty error message if the target was not reached (general "Insufficient funds")
|
||||
* or (2) an specific error message if there was something particularly wrong (e.g. a selection
|
||||
* or (2) a specific error message if there was something particularly wrong (e.g. a selection
|
||||
* result that surpassed the tx max weight size).
|
||||
*/
|
||||
util::Result<SelectionResult> AttemptSelection(interfaces::Chain& chain, const CAmount& nTargetValue, OutputGroupTypeMap& groups,
|
||||
@@ -141,13 +141,13 @@ util::Result<SelectionResult> AttemptSelection(interfaces::Chain& chain, const C
|
||||
* Multiple coin selection algorithms will be run and the input set that produces the least waste
|
||||
* (according to the waste metric) will be chosen.
|
||||
*
|
||||
* param@[in] chain The chain interface to get information on unconfirmed UTXOs bump fees
|
||||
* param@[in] nTargetValue The target value
|
||||
* param@[in] groups The struct containing the outputs grouped by script and divided by (1) positive only outputs and (2) all outputs (positive + negative).
|
||||
* param@[in] coin_selection_params Parameters for the coin selection
|
||||
* @param[in] chain The chain interface to get information on bump fees for unconfirmed UTXOs
|
||||
* @param[in] nTargetValue The target value
|
||||
* @param[in] groups The struct containing the outputs grouped by script and divided by (1) positive only outputs and (2) all outputs (positive + negative).
|
||||
* @param[in] coin_selection_params Parameters for the coin selection
|
||||
* returns If successful, a SelectionResult containing the input set
|
||||
* If failed, returns (1) an empty error message if the target was not reached (general "Insufficient funds")
|
||||
* or (2) an specific error message if there was something particularly wrong (e.g. a selection
|
||||
* or (2) a specific error message if there was something particularly wrong (e.g. a selection
|
||||
* result that surpassed the tx max weight size).
|
||||
*/
|
||||
util::Result<SelectionResult> ChooseSelectionResult(interfaces::Chain& chain, const CAmount& nTargetValue, Groups& groups, const CoinSelectionParams& coin_selection_params);
|
||||
@@ -181,10 +181,10 @@ util::Result<PreSelectedInputs> FetchSelectedInputs(const CWallet& wallet, const
|
||||
|
||||
/**
|
||||
* Select a set of coins such that nTargetValue is met; never select unconfirmed coins if they are not ours
|
||||
* param@[in] wallet The wallet which provides data necessary to spend the selected coins
|
||||
* param@[in] available_coins The struct of coins, organized by OutputType, available for selection prior to filtering
|
||||
* param@[in] nTargetValue The target value
|
||||
* param@[in] coin_selection_params Parameters for this coin selection such as feerates, whether to avoid partial spends,
|
||||
* @param[in] wallet The wallet which provides data necessary to spend the selected coins
|
||||
* @param[in] available_coins The struct of coins, organized by OutputType, available for selection prior to filtering
|
||||
* @param[in] nTargetValue The target value
|
||||
* @param[in] coin_selection_params Parameters for this coin selection such as feerates, whether to avoid partial spends,
|
||||
* and whether to subtract the fee from the outputs.
|
||||
* returns If successful, a SelectionResult containing the selected coins
|
||||
* If failed, returns (1) an empty error message if the target was not reached (general "Insufficient funds")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2022 The Bitcoin Core developers
|
||||
// Copyright (c) 2015-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.
|
||||
|
||||
@@ -22,7 +22,7 @@ struct NewMempoolTransactionInfo;
|
||||
class CZMQNotificationInterface final : public CValidationInterface
|
||||
{
|
||||
public:
|
||||
virtual ~CZMQNotificationInterface();
|
||||
~CZMQNotificationInterface();
|
||||
|
||||
std::list<const CZMQAbstractNotifier*> GetActiveNotifiers() const;
|
||||
|
||||
|
||||
@@ -148,8 +148,10 @@ class BIP68Test(BitcoinTestFramework):
|
||||
# between height/time locking). Small random chance of making the locks
|
||||
# all pass.
|
||||
for _ in range(400):
|
||||
available_utxos = len(utxos)
|
||||
|
||||
# Randomly choose up to 10 inputs
|
||||
num_inputs = random.randint(1, 10)
|
||||
num_inputs = random.randint(1, min(10, available_utxos))
|
||||
random.shuffle(utxos)
|
||||
|
||||
# Track whether any sequence locks used should fail
|
||||
|
||||
@@ -398,6 +398,7 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||
self.start_node(0)
|
||||
self.connect_nodes(0, 1)
|
||||
self.connect_nodes(0, 2)
|
||||
self.sync_blocks()
|
||||
assert_equal(self.nodes[0].estimatesmartfee(1)["errors"], ["Insufficient data or no feerate found"])
|
||||
|
||||
def broadcast_and_mine(self, broadcaster, miner, feerate, count):
|
||||
|
||||
60
test/functional/feature_port.py
Executable file
60
test/functional/feature_port.py
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2024-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.
|
||||
"""
|
||||
Test the -port option and its interactions with
|
||||
-bind.
|
||||
"""
|
||||
|
||||
from test_framework.test_framework import (
|
||||
BitcoinTestFramework,
|
||||
)
|
||||
from test_framework.util import (
|
||||
p2p_port,
|
||||
)
|
||||
|
||||
|
||||
class PortTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
# Avoid any -bind= on the command line.
|
||||
self.bind_to_localhost_only = False
|
||||
self.num_nodes = 1
|
||||
|
||||
def run_test(self):
|
||||
node = self.nodes[0]
|
||||
node.has_explicit_bind = True
|
||||
port1 = p2p_port(self.num_nodes)
|
||||
port2 = p2p_port(self.num_nodes + 5)
|
||||
|
||||
self.log.info("When starting with -port, bitcoind binds to it and uses port + 1 for an onion bind")
|
||||
with node.assert_debug_log(expected_msgs=[f'Bound to 0.0.0.0:{port1}', f'Bound to 127.0.0.1:{port1 + 1}']):
|
||||
self.restart_node(0, extra_args=["-listen", f"-port={port1}"])
|
||||
|
||||
self.log.info("When specifying -port multiple times, only the last one is taken")
|
||||
with node.assert_debug_log(expected_msgs=[f'Bound to 0.0.0.0:{port2}', f'Bound to 127.0.0.1:{port2 + 1}'], unexpected_msgs=[f'Bound to 0.0.0.0:{port1}']):
|
||||
self.restart_node(0, extra_args=["-listen", f"-port={port1}", f"-port={port2}"])
|
||||
|
||||
self.log.info("When specifying ports with both -port and -bind, the one from -port is ignored")
|
||||
with node.assert_debug_log(expected_msgs=[f'Bound to 0.0.0.0:{port2}'], unexpected_msgs=[f'Bound to 0.0.0.0:{port1}']):
|
||||
self.restart_node(0, extra_args=["-listen", f"-port={port1}", f"-bind=0.0.0.0:{port2}"])
|
||||
|
||||
self.log.info("When -bind specifies no port, the values from -port and -bind are combined")
|
||||
with self.nodes[0].assert_debug_log(expected_msgs=[f'Bound to 0.0.0.0:{port1}']):
|
||||
self.restart_node(0, extra_args=["-listen", f"-port={port1}", "-bind=0.0.0.0"])
|
||||
|
||||
self.log.info("When an onion bind specifies no port, the value from -port, incremented by 1, is taken")
|
||||
with self.nodes[0].assert_debug_log(expected_msgs=[f'Bound to 127.0.0.1:{port1 + 1}']):
|
||||
self.restart_node(0, extra_args=["-listen", f"-port={port1}", "-bind=127.0.0.1=onion"])
|
||||
|
||||
self.log.info("Invalid values for -port raise errors")
|
||||
self.stop_node(0)
|
||||
node.extra_args = ["-listen", "-port=65536"]
|
||||
node.assert_start_raises_init_error(expected_msg="Error: Invalid port specified in -port: '65536'")
|
||||
node.extra_args = ["-listen", "-port=0"]
|
||||
node.assert_start_raises_init_error(expected_msg="Error: Invalid port specified in -port: '0'")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
PortTest(__file__).main()
|
||||
@@ -14,7 +14,10 @@ from test_framework.messages import (
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_greater_than,
|
||||
assert_greater_than_or_equal,
|
||||
assert_raises_rpc_error,
|
||||
get_fee,
|
||||
)
|
||||
from test_framework.wallet import MiniWallet
|
||||
from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE
|
||||
@@ -87,6 +90,9 @@ class ReplaceByFeeTest(BitcoinTestFramework):
|
||||
self.log.info("Running test full replace by fee...")
|
||||
self.test_fullrbf()
|
||||
|
||||
self.log.info("Running test incremental relay feerates...")
|
||||
self.test_incremental_relay_feerates()
|
||||
|
||||
self.log.info("Passed")
|
||||
|
||||
def make_utxo(self, node, amount, *, confirmed=True, scriptPubKey=None):
|
||||
@@ -697,10 +703,42 @@ class ReplaceByFeeTest(BitcoinTestFramework):
|
||||
|
||||
# Higher fee, higher feerate, different txid, but the replacement does not provide a relay
|
||||
# fee conforming to node's `incrementalrelayfee` policy of 1000 sat per KB.
|
||||
assert_equal(self.nodes[0].getmempoolinfo()["incrementalrelayfee"], Decimal("0.00001"))
|
||||
assert_equal(self.nodes[0].getmempoolinfo()["incrementalrelayfee"], Decimal("0.000001"))
|
||||
tx.vout[0].nValue -= 1
|
||||
assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx.serialize().hex())
|
||||
|
||||
def test_incremental_relay_feerates(self):
|
||||
self.log.info("Test that incremental relay fee is applied correctly in RBF for various settings...")
|
||||
node = self.nodes[0]
|
||||
for incremental_setting in (0, 5, 10, 50, 100, 234, 1000, 5000, 21000):
|
||||
incremental_setting_decimal = incremental_setting / Decimal(COIN)
|
||||
self.log.info(f"-> Test -incrementalrelayfee={incremental_setting_decimal:.8f}sat/kvB...")
|
||||
self.restart_node(0, extra_args=[f"-incrementalrelayfee={incremental_setting_decimal:.8f}", "-datacarriersize=5000", "-persistmempool=0"])
|
||||
|
||||
# When incremental relay feerate is higher than min relay feerate, min relay feerate is automatically increased.
|
||||
min_relay_feerate = node.getmempoolinfo()["minrelaytxfee"]
|
||||
assert_greater_than_or_equal(min_relay_feerate, incremental_setting_decimal)
|
||||
|
||||
low_feerate = min_relay_feerate * 2
|
||||
confirmed_utxo = self.wallet.get_utxo(confirmed_only=True)
|
||||
replacee_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee_rate=low_feerate, target_weight=20000)
|
||||
node.sendrawtransaction(replacee_tx['hex'])
|
||||
|
||||
replacement_placeholder_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo)
|
||||
replacement_expected_size = replacement_placeholder_tx['tx'].get_vsize()
|
||||
replacement_required_fee = get_fee(replacement_expected_size, incremental_setting_decimal) + replacee_tx['fee']
|
||||
|
||||
# Should always be required to pay additional fees
|
||||
if incremental_setting > 0:
|
||||
assert_greater_than(replacement_required_fee, replacee_tx['fee'])
|
||||
|
||||
# 1 satoshi shy of the required fee
|
||||
failed_replacement_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee=replacement_required_fee - Decimal("0.00000001"))
|
||||
assert_raises_rpc_error(-26, "insufficient fee", node.sendrawtransaction, failed_replacement_tx['hex'])
|
||||
|
||||
replacement_tx = self.wallet.create_self_transfer(utxo_to_spend=confirmed_utxo, fee=replacement_required_fee)
|
||||
node.sendrawtransaction(replacement_tx['hex'])
|
||||
|
||||
def test_fullrbf(self):
|
||||
|
||||
confirmed_utxo = self.make_utxo(self.nodes[0], int(2 * COIN))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2022 The Bitcoin Core developers
|
||||
# Copyright (c) 2022-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.
|
||||
|
||||
@@ -17,6 +17,7 @@ from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_greater_than,
|
||||
assert_raises_rpc_error,
|
||||
bpf_cflags,
|
||||
)
|
||||
|
||||
coinselection_tracepoints_program = """
|
||||
@@ -166,7 +167,7 @@ class CoinSelectionTracepointTest(BitcoinTestFramework):
|
||||
ctx.enable_probe(probe="coin_selection:normal_create_tx_internal", fn_name="trace_normal_create_tx")
|
||||
ctx.enable_probe(probe="coin_selection:attempting_aps_create_tx", fn_name="trace_attempt_aps")
|
||||
ctx.enable_probe(probe="coin_selection:aps_create_tx_internal", fn_name="trace_aps_create_tx")
|
||||
self.bpf = BPF(text=coinselection_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"])
|
||||
self.bpf = BPF(text=coinselection_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())
|
||||
|
||||
self.log.info("Prepare wallets")
|
||||
self.generate(self.nodes[0], 101)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2022 The Bitcoin Core developers
|
||||
# Copyright (c) 2022-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.
|
||||
|
||||
@@ -19,7 +19,10 @@ from test_framework.blocktools import COINBASE_MATURITY
|
||||
from test_framework.messages import COIN, DEFAULT_MEMPOOL_EXPIRY_HOURS
|
||||
from test_framework.p2p import P2PDataStore
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
bpf_cflags,
|
||||
)
|
||||
from test_framework.wallet import MiniWallet
|
||||
|
||||
MEMPOOL_TRACEPOINTS_PROGRAM = """
|
||||
@@ -144,7 +147,7 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
||||
node = self.nodes[0]
|
||||
ctx = USDT(pid=node.process.pid)
|
||||
ctx.enable_probe(probe="mempool:added", fn_name="trace_added")
|
||||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"])
|
||||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())
|
||||
|
||||
def handle_added_event(_, data, __):
|
||||
events.append(bpf["added_events"].event(data))
|
||||
@@ -181,7 +184,7 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
||||
node = self.nodes[0]
|
||||
ctx = USDT(pid=node.process.pid)
|
||||
ctx.enable_probe(probe="mempool:removed", fn_name="trace_removed")
|
||||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"])
|
||||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())
|
||||
|
||||
def handle_removed_event(_, data, __):
|
||||
events.append(bpf["removed_events"].event(data))
|
||||
@@ -227,7 +230,7 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
||||
node = self.nodes[0]
|
||||
ctx = USDT(pid=node.process.pid)
|
||||
ctx.enable_probe(probe="mempool:replaced", fn_name="trace_replaced")
|
||||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"])
|
||||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())
|
||||
|
||||
def handle_replaced_event(_, data, __):
|
||||
events.append(bpf["replaced_events"].event(data))
|
||||
@@ -278,7 +281,7 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
||||
self.log.info("Hooking into mempool:rejected tracepoint...")
|
||||
ctx = USDT(pid=node.process.pid)
|
||||
ctx.enable_probe(probe="mempool:rejected", fn_name="trace_rejected")
|
||||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"])
|
||||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())
|
||||
|
||||
def handle_rejected_event(_, data, __):
|
||||
events.append(bpf["rejected_events"].event(data))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user