Merge bitcoin/bitcoin#35234: [29.x] Backports

d8da418220 doc: update release notes for v29.x (fanquake)
9d62f5d0be ci: use ubuntu-latest instead of ubuntu-24.04 (fanquake)
33dd5e74d8 doc: remove reference to cirrus (fanquake)
1907ee01fe ci: switch runners from cirrus to warpbuild (will)
b631f27246 Disable seek compaction (Andrew Toth)
e5613db113 depends: Unset `SOURCE_DATE_EPOCH` in `gen_id` script (Hennadii Stepanov)
005738e3b8 wallet: use outpoint when estimating input size (Lőrinc)
4e3dd136b8 doc: mention -DWITH_ZMQ=ON in BSD build guides (junbyjun1238)

Pull request description:

  Backports:
  * #34228
  * #35228
  * #35283
  * #35313 (only https://github.com/bitcoin-core/leveldb-subtree/pull/61)
  * #35378
  * #35408

ACKs for top commit:
  andrewtoth:
    ACK d8da418220
  marcofleon:
    ACK d8da418220

Tree-SHA512: 95b127da5d16ca26648c41e1b50d1a82b2d94a9a45efbea788accbf67ea8f46fc04ca3c9fe680cd302985cafbde2ac34873fbaf39634e575da22301e13818227
This commit is contained in:
merge-script 2026-06-03 09:43:29 +01:00
commit d476c286c4
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
14 changed files with 112 additions and 80 deletions

View file

@ -13,7 +13,7 @@ trim_trailing_whitespace = true
[*.{h,cpp,rs,py,sh}] [*.{h,cpp,rs,py,sh}]
indent_size = 4 indent_size = 4
# .cirrus.yml, etc. # ci.yml, etc.
[*.yml] [*.yml]
indent_size = 2 indent_size = 2

View file

@ -1,7 +1,7 @@
name: 'Configure Docker' name: 'Configure Docker'
description: 'Set up Docker build driver and configure build cache args' description: 'Set up Docker build driver and configure build cache args'
inputs: inputs:
use-cirrus: use-warp:
description: 'Use cirrus cache' description: 'Use cirrus cache'
required: true required: true
runs: runs:
@ -35,12 +35,7 @@ runs:
# Docker will check for variables $ACTIONS_CACHE_URL, $ACTIONS_RESULTS_URL and $ACTIONS_RUNTIME_TOKEN # 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 # which are set automatically when running on GitHub infra: https://docs.docker.com/build/cache/backends/gha/#synopsis
# Use cirrus cache host url_args=""
if [[ ${{ inputs.use-cirrus }} == 'true' ]]; then
url_args="url=${CIRRUS_CACHE_HOST},url_v2=${CIRRUS_CACHE_HOST}"
else
url_args=""
fi
# Always optimistically --cachefrom in case a cache blob exists # Always optimistically --cachefrom in case a cache blob exists
args=(--cache-from "type=gha${url_args:+,${url_args}},scope=${CONTAINER_NAME}") args=(--cache-from "type=gha${url_args:+,${url_args}},scope=${CONTAINER_NAME}")

View file

@ -19,29 +19,29 @@ concurrency:
env: 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 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
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_WARP_RUNNERS: 'bitcoin/bitcoin' # Use warp runners for this repo, instead of falling back to the slow GHA runners
REPO_USE_CIRRUS_RUNNERS: 'bitcoin/bitcoin' # Use cirrus runners and cache for this repo, instead of falling back to the slow GHA runners
jobs: jobs:
runners: runners:
name: 'determine runners' name: 'determine runners'
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
use-cirrus-runners: ${{ steps.runners.outputs.use-cirrus-runners }} use-warp-runners: ${{ steps.runners.outputs.use-warp-runners }}
steps: steps:
- id: runners - id: runners
run: | run: |
if [[ "${REPO_USE_CIRRUS_RUNNERS}" == "${{ github.repository }}" ]]; then if [[ "${REPO_USE_WARP_RUNNERS}" == "${{ github.repository }}" ]]; then
echo "use-cirrus-runners=true" >> "$GITHUB_OUTPUT" echo "provider=warp" >> "$GITHUB_OUTPUT"
echo "::notice title=Runner Selection::Using Cirrus Runners" echo "::notice title=Runner Selection::Using Warp Runners"
else else
echo "use-cirrus-runners=false" >> "$GITHUB_OUTPUT" echo "use-warp-runners=false" >> "$GITHUB_OUTPUT"
echo "::notice title=Runner Selection::Using GitHub-hosted runners" echo "::notice title=Runner Selection::Using GitHub-hosted runners"
fi fi
test-each-commit: test-each-commit:
name: 'test each commit' name: 'test each commit'
runs-on: ubuntu-24.04 needs: runners
runs-on: ${{ needs.runners.outputs.provider == 'warp' && 'warp-ubuntu-latest-x64-8x' || 'ubuntu-latest' }}
if: github.event_name == 'pull_request' && github.event.pull_request.commits != 1 if: github.event_name == 'pull_request' && github.event.pull_request.commits != 1
timeout-minutes: 360 # Use maximum time, see https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes. Assuming a worst case time of 1 hour per commit, this leads to a --max-count=6 below. timeout-minutes: 360 # Use maximum time, see https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes. Assuming a worst case time of 1 hour per commit, this leads to a --max-count=6 below.
env: env:
@ -292,7 +292,7 @@ jobs:
ci-matrix: ci-matrix:
name: ${{ matrix.name }} name: ${{ matrix.name }}
needs: runners needs: runners
runs-on: ${{ needs.runners.outputs.use-cirrus-runners == 'true' && matrix.cirrus-runner || matrix.fallback-runner }} runs-on: ${{ needs.runners.outputs.provider == 'warp' && matrix.warp-runner || matrix.fallback-runner }}
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
timeout-minutes: ${{ matrix.timeout-minutes }} timeout-minutes: ${{ matrix.timeout-minutes }}
@ -305,74 +305,74 @@ jobs:
matrix: matrix:
include: include:
- name: '32 bit ARM, unit tests, no functional tests' - name: '32 bit 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 warp-runner: 'ubuntu-24.04-arm' # Warp's Arm runners don't support 32-bit mode currently
fallback-runner: 'ubuntu-24.04-arm' fallback-runner: 'ubuntu-24.04-arm'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_arm.sh' file-env: './ci/test/00_setup_env_arm.sh'
- name: 'win64 Cross' - name: 'win64 Cross'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' warp-runner: 'warp-ubuntu-latest-x64-4x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_win64.sh' file-env: './ci/test/00_setup_env_win64.sh'
- name: 'ASan + LSan + UBSan + integer, no depends, USDT' - 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 warp-runner: 'warp-ubuntu-2404-x64-8x' # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_asan.sh' file-env: './ci/test/00_setup_env_native_asan.sh'
- name: 'macOS-cross, gui, no tests' - name: 'macOS-cross, gui, no tests'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' warp-runner: 'warp-ubuntu-latest-x64-4x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_mac_cross.sh' file-env: './ci/test/00_setup_env_mac_cross.sh'
- name: 'No wallet, libbitcoinkernel' - name: 'No wallet, libbitcoinkernel'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' warp-runner: 'warp-ubuntu-latest-x64-4x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh' file-env: './ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh'
- name: 'i686, multiprocess, DEBUG' - name: 'i686, multiprocess, DEBUG'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_i686_multiprocess.sh' file-env: './ci/test/00_setup_env_i686_multiprocess.sh'
- name: 'fuzzer,address,undefined,integer, no depends' - name: 'fuzzer,address,undefined,integer, no depends'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg' warp-runner: 'warp-ubuntu-latest-x64-16x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 240 timeout-minutes: 240
file-env: './ci/test/00_setup_env_native_fuzz.sh' file-env: './ci/test/00_setup_env_native_fuzz.sh'
- name: 'previous releases, depends DEBUG' - name: 'previous releases, depends DEBUG'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_previous_releases.sh' file-env: './ci/test/00_setup_env_native_previous_releases.sh'
- name: 'CentOS, depends, gui' - name: 'CentOS, depends, gui'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg' warp-runner: 'warp-ubuntu-latest-x64-16x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_centos.sh' file-env: './ci/test/00_setup_env_native_centos.sh'
- name: 'tidy' - name: 'tidy'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_tidy.sh' file-env: './ci/test/00_setup_env_native_tidy.sh'
- name: 'TSan, depends, no gui' - name: 'TSan, depends, no gui'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_tsan.sh' file-env: './ci/test/00_setup_env_native_tsan.sh'
- name: 'MSan, depends' - name: 'MSan, depends'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg' warp-runner: 'warp-ubuntu-latest-x64-16x'
fallback-runner: 'ubuntu-24.04' fallback-runner: 'ubuntu-latest'
timeout-minutes: 120 timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_msan.sh' file-env: './ci/test/00_setup_env_native_msan.sh'
@ -389,7 +389,7 @@ jobs:
- name: Configure Docker - name: Configure Docker
uses: ./.github/actions/configure-docker uses: ./.github/actions/configure-docker
with: with:
use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }} use-warp: ${{ needs.runners.outputs.use-warp-runners }}
- name: Enable bpfcc script - name: Enable bpfcc script
if: ${{ env.CONTAINER_NAME == 'ci_native_asan' }} if: ${{ env.CONTAINER_NAME == 'ci_native_asan' }}
@ -411,7 +411,7 @@ jobs:
lint: lint:
name: 'lint' name: 'lint'
needs: runners needs: runners
runs-on: ${{ needs.runners.outputs.use-cirrus-runners == 'true' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-xs' || 'ubuntu-24.04' }} runs-on: ${{ needs.runners.outputs.provider == 'warp' && 'warp-ubuntu-latest-x64-2x' || 'ubuntu-latest' }}
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
timeout-minutes: 20 timeout-minutes: 20
env: env:
@ -426,7 +426,7 @@ jobs:
- name: Configure Docker - name: Configure Docker
uses: ./.github/actions/configure-docker uses: ./.github/actions/configure-docker
with: with:
use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }} use-warp: ${{ needs.runners.outputs.use-warp-runners }}
- name: CI script - name: CI script
run: | run: |

View file

@ -61,13 +61,11 @@ trigger cache-invalidation and rebuilds as necessary.
To configure the primary repository, follow these steps: To configure the primary repository, follow these steps:
1. Register with [Cirrus Runners](https://cirrus-runners.app/) and purchase runners. 1. Register with [WarpBuild](https://www.warpbuild.com/) and purchase runners.
2. Install the Cirrus Runners GitHub app against the GitHub organization. 2. Install the WarpBuild GitHub app against the GitHub organization.
3. Enable organisation-level runners to be used in public repositories: 3. Enable organisation-level runners to be used in public repositories:
1. `Org settings -> Actions -> Runner Groups -> Default -> Allow public repos` 1. `Org settings -> Actions -> Runner Groups -> Default -> Allow public repos`
4. Permit the following actions to run: 4. Permit the following actions to run:
1. cirruslabs/cache/restore@\*
1. cirruslabs/cache/save@\*
1. docker/setup-buildx-action@\* 1. docker/setup-buildx-action@\*
1. actions/github-script@\* 1. actions/github-script@\*
@ -76,5 +74,5 @@ To configure the primary repository, follow these steps:
When used in a fork the CI will run on GitHub's free hosted runners by default. 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). 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 It is also possible to use your own WarpBuild Runners in your own fork with an appropriate patch to the `REPO_USE_WARP_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*. NB that WarpBuild Runners only work at an organisation level, therefore in order to use your own WarpBuild Runners, *the fork must be within your own organisation*.

View file

@ -28,6 +28,10 @@
# Redirect stderr to stdout # Redirect stderr to stdout
exec 2>&1 exec 2>&1
# Unset SOURCE_DATE_EPOCH to prevent it from leaking into tool
# outputs and to maximize reuse of the built package cache.
unset SOURCE_DATE_EPOCH
echo "BEGIN ALL" echo "BEGIN ALL"
# Include any ID salts supplied via command line # Include any ID salts supplied via command line

View file

@ -86,7 +86,7 @@ Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF`
#### Notifications #### Notifications
###### ZeroMQ ###### ZeroMQ
Bitcoin Core can provide notifications via ZeroMQ. If the package is installed, support will be compiled in. Bitcoin Core can provide notifications via ZeroMQ. To compile ZMQ support, install the following dependency and pass `-DWITH_ZMQ=ON` when configuring.
```bash ```bash
pkg install libzmq4 pkg install libzmq4
``` ```

View file

@ -86,7 +86,7 @@ Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF`
#### Notifications #### Notifications
###### ZeroMQ ###### ZeroMQ
Bitcoin Core can provide notifications via ZeroMQ. If the package is installed, support will be compiled in. Bitcoin Core can provide notifications via ZeroMQ. To compile ZMQ support, install the following dependency and pass `-DWITH_ZMQ=ON` when configuring.
```bash ```bash
pkgin zeromq pkgin zeromq
``` ```

View file

@ -80,7 +80,7 @@ Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF`
#### Notifications #### Notifications
###### ZeroMQ ###### ZeroMQ
Bitcoin Core can provide notifications via ZeroMQ. If the package is installed, support will be compiled in. Bitcoin Core can provide notifications via ZeroMQ. To compile ZMQ support, install the following dependency and pass `-DWITH_ZMQ=ON` when configuring.
```bash ```bash
pkg_add zeromq pkg_add zeromq
``` ```

View file

@ -37,12 +37,25 @@ unsupported systems.
Notable changes Notable changes
=============== ===============
### Validation
- #35209 validation: correct lifetime of precomputed tx data
### Leveldb
- #61(bitcoin-core/leveldb): Disable seek compaction
### Net ### Net
- #34093 netif: fix compilation warning in QueryDefaultGatewayImpl() - #34093 netif: fix compilation warning in QueryDefaultGatewayImpl()
### Wallet
- #35228 wallet: use outpoint when estimating input size
### Build ### Build
- #34228 depends: Unset SOURCE_DATE_EPOCH in gen_id script
- #34848 cmake: Migrate away from deprecated SQLite3 target - #34848 cmake: Migrate away from deprecated SQLite3 target
### Doc ### Doc
@ -50,10 +63,13 @@ Notable changes
- #34510 doc: fix broken bpftrace installation link - #34510 doc: fix broken bpftrace installation link
- #34561 wallet: rpc: manpage: fix example missing `fee_rate` argument - #34561 wallet: rpc: manpage: fix example missing `fee_rate` argument
- #34671 doc: Update Guix install for Debian/Ubuntu - #34671 doc: Update Guix install for Debian/Ubuntu
- #35283 doc: mention -DWITH_ZMQ=ON in BSD build guides
### CI ### CI
- #35202 ci: restore sockets in i686, no IPC job - #35202 ci: restore sockets in i686, no IPC job
- #35378 ci: switch runners from cirrus to warpbuild
- #35408 ci: 35378 followups
### Misc ### Misc
@ -64,14 +80,19 @@ Credits
Thanks to everyone who directly contributed to this release: Thanks to everyone who directly contributed to this release:
- andrewtoth
- Cory Fields - Cory Fields
- Daniel Pfeifer - Daniel Pfeifer
- darosior
- fanquake
- Hennadii Stepanov - Hennadii Stepanov
- jayvaliya - jayvaliya
- junbyjun1238
- Lőrinc - Lőrinc
- MarcoFalke - MarcoFalke
- SomberNight - SomberNight
- ToRyVand - ToRyVand
- willcl-ark
As well as to everyone that helped with translations on As well as to everyone that helped with translations on
[Transifex](https://explore.transifex.com/bitcoin/bitcoin/). [Transifex](https://explore.transifex.com/bitcoin/bitcoin/).

View file

@ -54,8 +54,8 @@ static const int kValueSize = 200 * 1024;
static const int kTotalSize = 100 * 1024 * 1024; static const int kTotalSize = 100 * 1024 * 1024;
static const int kCount = kTotalSize / kValueSize; static const int kCount = kTotalSize / kValueSize;
// Read through the first n keys repeatedly and check that they get // Read through the first n keys repeatedly and check that reads do NOT
// compacted (verified by checking the size of the key space). // trigger compaction (seek compaction is disabled in this fork).
void AutoCompactTest::DoReads(int n) { void AutoCompactTest::DoReads(int n) {
std::string value(kValueSize, 'x'); std::string value(kValueSize, 'x');
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
@ -76,25 +76,23 @@ void AutoCompactTest::DoReads(int n) {
const int64_t initial_size = Size(Key(0), Key(n)); const int64_t initial_size = Size(Key(0), Key(n));
const int64_t initial_other_size = Size(Key(n), Key(kCount)); const int64_t initial_other_size = Size(Key(n), Key(kCount));
// Read until size drops significantly. // Read repeatedly. The size of the read range must NOT shrink: with
// seek compaction disabled, reads never schedule a compaction.
std::string limit_key = Key(n); std::string limit_key = Key(n);
for (int read = 0; true; read++) { for (int read = 0; read < 100; read++) {
ASSERT_LT(read, 100) << "Taking too long to compact";
Iterator* iter = db_->NewIterator(ReadOptions()); Iterator* iter = db_->NewIterator(ReadOptions());
for (iter->SeekToFirst(); for (iter->SeekToFirst();
iter->Valid() && iter->key().ToString() < limit_key; iter->Next()) { iter->Valid() && iter->key().ToString() < limit_key; iter->Next()) {
// Drop data // Drop data
} }
delete iter; delete iter;
// Wait a little bit to allow any triggered compactions to complete.
Env::Default()->SleepForMicroseconds(1000000);
uint64_t size = Size(Key(0), Key(n)); uint64_t size = Size(Key(0), Key(n));
fprintf(stderr, "iter %3d => %7.3f MB [other %7.3f MB]\n", read + 1, fprintf(stderr, "iter %3d => %7.3f MB [other %7.3f MB]\n", read + 1,
size / 1048576.0, Size(Key(n), Key(kCount)) / 1048576.0); size / 1048576.0, Size(Key(n), Key(kCount)) / 1048576.0);
if (size <= initial_size / 10) {
break;
}
} }
// Give any background work a chance to run, even though none should.
Env::Default()->SleepForMicroseconds(1000000);
ASSERT_EQ(Size(Key(0), Key(n)), static_cast<uint64_t>(initial_size));
// Verify that the size of the key space not touched by the reads // Verify that the size of the key space not touched by the reads
// is pretty much unchanged. // is pretty much unchanged.

View file

@ -735,15 +735,14 @@ TEST(DBTest, GetPicksCorrectFile) {
} while (ChangeOptions()); } while (ChangeOptions());
} }
TEST(DBTest, GetEncountersEmptyLevel) { TEST(DBTest, GetDoesNotTriggerSeekCompaction) {
do { do {
// Arrange for the following to happen: // Arrange for the following to happen:
// * sstable A in level 0 // * sstable A in level 0
// * nothing in level 1 // * nothing in level 1
// * sstable B in level 2 // * sstable B in level 2
// Then do enough Get() calls to arrange for an automatic compaction // Seek compaction is disabled in this fork, so repeated reads must
// of sstable A. A bug would cause the compaction to be marked as // not change the level layout. A manual compaction must still work.
// occurring at level 1 (instead of the correct level 0).
// Step 1: First place sstables in levels 0 and 2 // Step 1: First place sstables in levels 0 and 2
int compaction_count = 0; int compaction_count = 0;
@ -761,14 +760,17 @@ TEST(DBTest, GetEncountersEmptyLevel) {
ASSERT_EQ(NumTableFilesAtLevel(1), 0); ASSERT_EQ(NumTableFilesAtLevel(1), 0);
ASSERT_EQ(NumTableFilesAtLevel(2), 1); ASSERT_EQ(NumTableFilesAtLevel(2), 1);
// Step 3: read a bunch of times // Step 3: many read misses must not schedule any compaction.
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
ASSERT_EQ("NOT_FOUND", Get("missing")); ASSERT_EQ("NOT_FOUND", Get("missing"));
} }
// Step 4: Wait for compaction to finish
DelayMilliseconds(1000); DelayMilliseconds(1000);
ASSERT_EQ(NumTableFilesAtLevel(0), 1);
ASSERT_EQ(NumTableFilesAtLevel(1), 0);
ASSERT_EQ(NumTableFilesAtLevel(2), 1);
// Step 4: a manual compaction still moves the L0 file down.
dbfull()->TEST_CompactRange(0, nullptr, nullptr);
ASSERT_EQ(NumTableFilesAtLevel(0), 0); ASSERT_EQ(NumTableFilesAtLevel(0), 0);
} while (ChangeOptions()); } while (ChangeOptions());
} }

View file

@ -400,16 +400,11 @@ Status Version::Get(const ReadOptions& options, const LookupKey& k,
return state.found ? state.s : Status::NotFound(Slice()); return state.found ? state.s : Status::NotFound(Slice());
} }
bool Version::UpdateStats(const GetStats& stats) { bool Version::UpdateStats(const GetStats& /*stats*/) {
FileMetaData* f = stats.seek_file; // Disable automatic compactions triggered by read seek counters.
if (f != nullptr) { // The heuristic was tuned for expensive random seeks and can create
f->allowed_seeks--; // severe write amplification on large random-key databases.
if (f->allowed_seeks <= 0 && file_to_compact_ == nullptr) { // Size and manual compactions still run.
file_to_compact_ = f;
file_to_compact_level_ = stats.seek_file_level;
return true;
}
}
return false; return false;
} }
@ -661,6 +656,8 @@ class VersionSet::Builder {
// same as the compaction of 40KB of data. We are a little // same as the compaction of 40KB of data. We are a little
// conservative and allow approximately one seek for every 16KB // conservative and allow approximately one seek for every 16KB
// of data before triggering a compaction. // of data before triggering a compaction.
//
// Note: seek compactions are disabled. See Version::UpdateStats.
f->allowed_seeks = static_cast<int>((f->file_size / 16384U)); f->allowed_seeks = static_cast<int>((f->file_size / 16384U));
if (f->allowed_seeks < 100) f->allowed_seeks = 100; if (f->allowed_seeks < 100) f->allowed_seeks = 100;

View file

@ -92,7 +92,7 @@ int CalculateMaximumSignedInputSize(const CTxOut& txout, const COutPoint outpoin
if (!provider) return -1; if (!provider) return -1;
if (const auto desc = InferDescriptor(txout.scriptPubKey, *provider)) { if (const auto desc = InferDescriptor(txout.scriptPubKey, *provider)) {
if (const auto weight = MaxInputWeight(*desc, {}, coin_control, true, can_grind_r)) { if (const auto weight = MaxInputWeight(*desc, CTxIn{outpoint}, coin_control, true, can_grind_r)) {
return static_cast<int>(GetVirtualTransactionSize(*weight, 0, 0)); return static_cast<int>(GetVirtualTransactionSize(*weight, 0, 0));
} }
} }

View file

@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <consensus/amount.h> #include <consensus/amount.h>
#include <key.h>
#include <policy/fees.h> #include <policy/fees.h>
#include <script/solver.h> #include <script/solver.h>
#include <validation.h> #include <validation.h>
@ -16,6 +17,22 @@
namespace wallet { namespace wallet {
BOOST_FIXTURE_TEST_SUITE(spend_tests, WalletTestingSetup) BOOST_FIXTURE_TEST_SUITE(spend_tests, WalletTestingSetup)
BOOST_AUTO_TEST_CASE(max_signed_input_size_uses_external_outpoint)
{
const CKey key{GenerateRandomKey()};
FillableSigningProvider provider;
BOOST_REQUIRE(provider.AddKey(key));
const CTxOut txout{COIN, GetScriptForDestination(PKHash{key.GetPubKey()})};
const COutPoint outpoint{Txid{}, 0};
CCoinControl coin_control;
coin_control.Select(outpoint).SetTxOut(txout);
const int low_r{CalculateMaximumSignedInputSize(txout, COutPoint{}, &provider, /*can_grind_r=*/true, &coin_control)};
const int high_r{CalculateMaximumSignedInputSize(txout, outpoint, &provider, /*can_grind_r=*/true, &coin_control)};
BOOST_CHECK_EQUAL(high_r, low_r + 1);
}
BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup)
{ {
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));