diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82351b89..df2e1519 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: cargo build --all-features - name: Run tests with MSRV - run: cargo test --all-features + run: cargo test --all-features -- --test-threads=1 build: name: Build and Test @@ -73,7 +73,7 @@ jobs: run: cargo fmt -- --check - name: Run tests - run: cargo test -vv + run: cargo test -vv -- --test-threads=1 - name: Install Valgrind run: | @@ -118,7 +118,7 @@ jobs: echo "BOOST_LIBRARYDIR=$env:GITHUB_WORKSPACE\vcpkg\installed\x64-windows-static\lib" | Out-File -FilePath $env:GITHUB_ENV -Append - name: Run tests - run: cargo test -vv + run: cargo test -vv -- --test-threads=1 linux-aarch64: name: Build and Test on Linux ARM64 @@ -144,7 +144,7 @@ jobs: sudo apt-get install -y libboost-all-dev - name: Build and test - run: cargo test -vv + run: cargo test -vv -- --test-threads=1 macos-build: name: Build and Test on macOS @@ -169,7 +169,7 @@ jobs: brew install boost - name: Build and test - run: cargo test -vv + run: cargo test -vv -- --test-threads=1 fuzzing: name: Check Fuzzing Setup diff --git a/Cargo.toml b/Cargo.toml index 4f355043..effc4459 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +# Copyright (c) 2023-present The Bitcoin Kernel developers +# Licensed under the MIT License. See LICENSE file in the project root. + [package] name = "bitcoinkernel" version = "0.0.22" diff --git a/LICENSE b/LICENSE index 7d34fad9..81a4b9da 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 TheCharlatan +Copyright (c) 2023-present The Bitcoin Kernel 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 diff --git a/README.md b/README.md index bd388626..665d46ac 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,14 @@ Examples for the usage of the library can be found in the `examples/` directory and the `tests`. For now, the example binary implements a bare-bones silent payments scanner. +## Testing + +Due to the underlying Bitcoin Core logging system using global state, tests must be run sequentially: + +```bash +cargo test -- --test-threads=1 +``` + ## Fuzzing Fuzzing is done with [cargo fuzz](https://github.com/rust-fuzz/cargo-fuzz). @@ -82,3 +90,10 @@ rustup component add llvm-tools-preview cargo install rustfilt ``` +## Copyright + +This project is copyright "The Bitcoin Kernel developers" which includes: +- TheCharlatan (2023-present) - Original author and maintainer +- All contributors to this repository + +For a complete list of contributors, see: `git log --format='%an' | sort -u` diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 8fc0bf81..12b24130 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -1,3 +1,6 @@ +# Copyright (c) 2023-present The Bitcoin Kernel developers +# Licensed under the MIT License. See LICENSE file in the project root. + [package] name = "examples" version = "0.0.1" diff --git a/examples/src/silentpaymentscanner.rs b/examples/src/silentpaymentscanner.rs index 3321432a..5a99243f 100644 --- a/examples/src/silentpaymentscanner.rs +++ b/examples/src/silentpaymentscanner.rs @@ -1,3 +1,6 @@ +// Copyright (c) 2023-present The Bitcoin Kernel developers +// Licensed under the MIT License. See LICENSE file in the project root. + use std::env; use std::fmt; use std::process; @@ -28,7 +31,7 @@ impl Log for MainLog { } } -fn setup_logging() -> Result, KernelError> { +fn setup_logging() -> Result { let mut builder = Builder::from_default_env(); builder.filter(None, LevelFilter::Info).init(); Logger::new(MainLog {}) @@ -37,7 +40,7 @@ fn setup_logging() -> Result, KernelError> { fn create_context() -> Arc { Arc::new( ContextBuilder::new() - .chain_type(ChainType::REGTEST) + .chain_type(ChainType::Regtest) .build() .unwrap(), ) diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index cdc2c192..3f370c3a 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -1,3 +1,6 @@ +# Copyright (c) 2023-present The Bitcoin Kernel developers +# Licensed under the MIT License. See LICENSE file in the project root. + [package] name = "rust-bitcoinkernel-fuzz" version = "0.0.0" diff --git a/fuzz/fuzz_targets/fuzz_target_block.rs b/fuzz/fuzz_targets/fuzz_target_block.rs index 6ce42438..9beb2c91 100644 --- a/fuzz/fuzz_targets/fuzz_target_block.rs +++ b/fuzz/fuzz_targets/fuzz_target_block.rs @@ -1,3 +1,6 @@ +// Copyright (c) 2023-present The Bitcoin Kernel developers +// Licensed under the MIT License. See LICENSE file in the project root. + #![no_main] use bitcoinkernel::Block; diff --git a/fuzz/fuzz_targets/fuzz_target_chainman.rs b/fuzz/fuzz_targets/fuzz_target_chainman.rs index af8d6c0b..474d8c10 100644 --- a/fuzz/fuzz_targets/fuzz_target_chainman.rs +++ b/fuzz/fuzz_targets/fuzz_target_chainman.rs @@ -1,3 +1,6 @@ +// Copyright (c) 2023-present The Bitcoin Kernel developers +// Licensed under the MIT License. See LICENSE file in the project root. + #![no_main] use std::sync::{Arc, Once}; @@ -44,10 +47,10 @@ pub enum FuzzChainType { impl Into for FuzzChainType { fn into(self) -> ChainType { match self { - FuzzChainType::MAINNET => ChainType::MAINNET, - FuzzChainType::TESTNET => ChainType::TESTNET, - FuzzChainType::REGTEST => ChainType::REGTEST, - FuzzChainType::SIGNET => ChainType::SIGNET, + FuzzChainType::MAINNET => ChainType::Mainnet, + FuzzChainType::TESTNET => ChainType::Testnet, + FuzzChainType::REGTEST => ChainType::Regtest, + FuzzChainType::SIGNET => ChainType::Signet, } } } diff --git a/fuzz/fuzz_targets/fuzz_target_verify.rs b/fuzz/fuzz_targets/fuzz_target_verify.rs index 8b5a82d8..c3ab5acd 100644 --- a/fuzz/fuzz_targets/fuzz_target_verify.rs +++ b/fuzz/fuzz_targets/fuzz_target_verify.rs @@ -1,3 +1,6 @@ +// Copyright (c) 2023-present The Bitcoin Kernel developers +// Licensed under the MIT License. See LICENSE file in the project root. + #![no_main] use arbitrary::Arbitrary; diff --git a/libbitcoinkernel-sys/Cargo.toml b/libbitcoinkernel-sys/Cargo.toml index f765c659..119015b6 100644 --- a/libbitcoinkernel-sys/Cargo.toml +++ b/libbitcoinkernel-sys/Cargo.toml @@ -1,3 +1,6 @@ +# Copyright (c) 2023-present The Bitcoin Kernel developers +# Licensed under the MIT License. See LICENSE file in the project root. + [package] name = "libbitcoinkernel-sys" version = "0.0.21" diff --git a/libbitcoinkernel-sys/bitcoin/.github/workflows/ci.yml b/libbitcoinkernel-sys/bitcoin/.github/workflows/ci.yml index e2cc635c..fede6150 100644 --- a/libbitcoinkernel-sys/bitcoin/.github/workflows/ci.yml +++ b/libbitcoinkernel-sys/bitcoin/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Determine fetch depth run: echo "FETCH_DEPTH=$((${{ github.event.pull_request.commits }} + 2))" >> "$GITHUB_ENV" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: ${{ env.FETCH_DEPTH }} @@ -116,7 +116,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Clang version run: | @@ -183,7 +183,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure Developer Command Prompt for Microsoft Visual C++ # Using microsoft/setup-msbuild is not enough. @@ -294,7 +294,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set CI directories run: | @@ -348,7 +348,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download built executables uses: actions/download-artifact@v4 @@ -417,7 +417,7 @@ jobs: DANGER_CI_ON_HOST_FOLDERS: 1 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set CI directories run: | diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/security-check.py b/libbitcoinkernel-sys/bitcoin/contrib/guix/security-check.py index 8e8285fe..be2e0cfb 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/security-check.py +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/security-check.py @@ -123,9 +123,6 @@ def check_ELF_CONTROL_FLOW(binary) -> bool: def check_ELF_FORTIFY(binary) -> bool: - # bitcoin-util does not currently contain any fortified functions - if 'Bitcoin Core bitcoin-util utility version ' in binary.strings: - return True # bitcoin wrapper does not currently contain any fortified functions if '--monolithic' in binary.strings: return True diff --git a/libbitcoinkernel-sys/bitcoin/contrib/guix/symbol-check.py b/libbitcoinkernel-sys/bitcoin/contrib/guix/symbol-check.py index 91241eda..b5093f34 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/guix/symbol-check.py +++ b/libbitcoinkernel-sys/bitcoin/contrib/guix/symbol-check.py @@ -32,7 +32,7 @@ # See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html for more info. MAX_VERSIONS = { -'GCC': (4,3,0), +'GCC': (7,0,0), 'GLIBC': { lief.ELF.ARCH.X86_64: (2,31), lief.ELF.ARCH.ARM: (2,31), diff --git a/libbitcoinkernel-sys/bitcoin/contrib/tracing/mempool_monitor.py b/libbitcoinkernel-sys/bitcoin/contrib/tracing/mempool_monitor.py index eb29b374..c5f672fb 100755 --- a/libbitcoinkernel-sys/bitcoin/contrib/tracing/mempool_monitor.py +++ b/libbitcoinkernel-sys/bitcoin/contrib/tracing/mempool_monitor.py @@ -17,9 +17,9 @@ PROGRAM = """ # include -// The longest rejection reason is 118 chars and is generated in case of SCRIPT_ERR_EVAL_FALSE by -// strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())) -#define MAX_REJECT_REASON_LENGTH 118 +// The longest rejection reason is 114 chars and is generated in case of SCRIPT_ERR_EVAL_FALSE by +// strprintf("block-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())) +#define MAX_REJECT_REASON_LENGTH 114 // The longest string returned by RemovalReasonToString() is 'sizelimit' #define MAX_REMOVAL_REASON_LENGTH 9 #define HASH_LENGTH 32 diff --git a/libbitcoinkernel-sys/bitcoin/doc/build-freebsd.md b/libbitcoinkernel-sys/bitcoin/doc/build-freebsd.md index 35ef1408..4b5a1d0f 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/build-freebsd.md +++ b/libbitcoinkernel-sys/bitcoin/doc/build-freebsd.md @@ -13,6 +13,14 @@ Run the following as root to install the base dependencies for building. pkg install boost-libs cmake git libevent pkgconf ``` +SQLite is required for the wallet: + +```bash +pkg install sqlite3 +``` + +To build Bitcoin Core without the wallet, use `-DENABLE_WALLET=OFF`. + See [dependencies.md](dependencies.md) for a complete overview. ### 2. Clone Bitcoin Repo @@ -23,17 +31,6 @@ git clone https://github.com/bitcoin/bitcoin.git ### 3. Install Optional Dependencies -#### Wallet Dependencies -It is not necessary to build wallet functionality to run either `bitcoind` or `bitcoin-qt`. - -###### Descriptor Wallet Support - -`sqlite3` is required to support [descriptor wallets](descriptors.md). -Skip if you don't intend to use descriptor wallets. -```bash -pkg install sqlite3 -``` - #### GUI Dependencies ###### Qt6 @@ -79,7 +76,7 @@ pkg install python3 databases/py-sqlite3 net/py-pyzmq There are many ways to configure Bitcoin Core, here are a few common examples: -##### Descriptor Wallet and GUI: +##### Wallet and GUI: This enables the GUI, assuming `sqlite` and `qt` are installed. ```bash cmake -B build -DBUILD_GUI=ON diff --git a/libbitcoinkernel-sys/bitcoin/doc/build-netbsd.md b/libbitcoinkernel-sys/bitcoin/doc/build-netbsd.md index 79cce2ff..b485bb5a 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/build-netbsd.md +++ b/libbitcoinkernel-sys/bitcoin/doc/build-netbsd.md @@ -31,6 +31,14 @@ cmake -B build ... ``` +SQLite is required for the wallet: + +```bash +pkgin sqlite3 +``` + +To build Bitcoin Core without the wallet, use `-DENABLE_WALLET=OFF`. + See [dependencies.md](dependencies.md) for a complete overview. ### 2. Clone Bitcoin Repo @@ -43,18 +51,6 @@ git clone https://github.com/bitcoin/bitcoin.git ### 3. Install Optional Dependencies -#### Wallet Dependencies - -It is not necessary to build wallet functionality to run bitcoind or the GUI. - -###### Descriptor Wallet Support - -`sqlite3` is required to enable support for [descriptor wallets](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md). - -```bash -pkgin install sqlite3 -``` - #### GUI Dependencies ###### Qt6 diff --git a/libbitcoinkernel-sys/bitcoin/doc/build-openbsd.md b/libbitcoinkernel-sys/bitcoin/doc/build-openbsd.md index f3fae645..d68a118b 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/build-openbsd.md +++ b/libbitcoinkernel-sys/bitcoin/doc/build-openbsd.md @@ -13,6 +13,14 @@ Run the following as root to install the base dependencies for building. pkg_add git cmake boost libevent ``` +SQLite is required for the wallet: + +```bash +pkg_add sqlite3 +``` + +To build Bitcoin Core without the wallet, use `-DENABLE_WALLET=OFF`. + See [dependencies.md](dependencies.md) for a complete overview. ### 2. Clone Bitcoin Repo @@ -23,16 +31,6 @@ git clone https://github.com/bitcoin/bitcoin.git ### 3. Install Optional Dependencies -#### Wallet Dependencies - -It is not necessary to build wallet functionality to run either `bitcoind` or `bitcoin-qt`. -SQLite is required to build the wallet. - - -``` bash -pkg_add sqlite3 -``` - #### GUI Dependencies ###### Qt6 @@ -77,8 +75,8 @@ pkg_add python py3-zmq # Select the newest version of the python package if nec There are many ways to configure Bitcoin Core, here are a few common examples: -##### Descriptor Wallet and GUI: -This enables descriptor wallet support and the GUI, assuming SQLite and Qt 6 are installed. +##### Wallet and GUI: +This enables wallet support and the GUI, assuming SQLite and Qt 6 are installed. ```bash cmake -B build -DBUILD_GUI=ON diff --git a/libbitcoinkernel-sys/bitcoin/doc/build-osx.md b/libbitcoinkernel-sys/bitcoin/doc/build-osx.md index ab4726d9..523946d9 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/build-osx.md +++ b/libbitcoinkernel-sys/bitcoin/doc/build-osx.md @@ -51,6 +51,14 @@ To install, run the following from your terminal: brew install cmake boost pkgconf libevent ``` +#### Wallet Dependencies + +If you do not need wallet functionality, you can use `-DENABLE_WALLET=OFF` in +the `cmake -B` step below. + +SQLite is required, but since macOS ships with a useable `sqlite` package, you don't need to +install anything. + ### 4. Clone Bitcoin repository `git` should already be installed by default on your system. @@ -63,19 +71,6 @@ git clone https://github.com/bitcoin/bitcoin.git ### 5. Install Optional Dependencies -#### Wallet Dependencies - -It is not necessary to build wallet functionality to run `bitcoind` or `bitcoin-qt`. - -###### Descriptor Wallet Support - -`sqlite` is required to support for descriptor wallets. - -macOS ships with a useable `sqlite` package, meaning you don't need to -install anything. - ---- - #### GUI Dependencies ###### Qt diff --git a/libbitcoinkernel-sys/bitcoin/doc/build-unix.md b/libbitcoinkernel-sys/bitcoin/doc/build-unix.md index 760d6a2a..ad577636 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/build-unix.md +++ b/libbitcoinkernel-sys/bitcoin/doc/build-unix.md @@ -54,11 +54,11 @@ Now, you can either build from self-compiled [depends](#dependencies) or install sudo apt-get install libevent-dev libboost-dev -SQLite is required for the descriptor wallet: +SQLite is required for the wallet: sudo apt install libsqlite3-dev -To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode) +To build Bitcoin Core without the wallet, see [*Disable-wallet mode*](#disable-wallet-mode) ZMQ-enabled binaries are compiled with `-DWITH_ZMQ=ON` and require the following dependency: @@ -105,11 +105,11 @@ Now, you can either build from self-compiled [depends](#dependencies) or install sudo dnf install libevent-devel boost-devel -SQLite is required for the descriptor wallet: +SQLite is required for the wallet: sudo dnf install sqlite-devel -To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode) +To build Bitcoin Core without the wallet, see [*Disable-wallet mode*](#disable-wallet-mode) ZMQ-enabled binaries are compiled with `-DWITH_ZMQ=ON` and require the following dependency: @@ -155,11 +155,11 @@ Now, you can either build from self-compiled [depends](#dependencies) or install apk add libevent-dev boost-dev -SQLite is required for the descriptor wallet: +SQLite is required for the wallet: apk add sqlite-dev -To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode) +To build Bitcoin Core without the wallet, see [*Disable-wallet mode*](#disable-wallet-mode) ZMQ dependencies (provides ZMQ API): diff --git a/libbitcoinkernel-sys/bitcoin/doc/files.md b/libbitcoinkernel-sys/bitcoin/doc/files.md index 1e5abdbc..5ef1e492 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/files.md +++ b/libbitcoinkernel-sys/bitcoin/doc/files.md @@ -18,6 +18,8 @@ - [Installed Files](#installed-files) +- [Filesystem recommendations](#filesystem-recommendations) + ## Data directory location The data directory is the default location where the Bitcoin Core files are stored. @@ -160,3 +162,8 @@ This table describes the files installed by Bitcoin Core across different platfo - *Italicized* files are only installed in source builds if relevant CMake options are enabled. They are not included in binary releases. - README and bitcoin.conf files are included in binary releases but not installed in source builds. - On Windows, binaries have a `.exe` suffix (e.g., `bitcoin-cli.exe`). + +## Filesystem recommendations + +When choosing a filesystem for the data directory (`datadir`) or blocks directory (`blocksdir`) on **macOS**,the `exFAT` filesystem should be avoided. +There have been multiple reports of database corruption and data loss when using this filesystem with Bitcoin Core, see [Issue #31454](https://github.com/bitcoin/bitcoin/issues/31454) for more details. diff --git a/libbitcoinkernel-sys/bitcoin/doc/policy/mempool-replacements.md b/libbitcoinkernel-sys/bitcoin/doc/policy/mempool-replacements.md index eb370672..73682e2f 100644 --- a/libbitcoinkernel-sys/bitcoin/doc/policy/mempool-replacements.md +++ b/libbitcoinkernel-sys/bitcoin/doc/policy/mempool-replacements.md @@ -32,8 +32,8 @@ other consensus and policy rules, each of the following conditions are met: 4. The additional fees (difference between absolute fee paid by the replacement transaction and the sum paid by the original transactions) pays for the replacement transaction's bandwidth at or above the rate set by the node's incremental relay feerate. For example, if the incremental relay - feerate is 1 satoshi/vB and the replacement transaction is 500 virtual bytes total, then the - replacement pays a fee at least 500 satoshis higher than the sum of the original transactions. + feerate is 0.1 satoshi/vB and the replacement transaction is 500 virtual bytes total, then the + replacement pays a fee at least 50 satoshis higher than the sum of the original transactions. *Rationale*: Try to prevent DoS attacks where an attacker causes the network to repeatedly relay transactions each paying a tiny additional amount in fees, e.g. just 1 satoshi. @@ -77,3 +77,5 @@ This set of rules is similar but distinct from BIP125. * Full replace-by-fee is the default policy as of **v28.0** ([PR #30493](https://github.com/bitcoin/bitcoin/pull/30493)). * Signaling for replace-by-fee is no longer required as of [PR 30592](https://github.com/bitcoin/bitcoin/pull/30592). + +* The incremental relay feerate default is 0.1sat/vB ([PR #33106](https://github.com/bitcoin/bitcoin/pull/33106)). diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-32896.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-32896.md new file mode 100644 index 00000000..a577e81f --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-32896.md @@ -0,0 +1,19 @@ +Updated RPCs +------------ +The following RPCs now contain a `version` parameter that allows +the user to create transactions of any standard version number (1-3): +- `createrawtransaction` +- `createpsbt` +- `send` +- `sendall` +- `walletcreatefundedpsbt` + +Wallet +------ +Support has been added for spending TRUC transactions received by the +wallet, as well as creating TRUC transactions. The wallet ensures that +TRUC policy rules are being met. The wallet will throw an error if the +user is trying to spend TRUC utxos with utxos of other versions. +Additionally, the wallet will treat unconfirmed TRUC sibling +transactions as mempool conflicts. The wallet will also ensure that +transactions spending TRUC utxos meet the required size restrictions. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-33106.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-33106.md new file mode 100644 index 00000000..95750ced --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-33106.md @@ -0,0 +1,17 @@ +Mining and Transaction Relay 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 but more gradually, as a +result of the change to the incremental relay feerate. + +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. diff --git a/libbitcoinkernel-sys/bitcoin/doc/release-notes-33183.md b/libbitcoinkernel-sys/bitcoin/doc/release-notes-33183.md new file mode 100644 index 00000000..fdc3f1fb --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/doc/release-notes-33183.md @@ -0,0 +1,7 @@ +Updated RPCs +------------ + +Transaction Script validation errors used to return the reason for the error prefixed by either +"mandatory-script-verify-flag-failed" if it was a consensus error, or "non-mandatory-script-verify-flag" +(without "-failed") if it was a standardness error. This has been changed to "block-script-verify-flag-failed" +and "mempool-script-verify-flag-failed" for all block and mempool errors respectively. diff --git a/libbitcoinkernel-sys/bitcoin/share/qt/extract_strings_qt.py b/libbitcoinkernel-sys/bitcoin/share/qt/extract_strings_qt.py deleted file mode 100755 index 42971430..00000000 --- a/libbitcoinkernel-sys/bitcoin/share/qt/extract_strings_qt.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2012-2021 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' -Extract _("...") strings for translation and convert to Qt stringdefs so that -they can be picked up by Qt linguist. -''' -from subprocess import Popen, PIPE -import operator -import os -import sys - -OUT_CPP="qt/bitcoinstrings.cpp" -EMPTY=['""'] - -def parse_po(text): - """ - Parse 'po' format produced by xgettext. - Return a list of (msgid,msgstr) tuples. - """ - messages = [] - msgid = [] - msgstr = [] - in_msgid = False - in_msgstr = False - - for line in text.split('\n'): - line = line.rstrip('\r') - if line.startswith('msgid '): - if in_msgstr: - messages.append((msgid, msgstr)) - in_msgstr = False - # message start - in_msgid = True - - msgid = [line[6:]] - elif line.startswith('msgstr '): - in_msgid = False - in_msgstr = True - msgstr = [line[7:]] - elif line.startswith('"'): - if in_msgid: - msgid.append(line) - if in_msgstr: - msgstr.append(line) - - if in_msgstr: - messages.append((msgid, msgstr)) - - return messages - -files = sys.argv[1:] - -# xgettext -n --keyword=_ $FILES -XGETTEXT=os.getenv('XGETTEXT', 'xgettext') -if not XGETTEXT: - print('Cannot extract strings: xgettext utility is not installed or not configured.',file=sys.stderr) - print('Please install package "gettext" and re-run \'cmake -B build\'.',file=sys.stderr) - sys.exit(1) -child = Popen([XGETTEXT,'--output=-','--from-code=utf-8','-n','--keyword=_'] + files, stdout=PIPE) -(out, err) = child.communicate() - -messages = parse_po(out.decode('utf-8')) - -f = open(OUT_CPP, 'w', encoding="utf8") -f.write(""" - -#include - -// Automatically generated by extract_strings_qt.py -#ifdef __GNUC__ -#define UNUSED __attribute__((unused)) -#else -#define UNUSED -#endif -""") -f.write('static const char UNUSED *bitcoin_strings[] = {\n') -f.write('QT_TRANSLATE_NOOP("bitcoin-core", "%s"),\n' % (os.getenv('COPYRIGHT_HOLDERS'),)) -messages.sort(key=operator.itemgetter(0)) -for (msgid, msgstr) in messages: - if msgid != EMPTY: - f.write('QT_TRANSLATE_NOOP("bitcoin-core", %s),\n' % ('\n'.join(msgid))) -f.write('};\n') -f.close() diff --git a/libbitcoinkernel-sys/bitcoin/share/qt/translate.cmake b/libbitcoinkernel-sys/bitcoin/share/qt/translate.cmake new file mode 100644 index 00000000..ed32c6dd --- /dev/null +++ b/libbitcoinkernel-sys/bitcoin/share/qt/translate.cmake @@ -0,0 +1,130 @@ +# Copyright (c) 2025 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +cmake_minimum_required(VERSION 3.22) + +set(input_variables + PROJECT_SOURCE_DIR + COPYRIGHT_HOLDERS + LCONVERT_EXECUTABLE + LUPDATE_EXECUTABLE + XGETTEXT_EXECUTABLE +) + +foreach(var IN LISTS input_variables) + if(NOT DEFINED ${var}) + message(FATAL_ERROR "Variable '${var}' is not defined!") + endif() +endforeach() + +# Extract _("...") strings for translation and convert to Qt stringdefs so that +# they can be picked up by Qt linguist. +function(extract_strings output) + execute_process( + COMMAND ${XGETTEXT_EXECUTABLE} + --output=bitcoinstrings.po + --no-location + --from-code=utf-8 + --keyword=_ + ${ARGN} + COMMAND_ERROR_IS_FATAL ANY + ) + + file(STRINGS "bitcoinstrings.po" text ENCODING "UTF-8") + + set(messages "${COPYRIGHT_HOLDERS}") + foreach(line IN LISTS text) + if(line MATCHES "^msgid \"(.*)\"$") + set(msgid "${CMAKE_MATCH_1}") + elseif(line MATCHES "^\"(.*)\"$") + string(APPEND msgid "${CMAKE_MATCH_1}") + elseif(line MATCHES "^msgstr .*$" AND NOT msgid STREQUAL "") + # CMake uses ';' as a list separator. + # We need to temporarily replace that in order to keep strings intact. + string(REPLACE ";" "" msgid "${msgid}") + list(APPEND messages "${msgid}") + endif() + endforeach() + + set(content [[// Automatically generated by translate.cmake + +#include + +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + +static const char UNUSED *bitcoin_strings[] = { +]]) + + set(prefix "QT_TRANSLATE_NOOP(\"bitcoin-core\", \"") + set(suffix "\"),\n") + + list(SORT messages) + list(JOIN messages "${suffix}${prefix}" messages_str) + string(APPEND content "${prefix}${messages_str}${suffix}") + string(APPEND content "};\n") + string(REPLACE "" ";" content "${content}") + + file(WRITE "${output}" "${content}") +endfunction() + +file(GLOB_RECURSE translatable_sources + "${PROJECT_SOURCE_DIR}/src/*.h" + "${PROJECT_SOURCE_DIR}/src/*.cpp" + "${PROJECT_SOURCE_DIR}/src/*.mm" +) + +file(GLOB_RECURSE qt_translatable_sources + "${PROJECT_SOURCE_DIR}/src/qt/*.h" + "${PROJECT_SOURCE_DIR}/src/qt/*.cpp" + "${PROJECT_SOURCE_DIR}/src/qt/*.mm" +) + +file(GLOB ui_files + "${PROJECT_SOURCE_DIR}/src/qt/forms/*.ui" +) + +set(subtrees crc32c crypto/ctaes leveldb minisketch secp256k1) +set(exclude_dirs bench compat crypto support test univalue) +foreach(directory IN LISTS subtrees exclude_dirs) + list(FILTER translatable_sources + EXCLUDE REGEX "${PROJECT_SOURCE_DIR}/src/${directory}/.*" + ) +endforeach() + +extract_strings("${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp" + ${translatable_sources} +) + +execute_process( + COMMAND ${LUPDATE_EXECUTABLE} + -no-obsolete + -I ${PROJECT_SOURCE_DIR}/src + -locations relative + ${ui_files} + ${qt_translatable_sources} + ${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp + -ts ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts + COMMAND_ERROR_IS_FATAL ANY +) + +execute_process( + COMMAND ${LCONVERT_EXECUTABLE} + -drop-translations + -o ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf + -i ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts + COMMAND_ERROR_IS_FATAL ANY +) + +file(READ "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" bitcoin_en) +string(REPLACE "source-language=\"en\" target-language=\"en\"" + "source-language=\"en\"" bitcoin_en "${bitcoin_en}" +) +string(REGEX REPLACE " *\n" + "" bitcoin_en "${bitcoin_en}" +) +file(WRITE "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" "${bitcoin_en}") diff --git a/libbitcoinkernel-sys/bitcoin/src/bitcoin-chainstate.cpp b/libbitcoinkernel-sys/bitcoin/src/bitcoin-chainstate.cpp index 0db26486..24127d07 100644 --- a/libbitcoinkernel-sys/bitcoin/src/bitcoin-chainstate.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/bitcoin-chainstate.cpp @@ -53,49 +53,49 @@ class TestValidationInterface : public ValidationInterface m_expected_valid_block = std::nullopt; - void BlockChecked(const UnownedBlock block, const BlockValidationState state) override + void BlockChecked(const Block block, const BlockValidationState state) override { - auto mode{state.ValidationMode()}; + auto mode{state.GetValidationMode()}; switch (mode) { - case btck_ValidationMode::btck_VALIDATION_STATE_VALID: { + case ValidationMode::VALID: { std::cout << "Valid block" << std::endl; return; } - case btck_ValidationMode::btck_VALIDATION_STATE_INVALID: { + case ValidationMode::INVALID: { std::cout << "Invalid block: "; - auto result{state.BlockValidationResult()}; + auto result{state.GetBlockValidationResult()}; switch (result) { - case btck_BlockValidationResult::btck_BLOCK_RESULT_UNSET: + case BlockValidationResult::UNSET: std::cout << "initial value. Block has not yet been rejected" << std::endl; break; - case btck_BlockValidationResult::btck_BLOCK_HEADER_LOW_WORK: + case BlockValidationResult::HEADER_LOW_WORK: std::cout << "the block header may be on a too-little-work chain" << std::endl; break; - case btck_BlockValidationResult::btck_BLOCK_CONSENSUS: + case BlockValidationResult::CONSENSUS: std::cout << "invalid by consensus rules (excluding any below reasons)" << std::endl; break; - case btck_BlockValidationResult::btck_BLOCK_CACHED_INVALID: + case BlockValidationResult::CACHED_INVALID: std::cout << "this block was cached as being invalid and we didn't store the reason why" << std::endl; break; - case btck_BlockValidationResult::btck_BLOCK_INVALID_HEADER: + case BlockValidationResult::INVALID_HEADER: std::cout << "invalid proof of work or time too old" << std::endl; break; - case btck_BlockValidationResult::btck_BLOCK_MUTATED: + case BlockValidationResult::MUTATED: std::cout << "the block's data didn't match the data committed to by the PoW" << std::endl; break; - case btck_BlockValidationResult::btck_BLOCK_MISSING_PREV: + case BlockValidationResult::MISSING_PREV: std::cout << "We don't have the previous block the checked one is built on" << std::endl; break; - case btck_BlockValidationResult::btck_BLOCK_INVALID_PREV: + case BlockValidationResult::INVALID_PREV: std::cout << "A block this one builds on is invalid" << std::endl; break; - case btck_BlockValidationResult::btck_BLOCK_TIME_FUTURE: + case BlockValidationResult::TIME_FUTURE: std::cout << "block timestamp was > 2 hours in the future (or our clock is bad)" << std::endl; break; } return; } - case btck_ValidationMode::btck_VALIDATION_STATE_ERROR: { + case ValidationMode::INTERNAL_ERROR: { std::cout << "Internal error" << std::endl; return; } @@ -106,7 +106,7 @@ class TestValidationInterface : public ValidationInterface { public: - void BlockTipHandler(btck_SynchronizationState, const BlockTreeEntry, double) override + void BlockTipHandler(SynchronizationState, const BlockTreeEntry, double) override { std::cout << "Block tip changed" << std::endl; } @@ -116,14 +116,14 @@ class TestKernelNotifications : public KernelNotifications>(warning) << std::endl; } void FlushErrorHandler(std::string_view error) override @@ -179,13 +179,11 @@ int main(int argc, char* argv[]) Logger logger{std::make_unique(KernelLog{}), logging_options}; ContextOptions options{}; - ChainParams params{btck_ChainType::btck_CHAIN_TYPE_MAINNET}; + ChainParams params{ChainType::MAINNET}; options.SetChainParams(params); - TestKernelNotifications notifications{}; - options.SetNotifications(notifications); - TestValidationInterface validation_interface{}; - options.SetValidationInterface(validation_interface); + options.SetNotifications(std::make_shared()); + options.SetValidationInterface(std::make_shared()); Context context{options}; diff --git a/libbitcoinkernel-sys/bitcoin/src/blockencodings.cpp b/libbitcoinkernel-sys/bitcoin/src/blockencodings.cpp index 947f605d..3f61a122 100644 --- a/libbitcoinkernel-sys/bitcoin/src/blockencodings.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/blockencodings.cpp @@ -42,7 +42,7 @@ void CBlockHeaderAndShortTxIDs::FillShortTxIDSelector() const { uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const Wtxid& wtxid) const { static_assert(SHORTTXIDS_LENGTH == 6, "shorttxids calculation assumes 6-byte shorttxids"); - return SipHashUint256(shorttxidk0, shorttxidk1, wtxid) & 0xffffffffffffL; + return SipHashUint256(shorttxidk0, shorttxidk1, wtxid.ToUint256()) & 0xffffffffffffL; } ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector& extra_txn) { diff --git a/libbitcoinkernel-sys/bitcoin/src/chain.cpp b/libbitcoinkernel-sys/bitcoin/src/chain.cpp index 82007a8a..4e2d1bf0 100644 --- a/libbitcoinkernel-sys/bitcoin/src/chain.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/chain.cpp @@ -52,11 +52,6 @@ CBlockLocator GetLocator(const CBlockIndex* index) return CBlockLocator{LocatorEntries(index)}; } -CBlockLocator CChain::GetLocator() const -{ - return ::GetLocator(Tip()); -} - const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { if (pindex == nullptr) { return nullptr; diff --git a/libbitcoinkernel-sys/bitcoin/src/chain.h b/libbitcoinkernel-sys/bitcoin/src/chain.h index f5bfdb2f..68aa612b 100644 --- a/libbitcoinkernel-sys/bitcoin/src/chain.h +++ b/libbitcoinkernel-sys/bitcoin/src/chain.h @@ -467,9 +467,6 @@ class CChain /** Set/initialize a chain with a given tip. */ void SetTip(CBlockIndex& block); - /** Return a CBlockLocator that refers to the tip in of this chain. */ - CBlockLocator GetLocator() const; - /** Find the last common block between this chain and a block index entry. */ const CBlockIndex* FindFork(const CBlockIndex* pindex) const; diff --git a/libbitcoinkernel-sys/bitcoin/src/common/args.cpp b/libbitcoinkernel-sys/bitcoin/src/common/args.cpp index 94eb9230..ff30ec5b 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/args.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/common/args.cpp @@ -589,6 +589,14 @@ void ArgsManager::AddHiddenArgs(const std::vector& names) } } +void ArgsManager::ClearArgs() +{ + LOCK(cs_args); + m_settings = {}; + m_available_args.clear(); + m_network_only_args.clear(); +} + void ArgsManager::CheckMultipleCLIArgs() const { LOCK(cs_args); diff --git a/libbitcoinkernel-sys/bitcoin/src/common/args.h b/libbitcoinkernel-sys/bitcoin/src/common/args.h index 6c5ac48a..da19cbda 100644 --- a/libbitcoinkernel-sys/bitcoin/src/common/args.h +++ b/libbitcoinkernel-sys/bitcoin/src/common/args.h @@ -359,11 +359,7 @@ class ArgsManager /** * Clear available arguments */ - void ClearArgs() { - LOCK(cs_args); - m_available_args.clear(); - m_network_only_args.clear(); - } + void ClearArgs(); /** * Check CLI command args diff --git a/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.cpp b/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.cpp index 7dd24e18..e274ed82 100644 --- a/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/consensus/merkle.cpp @@ -68,7 +68,7 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated) std::vector leaves; leaves.resize(block.vtx.size()); for (size_t s = 0; s < block.vtx.size(); s++) { - leaves[s] = block.vtx[s]->GetHash(); + leaves[s] = block.vtx[s]->GetHash().ToUint256(); } return ComputeMerkleRoot(std::move(leaves), mutated); } @@ -79,7 +79,7 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated) leaves.resize(block.vtx.size()); leaves[0].SetNull(); // The witness hash of the coinbase is 0. for (size_t s = 1; s < block.vtx.size(); s++) { - leaves[s] = block.vtx[s]->GetWitnessHash(); + leaves[s] = block.vtx[s]->GetWitnessHash().ToUint256(); } return ComputeMerkleRoot(std::move(leaves), mutated); } @@ -185,7 +185,7 @@ std::vector TransactionMerklePath(const CBlock& block, uint32_t positio std::vector leaves; leaves.resize(block.vtx.size()); for (size_t s = 0; s < block.vtx.size(); s++) { - leaves[s] = block.vtx[s]->GetHash(); + leaves[s] = block.vtx[s]->GetHash().ToUint256(); } return ComputeMerklePath(leaves, position); } diff --git a/libbitcoinkernel-sys/bitcoin/src/headerssync.cpp b/libbitcoinkernel-sys/bitcoin/src/headerssync.cpp index 9e8b1905..fbe2026e 100644 --- a/libbitcoinkernel-sys/bitcoin/src/headerssync.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/headerssync.cpp @@ -48,7 +48,7 @@ HeadersSyncState::HeadersSyncState(NodeId id, const Consensus::Params& consensus /** Free any memory in use, and mark this object as no longer usable. This is * required to guarantee that we won't reuse this object with the same - * SaltedTxidHasher for another sync. */ + * SaltedUint256Hasher for another sync. */ void HeadersSyncState::Finalize() { Assume(m_download_state != State::FINAL); diff --git a/libbitcoinkernel-sys/bitcoin/src/headerssync.h b/libbitcoinkernel-sys/bitcoin/src/headerssync.h index 2e7017f1..56380c66 100644 --- a/libbitcoinkernel-sys/bitcoin/src/headerssync.h +++ b/libbitcoinkernel-sys/bitcoin/src/headerssync.h @@ -224,7 +224,7 @@ class HeadersSyncState { arith_uint256 m_current_chain_work; /** m_hasher is a salted hasher for making our 1-bit commitments to headers we've seen. */ - const SaltedTxidHasher m_hasher; + const SaltedUint256Hasher m_hasher; /** A queue of commitment bits, created during the 1st phase, and verified during the 2nd. */ bitdeque<> m_header_commitments; diff --git a/libbitcoinkernel-sys/bitcoin/src/index/base.cpp b/libbitcoinkernel-sys/bitcoin/src/index/base.cpp index fdd0e0d8..6bbe3fde 100644 --- a/libbitcoinkernel-sys/bitcoin/src/index/base.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/index/base.cpp @@ -186,8 +186,8 @@ void BaseIndex::Sync() { const CBlockIndex* pindex = m_best_block_index.load(); if (!m_synced) { - std::chrono::steady_clock::time_point last_log_time{0s}; - std::chrono::steady_clock::time_point last_locator_write_time{0s}; + auto last_log_time{NodeClock::now()}; + auto last_locator_write_time{last_log_time}; while (true) { if (m_interrupt) { LogInfo("%s: m_interrupt set; exiting ThreadSync", GetName()); @@ -229,14 +229,13 @@ void BaseIndex::Sync() if (!ProcessBlock(pindex)) return; // error logged internally - auto current_time{std::chrono::steady_clock::now()}; - if (last_log_time + SYNC_LOG_INTERVAL < current_time) { - LogInfo("Syncing %s with block chain from height %d", - GetName(), pindex->nHeight); + auto current_time{NodeClock::now()}; + if (current_time - last_log_time >= SYNC_LOG_INTERVAL) { + LogInfo("Syncing %s with block chain from height %d", GetName(), pindex->nHeight); last_log_time = current_time; } - if (last_locator_write_time + SYNC_LOCATOR_WRITE_INTERVAL < current_time) { + if (current_time - last_locator_write_time >= SYNC_LOCATOR_WRITE_INTERVAL) { SetBestBlockIndex(pindex); last_locator_write_time = current_time; // No need to handle errors in Commit. See rationale above. @@ -274,7 +273,6 @@ bool BaseIndex::Commit() bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip) { - assert(current_tip == m_best_block_index); assert(current_tip->GetAncestor(new_tip->nHeight) == new_tip); CBlock block; diff --git a/libbitcoinkernel-sys/bitcoin/src/index/txindex.cpp b/libbitcoinkernel-sys/bitcoin/src/index/txindex.cpp index 4bb6dc74..11dd856e 100644 --- a/libbitcoinkernel-sys/bitcoin/src/index/txindex.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/index/txindex.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include constexpr uint8_t DB_TXINDEX{'t'}; @@ -24,26 +25,26 @@ class TxIndex::DB : public BaseIndex::DB /// Read the disk location of the transaction data with the given hash. Returns false if the /// transaction hash is not indexed. - bool ReadTxPos(const uint256& txid, CDiskTxPos& pos) const; + bool ReadTxPos(const Txid& txid, CDiskTxPos& pos) const; /// Write a batch of transaction positions to the DB. - [[nodiscard]] bool WriteTxs(const std::vector>& v_pos); + [[nodiscard]] bool WriteTxs(const std::vector>& v_pos); }; TxIndex::DB::DB(size_t n_cache_size, bool f_memory, bool f_wipe) : BaseIndex::DB(gArgs.GetDataDirNet() / "indexes" / "txindex", n_cache_size, f_memory, f_wipe) {} -bool TxIndex::DB::ReadTxPos(const uint256 &txid, CDiskTxPos& pos) const +bool TxIndex::DB::ReadTxPos(const Txid& txid, CDiskTxPos& pos) const { - return Read(std::make_pair(DB_TXINDEX, txid), pos); + return Read(std::make_pair(DB_TXINDEX, txid.ToUint256()), pos); } -bool TxIndex::DB::WriteTxs(const std::vector>& v_pos) +bool TxIndex::DB::WriteTxs(const std::vector>& v_pos) { CDBBatch batch(*this); - for (const auto& tuple : v_pos) { - batch.Write(std::make_pair(DB_TXINDEX, tuple.first), tuple.second); + for (const auto& [txid, pos] : v_pos) { + batch.Write(std::make_pair(DB_TXINDEX, txid.ToUint256()), pos); } return WriteBatch(batch); } @@ -61,7 +62,7 @@ bool TxIndex::CustomAppend(const interfaces::BlockInfo& block) assert(block.data); CDiskTxPos pos({block.file_number, block.data_pos}, GetSizeOfCompactSize(block.data->vtx.size())); - std::vector> vPos; + std::vector> vPos; vPos.reserve(block.data->vtx.size()); for (const auto& tx : block.data->vtx) { vPos.emplace_back(tx->GetHash(), pos); @@ -72,7 +73,7 @@ bool TxIndex::CustomAppend(const interfaces::BlockInfo& block) BaseIndex::DB& TxIndex::GetDB() const { return *m_db; } -bool TxIndex::FindTx(const uint256& tx_hash, uint256& block_hash, CTransactionRef& tx) const +bool TxIndex::FindTx(const Txid& tx_hash, uint256& block_hash, CTransactionRef& tx) const { CDiskTxPos postx; if (!m_db->ReadTxPos(tx_hash, postx)) { diff --git a/libbitcoinkernel-sys/bitcoin/src/index/txindex.h b/libbitcoinkernel-sys/bitcoin/src/index/txindex.h index ef835fe5..f8236c92 100644 --- a/libbitcoinkernel-sys/bitcoin/src/index/txindex.h +++ b/libbitcoinkernel-sys/bitcoin/src/index/txindex.h @@ -42,7 +42,7 @@ class TxIndex final : public BaseIndex /// @param[out] block_hash The hash of the block the transaction is found in. /// @param[out] tx The transaction itself. /// @return true if transaction is found, false otherwise - bool FindTx(const uint256& tx_hash, uint256& block_hash, CTransactionRef& tx) const; + bool FindTx(const Txid& tx_hash, uint256& block_hash, CTransactionRef& tx) const; }; /// The global transaction index, used in GetTransaction. May be null. diff --git a/libbitcoinkernel-sys/bitcoin/src/init.cpp b/libbitcoinkernel-sys/bitcoin/src/init.cpp index ac401bb7..b6b52e2c 100644 --- a/libbitcoinkernel-sys/bitcoin/src/init.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/init.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -298,6 +299,14 @@ void Shutdown(NodeContext& node) StopREST(); StopRPC(); StopHTTPServer(); + for (auto& client : node.chain_clients) { + try { + client->stop(); + } catch (const ipc::Exception& e) { + LogDebug(BCLog::IPC, "Chain client did not disconnect cleanly: %s", e.what()); + client.reset(); + } + } StopMapPort(); // Because these depend on each-other, we make sure that neither can be @@ -370,8 +379,11 @@ void Shutdown(NodeContext& node) } } } - for (const auto& client : node.chain_clients) { - client->stop(); + + // If any -ipcbind clients are still connected, disconnect them now so they + // do not block shutdown. + if (interfaces::Ipc* ipc = node.init->ipc()) { + ipc->disconnectIncoming(); } #ifdef ENABLE_ZMQ @@ -1400,10 +1412,14 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } }, std::chrono::minutes{5}); - LogInstance().SetRateLimiting(std::make_unique( - [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }, - BCLog::RATELIMIT_MAX_BYTES, - 1h)); + if (args.GetBoolArg("-logratelimit", BCLog::DEFAULT_LOGRATELIMIT)) { + LogInstance().SetRateLimiting(BCLog::LogRateLimiter::Create( + [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }, + BCLog::RATELIMIT_MAX_BYTES, + BCLog::RATELIMIT_WINDOW)); + } else { + LogInfo("Log rate limiting disabled"); + } assert(!node.validation_signals); node.validation_signals = std::make_unique(std::make_unique(scheduler)); @@ -1866,6 +1882,26 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } } +#ifdef __APPLE__ + auto check_and_warn_fs{[&](const fs::path& path, std::string_view desc) { + const auto path_desc{strprintf("%s (\"%s\")", desc, fs::PathToString(path))}; + switch (GetFilesystemType(path)) { + case FSType::EXFAT: + InitWarning(strprintf(_("The %s path uses exFAT, which is known to have intermittent corruption problems on macOS. " + "Move this directory to a different filesystem to avoid data loss."), path_desc)); + break; + case FSType::ERROR: + LogInfo("Failed to detect filesystem type for %s", path_desc); + break; + case FSType::OTHER: + break; + } + }}; + + check_and_warn_fs(args.GetDataDirNet(), "data directory"); + check_and_warn_fs(args.GetBlocksDirPath(), "blocks directory"); +#endif + #if HAVE_SYSTEM const std::string block_notify = args.GetArg("-blocknotify", ""); if (!block_notify.empty()) { diff --git a/libbitcoinkernel-sys/bitcoin/src/init/common.cpp b/libbitcoinkernel-sys/bitcoin/src/init/common.cpp index 25121d74..53f4215c 100644 --- a/libbitcoinkernel-sys/bitcoin/src/init/common.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/init/common.cpp @@ -38,6 +38,7 @@ void AddLoggingArgs(ArgsManager& argsman) argsman.AddArg("-logsourcelocations", strprintf("Prepend debug output with name of the originating source location (source file, line number and function name) (default: %u)", DEFAULT_LOGSOURCELOCATIONS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-loglevelalways", strprintf("Always prepend a category and level (default: %u)", DEFAULT_LOGLEVELALWAYS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + argsman.AddArg("-logratelimit", strprintf("Apply rate limiting to unconditional logging to mitigate disk-filling attacks (default: %u)", BCLog::DEFAULT_LOGRATELIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -daemon. To disable logging to file, set -nodebuglogfile)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-shrinkdebugfile", "Shrink debug.log file on client startup (default: 1 when no -debug)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); } diff --git a/libbitcoinkernel-sys/bitcoin/src/interfaces/chain.h b/libbitcoinkernel-sys/bitcoin/src/interfaces/chain.h index 56716ec6..34ab3631 100644 --- a/libbitcoinkernel-sys/bitcoin/src/interfaces/chain.h +++ b/libbitcoinkernel-sys/bitcoin/src/interfaces/chain.h @@ -143,13 +143,6 @@ class Chain //! pruned), and contains transactions. virtual bool haveBlockOnDisk(int height) = 0; - //! Get locator for the current chain tip. - virtual CBlockLocator getTipLocator() = 0; - - //! Return a locator that refers to a block in the active chain. - //! If specified block is not in the active chain, return locator for the latest ancestor that is in the chain. - virtual CBlockLocator getActiveChainLocator(const uint256& block_hash) = 0; - //! Return height of the highest block on chain in common with the locator, //! which will either be the original block used to create the locator, //! or one of its ancestors. @@ -211,7 +204,7 @@ class Chain virtual bool isInMempool(const Txid& txid) = 0; //! Check if transaction has descendants in mempool. - virtual bool hasDescendantsInMempool(const uint256& txid) = 0; + virtual bool hasDescendantsInMempool(const Txid& txid) = 0; //! Transaction is added to memory pool, if the transaction fee is below the //! amount specified by max_tx_fee, and broadcast to all peers if relay is set to true. @@ -222,7 +215,7 @@ class Chain std::string& err_string) = 0; //! Calculate mempool ancestor and descendant counts for the given transaction. - virtual void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) = 0; + virtual void getTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) = 0; //! For each outpoint, calculate the fee-bumping cost to spend this outpoint at the specified // feerate, including bumping its ancestors. For example, if the target feerate is 10sat/vbyte diff --git a/libbitcoinkernel-sys/bitcoin/src/interfaces/ipc.h b/libbitcoinkernel-sys/bitcoin/src/interfaces/ipc.h index fb340552..8f441118 100644 --- a/libbitcoinkernel-sys/bitcoin/src/interfaces/ipc.h +++ b/libbitcoinkernel-sys/bitcoin/src/interfaces/ipc.h @@ -59,17 +59,20 @@ class Ipc //! true. If this is not a spawned child process, return false. virtual bool startSpawnedProcess(int argc, char* argv[], int& exit_status) = 0; - //! Connect to a socket address and make a client interface proxy object - //! using provided callback. connectAddress returns an interface pointer if - //! the connection was established, returns null if address is empty ("") or - //! disabled ("0") or if a connection was refused but not required ("auto"), - //! and throws an exception if there was an unexpected error. + //! Connect to a socket address and return a pointer to its Init interface. + //! Returns a non-null pointer if the connection was established, returns + //! null if address is empty ("") or disabled ("0") or if a connection was + //! refused but not required ("auto"), and throws an exception if there was + //! an unexpected error. virtual std::unique_ptr connectAddress(std::string& address) = 0; - //! Connect to a socket address and make a client interface proxy object - //! using provided callback. Throws an exception if there was an error. + //! Listen on a socket address exposing this process's init interface to + //! clients. Throws an exception if there was an error. virtual void listenAddress(std::string& address) = 0; + //! Disconnect any incoming connections that are still connected. + virtual void disconnectIncoming() = 0; + //! Add cleanup callback to remote interface that will run when the //! interface is deleted. template diff --git a/libbitcoinkernel-sys/bitcoin/src/interfaces/wallet.h b/libbitcoinkernel-sys/bitcoin/src/interfaces/wallet.h index 94869aff..412cbb61 100644 --- a/libbitcoinkernel-sys/bitcoin/src/interfaces/wallet.h +++ b/libbitcoinkernel-sys/bitcoin/src/interfaces/wallet.h @@ -9,12 +9,12 @@ #include #include #include +#include #include #include