From 153bd443ecf1bfabf3a78eb82fbbc901137c4ba0 Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 12 Mar 2025 10:58:37 -0400 Subject: [PATCH 001/314] [build] bump CLIENT_VERSION_MAJOR to 29 Github-Pull: #32041 Rebased-From: a3f0e9a --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f9467a5612d..094653418c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ endif() # Project / Package metadata #============================= set(CLIENT_NAME "Bitcoin Core") -set(CLIENT_VERSION_MAJOR 28) +set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 99) set(CLIENT_VERSION_BUILD 0) set(CLIENT_VERSION_RC 0) From 95c21b1fdd14f89d762b46b0162bd2fcca1e5a93 Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 12 Mar 2025 10:53:10 -0400 Subject: [PATCH 002/314] [build] bump version to 29.0rc1 --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 094653418c8..3ad29249e95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,10 +24,10 @@ endif() #============================= set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) -set(CLIENT_VERSION_MINOR 99) +set(CLIENT_VERSION_MINOR 0) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 0) -set(CLIENT_VERSION_IS_RELEASE "false") +set(CLIENT_VERSION_RC 1) +set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") # During the enabling of the CXX and CXXOBJ languages, we modify From 86a3ce62096b2faefd01366a6f300fff6f8b9c0b Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 12 Mar 2025 14:21:57 -0400 Subject: [PATCH 003/314] [doc] update man pages for 29.0rc1 --- doc/man/bitcoin-cli.1 | 202 ++++++++- doc/man/bitcoin-qt.1 | 853 ++++++++++++++++++++++++++++++++++++++- doc/man/bitcoin-tx.1 | 160 +++++++- doc/man/bitcoin-util.1 | 79 +++- doc/man/bitcoin-wallet.1 | 137 ++++++- doc/man/bitcoind.1 | 831 +++++++++++++++++++++++++++++++++++++- 6 files changed, 2244 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 6bcad7006b0..2eb89ffa085 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,5 +1,201 @@ -.TH BITCOIN-CLI "1" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-CLI "1" "March 2025" "bitcoin-cli v29.0.0rc1" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli +bitcoin-cli \- manual page for bitcoin-cli v29.0.0rc1 +.SH SYNOPSIS +.B bitcoin-cli +[\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] +.br +.B bitcoin-cli +[\fI\,options\/\fR] \fI\,-named \/\fR[\fI\,name=value\/\fR]... +.br +.B bitcoin-cli +[\fI\,options\/\fR] \fI\,help\/\fR +.br +.B bitcoin-cli +[\fI\,options\/\fR] \fI\,help \/\fR +.SH DESCRIPTION +Bitcoin Core RPC client version v29.0.0rc1 +.PP +The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. +.PP +It can be used to query network information, manage wallets, create or broadcast transactions, and control the Bitcoin Core server. +.PP +Use the "help" command to list all commands. Use "help " to show help for that command. +The \fB\-named\fR option allows you to specify parameters using the key=value format, eliminating the need to pass unused positional parameters. +.SH OPTIONS +.HP +\fB\-color=\fR +.IP +Color setting for CLI output (default: auto). Valid values: always, auto +(add color codes when standard output is connected to a terminal +and OS is not WIN32), never. Only applies to the output of +\fB\-getinfo\fR. +.HP +\fB\-conf=\fR +.IP +Specify configuration file. Relative paths will be prefixed by datadir +location. (default: bitcoin.conf) +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.HP +\fB\-help\fR +.IP +Print this help message and exit (also \fB\-h\fR or \-?) +.HP +\fB\-named\fR +.IP +Pass named instead of positional arguments (default: false) +.HP +\fB\-rpcclienttimeout=\fR +.IP +Timeout in seconds during HTTP requests, or 0 for no timeout. (default: +900) +.HP +\fB\-rpcconnect=\fR +.IP +Send commands to node running on (default: 127.0.0.1) +.HP +\fB\-rpccookiefile=\fR +.IP +Location of the auth cookie. Relative paths will be prefixed by a +net\-specific datadir location. (default: data dir) +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcport=\fR +.IP +Connect to JSON\-RPC on (default: 8332, testnet: 18332, testnet4: +48332, signet: 38332, regtest: 18443) +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcwait\fR +.IP +Wait for RPC server to start +.HP +\fB\-rpcwaittimeout=\fR +.IP +Timeout in seconds to wait for the RPC server to start, or 0 for no +timeout. (default: 0) +.HP +\fB\-rpcwallet=\fR +.IP +Send RPC for non\-default wallet on RPC server (needs to exactly match +corresponding \fB\-wallet\fR option passed to bitcoind). This changes +the RPC endpoint used, e.g. +http://127.0.0.1:8332/wallet/ +.HP +\fB\-stdin\fR +.IP +Read extra arguments from standard input, one per line until EOF/Ctrl\-D +(recommended for sensitive information such as passphrases). When +combined with \fB\-stdinrpcpass\fR, the first line from standard input +is used for the RPC password. +.HP +\fB\-stdinrpcpass\fR +.IP +Read RPC password from standard input as a single line. When combined +with \fB\-stdin\fR, the first line from standard input is used for the +RPC password. When combined with \fB\-stdinwalletpassphrase\fR, +\fB\-stdinrpcpass\fR consumes the first line, and \fB\-stdinwalletpassphrase\fR +consumes the second. +.HP +\fB\-stdinwalletpassphrase\fR +.IP +Read wallet passphrase from standard input as a single line. When +combined with \fB\-stdin\fR, the first line from standard input is used +for the wallet passphrase. +.HP +\fB\-version\fR +.IP +Print version and exit +.PP +Debugging/Testing options: +.PP +Chain selection options: +.HP +\fB\-chain=\fR +.IP +Use the chain (default: main). Allowed values: main, test, +testnet4, signet, regtest +.HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP +\fB\-testnet\fR +.IP +Use the testnet3 chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. Support for testnet3 +is deprecated and will be removed in an upcoming release. +Consider moving to testnet4 now by using \fB\-testnet4\fR. +.HP +\fB\-testnet4\fR +.IP +Use the testnet4 chain. Equivalent to \fB\-chain\fR=\fI\,testnet4\/\fR. +.PP +CLI Commands: +.HP +\fB\-addrinfo\fR +.IP +Get the number of addresses known to the node, per network and total, +after filtering for quality and recency. The total number of +addresses known to the node may be higher. +.HP +\fB\-generate\fR +.IP +Generate blocks, equivalent to RPC getnewaddress followed by RPC +generatetoaddress. Optional positional integer arguments are +number of blocks to generate (default: 1) and maximum iterations +to try (default: 1000000), equivalent to RPC generatetoaddress +nblocks and maxtries arguments. Example: bitcoin\-cli \fB\-generate\fR 4 +1000 +.HP +\fB\-getinfo\fR +.IP +Get general information from the remote server. Note that unlike +server\-side RPC calls, the output of \fB\-getinfo\fR is the result of +multiple non\-atomic requests. Some entries in the output may +represent results from different states (e.g. wallet balance may +be as of a different block from the chain state reported) +.HP +\fB\-netinfo\fR +.IP +Get network peer connection information from the remote server. An +optional argument from 0 to 4 can be passed for different peers +listings (default: 0). If a non\-zero value is passed, an +additional "outonly" (or "o") argument can be passed to see +outbound peers only. Pass "help" (or "h") for detailed help +documentation. +.SH COPYRIGHT +Copyright (C) 2009-2025 The Bitcoin Core developers -This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release. +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or +.SH "SEE ALSO" +bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1) diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index ff4d1d2c7ac..20b7b96e3e3 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,5 +1,852 @@ -.TH BITCOIN-QT "1" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-QT "1" "March 2025" "bitcoin-qt v29.0.0rc1" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt +bitcoin-qt \- manual page for bitcoin-qt v29.0.0rc1 +.SH SYNOPSIS +.B bitcoin-qt +[\fI\,options\/\fR] [\fI\,URI\/\fR] +.SH DESCRIPTION +Bitcoin Core version v29.0.0rc1 +.PP +The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. +.PP +It combines the core functionalities of bitcoind with a user\-friendly interface for wallet management, transaction history, and network statistics. +.PP +It is suitable for users who prefer a graphical over a command\-line interface. +.PP +You can optionally specify a payment [URI], in e.g. the BIP21 URI format. +.SH OPTIONS +.HP +\fB\-alertnotify=\fR +.IP +Execute command when an alert is raised (%s in cmd is replaced by +message) +.HP +\fB\-allowignoredconf\fR +.IP +For backwards compatibility, treat an unused bitcoin.conf file in the +datadir as a warning, not an error. +.HP +\fB\-assumevalid=\fR +.IP +If this block is in the chain assume that it and its ancestors are valid +and potentially skip their script verification (0 to verify all, +default: +00000000000000000001b658dd1120e82e66d2790811f89ede9742ada3ed6d77, +testnet3: +00000000000003fc7967410ba2d0a8a8d50daedc318d43e8baf1a9782c236a57, +testnet4: +0000000000003ed4f08dbdf6f7d6b271a6bcffce25675cb40aa9fa43179a89f3, +signet: +000000895a110f46e59eb82bbc5bfb67fa314656009c295509c21b4999f5180a) +.HP +\fB\-blockfilterindex=\fR +.IP +Maintain an index of compact filters by block (default: 0, values: +basic). If is not supplied or if = 1, indexes for +all known types are enabled. +.HP +\fB\-blocknotify=\fR +.IP +Execute command when the best block changes (%s in cmd is replaced by +block hash) +.HP +\fB\-blockreconstructionextratxn=\fR +.IP +Extra transactions to keep in memory for compact block reconstructions +(default: 100) +.HP +\fB\-blocksdir=\fR +.IP +Specify directory to hold blocks subdirectory for *.dat files (default: +) +.HP +\fB\-blocksonly\fR +.IP +Whether to reject transactions from network peers. Disables automatic +broadcast and rebroadcast of transactions, unless the source peer +has the 'forcerelay' permission. RPC transactions are not +affected. (default: 0) +.HP +\fB\-blocksxor\fR +.IP +Whether an XOR\-key applies to blocksdir *.dat files. The created XOR\-key +will be zeros for an existing blocksdir or when `\-blocksxor=0` is +set, and random for a freshly initialized blocksdir. (default: 1) +.HP +\fB\-coinstatsindex\fR +.IP +Maintain coinstats index used by the gettxoutsetinfo RPC (default: 0) +.HP +\fB\-conf=\fR +.IP +Specify path to read\-only configuration file. Relative paths will be +prefixed by datadir location (only useable from command line, not +configuration file) (default: bitcoin.conf) +.HP +\fB\-daemon\fR +.IP +Run in the background as a daemon and accept commands (default: 0) +.HP +\fB\-daemonwait\fR +.IP +Wait for initialization to be finished before exiting. This implies +\fB\-daemon\fR (default: 0) +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.HP +\fB\-dbcache=\fR +.IP +Maximum database cache size MiB (minimum 4, default: 450). Make sure +you have enough RAM. In addition, unused memory allocated to the +mempool is shared with this cache (see \fB\-maxmempool\fR). +.HP +\fB\-debuglogfile=\fR +.IP +Specify location of debug log file (default: debug.log). Relative paths +will be prefixed by a net\-specific datadir location. Pass +\fB\-nodebuglogfile\fR to disable writing the log to a file. +.HP +\fB\-help\fR +.IP +Print this help message and exit (also \fB\-h\fR or \-?) +.HP +\fB\-includeconf=\fR +.IP +Specify additional configuration file, relative to the \fB\-datadir\fR path +(only useable from configuration file, not command line) +.HP +\fB\-loadblock=\fR +.IP +Imports blocks from external file on startup +.HP +\fB\-maxmempool=\fR +.IP +Keep the transaction memory pool below megabytes (default: 300) +.HP +\fB\-maxorphantx=\fR +.IP +Keep at most unconnectable transactions in memory (default: 100) +.HP +\fB\-mempoolexpiry=\fR +.IP +Do not keep transactions in the mempool longer than hours (default: +336) +.HP +\fB\-par=\fR +.IP +Set the number of script verification threads (0 = auto, up to 15, <0 = +leave that many cores free, default: 0) +.HP +\fB\-persistmempool\fR +.IP +Whether to save the mempool on shutdown and load on restart (default: 1) +.HP +\fB\-persistmempoolv1\fR +.IP +Whether a mempool.dat file created by \fB\-persistmempool\fR or the savemempool +RPC will be written in the legacy format (version 1) or the +current format (version 2). This temporary option will be removed +in the future. (default: 0) +.HP +\fB\-pid=\fR +.IP +Specify pid file. Relative paths will be prefixed by a net\-specific +datadir location. (default: bitcoind.pid) +.HP +\fB\-prune=\fR +.IP +Reduce storage requirements by enabling pruning (deleting) of old +blocks. This allows the pruneblockchain RPC to be called to +delete specific blocks and enables automatic pruning of old +blocks if a target size in MiB is provided. This mode is +incompatible with \fB\-txindex\fR. Warning: Reverting this setting +requires re\-downloading the entire blockchain. (default: 0 = +disable pruning blocks, 1 = allow manual pruning via RPC, >=550 = +automatically prune block files to stay under the specified +target size in MiB) +.HP +\fB\-reindex\fR +.IP +If enabled, wipe chain state and block index, and rebuild them from +blk*.dat files on disk. Also wipe and rebuild other optional +indexes that are active. If an assumeutxo snapshot was loaded, +its chainstate will be wiped as well. The snapshot can then be +reloaded via RPC. +.HP +\fB\-reindex\-chainstate\fR +.IP +If enabled, wipe chain state, and rebuild it from blk*.dat files on +disk. If an assumeutxo snapshot was loaded, its chainstate will +be wiped as well. The snapshot can then be reloaded via RPC. +.HP +\fB\-settings=\fR +.IP +Specify path to dynamic settings data file. Can be disabled with +\fB\-nosettings\fR. File is written at runtime and not meant to be +edited by users (use bitcoin.conf instead for custom settings). +Relative paths will be prefixed by datadir location. (default: +settings.json) +.HP +\fB\-shutdownnotify=\fR +.IP +Execute command immediately before beginning shutdown. The need for +shutdown may be urgent, so be careful not to delay it long (if +the command doesn't require interaction with the server, consider +having it fork into the background). +.HP +\fB\-startupnotify=\fR +.IP +Execute command on startup. +.HP +\fB\-txindex\fR +.IP +Maintain a full transaction index, used by the getrawtransaction rpc +call (default: 0) +.HP +\fB\-version\fR +.IP +Print version and exit +.PP +Connection options: +.HP +\fB\-addnode=\fR +.IP +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 +8 at a time and are counted separately from the \fB\-maxconnections\fR +limit. +.HP +\fB\-asmap=\fR +.IP +Specify asn mapping used for bucketing of the peers (default: +ip_asn.map). Relative paths will be prefixed by the net\-specific +datadir location. +.HP +\fB\-bantime=\fR +.IP +Default duration (in seconds) of manually configured bans (default: +86400) +.HP +\fB\-bind=\fR[:][=onion] +.IP +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:8334=onion, testnet3: 127.0.0.1:18334=onion, +testnet4: 127.0.0.1:48334=onion, signet: 127.0.0.1:38334=onion, +regtest: 127.0.0.1:18445=onion) +.HP +\fB\-cjdnsreachable\fR +.IP +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) +.HP +\fB\-connect=\fR +.IP +Connect only to the specified node; \fB\-noconnect\fR disables automatic +connections (the rules for this peer are the same as for +\fB\-addnode\fR). This option can be specified multiple times to connect +to multiple nodes. +.HP +\fB\-discover\fR +.IP +Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR +or \fB\-proxy\fR) +.HP +\fB\-dns\fR +.IP +Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) +.HP +\fB\-dnsseed\fR +.IP +Query for peer addresses via DNS lookup, if low on addresses (default: 1 +unless \fB\-connect\fR used or \fB\-maxconnections\fR=\fI\,0\/\fR) +.HP +\fB\-externalip=\fR +.IP +Specify your own public address +.HP +\fB\-fixedseeds\fR +.IP +Allow fixed seeds if DNS seeds don't provide peers (default: 1) +.HP +\fB\-forcednsseed\fR +.IP +Always query for peer addresses via DNS lookup (default: 0) +.HP +\fB\-i2pacceptincoming\fR +.IP +Whether to accept inbound I2P connections (default: 1). Ignored if +\fB\-i2psam\fR is not set. Listening for inbound I2P connections is done +through the SAM proxy, not by binding to a local address and +port. +.HP +\fB\-i2psam=\fR +.IP +I2P SAM proxy to reach I2P peers and accept I2P connections (default: +none) +.HP +\fB\-listen\fR +.IP +Accept connections from outside (default: 1 if no \fB\-proxy\fR, \fB\-connect\fR or +\fB\-maxconnections\fR=\fI\,0\/\fR) +.HP +\fB\-listenonion\fR +.IP +Automatically create Tor onion service (default: 1) +.HP +\fB\-maxconnections=\fR +.IP +Maintain at most automatic connections to peers (default: 125). This +limit does not apply to connections manually added via \fB\-addnode\fR +or the addnode RPC, which have a separate limit of 8. +.HP +\fB\-maxreceivebuffer=\fR +.IP +Maximum per\-connection receive buffer, *1000 bytes (default: 5000) +.HP +\fB\-maxsendbuffer=\fR +.IP +Maximum per\-connection memory usage for the send buffer, *1000 bytes +(default: 1000) +.HP +\fB\-maxuploadtarget=\fR +.IP +Tries to keep outbound traffic under the given target per 24h. Limit +does not apply to peers with 'download' permission or blocks +created within past week. 0 = no limit (default: 0M). Optional +suffix units [k|K|m|M|g|G|t|T] (default: M). Lowercase is 1000 +base while uppercase is 1024 base +.HP +\fB\-natpmp\fR +.IP +Use PCP or NAT\-PMP to map the listening port (default: 0) +.HP +\fB\-networkactive\fR +.IP +Enable all P2P network activity (default: 1). Can be changed by the +setnetworkactive RPC command +.HP +\fB\-onion=\fR +.IP +Use separate SOCKS5 proxy to reach peers via Tor onion services, set +\fB\-noonion\fR to disable (default: \fB\-proxy\fR). May be a local file path +prefixed with 'unix:'. +.HP +\fB\-onlynet=\fR +.IP +Make automatic outbound connections only to network (ipv4, ipv6, +onion, i2p, cjdns). Inbound and manual connections are not +affected by this option. It can be specified multiple times to +allow multiple networks. +.HP +\fB\-peerblockfilters\fR +.IP +Serve compact block filters to peers per BIP 157 (default: 0) +.HP +\fB\-peerbloomfilters\fR +.IP +Support filtering of blocks and transaction with bloom filters (default: +0) +.HP +\fB\-port=\fR +.IP +Listen for connections on (default: 8333, testnet3: 18333, +testnet4: 48333, signet: 38333, regtest: 18444). 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. +.HP +\fB\-proxy=\fR +.IP +Connect through SOCKS5 proxy, set \fB\-noproxy\fR to disable (default: +disabled). May be a local file path prefixed with 'unix:' if the +proxy supports it. +.HP +\fB\-proxyrandomize\fR +.IP +Randomize credentials for every proxy connection. This enables Tor +stream isolation (default: 1) +.HP +\fB\-seednode=\fR +.IP +Connect to a node to retrieve peer addresses, and disconnect. This +option can be specified multiple times to connect to multiple +nodes. During startup, seednodes will be tried before dnsseeds. +.HP +\fB\-timeout=\fR +.IP +Specify socket connection timeout in milliseconds. If an initial attempt +to connect is unsuccessful after this amount of time, drop it +(minimum: 1, default: 5000) +.HP +\fB\-torcontrol=\fR: +.IP +Tor control host and port to use if onion listening enabled (default: +127.0.0.1:9051). If no port is specified, the default port of +9051 will be used. +.HP +\fB\-torpassword=\fR +.IP +Tor control port password (default: empty) +.HP +\fB\-v2transport\fR +.IP +Support v2 transport (default: 1) +.HP +\fB\-whitebind=\fR<[permissions@]addr> +.IP +Bind to the given address and add permission flags to the peers +connecting to it. Use [host]:port notation for IPv6. Allowed +permissions: bloomfilter (allow requesting BIP37 filtered blocks +and transactions), noban (do not ban for misbehavior; implies +download), forcerelay (relay transactions that are already in the +mempool; implies relay), relay (relay even in \fB\-blocksonly\fR mode, +and unlimited transaction announcements), mempool (allow +requesting BIP35 mempool contents), download (allow getheaders +during IBD, no disconnect after maxuploadtarget limit), addr +(responses to GETADDR avoid hitting the cache and contain random +records with the most up\-to\-date info). Specify multiple +permissions separated by commas (default: +download,noban,mempool,relay). Can be specified multiple times. +.HP +\fB\-whitelist=\fR<[permissions@]IP address or network> +.IP +Add permission flags to the peers using the given IP address (e.g. +1.2.3.4) or CIDR\-notated network (e.g. 1.2.3.0/24). Uses the same +permissions as \fB\-whitebind\fR. Additional flags "in" and "out" +control whether permissions apply to incoming connections and/or +manual (default: incoming only). Can be specified multiple times. +.PP +Wallet options: +.HP +\fB\-addresstype\fR +.IP +What type of addresses to use ("legacy", "p2sh\-segwit", "bech32", or +"bech32m", default: "bech32") +.HP +\fB\-avoidpartialspends\fR +.IP +Group outputs by address, selecting many (possibly all) or none, instead +of selecting on a per\-output basis. Privacy is improved as +addresses are mostly swept with fewer transactions and outputs +are aggregated in clean change addresses. It may result in higher +fees due to less optimal coin selection caused by this added +limitation and possibly a larger\-than\-necessary number of inputs +being used. Always enabled for wallets with "avoid_reuse" +enabled, otherwise default: 0. +.HP +\fB\-changetype\fR +.IP +What type of change to use ("legacy", "p2sh\-segwit", "bech32", or +"bech32m"). Default is "legacy" when \fB\-addresstype\fR=\fI\,legacy\/\fR, else it +is an implementation detail. +.HP +\fB\-consolidatefeerate=\fR +.IP +The maximum feerate (in BTC/kvB) at which transaction building may use +more inputs than strictly necessary so that the wallet's UTXO +pool can be reduced (default: 0.0001). +.HP +\fB\-disablewallet\fR +.IP +Do not load the wallet and disable wallet RPC calls +.HP +\fB\-discardfee=\fR +.IP +The fee rate (in BTC/kvB) that indicates your tolerance for discarding +change by adding it to the fee (default: 0.0001). Note: An output +is discarded if it is dust at this rate, but we will always +discard up to the dust relay fee and a discard fee above that is +limited by the fee estimate for the longest target +.HP +\fB\-fallbackfee=\fR +.IP +A fee rate (in BTC/kvB) that will be used when fee estimation has +insufficient data. 0 to entirely disable the fallbackfee feature. +(default: 0.00) +.HP +\fB\-keypool=\fR +.IP +Set key pool size to (default: 1000). Warning: Smaller sizes may +increase the risk of losing funds when restoring from an old +backup, if none of the addresses in the original keypool have +been used. +.HP +\fB\-maxapsfee=\fR +.IP +Spend up to this amount in additional (absolute) fees (in BTC) if it +allows the use of partial spend avoidance (default: 0.00) +.HP +\fB\-mintxfee=\fR +.IP +Fee rates (in BTC/kvB) smaller than this are considered zero fee for +transaction creation (default: 0.00001) +.HP +\fB\-paytxfee=\fR +.IP +Fee rate (in BTC/kvB) to add to transactions you send (default: 0.00) +.HP +\fB\-signer=\fR +.IP +External signing tool, see doc/external\-signer.md +.HP +\fB\-spendzeroconfchange\fR +.IP +Spend unconfirmed change when sending transactions (default: 1) +.HP +\fB\-txconfirmtarget=\fR +.IP +If paytxfee is not set, include enough fee so transactions begin +confirmation on average within n blocks (default: 6) +.HP +\fB\-wallet=\fR +.IP +Specify wallet path to load at startup. Can be used multiple times to +load multiple wallets. Path is to a directory containing wallet +data and log files. If the path is not absolute, it is +interpreted relative to . This only loads existing +wallets and does not create new ones. For backwards compatibility +this also accepts names of existing top\-level data files in +. +.HP +\fB\-walletbroadcast\fR +.IP +Make the wallet broadcast transactions (default: 1) +.HP +\fB\-walletdir=\fR +.IP +Specify directory to hold wallets (default: /wallets if it +exists, otherwise ) +.HP +\fB\-walletnotify=\fR +.IP +Execute command when a wallet transaction changes. %s in cmd is replaced +by TxID, %w is replaced by wallet name, %b is replaced by the +hash of the block including the transaction (set to 'unconfirmed' +if the transaction is not included) and %h is replaced by the +block height (\fB\-1\fR if not included). %w is not currently +implemented on windows. On systems where %w is supported, it +should NOT be quoted because this would break shell escaping used +to invoke the command. +.HP +\fB\-walletrbf\fR +.IP +Send transactions with full\-RBF opt\-in enabled (RPC only, default: 1) +.PP +ZeroMQ notification options: +.HP +\fB\-zmqpubhashblock=\fR
+.IP +Enable publish hash block in
+.HP +\fB\-zmqpubhashblockhwm=\fR +.IP +Set publish hash block outbound message high water mark (default: 1000) +.HP +\fB\-zmqpubhashtx=\fR
+.IP +Enable publish hash transaction in
+.HP +\fB\-zmqpubhashtxhwm=\fR +.IP +Set publish hash transaction outbound message high water mark (default: +1000) +.HP +\fB\-zmqpubrawblock=\fR
+.IP +Enable publish raw block in
+.HP +\fB\-zmqpubrawblockhwm=\fR +.IP +Set publish raw block outbound message high water mark (default: 1000) +.HP +\fB\-zmqpubrawtx=\fR
+.IP +Enable publish raw transaction in
+.HP +\fB\-zmqpubrawtxhwm=\fR +.IP +Set publish raw transaction outbound message high water mark (default: +1000) +.HP +\fB\-zmqpubsequence=\fR
+.IP +Enable publish hash block and tx sequence in
+.HP +\fB\-zmqpubsequencehwm=\fR +.IP +Set publish hash sequence message high water mark (default: 1000) +.PP +Debugging/Testing options: +.HP +\fB\-debug=\fR +.IP +Output debug and trace logging (default: \fB\-nodebug\fR, supplying +is optional). If is not supplied or if is 1 +or "all", output all debug logging. If is 0 or "none", +any other categories are ignored. Other valid values for + are: addrman, bench, blockstorage, cmpctblock, coindb, +estimatefee, http, i2p, ipc, leveldb, libevent, mempool, +mempoolrej, net, proxy, prune, qt, rand, reindex, rpc, scan, +selectcoins, tor, txpackages, txreconciliation, validation, +walletdb, zmq. This option can be specified multiple times to +output multiple categories. +.HP +\fB\-debugexclude=\fR +.IP +Exclude debug and trace logging for a category. Can be used in +conjunction with \fB\-debug\fR=\fI\,1\/\fR to output debug and trace logging for +all categories except the specified category. This option can be +specified multiple times to exclude multiple categories. This +takes priority over "\-debug" +.HP +\fB\-help\-debug\fR +.IP +Print help message with debugging options and exit +.HP +\fB\-logips\fR +.IP +Include IP addresses in debug output (default: 0) +.HP +\fB\-loglevelalways\fR +.IP +Always prepend a category and level (default: 0) +.HP +\fB\-logsourcelocations\fR +.IP +Prepend debug output with name of the originating source location +(source file, line number and function name) (default: 0) +.HP +\fB\-logthreadnames\fR +.IP +Prepend debug output with name of the originating thread (default: 0) +.HP +\fB\-logtimestamps\fR +.IP +Prepend debug output with timestamp (default: 1) +.HP +\fB\-maxtxfee=\fR +.IP +Maximum total fees (in BTC) to use in a single wallet transaction; +setting this too low may abort large transactions (default: 0.10) +.HP +\fB\-printtoconsole\fR +.IP +Send trace/debug info to console (default: 1 when no \fB\-daemon\fR. To disable +logging to file, set \fB\-nodebuglogfile\fR) +.HP +\fB\-shrinkdebugfile\fR +.IP +Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) +.HP +\fB\-uacomment=\fR +.IP +Append comment to the user agent string +.PP +Chain selection options: +.HP +\fB\-chain=\fR +.IP +Use the chain (default: main). Allowed values: main, test, +testnet4, signet, regtest +.HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP +\fB\-testnet\fR +.IP +Use the testnet3 chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. Support for testnet3 +is deprecated and will be removed in an upcoming release. +Consider moving to testnet4 now by using \fB\-testnet4\fR. +.HP +\fB\-testnet4\fR +.IP +Use the testnet4 chain. Equivalent to \fB\-chain\fR=\fI\,testnet4\/\fR. +.PP +Node relay options: +.HP +\fB\-bytespersigop\fR +.IP +Equivalent bytes per sigop in transactions for relay and mining +(default: 20) +.HP +\fB\-datacarrier\fR +.IP +Relay and mine data carrier transactions (default: 1) +.HP +\fB\-datacarriersize\fR +.IP +Relay and mine transactions whose data\-carrying raw scriptPubKey is of +this size or less (default: 83) +.HP +\fB\-minrelaytxfee=\fR +.IP +Fees (in BTC/kvB) smaller than this are considered zero fee for +relaying, mining and transaction creation (default: 0.00001) +.HP +\fB\-permitbaremultisig\fR +.IP +Relay transactions creating non\-P2SH multisig outputs (default: 1) +.HP +\fB\-whitelistforcerelay\fR +.IP +Add 'forcerelay' permission to whitelisted peers with default +permissions. This will relay transactions even if the +transactions were already in the mempool. (default: 0) +.HP +\fB\-whitelistrelay\fR +.IP +Add 'relay' permission to whitelisted peers with default permissions. +This will accept relayed transactions even when not relaying +transactions (default: 1) +.PP +Block creation options: +.HP +\fB\-blockmaxweight=\fR +.IP +Set maximum BIP141 block weight (default: 4000000) +.HP +\fB\-blockmintxfee=\fR +.IP +Set lowest fee rate (in BTC/kvB) for transactions to be included in +block creation. (default: 0.00001) +.HP +\fB\-blockreservedweight=\fR +.IP +Reserve space for the fixed\-size block header plus the largest coinbase +transaction the mining software may add to the block. (default: +8000). +.PP +RPC server options: +.HP +\fB\-rest\fR +.IP +Accept public REST requests (default: 0) +.HP +\fB\-rpcallowip=\fR +.IP +Allow JSON\-RPC connections from specified source. Valid values for +are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. +1.2.3.4/255.255.255.0), a network/CIDR (e.g. 1.2.3.4/24), all +ipv4 (0.0.0.0/0), or all ipv6 (::/0). This option can be +specified multiple times +.HP +\fB\-rpcauth=\fR +.IP +Username and HMAC\-SHA\-256 hashed password for JSON\-RPC connections. The +field comes in the format: :$. A +canonical python script is included in share/rpcauth. The client +then connects normally using the +rpcuser=/rpcpassword= pair of arguments. This +option can be specified multiple times +.HP +\fB\-rpcbind=\fR[:port] +.IP +Bind to given address to listen for JSON\-RPC connections. Do not expose +the RPC server to untrusted networks such as the public internet! +This option is ignored unless \fB\-rpcallowip\fR is also passed. Port is +optional and overrides \fB\-rpcport\fR. Use [host]:port notation for +IPv6. This option can be specified multiple times (default: +127.0.0.1 and ::1 i.e., localhost) +.HP +\fB\-rpccookiefile=\fR +.IP +Location of the auth cookie. Relative paths will be prefixed by a +net\-specific datadir location. (default: data dir) +.HP +\fB\-rpccookieperms=\fR +.IP +Set permissions on the RPC auth cookie file so that it is readable by +[owner|group|all] (default: owner [via umask 0077]) +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcport=\fR +.IP +Listen for JSON\-RPC connections on (default: 8332, testnet3: +18332, testnet4: 48332, signet: 38332, regtest: 18443) +.HP +\fB\-rpcthreads=\fR +.IP +Set the number of threads to service RPC calls (default: 16) +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcwhitelist=\fR +.IP +Set a whitelist to filter incoming RPC calls for a specific user. The +field comes in the format: :,,...,. If multiple whitelists are set for a given user, +they are set\-intersected. See \fB\-rpcwhitelistdefault\fR documentation +for information on default whitelist behavior. +.HP +\fB\-rpcwhitelistdefault\fR +.IP +Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault +is set to 0, if any \fB\-rpcwhitelist\fR is set, the rpc server acts as +if all rpc users are subject to empty\-unless\-otherwise\-specified +whitelists. If rpcwhitelistdefault is set to 1 and no +\fB\-rpcwhitelist\fR is set, rpc server acts as if all rpc users are +subject to empty whitelists. +.HP +\fB\-server\fR +.IP +Accept command line and JSON\-RPC commands +.PP +UI Options: +.HP +\fB\-choosedatadir\fR +.IP +Choose data directory on startup (default: 0) +.HP +\fB\-lang=\fR +.IP +Set language, for example "de_DE" (default: system locale) +.HP +\fB\-min\fR +.IP +Start minimized +.HP +\fB\-resetguisettings\fR +.IP +Reset all settings changed in the GUI +.HP +\fB\-splash\fR +.IP +Show splash screen on startup (default: 1) +.SH COPYRIGHT +Copyright (C) 2009-2025 The Bitcoin Core developers -This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release. +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or +.SH "SEE ALSO" +bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1) diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 776bb462342..b493f916b0f 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,5 +1,159 @@ -.TH BITCOIN-TX "1" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-TX "1" "March 2025" "bitcoin-tx v29.0.0rc1" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx +bitcoin-tx \- manual page for bitcoin-tx v29.0.0rc1 +.SH SYNOPSIS +.B bitcoin-tx +[\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] +.br +.B bitcoin-tx +[\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] +.SH DESCRIPTION +Bitcoin Core bitcoin\-tx utility version v29.0.0rc1 +.PP +The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. +.PP +bitcoin\-tx can be used with " [commands]" to update a hex\-encoded bitcoin transaction, or with "\-create [commands]" to create a hex\-encoded bitcoin transaction. +.SH OPTIONS +.HP +\fB\-create\fR +.IP +Create new, empty TX. +.HP +\fB\-help\fR +.IP +Print this help message and exit (also \fB\-h\fR or \-?) +.HP +\fB\-json\fR +.IP +Select JSON output +.HP +\fB\-txid\fR +.IP +Output only the hex\-encoded transaction id of the resultant transaction. +.HP +\fB\-version\fR +.IP +Print version and exit +.PP +Debugging/Testing options: +.PP +Chain selection options: +.HP +\fB\-chain=\fR +.IP +Use the chain (default: main). Allowed values: main, test, +testnet4, signet, regtest +.HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP +\fB\-testnet\fR +.IP +Use the testnet3 chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. Support for testnet3 +is deprecated and will be removed in an upcoming release. +Consider moving to testnet4 now by using \fB\-testnet4\fR. +.HP +\fB\-testnet4\fR +.IP +Use the testnet4 chain. Equivalent to \fB\-chain\fR=\fI\,testnet4\/\fR. +.PP +Commands: +.IP +delin=N +.IP +Delete input N from TX +.IP +delout=N +.IP +Delete output N from TX +.IP +in=TXID:VOUT(:SEQUENCE_NUMBER) +.IP +Add input to TX +.IP +locktime=N +.IP +Set TX lock time to N +.IP +nversion=N +.IP +Set TX version to N +.IP +outaddr=VALUE:ADDRESS +.IP +Add address\-based output to TX +.IP +outdata=[VALUE:]DATA +.IP +Add data\-based output to TX +.IP +outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS] +.IP +Add Pay To n\-of\-m Multi\-sig output to TX. n = REQUIRED, m = PUBKEYS. +Optionally add the "W" flag to produce a +pay\-to\-witness\-script\-hash output. Optionally add the "S" flag to +wrap the output in a pay\-to\-script\-hash. +.IP +outpubkey=VALUE:PUBKEY[:FLAGS] +.IP +Add pay\-to\-pubkey output to TX. Optionally add the "W" flag to produce a +pay\-to\-witness\-pubkey\-hash output. Optionally add the "S" flag to +wrap the output in a pay\-to\-script\-hash. +.IP +outscript=VALUE:SCRIPT[:FLAGS] +.IP +Add raw script output to TX. Optionally add the "W" flag to produce a +pay\-to\-witness\-script\-hash output. Optionally add the "S" flag to +wrap the output in a pay\-to\-script\-hash. +.IP +replaceable(=N) +.IP +Sets Replace\-By\-Fee (RBF) opt\-in sequence number for input N. If N is +not provided, the command attempts to opt\-in all available inputs +for RBF. If the transaction has no inputs, this option is +ignored. +.IP +sign=SIGHASH\-FLAGS +.IP +Add zero or more signatures to transaction. This command requires JSON +registers:prevtxs=JSON object, privatekeys=JSON object. See +signrawtransactionwithkey docs for format of sighash flags, JSON +objects. +.PP +Register Commands: +.IP +load=NAME:FILENAME +.IP +Load JSON file FILENAME into register NAME +.IP +set=NAME:JSON\-STRING +.IP +Set register NAME to given JSON\-STRING +.SH COPYRIGHT +Copyright (C) 2009-2025 The Bitcoin Core developers -This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release. +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or +.SH "SEE ALSO" +bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1) diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index 5c733c6e21d..74cf2329ed1 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,5 +1,78 @@ -.TH BITCOIN-UTIL "1" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-UTIL "1" "March 2025" "bitcoin-util v29.0.0rc1" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util +bitcoin-util \- manual page for bitcoin-util v29.0.0rc1 +.SH SYNOPSIS +.B bitcoin-util +[\fI\,options\/\fR] [\fI\,command\/\fR] +.br +.B bitcoin-util +[\fI\,options\/\fR] \fI\,grind \/\fR +.SH DESCRIPTION +Bitcoin Core bitcoin\-util utility version v29.0.0rc1 +.PP +The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. +.SH OPTIONS +.HP +\fB\-help\fR +.IP +Print this help message and exit (also \fB\-h\fR or \-?) +.HP +\fB\-version\fR +.IP +Print version and exit +.PP +Debugging/Testing options: +.PP +Chain selection options: +.HP +\fB\-chain=\fR +.IP +Use the chain (default: main). Allowed values: main, test, +testnet4, signet, regtest +.HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP +\fB\-testnet\fR +.IP +Use the testnet3 chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. Support for testnet3 +is deprecated and will be removed in an upcoming release. +Consider moving to testnet4 now by using \fB\-testnet4\fR. +.HP +\fB\-testnet4\fR +.IP +Use the testnet4 chain. Equivalent to \fB\-chain\fR=\fI\,testnet4\/\fR. +.PP +Commands: +.IP +grind +.IP +Perform proof of work on hex header string +.SH COPYRIGHT +Copyright (C) 2009-2025 The Bitcoin Core developers -This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release. +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or +.SH "SEE ALSO" +bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1) diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index 2da43dec663..dbf30100705 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,5 +1,136 @@ -.TH BITCOIN-WALLET "1" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-WALLET "1" "March 2025" "bitcoin-wallet v29.0.0rc1" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet +bitcoin-wallet \- manual page for bitcoin-wallet v29.0.0rc1 +.SH SYNOPSIS +.B bitcoin-wallet +[\fI\,options\/\fR] \fI\,\/\fR +.SH DESCRIPTION +Bitcoin Core bitcoin\-wallet utility version v29.0.0rc1 +.PP +bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. +.PP +By default bitcoin\-wallet will act on wallets in the default mainnet wallet directory in the datadir. +.PP +To change the target wallet, use the \fB\-datadir\fR, \fB\-wallet\fR and (test)chain selection arguments. +.SH OPTIONS +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.HP +\fB\-descriptors\fR +.IP +Create descriptors wallet. Only for 'create' +.HP +\fB\-dumpfile=\fR +.IP +When used with 'dump', writes out the records to this file. When used +with 'createfromdump', loads the records into a new wallet. +.HP +\fB\-format=\fR +.IP +The format of the wallet file to create. Either "bdb" or "sqlite". Only +used with 'createfromdump' +.HP +\fB\-help\fR +.IP +Print this help message and exit (also \fB\-h\fR or \-?) +.HP +\fB\-legacy\fR +.IP +Create legacy wallet. Only for 'create' +.HP +\fB\-version\fR +.IP +Print version and exit +.HP +\fB\-wallet=\fR +.IP +Specify wallet name +.PP +Debugging/Testing options: +.HP +\fB\-debug=\fR +.IP +Output debugging information (default: 0). +.HP +\fB\-printtoconsole\fR +.IP +Send trace/debug info to console (default: 1 when no \fB\-debug\fR is true, 0 +otherwise). +.HP +\fB\-withinternalbdb\fR +.IP +Use the internal Berkeley DB parser when dumping a Berkeley DB wallet +file (default: false) +.PP +Chain selection options: +.HP +\fB\-chain=\fR +.IP +Use the chain (default: main). Allowed values: main, test, +testnet4, signet, regtest +.HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP +\fB\-testnet\fR +.IP +Use the testnet3 chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. Support for testnet3 +is deprecated and will be removed in an upcoming release. +Consider moving to testnet4 now by using \fB\-testnet4\fR. +.HP +\fB\-testnet4\fR +.IP +Use the testnet4 chain. Equivalent to \fB\-chain\fR=\fI\,testnet4\/\fR. +.PP +Commands: +.IP +create +.IP +Create new wallet file +.IP +createfromdump +.IP +Create new wallet file from dumped records +.IP +dump +.IP +Print out all of the wallet key\-value records +.IP +info +.IP +Get wallet info +.IP +salvage +.IP +Attempt to recover private keys from a corrupt wallet. Warning: +\&'salvage' is experimental. +.SH COPYRIGHT +Copyright (C) 2009-2025 The Bitcoin Core developers -This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release. +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or +.SH "SEE ALSO" +bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1) diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 2c88f745205..865a59e87cb 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,5 +1,830 @@ -.TH BITCOIND "1" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIND "1" "March 2025" "bitcoind v29.0.0rc1" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind +bitcoind \- manual page for bitcoind v29.0.0rc1 +.SH SYNOPSIS +.B bitcoind +[\fI\,options\/\fR] +.SH DESCRIPTION +Bitcoin Core daemon version v29.0.0rc1 +.PP +The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. +.PP +It provides the backbone of the Bitcoin network and its RPC, REST and ZMQ services can provide various transaction, block and address\-related services. +.PP +There is an optional wallet component which provides transaction services. +.PP +It can be used in a headless environment or as part of a server setup. +.SH OPTIONS +.HP +\fB\-alertnotify=\fR +.IP +Execute command when an alert is raised (%s in cmd is replaced by +message) +.HP +\fB\-allowignoredconf\fR +.IP +For backwards compatibility, treat an unused bitcoin.conf file in the +datadir as a warning, not an error. +.HP +\fB\-assumevalid=\fR +.IP +If this block is in the chain assume that it and its ancestors are valid +and potentially skip their script verification (0 to verify all, +default: +00000000000000000001b658dd1120e82e66d2790811f89ede9742ada3ed6d77, +testnet3: +00000000000003fc7967410ba2d0a8a8d50daedc318d43e8baf1a9782c236a57, +testnet4: +0000000000003ed4f08dbdf6f7d6b271a6bcffce25675cb40aa9fa43179a89f3, +signet: +000000895a110f46e59eb82bbc5bfb67fa314656009c295509c21b4999f5180a) +.HP +\fB\-blockfilterindex=\fR +.IP +Maintain an index of compact filters by block (default: 0, values: +basic). If is not supplied or if = 1, indexes for +all known types are enabled. +.HP +\fB\-blocknotify=\fR +.IP +Execute command when the best block changes (%s in cmd is replaced by +block hash) +.HP +\fB\-blockreconstructionextratxn=\fR +.IP +Extra transactions to keep in memory for compact block reconstructions +(default: 100) +.HP +\fB\-blocksdir=\fR +.IP +Specify directory to hold blocks subdirectory for *.dat files (default: +) +.HP +\fB\-blocksonly\fR +.IP +Whether to reject transactions from network peers. Disables automatic +broadcast and rebroadcast of transactions, unless the source peer +has the 'forcerelay' permission. RPC transactions are not +affected. (default: 0) +.HP +\fB\-blocksxor\fR +.IP +Whether an XOR\-key applies to blocksdir *.dat files. The created XOR\-key +will be zeros for an existing blocksdir or when `\-blocksxor=0` is +set, and random for a freshly initialized blocksdir. (default: 1) +.HP +\fB\-coinstatsindex\fR +.IP +Maintain coinstats index used by the gettxoutsetinfo RPC (default: 0) +.HP +\fB\-conf=\fR +.IP +Specify path to read\-only configuration file. Relative paths will be +prefixed by datadir location (only useable from command line, not +configuration file) (default: bitcoin.conf) +.HP +\fB\-daemon\fR +.IP +Run in the background as a daemon and accept commands (default: 0) +.HP +\fB\-daemonwait\fR +.IP +Wait for initialization to be finished before exiting. This implies +\fB\-daemon\fR (default: 0) +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.HP +\fB\-dbcache=\fR +.IP +Maximum database cache size MiB (minimum 4, default: 450). Make sure +you have enough RAM. In addition, unused memory allocated to the +mempool is shared with this cache (see \fB\-maxmempool\fR). +.HP +\fB\-debuglogfile=\fR +.IP +Specify location of debug log file (default: debug.log). Relative paths +will be prefixed by a net\-specific datadir location. Pass +\fB\-nodebuglogfile\fR to disable writing the log to a file. +.HP +\fB\-help\fR +.IP +Print this help message and exit (also \fB\-h\fR or \-?) +.HP +\fB\-includeconf=\fR +.IP +Specify additional configuration file, relative to the \fB\-datadir\fR path +(only useable from configuration file, not command line) +.HP +\fB\-loadblock=\fR +.IP +Imports blocks from external file on startup +.HP +\fB\-maxmempool=\fR +.IP +Keep the transaction memory pool below megabytes (default: 300) +.HP +\fB\-maxorphantx=\fR +.IP +Keep at most unconnectable transactions in memory (default: 100) +.HP +\fB\-mempoolexpiry=\fR +.IP +Do not keep transactions in the mempool longer than hours (default: +336) +.HP +\fB\-par=\fR +.IP +Set the number of script verification threads (0 = auto, up to 15, <0 = +leave that many cores free, default: 0) +.HP +\fB\-persistmempool\fR +.IP +Whether to save the mempool on shutdown and load on restart (default: 1) +.HP +\fB\-persistmempoolv1\fR +.IP +Whether a mempool.dat file created by \fB\-persistmempool\fR or the savemempool +RPC will be written in the legacy format (version 1) or the +current format (version 2). This temporary option will be removed +in the future. (default: 0) +.HP +\fB\-pid=\fR +.IP +Specify pid file. Relative paths will be prefixed by a net\-specific +datadir location. (default: bitcoind.pid) +.HP +\fB\-prune=\fR +.IP +Reduce storage requirements by enabling pruning (deleting) of old +blocks. This allows the pruneblockchain RPC to be called to +delete specific blocks and enables automatic pruning of old +blocks if a target size in MiB is provided. This mode is +incompatible with \fB\-txindex\fR. Warning: Reverting this setting +requires re\-downloading the entire blockchain. (default: 0 = +disable pruning blocks, 1 = allow manual pruning via RPC, >=550 = +automatically prune block files to stay under the specified +target size in MiB) +.HP +\fB\-reindex\fR +.IP +If enabled, wipe chain state and block index, and rebuild them from +blk*.dat files on disk. Also wipe and rebuild other optional +indexes that are active. If an assumeutxo snapshot was loaded, +its chainstate will be wiped as well. The snapshot can then be +reloaded via RPC. +.HP +\fB\-reindex\-chainstate\fR +.IP +If enabled, wipe chain state, and rebuild it from blk*.dat files on +disk. If an assumeutxo snapshot was loaded, its chainstate will +be wiped as well. The snapshot can then be reloaded via RPC. +.HP +\fB\-settings=\fR +.IP +Specify path to dynamic settings data file. Can be disabled with +\fB\-nosettings\fR. File is written at runtime and not meant to be +edited by users (use bitcoin.conf instead for custom settings). +Relative paths will be prefixed by datadir location. (default: +settings.json) +.HP +\fB\-shutdownnotify=\fR +.IP +Execute command immediately before beginning shutdown. The need for +shutdown may be urgent, so be careful not to delay it long (if +the command doesn't require interaction with the server, consider +having it fork into the background). +.HP +\fB\-startupnotify=\fR +.IP +Execute command on startup. +.HP +\fB\-txindex\fR +.IP +Maintain a full transaction index, used by the getrawtransaction rpc +call (default: 0) +.HP +\fB\-version\fR +.IP +Print version and exit +.PP +Connection options: +.HP +\fB\-addnode=\fR +.IP +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 +8 at a time and are counted separately from the \fB\-maxconnections\fR +limit. +.HP +\fB\-asmap=\fR +.IP +Specify asn mapping used for bucketing of the peers (default: +ip_asn.map). Relative paths will be prefixed by the net\-specific +datadir location. +.HP +\fB\-bantime=\fR +.IP +Default duration (in seconds) of manually configured bans (default: +86400) +.HP +\fB\-bind=\fR[:][=onion] +.IP +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:8334=onion, testnet3: 127.0.0.1:18334=onion, +testnet4: 127.0.0.1:48334=onion, signet: 127.0.0.1:38334=onion, +regtest: 127.0.0.1:18445=onion) +.HP +\fB\-cjdnsreachable\fR +.IP +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) +.HP +\fB\-connect=\fR +.IP +Connect only to the specified node; \fB\-noconnect\fR disables automatic +connections (the rules for this peer are the same as for +\fB\-addnode\fR). This option can be specified multiple times to connect +to multiple nodes. +.HP +\fB\-discover\fR +.IP +Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR +or \fB\-proxy\fR) +.HP +\fB\-dns\fR +.IP +Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) +.HP +\fB\-dnsseed\fR +.IP +Query for peer addresses via DNS lookup, if low on addresses (default: 1 +unless \fB\-connect\fR used or \fB\-maxconnections\fR=\fI\,0\/\fR) +.HP +\fB\-externalip=\fR +.IP +Specify your own public address +.HP +\fB\-fixedseeds\fR +.IP +Allow fixed seeds if DNS seeds don't provide peers (default: 1) +.HP +\fB\-forcednsseed\fR +.IP +Always query for peer addresses via DNS lookup (default: 0) +.HP +\fB\-i2pacceptincoming\fR +.IP +Whether to accept inbound I2P connections (default: 1). Ignored if +\fB\-i2psam\fR is not set. Listening for inbound I2P connections is done +through the SAM proxy, not by binding to a local address and +port. +.HP +\fB\-i2psam=\fR +.IP +I2P SAM proxy to reach I2P peers and accept I2P connections (default: +none) +.HP +\fB\-listen\fR +.IP +Accept connections from outside (default: 1 if no \fB\-proxy\fR, \fB\-connect\fR or +\fB\-maxconnections\fR=\fI\,0\/\fR) +.HP +\fB\-listenonion\fR +.IP +Automatically create Tor onion service (default: 1) +.HP +\fB\-maxconnections=\fR +.IP +Maintain at most automatic connections to peers (default: 125). This +limit does not apply to connections manually added via \fB\-addnode\fR +or the addnode RPC, which have a separate limit of 8. +.HP +\fB\-maxreceivebuffer=\fR +.IP +Maximum per\-connection receive buffer, *1000 bytes (default: 5000) +.HP +\fB\-maxsendbuffer=\fR +.IP +Maximum per\-connection memory usage for the send buffer, *1000 bytes +(default: 1000) +.HP +\fB\-maxuploadtarget=\fR +.IP +Tries to keep outbound traffic under the given target per 24h. Limit +does not apply to peers with 'download' permission or blocks +created within past week. 0 = no limit (default: 0M). Optional +suffix units [k|K|m|M|g|G|t|T] (default: M). Lowercase is 1000 +base while uppercase is 1024 base +.HP +\fB\-natpmp\fR +.IP +Use PCP or NAT\-PMP to map the listening port (default: 0) +.HP +\fB\-networkactive\fR +.IP +Enable all P2P network activity (default: 1). Can be changed by the +setnetworkactive RPC command +.HP +\fB\-onion=\fR +.IP +Use separate SOCKS5 proxy to reach peers via Tor onion services, set +\fB\-noonion\fR to disable (default: \fB\-proxy\fR). May be a local file path +prefixed with 'unix:'. +.HP +\fB\-onlynet=\fR +.IP +Make automatic outbound connections only to network (ipv4, ipv6, +onion, i2p, cjdns). Inbound and manual connections are not +affected by this option. It can be specified multiple times to +allow multiple networks. +.HP +\fB\-peerblockfilters\fR +.IP +Serve compact block filters to peers per BIP 157 (default: 0) +.HP +\fB\-peerbloomfilters\fR +.IP +Support filtering of blocks and transaction with bloom filters (default: +0) +.HP +\fB\-port=\fR +.IP +Listen for connections on (default: 8333, testnet3: 18333, +testnet4: 48333, signet: 38333, regtest: 18444). 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. +.HP +\fB\-proxy=\fR +.IP +Connect through SOCKS5 proxy, set \fB\-noproxy\fR to disable (default: +disabled). May be a local file path prefixed with 'unix:' if the +proxy supports it. +.HP +\fB\-proxyrandomize\fR +.IP +Randomize credentials for every proxy connection. This enables Tor +stream isolation (default: 1) +.HP +\fB\-seednode=\fR +.IP +Connect to a node to retrieve peer addresses, and disconnect. This +option can be specified multiple times to connect to multiple +nodes. During startup, seednodes will be tried before dnsseeds. +.HP +\fB\-timeout=\fR +.IP +Specify socket connection timeout in milliseconds. If an initial attempt +to connect is unsuccessful after this amount of time, drop it +(minimum: 1, default: 5000) +.HP +\fB\-torcontrol=\fR: +.IP +Tor control host and port to use if onion listening enabled (default: +127.0.0.1:9051). If no port is specified, the default port of +9051 will be used. +.HP +\fB\-torpassword=\fR +.IP +Tor control port password (default: empty) +.HP +\fB\-v2transport\fR +.IP +Support v2 transport (default: 1) +.HP +\fB\-whitebind=\fR<[permissions@]addr> +.IP +Bind to the given address and add permission flags to the peers +connecting to it. Use [host]:port notation for IPv6. Allowed +permissions: bloomfilter (allow requesting BIP37 filtered blocks +and transactions), noban (do not ban for misbehavior; implies +download), forcerelay (relay transactions that are already in the +mempool; implies relay), relay (relay even in \fB\-blocksonly\fR mode, +and unlimited transaction announcements), mempool (allow +requesting BIP35 mempool contents), download (allow getheaders +during IBD, no disconnect after maxuploadtarget limit), addr +(responses to GETADDR avoid hitting the cache and contain random +records with the most up\-to\-date info). Specify multiple +permissions separated by commas (default: +download,noban,mempool,relay). Can be specified multiple times. +.HP +\fB\-whitelist=\fR<[permissions@]IP address or network> +.IP +Add permission flags to the peers using the given IP address (e.g. +1.2.3.4) or CIDR\-notated network (e.g. 1.2.3.0/24). Uses the same +permissions as \fB\-whitebind\fR. Additional flags "in" and "out" +control whether permissions apply to incoming connections and/or +manual (default: incoming only). Can be specified multiple times. +.PP +Wallet options: +.HP +\fB\-addresstype\fR +.IP +What type of addresses to use ("legacy", "p2sh\-segwit", "bech32", or +"bech32m", default: "bech32") +.HP +\fB\-avoidpartialspends\fR +.IP +Group outputs by address, selecting many (possibly all) or none, instead +of selecting on a per\-output basis. Privacy is improved as +addresses are mostly swept with fewer transactions and outputs +are aggregated in clean change addresses. It may result in higher +fees due to less optimal coin selection caused by this added +limitation and possibly a larger\-than\-necessary number of inputs +being used. Always enabled for wallets with "avoid_reuse" +enabled, otherwise default: 0. +.HP +\fB\-changetype\fR +.IP +What type of change to use ("legacy", "p2sh\-segwit", "bech32", or +"bech32m"). Default is "legacy" when \fB\-addresstype\fR=\fI\,legacy\/\fR, else it +is an implementation detail. +.HP +\fB\-consolidatefeerate=\fR +.IP +The maximum feerate (in BTC/kvB) at which transaction building may use +more inputs than strictly necessary so that the wallet's UTXO +pool can be reduced (default: 0.0001). +.HP +\fB\-disablewallet\fR +.IP +Do not load the wallet and disable wallet RPC calls +.HP +\fB\-discardfee=\fR +.IP +The fee rate (in BTC/kvB) that indicates your tolerance for discarding +change by adding it to the fee (default: 0.0001). Note: An output +is discarded if it is dust at this rate, but we will always +discard up to the dust relay fee and a discard fee above that is +limited by the fee estimate for the longest target +.HP +\fB\-fallbackfee=\fR +.IP +A fee rate (in BTC/kvB) that will be used when fee estimation has +insufficient data. 0 to entirely disable the fallbackfee feature. +(default: 0.00) +.HP +\fB\-keypool=\fR +.IP +Set key pool size to (default: 1000). Warning: Smaller sizes may +increase the risk of losing funds when restoring from an old +backup, if none of the addresses in the original keypool have +been used. +.HP +\fB\-maxapsfee=\fR +.IP +Spend up to this amount in additional (absolute) fees (in BTC) if it +allows the use of partial spend avoidance (default: 0.00) +.HP +\fB\-mintxfee=\fR +.IP +Fee rates (in BTC/kvB) smaller than this are considered zero fee for +transaction creation (default: 0.00001) +.HP +\fB\-paytxfee=\fR +.IP +Fee rate (in BTC/kvB) to add to transactions you send (default: 0.00) +.HP +\fB\-signer=\fR +.IP +External signing tool, see doc/external\-signer.md +.HP +\fB\-spendzeroconfchange\fR +.IP +Spend unconfirmed change when sending transactions (default: 1) +.HP +\fB\-txconfirmtarget=\fR +.IP +If paytxfee is not set, include enough fee so transactions begin +confirmation on average within n blocks (default: 6) +.HP +\fB\-wallet=\fR +.IP +Specify wallet path to load at startup. Can be used multiple times to +load multiple wallets. Path is to a directory containing wallet +data and log files. If the path is not absolute, it is +interpreted relative to . This only loads existing +wallets and does not create new ones. For backwards compatibility +this also accepts names of existing top\-level data files in +. +.HP +\fB\-walletbroadcast\fR +.IP +Make the wallet broadcast transactions (default: 1) +.HP +\fB\-walletdir=\fR +.IP +Specify directory to hold wallets (default: /wallets if it +exists, otherwise ) +.HP +\fB\-walletnotify=\fR +.IP +Execute command when a wallet transaction changes. %s in cmd is replaced +by TxID, %w is replaced by wallet name, %b is replaced by the +hash of the block including the transaction (set to 'unconfirmed' +if the transaction is not included) and %h is replaced by the +block height (\fB\-1\fR if not included). %w is not currently +implemented on windows. On systems where %w is supported, it +should NOT be quoted because this would break shell escaping used +to invoke the command. +.HP +\fB\-walletrbf\fR +.IP +Send transactions with full\-RBF opt\-in enabled (RPC only, default: 1) +.PP +ZeroMQ notification options: +.HP +\fB\-zmqpubhashblock=\fR
+.IP +Enable publish hash block in
+.HP +\fB\-zmqpubhashblockhwm=\fR +.IP +Set publish hash block outbound message high water mark (default: 1000) +.HP +\fB\-zmqpubhashtx=\fR
+.IP +Enable publish hash transaction in
+.HP +\fB\-zmqpubhashtxhwm=\fR +.IP +Set publish hash transaction outbound message high water mark (default: +1000) +.HP +\fB\-zmqpubrawblock=\fR
+.IP +Enable publish raw block in
+.HP +\fB\-zmqpubrawblockhwm=\fR +.IP +Set publish raw block outbound message high water mark (default: 1000) +.HP +\fB\-zmqpubrawtx=\fR
+.IP +Enable publish raw transaction in
+.HP +\fB\-zmqpubrawtxhwm=\fR +.IP +Set publish raw transaction outbound message high water mark (default: +1000) +.HP +\fB\-zmqpubsequence=\fR
+.IP +Enable publish hash block and tx sequence in
+.HP +\fB\-zmqpubsequencehwm=\fR +.IP +Set publish hash sequence message high water mark (default: 1000) +.PP +Debugging/Testing options: +.HP +\fB\-debug=\fR +.IP +Output debug and trace logging (default: \fB\-nodebug\fR, supplying +is optional). If is not supplied or if is 1 +or "all", output all debug logging. If is 0 or "none", +any other categories are ignored. Other valid values for + are: addrman, bench, blockstorage, cmpctblock, coindb, +estimatefee, http, i2p, ipc, leveldb, libevent, mempool, +mempoolrej, net, proxy, prune, qt, rand, reindex, rpc, scan, +selectcoins, tor, txpackages, txreconciliation, validation, +walletdb, zmq. This option can be specified multiple times to +output multiple categories. +.HP +\fB\-debugexclude=\fR +.IP +Exclude debug and trace logging for a category. Can be used in +conjunction with \fB\-debug\fR=\fI\,1\/\fR to output debug and trace logging for +all categories except the specified category. This option can be +specified multiple times to exclude multiple categories. This +takes priority over "\-debug" +.HP +\fB\-help\-debug\fR +.IP +Print help message with debugging options and exit +.HP +\fB\-logips\fR +.IP +Include IP addresses in debug output (default: 0) +.HP +\fB\-loglevelalways\fR +.IP +Always prepend a category and level (default: 0) +.HP +\fB\-logsourcelocations\fR +.IP +Prepend debug output with name of the originating source location +(source file, line number and function name) (default: 0) +.HP +\fB\-logthreadnames\fR +.IP +Prepend debug output with name of the originating thread (default: 0) +.HP +\fB\-logtimestamps\fR +.IP +Prepend debug output with timestamp (default: 1) +.HP +\fB\-maxtxfee=\fR +.IP +Maximum total fees (in BTC) to use in a single wallet transaction; +setting this too low may abort large transactions (default: 0.10) +.HP +\fB\-printtoconsole\fR +.IP +Send trace/debug info to console (default: 1 when no \fB\-daemon\fR. To disable +logging to file, set \fB\-nodebuglogfile\fR) +.HP +\fB\-shrinkdebugfile\fR +.IP +Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) +.HP +\fB\-uacomment=\fR +.IP +Append comment to the user agent string +.PP +Chain selection options: +.HP +\fB\-chain=\fR +.IP +Use the chain (default: main). Allowed values: main, test, +testnet4, signet, regtest +.HP +\fB\-signet\fR +.IP +Use the signet chain. Equivalent to \fB\-chain\fR=\fI\,signet\/\fR. Note that the network +is defined by the \fB\-signetchallenge\fR parameter +.HP +\fB\-signetchallenge\fR +.IP +Blocks must satisfy the given script to be considered valid (only for +signet networks; defaults to the global default signet test +network challenge) +.HP +\fB\-signetseednode\fR +.IP +Specify a seed node for the signet network, in the hostname[:port] +format, e.g. sig.net:1234 (may be used multiple times to specify +multiple seed nodes; defaults to the global default signet test +network seed node(s)) +.HP +\fB\-testnet\fR +.IP +Use the testnet3 chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR. Support for testnet3 +is deprecated and will be removed in an upcoming release. +Consider moving to testnet4 now by using \fB\-testnet4\fR. +.HP +\fB\-testnet4\fR +.IP +Use the testnet4 chain. Equivalent to \fB\-chain\fR=\fI\,testnet4\/\fR. +.PP +Node relay options: +.HP +\fB\-bytespersigop\fR +.IP +Equivalent bytes per sigop in transactions for relay and mining +(default: 20) +.HP +\fB\-datacarrier\fR +.IP +Relay and mine data carrier transactions (default: 1) +.HP +\fB\-datacarriersize\fR +.IP +Relay and mine transactions whose data\-carrying raw scriptPubKey is of +this size or less (default: 83) +.HP +\fB\-minrelaytxfee=\fR +.IP +Fees (in BTC/kvB) smaller than this are considered zero fee for +relaying, mining and transaction creation (default: 0.00001) +.HP +\fB\-permitbaremultisig\fR +.IP +Relay transactions creating non\-P2SH multisig outputs (default: 1) +.HP +\fB\-whitelistforcerelay\fR +.IP +Add 'forcerelay' permission to whitelisted peers with default +permissions. This will relay transactions even if the +transactions were already in the mempool. (default: 0) +.HP +\fB\-whitelistrelay\fR +.IP +Add 'relay' permission to whitelisted peers with default permissions. +This will accept relayed transactions even when not relaying +transactions (default: 1) +.PP +Block creation options: +.HP +\fB\-blockmaxweight=\fR +.IP +Set maximum BIP141 block weight (default: 4000000) +.HP +\fB\-blockmintxfee=\fR +.IP +Set lowest fee rate (in BTC/kvB) for transactions to be included in +block creation. (default: 0.00001) +.HP +\fB\-blockreservedweight=\fR +.IP +Reserve space for the fixed\-size block header plus the largest coinbase +transaction the mining software may add to the block. (default: +8000). +.PP +RPC server options: +.HP +\fB\-rest\fR +.IP +Accept public REST requests (default: 0) +.HP +\fB\-rpcallowip=\fR +.IP +Allow JSON\-RPC connections from specified source. Valid values for +are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. +1.2.3.4/255.255.255.0), a network/CIDR (e.g. 1.2.3.4/24), all +ipv4 (0.0.0.0/0), or all ipv6 (::/0). This option can be +specified multiple times +.HP +\fB\-rpcauth=\fR +.IP +Username and HMAC\-SHA\-256 hashed password for JSON\-RPC connections. The +field comes in the format: :$. A +canonical python script is included in share/rpcauth. The client +then connects normally using the +rpcuser=/rpcpassword= pair of arguments. This +option can be specified multiple times +.HP +\fB\-rpcbind=\fR[:port] +.IP +Bind to given address to listen for JSON\-RPC connections. Do not expose +the RPC server to untrusted networks such as the public internet! +This option is ignored unless \fB\-rpcallowip\fR is also passed. Port is +optional and overrides \fB\-rpcport\fR. Use [host]:port notation for +IPv6. This option can be specified multiple times (default: +127.0.0.1 and ::1 i.e., localhost) +.HP +\fB\-rpccookiefile=\fR +.IP +Location of the auth cookie. Relative paths will be prefixed by a +net\-specific datadir location. (default: data dir) +.HP +\fB\-rpccookieperms=\fR +.IP +Set permissions on the RPC auth cookie file so that it is readable by +[owner|group|all] (default: owner [via umask 0077]) +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcport=\fR +.IP +Listen for JSON\-RPC connections on (default: 8332, testnet3: +18332, testnet4: 48332, signet: 38332, regtest: 18443) +.HP +\fB\-rpcthreads=\fR +.IP +Set the number of threads to service RPC calls (default: 16) +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcwhitelist=\fR +.IP +Set a whitelist to filter incoming RPC calls for a specific user. The +field comes in the format: :,,...,. If multiple whitelists are set for a given user, +they are set\-intersected. See \fB\-rpcwhitelistdefault\fR documentation +for information on default whitelist behavior. +.HP +\fB\-rpcwhitelistdefault\fR +.IP +Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault +is set to 0, if any \fB\-rpcwhitelist\fR is set, the rpc server acts as +if all rpc users are subject to empty\-unless\-otherwise\-specified +whitelists. If rpcwhitelistdefault is set to 1 and no +\fB\-rpcwhitelist\fR is set, rpc server acts as if all rpc users are +subject to empty whitelists. +.HP +\fB\-server\fR +.IP +Accept command line and JSON\-RPC commands +.SH COPYRIGHT +Copyright (C) 2009-2025 The Bitcoin Core developers -This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release. +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or +.SH "SEE ALSO" +bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1) From 21f423939e521aa61b96689b9f8ee61c59abf5eb Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 12 Mar 2025 14:23:01 -0400 Subject: [PATCH 004/314] [examples] generate example bitcoin.conf --- share/examples/bitcoin.conf | 634 +++++++++++++++++++++++++++++++++++- 1 file changed, 633 insertions(+), 1 deletion(-) diff --git a/share/examples/bitcoin.conf b/share/examples/bitcoin.conf index 5bee4bf92e7..5b0003b7233 100644 --- a/share/examples/bitcoin.conf +++ b/share/examples/bitcoin.conf @@ -1 +1,633 @@ -# This is a placeholder file. Please follow the instructions in `contrib/devtools/README.md` to generate a bitcoin.conf file. +## +## bitcoin.conf configuration file. +## Generated by contrib/devtools/gen-bitcoin-conf.sh. +## +## Lines beginning with # are comments. +## All possible configuration options are provided. To use, copy this file +## to your data directory (default or specified by -datadir), uncomment +## options you would like to change, and save the file. +## + + +### Options + + +# Specify additional configuration file, relative to the -datadir path +# (only useable from configuration file, not command line) +#includeconf= + +# Imports blocks from external file on startup +#loadblock= + +# Keep the transaction memory pool below megabytes (default: 300) +#maxmempool= + +# Keep at most unconnectable transactions in memory (default: 100) +#maxorphantx= + +# Do not keep transactions in the mempool longer than hours (default: +# 336) +#mempoolexpiry= + +# Set the number of script verification threads (0 = auto, up to 15, <0 = +# leave that many cores free, default: 0) +#par= + +# Whether to save the mempool on shutdown and load on restart (default: 1) +#persistmempool=1 + +# Whether a mempool.dat file created by -persistmempool or the savemempool +# RPC will be written in the legacy format (version 1) or the +# current format (version 2). This temporary option will be removed +# in the future. (default: 0) +#persistmempoolv1=1 + +# Specify pid file. Relative paths will be prefixed by a net-specific +# datadir location. (default: bitcoind.pid) +#pid= + +# Reduce storage requirements by enabling pruning (deleting) of old +# blocks. This allows the pruneblockchain RPC to be called to +# delete specific blocks and enables automatic pruning of old +# blocks if a target size in MiB is provided. This mode is +# incompatible with -txindex. Warning: Reverting this setting +# requires re-downloading the entire blockchain. (default: 0 = +# disable pruning blocks, 1 = allow manual pruning via RPC, >=550 = +# automatically prune block files to stay under the specified +# target size in MiB) +#prune= + +# If enabled, wipe chain state and block index, and rebuild them from +# blk*.dat files on disk. Also wipe and rebuild other optional +# indexes that are active. If an assumeutxo snapshot was loaded, +# its chainstate will be wiped as well. The snapshot can then be +# reloaded via RPC. +#reindex=1 + +# If enabled, wipe chain state, and rebuild it from blk*.dat files on +# disk. If an assumeutxo snapshot was loaded, its chainstate will +# be wiped as well. The snapshot can then be reloaded via RPC. +#reindex-chainstate=1 + +# Specify path to dynamic settings data file. Can be disabled with +# -nosettings. File is written at runtime and not meant to be +# edited by users (use bitcoin.conf instead for custom settings). +# Relative paths will be prefixed by datadir location. (default: +# settings.json) +#settings= + +# Execute command immediately before beginning shutdown. The need for +# shutdown may be urgent, so be careful not to delay it long (if +# the command doesn't require interaction with the server, consider +# having it fork into the background). +#shutdownnotify= + +# Execute command on startup. +#startupnotify= + +# Maintain a full transaction index, used by the getrawtransaction rpc +# call (default: 0) +#txindex=1 + +# Print version and exit +#version=1 + + +### Connection options + + +# 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 +# 8 at a time and are counted separately from the -maxconnections +# limit. +#addnode= + +# Specify asn mapping used for bucketing of the peers (default: +# ip_asn.map). Relative paths will be prefixed by the net-specific +# datadir location. +#asmap= + +# Default duration (in seconds) of manually configured bans (default: +# 86400) +#bantime= + +# 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:8334=onion, testnet3: 127.0.0.1:18334=onion, +# testnet4: 127.0.0.1:48334=onion, signet: 127.0.0.1:38334=onion, +# regtest: 127.0.0.1:18445=onion) +#bind=[:][=onion] + +# 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) +#cjdnsreachable=1 + +# 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. +#connect= + +# Discover own IP addresses (default: 1 when listening and no -externalip +# or -proxy) +#discover=1 + +# Allow DNS lookups for -addnode, -seednode and -connect (default: 1) +#dns=1 + +# Query for peer addresses via DNS lookup, if low on addresses (default: 1 +# unless -connect used or -maxconnections=0) +#dnsseed=1 + +# Specify your own public address +#externalip= + +# Allow fixed seeds if DNS seeds don't provide peers (default: 1) +#fixedseeds=1 + +# Always query for peer addresses via DNS lookup (default: 0) +#forcednsseed=1 + +# Whether to accept inbound I2P connections (default: 1). Ignored if +# -i2psam is not set. Listening for inbound I2P connections is done +# through the SAM proxy, not by binding to a local address and +# port. +#i2pacceptincoming=1 + +# I2P SAM proxy to reach I2P peers and accept I2P connections (default: +# none) +#i2psam= + +# Accept connections from outside (default: 1 if no -proxy, -connect or +# -maxconnections=0) +#listen=1 + +# Automatically create Tor onion service (default: 1) +#listenonion=1 + +# Maintain at most automatic connections to peers (default: 125). This +# limit does not apply to connections manually added via -addnode +# or the addnode RPC, which have a separate limit of 8. +#maxconnections= + +# Maximum per-connection receive buffer, *1000 bytes (default: 5000) +#maxreceivebuffer= + +# Maximum per-connection memory usage for the send buffer, *1000 bytes +# (default: 1000) +#maxsendbuffer= + +# Tries to keep outbound traffic under the given target per 24h. Limit +# does not apply to peers with 'download' permission or blocks +# created within past week. 0 = no limit (default: 0M). Optional +# suffix units [k|K|m|M|g|G|t|T] (default: M). Lowercase is 1000 +# base while uppercase is 1024 base +#maxuploadtarget= + +# Use PCP or NAT-PMP to map the listening port (default: 0) +#natpmp=1 + +# Enable all P2P network activity (default: 1). Can be changed by the +# setnetworkactive RPC command +#networkactive=1 + +# Use separate SOCKS5 proxy to reach peers via Tor onion services, set +# -noonion to disable (default: -proxy). May be a local file path +# prefixed with 'unix:'. +#onion= + +# Make automatic outbound connections only to network (ipv4, ipv6, +# onion, i2p, cjdns). Inbound and manual connections are not +# affected by this option. It can be specified multiple times to +# allow multiple networks. +#onlynet= + +# Serve compact block filters to peers per BIP 157 (default: 0) +#peerblockfilters=1 + +# Support filtering of blocks and transaction with bloom filters (default: +# 0) +#peerbloomfilters=1 + +# Listen for connections on (default: 8333, testnet3: 18333, +# testnet4: 48333, signet: 38333, regtest: 18444). 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. +#port= + +# Connect through SOCKS5 proxy, set -noproxy to disable (default: +# disabled). May be a local file path prefixed with 'unix:' if the +# proxy supports it. +#proxy= + +# Randomize credentials for every proxy connection. This enables Tor +# stream isolation (default: 1) +#proxyrandomize=1 + +# Connect to a node to retrieve peer addresses, and disconnect. This +# option can be specified multiple times to connect to multiple +# nodes. During startup, seednodes will be tried before dnsseeds. +#seednode= + +# Specify socket connection timeout in milliseconds. If an initial attempt +# to connect is unsuccessful after this amount of time, drop it +# (minimum: 1, default: 5000) +#timeout= + +# Tor control host and port to use if onion listening enabled (default: +# 127.0.0.1:9051). If no port is specified, the default port of +# 9051 will be used. +#torcontrol=: + +# Tor control port password (default: empty) +#torpassword= + +# Support v2 transport (default: 1) +#v2transport=1 + +# Bind to the given address and add permission flags to the peers +# connecting to it. Use [host]:port notation for IPv6. Allowed +# permissions: bloomfilter (allow requesting BIP37 filtered blocks +# and transactions), noban (do not ban for misbehavior; implies +# download), forcerelay (relay transactions that are already in the +# mempool; implies relay), relay (relay even in -blocksonly mode, +# and unlimited transaction announcements), mempool (allow +# requesting BIP35 mempool contents), download (allow getheaders +# during IBD, no disconnect after maxuploadtarget limit), addr +# (responses to GETADDR avoid hitting the cache and contain random +# records with the most up-to-date info). Specify multiple +# permissions separated by commas (default: +# download,noban,mempool,relay). Can be specified multiple times. +#whitebind=<[permissions@]addr> + +# Add permission flags to the peers using the given IP address (e.g. +# 1.2.3.4) or CIDR-notated network (e.g. 1.2.3.0/24). Uses the same +# permissions as -whitebind. Additional flags "in" and "out" +# control whether permissions apply to incoming connections and/or +# manual (default: incoming only). Can be specified multiple times. +#whitelist=<[permissions@]IP address or network> + + +### Wallet options + + +# What type of addresses to use ("legacy", "p2sh-segwit", "bech32", or +# "bech32m", default: "bech32") +#addresstype=1 + +# Group outputs by address, selecting many (possibly all) or none, instead +# of selecting on a per-output basis. Privacy is improved as +# addresses are mostly swept with fewer transactions and outputs +# are aggregated in clean change addresses. It may result in higher +# fees due to less optimal coin selection caused by this added +# limitation and possibly a larger-than-necessary number of inputs +# being used. Always enabled for wallets with "avoid_reuse" +# enabled, otherwise default: 0. +#avoidpartialspends=1 + +# What type of change to use ("legacy", "p2sh-segwit", "bech32", or +# "bech32m"). Default is "legacy" when -addresstype=legacy, else it +# is an implementation detail. +#changetype=1 + +# The maximum feerate (in BTC/kvB) at which transaction building may use +# more inputs than strictly necessary so that the wallet's UTXO +# pool can be reduced (default: 0.0001). +#consolidatefeerate= + +# Do not load the wallet and disable wallet RPC calls +#disablewallet=1 + +# The fee rate (in BTC/kvB) that indicates your tolerance for discarding +# change by adding it to the fee (default: 0.0001). Note: An output +# is discarded if it is dust at this rate, but we will always +# discard up to the dust relay fee and a discard fee above that is +# limited by the fee estimate for the longest target +#discardfee= + +# A fee rate (in BTC/kvB) that will be used when fee estimation has +# insufficient data. 0 to entirely disable the fallbackfee feature. +# (default: 0.00) +#fallbackfee= + +# Set key pool size to (default: 1000). Warning: Smaller sizes may +# increase the risk of losing funds when restoring from an old +# backup, if none of the addresses in the original keypool have +# been used. +#keypool= + +# Spend up to this amount in additional (absolute) fees (in BTC) if it +# allows the use of partial spend avoidance (default: 0.00) +#maxapsfee= + +# Fee rates (in BTC/kvB) smaller than this are considered zero fee for +# transaction creation (default: 0.00001) +#mintxfee= + +# Fee rate (in BTC/kvB) to add to transactions you send (default: 0.00) +#paytxfee= + +# External signing tool, see doc/external-signer.md +#signer= + +# Spend unconfirmed change when sending transactions (default: 1) +#spendzeroconfchange=1 + +# If paytxfee is not set, include enough fee so transactions begin +# confirmation on average within n blocks (default: 6) +#txconfirmtarget= + +# Specify wallet path to load at startup. Can be used multiple times to +# load multiple wallets. Path is to a directory containing wallet +# data and log files. If the path is not absolute, it is +# interpreted relative to . This only loads existing +# wallets and does not create new ones. For backwards compatibility +# this also accepts names of existing top-level data files in +# . +#wallet= + +# Make the wallet broadcast transactions (default: 1) +#walletbroadcast=1 + +# Specify directory to hold wallets (default: /wallets if it +# exists, otherwise ) +#walletdir= + +# Execute command when a wallet transaction changes. %s in cmd is replaced +# by TxID, %w is replaced by wallet name, %b is replaced by the +# hash of the block including the transaction (set to 'unconfirmed' +# if the transaction is not included) and %h is replaced by the +# block height (-1 if not included). %w is not currently +# implemented on windows. On systems where %w is supported, it +# should NOT be quoted because this would break shell escaping used +# to invoke the command. +#walletnotify= + +# Send transactions with full-RBF opt-in enabled (RPC only, default: 1) +#walletrbf=1 + + +### ZeroMQ notification options + + +# Enable publish hash block in
+#zmqpubhashblock=
+ +# Set publish hash block outbound message high water mark (default: 1000) +#zmqpubhashblockhwm= + +# Enable publish hash transaction in
+#zmqpubhashtx=
+ +# Set publish hash transaction outbound message high water mark (default: +# 1000) +#zmqpubhashtxhwm= + +# Enable publish raw block in
+#zmqpubrawblock=
+ +# Set publish raw block outbound message high water mark (default: 1000) +#zmqpubrawblockhwm= + +# Enable publish raw transaction in
+#zmqpubrawtx=
+ +# Set publish raw transaction outbound message high water mark (default: +# 1000) +#zmqpubrawtxhwm= + +# Enable publish hash block and tx sequence in
+#zmqpubsequence=
+ +# Set publish hash sequence message high water mark (default: 1000) +#zmqpubsequencehwm= + + +### Debugging/Testing options + + +# Output debug and trace logging (default: -nodebug, supplying +# is optional). If is not supplied or if is 1 +# or "all", output all debug logging. If is 0 or "none", +# any other categories are ignored. Other valid values for +# are: addrman, bench, blockstorage, cmpctblock, coindb, +# estimatefee, http, i2p, ipc, leveldb, libevent, mempool, +# mempoolrej, net, proxy, prune, qt, rand, reindex, rpc, scan, +# selectcoins, tor, txpackages, txreconciliation, validation, +# walletdb, zmq. This option can be specified multiple times to +# output multiple categories. +#debug= + +# Exclude debug and trace logging for a category. Can be used in +# conjunction with -debug=1 to output debug and trace logging for +# all categories except the specified category. This option can be +# specified multiple times to exclude multiple categories. This +# takes priority over "-debug" +#debugexclude= + +# Print help message with debugging options and exit +#help-debug=1 + +# Include IP addresses in debug output (default: 0) +#logips=1 + +# Always prepend a category and level (default: 0) +#loglevelalways=1 + +# Prepend debug output with name of the originating source location +# (source file, line number and function name) (default: 0) +#logsourcelocations=1 + +# Prepend debug output with name of the originating thread (default: 0) +#logthreadnames=1 + +# Prepend debug output with timestamp (default: 1) +#logtimestamps=1 + +# Maximum total fees (in BTC) to use in a single wallet transaction; +# setting this too low may abort large transactions (default: 0.10) +#maxtxfee= + +# Send trace/debug info to console (default: 1 when no -daemon. To disable +# logging to file, set -nodebuglogfile) +#printtoconsole=1 + +# Shrink debug.log file on client startup (default: 1 when no -debug) +#shrinkdebugfile=1 + +# Append comment to the user agent string +#uacomment= + + +### Chain selection options + + +# Use the chain (default: main). Allowed values: main, test, +# testnet4, signet, regtest +#chain= + +# Use the signet chain. Equivalent to -chain=signet. Note that the network +# is defined by the -signetchallenge parameter +#signet=1 + +# Blocks must satisfy the given script to be considered valid (only for +# signet networks; defaults to the global default signet test +# network challenge) +#signetchallenge=1 + +# Specify a seed node for the signet network, in the hostname[:port] +# format, e.g. sig.net:1234 (may be used multiple times to specify +# multiple seed nodes; defaults to the global default signet test +# network seed node(s)) +#signetseednode=1 + +# Use the testnet3 chain. Equivalent to -chain=test. Support for testnet3 +# is deprecated and will be removed in an upcoming release. +# Consider moving to testnet4 now by using -testnet4. +#testnet=1 + +# Use the testnet4 chain. Equivalent to -chain=testnet4. +#testnet4=1 + + +### Node relay options + + +# Equivalent bytes per sigop in transactions for relay and mining +# (default: 20) +#bytespersigop=1 + +# Relay and mine data carrier transactions (default: 1) +#datacarrier=1 + +# Relay and mine transactions whose data-carrying raw scriptPubKey is of +# this size or less (default: 83) +#datacarriersize=1 + +# Fees (in BTC/kvB) smaller than this are considered zero fee for +# relaying, mining and transaction creation (default: 0.00001) +#minrelaytxfee= + +# Relay transactions creating non-P2SH multisig outputs (default: 1) +#permitbaremultisig=1 + +# Add 'forcerelay' permission to whitelisted peers with default +# permissions. This will relay transactions even if the +# transactions were already in the mempool. (default: 0) +#whitelistforcerelay=1 + +# Add 'relay' permission to whitelisted peers with default permissions. +# This will accept relayed transactions even when not relaying +# transactions (default: 1) +#whitelistrelay=1 + + +### Block creation options + + +# Set maximum BIP141 block weight (default: 4000000) +#blockmaxweight= + +# Set lowest fee rate (in BTC/kvB) for transactions to be included in +# block creation. (default: 0.00001) +#blockmintxfee= + +# Reserve space for the fixed-size block header plus the largest coinbase +# transaction the mining software may add to the block. (default: +# 8000). +#blockreservedweight= + + +### RPC server options + + +# Accept public REST requests (default: 0) +#rest=1 + +# Allow JSON-RPC connections from specified source. Valid values for +# are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. +# 1.2.3.4/255.255.255.0), a network/CIDR (e.g. 1.2.3.4/24), all +# ipv4 (0.0.0.0/0), or all ipv6 (::/0). This option can be +# specified multiple times +#rpcallowip= + +# Username and HMAC-SHA-256 hashed password for JSON-RPC connections. The +# field comes in the format: :$. A +# canonical python script is included in share/rpcauth. The client +# then connects normally using the +# rpcuser=/rpcpassword= pair of arguments. This +# option can be specified multiple times +#rpcauth= + +# Bind to given address to listen for JSON-RPC connections. Do not expose +# the RPC server to untrusted networks such as the public internet! +# This option is ignored unless -rpcallowip is also passed. Port is +# optional and overrides -rpcport. Use [host]:port notation for +# IPv6. This option can be specified multiple times (default: +# 127.0.0.1 and ::1 i.e., localhost) +#rpcbind=[:port] + +# Location of the auth cookie. Relative paths will be prefixed by a +# net-specific datadir location. (default: data dir) +#rpccookiefile= + +# Set permissions on the RPC auth cookie file so that it is readable by +# [owner|group|all] (default: owner [via umask 0077]) +#rpccookieperms= + +# Password for JSON-RPC connections +#rpcpassword= + +# Listen for JSON-RPC connections on (default: 8332, testnet3: +# 18332, testnet4: 48332, signet: 38332, regtest: 18443) +#rpcport= + +# Set the number of threads to service RPC calls (default: 16) +#rpcthreads= + +# Username for JSON-RPC connections +#rpcuser= + +# Set a whitelist to filter incoming RPC calls for a specific user. The +# field comes in the format: :,,...,. If multiple whitelists are set for a given user, +# they are set-intersected. See -rpcwhitelistdefault documentation +# for information on default whitelist behavior. +#rpcwhitelist= + +# Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault +# is set to 0, if any -rpcwhitelist is set, the rpc server acts as +# if all rpc users are subject to empty-unless-otherwise-specified +# whitelists. If rpcwhitelistdefault is set to 1 and no +# -rpcwhitelist is set, rpc server acts as if all rpc users are +# subject to empty whitelists. +#rpcwhitelistdefault=1 + +# Accept command line and JSON-RPC commands +#server=1 + + +# [Sections] +# Most options will apply to all networks. To confine an option to a specific +# network, add it under the relevant section below. +# +# Note: If not specified under a network section, the options addnode, connect, +# port, bind, rpcport, rpcbind, and wallet will only apply to mainnet. + +# Options for mainnet +[main] + +# Options for testnet3 +[test] + +# Options for testnet4 +[testnet4] + +# Options for signet +[signet] + +# Options for regtest +[regtest] From 47e2fa86dc5433852fd9e5050a23de2accfdca8d Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 12 Mar 2025 14:24:08 -0400 Subject: [PATCH 005/314] [doc] release notes link for 29.0 --- doc/release-notes.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/release-notes.md diff --git a/doc/release-notes.md b/doc/release-notes.md new file mode 100644 index 00000000000..c5dc3e0b302 --- /dev/null +++ b/doc/release-notes.md @@ -0,0 +1 @@ +See https://github.com/bitcoin-core/bitcoin-devwiki/wiki/29.0-Release-Notes-draft From 80c5d57bd118b1812c21604224dd316214af879c Mon Sep 17 00:00:00 2001 From: David Gumberg Date: Wed, 12 Mar 2025 14:55:14 -0700 Subject: [PATCH 006/314] contrib: Fix `gen-bitcoin-conf.sh`. In #31118, the format of bitcoind's `--help` output changed slightly in a way that breaks `gen-bitcoin-conf.sh`, modify the script to accomodate the new format, by starting after the line that says "Options:" and strip the `-help` option and its description from the output. Github-Pull: #32049 Rebased-From: a24419f8bed5e1145ce171dbbdad957750585471 --- contrib/devtools/gen-bitcoin-conf.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/devtools/gen-bitcoin-conf.sh b/contrib/devtools/gen-bitcoin-conf.sh index 234318e1a14..d31f5462956 100755 --- a/contrib/devtools/gen-bitcoin-conf.sh +++ b/contrib/devtools/gen-bitcoin-conf.sh @@ -50,7 +50,8 @@ EOF # adding newlines is a bit funky to ensure portability for BSD # see here for more details: https://stackoverflow.com/a/24575385 ${BITCOIND} --help \ - | sed '1,/Print this help message and exit/d' \ + | sed '1,/Options:/d' \ + | sed -E '/^[[:space:]]{2}-help/,/^[[:space:]]*$/d' \ | sed -E 's/^[[:space:]]{2}\-/#/' \ | sed -E 's/^[[:space:]]{7}/# /' \ | sed -E '/[=[:space:]]/!s/#.*$/&=1/' \ From 15ecae31a83ea66985496d2b8f2017cbd7749c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Thu, 20 Feb 2025 16:48:28 +0100 Subject: [PATCH 007/314] fuzz: Always restrict base conversion input lengths They seem to cause timeouts: > Issue 397734700: bitcoin-core:base58check_encode_decode: Timeout in base58check_encode_decode The `encoded_string.empty()` check was corrected here to `decoded.empty()` to make sure the `(0, decoded.size() - 1)` range is always valid. Github-Pull: #31917 Rebased-From: bad1433ef2b5b02ac4b1c6c1d9482c513e5b2192 Co-authored-by: maflcko <6399679+maflcko@users.noreply.github.com> Co-authored-by: marcofleon Co-authored-by: Martin Zumsande --- src/test/fuzz/base_encode_decode.cpp | 35 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/test/fuzz/base_encode_decode.cpp b/src/test/fuzz/base_encode_decode.cpp index 06b249fb8d3..69caac58100 100644 --- a/src/test/fuzz/base_encode_decode.cpp +++ b/src/test/fuzz/base_encode_decode.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -19,42 +20,40 @@ using util::TrimStringView; FUZZ_TARGET(base58_encode_decode) { - FuzzedDataProvider provider(buffer.data(), buffer.size()); - const std::string random_string{provider.ConsumeRandomLengthString(1000)}; - const int max_ret_len{provider.ConsumeIntegralInRange(-1, 1000)}; + FuzzedDataProvider provider{buffer.data(), buffer.size()}; + const auto random_string{provider.ConsumeRandomLengthString(100)}; + const int max_ret_len{provider.ConsumeIntegralInRange(-1, 100)}; // Decode/Encode roundtrip - std::vector decoded; - if (DecodeBase58(random_string, decoded, max_ret_len)) { + if (std::vector decoded; DecodeBase58(random_string, decoded, max_ret_len)) { const auto encoded_string{EncodeBase58(decoded)}; assert(encoded_string == TrimStringView(random_string)); - assert(encoded_string.empty() || !DecodeBase58(encoded_string, decoded, provider.ConsumeIntegralInRange(0, decoded.size() - 1))); + assert(decoded.empty() || !DecodeBase58(encoded_string, decoded, provider.ConsumeIntegralInRange(0, decoded.size() - 1))); } // Encode/Decode roundtrip - const auto encoded{EncodeBase58(buffer)}; + const auto encoded{EncodeBase58(MakeUCharSpan(random_string))}; std::vector roundtrip_decoded; - assert(DecodeBase58(encoded, roundtrip_decoded, buffer.size()) - && std::ranges::equal(roundtrip_decoded, buffer)); + assert(DecodeBase58(encoded, roundtrip_decoded, random_string.size()) + && std::ranges::equal(roundtrip_decoded, MakeUCharSpan(random_string))); } FUZZ_TARGET(base58check_encode_decode) { - FuzzedDataProvider provider(buffer.data(), buffer.size()); - const std::string random_string{provider.ConsumeRandomLengthString(1000)}; - const int max_ret_len{provider.ConsumeIntegralInRange(-1, 1000)}; + FuzzedDataProvider provider{buffer.data(), buffer.size()}; + const auto random_string{provider.ConsumeRandomLengthString(100)}; + const int max_ret_len{provider.ConsumeIntegralInRange(-1, 100)}; // Decode/Encode roundtrip - std::vector decoded; - if (DecodeBase58Check(random_string, decoded, max_ret_len)) { + if (std::vector decoded; DecodeBase58Check(random_string, decoded, max_ret_len)) { const auto encoded_string{EncodeBase58Check(decoded)}; assert(encoded_string == TrimStringView(random_string)); - assert(encoded_string.empty() || !DecodeBase58Check(encoded_string, decoded, provider.ConsumeIntegralInRange(0, decoded.size() - 1))); + assert(decoded.empty() || !DecodeBase58Check(encoded_string, decoded, provider.ConsumeIntegralInRange(0, decoded.size() - 1))); } // Encode/Decode roundtrip - const auto encoded{EncodeBase58Check(buffer)}; + const auto encoded{EncodeBase58Check(MakeUCharSpan(random_string))}; std::vector roundtrip_decoded; - assert(DecodeBase58Check(encoded, roundtrip_decoded, buffer.size()) - && std::ranges::equal(roundtrip_decoded, buffer)); + assert(DecodeBase58Check(encoded, roundtrip_decoded, random_string.size()) + && std::ranges::equal(roundtrip_decoded, MakeUCharSpan(random_string))); } FUZZ_TARGET(base32_encode_decode) From 458655bca8eddd4d913958c579a46a6fca23cbf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Thu, 20 Feb 2025 16:57:26 +0100 Subject: [PATCH 008/314] fuzz: make sure DecodeBase58(Check) is called with valid values more often In Base58 fuzz the two roundtrips are merged now, the new `decode_input` switches between a completely random input and a valid encoded one, to make sure the decoding passes more often. The `max_ret_len` can also exceed the original length now and is being validated more thoroughly. Github-Pull: #31917 Rebased-From: d5537c18a9034647ba4c9ed4008abd7fee33989e Co-authored-by: maflcko <6399679+maflcko@users.noreply.github.com> Co-authored-by: marcofleon --- src/test/fuzz/base_encode_decode.cpp | 40 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/test/fuzz/base_encode_decode.cpp b/src/test/fuzz/base_encode_decode.cpp index 69caac58100..2ffcbdf7207 100644 --- a/src/test/fuzz/base_encode_decode.cpp +++ b/src/test/fuzz/base_encode_decode.cpp @@ -22,38 +22,38 @@ FUZZ_TARGET(base58_encode_decode) { FuzzedDataProvider provider{buffer.data(), buffer.size()}; const auto random_string{provider.ConsumeRandomLengthString(100)}; - const int max_ret_len{provider.ConsumeIntegralInRange(-1, 100)}; - // Decode/Encode roundtrip - if (std::vector decoded; DecodeBase58(random_string, decoded, max_ret_len)) { + const auto encoded{EncodeBase58(MakeUCharSpan(random_string))}; + const auto decode_input{provider.ConsumeBool() ? random_string : encoded}; + const int max_ret_len{provider.ConsumeIntegralInRange(-1, decode_input.size() + 1)}; + if (std::vector decoded; DecodeBase58(decode_input, decoded, max_ret_len)) { const auto encoded_string{EncodeBase58(decoded)}; - assert(encoded_string == TrimStringView(random_string)); - assert(decoded.empty() || !DecodeBase58(encoded_string, decoded, provider.ConsumeIntegralInRange(0, decoded.size() - 1))); + assert(encoded_string == TrimStringView(decode_input)); + if (decoded.size() > 0) { + assert(max_ret_len > 0); + assert(decoded.size() <= static_cast(max_ret_len)); + assert(!DecodeBase58(encoded_string, decoded, provider.ConsumeIntegralInRange(0, decoded.size() - 1))); + } } - // Encode/Decode roundtrip - const auto encoded{EncodeBase58(MakeUCharSpan(random_string))}; - std::vector roundtrip_decoded; - assert(DecodeBase58(encoded, roundtrip_decoded, random_string.size()) - && std::ranges::equal(roundtrip_decoded, MakeUCharSpan(random_string))); } FUZZ_TARGET(base58check_encode_decode) { FuzzedDataProvider provider{buffer.data(), buffer.size()}; const auto random_string{provider.ConsumeRandomLengthString(100)}; - const int max_ret_len{provider.ConsumeIntegralInRange(-1, 100)}; - // Decode/Encode roundtrip - if (std::vector decoded; DecodeBase58Check(random_string, decoded, max_ret_len)) { + const auto encoded{EncodeBase58Check(MakeUCharSpan(random_string))}; + const auto decode_input{provider.ConsumeBool() ? random_string : encoded}; + const int max_ret_len{provider.ConsumeIntegralInRange(-1, decode_input.size() + 1)}; + if (std::vector decoded; DecodeBase58Check(decode_input, decoded, max_ret_len)) { const auto encoded_string{EncodeBase58Check(decoded)}; - assert(encoded_string == TrimStringView(random_string)); - assert(decoded.empty() || !DecodeBase58Check(encoded_string, decoded, provider.ConsumeIntegralInRange(0, decoded.size() - 1))); + assert(encoded_string == TrimStringView(decode_input)); + if (decoded.size() > 0) { + assert(max_ret_len > 0); + assert(decoded.size() <= static_cast(max_ret_len)); + assert(!DecodeBase58Check(encoded_string, decoded, provider.ConsumeIntegralInRange(0, decoded.size() - 1))); + } } - // Encode/Decode roundtrip - const auto encoded{EncodeBase58Check(MakeUCharSpan(random_string))}; - std::vector roundtrip_decoded; - assert(DecodeBase58Check(encoded, roundtrip_decoded, random_string.size()) - && std::ranges::equal(roundtrip_decoded, MakeUCharSpan(random_string))); } FUZZ_TARGET(base32_encode_decode) From 5ebcb59fdb1270edac6b878d7bd97dd1f077aa06 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Thu, 13 Mar 2025 17:58:59 -0400 Subject: [PATCH 009/314] test: fix intermittent failure in p2p_orphan_handling.py If we bump the mocktime before the node has successfully disconnected the peer, the requests for both parents could be spread over two GETDATAS, which would make the test fail. Github-Pull: #32063 Rebased-From: 02942056fd861581503a8a35a06dcf22d4ba1473 --- test/functional/p2p_orphan_handling.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functional/p2p_orphan_handling.py b/test/functional/p2p_orphan_handling.py index 370caad8800..d74a866ae5a 100755 --- a/test/functional/p2p_orphan_handling.py +++ b/test/functional/p2p_orphan_handling.py @@ -788,6 +788,7 @@ def test_parents_change(self): # Disconnect peer1. peer2 should become the new candidate for orphan resolution. peer1.peer_disconnect() + self.wait_until(lambda: node.num_test_p2p_connections() == 1) node.bumpmocktime(TXREQUEST_TIME_SKIP) self.wait_until(lambda: len(node.getorphantxs(verbosity=2)[0]["from"]) == 1) # Both parents should be requested, now that they are both missing. From 7ff0b02161a1687b8bee6af0ff93ec65bbfc6cf2 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Thu, 13 Mar 2025 17:41:33 -0700 Subject: [PATCH 010/314] build: Remove manpages when making MacOS app Github-Pull: #32064 Rebased-From: 80b5e7f2cb7fbfbd724e1f52b00c0e72b79a200b --- cmake/module/Maintenance.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/module/Maintenance.cmake b/cmake/module/Maintenance.cmake index a1ae7c9e8f6..59e26d1bc11 100644 --- a/cmake/module/Maintenance.cmake +++ b/cmake/module/Maintenance.cmake @@ -83,6 +83,7 @@ function(add_macos_deploy_target) COMMAND ${CMAKE_COMMAND} --install ${PROJECT_BINARY_DIR} --config $ --component bitcoin-qt --prefix ${macos_app}/Contents/MacOS --strip COMMAND ${CMAKE_COMMAND} -E rename ${macos_app}/Contents/MacOS/bin/$ ${macos_app}/Contents/MacOS/Bitcoin-Qt COMMAND ${CMAKE_COMMAND} -E rm -rf ${macos_app}/Contents/MacOS/bin + COMMAND ${CMAKE_COMMAND} -E rm -rf ${macos_app}/Contents/MacOS/share VERBATIM ) From 4e438d326ea55ac0f98f89e41e69b56354e801e7 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Fri, 14 Mar 2025 16:19:45 +0100 Subject: [PATCH 011/314] build: use make < 3.82 syntax for define directive From the GNU make 3.82 release announcement: * The 'define' make directive now allows a variable assignment operator after the variable name, to allow for simple, conditional, or appending multi-line variable assignment. macOS ships with 3.81. This caused the multiprocess config options to be ignored. Fixes #32068 Github-Pull: #32070 Rebased-From: 9157d9e449870851ef455e077249ac46fc2df24c Co-authored-by: Ryan Ofsky --- depends/packages/capnp.mk | 2 +- depends/packages/libmultiprocess.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/capnp.mk b/depends/packages/capnp.mk index 7f41d3b5a4e..542bf126297 100644 --- a/depends/packages/capnp.mk +++ b/depends/packages/capnp.mk @@ -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 diff --git a/depends/packages/libmultiprocess.mk b/depends/packages/libmultiprocess.mk index afbd315e388..47064a9bb6c 100644 --- a/depends/packages/libmultiprocess.mk +++ b/depends/packages/libmultiprocess.mk @@ -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++" From a4c30bd00a0ec977a1518416cdf7f0a24868a9f2 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Sun, 16 Mar 2025 17:14:22 +0100 Subject: [PATCH 012/314] qt: doc: adapt outdated binary paths to CMake changes Github-Pull: bitcoin-core/gui#858 Rebased-From: 7ebc458a8cb994bc3c0c129da61353968d955bc2 --- src/qt/README.md | 2 +- src/qt/test/wallettests.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/README.md b/src/qt/README.md index 1fcac5414f5..4a662b2a12d 100644 --- a/src/qt/README.md +++ b/src/qt/README.md @@ -120,5 +120,5 @@ sudo apt-get install qtcreator - Under `Debuggers`: select `"GDB"` as debugger 8. While in the `Projects` tab, ensure that you have the `bitcoin-qt` executable specified under `Run` - - If the executable is not specified: click `"Choose..."`, navigate to `src/qt`, and select `bitcoin-qt` + - If the executable is not specified: click `"Choose..."`, navigate to `build/bin`, and select `bitcoin-qt` 9. You're all set! Start developing, building, and debugging the Bitcoin Core GUI diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index 98dfe12f084..816d47fed46 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -268,9 +268,9 @@ struct MiniGUI { // // This also requires overriding the default minimal Qt platform: // -// QT_QPA_PLATFORM=xcb src/qt/test/test_bitcoin-qt # Linux -// QT_QPA_PLATFORM=windows src/qt/test/test_bitcoin-qt # Windows -// QT_QPA_PLATFORM=cocoa src/qt/test/test_bitcoin-qt # macOS +// QT_QPA_PLATFORM=xcb build/bin/test_bitcoin-qt # Linux +// QT_QPA_PLATFORM=windows build/bin/test_bitcoin-qt # Windows +// QT_QPA_PLATFORM=cocoa build/bin/test_bitcoin-qt # macOS void TestGUI(interfaces::Node& node, const std::shared_ptr& wallet) { // Create widgets for sending coins and listing transactions. From 472d582bfec4dcdecb5f4d9bbbe41ea7961ca62b Mon Sep 17 00:00:00 2001 From: glozow Date: Sun, 16 Mar 2025 22:07:46 -0400 Subject: [PATCH 013/314] [build] bump to 29.0rc2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ad29249e95..8b7e6631348 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 0) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 1) +set(CLIENT_VERSION_RC 2) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From 8082f88d1a434b3ba1018c6592affe759d53df48 Mon Sep 17 00:00:00 2001 From: glozow Date: Sun, 16 Mar 2025 22:09:03 -0400 Subject: [PATCH 014/314] [doc] update man pages for 29.0rc2 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 2eb89ffa085..94d06025c3a 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "March 2025" "bitcoin-cli v29.0.0rc1" "User Commands" +.TH BITCOIN-CLI "1" "March 2025" "bitcoin-cli v29.0.0rc2" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.0.0rc1 +bitcoin-cli \- manual page for bitcoin-cli v29.0.0rc2 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.0.0rc1 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.0.0rc1 +Bitcoin Core RPC client version v29.0.0rc2 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 20b7b96e3e3..58640975b8c 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "March 2025" "bitcoin-qt v29.0.0rc1" "User Commands" +.TH BITCOIN-QT "1" "March 2025" "bitcoin-qt v29.0.0rc2" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.0.0rc1 +bitcoin-qt \- manual page for bitcoin-qt v29.0.0rc2 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.0.0rc1 +Bitcoin Core version v29.0.0rc2 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index b493f916b0f..7d4f7de5a39 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "March 2025" "bitcoin-tx v29.0.0rc1" "User Commands" +.TH BITCOIN-TX "1" "March 2025" "bitcoin-tx v29.0.0rc2" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.0.0rc1 +bitcoin-tx \- manual page for bitcoin-tx v29.0.0rc2 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.0.0rc1 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.0.0rc1 +Bitcoin Core bitcoin\-tx utility version v29.0.0rc2 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index 74cf2329ed1..44ff8e860a6 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "March 2025" "bitcoin-util v29.0.0rc1" "User Commands" +.TH BITCOIN-UTIL "1" "March 2025" "bitcoin-util v29.0.0rc2" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.0.0rc1 +bitcoin-util \- manual page for bitcoin-util v29.0.0rc2 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.0.0rc1 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.0.0rc1 +Bitcoin Core bitcoin\-util utility version v29.0.0rc2 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index dbf30100705..b41d5e965e0 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "March 2025" "bitcoin-wallet v29.0.0rc1" "User Commands" +.TH BITCOIN-WALLET "1" "March 2025" "bitcoin-wallet v29.0.0rc2" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.0.0rc1 +bitcoin-wallet \- manual page for bitcoin-wallet v29.0.0rc2 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.0.0rc1 +Bitcoin Core bitcoin\-wallet utility version v29.0.0rc2 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 865a59e87cb..b5993a052ad 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "March 2025" "bitcoind v29.0.0rc1" "User Commands" +.TH BITCOIND "1" "March 2025" "bitcoind v29.0.0rc2" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.0.0rc1 +bitcoind \- manual page for bitcoind v29.0.0rc2 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.0.0rc1 +Bitcoin Core daemon version v29.0.0rc2 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From 74df31cb0bdef9cce31ae62ed71a1e386cba0274 Mon Sep 17 00:00:00 2001 From: glozow Date: Thu, 13 Mar 2025 17:04:10 -0400 Subject: [PATCH 015/314] [doc] update example bitcoin.conf with missing options --- share/examples/bitcoin.conf | 79 +++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/share/examples/bitcoin.conf b/share/examples/bitcoin.conf index 5b0003b7233..d3999ecb4ac 100644 --- a/share/examples/bitcoin.conf +++ b/share/examples/bitcoin.conf @@ -12,6 +12,82 @@ ### Options +# Execute command when an alert is raised (%s in cmd is replaced by +# message) +#alertnotify= + +# For backwards compatibility, treat an unused bitcoin.conf file in the +# datadir as a warning, not an error. +#allowignoredconf=1 + +# If this block is in the chain assume that it and its ancestors are valid +# and potentially skip their script verification (0 to verify all, +# default: +# 00000000000000000001b658dd1120e82e66d2790811f89ede9742ada3ed6d77, +# testnet3: +# 00000000000003fc7967410ba2d0a8a8d50daedc318d43e8baf1a9782c236a57, +# testnet4: +# 0000000000003ed4f08dbdf6f7d6b271a6bcffce25675cb40aa9fa43179a89f3, +# signet: +# 000000895a110f46e59eb82bbc5bfb67fa314656009c295509c21b4999f5180a) +#assumevalid= + +# Maintain an index of compact filters by block (default: 0, values: +# basic). If is not supplied or if = 1, indexes for +# all known types are enabled. +#blockfilterindex= + +# Execute command when the best block changes (%s in cmd is replaced by +# block hash) +#blocknotify= + +# Extra transactions to keep in memory for compact block reconstructions +# (default: 100) +#blockreconstructionextratxn= + +# Specify directory to hold blocks subdirectory for *.dat files (default: +# ) +#blocksdir= + +# Whether to reject transactions from network peers. Disables automatic +# broadcast and rebroadcast of transactions, unless the source peer +# has the 'forcerelay' permission. RPC transactions are not +# affected. (default: 0) +#blocksonly=1 + +# Whether an XOR-key applies to blocksdir *.dat files. The created XOR-key +# will be zeros for an existing blocksdir or when `-blocksxor=0` is +# set, and random for a freshly initialized blocksdir. (default: 1) +#blocksxor=1 + +# Maintain coinstats index used by the gettxoutsetinfo RPC (default: 0) +#coinstatsindex=1 + +# Specify path to read-only configuration file. Relative paths will be +# prefixed by datadir location (only useable from command line, not +# configuration file) (default: bitcoin.conf) +#conf= + +# Run in the background as a daemon and accept commands (default: 0) +#daemon=1 + +# Wait for initialization to be finished before exiting. This implies +# -daemon (default: 0) +#daemonwait=1 + +# Specify data directory +#datadir= + +# Maximum database cache size MiB (minimum 4, default: 450). Make sure +# you have enough RAM. In addition, unused memory allocated to the +# mempool is shared with this cache (see -maxmempool). +#dbcache= + +# Specify location of debug log file (default: debug.log). Relative paths +# will be prefixed by a net-specific datadir location. Pass +# -nodebuglogfile to disable writing the log to a file. +#debuglogfile= + # Specify additional configuration file, relative to the -datadir path # (only useable from configuration file, not command line) #includeconf= @@ -428,9 +504,6 @@ # takes priority over "-debug" #debugexclude= -# Print help message with debugging options and exit -#help-debug=1 - # Include IP addresses in debug output (default: 0) #logips=1 From a3060483fa2ecc4696d1214dfe6030195c572df0 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Sat, 15 Mar 2025 16:07:07 +0100 Subject: [PATCH 016/314] test: avoid disk space warning for non-regtest feature_config_args.py incorrectly assumed that its testnet4 node would not log a disk space warning. 0683b8ebf33386d5c05140df89df10b1853d7c7e increased m_assumed_blockchain_size on testnet4 from 1 to 11 GiB which triggers this bug on more systems, e.g. a RAM disk. Prevent the warning by setting -prune for these nodes. Fix the same issue in feature_signet.py Github-Pull: #32057 Rebased-From: 20fe41e9e83d510fd467f5a999d55a614b16ef89 --- test/functional/feature_config_args.py | 20 ++++++-------------- test/functional/feature_signet.py | 6 ++++-- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index e8fc1aca46c..c5e3c33b14d 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -24,6 +24,9 @@ def add_options(self, parser): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 1 + # Prune to prevent disk space warning on CI systems with limited space, + # when using networks other than regtest. + self.extra_args = [["-prune=550"]] self.supports_cli = False self.wallet_names = [] self.disable_autoconnect = False @@ -471,32 +474,21 @@ def test_testnet3_deprecation_msg(self): self.log.info("Test testnet3 deprecation warning") t3_warning_log = "Warning: Support for testnet3 is deprecated and will be removed in an upcoming release. Consider switching to testnet4." - def warning_msg(node, approx_size): - return f'Warning: Disk space for "{node.datadir_path / node.chain / "blocks" }" may not accommodate the block files. Approximately {approx_size} GB of data will be stored in this directory.' - - # Testnet3 node will log the warning + self.log.debug("Testnet3 node will log the deprecation warning") self.nodes[0].chain = 'testnet3' self.nodes[0].replace_in_config([('regtest=', 'testnet='), ('[regtest]', '[test]')]) with self.nodes[0].assert_debug_log([t3_warning_log]): self.start_node(0) - # Some CI environments will have limited space and some others won't - # so we need to handle both cases as a valid result. - self.nodes[0].stderr.seek(0) - err = self.nodes[0].stdout.read() - self.nodes[0].stderr.seek(0) - self.nodes[0].stderr.truncate() - if err != b'' and err != warning_msg(self.nodes[0], 42): - raise AssertionError("Unexpected stderr after shutdown of Testnet3 node") self.stop_node(0) - # Testnet4 node will not log the warning + self.log.debug("Testnet4 node will not log the deprecation warning") self.nodes[0].chain = 'testnet4' self.nodes[0].replace_in_config([('testnet=', 'testnet4='), ('[test]', '[testnet4]')]) with self.nodes[0].assert_debug_log([], unexpected_msgs=[t3_warning_log]): self.start_node(0) self.stop_node(0) - # Reset to regtest + self.log.debug("Reset to regtest") self.nodes[0].chain = 'regtest' self.nodes[0].replace_in_config([('testnet4=', 'regtest='), ('[testnet4]', '[regtest]')]) diff --git a/test/functional/feature_signet.py b/test/functional/feature_signet.py index 63091b3ee87..02e37f0fdd3 100755 --- a/test/functional/feature_signet.py +++ b/test/functional/feature_signet.py @@ -26,12 +26,14 @@ class SignetParams: def __init__(self, challenge=None): + # Prune to prevent disk space warning on CI systems with limited space, + # when using networks other than regtest. if challenge is None: self.challenge = SIGNET_DEFAULT_CHALLENGE - self.shared_args = [] + self.shared_args = ["-prune=550"] else: self.challenge = challenge - self.shared_args = [f"-signetchallenge={challenge}"] + self.shared_args = ["-prune=550", f"-signetchallenge={challenge}"] class SignetBasicTest(BitcoinTestFramework): def set_test_params(self): From 288163ea0fe1a69d8dabbc5b3d2877cc8f9b1c43 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Sat, 22 Mar 2025 07:36:41 +0100 Subject: [PATCH 017/314] fuzz: Fix off-by-one in package_rbf target Github-Pull: #32122 Rebased-From: fa5674c264d91eb3a99fa74ace8a1b6be113c0a8 --- src/test/fuzz/rbf.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/test/fuzz/rbf.cpp b/src/test/fuzz/rbf.cpp index 3e5b361186a..db8682e27c4 100644 --- a/src/test/fuzz/rbf.cpp +++ b/src/test/fuzz/rbf.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022 The Bitcoin Core developers +// Copyright (c) 2020-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. @@ -108,7 +108,7 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) // Add a bunch of parent-child pairs to the mempool, and remember them. std::vector mempool_txs; - size_t iter{0}; + uint32_t iter{0}; // Keep track of the total vsize of CTxMemPoolEntry's being added to the mempool to avoid overflow // Add replacement_vsize since this is added to new diagram during RBF check @@ -116,9 +116,8 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) if (!replacement_tx) { return; } - assert(iter <= g_outpoints.size()); replacement_tx->vin.resize(1); - replacement_tx->vin[0].prevout = g_outpoints[iter++]; + replacement_tx->vin[0].prevout = g_outpoints.at(iter++); CTransaction replacement_tx_final{*replacement_tx}; auto replacement_entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, replacement_tx_final); int32_t replacement_vsize = replacement_entry.GetTxSize(); @@ -126,13 +125,13 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) LOCK2(cs_main, pool.cs); - LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), NUM_ITERS) - { + while (fuzzed_data_provider.ConsumeBool()) { + if (iter >= NUM_ITERS) break; + // Make sure txns only have one input, and that a unique input is given to avoid circular references CMutableTransaction parent; - assert(iter <= g_outpoints.size()); parent.vin.resize(1); - parent.vin[0].prevout = g_outpoints[iter++]; + parent.vin[0].prevout = g_outpoints.at(iter++); parent.vout.emplace_back(0, CScript()); mempool_txs.emplace_back(parent); From 7bc7af995102c6b360f61a389060e712de79f4ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Tue, 25 Mar 2025 19:22:23 +0100 Subject: [PATCH 018/314] fuzz: extract unsequenced operations with side-effects https://github.com/bitcoin/bitcoin/pull/30746#discussion_r1817851827 introduced an unsequenced operations with side-effects - which is undefined behavior, i.e. the right hand side can be evaluated before the left hand side, which happens to mutate it. Tried: ``` clang++ --analyze -std=c++20 -I./src -I./src/test -I./src/test/fuzz src/test/fuzz/base_encode_decode.cpp src/psbt.cpp ``` but it didn't warn about UB. Grepped for similar ones, but could find any other one in the codebase: > grep -rnE --include='*.cpp' --include='*.h' '\b(\w+)\(([^)]*\b(\w+)\b[^)]*)\)\s*==\s*\3\.' . ``` ./src/test/arith_uint256_tests.cpp:373: BOOST_CHECK(R1L.GetHex() == R1L.ToString()); ./src/test/arith_uint256_tests.cpp:374: BOOST_CHECK(R2L.GetHex() == R2L.ToString()); ./src/test/arith_uint256_tests.cpp:375: BOOST_CHECK(OneL.GetHex() == OneL.ToString()); ./src/test/arith_uint256_tests.cpp:376: BOOST_CHECK(MaxL.GetHex() == MaxL.ToString()); ./src/test/fuzz/cluster_linearize.cpp:565: assert(depgraph.FeeRate(best_anc.transactions) == best_anc.feerate); ./src/test/fuzz/cluster_linearize.cpp:646: assert(depgraph.FeeRate(found.transactions) == found.feerate); ./src/test/fuzz/cluster_linearize.cpp:765: assert(depgraph.FeeRate(chunk_info.transactions) == chunk_info.feerate); ./src/test/fuzz/base_encode_decode.cpp:95: assert(DecodeBase64PSBT(psbt, random_string, error) == error.empty()); ./src/test/fuzz/key.cpp:102: assert(pubkey.data() == pubkey.begin()); ./src/test/skiplist_tests.cpp:42: BOOST_CHECK(vIndex[from].GetAncestor(0) == vIndex.data()); ./src/script/signingprovider.cpp:535: ComputeTapbranchHash(node.sub[1]->hash, node.sub[1]->hash) == node.hash) { ./src/pubkey.h:78: return vch.size() > 0 && GetLen(vch[0]) == vch.size(); ./src/cluster_linearize.h:881: Assume(elem.inc.feerate.IsEmpty() == elem.pot_feerate.IsEmpty()); ``` Hodlinator deduced the UB on Windows in https://github.com/bitcoin/bitcoin/issues/32135#issuecomment-2751723855 Github-Pull: #32141 Rebased-From: b1de59e8965354fff5a149bc0fe61ed0704aea7a Co-authored-by: Hodlinator <172445034+hodlinator@users.noreply.github.com> --- src/test/fuzz/base_encode_decode.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/fuzz/base_encode_decode.cpp b/src/test/fuzz/base_encode_decode.cpp index 2ffcbdf7207..45088187178 100644 --- a/src/test/fuzz/base_encode_decode.cpp +++ b/src/test/fuzz/base_encode_decode.cpp @@ -92,5 +92,6 @@ FUZZ_TARGET(psbt_base64_decode) PartiallySignedTransaction psbt; std::string error; - assert(DecodeBase64PSBT(psbt, random_string, error) == error.empty()); + const bool ok{DecodeBase64PSBT(psbt, random_string, error)}; + assert(ok == error.empty()); } From 477345207b895038a07d8ecb472d3c95b033dcc1 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:55:48 +0000 Subject: [PATCH 019/314] cmake: Add `NO_CACHE_IF_FAILED` option for checking linker flags Use it for checking `-fsanitize`. This change improves the user experience when the configuration step fails due to a missing library. Now, there is no need to manually clean the CMake cache after installing the required library. Github-Pull: #32027 Rebased-From: 52ac17757eed5056d03a6861bcc24ee864c17385 --- CMakeLists.txt | 1 + cmake/module/TryAppendLinkerFlag.cmake | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b7e6631348..06f88975ee9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -376,6 +376,7 @@ if(SANITIZERS) int main() { return 0; } " RESULT_VAR linker_supports_sanitizers + NO_CACHE_IF_FAILED ) if(NOT linker_supports_sanitizers) message(FATAL_ERROR "Linker did not accept requested flags, you are missing required libraries.") diff --git a/cmake/module/TryAppendLinkerFlag.cmake b/cmake/module/TryAppendLinkerFlag.cmake index be41a2e1cc2..fe7c2bce51e 100644 --- a/cmake/module/TryAppendLinkerFlag.cmake +++ b/cmake/module/TryAppendLinkerFlag.cmake @@ -20,7 +20,7 @@ In configuration output, this function prints a string by the following pattern: function(try_append_linker_flag flag) cmake_parse_arguments(PARSE_ARGV 1 TALF # prefix - "" # options + "NO_CACHE_IF_FAILED" # options "TARGET;VAR;SOURCE;RESULT_VAR" # one_value_keywords "IF_CHECK_PASSED" # multi_value_keywords ) @@ -68,6 +68,10 @@ function(try_append_linker_flag flag) if(DEFINED TALF_RESULT_VAR) set(${TALF_RESULT_VAR} "${${result}}" PARENT_SCOPE) endif() + + if(NOT ${result} AND TALF_NO_CACHE_IF_FAILED) + unset(${result} CACHE) + endif() endfunction() if(MSVC) From c0756b758fc1a458f18ccfb01127769ed39d744e Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 3 Feb 2025 12:20:31 +0000 Subject: [PATCH 020/314] depends: set CMAKE_*_COMPILER_TARGET in toolchain According to the CMake docs, this is the correct way to setup a toolchain file for cross-compilation using Clang. See https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-using-clang Internally it looks like CMake will only take this variable into account if it detects the compiler to be Clang, so this shouldn't effect other builds, but in the case of our Apple cross builds, we'd end up with a duplicated `--target=arm64-apple-darwin` on the compiler line, given we are already setting `--target` for Darwin builds. Would fix #31748. Github-Pull: #31849 Rebased-From: 963355037fe78eb4fbdda8631ac05a7b07fcec8c --- depends/Makefile | 1 + depends/toolchain.cmake.in | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/depends/Makefile b/depends/Makefile index 25c86467394..3dbd69221aa 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -206,6 +206,7 @@ endif $(host_prefix)/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_$(final_build_id) @mkdir -p $(@D) sed -e 's|@depends_crosscompiling@|$(crosscompiling)|' \ + -e 's|@host@|$(host)|' \ -e 's|@host_system_name@|$($(host_os)_cmake_system_name)|' \ -e 's|@host_system_version@|$($(host_os)_cmake_system_version)|' \ -e 's|@host_arch@|$(host_arch)|' \ diff --git a/depends/toolchain.cmake.in b/depends/toolchain.cmake.in index 89a6e369690..65036d07a9e 100644 --- a/depends/toolchain.cmake.in +++ b/depends/toolchain.cmake.in @@ -13,6 +13,10 @@ if(@depends_crosscompiling@) set(CMAKE_SYSTEM_NAME @host_system_name@) set(CMAKE_SYSTEM_VERSION @host_system_version@) set(CMAKE_SYSTEM_PROCESSOR @host_arch@) + + set(CMAKE_C_COMPILER_TARGET @host@) + set(CMAKE_CXX_COMPILER_TARGET @host@) + set(CMAKE_OBJCXX_COMPILER_TARGET @host@) endif() if(NOT DEFINED CMAKE_C_FLAGS_INIT) From 7c05ef567328031641b7197b30508d0989bd15a7 Mon Sep 17 00:00:00 2001 From: glozow Date: Fri, 28 Mar 2025 14:37:09 -0400 Subject: [PATCH 021/314] [build] bump to 29.0rc3 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06f88975ee9..a5e3670ba40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 0) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 2) +set(CLIENT_VERSION_RC 3) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From f80ab9a5d8cd5418655fe1a6f01c77926e2cc2e5 Mon Sep 17 00:00:00 2001 From: glozow Date: Fri, 28 Mar 2025 14:56:29 -0400 Subject: [PATCH 022/314] [doc] update man pages for 29.0rc3 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 94d06025c3a..d4095c84780 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "March 2025" "bitcoin-cli v29.0.0rc2" "User Commands" +.TH BITCOIN-CLI "1" "March 2025" "bitcoin-cli v29.0.0rc3" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.0.0rc2 +bitcoin-cli \- manual page for bitcoin-cli v29.0.0rc3 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.0.0rc2 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.0.0rc2 +Bitcoin Core RPC client version v29.0.0rc3 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 58640975b8c..1e49f6925d0 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "March 2025" "bitcoin-qt v29.0.0rc2" "User Commands" +.TH BITCOIN-QT "1" "March 2025" "bitcoin-qt v29.0.0rc3" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.0.0rc2 +bitcoin-qt \- manual page for bitcoin-qt v29.0.0rc3 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.0.0rc2 +Bitcoin Core version v29.0.0rc3 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 7d4f7de5a39..0f5b79854fb 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "March 2025" "bitcoin-tx v29.0.0rc2" "User Commands" +.TH BITCOIN-TX "1" "March 2025" "bitcoin-tx v29.0.0rc3" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.0.0rc2 +bitcoin-tx \- manual page for bitcoin-tx v29.0.0rc3 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.0.0rc2 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.0.0rc2 +Bitcoin Core bitcoin\-tx utility version v29.0.0rc3 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index 44ff8e860a6..9c7585c89b6 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "March 2025" "bitcoin-util v29.0.0rc2" "User Commands" +.TH BITCOIN-UTIL "1" "March 2025" "bitcoin-util v29.0.0rc3" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.0.0rc2 +bitcoin-util \- manual page for bitcoin-util v29.0.0rc3 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.0.0rc2 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.0.0rc2 +Bitcoin Core bitcoin\-util utility version v29.0.0rc3 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index b41d5e965e0..f01c058282c 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "March 2025" "bitcoin-wallet v29.0.0rc2" "User Commands" +.TH BITCOIN-WALLET "1" "March 2025" "bitcoin-wallet v29.0.0rc3" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.0.0rc2 +bitcoin-wallet \- manual page for bitcoin-wallet v29.0.0rc3 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.0.0rc2 +Bitcoin Core bitcoin\-wallet utility version v29.0.0rc3 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index b5993a052ad..92ef813d959 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "March 2025" "bitcoind v29.0.0rc2" "User Commands" +.TH BITCOIND "1" "March 2025" "bitcoind v29.0.0rc3" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.0.0rc2 +bitcoind \- manual page for bitcoind v29.0.0rc3 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.0.0rc2 +Bitcoin Core daemon version v29.0.0rc3 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From 50108104d7c5800ce5be7c8accda835aa88c92b9 Mon Sep 17 00:00:00 2001 From: glozow Date: Mon, 7 Apr 2025 11:20:16 -0400 Subject: [PATCH 023/314] [doc] copy over Release Notes draft from wiki --- doc/release-notes.md | 267 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 266 insertions(+), 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index c5dc3e0b302..d42366b7290 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1 +1,266 @@ -See https://github.com/bitcoin-core/bitcoin-devwiki/wiki/29.0-Release-Notes-draft +Bitcoin Core version 29.0 is now available from: + + + +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: + + + +To receive security and update notifications, please subscribe to: + + + +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 tested on operating systems using the +Linux Kernel 3.17+, macOS 13+, and Windows 10+. 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 +=============== + +### P2P and Network Changes + +- Support for UPnP was dropped. If you want to open a port automatically, consider using the `-natpmp` +option instead, which uses PCP or NAT-PMP depending on router support. (#31130) + +- libnatpmp was replaced with a built-in implementation of PCP and NAT-PMP (still enabled using the `-natpmp` option). This supports automatic IPv4 port forwarding as well as IPv6 pinholing. (#30043) + +- When the `-port` configuration option is used, the default onion listening port will now +be derived to be that port + 1 instead of being set to a fixed value (8334 on mainnet). +This re-allows setups with multiple local nodes using different `-port` and not using `-bind`, +which would lead to a startup failure in v28.0 due to a port collision. +Note that a `HiddenServicePort` manually configured in `torrc` may need adjustment if used in +connection with the `-port` option. +For example, if you are using `-port=5555` with a non-standard value and not using `-bind=...=onion`, +previously Bitcoin Core would listen for incoming Tor connections on `127.0.0.1:8334`. +Now it would listen on `127.0.0.1:5556` (`-port` plus one). If you configured the hidden service manually +in torrc now you have to change it from `HiddenServicePort 8333 127.0.0.1:8334` to `HiddenServicePort 8333 +127.0.0.1:5556`, or configure bitcoind with `-bind=127.0.0.1:8334=onion` to get the previous behavior. +(#31223) + +- Upon receiving an orphan transaction (an unconfirmed transaction that spends unknown inputs), the node will attempt to download missing parents from all peers who announced the orphan. This change may increase bandwidth usage but make orphan-handling more reliable. (#31397) + +### Mempool Policy and Mining Changes + +- Ephemeral dust is a new concept that allows a single +dust output in a transaction, provided the transaction +is zero fee. In order to spend any unconfirmed outputs +from this transaction, the spender must also spend +this dust in addition to any other desired outputs. +In other words, this type of transaction +should be created in a transaction package where +the dust is both created and spent simultaneously. (#30239) + +- Due to a bug, the default block reserved weight (`4,000 WU`) for fixed-size block header, transactions count, and coinbase transaction was reserved twice and could not be lowered. As a result the total reserved weight was always `8,000 WU`, meaning that even when specifying a `-blockmaxweight` higher than the default (even to the max of `4,000,000 WU`), the actual block size will never exceed `3,992,000 WU`. +The fix consolidates the reservation into a single place and introduces a new startup option, `-blockreservedweight` which specifies the reserved weight directly. The default value of `-blockreservedweight` is set to `8,000 WU` to ensure backward compatibility for users who relied on the previous behavior of `-blockmaxweight`. +The minimum value of `-blockreservedweight` is set to `2,000 WU`. Users setting `-blockreservedweight` below the default should ensure that the total weight of their block header, transaction count, and coinbase transaction does not exceed the reduced value or they may risk mining an invalid block. (#31384) + +### Updated RPCs + +- The RPC `testmempoolaccept` response now includes a `reject-details` field in some cases, +similar to the complete error messages returned by `sendrawtransaction` (#28121) + +- Duplicate blocks submitted with `submitblock` will now persist their block data +even if it was previously pruned. If pruning is activated, the data will be +pruned again eventually once the block file it is persisted in is selected for +pruning. This is consistent with the behaviour of `getblockfrompeer` where the +block is persisted as well even when pruning. (#31175) + +- `getmininginfo` now returns `nBits` and the current target in the `target` field. It also returns a `next` object which specifies the `height`, `nBits`, `difficulty`, and `target` for the next block. (#31583) + +- `getblock` and `getblockheader` now return the current target in the `target` field (#31583) + +- `getblockchaininfo` and `getchainstates` now return `nBits` and the current target in the `target` field (#31583) + +- the `getblocktemplate` RPC `curtime` (BIP22) and `mintime` (BIP23) fields now + account for the timewarp fix proposed in BIP94 on all networks. This ensures + that, in the event a timewarp fix softfork activates on mainnet, un-upgraded + miners will not accidentally violate the timewarp rule. (#31376, #31600) +As a reminder, it's important that any software which uses the `getblocktemplate` +RPC takes these values into account (either `curtime` or `mintime` is fine). +Relying only on a clock can lead to invalid blocks under some circumstances, +especially once a timewarp fix is deployed. (#31600) + +### New RPCs + +- `getdescriptoractivity` can be used to find all spend/receive activity relevant to + a given set of descriptors within a set of specified blocks. This call can be used with + `scanblocks` to lessen the need for additional indexing programs. (#30708) + + +### Updated REST APIs + +- `GET /rest/block/.json` and `GET /rest/headers/.json` now return the current target in the `target` field + +### Updated Settings + +- The maximum allowed value for the `-dbcache` configuration option has been + dropped due to recent UTXO set growth. Note that before this change, large `-dbcache` + values were automatically reduced to 16 GiB (1 GiB on 32 bit systems). (#28358) + +- Handling of negated `-noseednode`, `-nobind`, `-nowhitebind`, `-norpcbind`, `-norpcallowip`, `-norpcwhitelist`, `-notest`, `-noasmap`, `-norpcwallet`, `-noonlynet`, and `-noexternalip` options has changed. Previously negating these options had various confusing and undocumented side effects. Now negating them just resets the settings and restores default behaviors, as if the options were not specified. + +- Starting with v28.0, the `-mempoolfullrbf` startup option was set to +default to `1`. With widespread adoption of this policy, users no longer +benefit from disabling it, so the option has been removed, making full +replace-by-fee the standard behavior. (#30592) + +- Setting `-upnp` will now log a warning and be interpreted as `-natpmp`. Consider using `-natpmp` directly instead. (#31130, #31916) + +- As a safety check, Bitcoin core will **fail to start** when `-blockreservedweight` init parameter value is lower than `2000` weight units. Bitcoin Core will also **fail to start** if the `-blockmaxweight` or `-blockreservedweight` init parameter exceeds consensus limit of `4,000,000 WU`. + +- Passing `-debug=0` or `-debug=none` now behaves like `-nodebug`: previously set debug categories will be cleared, but subsequent `-debug` options will still be applied. + +- The default for `-rpcthreads` has been changed from 4 to 16, and the default for `-rpcworkqueue` has been changed from 16 to 64. (#31215). + +### Wallet + +### GUI Changes + +### Build System + +The build system has been migrated from Autotools to CMake: + +1. The minimum required CMake version is 3.22. +2. In-source builds are not allowed. When using a subdirectory within the root source tree as a build directory, it is recommended that its name includes the substring "build". +3. CMake variables may be used to configure the build system. See [Autotools to CMake Options Mapping](https://github.com/bitcoin-core/bitcoin-devwiki/wiki/Autotools-to-CMake-Options-Mapping) for details. +4. For single-configuration generators, the default build configuration (`CMAKE_BUILD_TYPE`) is "RelWithDebInfo". However, for the "Release" configuration, CMake defaults to the compiler optimization flag `-O3`, which has not been extensively tested with Bitcoin Core. Therefore, the build system replaces it with `-O2`. +5. By default, the built executables and libraries are located in the `bin/` and `lib/` subdirectories of the build directory. +6. The build system supports component‐based installation. The names of the installable components coincide with the build target names. For example: +``` +cmake -B build +cmake --build build --target bitcoind +cmake --install build --component bitcoind +``` + +7. If any of the `CPPFLAGS`, `CFLAGS`, `CXXFLAGS` or `LDFLAGS` environment variables were used in your Autotools-based build process, you should instead use the corresponding CMake variables (`APPEND_CPPFLAGS`, `APPEND_CFLAGS`, `APPEND_CXXFLAGS` and `APPEND_LDFLAGS`). Alternatively, if you opt to use the dedicated `CMAKE_<...>_FLAGS` variables, you must ensure that the resulting compiler or linker invocations are as expected. + +For more detailed guidance on configuring and using CMake, please refer to the official [CMake documentation](https://cmake.org/cmake/help/latest/) and [CMake’s User Interaction Guide](https://cmake.org/cmake/help/latest/guide/user-interaction/index.html). Additionally, consult platform-specific `doc/build-*.md` build guides for instructions tailored to your operating system. + +## Low-Level Changes + +### Tools and Utilities + +- A new tool [`utxo_to_sqlite.py`](/contrib/utxo-tools/utxo_to_sqlite.py) + converts a compact-serialized UTXO snapshot (as created with the + `dumptxoutset` RPC) to a SQLite3 database. Refer to the script's `--help` + output for more details. (#27432) + +### Tests + +- The BIP94 timewarp attack mitigation (designed for testnet4) is no longer active on the regtest network. (#31156) + +### Dependencies + +- MiniUPnPc and libnatpmp have been removed as dependencies (#31130, #30043). + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- 0xb10c +- Adlai Chandrasekhar +- Afanti +- Alfonso Roman Zubeldia +- am-sq +- Andre +- Andre Alves +- Anthony Towns +- Antoine Poinsot +- Ash Manning +- Ava Chow +- Boris Nagaev +- Brandon Odiwuor +- brunoerg +- Chris Stewart +- Cory Fields +- costcould +- Daniel Pfeifer +- Daniela Brozzoni +- David Gumberg +- dergoegge +- epysqyli +- espi3 +- Eval EXEC +- Fabian Jahr +- fanquake +- furszy +- Gabriele Bocchi +- glozow +- Greg Sanders +- Gutflo +- Hennadii Stepanov +- Hodlinator +- i-am-yuvi +- ion- +- ismaelsadeeq +- Jadi +- James O'Beirne +- Jeremy Rand +- Jon Atack +- jurraca +- Kay +- kevkevinpal +- l0rinc +- laanwj +- Larry Ruane +- Lőrinc +- Maciej S. Szmigiero +- Mackain +- MarcoFalke +- marcofleon +- Marnix +- Martin Leitner-Ankerl +- Martin Saposnic +- Martin Zumsande +- Matthew Zipkin +- Max Edwards +- Michael Dietz +- naiyoma +- Nicola Leonardo Susca +- omahs +- pablomartin4btc +- Pieter Wuille +- Randall Naar +- RiceChuan +- rkrux +- Roman Zeyde +- Ryan Ofsky +- Sebastian Falbesoner +- secp512k2 +- Sergi Delgado Segura +- Simon +- Sjors Provoost +- stickies-v +- Suhas Daftuar +- tdb3 +- TheCharlatan +- tianzedavid +- Torkel Rogstad +- Vasil Dimov +- wgyt +- willcl-ark +- yancy + +As well as to everyone that helped with translations on +[Transifex](https://www.transifex.com/bitcoin/bitcoin/). From 190e718e8382dda25891e709588111dc54e18be0 Mon Sep 17 00:00:00 2001 From: glozow Date: Mon, 7 Apr 2025 11:42:08 -0400 Subject: [PATCH 024/314] [build] bump to 29.0 final --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a5e3670ba40..3b8716c491e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 0) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 3) +set(CLIENT_VERSION_RC 0) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From 977db54233ef06f70cf9723b46fbcd1936c95be0 Mon Sep 17 00:00:00 2001 From: glozow Date: Mon, 7 Apr 2025 13:31:14 -0400 Subject: [PATCH 025/314] [doc] update man pages for 29.0 --- doc/man/bitcoin-cli.1 | 8 ++++---- doc/man/bitcoin-qt.1 | 8 ++++---- doc/man/bitcoin-tx.1 | 8 ++++---- doc/man/bitcoin-util.1 | 8 ++++---- doc/man/bitcoin-wallet.1 | 8 ++++---- doc/man/bitcoind.1 | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index d4095c84780..168b486862e 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "March 2025" "bitcoin-cli v29.0.0rc3" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH BITCOIN-CLI "1" "April 2025" "bitcoin-cli v29.0.0" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.0.0rc3 +bitcoin-cli \- manual page for bitcoin-cli v29.0.0 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.0.0rc3 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.0.0rc3 +Bitcoin Core RPC client version v29.0.0 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 1e49f6925d0..0093d08b3f0 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "March 2025" "bitcoin-qt v29.0.0rc3" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH BITCOIN-QT "1" "April 2025" "bitcoin-qt v29.0.0" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.0.0rc3 +bitcoin-qt \- manual page for bitcoin-qt v29.0.0 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.0.0rc3 +Bitcoin Core version v29.0.0 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 0f5b79854fb..f45d7094bbc 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "March 2025" "bitcoin-tx v29.0.0rc3" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH BITCOIN-TX "1" "April 2025" "bitcoin-tx v29.0.0" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.0.0rc3 +bitcoin-tx \- manual page for bitcoin-tx v29.0.0 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.0.0rc3 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.0.0rc3 +Bitcoin Core bitcoin\-tx utility version v29.0.0 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index 9c7585c89b6..330e6944113 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "March 2025" "bitcoin-util v29.0.0rc3" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH BITCOIN-UTIL "1" "April 2025" "bitcoin-util v29.0.0" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.0.0rc3 +bitcoin-util \- manual page for bitcoin-util v29.0.0 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.0.0rc3 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.0.0rc3 +Bitcoin Core bitcoin\-util utility version v29.0.0 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index f01c058282c..5e0406b1485 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "March 2025" "bitcoin-wallet v29.0.0rc3" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH BITCOIN-WALLET "1" "April 2025" "bitcoin-wallet v29.0.0" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.0.0rc3 +bitcoin-wallet \- manual page for bitcoin-wallet v29.0.0 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.0.0rc3 +Bitcoin Core bitcoin\-wallet utility version v29.0.0 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 92ef813d959..f4ec4d3ecd4 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "March 2025" "bitcoind v29.0.0rc3" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH BITCOIND "1" "April 2025" "bitcoind v29.0.0" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.0.0rc3 +bitcoind \- manual page for bitcoind v29.0.0 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.0.0rc3 +Bitcoin Core daemon version v29.0.0 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From 87e53781f7d54d0582b9d14bc458ee474a5e5c80 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 11 Apr 2025 16:00:42 +0100 Subject: [PATCH 026/314] doc: minor rel notes changes Remove two unused headers. Remove the empty-template, as point releases will modify release-notes.md. --- doc/release-notes-empty-template.md | 99 ----------------------------- doc/release-notes.md | 4 -- 2 files changed, 103 deletions(-) delete mode 100644 doc/release-notes-empty-template.md diff --git a/doc/release-notes-empty-template.md b/doc/release-notes-empty-template.md deleted file mode 100644 index fdb0d7c8b13..00000000000 --- a/doc/release-notes-empty-template.md +++ /dev/null @@ -1,99 +0,0 @@ -*The release notes draft is a temporary file that can be added to by anyone. See -[/doc/developer-notes.md#release-notes](/doc/developer-notes.md#release-notes) -for the process.* - -*version* Release Notes Draft -=============================== - -Bitcoin Core version *version* is now available from: - - - -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: - - - -To receive security and update notifications, please subscribe to: - - - -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 tested on operating systems using the -Linux Kernel 3.17+, macOS 13+, and Windows 10+. 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 -=============== - -P2P and network changes ------------------------ - -Updated RPCs ------------- - - -Changes to wallet related RPCs can be found in the Wallet section below. - -New RPCs --------- - -Build System ------------- - -Updated settings ----------------- - - -Changes to GUI or wallet related settings can be found in the GUI or Wallet section below. - -New settings ------------- - -Tools and Utilities -------------------- - -Wallet ------- - -GUI changes ------------ - -Low-level changes -================= - -RPC ---- - -Tests ------ - -*version* change log -==================== - -Credits -======= - -Thanks to everyone who directly contributed to this release: - - -As well as to everyone that helped with translations on -[Transifex](https://www.transifex.com/bitcoin/bitcoin/). diff --git a/doc/release-notes.md b/doc/release-notes.md index d42366b7290..1a6fe22459e 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -132,10 +132,6 @@ replace-by-fee the standard behavior. (#30592) - The default for `-rpcthreads` has been changed from 4 to 16, and the default for `-rpcworkqueue` has been changed from 16 to 64. (#31215). -### Wallet - -### GUI Changes - ### Build System The build system has been migrated from Autotools to CMake: From fc60337733a9dffaa42e08fcbff0ab24b5f679a4 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 25 Apr 2025 15:08:46 +0100 Subject: [PATCH 027/314] qt: 29.1 translations update --- src/qt/bitcoin_locale.qrc | 2 - src/qt/locale/bitcoin_ar.ts | 36 + src/qt/locale/bitcoin_bg.ts | 2 +- src/qt/locale/bitcoin_bn.ts | 2 +- src/qt/locale/bitcoin_cmn.ts | 8 + src/qt/locale/bitcoin_da.ts | 2 +- src/qt/locale/bitcoin_es.ts | 396 +- src/qt/locale/bitcoin_es_CL.ts | 6 +- src/qt/locale/bitcoin_es_CO.ts | 2 +- src/qt/locale/bitcoin_es_DO.ts | 2 +- src/qt/locale/bitcoin_es_SV.ts | 2 +- src/qt/locale/bitcoin_es_VE.ts | 2 +- src/qt/locale/bitcoin_et.ts | 64 + src/qt/locale/bitcoin_fa.ts | 11 + src/qt/locale/bitcoin_fi.ts | 32 + src/qt/locale/bitcoin_fr_CM.ts | 5093 -------------------- src/qt/locale/bitcoin_fr_LU.ts | 5093 -------------------- src/qt/locale/bitcoin_hi.ts | 70 + src/qt/locale/bitcoin_hu.ts | 41 + src/qt/locale/bitcoin_it.ts | 2 +- src/qt/locale/bitcoin_kn.ts | 12 + src/qt/locale/bitcoin_ko.ts | 14 +- src/qt/locale/bitcoin_ml.ts | 45 + src/qt/locale/bitcoin_ne.ts | 17 + src/qt/locale/bitcoin_pl.ts | 325 +- src/qt/locale/bitcoin_ro.ts | 92 + src/qt/locale/bitcoin_ru.ts | 8 + src/qt/locale/bitcoin_sr.ts | 4 +- src/qt/locale/bitcoin_sr@ijekavianlatin.ts | 4 +- src/qt/locale/bitcoin_sr@latin.ts | 4 +- src/qt/locale/bitcoin_sv.ts | 28 + src/qt/locale/bitcoin_ta.ts | 72 +- src/qt/locale/bitcoin_th.ts | 2680 +++++++++- src/qt/locale/bitcoin_tl.ts | 18 +- src/qt/locale/bitcoin_ur.ts | 12 +- src/qt/locale/bitcoin_zh_CN.ts | 4 + 36 files changed, 3501 insertions(+), 10706 deletions(-) delete mode 100644 src/qt/locale/bitcoin_fr_CM.ts delete mode 100644 src/qt/locale/bitcoin_fr_LU.ts diff --git a/src/qt/bitcoin_locale.qrc b/src/qt/bitcoin_locale.qrc index a3f8d609c27..a8102c69967 100644 --- a/src/qt/bitcoin_locale.qrc +++ b/src/qt/bitcoin_locale.qrc @@ -35,8 +35,6 @@ locale/bitcoin_fil.qm locale/bitcoin_fo.qm locale/bitcoin_fr.qm - locale/bitcoin_fr_CM.qm - locale/bitcoin_fr_LU.qm locale/bitcoin_ga.qm locale/bitcoin_ga_IE.qm locale/bitcoin_gd.qm diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index f2d1b608fdf..3fe688b277e 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -782,6 +782,10 @@ OptionsDialog + + Automatically open the Bitcoin client port on the router. This only works when your router supports PCP or NAT-PMP and it is enabled. The external port could be random. + افتح تلقائيًا منفذ عميل البتكوين على جهاز التوجيه. يعمل هذا فقط عندما يدعم جهاز التوجيه الخاص بك PCP أو NAT-PMP ويتم تمكينه. يمكن أن يكون المنفذ الخارجي عشوائيًا + Options set in this dialog are overridden by the command line: ‫التفضيلات المعينة عن طريق سطر الأوامر لها أولوية أكبر وتتجاوز التفضيلات المختارة هنا:‬ @@ -1471,6 +1475,14 @@ If you are receiving this error you should request the merchant provide a BIP21 bitcoin-core + + Error starting/committing db txn for wallet transactions removal process + خطأ بدء/ارتكاب DB TXN لعملية إزالة معاملات المحفظة + + + Invalid value detected for '-wallet' or '-nowallet'. '-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets + قيمة غير صالحة تم اكتشافها لـ "-wallet" أو "-Nowallet". يتطلب "-wallet" قيمة سلسلة ، في حين أن "-Nowallet" تقبل فقط "1" لتعطيل جميع المحافظ + More than one onion bind address is provided. Using %s for the automatically created Tor onion service. أكثر من عنوان مربوط بالonion مقدم. استخدام %s من أجل خدمة تور (Tor) المنشأة تلقائيا. @@ -1479,5 +1491,29 @@ If you are receiving this error you should request the merchant provide a BIP21 Maximum transaction weight is too low, can not accommodate change output الحد الأقصى لوزن المعاملة منخفض جدًا، ولا يمكنه استيعاب مخرجات التغيير + + Error loading databases + خطأ تحميل قواعد البيانات + + + Error opening coins database + خطأ فتح قاعدة بيانات العملات المعدنية + + + The transactions removal process can only be executed within a db txn + لا يمكن تنفيذ عملية إزالة المعاملات إلا داخل DB TXN + + + Do you want to rebuild the databases now? + هل تريد إعادة بناء قواعد البيانات الآن؟ + + + Error: Wallet does not exist + خطأ: محفظة غير موجودة + + + Error: cannot remove legacy wallet records + خطأ: لا يمكن إزالة سجلات المحفظة القديمة + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index 72faaa2f169..ab209c70245 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -1039,7 +1039,7 @@ Signing is only possible with addresses of the type 'legacy'. Creating Wallet <b>%1</b>… Descriptive text of the create wallet progress window which indicates to the user which wallet is currently being created. - Създаване на уолет 1 1%1 1 + Създаване на уолет <b>%1</b>… Create wallet failed diff --git a/src/qt/locale/bitcoin_bn.ts b/src/qt/locale/bitcoin_bn.ts index a4f8fb031d8..36d4e207c64 100644 --- a/src/qt/locale/bitcoin_bn.ts +++ b/src/qt/locale/bitcoin_bn.ts @@ -163,7 +163,7 @@ Signing is only possible with addresses of the type 'legacy'. BitcoinApplication Settings file %1 might be corrupt or invalid. - 1%1 সেটিংস ফাইল টি সম্ভবত নষ্ট বা করাপ্ট + %1 সেটিংস ফাইল টি সম্ভবত নষ্ট বা করাপ্ট Runaway exception diff --git a/src/qt/locale/bitcoin_cmn.ts b/src/qt/locale/bitcoin_cmn.ts index 703de4da3d3..acb9eef6316 100644 --- a/src/qt/locale/bitcoin_cmn.ts +++ b/src/qt/locale/bitcoin_cmn.ts @@ -9,6 +9,10 @@ Create a new address 创建新地址 + + &New + 新建(&N) + Copy the currently selected address to the system clipboard 把目前选择的地址复制到系统粘贴板中 @@ -146,6 +150,10 @@ Signing is only possible with addresses of the type 'legacy'. This operation needs your wallet passphrase to unlock the wallet. 這個動作需要你的錢包密碼來解鎖錢包。 + + Unlock wallet + 解鎖錢包 + Change passphrase 修改密码 diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 78ce4e7155b..973f3b5b994 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -242,7 +242,7 @@ Signing is only possible with addresses of the type 'legacy'. BitcoinApplication Settings file %1 might be corrupt or invalid. - Indstillings filen 1%1 kan være korrupt eller invalid. + Indstillings filen %1 kan være korrupt eller invalid. Runaway exception diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index 265447fbcde..96e8c723a58 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -3,11 +3,11 @@ AddressBookPage Right-click to edit address or label - Hacer clic derecho para editar la dirección o etiqueta + Pulsación secundaria para editar la dirección o etiqueta Create a new address - Crear una nueva dirección + Crea una dirección nueva &New @@ -64,8 +64,8 @@ These are your Bitcoin addresses for receiving payments. Use the 'Create new receiving address' button in the receive tab to create new addresses. Signing is only possible with addresses of the type 'legacy'. - Estas son tus direcciones de Bitcoin para recibir pagos. Usa el botón "Crear nueva dirección de recepción" en la pestaña "Recibir" para crear nuevas direcciones. -Solo es posible firmar con direcciones de tipo "legacy". + Estas son tus direcciones de Bitcoin para recibir pagos. Usa el botón «Crear nueva dirección de recepción» en la pestaña «Recibir» para crear nuevas direcciones. +Solo es posible firmar con direcciones de tipo «heredero». &Copy Address @@ -103,7 +103,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Exporting Failed - Error al exportar + Exportación incorrecta @@ -165,11 +165,11 @@ Solo es posible firmar con direcciones de tipo "legacy". Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Atención: Si cifras el monedero y pierdes la frase de contraseña, <b>¡PERDERÁS TODOS TUS BITCOINS</b>! + Atención: Si cifras el monedero y pierdes la frase de contraseña, <b>¡PERDERÁS TODOS TUS BITCOIN</b>! Are you sure you wish to encrypt your wallet? - ¿Seguro deseas cifrar el monedero? + ¿Seguro que deseas cifrar el monedero? Wallet encrypted @@ -177,7 +177,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Enter the new passphrase for the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Introduce la nueva frase de contraseña para el monedero. <br/>Usa una frase de contraseña de <b>diez o más caracteres aleatorios</b>, u <b>ocho o más palabras</b>. + Introduce la nueva frase de contraseña para el monedero. <br/>Utilice una frase de contraseña de <b>diez o más caracteres aleatorios</b>, u <b>ocho o más palabras</b>. Enter the old passphrase and new passphrase for the wallet. @@ -197,7 +197,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Wallet to be encrypted - Monedero para cifrar + Monedero para ser cifrado Your wallet is about to be encrypted. @@ -241,7 +241,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Passphrase change failed - Error al cambiar la frase de contraseña + El cambio de la frase de contraseña es incorrecto The old passphrase entered for the wallet decryption is incorrect. It contains a null character (ie - a zero byte). If the passphrase was set with a version of this software prior to 25.0, please try again with only the characters up to — but not including — the first null character. @@ -249,7 +249,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Warning: The Caps Lock key is on! - Advertencia: ¡La tecla Bloq Mayus está activada! + Advertencia: ¡La tecla Bloq Mayús está activada! @@ -283,7 +283,7 @@ Solo es posible firmar con direcciones de tipo "legacy". An internal error occurred. %1 will attempt to continue safely. This is an unexpected bug which can be reported as described below. - Ha ocurrido un error interno. %1 intentará continuar de manera segura. Este es un error inesperado que puede ser comunicado de las formas que se muestran debajo. + Ha ocurrido un error interno. %1 intentará continuar de manera segura. Esto es un defecto inesperado que puede ser comunicado de las formas que se muestran debajo. @@ -296,11 +296,11 @@ Solo es posible firmar con direcciones de tipo "legacy". A fatal error occurred. Check that settings file is writable, or try running with -nosettings. Explanatory text shown on startup when the settings file could not be written. Prompts user to check that we have the ability to write to the file. Explains that the user has the option of running without a settings file. - Un error fatal ha ocurrido. Comprueba que el archivo de configuración admite escritura, o intenta ejecutar de nuevo el programa con -nosettings + Ha sucedido un error fatal. Comprueba que el archivo de configuración admite escritura, o intenta ejecutar de nuevo el programa con -nosettings. %1 didn't yet exit safely… - %1 todavía no ha terminado de forma segura... + %1 aún no ha terminado de forma segura... unknown @@ -308,11 +308,11 @@ Solo es posible firmar con direcciones de tipo "legacy". Embedded "%1" - "%1" insertado + «%1» empotrado Default system font "%1" - Fuente predeterminada del sistema "%1" + Fuente predeterminada del sistema «%1» Custom… @@ -348,7 +348,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Block Relay Peer connection type that relays network information about blocks and not transactions or addresses. - Retransmisión de bloques + Retransmisión de bloque Feeler @@ -358,7 +358,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Address Fetch Short-lived peer connection type that solicits known addresses from a peer. - Recuperación de direcciones + Recuperación de dirección None @@ -467,7 +467,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Create a new wallet - Crear monedero nuevo + Crea un monedero nuevo &Minimize @@ -492,7 +492,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Backup wallet to another location - Respaldar monedero en otra ubicación + Respaldar monedero en otro lugar Change the passphrase used for wallet encryption @@ -512,11 +512,15 @@ Solo es posible firmar con direcciones de tipo "legacy". &Encrypt Wallet… - &Cifrar monedero + &Cifrar monedero… + + + Encrypt the private keys that belong to your wallet + Cifra las claves privadas que pertenecen a su monedero &Backup Wallet… - &Copia de seguridad del monedero + &Respaldar monedero… &Change Passphrase… @@ -526,10 +530,18 @@ Solo es posible firmar con direcciones de tipo "legacy". Sign &message… Firmar &mensaje... + + Sign messages with your Bitcoin addresses to prove you own them + Firma mensajes con sus direcciones Bitcoin para proporcionarle sus propias + &Verify message… &Verificar mensaje... + + Verify messages to ensure they were signed with specified Bitcoin addresses + Verifique mensajes para asegurar que fueron firmados con direcciones especificadas de Bitcoin + &Load PSBT from file… &Cargar TBPF desde archivo... @@ -550,13 +562,25 @@ Solo es posible firmar con direcciones de tipo "legacy". Close All Wallets… Cerrar todos los monederos... + + &File + &Archivo + + + &Settings + &Parámetros + &Help - &Ayuda + Ay&uda + + + Tabs toolbar + Barra de pestañas Syncing Headers (%1%)… - Sincronizando cabeceras (1%1%) + Sincronizando cabeceras (%1%)… Synchronizing with network… @@ -572,19 +596,19 @@ Solo es posible firmar con direcciones de tipo "legacy". Connecting to peers… - Conectando con pares... + Conectando con parejas... Request payments (generates QR codes and bitcoin: URIs) - Solicitar pagos (genera código QR y URI's de Bitcoin) + Solicitar pagos (genera código QR y las URI de Bitcoin) Show the list of used sending addresses and labels - Editar la lista de las direcciones y etiquetas almacenadas + Muestra la lista de las direcciones y etiquetas enviadas utilizadas Show the list of used receiving addresses and labels - Mostrar la lista de direcciones de envío y etiquetas + Muestra la lista de direcciones de recepción y etiquetas &Command-line options @@ -607,7 +631,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Last received block was generated %1 ago. - El último bloque recibido fue generado hace %1 horas. + El último bloque recibido fue generado hace %1 . Transactions after this will not yet be visible. @@ -635,12 +659,16 @@ Solo es posible firmar con direcciones de tipo "legacy". Load Partially Signed Bitcoin Transaction from clipboard - Cargar una transacción de Bitcoin parcialmente firmada desde el Portapapeles + Cargar Transacción de Bitcoin Parcialmente Firmada desde el portapapeles Node window Ventana del nodo + + Open node debugging and diagnostic console + Abrir nodo depurando y diagnosticando consola + &Sending addresses Direcciones de &envío @@ -659,7 +687,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Open a wallet - Abrir un monedero + Abre un monedero Close wallet @@ -673,7 +701,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Restore a wallet from a backup file Status tip for Restore Wallet menu item - Restaurar monedero desde un archivo de respaldo + Restaura un monedero desde un archivo de respaldo Close all wallets @@ -685,11 +713,11 @@ Solo es posible firmar con direcciones de tipo "legacy". Migrate a wallet - Migrar un monedero + Migra un monedero Show the %1 help message to get a list with possible Bitcoin command-line options - Muestra el mensaje de ayuda %1 para obtener una lista con posibles opciones de línea de comandos de Bitcoin. + Muestra el mensaje de ayuda %1 para obtener una lista con posibles opciones de línea de comandos de Bitcoin &Mask values @@ -697,7 +725,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Mask the values in the Overview tab - Ocultar los valores de la ventana de previsualización + Ocultar los valores en la pestaña de previsualización No wallets available @@ -711,7 +739,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Load Wallet Backup The title for Restore Wallet File Windows - Cargar copia de seguridad del monedero + Cargar respaldo del monedero Restore Wallet @@ -758,12 +786,12 @@ Solo es posible firmar con direcciones de tipo "legacy". Click for more actions. A substring of the tooltip. "More actions" are available via the context menu. - Haz clic para ver más acciones. + Pulse para ver más acciones. Show Peers tab A context menu item. The "Peers tab" is an element of the "Node window". - Mostrar pestaña de pares + Mostrar pestaña de parejas Disable network activity @@ -777,7 +805,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Pre-syncing Headers (%1%)… - Presincronizando cabeceras (%1%)... + Pre-sincronizando cabeceras (%1%)... Error creating wallet @@ -785,7 +813,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Cannot create new wallet, the software was compiled without sqlite support (required for descriptor wallets) - No se puede crear un nuevo monedero, ya que el software se compiló sin compatibilidad con sqlite (requerido para monederos basados en descriptores) + No se puede crear un nuevo monedero, ya que el software fue compilado sin compatibilidad con sqlite (requerido para descriptor de monederos) Warning: %1 @@ -833,7 +861,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Incoming transaction - Transacción entrante + Transacción recibida HD key generation is <b>enabled</b> @@ -887,7 +915,7 @@ Solo es posible firmar con direcciones de tipo "legacy". After Fee: - Después de la comisión: + Tras comisión: Change: @@ -911,11 +939,11 @@ Solo es posible firmar con direcciones de tipo "legacy". Received with label - Recibido con dirección + Recibido con etiqueta Received with address - Recibido con etiqueta + Recibido con dirección Date @@ -967,7 +995,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Copy after fee - Copiar después de la comisión + Copiar tras comisión Copy bytes @@ -983,7 +1011,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Can vary +/- %1 satoshi(s) per input. - Puede variar en +/- %1 satoshi(s) por entrada. + Puede variar en ± %1 satoshi(s) por entrada. (no label) @@ -1048,7 +1076,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Are you sure you wish to migrate the wallet <i>%1</i>? - ¿Seguro deseas migrar el monedero <i>%1</i>? + ¿Seguro que deseas migrar el monedero <i>%1</i>? Migrating the wallet will convert this wallet to one or more descriptor wallets. A new wallet backup will need to be made. @@ -1060,7 +1088,7 @@ The migration process will create a backup of the wallet before migrating. This Si este monedero contiene scripts solo de observación, se creará un nuevo monedero que los contenga. Si este monedero contiene scripts solucionables pero no de observación, se creará un nuevo monedero diferente que los contenga. -El proceso de migración creará un respaldo del monedero antes de migrar. Este archivo de respaldo se llamará <wallet name>-<timestamp>.legacy.bak y se encontrará en el directorio de este monedero. En el caso de una migración incorrecta, el respaldo puede restaurarse con la funcionalidad "Restaurar monedero". +El proceso de migración creará un respaldo del monedero antes de migrar. Este archivo de respaldo se llamará <wallet name>-<timestamp>.legacy.bak y se encontrará en el directorio de este monedero. En el caso de una migración incorrecta, el respaldo puede restaurarse con la funcionalidad «Restaurar monedero». Migrate Wallet @@ -1072,11 +1100,11 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este The wallet '%1' was migrated successfully. - La migración del monedero "%1" se ha realizado correctamente. + La migración del monedero «%1» se ha realizado correctamente. Watchonly scripts have been migrated to a new wallet named '%1'. - Los scripts solo de observación se han migrado a un nuevo monedero llamado "%1". + Los guiones solo de observación se han migrado a un monedero nuevo llamado «%1». Solvable but not watched scripts have been migrated to a new wallet named '%1'. @@ -1084,7 +1112,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este Migration failed - Migración errónea + Migración incorrecta Migration Successful @@ -1095,7 +1123,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este OpenWalletActivity Open wallet failed - Error al abrir monedero + Apertura de monedero incorrecta Open wallet warning @@ -1148,7 +1176,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este Are you sure you wish to close the wallet <i>%1</i>? - ¿Seguro deseas cerrar el monedero <i>%1</i>? + ¿Seguro que deseas cerrar el monedero <i>%1</i>? Closing the wallet for too long can result in having to resync the entire chain if pruning is enabled. @@ -1199,7 +1227,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets. - Deshabilita las claves privadas para este monedero. Los monederos con claves privadas deshabilitadas no tendrán claves privadas y no podrán tener ni una semilla HD ni claves privadas importadas. Esto es ideal para monederos solo de observación. + Deshabilita las claves privadas para este monedero. Los monederos con claves privadas deshabilitadas no tendrán claves privadas y no podrán tener ni una semilla HD ni claves privadas importadas. Esto es ideal para monederos solo de vigilancia. Disable Private Keys @@ -1243,11 +1271,11 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este The label associated with this address list entry - La etiqueta asociada con esta entrada en la lista de direcciones + La etiqueta asociada con este apunte en la lista de direcciones The address associated with this address list entry. This can only be modified for sending addresses. - La dirección asociada con esta entrada en la lista de direcciones. Solo se puede modificar para las direcciones de envío. + La dirección asociada con este apunte en la lista de direcciones. Solo se puede modificar para las direcciones de envío. &Address @@ -1267,11 +1295,11 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este The entered address "%1" is not a valid Bitcoin address. - La dirección introducida "%1" no es una dirección Bitcoin válida. + La dirección introducida «%1» no es una dirección Bitcoin válida. Address "%1" already exists as a receiving address with label "%2" and so cannot be added as a sending address. - La dirección "%1" ya existe como dirección de recepción con la etiqueta "%2" y, por lo tanto, no se puede agregar como dirección de envío. + La dirección «%1» ya existe como dirección de recepción con la etiqueta «%2» y, por lo tanto, no se puede agregar como dirección de envío. The entered address "%1" is already in the address book with label "%2". @@ -1390,7 +1418,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este When you click OK, %1 will begin to download and process the full %4 block chain (%2 GB) starting with the earliest transactions in %3 when %4 initially launched. - Al hacer clic en "Aceptar", %1 iniciará el proceso de descarga y procesará la cadena de bloques %4 completa (%2 GB), empezando con la transacción más antigua en %3 cuando %4 se ejecutó inicialmente. + Cuando pulse «Aceptar», %1 iniciará el proceso de descarga y procesará la cadena del bloque %4 completa (%2 GB), empezando con la transacción más antigua en %3 cuando %4 se ejecutó inicialmente. If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low. @@ -1443,7 +1471,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network. - La red no aceptará intentar gastar bitcoins que se vean afectados por transacciones aún no mostradas. + La red no aceptará intentar gastar los bitcoin que se vean afectados por transacciones aún no mostradas. Number of blocks left @@ -1451,11 +1479,11 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este Unknown… - Desconocido... + Desconocido… calculating… - calculando... + calculando… Last block time @@ -1563,7 +1591,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este Font in the Overview tab: - Fuente en la pestaña de vista general: + Tipografía en la pestaña de vista general: Options set in this dialog are overridden by the command line: @@ -1722,7 +1750,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este &Display - &Visualización + &Exhibir User Interface &language: @@ -1794,7 +1822,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este Current settings will be backed up at "%1". Text explaining to the user that the client's current settings will be backed up at a specific location. %1 is a stand-in argument for the backup location's path. - Los parámetros actuales se guardarán en "%1". + Los parámetros actuales se guardarán en «%1». Client will be shut down. Do you want to proceed? @@ -1809,7 +1837,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este The configuration file is used to specify advanced user options which override GUI settings. Additionally, any command-line options will override this configuration file. Explanatory text about the priority order of instructions considered by client. The order from high to low being: command-line, configuration file, GUI settings. - El archivo de configuración se usa para especificar opciones avanzadas del usuario, que remplazan la configuración de la GUI. Además, las opciones de la línea de comandos remplazarán este archivo de configuración. + El archivo de configuración se usa para especificar opciones avanzadas del usuario, que remplazan la configuración de la IGU. Además, las opciones de la línea de comandos remplazarán este archivo de configuración. Continue @@ -1836,7 +1864,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este OptionsModel Could not read setting "%1", %2. - No se puede leer la configuración "%1", %2. + No se puede leer la configuración «%1», %2. @@ -1911,7 +1939,7 @@ El proceso de migración creará un respaldo del monedero antes de migrar. Este Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings->Mask values. - Modo de privacidad activado para la pestaña de vista general. Para mostrar los valores, anula la selección de "Configuración->Ocultar valores". + Modo de privacidad activado para la pestaña de vista general. Para mostrar los valores, anula la selección de «Configuración → Ocultar valores». @@ -2082,7 +2110,7 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI Payment request file handling - Gestión de archivos de solicitud de pago + Negociación del archivo de solicitud de pago @@ -2095,7 +2123,7 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI Peer Title of Peers Table column which contains a unique number used to identify a connection. - Par + Pareja Age @@ -2195,7 +2223,7 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI To specify a non-default location of the data directory use the '%1' option. - Para especificar una localización personalizada del directorio de datos, usa la opción "%1". + Para especificar un lugar personalizado del directorio de datos, utiliza la opción «%1». Blocksdir @@ -2267,11 +2295,11 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI &Peers - &Pares + &Parejas Banned peers - Pares bloqueados + Parejas bloqueadas Select a peer to view detailed information. @@ -2323,7 +2351,7 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI The mapped Autonomous System used for diversifying peer selection. - El sistema autónomo asignado que se usó para diversificar la selección de pares. + El sistema autónomo asignado que se usó para diversificar la selección de parejas. Mapped AS @@ -2332,7 +2360,7 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI Whether we relay addresses to this peer. Tooltip text for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No). - Si retransmitimos las direcciones a este par. + Si retransmitimos las direcciones a esta pareja. Address Relay @@ -2342,12 +2370,12 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI The total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). Tooltip text for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). - El número total de direcciones recibidas desde este par que han sido procesadas (excluyendo las direcciones que han sido desestimadas debido a la limitación de volumen). + El número total de direcciones recibidas desde este par que han sido procesadas (excluyendo las direcciones que han sido desestimadas debido a la limitación de proporción). The total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. Tooltip text for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - El número total de direcciones recibidas desde este par que han sido desestimadas (no procesadas) debido a la limitación de volumen. + El número total de direcciones recibidas desde esta pareja que han sido desestimadas (no procesadas) debido a la limitación de proporción. Addresses Processed @@ -2357,7 +2385,7 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI Addresses Rate-Limited Text title for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - Direcciones desestimadas por limitación de volumen + Direcciones desestimadas por proporción limitada User Agent @@ -2373,15 +2401,15 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. - Abre el archivo de registro de depuración %1 del directorio de datos actual. Esto puede tomar unos segundos para archivos de registro grandes. + Abre el archivo de registro de depuración %1 del directorio de datos actual. Esto puede tomar unos segundos para boletines grandes. Decrease font size - Reducir el tamaño de la fuente + Reducir el tamaño de la tipografía Increase font size - Aumentar el tamaño de la fuente + Aumentar el tamaño de la tipografía Permissions @@ -2389,11 +2417,11 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI The direction and type of peer connection: %1 - El sentido y el tipo de conexión entre pares: %1 + La dirección y el tipo de conexión entre parejas: %1 Direction/Type - Sentido/Tipo + Dirección/Tipo The BIP324 session ID string in hex. @@ -2519,7 +2547,7 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI Outbound Feeler: short-lived, for testing addresses Explanatory text for a short-lived outbound peer connection that is used to test the aliveness of known addresses. - Sensor saliente: de corta duración para probar direcciones + Sensor saliente: de duración breve para probar direcciones Outbound Address Fetch: short-lived, for soliciting addresses @@ -2529,7 +2557,7 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI detecting: peer could be v1 or v2 Explanatory text for "detecting" transport type. - Detectando: el par puede ser v1 o v2 + detectando: el par puede ser v1 o v2 v1: unencrypted, plaintext transport protocol @@ -2543,15 +2571,15 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI we selected the peer for high bandwidth relay - Seleccionamos el par para la retransmisión de banda ancha + seleccionamos el par para la retransmisión de banda ancha the peer selected us for high bandwidth relay - El par nos seleccionó para la retransmisión de banda ancha + el par nos seleccionó para la retransmisión de banda ancha no high bandwidth relay selected - No se seleccionó la retransmisión de banda ancha + no se seleccionó la retransmisión de banda ancha &Copy address @@ -2605,7 +2633,7 @@ Si recibes este error, debes solicitar al comerciante que te proporcione un URI Executing command using "%1" wallet - Ejecutar comando con el monedero "%1" + Ejecutar comando con el monedero «%1» Welcome to the %1 RPC console. @@ -2631,7 +2659,7 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. (peer: %1) - (par: %1) + (pareja: %1) via %1 @@ -2643,11 +2671,11 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. To - A + Destino From - De + Remite Ban for @@ -2678,7 +2706,7 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. - Mensaje opcional para adjuntar a la solicitud de pago, que se mostrará cuando se abra la solicitud. Nota: Este mensaje no se enviará con el pago a través de la red de Bitcoin. + Mensaje opcional para adjuntar a la solicitud de pago, que se mostrará cuando se abra la solicitud. Nota: El mensaje no se enviará con el pago a través de la red de Bitcoin. An optional label to associate with the new receiving address. @@ -2706,11 +2734,11 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. Clear all fields of the form. - Borrar todos los campos del formulario. + Vaciar todos los campos del formulario. Clear - Borrar + Vaciar Requested payments history @@ -2718,7 +2746,7 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. Show the selected request (does the same as double clicking an entry) - Mostrar la solicitud seleccionada (equivale a hacer doble clic en una entrada) + Mostrar la solicitud seleccionada (equivale a pulsación doble en un apunte) Show @@ -2726,7 +2754,7 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. Remove the selected entries from the list - Eliminar las entradas seleccionadas de la lista + Elimina los apuntes seleccionados de la lista Remove @@ -2752,6 +2780,10 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. Copy &amount Copiar &importe + + Base58 (Legacy) + Base58 (Heredada) + Not recommended due to higher fees and less protection against typos. No se recomienda debido a las altas comisiones y la poca protección contra errores tipográficos. @@ -2766,7 +2798,7 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited. - Bech32m (BIP-350) es una actualización de Bech32. La compatibilidad con el monedero todavía es limitada. + Bech32m (BIP-350) es una actualización de Bech32. La compatibilidad con el monedero aún está limitada. Could not unlock wallet. @@ -2875,7 +2907,7 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. automatically selected - Seleccionado automáticamente + auto-seleccionado Insufficient funds! @@ -2903,7 +2935,7 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. - Si se activa, pero la dirección de cambio está vacía o es inválida, el cambio se enviará a una dirección generada recientemente. + Si se activa, pero la dirección de cambio está vacía o no es válida, el cambio se enviará a una dirección generada recientemente. Custom change address @@ -2965,9 +2997,9 @@ Para obtener más información sobre cómo usar esta consola, escribe %6. Specify a custom fee per kB (1,000 bytes) of the transaction's virtual size. Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 satoshis per kvB" for a transaction size of 500 virtual bytes (half of 1 kvB) would ultimately yield a fee of only 50 satoshis. - Especifica una comisión personalizada por kB (1000 bytes) del tamaño virtual de la transacción. + Especifica una comisión personalizada por kB (1.000 bytes) del tamaño virtual de la transacción. -Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por kvB" para una transacción de 500 bytes virtuales (la mitad de 1 kvB) supondría finalmente una comisión de solo 50 satoshis. +Nota: Dado que la comisión se calcula por byte, una tasa de «100 satoshis por kvB» para una transacción de 500 bytes virtuales (la mitad de 1 kvB) supondría finalmente una comisión de solo 50 satoshis. When there is less transaction volume than space in the blocks, miners as well as relaying nodes may enforce a minimum fee. Paying only this minimum fee is just fine, but be aware that this can result in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. @@ -2975,27 +3007,27 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k A too low fee might result in a never confirming transaction (read the tooltip) - Si la comisión es demasiado baja, es posible que la transacción nunca se confirme (leer la información en pantalla). + Si la comisión es demasiado baja, es posible que la transacción nunca se confirme (lea el consejo). (Smart fee not initialized yet. This usually takes a few blocks…) - (La comisión inteligente no se ha inicializado todavía. Esto tarda normalmente algunos bloques…) + (La comisión inteligente aún no se ha inicializado. Esto tarda normalmente algunos bloques…) Confirmation time target: - Objetivo de tiempo de confirmación: + Hora de confirmación del destino: Enable Replace-By-Fee - Activar "Reemplazar por comisión" + Activar «Reemplazar por comisión» With Replace-By-Fee (BIP-125) you can increase a transaction's fee after it is sent. Without this, a higher fee may be recommended to compensate for increased transaction delay risk. - Con la función "Reemplazar por comisión" (BIP-125), puedes aumentar la comisión de una transacción después de enviarla. Sin esta, es posible que se recomiende una comisión más alta para compensar el mayor riesgo de retraso de la transacción. + Con la función «Reemplazar por comisión» (BIP-125), puedes aumentar la comisión de una transacción después de enviarla. Sin ésta, es posible que se recomiende una comisión más alta para compensar el mayor riesgo de retraso de la transacción. Clear &All - Borrar &todo + Vaciar &todo Balance: @@ -3023,7 +3055,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Copy after fee - Copiar después de la comisión + Copiar tras comisión Copy bytes @@ -3044,12 +3076,12 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Connect your hardware wallet first. - Conecta primero tu monedero de hardware. + Conecta primero tu monedero hardware. Set external signer script path in Options -> Wallet "External signer" means using devices such as hardware wallets. - Establecer la ruta al script del firmante externo en "Opciones -> Monedero" + Establecer la ruta al script del firmante externo en «Opciones → Monedero» Cr&eate Unsigned @@ -3057,11 +3089,11 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Creates a Partially Signed Bitcoin Transaction (PSBT) for use with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet. - Crea una transacción de Bitcoin parcialmente firmada (TBPF) para usarla, por ejemplo, con un monedero %1 sin conexión o un monedero de hardware compatible con TBPF. + Crea una transacción de Bitcoin parcialmente firmada (TBPF) para usarla, por ejemplo, con un monedero %1 sin conexión o un monedero hardware compatible con TBPF. %1 to '%2' - %1 a "%2" + %1 a ‘%2’ %1 to %2 @@ -3069,21 +3101,21 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k To review recipient list click "Show Details…" - Para consultar la lista de destinatarios, haz clic en "Mostrar detalles..." + Para consultar la lista de destinatarios, pulse en «Mostrar detalles…» Sign failed - Error de firma + Firma incorrecta External signer not found "External signer" means using devices such as hardware wallets. - No se encontró el dispositivo firmante externo + No se encontró el firmante externo External signer failure "External signer" means using devices such as hardware wallets. - Error de firmante externo + Firmante externo incorrecto Save Transaction Data @@ -3109,7 +3141,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k You can increase the fee later (signals Replace-By-Fee, BIP-125). - Puedes aumentar la comisión después (indica "Reemplazar por comisión", BIP-125). + Puedes aumentar la comisión después (indica «Reemplazar por comisión», BIP-125). Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can save or copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet. @@ -3118,7 +3150,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k %1 from wallet '%2' - %1 desde el monedero "%2" + %1 desde el monedero «%2» Do you want to create this transaction? @@ -3133,7 +3165,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Please, review your transaction. Text to prompt a user to review the details of the transaction they are attempting to send. - Revisa la transacción. + Revisa su transacción. Transaction fee @@ -3141,7 +3173,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Not signalling Replace-By-Fee, BIP-125. - No indica "Reemplazar por comisión", BIP-125. + No indica «Reemplazar por comisión», BIP-125. Total Amount @@ -3253,7 +3285,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Remove this entry - Eliminar esta entrada + Eliminar este apunte The amount to send in the selected unit @@ -3281,7 +3313,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network. - Un mensaje adjunto al URI de tipo "bitcoin:" que se almacenará con la transacción a modo de referencia. Nota: Este mensaje no se enviará por la red de Bitcoin. + Un mensaje adjunto al URI de tipo «bitcoin:» que se almacenará con la transacción a modo de referencia. Nota: Este mensaje no se enviará por la red de Bitcoin. @@ -3307,7 +3339,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k You can sign messages/agreements with your legacy (P2PKH) addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. - Puedes firmar mensajes o acuerdos con tus direcciones tipo legacy (P2PKH) para demostrar que puedes recibir los bitcoins que se envíen a ellas. Ten cuidado de no firmar cosas confusas o al azar, ya que los ataques de phishing pueden tratar de engañarte para que les envíes la firma con tu identidad. Firma solo declaraciones totalmente detalladas con las que estés de acuerdo. + Puedes firmar mensajes o acuerdos con tus direcciones tipo heredado (P2PKH) para demostrar que puedes recibir los bitcoin que se envíen a ellas. Ten cuidado de no firmar cosas confusas o al azar, ya que los ataques de phishing pueden tratar de engañarte para que les envíes la firma con tu identidad. Firma solo declaraciones totalmente detalladas con las que estés de acuerdo. The Bitcoin address to sign the message with @@ -3347,7 +3379,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Clear &All - Borrar &todo + Vaciar &todo &Verify Message @@ -3371,7 +3403,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Verify the message to ensure it was signed with the specified Bitcoin address - Verifica el mensaje para asegurarte de que se firmó con la dirección de Bitcoin especificada. + Verifica el mensaje para asegurarte que se firmó con la dirección de Bitcoin especificada. Verify &Message @@ -3383,7 +3415,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Click "Sign Message" to generate signature - Hacer clic en "Firmar mensaje" para generar una firma + Pulse en «Firmar mensaje» para generar una firma The entered address is invalid. @@ -3395,7 +3427,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k The entered address does not refer to a legacy (P2PKH) key. Message signing for SegWit and other non-P2PKH address types is not supported in this version of %1. Please check the address and try again. - La dirección ingresada no se refiere a una clave tipo legacy (P2PKH). La firma de mensajes para direcciones SegWit y de otros tipos que no sean P2PKH no es compatible con esta versión de %1. Comprueba la dirección e inténtalo de nuevo. + La dirección ingresada no se refiere a una clave tipo heredado (P2PKH). La firma de mensajes para direcciones SegWit y de otros tipos que no sean P2PKH no es compatible con esta versión de %1. Comprueba la dirección e inténtalo de nuevo. Wallet unlock was cancelled. @@ -3442,11 +3474,11 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k SplashScreen (press q to shutdown and continue later) - (Presionar q para apagar y seguir luego) + (presione q para apagar y seguir luego) press q to shutdown - Presionar q para apagar + presionar q para apagar @@ -3454,7 +3486,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k conflicted with a transaction with %1 confirmations Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that conflicts with a confirmed transaction. - Hay un conflicto con una transacción con %1 confirmaciones + hay un conflicto con una transacción con %1 confirmaciones 0/unconfirmed, in memory pool @@ -3499,7 +3531,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k From - De + Remite unknown @@ -3507,7 +3539,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k To - A + Destino own address @@ -3590,7 +3622,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. - Las monedas generadas deben madurar %1 bloques antes de que se puedan gastar. Cuando generaste este bloque, se transmitió a la red para agregarlo a la cadena de bloques. Si no logra entrar a la cadena, su estado cambiará a "no aceptado" y no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del tuyo. + Las monedas generadas deben madurar %1 bloques antes de que se puedan gastar. Cuando generaste este bloque, se transmitió a la red para agregarlo a la cadena de bloques. Si no logra entrar a la cadena, su estado cambiará a «no aceptado» y no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del tuyo. Debug information @@ -3767,7 +3799,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Enter address, transaction id, or label to search - Ingresar la dirección, el identificador de transacción o la etiqueta para buscar + Ingresar la dirección, el ID de transacción o la etiqueta para buscar Min amount @@ -3837,7 +3869,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Watch-only - Solo de observación + Solo observación Date @@ -3855,13 +3887,9 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Address Dirección - - ID - Identificador - Exporting Failed - Error al exportar + Exportación incorrecta There was an error trying to save the transaction history to %1. @@ -3891,7 +3919,7 @@ Nota: Dado que la comisión se calcula por byte, una tasa de "100 satoshis por k Go to File > Open Wallet to load a wallet. - OR - No se ha cargado ningún monedero. -Ve a "Archivo > Abrir monedero" para cargar uno. +Ve a Archivo > Abrir monedero para cargar uno. - O - @@ -3984,7 +4012,7 @@ Ve a "Archivo > Abrir monedero" para cargar uno. Can't display address - No se puede mostrar la dirección + No puede exhibir la dirección @@ -4075,11 +4103,11 @@ Ve a "Archivo > Abrir monedero" para cargar uno. Error: Dumpfile format record is incorrect. Got "%s", expected "format". - Error: El registro del formato del archivo de volcado es incorrecto. Se obtuvo "%s", mientras que se esperaba "formato". + Error: El registro del formato del archivo de volcado es incorrecto. Se obtuvo «%s», mientras que se esperaba «formato». Error: Dumpfile identifier record is incorrect. Got "%s", expected "%s". - Error: El registro del identificador del archivo de volcado es incorrecto. Se obtuvo "%s", mientras que se esperaba "%s". + Error: El registro del identificador del archivo de volcado es incorrecto. Se obtuvo «%s», mientras que se esperaba «%s». Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version %s @@ -4087,11 +4115,11 @@ Ve a "Archivo > Abrir monedero" para cargar uno. Error: Legacy wallets only support the "legacy", "p2sh-segwit", and "bech32" address types - Error: Los monederos de tipo "legacy" solo admiten los tipos de dirección "legacy", "p2sh-segwit" y "bech32". + Error: Los monederos de tipo heredado solo admiten los tipos de dirección heredado, "p2sh-segwit" y "bech32". Error: Unable to produce descriptors for this legacy wallet. Make sure to provide the wallet's passphrase if it is encrypted. - Error: No se pueden producir descriptores para este monedero de tipo "legacy". Asegúrate de proporcionar la frase de contraseña del monedero si está encriptada. + Error: No se pueden producir descriptores para este monedero de tipo heredado. Asegúrate de proporcionar la frase de contraseña del monedero si está encriptada. File %s already exists. If you are sure this is what you want, move it out of the way first. @@ -4099,7 +4127,7 @@ Ve a "Archivo > Abrir monedero" para cargar uno. Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start. - Archivo "peers.dat" inválido o corrupto (%s). Si crees que se trata de un error, infórmalo a %s. Como alternativa, puedes quitar el archivo %s (renombrarlo, moverlo o eliminarlo) para que se cree uno nuevo en el siguiente inicio. + Archivo «peers.dat» inválido o corrupto (%s). Si crees que se trata de un error, infórmalo a %s. Como alternativa, puedes quitar el archivo %s (renombrarlo, moverlo o eliminarlo) para que se cree uno nuevo en el siguiente inicio. Invalid value detected for '-wallet' or '-nowallet'. '-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets @@ -4107,7 +4135,7 @@ Ve a "Archivo > Abrir monedero" para cargar uno. More than one onion bind address is provided. Using %s for the automatically created Tor onion service. - Se proporciona más de una dirección de enlace onion. Se está usando %s para el servicio onion de Tor creado automáticamente. + Se proporciona más de una dirección de vínculo onion. Se está usando %s para el servicio onion de Tor creado automáticamente. No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided. @@ -4143,7 +4171,7 @@ Ve a "Archivo > Abrir monedero" para cargar uno. Rename of '%s' -> '%s' failed. You should resolve this by manually moving or deleting the invalid snapshot directory %s, otherwise you will encounter the same error again on the next startup. - Error al cambiar el nombre de "%s" a "%s". Para resolverlo, mueve o elimina manualmente el directorio %s de la instantánea no válida. De lo contrario, encontrarás el mismo error de nuevo en el siguiente inicio. + Error al cambiar el nombre de ‘%s’ a ‘%s’. Para resolverlo, mueve o elimina manualmente el directorio %s de la instantánea no válida. De lo contrario, encontrarás el mismo error de nuevo en el siguiente inicio. SQLiteDatabase: Unknown sqlite wallet schema version %d. Only version %d is supported @@ -4289,11 +4317,11 @@ Ve a "Archivo > Abrir monedero" para cargar uno. Failed to rename invalid peers.dat file. Please move or delete it and try again. - No se ha podido cambiar el nombre del archivo "peers.dat" inválido. Muévelo o elimínalo, e intenta de nuevo. + No se ha podido cambiar el nombre del archivo «peers.dat» no válido. Muévelo o elimínalo, e intenta de nuevo. Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s. - Error al calcular la comisión. La opción "fallbackfee" está desactivada. Espera algunos bloques o activa %s. + Error al calcular la comisión. La opción «fallbackfee» está desactivada. Espera algunos bloques o activa %s. Flushing block file to disk failed. This is likely the result of an I/O error. @@ -4309,15 +4337,15 @@ Ve a "Archivo > Abrir monedero" para cargar uno. Invalid amount for %s=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) - Importe inválido para %s=<amount>: "%s" (debe ser al menos la comisión mínima de retransmisión de %s para evitar transacciones atascadas) + Importe inválido para %s=<amount>: «%s» (debe ser al menos la comisión mínima de retransmisión de %s para evitar transacciones atascadas) Maximum transaction weight is less than transaction weight without inputs - El peso máximo de la transacción es menor que el peso de la transacción sin entradas. + La ponderación máxima de la transacción es menor que la ponderación de la transacción sin entradas. Maximum transaction weight is too low, can not accommodate change output - El peso máximo de la transacción es demasiado bajo, por lo que no puede incluir la salida de cambio. + La ponderación máxima de la transacción es demasiado bajo, por lo que no puede incluir la salida de cambio. Outbound connections restricted to CJDNS (-onlynet=cjdns) but -cjdnsreachable is not provided @@ -4337,7 +4365,7 @@ Ve a "Archivo > Abrir monedero" para cargar uno. Rename of '%s' -> '%s' failed. Cannot clean up the background chainstate leveldb directory. - Ha fallado el cambio de nombre de ''%s" a ''%s". No se puede limpiar el directorio leveldb del estado de la cadena de fondo. + Ha fallado el cambio de nombre de ‘%s’ a ‘%s’. No se puede limpiar el directorio leveldb del estado de la cadena de fondo. The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs @@ -4411,7 +4439,7 @@ No se puede restaurar el respaldo del monedero. Assumeutxo data not found for the given blockhash '%s'. - No se han encontrado datos assumeutxo para el blockhash indicado "%s". + No se han encontrado datos assumeutxo para el blockhash indicado ‘%s’. Block verification was interrupted @@ -4427,7 +4455,7 @@ No se puede restaurar el respaldo del monedero. Copyright (C) %i-%i - Derechos de autor (C) %i-%i + © %i-%i Corrupt block found indicating potential hardware failure. @@ -4435,7 +4463,7 @@ No se puede restaurar el respaldo del monedero. Corrupted block database detected - Se ha detectado que la base de datos de bloques está dañada. + Se ha detectado que la base de datos de bloques está dañada Could not find asmap file %s @@ -4479,15 +4507,15 @@ No se puede restaurar el respaldo del monedero. Error loading %s: Private keys can only be disabled during creation - Error al cargar %s: Las claves privadas solo se pueden deshabilitar durante la creación. + Error al cargar %s: Las claves privadas solo se pueden deshabilitar durante la creación Error loading %s: Wallet corrupted - Error al cargar %s: monedero dañado. + Error al cargar %s: monedero corrupto Error loading %s: Wallet requires newer version of %s - Error al cargar %s: el monedero requiere una versión más reciente de %s. + Error al cargar %s: el monedero requiere una versión más reciente de %s Error loading block database @@ -4691,39 +4719,39 @@ No se puede restaurar el respaldo del monedero. Invalid -i2psam address or hostname: '%s' - Dirección o nombre de host de -i2psam inválido: "%s" + Dirección o nombre de host de -i2psam no válido: ‘%s’ Invalid -onion address or hostname: '%s' - Dirección o nombre de host de -onion inválido: "%s" + Dirección o nombre de host de -onion no válido: ‘%s’ Invalid -proxy address or hostname: '%s' - Dirección o nombre de host de -proxy inválido: "%s" + Dirección o nombre de host de -proxy inválido: ‘%s’ Invalid P2P permission: '%s' - Permiso P2P inválido: "%s" + Permiso P2P inválido: ‘%s’ Invalid amount for %s=<amount>: '%s' (must be at least %s) - Importe inválido para %s=<amount>: "%s" (debe ser por lo menos %s) + Importe inválido para %s=<amount>: ‘%s’ (debe ser por lo menos %s) Invalid amount for %s=<amount>: '%s' - Importe inválido para %s=<amount>: "%s" + Importe inválido para %s=<amount>: ‘%s’ Invalid amount for -%s=<amount>: '%s' - Importe inválido para -%s=<amount>: "%s" + Importe inválido para -%s=<amount>: ‘%s’ Invalid netmask specified in -whitelist: '%s' - Máscara de red inválida especificada en -whitelist: "%s" + Máscara de red inválida especificada en -whitelist: ‘%s’ Invalid port specified in %s: '%s' - Puerto no válido especificado en %s: "%s" + Puerto no válido especificado en %s: ‘%s’ Invalid pre-selected input %s @@ -4811,7 +4839,7 @@ No se puede restaurar el respaldo del monedero. SQLiteDatabase: Failed to prepare statement to verify database: %s - SQLiteDatabase: Fallo al preparar la instrucción para verificar la base de datos (%s) + SQLiteDatabase: Fallo al preparar la instrucción para verificar la base de datos: %s SQLiteDatabase: Failed to read database verification error: %s @@ -4843,23 +4871,23 @@ No se puede restaurar el respaldo del monedero. Specified -walletdir "%s" does not exist - El valor especificado de -walletdir "%s" no existe + El valor especificado de -walletdir «%s» no existe Specified -walletdir "%s" is a relative path - El valor especificado de -walletdir "%s" es una ruta relativa + El valor especificado de -walletdir «%s» es una ruta relativa Specified -walletdir "%s" is not a directory - El valor especificado de -walletdir "%s" no es un directorio + El valor especificado de -walletdir «%s» no es un directorio Specified blocks directory "%s" does not exist. - El directorio de bloques especificado "%s" no existe. + El directorio de bloques especificado «%s» no existe. Specified data directory "%s" does not exist. - El directorio de datos especificado "%s" no existe. + El directorio de datos especificado «%s» no existe. Starting network threads… @@ -4951,7 +4979,7 @@ No se puede restaurar el respaldo del monedero. Unable to create the PID file '%s': %s - No se puede crear el archivo PID "%s": %s + No se puede crear el archivo PID «%s»: %s Unable to find UTXO for external input @@ -4987,11 +5015,11 @@ No se puede restaurar el respaldo del monedero. Unknown address type '%s' - Se desconoce el tipo de dirección "%s" + Se desconoce el tipo de dirección «%s» Unknown change type '%s' - Se desconoce el tipo de cambio "%s" + Se desconoce el tipo de cambio «%s» Unknown network specified in -onlynet: '%s' @@ -5003,7 +5031,7 @@ No se puede restaurar el respaldo del monedero. Unrecognised option "%s" provided in -test=<option>. - Opción no reconocida "%s" proporcionada en -test=<option>. + Opción no reconocida «%s» proporcionada en -test=<option>. Unsupported global logging level %s=%s. Valid values: %s. @@ -5031,7 +5059,7 @@ No se puede restaurar el respaldo del monedero. Error: Could not delete watchonly transactions. - Error: No se pueden eliminar las transacciones solo de observación + Error: No se pueden eliminar las transacciones solo de observación. Error: Wallet does not exist @@ -5059,7 +5087,7 @@ No se puede restaurar el respaldo del monedero. Wallet needed to be rewritten: restart %s to complete - Es necesario reescribir el monedero: reiniciar %s para completar + Es necesario reescribir el monedero: reinicie %s para completar Settings file could not be read @@ -5067,7 +5095,7 @@ No se puede restaurar el respaldo del monedero. Settings file could not be written - El archivo de configuración no ha podido escribirse + El archivo de configuración no pudo escribirse \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index 2bfd8e0ac1e..db3766ec56c 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -5,6 +5,10 @@ Right-click to edit address or label Click derecho para editar la dirección o etiqueta + + Create a new address + Crea una dirección nueva + &New &Nuevo @@ -560,7 +564,7 @@ Usa el boton "Crear nueva direccion de recibimiento" en la pestaña de recibir p Syncing Headers (%1%)… - Sincronizando cabeceras (1%1%) + Sincronizando cabeceras (%1%)… Synchronizing with network… diff --git a/src/qt/locale/bitcoin_es_CO.ts b/src/qt/locale/bitcoin_es_CO.ts index ae1ad76f0e2..41996365b34 100644 --- a/src/qt/locale/bitcoin_es_CO.ts +++ b/src/qt/locale/bitcoin_es_CO.ts @@ -575,7 +575,7 @@ Solo es posible firmar con direcciones de tipo "legacy". Syncing Headers (%1%)… - Sincronizando cabeceras (1%1%) + Sincronizando cabeceras (%1%)… Synchronizing with network… diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index 1fa874a6819..a64b698c193 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -571,7 +571,7 @@ Solo es posible firmar con direcciones de tipo legacy. Syncing Headers (%1%)… - Sincronizando cabeceras (1%1%) + Sincronizando cabeceras (%1%)… Synchronizing with network… diff --git a/src/qt/locale/bitcoin_es_SV.ts b/src/qt/locale/bitcoin_es_SV.ts index 319037a258f..109665a1a3f 100644 --- a/src/qt/locale/bitcoin_es_SV.ts +++ b/src/qt/locale/bitcoin_es_SV.ts @@ -555,7 +555,7 @@ Solo es posible firmar con direcciones de tipo legacy. Syncing Headers (%1%)… - Sincronizando cabeceras (1%1%) + Sincronizando cabeceras (%1%)… Synchronizing with network… diff --git a/src/qt/locale/bitcoin_es_VE.ts b/src/qt/locale/bitcoin_es_VE.ts index 4b465cdb815..4eac9d6056a 100644 --- a/src/qt/locale/bitcoin_es_VE.ts +++ b/src/qt/locale/bitcoin_es_VE.ts @@ -571,7 +571,7 @@ Solo es posible firmar con direcciones de tipo legacy. Syncing Headers (%1%)… - Sincronizando cabeceras (1%1%) + Sincronizando cabeceras (%1%)… Synchronizing with network… diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 729251de22f..98eac4acf19 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -406,10 +406,18 @@ Signing is only possible with addresses of the type 'legacy'. &Change Passphrase… &Muuda Salasõna... + + Sign &message… + Allkirjuta &sõnum... + Sign messages with your Bitcoin addresses to prove you own them Omandi tõestamiseks allkirjasta sõnumid oma Bitcoini aadressiga + + &Verify message… + &Kinnita sõnum... + Verify messages to ensure they were signed with specified Bitcoin addresses Kinnita sõnumid kindlustamaks et need allkirjastati määratud Bitcoini aadressiga @@ -489,14 +497,48 @@ Signing is only possible with addresses of the type 'legacy'. Open Wallet Ava Rahakott + + Open a wallet + Ava Rahakott + + + Close wallet + Sulge rahakott + + + Restore Wallet… + Name of the menu item that restores wallet from a backup file. + Taasta Rahakoti... + + + Restore a wallet from a backup file + Status tip for Restore Wallet menu item + Taasta rahakoti varukoopiafailist + + + Close all wallets + Sulge rkõik rahakotid + + + Migrate Wallet + Migreeri rahakott + &Window &Aken + + Main Window + Pea Aken + %1 client %1 klient + + &Hide + &Peida + %n active connection(s) to Bitcoin network. A substring of the tooltip. @@ -505,6 +547,10 @@ Signing is only possible with addresses of the type 'legacy'. + + Error creating wallet + Viga rahakoti loomisel + Error: %1 Tõrge %1 @@ -647,6 +693,13 @@ Signing is only possible with addresses of the type 'legacy'. (vahetusraha) + + MigrateWalletActivity + + Migrate Wallet + Migreeri rahakott + + OpenWalletActivity @@ -655,6 +708,17 @@ Signing is only possible with addresses of the type 'legacy'. Ava Rahakott + + WalletController + + Close wallet + Sulge rahakott + + + Close all wallets + Sulge rkõik rahakotid + + CreateWalletDialog diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 561c2277af1..36ecbe2ddad 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -1360,6 +1360,17 @@ If you are receiving this error you should request the merchant provide a BIP21 خطا + + WalletModel + + Fee-bump PSBT copied to clipboard + PSBT با هزینه اضافه شده، در بریده‌دان کپی شد + + + Signer error + خطای امضا کننده + + WalletView diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 128148224d4..7c447233f66 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -2272,6 +2272,14 @@ Jos saat tämän virheen, pyydä kauppiasta antamaan BIP21-yhteensopiva URI.Number of connections Yhteyksien lukumäärä + + Local Addresses + Paikalliset osoitteet + + + Network addresses that your Bitcoin node is currently using to communicate with other nodes. + Verkko-osoitteet, joita Bitcoin-solmusi käyttää tällä hetkellä kommunikoidakseen muiden solmujen kanssa. + Block chain Lohkoketju @@ -2320,6 +2328,10 @@ Jos saat tämän virheen, pyydä kauppiasta antamaan BIP21-yhteensopiva URI.Select a peer to view detailed information. Valitse vertainen eriteltyjä tietoja varten. + + Hide Peers Detail + Piilota vertaisten yksityiskohdat + The transport layer version: %1 Kuljetuskerroksen versio: %1 @@ -2434,6 +2446,10 @@ Jos saat tämän virheen, pyydä kauppiasta antamaan BIP21-yhteensopiva URI.Direction/Type Suunta/Tyyppi + + The BIP324 session ID string in hex. + BIP324-istunnon ID-merkkijono heksana. + The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS. Verkkoprotokolla, jonka kautta tämä vertaisverkko on yhdistetty: IPv4, IPv6, Onion, I2P tai CJDNS. @@ -3341,6 +3357,10 @@ Huom: Koska maksu lasketaan per tavu, "100 satoshin per kB" maksunopeus 500 virt &Sign Message &Allekirjoita viesti + + You can sign messages/agreements with your legacy (P2PKH) addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Voit allekirjoittaa viestejä/sopimuksia vanhojen (P2PKH) osoitteidesi kanssa todistaaksesi, että voit vastaanottaa niihin lähetettyjä bitcoineja. Varo allekirjoittamasta mitään epämääräistä tai satunnaista, sillä phishing-hyökkäykset voivat yrittää huijata sinua allekirjoittamaan henkilöllisyytesi heille. Allekirjoita vain täysin yksityiskohtaiset lausunnot, joihin suostut. + The Bitcoin address to sign the message with Bitcoin-osoite jolla viesti allekirjoitetaan @@ -3995,6 +4015,10 @@ Varoitus: Tämä voi maksaa ylimääräisen maksun vähentämällä vaihtotuloja PSBT copied PSBT kopioitu + + Fee-bump PSBT copied to clipboard + Siirtokulujen nosto PSBT kopioitu leikepöydälle + Can't sign transaction. Siirtoa ei voida allekirjoittaa. @@ -4003,6 +4027,10 @@ Varoitus: Tämä voi maksaa ylimääräisen maksun vähentämällä vaihtotuloja Could not commit transaction Siirtoa ei voitu tehdä + + Signer error + Signaalivirhe + Can't display address Osoitetta ei voida näyttää @@ -4063,6 +4091,10 @@ Varoitus: Tämä voi maksaa ylimääräisen maksun vähentämällä vaihtotuloja %s virheellinen -assumeutxo-snapshot-tila. Tämä viittaa laitteistoon liittyvään ongelmaan, ohjelmistovirheeseen tai huonoon ohjelmistomuutokseen, joka on sallinut virheellisen snapshotin lataamisen. Tämän seurauksena solmu sulkeutuu ja lopettaa kaiken sen tilan käytön, joka perustui snapshottiin, ja nollaa lohkokorkeuden%darvoon%d. Seuraavassa uudelleenkäynnistyksessä solmu jatkaa synkronointia kohdasta%d   ilman, että käytetään mitään snapshot-tietoja. Ilmoita tästä tapauksesta osoitteeseen%s, mukaan lukien se, miten sait snapshotin. Virheellinen snapshot-tilatiedosto jätetään levylle, jos se on hyödyllinen ongelman diagnosoinnissa, joka aiheutti tämän virheen. + + %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 doc/p2p-bad-ports.md for details and a full list. + %s pyyntö kuunnella porttia %u. Tätä porttia pidetään ”huonona”, joten on epätodennäköistä, että mikään vertaisohjelma muodostaa siihen yhteyden. Katso lisätietoja ja täydellinen luettelo doc/p2p-bad-ports.md-tiedostosta. + Cannot downgrade wallet from version %i to version %i. Wallet version unchanged. Ei voida alentaa lompakon versiota versiosta %i versioon %i. Lompakon versio pysyy ennallaan. diff --git a/src/qt/locale/bitcoin_fr_CM.ts b/src/qt/locale/bitcoin_fr_CM.ts deleted file mode 100644 index a267f0b7d91..00000000000 --- a/src/qt/locale/bitcoin_fr_CM.ts +++ /dev/null @@ -1,5093 +0,0 @@ - - - AddressBookPage - - Right-click to edit address or label - Clic droit pour modifier l'adresse ou l'étiquette - - - Create a new address - Créer une nouvelle adresse - - - &New - &Nouvelle - - - Copy the currently selected address to the system clipboard - Copier l’adresse sélectionnée actuellement dans le presse-papiers - - - &Copy - &Copier - - - C&lose - &Fermer - - - Delete the currently selected address from the list - Supprimer l’adresse sélectionnée actuellement de la liste - - - Enter address or label to search - Saisir une adresse ou une étiquette à rechercher - - - Export the data in the current tab to a file - Exporter les données de l’onglet actuel vers un fichier - - - &Export - &Exporter - - - &Delete - &Supprimer - - - Choose the address to send coins to - Choisir l’adresse à laquelle envoyer des pièces - - - Choose the address to receive coins with - Choisir l’adresse avec laquelle recevoir des pièces - - - C&hoose - C&hoisir - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Ce sont vos adresses Bitcoin pour envoyer des paiements. Vérifiez toujours le montant et l’adresse du destinataire avant d’envoyer des pièces. - - - These are your Bitcoin addresses for receiving payments. Use the 'Create new receiving address' button in the receive tab to create new addresses. -Signing is only possible with addresses of the type 'legacy'. - Il s'agit de vos adresses Bitcoin pour la réception des paiements. Utilisez le bouton "Créer une nouvelle adresse de réception" dans l'onglet "Recevoir" pour créer de nouvelles adresses. -La signature n'est possible qu'avec les adresses de type "patrimoine". - - - &Copy Address - &Copier l’adresse - - - Copy &Label - Copier l’é&tiquette - - - &Edit - &Modifier - - - Export Address List - Exporter la liste d’adresses - - - Comma separated file - Expanded name of the CSV file format. See: https://en.wikipedia.org/wiki/Comma-separated_values. - Fichier séparé par des virgules - - - There was an error trying to save the address list to %1. Please try again. - An error message. %1 is a stand-in argument for the name of the file we attempted to save to. - Une erreur est survenue lors de l'enregistrement de la liste d'adresses vers %1. Veuillez réessayer plus tard. - - - Receiving addresses - %1 - Adresses de réceptions - %1 - - - Exporting Failed - Échec d’exportation - - - - AddressTableModel - - Label - Étiquette - - - Address - Adresse - - - (no label) - (aucune étiquette) - - - - AskPassphraseDialog - - Passphrase Dialog - Fenêtre de dialogue de la phrase de passe - - - Enter passphrase - Saisir la phrase de passe - - - New passphrase - Nouvelle phrase de passe - - - Repeat new passphrase - Répéter la phrase de passe - - - Show passphrase - Afficher la phrase de passe - - - Encrypt wallet - Chiffrer le porte-monnaie - - - This operation needs your wallet passphrase to unlock the wallet. - Cette opération nécessite votre phrase de passe pour déverrouiller le porte-monnaie. - - - Unlock wallet - Déverrouiller le porte-monnaie - - - Change passphrase - Changer la phrase de passe - - - Confirm wallet encryption - Confirmer le chiffrement du porte-monnaie - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Avertissement : Si vous chiffrez votre porte-monnaie et perdez votre phrase de passe, vous <b>PERDREZ TOUS VOS BITCOINS</b> ! - - - Are you sure you wish to encrypt your wallet? - Voulez-vous vraiment chiffrer votre porte-monnaie ? - - - Wallet encrypted - Le porte-monnaie est chiffré - - - Enter the new passphrase for the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Saisissez la nouvelle phrase de passe du porte-monnaie.<br/>Veuillez utiliser une phrase de passe composée de <b>dix caractères aléatoires ou plus</b>, ou de <b>huit mots ou plus</b>. - - - Enter the old passphrase and new passphrase for the wallet. - Saisir l’ancienne puis la nouvelle phrase de passe du porte-monnaie. - - - Continue - Poursuivre - - - Back - Retour - - - Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - N’oubliez pas que le chiffrement de votre porte-monnaie ne peut pas protéger entièrement vos bitcoins contre le vol par des programmes malveillants qui infecteraient votre ordinateur. - - - Wallet to be encrypted - Porte-monnaie à chiffrer - - - Your wallet is about to be encrypted. - Votre porte-monnaie est sur le point d’être chiffré. - - - Your wallet is now encrypted. - Votre porte-monnaie est désormais chiffré. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANT : Toutes les sauvegardes précédentes du fichier de votre porte-monnaie devraient être remplacées par le fichier du porte-monnaie chiffré nouvellement généré. Pour des raisons de sécurité, les sauvegardes précédentes de votre fichier de porte-monnaie non chiffré deviendront inutilisables dès que vous commencerez à utiliser le nouveau porte-monnaie chiffré. - - - Wallet encryption failed - Échec de chiffrement du porte-monnaie - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Le chiffrement du porte-monnaie a échoué en raison d’une erreur interne. Votre porte-monnaie n’a pas été chiffré. - - - The supplied passphrases do not match. - Les phrases de passe saisies ne correspondent pas. - - - Wallet unlock failed - Échec de déverrouillage du porte-monnaie - - - The passphrase entered for the wallet decryption was incorrect. - La phrase de passe saisie pour déchiffrer le porte-monnaie était erronée. - - - The passphrase entered for the wallet decryption is incorrect. It contains a null character (ie - a zero byte). If the passphrase was set with a version of this software prior to 25.0, please try again with only the characters up to — but not including — the first null character. If this is successful, please set a new passphrase to avoid this issue in the future. - La phrase secrète saisie pour le décryptage du portefeuille est incorrecte. Elle contient un caractère nul (c'est-à-dire un octet de zéro). Si la phrase secrète a été définie avec une version de ce logiciel antérieure à la version 25.0, veuillez réessayer en ne saisissant que les caractères jusqu'au premier caractère nul (non compris). Si vous y parvenez, définissez une nouvelle phrase secrète afin d'éviter ce problème à l'avenir. - - - Wallet passphrase was successfully changed. - La phrase de passe du porte-monnaie a été modifiée avec succès. - - - Passphrase change failed - Le changement de phrase secrète a échoué - - - The old passphrase entered for the wallet decryption is incorrect. It contains a null character (ie - a zero byte). If the passphrase was set with a version of this software prior to 25.0, please try again with only the characters up to — but not including — the first null character. - L'ancienne phrase secrète introduite pour le décryptage du portefeuille est incorrecte. Elle contient un caractère nul (c'est-à-dire un octet de zéro). Si la phrase secrète a été définie avec une version de ce logiciel antérieure à la version 25.0, veuillez réessayer en ne saisissant que les caractères jusqu'au premier caractère nul (non compris). - - - Warning: The Caps Lock key is on! - Avertissement : La touche Verr. Maj. est activée - - - - BanTableModel - - IP/Netmask - IP/masque réseau - - - Banned Until - Banni jusqu’au - - - - BitcoinApplication - - Settings file %1 might be corrupt or invalid. - Le fichier de paramètres %1 est peut-être corrompu ou non valide. - - - Runaway exception - Exception excessive - - - A fatal error occurred. %1 can no longer continue safely and will quit. - Une erreur fatale est survenue. %1 ne peut plus poursuivre de façon sûre et va s’arrêter. - - - Internal error - Eurrer interne - - - An internal error occurred. %1 will attempt to continue safely. This is an unexpected bug which can be reported as described below. - Une erreur interne est survenue. %1 va tenter de poursuivre avec sécurité. Il s’agit d’un bogue inattendu qui peut être signalé comme décrit ci-dessous. - - - - QObject - - Do you want to reset settings to default values, or to abort without making changes? - Explanatory text shown on startup when the settings file cannot be read. Prompts user to make a choice between resetting or aborting. - Voulez-vous réinitialiser les paramètres à leur valeur par défaut ou abandonner sans aucun changement ? - - - A fatal error occurred. Check that settings file is writable, or try running with -nosettings. - Explanatory text shown on startup when the settings file could not be written. Prompts user to check that we have the ability to write to the file. Explains that the user has the option of running without a settings file. - Une erreur fatale est survenue. Vérifiez que le fichier des paramètres est modifiable ou essayer d’exécuter avec -nosettings. - - - Error: %1 - Erreur : %1 - - - %1 didn't yet exit safely… - %1 ne s’est pas encore fermer en toute sécurité… - - - unknown - inconnue - - - Embedded "%1" - Intégré « %1 » - - - Default system font "%1" - Police système par défaut « %1 » - - - Custom… - Persnnalisé… - - - Amount - Montant - - - Enter a Bitcoin address (e.g. %1) - Saisir une adresse Bitcoin (p. ex. %1) - - - Unroutable - Non routable - - - Inbound - An inbound connection from a peer. An inbound connection is a connection initiated by a peer. - Entrant - - - Outbound - An outbound connection to a peer. An outbound connection is a connection initiated by us. - Sortant - - - Full Relay - Peer connection type that relays all network information. - Relais intégral - - - Block Relay - Peer connection type that relays network information about blocks and not transactions or addresses. - Relais de blocs - - - Manual - Peer connection type established manually through one of several methods. - Manuelle - - - Feeler - Short-lived peer connection type that tests the aliveness of known addresses. - Palpeur - - - Address Fetch - Short-lived peer connection type that solicits known addresses from a peer. - Récupération d’adresses - - - %1 d - %1 j - - - %1 m - %1 min - - - None - Aucun - - - N/A - N.D. - - - %n second(s) - - %n seconde - %n secondes - - - - %n minute(s) - - %n minute - %n minutes - - - - %n hour(s) - - %n heure - %n heures - - - - %n day(s) - - %n jour - %n jours - - - - %n week(s) - - %n semaine - %n semaines - - - - %1 and %2 - %1 et %2 - - - %n year(s) - - %n an - %n ans - - - - %1 B - %1 o - - - %1 kB - %1 ko - - - %1 MB - %1 Mo - - - %1 GB - %1 Go - - - default wallet - porte-monnaie par défaut - - - - BitcoinGUI - - &Overview - &Vue d’ensemble - - - Show general overview of wallet - Afficher une vue d’ensemble du porte-monnaie - - - Browse transaction history - Parcourir l’historique transactionnel - - - E&xit - Q&uitter - - - Quit application - Fermer l’application - - - &About %1 - À &propos de %1 - - - Show information about %1 - Afficher des renseignements à propos de %1 - - - About &Qt - À propos de &Qt - - - Show information about Qt - Afficher des renseignements sur Qt - - - Modify configuration options for %1 - Modifier les options de configuration de %1 - - - Create a new wallet - Créer un nouveau porte-monnaie - - - &Minimize - &Réduire - - - Wallet: - Porte-monnaie : - - - Network activity disabled. - A substring of the tooltip. - L’activité réseau est désactivée. - - - Proxy is <b>enabled</b>: %1 - Le serveur mandataire est <b>activé</b> : %1 - - - Send coins to a Bitcoin address - Envoyer des pièces à une adresse Bitcoin - - - Backup wallet to another location - Sauvegarder le porte-monnaie vers un autre emplacement - - - Change the passphrase used for wallet encryption - Modifier la phrase de passe utilisée pour le chiffrement du porte-monnaie - - - &Send - &Envoyer - - - &Receive - &Recevoir - - - &Options… - &Choix - - - &Encrypt Wallet… - &Chiffrer le porte-monnaie… - - - Encrypt the private keys that belong to your wallet - Chiffrer les clés privées qui appartiennent à votre porte-monnaie - - - &Backup Wallet… - &auvegarder le porte-monnaie… - - - &Change Passphrase… - &Changer la phrase de passe… - - - Sign &message… - Signer un &message… - - - Sign messages with your Bitcoin addresses to prove you own them - Signer les messages avec vos adresses Bitcoin pour prouver que vous les détenez - - - &Verify message… - &Vérifier un message… - - - Verify messages to ensure they were signed with specified Bitcoin addresses - Vérifier les messages pour s’assurer qu’ils ont été signés avec les adresses Bitcoin indiquées - - - &Load PSBT from file… - &Charger une TBSP d’un fichier… - - - Open &URI… - Ouvrir une &URI… - - - Close Wallet… - Fermer le porte-monnaie… - - - Create Wallet… - Créer un porte-monnaie… - - - Close All Wallets… - Fermer tous les porte-monnaie… - - - &File - &Fichier - - - &Settings - &Paramètres - - - &Help - &Aide - - - Tabs toolbar - Barre d’outils des onglets - - - Syncing Headers (%1%)… - Synchronisation des en-têtes (%1)… - - - Synchronizing with network… - Synchronisation avec le réseau… - - - Indexing blocks on disk… - Indexation des blocs sur le disque… - - - Processing blocks on disk… - Traitement des blocs sur le disque… - - - Connecting to peers… - Connexion aux pairs… - - - Request payments (generates QR codes and bitcoin: URIs) - Demander des paiements (génère des codes QR et des URI bitcoin:) - - - Show the list of used sending addresses and labels - Afficher la liste d’adresses et d’étiquettes d’envoi utilisées - - - Show the list of used receiving addresses and labels - Afficher la liste d’adresses et d’étiquettes de réception utilisées - - - &Command-line options - Options de ligne de &commande - - - Processed %n block(s) of transaction history. - - %n bloc d’historique transactionnel a été traité. - %n blocs d’historique transactionnel ont été traités. - - - - %1 behind - en retard de %1 - - - Catching up… - Rattrapage… - - - Last received block was generated %1 ago. - Le dernier bloc reçu avait été généré il y a %1. - - - Transactions after this will not yet be visible. - Les transactions suivantes ne seront pas déjà visibles. - - - Error - Erreur - - - Warning - Avertissement - - - Information - Renseignements - - - Up to date - À jour - - - Load Partially Signed Bitcoin Transaction - Charger une transaction Bitcoin signée partiellement - - - Load PSBT from &clipboard… - Charger la TBSP du &presse-papiers… - - - Load Partially Signed Bitcoin Transaction from clipboard - Charger du presse-papiers une transaction Bitcoin signée partiellement - - - Node window - Fenêtre des nœuds - - - Open node debugging and diagnostic console - Ouvrir une console de débogage de nœuds et de diagnostic - - - &Sending addresses - &Adresses d’envoi - - - &Receiving addresses - &Adresses de réception - - - Open a bitcoin: URI - Ouvrir une URI bitcoin: - - - Open Wallet - Ouvrir le porte-monnaie - - - Open a wallet - Ouvrir un porte-monnaie - - - Close wallet - Fermer le porte-monnaie - - - Restore Wallet… - Name of the menu item that restores wallet from a backup file. - Restaurer le Portefeuille... - - - Restore a wallet from a backup file - Status tip for Restore Wallet menu item - Restaurer le Portefeuille depuis un fichier de sauvegarde - - - Close all wallets - Fermer tous les porte-monnaie - - - Migrate Wallet - Migrer le portefeuille - - - Migrate a wallet - Migrer un portefeuilles - - - Show the %1 help message to get a list with possible Bitcoin command-line options - Afficher le message d’aide de %1 pour obtenir la liste des options possibles en ligne de commande Bitcoin - - - &Mask values - &Masquer les montants - - - Mask the values in the Overview tab - Masquer les montants dans l’onglet Vue d’ensemble - - - No wallets available - Aucun porte-monnaie n’est disponible - - - Wallet Data - Name of the wallet data file format. - Données du porte-monnaie - - - Load Wallet Backup - The title for Restore Wallet File Windows - Lancer un Portefeuille de sauvegarde - - - Restore Wallet - Title of pop-up window shown when the user is attempting to restore a wallet. - Restaurer le portefeuille - - - Wallet Name - Label of the input field where the name of the wallet is entered. - Nom du porte-monnaie - - - &Window - &Fenêtre - - - Zoom - Zoomer - - - Main Window - Fenêtre principale - - - %1 client - Client %1 - - - &Hide - &Cacher - - - S&how - A&fficher - - - %n active connection(s) to Bitcoin network. - A substring of the tooltip. - - %n connexion active avec le réseau Bitcoin. - %n connexions actives avec le réseau Bitcoin. - - - - Click for more actions. - A substring of the tooltip. "More actions" are available via the context menu. - Cliquez pour afficher plus d’actions. - - - Show Peers tab - A context menu item. The "Peers tab" is an element of the "Node window". - Afficher l’onglet Pairs - - - Disable network activity - A context menu item. - Désactiver l’activité réseau - - - Enable network activity - A context menu item. The network activity was disabled previously. - Activer l’activité réseau - - - Pre-syncing Headers (%1%)… - En-têtes de pré-synchronisation (%1%)... - - - Error creating wallet - Erreur lors de la création du portefeuille - - - Cannot create new wallet, the software was compiled without sqlite support (required for descriptor wallets) - Impossible de créer un nouveau portefeuilles, le logiciel a été compilé sans support pour sqlite (nécessaire pour le portefeuille décris) - - - Error: %1 - Erreur : %1 - - - Warning: %1 - Avertissement : %1 - - - Date: %1 - - Date : %1 - - - - Amount: %1 - - Montant : %1 - - - - Wallet: %1 - - Porte-monnaie : %1 - - - - Type: %1 - - Type  : %1 - - - - Label: %1 - - Étiquette : %1 - - - - Address: %1 - - Adresse : %1 - - - - Sent transaction - Transaction envoyée - - - Incoming transaction - Transaction entrante - - - HD key generation is <b>enabled</b> - La génération de clé HD est <b>activée</b> - - - HD key generation is <b>disabled</b> - La génération de clé HD est <b>désactivée</b> - - - Private key <b>disabled</b> - La clé privée est <b>désactivée</b> - - - Wallet is <b>encrypted</b> and currently <b>unlocked</b> - Le porte-monnaie est <b>chiffré</b> et est actuellement <b>déverrouillé</b> - - - Wallet is <b>encrypted</b> and currently <b>locked</b> - Le porte-monnaie est <b>chiffré</b> et actuellement <b>verrouillé</b> - - - Original message: - Message original : - - - - UnitDisplayStatusBarControl - - Unit to show amounts in. Click to select another unit. - Unité d’affichage des montants. Cliquez pour sélectionner une autre unité. - - - - CoinControlDialog - - Coin Selection - Sélection des pièces - - - Quantity: - Quantité : - - - Bytes: - Octets : - - - Amount: - Montant : - - - Fee: - Frais : - - - After Fee: - Après les frais : - - - Change: - Monnaie : - - - (un)select all - Tout (des)sélectionner - - - Tree mode - Mode arborescence - - - List mode - Mode liste - - - Amount - Montant - - - Received with label - Reçu avec une étiquette - - - Received with address - Reçu avec une adresse - - - Confirmed - Confirmée - - - Copy amount - Copier le montant - - - &Copy address - &Copier l’adresse - - - Copy &label - Copier l’&étiquette - - - Copy &amount - Copier le &montant - - - Copy transaction &ID and output index - Copier l’ID de la transaction et l’index des sorties - - - L&ock unspent - &Verrouillé ce qui n’est pas dépensé - - - &Unlock unspent - &Déverrouiller ce qui n’est pas dépensé - - - Copy quantity - Copier la quantité - - - Copy fee - Copier les frais - - - Copy after fee - Copier après les frais - - - Copy bytes - Copier les octets - - - Copy change - Copier la monnaie - - - (%1 locked) - (%1 verrouillée) - - - Can vary +/- %1 satoshi(s) per input. - Peut varier +/- %1 satoshi(s) par entrée. - - - (no label) - (aucune étiquette) - - - change from %1 (%2) - monnaie de %1 (%2) - - - (change) - (monnaie) - - - - CreateWalletActivity - - Create Wallet - Title of window indicating the progress of creation of a new wallet. - Créer un porte-monnaie - - - Creating Wallet <b>%1</b>… - Descriptive text of the create wallet progress window which indicates to the user which wallet is currently being created. - Création du porte-monnaie <b>%1</b>… - - - Create wallet failed - Échec de création du porte-monnaie - - - Create wallet warning - Avertissement de création du porte-monnaie - - - Can't list signers - Impossible de lister les signataires - - - Too many external signers found - Trop de signataires externes trouvés - - - - LoadWalletsActivity - - Load Wallets - Title of progress window which is displayed when wallets are being loaded. - Charger les porte-monnaie - - - Loading wallets… - Descriptive text of the load wallets progress window which indicates to the user that wallets are currently being loaded. - Chargement des porte-monnaie… - - - - MigrateWalletActivity - - Migrate wallet - Migrer le portefeuille - - - Are you sure you wish to migrate the wallet <i>%1</i>? - Êtes-vous sûr de vouloir migrer le portefeuille <i>%1</i> - - - Migrating the wallet will convert this wallet to one or more descriptor wallets. A new wallet backup will need to be made. -If this wallet contains any watchonly scripts, a new wallet will be created which contains those watchonly scripts. -If this wallet contains any solvable but not watched scripts, a different and new wallet will be created which contains those scripts. - -The migration process will create a backup of the wallet before migrating. This backup file will be named <wallet name>-<timestamp>.legacy.bak and can be found in the directory for this wallet. In the event of an incorrect migration, the backup can be restored with the "Restore Wallet" functionality. - La migration du porte-monnaie convertira ce porte-monnaie en un ou plusieurs porte-monnaie de descripteurs. Une nouvelle sauvegarde du porte-monnaie devra être effectuée. -Si ce porte-monnaie contient des scripts en lecture seule, un nouveau porte-monnaie sera créé contenant ces scripts en lecture seule. -Si ce porte-monnaie contient des scripts solvables mais non surveillés, un autre nouveau porte-monnaie sera créé contenant ces scripts. - -Le processus de migration créera une sauvegarde du porte-monnaie avant la migration. Ce fichier de sauvegarde sera nommé <nom du porte-monnaie>-<horodatage>.legacy.bak et pourra être trouvé dans le répertoire de ce porte-monnaie. En cas de migration incorrecte, la sauvegarde peut être restaurée avec la fonctionnalité "Restaurer le porte-monnaie". - - - Migrate Wallet - Migrer le portefeuille - - - Migrating Wallet <b>%1</b>… - Migration du portefeuille <b>%1</b>… - - - The wallet '%1' was migrated successfully. - Le porte-monnaie '%1' a été migré avec succès. - - - Watchonly scripts have been migrated to a new wallet named '%1'. - Les scripts juste-regarder ont été migrés vers un nouveau porte-monnaie nommé « %1 ». - - - Solvable but not watched scripts have been migrated to a new wallet named '%1'. - Les scripts solubles, mais non surveillés ont été migrés vers un nouveau porte-monnaie nommé « %1 ». - - - Migration failed - La migration a échoué - - - Migration Successful - Migration réussie - - - - OpenWalletActivity - - Open wallet failed - Échec d’ouverture du porte-monnaie - - - Open wallet warning - Avertissement d’ouverture du porte-monnaie - - - Open Wallet - Title of window indicating the progress of opening of a wallet. - Ouvrir un porte-monnaie - - - Opening Wallet <b>%1</b>… - Descriptive text of the open wallet progress window which indicates to the user which wallet is currently being opened. - Ouverture du porte-monnaie <b>%1</b>… - - - - RestoreWalletActivity - - Restore Wallet - Title of progress window which is displayed when wallets are being restored. - Restaurer le portefeuille - - - Restoring Wallet <b>%1</b>… - Descriptive text of the restore wallets progress window which indicates to the user that wallets are currently being restored. - Restauration du Portefeuille<b>%1</b>... - - - Restore wallet failed - Title of message box which is displayed when the wallet could not be restored. - Échec de la restauration du portefeuille - - - Restore wallet warning - Title of message box which is displayed when the wallet is restored with some warning. - Avertissement de la récupération du Portefeuille - - - Restore wallet message - Title of message box which is displayed when the wallet is successfully restored. - Message du Portefeuille restauré - - - - WalletController - - Close wallet - Fermer le porte-monnaie - - - Are you sure you wish to close the wallet <i>%1</i>? - Voulez-vous vraiment fermer le porte-monnaie <i>%1</i> ? - - - Closing the wallet for too long can result in having to resync the entire chain if pruning is enabled. - Fermer le porte-monnaie trop longtemps peut impliquer de devoir resynchroniser la chaîne entière si l’élagage est activé. - - - Close all wallets - Fermer tous les porte-monnaie - - - Are you sure you wish to close all wallets? - Voulez-vous vraiment fermer tous les porte-monnaie ? - - - - CreateWalletDialog - - Create Wallet - Créer un porte-monnaie - - - You are one step away from creating your new wallet! - Vous n'êtes qu'à un pas de la création de votre nouveau portefeuille ! - - - Please provide a name and, if desired, enable any advanced options - Veuillez fournir un nom et, si désiré, activer toutes les options avancées. - - - Wallet Name - Nom du porte-monnaie - - - Wallet - Porte-monnaie - - - Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice. - Chiffrer le porte-monnaie. Le porte-monnaie sera chiffré avec une phrase de passe de votre choix. - - - Encrypt Wallet - Chiffrer le porte-monnaie - - - Advanced Options - Options avancées - - - Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets. - Désactiver les clés privées pour ce porte-monnaie. Les porte-monnaie pour lesquels les clés privées sont désactivées n’auront aucune clé privée et ne pourront ni avoir de graine HD ni de clés privées importées. Cela est idéal pour les porte-monnaie juste-regarder. - - - Disable Private Keys - Désactiver les clés privées - - - Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time. - Créer un porte-monnaie vide. Les porte-monnaie vides n’ont initialement ni clé privée ni script. Ultérieurement, des clés privées et des adresses peuvent être importées ou une graine HD peut être définie. - - - Make Blank Wallet - Créer un porte-monnaie vide - - - Use an external signing device such as a hardware wallet. Configure the external signer script in wallet preferences first. - Utiliser un appareil externe de signature tel qu’un porte-monnaie matériel. Configurer d’abord le script signataire externe dans les préférences du porte-monnaie. - - - External signer - Signataire externe - - - Create - Créer - - - Compiled without external signing support (required for external signing) - "External signing" means using devices such as hardware wallets. - Compilé sans prise en charge des signatures externes (requis pour la signature externe) - - - - EditAddressDialog - - Edit Address - Modifier l’adresse - - - &Label - É&tiquette - - - The label associated with this address list entry - L’étiquette associée à cette entrée de la liste d’adresses - - - The address associated with this address list entry. This can only be modified for sending addresses. - L’adresse associée à cette entrée de la liste d’adresses. Ne peut être modifié que pour les adresses d’envoi. - - - &Address - &Adresse - - - New sending address - Nouvelle adresse d’envoi - - - Edit receiving address - Modifier l’adresse de réception - - - Edit sending address - Modifier l’adresse d’envoi - - - The entered address "%1" is not a valid Bitcoin address. - L’adresse saisie « %1 » n’est pas une adresse Bitcoin valide. - - - Address "%1" already exists as a receiving address with label "%2" and so cannot be added as a sending address. - L’adresse « %1 » existe déjà en tant qu’adresse de réception avec l’étiquette « %2 » et ne peut donc pas être ajoutée en tant qu’adresse d’envoi. - - - The entered address "%1" is already in the address book with label "%2". - L’adresse saisie « %1 » est déjà présente dans le carnet d’adresses avec l’étiquette « %2 ». - - - Could not unlock wallet. - Impossible de déverrouiller le porte-monnaie. - - - New key generation failed. - Échec de génération de la nouvelle clé. - - - - FreespaceChecker - - A new data directory will be created. - Un nouveau répertoire de données sera créé. - - - name - nom - - - Directory already exists. Add %1 if you intend to create a new directory here. - Le répertoire existe déjà. Ajouter %1 si vous comptez créer un nouveau répertoire ici. - - - Path already exists, and is not a directory. - Le chemin existe déjà et n’est pas un répertoire. - - - Cannot create data directory here. - Impossible de créer un répertoire de données ici. - - - - Intro - - %n GB of space available - - %n Go d’espace libre - %n Go d’espace libre - - - - (of %n GB needed) - - (of %n GB needed) - (of %n GB needed) - - - - (%n GB needed for full chain) - - (%n GB needed for full chain) - (%n GB needed for full chain) - - - - Choose data directory - Choisissez un répertoire de donnée - - - At least %1 GB of data will be stored in this directory, and it will grow over time. - Au moins %1 Go de données seront stockés dans ce répertoire et sa taille augmentera avec le temps. - - - Approximately %1 GB of data will be stored in this directory. - Approximativement %1 Go de données seront stockés dans ce répertoire. - - - (sufficient to restore backups %n day(s) old) - Explanatory text on the capability of the current prune target. - - (suffisant pour restaurer les sauvegardes âgées de %n jour) - (suffisant pour restaurer les sauvegardes âgées de %n jours) - - - - %1 will download and store a copy of the Bitcoin block chain. - %1 téléchargera et stockera une copie de la chaîne de blocs Bitcoin. - - - The wallet will also be stored in this directory. - Le porte-monnaie sera aussi stocké dans ce répertoire. - - - Error: Specified data directory "%1" cannot be created. - Erreur : Le répertoire de données indiqué « %1 » ne peut pas être créé. - - - Error - Erreur - - - Welcome - Bienvenue - - - Welcome to %1. - Bienvenue à %1. - - - As this is the first time the program is launched, you can choose where %1 will store its data. - Comme le logiciel est lancé pour la première fois, vous pouvez choisir où %1 stockera ses données. - - - Limit block chain storage to - Limiter l’espace de stockage de chaîne de blocs à - - - Reverting this setting requires re-downloading the entire blockchain. It is faster to download the full chain first and prune it later. Disables some advanced features. - Rétablir ce paramètre à sa valeur antérieure exige de retélécharger la chaîne de blocs dans son intégralité. Il est plus rapide de télécharger la chaîne complète dans un premier temps et de l’élaguer ultérieurement. Désactive certaines fonctions avancées. - - - GB -  Go - - - This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off. - Cette synchronisation initiale est très exigeante et pourrait exposer des problèmes matériels dans votre ordinateur passés inaperçus auparavant. Chaque fois que vous exécuterez %1, le téléchargement reprendra où il s’était arrêté. - - - When you click OK, %1 will begin to download and process the full %4 block chain (%2 GB) starting with the earliest transactions in %3 when %4 initially launched. - Quand vous cliquerez sur Valider, %1 commencera à télécharger et à traiter l’intégralité de la chaîne de blocs %4 (%2 Go) en débutant avec les transactions les plus anciennes de %3, quand %4 a été lancé initialement. - - - If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low. - Si vous avez choisi de limiter le stockage de la chaîne de blocs (élagage), les données historiques doivent quand même être téléchargées et traitées, mais seront supprimées par la suite pour minimiser l’utilisation de votre espace disque. - - - Use the default data directory - Utiliser le répertoire de données par défaut - - - Use a custom data directory: - Utiliser un répertoire de données personnalisé : - - - - HelpMessageDialog - - About %1 - À propos de %1 - - - Command-line options - Options de ligne de commande - - - - ShutdownWindow - - %1 is shutting down… - %1 est en cours de fermeture… - - - Do not shut down the computer until this window disappears. - Ne pas éteindre l’ordinateur jusqu’à la disparition de cette fenêtre. - - - - ModalOverlay - - Form - Formulaire - - - Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below. - Les transactions récentes ne sont peut-être pas encore visibles et par conséquent le solde de votre porte-monnaie est peut-être erroné. Ces renseignements seront justes quand votre porte-monnaie aura fini de se synchroniser avec le réseau Bitcoin, comme décrit ci-dessous. - - - Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network. - Toute tentative de dépense de bitcoins affectés par des transactions qui ne sont pas encore affichées ne sera pas acceptée par le réseau. - - - Number of blocks left - Nombre de blocs restants - - - Unknown… - Inconnu… - - - calculating… - calcul en cours… - - - Last block time - Estampille temporelle du dernier bloc - - - Progress - Progression - - - Progress increase per hour - Avancement de la progression par heure - - - Estimated time left until synced - Temps estimé avant la fin de la synchronisation - - - Hide - Cacher - - - Esc - Échap - - - %1 is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain. - %1 est en cours de synchronisation. Il téléchargera les en-têtes et les blocs des pairs, et les validera jusqu’à ce qu’il atteigne la fin de la chaîne de blocs. - - - Unknown. Syncing Headers (%1, %2%)… - Inconnu. Synchronisation des en-têtes (%1, %2 %)… - - - Unknown. Pre-syncing Headers (%1, %2%)… - Inconnu. En-têtes de présynchronisation (%1, %2%)... - - - - OpenURIDialog - - Open bitcoin URI - Ouvrir une URI bitcoin - - - URI: - URI : - - - Paste address from clipboard - Tooltip text for button that allows you to paste an address that is in your clipboard. - Collez l’adresse du presse-papiers - - - - OptionsDialog - - &Main - &Principales - - - Automatically start %1 after logging in to the system. - Démarrer %1 automatiquement après avoir ouvert une session sur l’ordinateur. - - - &Start %1 on system login - &Démarrer %1 lors de l’ouverture d’une session - - - Enabling pruning significantly reduces the disk space required to store transactions. All blocks are still fully validated. Reverting this setting requires re-downloading the entire blockchain. - L’activation de l’élagage réduit considérablement l’espace disque requis pour stocker les transactions. Tous les blocs sont encore entièrement validés. L’annulation de ce paramètre exige de retélécharger la chaîne de blocs dans son intégralité. - - - Maximum database cache size. Make sure you have enough RAM. A larger cache can contribute to faster sync, after which the benefit is less pronounced for most use cases. Lowering the cache size will reduce memory usage. Unused mempool memory is shared for this cache. - Tooltip text for Options window setting that sets the size of the database cache. Explains the corresponding effects of increasing/decreasing this value. - Taille maximale du cache de la base de données. Assurez-vous d’avoir suffisamment de mémoire vive. Un cache plus grand peut accélérer la synchronisation, avec des avantages moindres par la suite dans la plupart des cas. Diminuer la taille du cache réduira l’utilisation de la mémoire. La mémoire non utilisée de la réserve de mémoire est partagée avec ce cache. - - - Size of &database cache - Taille du cache de la base de &données - - - Number of script &verification threads - Nombre de fils de &vérification de script - - - Full path to a %1 compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins! - Chemin complet vers un %1 script compatible (par exemple, C:\Downloads\hwi.exe ou /Users/you/Downloads/hwi.py). Attention : les malwares peuvent voler vos pièces ! - - - Automatically open the Bitcoin client port on the router. This only works when your router supports PCP or NAT-PMP and it is enabled. The external port could be random. - Ouvrir automatiquement le port du client Bitcoin sur le routeur. Cela ne fonctionne que si votre routeur prend en charge PCP ou NAT-PMP. Le port externe peut être aléatoire. - - - Map port using PCP or NA&T-PMP - Mapper le port avec PCP ou NA&T-PMP - - - IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) - Adresse IP du mandataire (p. ex. IPv4 : 127.0.0.1 / IPv6 : ::1) - - - Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type. - Indique si le mandataire SOCKS5 par défaut fourni est utilisé pour atteindre des pairs par ce type de réseau. - - - Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu. - Quand la fenêtre est fermée, la réduire au lieu de quitter l’application. Si cette option est activée, l’application ne sera fermée qu’en sélectionnant Quitter dans le menu. - - - Font in the Overview tab: - Police de l’onglet Vue d’ensemble : - - - Options set in this dialog are overridden by the command line: - Les options définies dans cette boîte de dialogue sont remplacées par la ligne de commande : - - - Open the %1 configuration file from the working directory. - Ouvrir le fichier de configuration %1 du répertoire de travail. - - - Open Configuration File - Ouvrir le fichier de configuration - - - Reset all client options to default. - Réinitialiser toutes les options du client aux valeurs par défaut. - - - &Reset Options - &Réinitialiser les options - - - &Network - &Réseau - - - Prune &block storage to - Élaguer l’espace de stockage des &blocs jusqu’à - - - GB - Go - - - Reverting this setting requires re-downloading the entire blockchain. - L’annulation de ce paramètre exige de retélécharger la chaîne de blocs dans son intégralité. - - - MiB - Mio - - - Set the number of script verification threads. Negative values correspond to the number of cores you want to leave free to the system. - Tooltip text for Options window setting that sets the number of script verification threads. Explains that negative values mean to leave these many cores free to the system. - Définissez le nombre de fils de vérification de script. Les valeurs négatives correspondent au nombre de cœurs que vous voulez laisser disponibles pour le système. - - - (0 = auto, <0 = leave that many cores free) - (0 = auto, < 0 = laisser ce nombre de cœurs inutilisés) - - - This allows you or a third party tool to communicate with the node through command-line and JSON-RPC commands. - Tooltip text for Options window setting that enables the RPC server. - Ceci vous permet ou permet à un outil tiers de communiquer avec le nœud grâce à la ligne de commande ou des commandes JSON-RPC. - - - Enable R&PC server - An Options window setting to enable the RPC server. - Activer le serveur R&PC - - - W&allet - &Porte-monnaie - - - Whether to set subtract fee from amount as default or not. - Tooltip text for Options window setting that sets subtracting the fee from a sending amount as default. - Définissez s’il faut soustraire par défaut les frais du montant ou non. - - - Subtract &fee from amount by default - An Options window setting to set subtracting the fee from a sending amount as default. - Soustraire par défaut les &frais du montant - - - Enable coin &control features - Activer les fonctions de &contrôle des pièces - - - If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed. - Si vous désactivé la dépense de la monnaie non confirmée, la monnaie d’une transaction ne peut pas être utilisée tant que cette transaction n’a pas reçu au moins une confirmation. Celai affecte aussi le calcul de votre solde. - - - &Spend unconfirmed change - &Dépenser la monnaie non confirmée - - - Enable &PSBT controls - An options window setting to enable PSBT controls. - Activer les contrôles &TBPS - - - Whether to show PSBT controls. - Tooltip text for options window setting that enables PSBT controls. - Affichez ou non les contrôles TBPS. - - - External Signer (e.g. hardware wallet) - Signataire externe (p. ex. porte-monnaie matériel) - - - &External signer script path - &Chemin du script signataire externe - - - Accept connections from outside. - Accepter les connexions provenant de l’extérieur. - - - Allow incomin&g connections - Permettre les connexions e&ntrantes - - - Connect to the Bitcoin network through a SOCKS5 proxy. - Se connecter au réseau Bitcoin par un mandataire SOCKS5. - - - &Connect through SOCKS5 proxy (default proxy): - Se &connecter par un mandataire SOCKS5 (mandataire par défaut) : - - - Proxy &IP: - &IP du mandataire : - - - &Port: - &Port : - - - Port of the proxy (e.g. 9050) - Port du mandataire (p. ex. 9050) - - - Used for reaching peers via: - Utilisé pour rejoindre les pairs par : - - - &Window - &Fenêtre - - - Show the icon in the system tray. - Afficher l’icône dans la zone de notification. - - - &Show tray icon - &Afficher l’icône dans la zone de notification - - - Show only a tray icon after minimizing the window. - Après réduction, n’afficher qu’une icône dans la zone de notification. - - - &Minimize to the tray instead of the taskbar - &Réduire dans la zone de notification au lieu de la barre des tâches - - - M&inimize on close - Ré&duire lors de la fermeture - - - &Display - &Affichage - - - User Interface &language: - &Langue de l’interface utilisateur : - - - The user interface language can be set here. This setting will take effect after restarting %1. - La langue de l’interface utilisateur peut être définie ici. Ce réglage sera pris en compte après redémarrage de %1. - - - &Unit to show amounts in: - &Unité d’affichage des montants : - - - Choose the default subdivision unit to show in the interface and when sending coins. - Choisir la sous-unité par défaut d’affichage dans l’interface et lors d’envoi de pièces. - - - Third-party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. - Les URL de tiers (p. ex. un explorateur de blocs) qui apparaissent dans l’onglet des transactions comme éléments du menu contextuel. Dans l’URL, %s est remplacé par le hachage de la transaction. Les URL multiples sont séparées par une barre verticale |. - - - &Third-party transaction URLs - URL de transaction de $tiers - - - Whether to show coin control features or not. - Afficher ou non les fonctions de contrôle des pièces. - - - Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor onion services. - Se connecter au réseau Bitcoin par un mandataire SOCKS5 séparé pour les services oignon de Tor. - - - Use separate SOCKS&5 proxy to reach peers via Tor onion services: - Utiliser un mandataire SOCKS&5 séparé pour atteindre les pairs par les services oignon de Tor : - - - &OK - &Valider - - - &Cancel - A&nnuler - - - Compiled without external signing support (required for external signing) - "External signing" means using devices such as hardware wallets. - Compilé sans prise en charge des signatures externes (requis pour la signature externe) - - - default - par défaut - - - none - aucune - - - Confirm options reset - Window title text of pop-up window shown when the user has chosen to reset options. - Confirmer la réinitialisation des options - - - Client restart required to activate changes. - Text explaining that the settings changed will not come into effect until the client is restarted. - Le redémarrage du client est exigé pour activer les changements. - - - Current settings will be backed up at "%1". - Text explaining to the user that the client's current settings will be backed up at a specific location. %1 is a stand-in argument for the backup location's path. - Les paramètres actuels vont être restaurés à "%1". - - - Client will be shut down. Do you want to proceed? - Text asking the user to confirm if they would like to proceed with a client shutdown. - Le client sera arrêté. Voulez-vous continuer ? - - - Configuration options - Window title text of pop-up box that allows opening up of configuration file. - Options de configuration - - - The configuration file is used to specify advanced user options which override GUI settings. Additionally, any command-line options will override this configuration file. - Explanatory text about the priority order of instructions considered by client. The order from high to low being: command-line, configuration file, GUI settings. - Le fichier de configuration est utilisé pour indiquer aux utilisateurs experts quelles options remplacent les paramètres de l’IUG. De plus, toute option de ligne de commande remplacera ce fichier de configuration. - - - Continue - Poursuivre - - - Cancel - Annuler - - - Error - Erreur - - - The configuration file could not be opened. - Impossible d’ouvrir le fichier de configuration. - - - This change would require a client restart. - Ce changement demanderait un redémarrage du client. - - - The supplied proxy address is invalid. - L’adresse de serveur mandataire fournie est invalide. - - - - OptionsModel - - Could not read setting "%1", %2. - Impossible de lire le paramètre "%1", %2. - - - - OverviewPage - - Form - Formulaire - - - The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. - Les renseignements affichés peuvent être obsolètes. Votre porte-monnaie se synchronise automatiquement avec le réseau Bitcoin dès qu’une connexion est établie, mais ce processus n’est pas encore achevé. - - - Watch-only: - Juste-regarder : - - - Available: - Disponible : - - - Your current spendable balance - Votre solde actuel disponible - - - Pending: - En attente : - - - Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance - Total des transactions qui doivent encore être confirmées et qui ne sont pas prises en compte dans le solde disponible - - - Immature: - Immature : - - - Mined balance that has not yet matured - Le solde miné n’est pas encore mûr - - - Balances - Soldes - - - Total: - Total : - - - Your current total balance - Votre solde total actuel - - - Your current balance in watch-only addresses - Votre balance actuelle en adresses juste-regarder - - - Spendable: - Disponible : - - - Recent transactions - Transactions récentes - - - Unconfirmed transactions to watch-only addresses - Transactions non confirmées vers des adresses juste-regarder - - - Mined balance in watch-only addresses that has not yet matured - Le solde miné dans des adresses juste-regarder, qui n’est pas encore mûr - - - Current total balance in watch-only addresses - Solde total actuel dans des adresses juste-regarder - - - Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings->Mask values. - Le mode privé est activé dans l’onglet Vue d’ensemble. Pour afficher les montants, décocher Paramètres -> Masquer les montants. - - - - PSBTOperationsDialog - - PSBT Operations - Opération PSBT - - - Sign Tx - Signer la transaction - - - Broadcast Tx - Diffuser la transaction - - - Copy to Clipboard - Copier dans le presse-papiers - - - Save… - Enregistrer… - - - Close - Fermer - - - Failed to load transaction: %1 - Échec de chargement de la transaction : %1 - - - Failed to sign transaction: %1 - Échec de signature de la transaction : %1 - - - Cannot sign inputs while wallet is locked. - Impossible de signer des entrées quand le porte-monnaie est verrouillé. - - - Could not sign any more inputs. - Aucune autre entrée n’a pu être signée. - - - Signed %1 inputs, but more signatures are still required. - %1 entrées ont été signées, mais il faut encore d’autres signatures. - - - Signed transaction successfully. Transaction is ready to broadcast. - La transaction a été signée avec succès et est prête à être diffusée. - - - Unknown error processing transaction. - Erreur inconnue lors de traitement de la transaction - - - Transaction broadcast successfully! Transaction ID: %1 - La transaction a été diffusée avec succès. ID de la transaction : %1 - - - Transaction broadcast failed: %1 - Échec de diffusion de la transaction : %1 - - - PSBT copied to clipboard. - La TBSP a été copiée dans le presse-papiers. - - - Save Transaction Data - Enregistrer les données de la transaction - - - Partially Signed Transaction (Binary) - Expanded name of the binary PSBT file format. See: BIP 174. - Transaction signée partiellement (fichier binaire) - - - PSBT saved to disk. - La TBSP a été enregistrée sur le disque. - - - Sends %1 to %2 - Envoie %1 à %2 - - - own address - votre adresse - - - Unable to calculate transaction fee or total transaction amount. - Impossible de calculer les frais de la transaction ou le montant total de la transaction. - - - Pays transaction fee: - Paye des frais de transaction : - - - Total Amount - Montant total - - - or - ou - - - Transaction has %1 unsigned inputs. - La transaction a %1 entrées non signées. - - - Transaction is missing some information about inputs. - Il manque des renseignements sur les entrées dans la transaction. - - - Transaction still needs signature(s). - La transaction a encore besoin d’une ou de signatures. - - - (But no wallet is loaded.) - (Mais aucun porte-monnaie n’est chargé.) - - - (But this wallet cannot sign transactions.) - (Mais ce porte-monnaie ne peut pas signer de transactions.) - - - (But this wallet does not have the right keys.) - (Mais ce porte-monnaie n’a pas les bonnes clés.) - - - Transaction is fully signed and ready for broadcast. - La transaction est complètement signée et prête à être diffusée. - - - Transaction status is unknown. - L’état de la transaction est inconnu. - - - - PaymentServer - - Payment request error - Erreur de demande de paiement - - - Cannot start bitcoin: click-to-pay handler - Impossible de démarrer le gestionnaire de cliquer-pour-payer bitcoin: - - - URI handling - Gestion des URI - - - 'bitcoin://' is not a valid URI. Use 'bitcoin:' instead. - 'bitcoin://' n’est pas une URI valide. Utilisez plutôt 'bitcoin:'. - - - Cannot process payment request because BIP70 is not supported. -Due to widespread security flaws in BIP70 it's strongly recommended that any merchant instructions to switch wallets be ignored. -If you are receiving this error you should request the merchant provide a BIP21 compatible URI. - Impossible de traiter la demande de paiement, car BIP70 n’est pas pris en charge. En raison des failles de sécurité généralisées de BIP70, il est fortement recommandé d’ignorer toute demande de marchand de changer de porte-monnaie. Si vous recevez cette erreur, vous devriez demander au marchand de vous fournir une URI compatible BIP21. - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - L’URI ne peut pas être analysée. Cela peut être causé par une adresse Bitcoin invalide ou par des paramètres d’URI mal formés. - - - Payment request file handling - Gestion des fichiers de demande de paiement - - - - PeerTableModel - - User Agent - Title of Peers Table column which contains the peer's User Agent string. - Agent utilisateur - - - Peer - Title of Peers Table column which contains a unique number used to identify a connection. - Pair - - - Sent - Title of Peers Table column which indicates the total amount of network information we have sent to the peer. - Envoyé - - - Received - Title of Peers Table column which indicates the total amount of network information we have received from the peer. - Reçus - - - Address - Title of Peers Table column which contains the IP/Onion/I2P address of the connected peer. - Adresse - - - Network - Title of Peers Table column which states the network the peer connected through. - Réseau - - - Inbound - An Inbound Connection from a Peer. - Entrant - - - Outbound - An Outbound Connection to a Peer. - Sortant - - - - QRImageWidget - - &Save Image… - &Enregistrer l’image… - - - &Copy Image - &Copier l’image - - - Resulting URI too long, try to reduce the text for label / message. - L’URI résultante est trop longue. Essayez de réduire le texte de l’étiquette ou du message. - - - Error encoding URI into QR Code. - Erreur d’encodage de l’URI en code QR. - - - QR code support not available. - La prise en charge des codes QR n’est pas proposée. - - - Save QR Code - Enregistrer le code QR - - - PNG Image - Expanded name of the PNG file format. See: https://en.wikipedia.org/wiki/Portable_Network_Graphics. - Image PNG - - - - RPCConsole - - N/A - N.D. - - - Client version - Version du client - - - &Information - &Renseignements - - - General - Générales - - - Datadir - Répertoire des données - - - To specify a non-default location of the data directory use the '%1' option. - Pour indiquer un emplacement du répertoire des données différent de celui par défaut, utiliser l’option ’%1’. - - - Blocksdir - Répertoire des blocs - - - To specify a non-default location of the blocks directory use the '%1' option. - Pour indiquer un emplacement du répertoire des blocs différent de celui par défaut, utiliser l’option ’%1’. - - - Startup time - Heure de démarrage - - - Network - Réseau - - - Name - Nom - - - Number of connections - Nombre de connexions - - - Local Addresses - Adresses locales - - - Network addresses that your Bitcoin node is currently using to communicate with other nodes. - Adresses réseau que votre nœud Bitcoin utilise actuellement pour communiquer avec d’autres nœuds. - - - Block chain - Chaîne de blocs - - - Memory Pool - Réserve de mémoire - - - Current number of transactions - Nombre actuel de transactions - - - Memory usage - Utilisation de la mémoire - - - Wallet: - Porte-monnaie : - - - (none) - (aucun) - - - &Reset - &Réinitialiser - - - Received - Reçus - - - Sent - Envoyé - - - &Peers - &Pairs - - - Banned peers - Pairs bannis - - - Select a peer to view detailed information. - Sélectionnez un pair pour afficher des renseignements détaillés. - - - Hide Peers Detail - Cacher les détails des pairs - - - The transport layer version: %1 - La version de la couche de transport : %1 - - - Session ID - ID de session - - - Whether we relay transactions to this peer. - Si nous relayons des transactions à ce pair. - - - Transaction Relay - Relais de transaction - - - Starting Block - Bloc de départ - - - Synced Headers - En-têtes synchronisés - - - Synced Blocks - Blocs synchronisés - - - Last Transaction - Dernière transaction - - - The mapped Autonomous System used for diversifying peer selection. - Le système autonome mappé utilisé pour diversifier la sélection des pairs. - - - Mapped AS - SA mappé - - - Whether we relay addresses to this peer. - Tooltip text for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No). - Reliez ou non des adresses à ce pair. - - - Address Relay - Text title for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No). - Relais d’adresses - - - The total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). - Tooltip text for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). - Nombre total d'adresses reçues de ce pair qui ont été traitées (à l'exclusion des adresses qui ont été abandonnées en raison de la limitation du débit). - - - The total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - Tooltip text for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - Nombre total d'adresses reçues de ce pair qui ont été abandonnées (non traitées) en raison de la limitation du débit. - - - Addresses Processed - Text title for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). - Adresses traitées - - - Addresses Rate-Limited - Text title for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - Adresses ciblées par la limite de débit - - - User Agent - Agent utilisateur - - - Node window - Fenêtre des nœuds - - - Current block height - Hauteur du bloc courant - - - Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. - Ouvrir le fichier journal de débogage de %1 à partir du répertoire de données actuel. Cela peut prendre quelques secondes pour les fichiers journaux de grande taille. - - - Decrease font size - Diminuer la taille de police - - - Increase font size - Augmenter la taille de police - - - Permissions - Autorisations - - - The direction and type of peer connection: %1 - La direction et le type de la connexion au pair : %1 - - - The BIP324 session ID string in hex. - ID hexadécimale de la session BIP324. - - - The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS. - Le protocole réseau par lequel ce pair est connecté : IPv4, IPv6, Oignon, I2P ou CJDNS. - - - High bandwidth BIP152 compact block relay: %1 - Relais de blocs BIP152 compact à large bande passante : %1 - - - High Bandwidth - Large bande passante - - - Connection Time - Temps de connexion - - - Elapsed time since a novel block passing initial validity checks was received from this peer. - Temps écoulé depuis qu’un nouveau bloc qui a réussi les vérifications initiales de validité a été reçu par ce pair. - - - Last Block - Dernier bloc - - - Elapsed time since a novel transaction accepted into our mempool was received from this peer. - Tooltip text for the Last Transaction field in the peer details area. - Temps écoulé depuis qu’une nouvelle transaction acceptée dans notre réserve de mémoire a été reçue par ce pair. - - - Last Send - Dernier envoi - - - Last Receive - Dernière réception - - - Ping Time - Temps de ping - - - The duration of a currently outstanding ping. - La durée d’un ping en cours. - - - Ping Wait - Attente du ping - - - Min Ping - Ping min. - - - Time Offset - Décalage temporel - - - Last block time - Estampille temporelle du dernier bloc - - - &Open - &Ouvrir - - - &Network Traffic - Trafic &réseau - - - Totals - Totaux - - - Debug log file - Fichier journal de débogage - - - Clear console - Effacer la console - - - In: - Entrant : - - - Out: - Sortant : - - - Inbound: initiated by peer - Explanatory text for an inbound peer connection. - Entrant : établie par le pair - - - Outbound Full Relay: default - Explanatory text for an outbound peer connection that relays all network information. This is the default behavior for outbound connections. - Relais intégral sortant : par défaut - - - Outbound Block Relay: does not relay transactions or addresses - Explanatory text for an outbound peer connection that relays network information about blocks and not transactions or addresses. - Relais de bloc sortant : ne relaye ni transactions ni adresses - - - Outbound Manual: added using RPC %1 or %2/%3 configuration options - Explanatory text for an outbound peer connection that was established manually through one of several methods. The numbered arguments are stand-ins for the methods available to establish manual connections. - Manuelle sortante : ajoutée avec un RPC %1 ou les options de configuration %2/%3 - - - Outbound Feeler: short-lived, for testing addresses - Explanatory text for a short-lived outbound peer connection that is used to test the aliveness of known addresses. - Palpeur sortant : de courte durée, pour tester des adresses - - - Outbound Address Fetch: short-lived, for soliciting addresses - Explanatory text for a short-lived outbound peer connection that is used to request addresses from a peer. - Récupération d’adresse sortante : de courte durée, pour solliciter des adresses - - - detecting: peer could be v1 or v2 - Explanatory text for "detecting" transport type. - détection : paires pourrait être v1 ou v2 - - - v1: unencrypted, plaintext transport protocol - Explanatory text for v1 transport type. - v1: protocole de transport non chiffré en texte clair - - - v2: BIP324 encrypted transport protocol - Explanatory text for v2 transport type. - v2: Protocole de transport chiffré BIP324 - - - we selected the peer for high bandwidth relay - nous avons sélectionné le pair comme relais à large bande passante - - - the peer selected us for high bandwidth relay - le pair nous avons sélectionné comme relais à large bande passante - - - no high bandwidth relay selected - aucun relais à large bande passante n’a été sélectionné - - - &Copy address - Context menu action to copy the address of a peer. - &Copier l’adresse - - - &Disconnect - &Déconnecter - - - 1 &hour - 1 &heure - - - 1 d&ay - 1 &jour - - - 1 &week - 1 &semaine - - - 1 &year - 1 &an - - - &Copy IP/Netmask - Context menu action to copy the IP/Netmask of a banned peer. IP/Netmask is the combination of a peer's IP address and its Netmask. For IP address, see: https://en.wikipedia.org/wiki/IP_address. - &Copier l’IP, le masque réseau - - - &Unban - &Réhabiliter - - - Network activity disabled - L’activité réseau est désactivée - - - None - Aucun - - - Executing command without any wallet - Exécution de la commande sans aucun porte-monnaie - - - Node window - [%1] - Fenêtre des nœuds – [%1] - - - Executing command using "%1" wallet - Exécution de la commande en utilisant le porte-monnaie « %1 » - - - Welcome to the %1 RPC console. -Use up and down arrows to navigate history, and %2 to clear screen. -Use %3 and %4 to increase or decrease the font size. -Type %5 for an overview of available commands. -For more information on using this console, type %6. - -%7WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.%8 - RPC console welcome message. Placeholders %7 and %8 are style tags for the warning content, and they are not space separated from the rest of the text intentionally. - Bienvenue dans la console RPC de %1. -Utilisez les touches de déplacement vers le haut et vers le bas pour parcourir l’historique et %2 pour effacer l’écran. -Utilisez %3 et %4 pour augmenter ou diminuer la taille de la police. -Tapez %5 pour un aperçu des commandes proposées. -Pour plus de précisions sur cette console, tapez %6. -%7AVERTISSEMENT : des escrocs sont à l’œuvre et demandent aux utilisateurs de taper des commandes ici, volant ainsi le contenu de leur porte-monnaie. N’utilisez pas cette console sans entièrement comprendre les ramifications d’une commande. %8 - - - Executing… - A console message indicating an entered command is currently being executed. - Éxécution… - - - (peer: %1) - (pair : %1) - - - via %1 - par %1 - - - Yes - Oui - - - No - Non - - - To - À - - - From - De - - - Ban for - Bannir pendant - - - Never - Jamais - - - Unknown - Inconnu - - - - ReceiveCoinsDialog - - &Amount: - &Montant : - - - &Label: - &Étiquette : - - - &Message: - M&essage : - - - An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. - Un message facultatif à joindre à la demande de paiement et qui sera affiché à l’ouverture de celle-ci. Note : Le message ne sera pas envoyé avec le paiement par le réseau Bitcoin. - - - An optional label to associate with the new receiving address. - Un étiquette facultative à associer à la nouvelle adresse de réception. - - - Use this form to request payments. All fields are <b>optional</b>. - Utiliser ce formulaire pour demander des paiements. Tous les champs sont <b>facultatifs</b>. - - - An optional amount to request. Leave this empty or zero to not request a specific amount. - Un montant facultatif à demander. Ne rien saisir ou un zéro pour ne pas demander de montant précis. - - - An optional label to associate with the new receiving address (used by you to identify an invoice). It is also attached to the payment request. - Une étiquette facultative à associer à la nouvelle adresse de réception (utilisée par vous pour identifier une facture). Elle est aussi jointe à la demande de paiement. - - - An optional message that is attached to the payment request and may be displayed to the sender. - Un message facultatif joint à la demande de paiement et qui peut être présenté à l’expéditeur. - - - &Create new receiving address - &Créer une nouvelle adresse de réception - - - Clear all fields of the form. - Effacer tous les champs du formulaire. - - - Clear - Effacer - - - Requested payments history - Historique des paiements demandés - - - Show the selected request (does the same as double clicking an entry) - Afficher la demande sélectionnée (comme double-cliquer sur une entrée) - - - Show - Afficher - - - Remove the selected entries from the list - Retirer les entrées sélectionnées de la liste - - - Remove - Retirer - - - Copy &URI - Copier l’&URI - - - &Copy address - &Copier l’adresse - - - Copy &label - Copier l’&étiquette - - - Copy &message - Copier le &message - - - Copy &amount - Copier le &montant - - - Not recommended due to higher fees and less protection against typos. - Non recommandé en raison de frais élevés et d'une faible protection contre les fautes de frappe. - - - Generates an address compatible with older wallets. - Génère une adresse compatible avec les anciens portefeuilles. - - - Generates a native segwit address (BIP-173). Some old wallets don't support it. - Génère une adresse segwit native (BIP-173). Certains anciens portefeuilles ne le supportent pas. - - - Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited. - Bech32m (BIP-350) est une mise à jour de Bech32, la prise en charge du portefeuille est encore limitée. - - - Could not unlock wallet. - Impossible de déverrouiller le porte-monnaie. - - - Could not generate new %1 address - Impossible de générer la nouvelle adresse %1 - - - - ReceiveRequestDialog - - Request payment to … - Demander de paiement à… - - - Address: - Adresse : - - - Amount: - Montant : - - - Label: - Étiquette : - - - Message: - Message : - - - Wallet: - Porte-monnaie : - - - Copy &URI - Copier l’&URI - - - Copy &Address - Copier l’&adresse - - - &Verify - &Vérifier - - - Verify this address on e.g. a hardware wallet screen - Confirmer p. ex. cette adresse sur l’écran d’un porte-monnaie matériel - - - &Save Image… - &Enregistrer l’image… - - - Payment information - Renseignements de paiement - - - Request payment to %1 - Demande de paiement à %1 - - - - RecentRequestsTableModel - - Label - Étiquette - - - (no label) - (aucune étiquette) - - - (no message) - (aucun message) - - - (no amount requested) - (aucun montant demandé) - - - Requested - Demandée - - - - SendCoinsDialog - - Send Coins - Envoyer des pièces - - - Coin Control Features - Fonctions de contrôle des pièces - - - automatically selected - sélectionné automatiquement - - - Insufficient funds! - Les fonds sont insuffisants - - - Quantity: - Quantité : - - - Bytes: - Octets : - - - Amount: - Montant : - - - Fee: - Frais : - - - After Fee: - Après les frais : - - - Change: - Monnaie : - - - If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. - Si cette option est activée et l’adresse de monnaie est vide ou invalide, la monnaie sera envoyée vers une adresse nouvellement générée. - - - Custom change address - Adresse personnalisée de monnaie - - - Transaction Fee: - Frais de transaction : - - - Using the fallbackfee can result in sending a transaction that will take several hours or days (or never) to confirm. Consider choosing your fee manually or wait until you have validated the complete chain. - L’utilisation de l’option « fallbackfee » (frais de repli) peut avoir comme effet d’envoyer une transaction qui prendra plusieurs heures ou jours pour être confirmée, ou qui ne le sera jamais. Envisagez de choisir vos frais manuellement ou attendez d’avoir validé l’intégralité de la chaîne. - - - Warning: Fee estimation is currently not possible. - Avertissement : L’estimation des frais n’est actuellement pas possible. - - - per kilobyte - par kilo-octet - - - Hide - Cacher - - - Recommended: - Recommandés : - - - Custom: - Personnalisés : - - - Send to multiple recipients at once - Envoyer à plusieurs destinataires à la fois - - - Add &Recipient - Ajouter un &destinataire - - - Clear all fields of the form. - Effacer tous les champs du formulaire. - - - Choose… - Choisir… - - - Hide transaction fee settings - Cacher les paramètres de frais de transaction - - - Specify a custom fee per kB (1,000 bytes) of the transaction's virtual size. - -Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 satoshis per kvB" for a transaction size of 500 virtual bytes (half of 1 kvB) would ultimately yield a fee of only 50 satoshis. - Indiquer des frais personnalisés par Ko (1 000 octets) de la taille virtuelle de la transaction. - -Note : Les frais étant calculés par octet, un taux de frais de « 100 satoshis par Kov » pour une transaction d’une taille de 500 octets (la moitié de 1 Kov) donneront des frais de seulement 50 satoshis. - - - When there is less transaction volume than space in the blocks, miners as well as relaying nodes may enforce a minimum fee. Paying only this minimum fee is just fine, but be aware that this can result in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. - Quand le volume des transactions est inférieur à l’espace dans les blocs, les mineurs et les nœuds de relais peuvent imposer des frais minimaux. Il est correct de payer ces frais minimaux, mais soyez conscient que cette transaction pourrait n’être jamais confirmée si la demande en transactions de bitcoins dépassait la capacité de traitement du réseau. - - - A too low fee might result in a never confirming transaction (read the tooltip) - Si les frais sont trop bas, cette transaction pourrait n’être jamais confirmée (lire l’infobulle) - - - (Smart fee not initialized yet. This usually takes a few blocks…) - (Les frais intelligents ne sont pas encore initialisés. Cela prend habituellement quelques blocs…) - - - Confirmation time target: - Estimation du délai de confirmation : - - - Enable Replace-By-Fee - Activer Remplacer-par-des-frais - - - With Replace-By-Fee (BIP-125) you can increase a transaction's fee after it is sent. Without this, a higher fee may be recommended to compensate for increased transaction delay risk. - Avec Remplacer-par-des-frais (BIP-125), vous pouvez augmenter les frais de transaction après qu’elle est envoyée. Sans cela, des frais plus élevés peuvent être recommandés pour compenser le risque accru de retard transactionnel. - - - Clear &All - &Tout effacer - - - Balance: - Solde : - - - Confirm the send action - Confirmer l’action d’envoi - - - S&end - E&nvoyer - - - Copy quantity - Copier la quantité - - - Copy amount - Copier le montant - - - Copy fee - Copier les frais - - - Copy after fee - Copier après les frais - - - Copy bytes - Copier les octets - - - Copy change - Copier la monnaie - - - %1 (%2 blocks) - %1 (%2 blocs) - - - Sign on device - "device" usually means a hardware wallet. - Signer sur l’appareil externe - - - Connect your hardware wallet first. - Connecter d’abord le porte-monnaie matériel. - - - Set external signer script path in Options -> Wallet - "External signer" means using devices such as hardware wallets. - Définir le chemin script du signataire externe dans Options -> Porte-monnaie - - - Cr&eate Unsigned - Cr&éer une transaction non signée - - - Creates a Partially Signed Bitcoin Transaction (PSBT) for use with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet. - Crée une transaction Bitcoin signée partiellement (TBSP) à utiliser, par exemple, avec un porte-monnaie %1 hors ligne ou avec un porte-monnaie matériel compatible TBSP. - - - %1 to '%2' - %1 à '%2' - - - %1 to %2 - %1 à %2 - - - To review recipient list click "Show Details…" - Pour réviser la liste des destinataires, cliquez sur « Afficher les détails… » - - - Sign failed - Échec de signature - - - External signer not found - "External signer" means using devices such as hardware wallets. - Le signataire externe est introuvable - - - External signer failure - "External signer" means using devices such as hardware wallets. - Échec du signataire externe - - - Save Transaction Data - Enregistrer les données de la transaction - - - Partially Signed Transaction (Binary) - Expanded name of the binary PSBT file format. See: BIP 174. - Transaction signée partiellement (fichier binaire) - - - PSBT saved - Popup message when a PSBT has been saved to a file - La TBSP a été enregistrée - - - External balance: - Solde externe : - - - or - ou - - - You can increase the fee later (signals Replace-By-Fee, BIP-125). - Vous pouvez augmenter les frais ultérieurement (signale Remplacer-par-des-frais, BIP-125). - - - Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can save or copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet. - Text to inform a user attempting to create a transaction of their current options. At this stage, a user can only create a PSBT. This string is displayed when private keys are disabled and an external signer is not available. - Veuillez réviser votre proposition de transaction. Une transaction Bitcoin partiellement signée (TBSP) sera produite, que vous pourrez enregistrer ou copier puis signer avec, par exemple, un porte-monnaie %1 hors ligne ou avec un porte-monnaie matériel compatible TBSP. - - - %1 from wallet '%2' - %1 du porte-monnaie « %2 ». - - - Do you want to create this transaction? - Message displayed when attempting to create a transaction. Cautionary text to prompt the user to verify that the displayed transaction details represent the transaction the user intends to create. - Voulez-vous créer cette transaction ? - - - Please, review your transaction. You can create and send this transaction or create a Partially Signed Bitcoin Transaction (PSBT), which you can save or copy and then sign with, e.g., an offline %1 wallet, or a PSBT-compatible hardware wallet. - Text to inform a user attempting to create a transaction of their current options. At this stage, a user can send their transaction or create a PSBT. This string is displayed when both private keys and PSBT controls are enabled. - Veuillez réviser votre transaction. Vous pouvez créer et envoyer cette transaction ou créer une transaction Bitcoin partiellement signée (TBSP), que vous pouvez enregistrer ou copier, et ensuite avec laquelle signer, par ex., un porte-monnaie %1 hors ligne ou avec un porte-monnaie matériel compatible TBSP. - - - Please, review your transaction. - Text to prompt a user to review the details of the transaction they are attempting to send. - Veuillez vérifier votre transaction. - - - Transaction fee - Frais de transaction - - - Not signalling Replace-By-Fee, BIP-125. - Ne signale pas Remplacer-par-des-frais, BIP-125. - - - Total Amount - Montant total - - - Unsigned Transaction - PSBT copied - Caption of "PSBT has been copied" messagebox - Transaction non signée - - - The PSBT has been copied to the clipboard. You can also save it. - Le PSBT a été copié dans le presse-papiers. Vous pouvez également le sauvegarder. - - - PSBT saved to disk - PSBT sauvegardé sur le disque - - - Confirm send coins - Confirmer l’envoi de pièces - - - Watch-only balance: - Solde juste-regarder : - - - The recipient address is not valid. Please recheck. - L’adresse du destinataire est invalide. Veuillez la revérifier. - - - The amount to pay must be larger than 0. - Le montant à payer doit être supérieur à 0. - - - The amount exceeds your balance. - Le montant dépasse votre solde. - - - The total exceeds your balance when the %1 transaction fee is included. - Le montant dépasse votre solde quand les frais de transaction de %1 sont compris. - - - Duplicate address found: addresses should only be used once each. - Une adresse identique a été trouvée : chaque adresse ne devrait être utilisée qu’une fois. - - - Transaction creation failed! - Échec de création de la transaction - - - A fee higher than %1 is considered an absurdly high fee. - Des frais supérieurs à %1 sont considérés comme ridiculement élevés. - - - Estimated to begin confirmation within %n block(s). - - Début de confirmation estimé à %n bloc. - Début de confirmation estimé à %n blocs. - - - - Warning: Invalid Bitcoin address - Avertissement : L’adresse Bitcoin est invalide - - - Warning: Unknown change address - Avertissement : L’adresse de monnaie est inconnue - - - Confirm custom change address - Confirmer l’adresse personnalisée de monnaie - - - The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure? - L’adresse que vous avez sélectionnée pour la monnaie ne fait pas partie de ce porte-monnaie. Les fonds de ce porte-monnaie peuvent en partie ou en totalité être envoyés vers cette adresse. Êtes-vous certain ? - - - (no label) - (aucune étiquette) - - - - SendCoinsEntry - - A&mount: - &Montant : - - - Pay &To: - &Payer à : - - - &Label: - &Étiquette : - - - Choose previously used address - Choisir une adresse utilisée précédemment - - - The Bitcoin address to send the payment to - L’adresse Bitcoin à laquelle envoyer le paiement - - - Paste address from clipboard - Collez l’adresse du presse-papiers - - - Remove this entry - Supprimer cette entrée - - - The amount to send in the selected unit - Le montant à envoyer dans l’unité sélectionnée - - - The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally. - Les frais seront déduits du montant envoyé. Le destinataire recevra moins de bitcoins que le montant saisi dans le champ de montant. Si plusieurs destinataires sont sélectionnés, les frais seront partagés également. - - - S&ubtract fee from amount - S&oustraire les frais du montant - - - Use available balance - Utiliser le solde disponible - - - Message: - Message : - - - Enter a label for this address to add it to the list of used addresses - Saisir une étiquette pour cette adresse afin de l’ajouter à la liste d’adresses utilisées - - - A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network. - Un message qui était joint à l’URI bitcoin: et qui sera stocké avec la transaction pour référence. Note : Ce message ne sera pas envoyé par le réseau Bitcoin. - - - - SendConfirmationDialog - - Send - Envoyer - - - Create Unsigned - Créer une transaction non signée - - - - SignVerifyMessageDialog - - Signatures - Sign / Verify a Message - Signatures – Signer ou vérifier un message - - - &Sign Message - &Signer un message - - - You can sign messages/agreements with your legacy (P2PKH) addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. - Vous pouvez signer des messages ou des accords avec vos anciennes adresses (P2PKH) pour prouver que vous pouvez recevoir des bitcoins à ces dernières. Ne signer rien de vague ou au hasard, car des attaques d’hameçonnage pourraient essayer de vous faire signer avec votre identité afin de l’usurper. Ne signez que des déclarations entièrement détaillées et que vous acceptez. - - - The Bitcoin address to sign the message with - L’adresse Bitcoin avec laquelle signer le message - - - Choose previously used address - Choisir une adresse utilisée précédemment - - - Paste address from clipboard - Collez l’adresse du presse-papiers - - - Enter the message you want to sign here - Saisir ici le message que vous voulez signer - - - Copy the current signature to the system clipboard - Copier la signature actuelle dans le presse-papiers - - - Sign the message to prove you own this Bitcoin address - Signer le message afin de prouver que vous détenez cette adresse Bitcoin - - - Sign &Message - Signer le &message - - - Reset all sign message fields - Réinitialiser tous les champs de signature de message - - - Clear &All - &Tout effacer - - - &Verify Message - &Vérifier un message - - - Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction! - Saisissez ci-dessous l’adresse du destinataire, le message (assurez-vous de copier fidèlement les retours à la ligne, les espaces, les tabulations, etc.) et la signature pour vérifier le message. Faites attention à ne pas déduire davantage de la signature que ce qui est contenu dans le message signé même, pour éviter d’être trompé par une attaque de l’intercepteur. Notez que cela ne fait que prouver que le signataire reçoit avec l’adresse et ne peut pas prouver la provenance d’une transaction. - - - The Bitcoin address the message was signed with - L’adresse Bitcoin avec laquelle le message a été signé - - - The signed message to verify - Le message signé à vérifier - - - The signature given when the message was signed - La signature donnée quand le message a été signé - - - Verify the message to ensure it was signed with the specified Bitcoin address - Vérifier le message pour s’assurer qu’il a été signé avec l’adresse Bitcoin indiquée - - - Verify &Message - Vérifier le &message - - - Reset all verify message fields - Réinitialiser tous les champs de vérification de message - - - Click "Sign Message" to generate signature - Cliquez sur « Signer le message » pour générer la signature - - - The entered address is invalid. - L’adresse saisie est invalide. - - - Please check the address and try again. - Veuillez vérifier l’adresse et réessayer. - - - The entered address does not refer to a legacy (P2PKH) key. Message signing for SegWit and other non-P2PKH address types is not supported in this version of %1. Please check the address and try again. - L’adresse saisie ne fait pas référence à une ancienne clé (P2PKH). La signature des messages n’est pas prise en charge pour SegWit ni pour les autres types d’adresses non P2PKH dans cette version de %1. Vérifiez l’adresse et réessayez. - - - Wallet unlock was cancelled. - Le déverrouillage du porte-monnaie a été annulé. - - - No error - Aucune erreur - - - Private key for the entered address is not available. - La clé privée pour l’adresse saisie n’est pas disponible. - - - Message signing failed. - Échec de signature du message. - - - Message signed. - Le message a été signé. - - - The signature could not be decoded. - La signature n’a pu être décodée. - - - Please check the signature and try again. - Veuillez vérifier la signature et réessayer. - - - The signature did not match the message digest. - La signature ne correspond pas au condensé du message. - - - Message verification failed. - Échec de vérification du message. - - - Message verified. - Le message a été vérifié. - - - - SplashScreen - - (press q to shutdown and continue later) - (appuyer sur q pour fermer et poursuivre plus tard) - - - press q to shutdown - Appuyer sur q pour fermer - - - - TrafficGraphWidget - - kB/s - Ko/s - - - - TransactionDesc - - conflicted with a transaction with %1 confirmations - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that conflicts with a confirmed transaction. - est en conflit avec une transaction ayant %1 confirmations - - - 0/unconfirmed, in memory pool - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that is in the memory pool. - 0/non confirmé, dans la pool de mémoire - - - 0/unconfirmed, not in memory pool - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that is not in the memory pool. - 0/non confirmé, pas dans la pool de mémoire - - - abandoned - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an abandoned transaction. - abandonnée - - - %1/unconfirmed - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents a transaction confirmed in at least one block, but less than 6 blocks. - %1/non confirmée - - - Status - État - - - Generated - Générée - - - From - De - - - unknown - inconnue - - - To - À - - - own address - votre adresse - - - watch-only - juste-regarder - - - label - étiquette - - - Credit - Crédit - - - matures in %n more block(s) - - arrivera à maturité dans %n bloc - arrivera à maturité dans %n blocs - - - - not accepted - non acceptée - - - Debit - Débit - - - Total debit - Débit total - - - Total credit - Crédit total - - - Transaction fee - Frais de transaction - - - Net amount - Montant net - - - Comment - Commentaire - - - Transaction ID - ID de la transaction - - - Transaction total size - Taille totale de la transaction - - - Transaction virtual size - Taille virtuelle de la transaction - - - Output index - Index des sorties - - - %1 (Certificate was not verified) - %1 (ce certificat n’a pas été vérifié) - - - Merchant - Marchand - - - Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. - Les pièces générées doivent mûrir pendant %1 blocs avant de pouvoir être dépensées. Quand vous avez généré ce bloc, il a été diffusé sur le réseau pour être ajouté à la chaîne de blocs. Si son intégration à la chaîne échoue, son état sera modifié en « non acceptée » et il ne sera pas possible de le dépenser. Cela peut arriver occasionnellement si un autre nœud génère un bloc à quelques secondes du vôtre. - - - Debug information - Renseignements de débogage - - - Inputs - Entrées - - - Amount - Montant - - - true - vrai - - - false - faux - - - - TransactionDescDialog - - This pane shows a detailed description of the transaction - Ce panneau affiche une description détaillée de la transaction - - - Details for %1 - Détails de %1 - - - - TransactionTableModel - - Label - Étiquette - - - Unconfirmed - Non confirmée - - - Abandoned - Abandonnée - - - Confirming (%1 of %2 recommended confirmations) - Confirmation (%1 sur %2 confirmations recommandées) - - - Confirmed (%1 confirmations) - Confirmée (%1 confirmations) - - - Conflicted - En conflit - - - Immature (%1 confirmations, will be available after %2) - Immature (%1 confirmations, sera disponible après %2) - - - Generated but not accepted - Générée mais non acceptée - - - Received with - Reçue avec - - - Received from - Reçue de - - - Sent to - Envoyée à - - - Mined - Miné - - - watch-only - juste-regarder - - - (n/a) - (n.d) - - - (no label) - (aucune étiquette) - - - Transaction status. Hover over this field to show number of confirmations. - État de la transaction. Survoler ce champ avec la souris pour afficher le nombre de confirmations. - - - Date and time that the transaction was received. - Date et heure de réception de la transaction. - - - Type of transaction. - Type de transaction. - - - Whether or not a watch-only address is involved in this transaction. - Une adresse juste-regarder est-elle ou non impliquée dans cette transaction. - - - User-defined intent/purpose of the transaction. - Intention, but de la transaction défini par l’utilisateur. - - - Amount removed from or added to balance. - Le montant a été ajouté ou soustrait du solde. - - - - TransactionView - - All - Toutes - - - Today - Aujourd’hui - - - This week - Cette semaine - - - This month - Ce mois - - - Last month - Le mois dernier - - - This year - Cette année - - - Received with - Reçue avec - - - Sent to - Envoyée à - - - Mined - Miné - - - Other - Autres - - - Enter address, transaction id, or label to search - Saisir l’adresse, l’ID de transaction ou l’étiquette à chercher - - - Min amount - Montant min. - - - Range… - Plage… - - - &Copy address - &Copier l’adresse - - - Copy &label - Copier l’&étiquette - - - Copy &amount - Copier le &montant - - - Copy transaction &ID - Copier l’&ID de la transaction - - - Copy &raw transaction - Copier la transaction &brute - - - Copy full transaction &details - Copier tous les &détails de la transaction - - - &Show transaction details - &Afficher les détails de la transaction - - - Increase transaction &fee - Augmenter les &frais de transaction - - - A&bandon transaction - A&bandonner la transaction - - - &Edit address label - &Modifier l’adresse de l’étiquette - - - Show in %1 - Transactions table context menu action to show the selected transaction in a third-party block explorer. %1 is a stand-in argument for the URL of the explorer. - Afficher dans %1 - - - Export Transaction History - Exporter l’historique transactionnel - - - Comma separated file - Expanded name of the CSV file format. See: https://en.wikipedia.org/wiki/Comma-separated_values. - Fichier séparé par des virgules - - - Confirmed - Confirmée - - - Watch-only - Juste-regarder - - - Label - Étiquette - - - Address - Adresse - - - ID - ID - - - Exporting Failed - Échec d’exportation - - - There was an error trying to save the transaction history to %1. - Une erreur est survenue lors de l’enregistrement de l’historique transactionnel vers %1. - - - Exporting Successful - L’exportation est réussie - - - The transaction history was successfully saved to %1. - L’historique transactionnel a été enregistré avec succès vers %1. - - - Range: - Plage : - - - to - à - - - - WalletFrame - - No wallet has been loaded. -Go to File > Open Wallet to load a wallet. -- OR - - Aucun porte-monnaie n’a été chargé. -Accédez à Fichier > Ouvrir un porte-monnaie pour en charger un. -– OU – - - - Create a new wallet - Créer un nouveau porte-monnaie - - - Error - Erreur - - - Unable to decode PSBT from clipboard (invalid base64) - Impossible de décoder la TBSP du presse-papiers (le Base64 est invalide) - - - Load Transaction Data - Charger les données de la transaction - - - Partially Signed Transaction (*.psbt) - Transaction signée partiellement (*.psbt) - - - PSBT file must be smaller than 100 MiB - Le fichier de la TBSP doit être inférieur à 100 Mio - - - Unable to decode PSBT - Impossible de décoder la TBSP - - - - WalletModel - - Send Coins - Envoyer des pièces - - - Fee bump error - Erreur d’augmentation des frais - - - Increasing transaction fee failed - Échec d’augmentation des frais de transaction - - - Do you want to increase the fee? - Asks a user if they would like to manually increase the fee of a transaction that has already been created. - Voulez-vous augmenter les frais ? - - - Current fee: - Frais actuels : - - - Increase: - Augmentation : - - - New fee: - Nouveaux frais : - - - Warning: This may pay the additional fee by reducing change outputs or adding inputs, when necessary. It may add a new change output if one does not already exist. These changes may potentially leak privacy. - Avertissement : Ceci pourrait payer les frais additionnel en réduisant les sorties de monnaie ou en ajoutant des entrées, si nécessaire. Une nouvelle sortie de monnaie pourrait être ajoutée si aucune n’existe déjà. Ces changements pourraient altérer la confidentialité. - - - Confirm fee bump - Confirmer l’augmentation des frais - - - Can't draft transaction. - Impossible de créer une ébauche de la transaction. - - - PSBT copied - La TBPS a été copiée - - - Fee-bump PSBT copied to clipboard - La TBSP des augmentations de frais a été copiée dans le presse-papiers. - - - Can't sign transaction. - Impossible de signer la transaction. - - - Could not commit transaction - Impossible de valider la transaction - - - Signer error - Erreur de signataire - - - Can't display address - Impossible d’afficher l’adresse - - - - WalletView - - &Export - &Exporter - - - Export the data in the current tab to a file - Exporter les données de l’onglet actuel vers un fichier - - - Backup Wallet - Sauvegarder le porte-monnaie - - - Wallet Data - Name of the wallet data file format. - Données du porte-monnaie - - - Backup Failed - Échec de sauvegarde - - - There was an error trying to save the wallet data to %1. - Une erreur est survenue lors de l’enregistrement des données du porte-monnaie vers %1. - - - Backup Successful - La sauvegarde est réussie - - - The wallet data was successfully saved to %1. - Les données du porte-monnaie ont été enregistrées avec succès vers %1. - - - Cancel - Annuler - - - - bitcoin-core - - The %s developers - Les développeurs de %s - - - %s corrupt. Try using the wallet tool bitcoin-wallet to salvage or restoring a backup. - %s est corrompu. Essayez l’outil bitcoin-wallet pour le sauver ou restaurez une sauvegarde. - - - %s failed to validate the -assumeutxo snapshot state. This indicates a hardware problem, or a bug in the software, or a bad software modification that allowed an invalid snapshot to be loaded. As a result of this, the node will shut down and stop using any state that was built on the snapshot, resetting the chain height from %d to %d. On the next restart, the node will resume syncing from %d without using any snapshot data. Please report this incident to %s, including how you obtained the snapshot. The invalid snapshot chainstate will be left on disk in case it is helpful in diagnosing the issue that caused this error. - %s a échoué à valider l'état instantané -assumeutxo. Cela indique un problème matériel, ou un bug dans le logiciel, ou une mauvaise modification du logiciel qui a permis de charger un instantané invalide. En conséquence, le nœud s'arrêtera et cessera d'utiliser tout état qui a été construit sur l'instantané, réinitialisant la hauteur de la chaîne de %d à %d. Au prochain redémarrage, le nœud reprendra la synchronisation à partir de %d sans utiliser de données d'instantané. Veuillez signaler cet incident à %s, en précisant comment vous avez obtenu l'instantané. L'état de chaîne d'instantané invalide sera conservé sur le disque au cas où il serait utile pour diagnostiquer le problème qui a causé cette erreur. - - - %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 doc/p2p-bad-ports.md for details and a full list. - %s demande d'écouter sur le port %u. Ce port est considéré comme "mauvais" et il est donc peu probable qu'un pair s'y connecte. Voir doc/p2p-bad-ports.md pour plus de détails et une liste complète. - - - Cannot downgrade wallet from version %i to version %i. Wallet version unchanged. - Impossible de rétrograder le porte-monnaie de la version %i à la version %i. La version du porte-monnaie reste inchangée. - - - Cannot upgrade a non HD split wallet from version %i to version %i without upgrading to support pre-split keypool. Please use version %i or no version specified. - Impossible de mettre à niveau un porte-monnaie divisé non-HD de la version %i vers la version %i sans mise à niveau pour prendre en charge la réserve de clés antérieure à la division. Veuillez utiliser la version %i ou ne pas indiquer de version. - - - Disk space for %s may not accommodate the block files. Approximately %u GB of data will be stored in this directory. - L'espace disque %s peut ne pas être suffisant pour les fichiers en bloc. Environ %u Go de données seront stockés dans ce répertoire. - - - Distributed under the MIT software license, see the accompanying file %s or %s - Distribué sous la licence MIT d’utilisation d’un logiciel, consultez le fichier joint %s ou %s - - - Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order when using assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height %s - Erreur de chargement du portefeuille. Le portefeuille nécessite le téléchargement de blocs, et le logiciel ne prend pas actuellement en charge le chargement de portefeuilles lorsque les blocs sont téléchargés dans le désordre lors de l'utilisation de snapshots assumeutxo. Le portefeuille devrait pouvoir être chargé avec succès une fois que la synchronisation des nœuds aura atteint la hauteur %s - - - Error reading %s! Transaction data may be missing or incorrect. Rescanning wallet. - Erreur de lecture de %s : soit les données de la transaction manquent soit elles sont incorrectes. Réanalyse du porte-monnaie. - - - Error starting/committing db txn for wallet transactions removal process - Erreur de lancement, de validation de la transaction de base de données pour la suppression des transactions du portemonnaie - - - Error: Dumpfile format record is incorrect. Got "%s", expected "format". - Erreur : L’enregistrement du format du fichier de vidage est incorrect. Est « %s », mais « format » est attendu. - - - Error: Dumpfile identifier record is incorrect. Got "%s", expected "%s". - Erreur : L’enregistrement de l’identificateur du fichier de vidage est incorrect. Est « %s », mais « %s » est attendu. - - - Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version %s - Erreur : La version du fichier de vidage n’est pas prise en charge. Cette version de bitcoin-wallet ne prend en charge que les fichiers de vidage version 1. Le fichier de vidage obtenu est de la version %s. - - - Error: Legacy wallets only support the "legacy", "p2sh-segwit", and "bech32" address types - Erreur : les porte-monnaie hérités ne prennent en charge que les types d’adresse « legacy », « p2sh-segwit », et « bech32 » - - - Error: Unable to produce descriptors for this legacy wallet. Make sure to provide the wallet's passphrase if it is encrypted. - Erreur : Impossible de produire des descripteurs pour ce portefeuille existant. Veillez à fournir la phrase secrète du portefeuille s'il est crypté. - - - File %s already exists. If you are sure this is what you want, move it out of the way first. - Le fichier %s existe déjà. Si vous confirmez l’opération, déplacez-le avant. - - - Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start. - peers.dat est invalide ou corrompu (%s). Si vous pensez que c’est un bogue, veuillez le signaler à %s. Pour y remédier, vous pouvez soit renommer, soit déplacer soit supprimer le fichier (%s) et un nouveau sera créé lors du prochain démarrage. - - - Invalid value detected for '-wallet' or '-nowallet'. '-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets - Une valeur invalide a été détectée pour « -wallet » ou pour « -nowallet ». « -wallet » nécessite une valeur de chaine alors que « -nowallet » n’accepte que « 1 » pour désactiver tous les portemonnaies - - - More than one onion bind address is provided. Using %s for the automatically created Tor onion service. - Plus d’une adresse oignon de liaison est indiquée. %s sera utilisée pour le service oignon de Tor créé automatiquement. - - - No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided. - Aucun fichier de vidage n’a été indiqué. Pour utiliser createfromdump, -dumpfile=<filename> doit être indiqué. - - - No dump file provided. To use dump, -dumpfile=<filename> must be provided. - Aucun fichier de vidage n’a été indiqué. Pour utiliser dump, -dumpfile=<filename> doit être indiqué. - - - No wallet file format provided. To use createfromdump, -format=<format> must be provided. - Aucun format de fichier de porte-monnaie n’a été indiqué. Pour utiliser createfromdump, -format=<format> doit être indiqué. - - - Option '-upnp' is set but UPnP support was dropped in version 29.0. Consider using '-natpmp' instead. - L’option « -upnp » est définie, mais la prise en charge d’UPnP a été abandonnée dans la version 29.0. Envisagez de la remplacer par « -natpmp ». - - - Please contribute if you find %s useful. Visit %s for further information about the software. - Si vous trouvez %s utile, veuillez y contribuer. Pour de plus de précisions sur le logiciel, rendez-vous sur %s. - - - Prune configured below the minimum of %d MiB. Please use a higher number. - L’élagage est configuré au-dessous du minimum de %d Mio. Veuillez utiliser un nombre plus élevé. - - - Prune mode is incompatible with -reindex-chainstate. Use full -reindex instead. - Le mode Prune est incompatible avec -reindex-chainstate. Utilisez plutôt -reindex complet. - - - Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) - Élagage : la dernière synchronisation de porte-monnaie va par-delà les données élaguées. Vous devez -reindex (réindexer, télécharger de nouveau toute la chaîne de blocs en cas de nœud élagué) - - - Rename of '%s' -> '%s' failed. You should resolve this by manually moving or deleting the invalid snapshot directory %s, otherwise you will encounter the same error again on the next startup. - La modification de '%s' -> '%s' a échoué. Vous devriez résoudre cela en déplaçant ou en supprimant manuellement le répertoire de snapshot invalide %s, sinon vous rencontrerez la même erreur à nouveau au prochain démarrage. - - - SQLiteDatabase: Unknown sqlite wallet schema version %d. Only version %d is supported - SQLiteDatabase : la version %d du schéma de porte-monnaie sqlite est inconnue. Seule la version %d est prise en charge - - - The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct - La base de données des blocs comprend un bloc qui semble provenir du futur. Cela pourrait être causé par la date et l’heure erronées de votre ordinateur. Ne reconstruisez la base de données des blocs que si vous êtes certain que la date et l’heure de votre ordinateur sont justes. - - - The transaction amount is too small to send after the fee has been deducted - Le montant de la transaction est trop bas pour être envoyé une fois que les frais ont été déduits - - - This error could occur if this wallet was not shutdown cleanly and was last loaded using a build with a newer version of Berkeley DB. If so, please use the software that last loaded this wallet - Cette erreur pourrait survenir si ce porte-monnaie n’a pas été fermé proprement et s’il a été chargé en dernier avec une nouvelle version de Berkeley DB. Si c’est le cas, veuillez utiliser le logiciel qui a chargé ce porte-monnaie en dernier. - - - This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - Ceci est une préversion de test — son utilisation est entièrement à vos risques — ne l’utilisez pour miner ou pour des applications marchandes - - - This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection. - Les frais maximaux de transaction que vous payez (en plus des frais habituels) afin de prioriser une dépense non partielle plutôt qu’une sélection normale de pièces. - - - This is the transaction fee you may discard if change is smaller than dust at this level - Les frais de transaction que vous pouvez ignorer si la monnaie rendue est inférieure à la poussière à ce niveau - - - This is the transaction fee you may pay when fee estimates are not available. - Il s’agit des frais de transaction que vous pourriez payer si aucune estimation de frais n’est proposée. - - - Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. - La taille totale de la chaîne de version de réseau (%i) dépasse la longueur maximale (%i). Réduire le nombre ou la taille de uacomments. - - - Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate. - Impossible de relire les blocs. Vous devrez reconstruire la base de données avec -reindex-chainstate. - - - Unknown wallet file format "%s" provided. Please provide one of "bdb" or "sqlite". - Le format de fichier porte-monnaie « %s » indiqué est inconnu. Veuillez soit indiquer « bdb » soit « sqlite ». - - - Unsupported category-specific logging level %1$s=%2$s. Expected %1$s=<category>:<loglevel>. Valid categories: %3$s. Valid loglevels: %4$s. - Niveau de journalisation spécifique à la catégorie non pris en charge %1$s=%2$s. Attendu %1$s=<catégorie>:<niveaudejournal>. Catégories valides : %3$s. Niveaux de journalisation valides : %4$s. - - - Unsupported chainstate database format found. Please restart with -reindex-chainstate. This will rebuild the chainstate database. - Le format de la base de données chainstate n'est pas supporté. Veuillez redémarrer avec -reindex-chainstate. Cela reconstruira la base de données chainstate. - - - Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future. - Portefeuille créé avec succès. Le type de portefeuille ancien est en cours de suppression et la prise en charge de la création et de l'ouverture des portefeuilles anciens sera supprimée à l'avenir. - - - Wallet loaded successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future. Legacy wallets can be migrated to a descriptor wallet with migratewallet. - Portefeuille chargé avec succès. Le type de portefeuille existant est obsolète et la prise en charge de la création et de l'ouverture de portefeuilles existants sera supprimée à l'avenir. Les anciens portefeuilles peuvent être migrés vers un portefeuille descripteur avec migratewallet. - - - Warning: Dumpfile wallet format "%s" does not match command line specified format "%s". - Avertissement : Le format du fichier de vidage de porte-monnaie « %s » ne correspond pas au format « %s » indiqué dans la ligne de commande. - - - Warning: Private keys detected in wallet {%s} with disabled private keys - Avertissement : Des clés privées ont été détectées dans le porte-monnaie {%s} avec des clés privées désactivées - - - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. - Avertissement : Nous ne semblons pas être en accord complet avec nos pairs. Une mise à niveau pourrait être nécessaire pour vous ou pour d’autres nœuds du réseau. - - - Witness data for blocks after height %d requires validation. Please restart with -reindex. - Les données témoin pour les blocs postérieurs à la hauteur %d exigent une validation. Veuillez redémarrer avec -reindex. - - - You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain - Vous devez reconstruire la base de données en utilisant -reindex afin de revenir au mode sans élagage. Ceci retéléchargera complètement la chaîne de blocs. - - - %s is set very high! - La valeur %s est très élevée - - - -maxmempool must be at least %d MB - -maxmempool doit être d’au moins %d Mo - - - Cannot obtain a lock on directory %s. %s is probably already running. - Impossible d’obtenir un verrou sur le dossier %s. %s fonctionne probablement déjà. - - - Cannot resolve -%s address: '%s' - Impossible de résoudre l’adresse -%s : « %s » - - - Cannot set -forcednsseed to true when setting -dnsseed to false. - Impossible de définir -forcednsseed comme vrai si -dnsseed est défini comme faux. - - - Cannot set -peerblockfilters without -blockfilterindex. - Impossible de définir -peerblockfilters sans -blockfilterindex - - - %s is set very high! Fees this large could be paid on a single transaction. - %s est très élevé ! Des frais aussi importants pourraient être payés sur une seule transaction. - - - Cannot provide specific connections and have addrman find outgoing connections at the same time. - Il est impossible d’indiquer des connexions précises et en même temps de demander à addrman de trouver les connexions sortantes. - - - Error loading %s: External signer wallet being loaded without external signer support compiled - Erreur de chargement de %s : le porte-monnaie signataire externe est chargé sans que la prise en charge de signataires externes soit compilée - - - Error reading %s! All keys read correctly, but transaction data or address metadata may be missing or incorrect. - Erreur de lecture de %s! Toutes les clés ont été lues correctement, mais les données de transaction ou les métadonnées d'adresse peuvent être manquantes ou incorrectes. - - - Error: Address book data in wallet cannot be identified to belong to migrated wallets - Erreur : Les données du carnet d'adresses du portefeuille ne peuvent pas être identifiées comme appartenant à des portefeuilles migrés - - - Error: Duplicate descriptors created during migration. Your wallet may be corrupted. - Erreur : Descripteurs en double créés pendant la migration. Votre portefeuille est peut-être corrompu. - - - Error: Transaction %s in wallet cannot be identified to belong to migrated wallets - Erreur : La transaction %s dans le portefeuille ne peut pas être identifiée comme appartenant aux portefeuilles migrés. - - - Failed to calculate bump fees, because unconfirmed UTXOs depend on enormous cluster of unconfirmed transactions. - Échec du calcul des frais de majoration, car les UTXO non confirmés dépendent d'un énorme groupe de transactions non confirmées. - - - Failed to remove snapshot chainstate dir (%s). Manually remove it before restarting. - - Échec de suppression du répertoire de l’instantané d’état de la chaîne (%s). Supprimez-le manuellement avant de redémarrer. - - - Failed to rename invalid peers.dat file. Please move or delete it and try again. - Échec de renommage du fichier peers.dat invalide. Veuillez le déplacer ou le supprimer, puis réessayer. - - - Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s. - L'estimation des frais a échoué. Fallbackfee est désactivé. Attendez quelques blocs ou activez %s. - - - Flushing block file to disk failed. This is likely the result of an I/O error. - Échec de vidage du fichier des blocs sur le disque, probablement à cause d’une erreur d’E/S. - - - Flushing undo file to disk failed. This is likely the result of an I/O error. - Échec de vidage du fichier d’annulation sur le disque, probablement à cause d’une erreur d’E/S. - - - Incompatible options: -dnsseed=1 was explicitly specified, but -onlynet forbids connections to IPv4/IPv6 - Options incompatibles : -dnsseed=1 a été explicitement spécifié, mais -onlynet interdit les connexions vers IPv4/IPv6 - - - Invalid amount for %s=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) - Montant non valide pour %s=<amount> : '%s' (doit être au moins égal au minrelay fee de %s pour éviter les transactions bloquées) - - - Maximum transaction weight is less than transaction weight without inputs - Le poids maximal de la transaction est inférieur au poids de la transaction sans entrées - - - Maximum transaction weight is too low, can not accommodate change output - Le poids maximal de la transaction est trop faible et ne permet pas les sorties de monnaie - - - Outbound connections restricted to CJDNS (-onlynet=cjdns) but -cjdnsreachable is not provided - Connexions sortantes limitées à CJDNS (-onlynet=cjdns) mais -cjdnsreachable n'est pas fourni - - - Outbound connections restricted to Tor (-onlynet=onion) but the proxy for reaching the Tor network is explicitly forbidden: -onion=0 - Connexions sortantes limitées à Tor (-onlynet=onion) mais le proxy pour atteindre le réseau Tor est explicitement interdit : -onion=0 - - - Outbound connections restricted to Tor (-onlynet=onion) but the proxy for reaching the Tor network is not provided: none of -proxy, -onion or -listenonion is given - Connexions sortantes limitées à Tor (-onlynet=onion) mais le proxy pour atteindre le réseau Tor n'est pas fourni : aucun des paramètres -proxy, -onion ou -listenonion n'est donné - - - Outbound connections restricted to i2p (-onlynet=i2p) but -i2psam is not provided - Connexions sortantes limitées à i2p (-onlynet=i2p) mais -i2psam n'est pas fourni - - - Rename of '%s' -> '%s' failed. Cannot clean up the background chainstate leveldb directory. - Échec de renommage de « %s » en « %s ». Impossible de nettoyer le répertoire de la base de données d’état de chaîne d’arrière-plan. - - - Specified -blockmaxweight (%d) exceeds consensus maximum block weight (%d) - Le poids maximal de bloc -blockmaxweight indiqué (%d) dépasse le poids maximal de bloc du consensus (%d). - - - Specified -blockreservedweight (%d) exceeds consensus maximum block weight (%d) - Le poids réservé de bloc -blockreservedweight indiqué (%d) dépasse le poids maximal de bloc du consensus (%d). - - - Specified -blockreservedweight (%d) is lower than minimum safety value of (%d) - Le poids réservé de bloc -blockreservedweight indiqué (%d) est inférieur à la valeur minimale de sécurité de (%d) - - - The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs - La combinaison des entrées présélectionnées et de la sélection automatique des entrées du porte-monnaie dépasse le poids maximal de la transaction. Essayez d’envoyer un montant inférieur ou de consolider manuellement les UTXO de votre porte-monnaie. - - - The inputs size exceeds the maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs - La taille des entrées dépasse le poids maximum. Veuillez essayer d'envoyer un montant plus petit ou de consolider manuellement les UTXOs de votre portefeuille - - - The preselected coins total amount does not cover the transaction target. Please allow other inputs to be automatically selected or include more coins manually - Le montant total des pièces présélectionnées ne couvre pas l'objectif de la transaction. Veuillez permettre à d'autres entrées d'être sélectionnées automatiquement ou inclure plus de pièces manuellement - - - Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input - La transaction nécessite une destination d'une valeur non nulle, un ratio de frais non nul, ou une entrée présélectionnée. - - - UTXO snapshot failed to validate. Restart to resume normal initial block download, or try loading a different snapshot. - La validation de la snapshot UTXO a échoué. Redémarrez pour reprendre le téléchargement normal du bloc initial, ou essayez de charger une autre snapshot. - - - Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool - Les UTXO non confirmés sont disponibles, mais les dépenser crée une chaîne de transactions qui sera rejetée par le mempool - - - Unexpected legacy entry in descriptor wallet found. Loading wallet %s - -The wallet might have been tampered with or created with malicious intent. - - Une entrée héritée inattendue dans le portefeuille de descripteurs a été trouvée. Chargement du portefeuille %s - -Le portefeuille peut avoir été altéré ou créé avec des intentions malveillantes. - - - - Unrecognized descriptor found. Loading wallet %s - -The wallet might had been created on a newer version. -Please try running the latest software version. - - Descripteur non reconnu trouvé. Chargement du portefeuille %s - -Le portefeuille a peut-être été créé avec une version plus récente. -Veuillez essayer d'utiliser la dernière version du logiciel. - - - - Your computer's date and time appear to be more than %d minutes out of sync with the network, this may lead to consensus failure. After you've confirmed your computer's clock, this message should no longer appear when you restart your node. Without a restart, it should stop showing automatically after you've connected to a sufficient number of new outbound peers, which may take some time. You can inspect the `timeoffset` field of the `getpeerinfo` and `getnetworkinfo` RPC methods to get more info. - La date et l’heure de votre ordinateur semblent décalées de plus de %d minutes par rapport au réseau, ce qui peut entraîner un échec de consensus. Après avoir confirmé l’heure de votre ordinateur, ce message ne devrait plus s’afficher après redémarrage de votre nœud. Sans redémarrage, il devrait cesser de s’afficher automatiquement si vous vous connectez à suffisamment de nouveaux pairs sortants, ce qui peut prendre du temps. Pour plus de précisions, vous pouvez inspecter le champ `timeoffset` des méthodes RPC `getpeerinfo` et `getnetworkinfo`. - - - -Unable to cleanup failed migration - -Impossible de corriger l'échec de la migration - - - -Unable to restore backup of wallet. - -Impossible de restaurer la sauvegarde du portefeuille. - - - whitebind may only be used for incoming connections ("out" was passed) - « whitebind » ne peut être utilisé que pour les connexions entrantes (« out » a été passé) - - - A fatal internal error occurred, see debug.log for details: - Une erreur interne fatale est survenue. Pour plus de précisions, consultez debug.log : - - - Assumeutxo data not found for the given blockhash '%s'. - Les données Assumeutxo sont introuvables pour l’empreinte de bloc « %s » donnée. - - - Block verification was interrupted - La vérification des blocs a été interrompue - - - Cannot write to directory '%s'; check permissions. - Impossible d’écrire dans le dossier « %s » ; vérifiez les droits. - - - Config setting for %s only applied on %s network when in [%s] section. - Paramètre de configuration pour %s qui n’est appliqué sur le réseau %s que s’il se trouve dans la section [%s]. - - - Copyright (C) %i-%i - Tous droits réservés © %i à %i - - - Corrupt block found indicating potential hardware failure. - Un bloc corrompu a été détecté, ce qui indique une défaillance matérielle possible. - - - Corrupted block database detected - Une base de données des blocs corrompue a été détectée - - - Could not find asmap file %s - Le fichier asmap %s est introuvable - - - Could not parse asmap file %s - Impossible d’analyser le fichier asmap %s - - - Disk space is too low! - L’espace disque est trop faible - - - Done loading - Le chargement est terminé - - - Dump file %s does not exist. - Le fichier de vidage %s n’existe pas. - - - Elliptic curve cryptography sanity check failure. %s is shutting down. - Échec du contrôle d’intégrité de la cryptographie à courbe elliptique. Fermeture de %s. - - - Error creating %s - Erreur de création de %s - - - Error initializing block database - Erreur d’initialisation de la base de données des blocs - - - Error initializing wallet database environment %s! - Erreur d’initialisation de l’environnement de la base de données du porte-monnaie %s  - - - Error loading %s - Erreur de chargement de %s - - - Error loading %s: Private keys can only be disabled during creation - Erreur de chargement de %s : les clés privées ne peuvent être désactivées qu’à la création - - - Error loading %s: Wallet corrupted - Erreur de chargement de %s : le porte-monnaie est corrompu - - - Error loading %s: Wallet requires newer version of %s - Erreur de chargement de %s : le porte-monnaie exige une version plus récente de %s - - - Error loading block database - Erreur de chargement de la base de données des blocs - - - Error loading databases - Erreur de chargement des bases de données - - - Error opening block database - Erreur d’ouverture de la base de données des blocs - - - Error opening coins database - Erreur d’ouverture de la base de données des pièces - - - Error reading configuration file: %s - Erreur de lecture du fichier de configuration : %s - - - Error reading from database, shutting down. - Erreur de lecture de la base de données, fermeture en cours - - - Error reading next record from wallet database - Erreur de lecture de l’enregistrement suivant de la base de données du porte-monnaie - - - Error: Cannot extract destination from the generated scriptpubkey - Erreur : Impossible d'extraire la destination du scriptpubkey généré - - - Error: Couldn't create cursor into database - Erreur : Impossible de créer le curseur dans la base de données - - - Error: Disk space is low for %s - Erreur : Il reste peu d’espace disque sur %s - - - Error: Dumpfile checksum does not match. Computed %s, expected %s - Erreur : La somme de contrôle du fichier de vidage ne correspond pas. Calculée %s, attendue %s - - - Error: Failed to create new watchonly wallet - Erreur : Echec de la création d'un nouveau porte-monnaie Watchonly - - - Error: Got key that was not hex: %s - Erreur : La clé obtenue n’était pas hexadécimale : %s - - - Error: Got value that was not hex: %s - Erreur : La valeur obtenue n’était pas hexadécimale : %s - - - Error: Keypool ran out, please call keypoolrefill first - Erreur : La réserve de clés est épuisée, veuillez d’abord appeler « keypoolrefill » - - - Error: Missing checksum - Erreur : Aucune somme de contrôle n’est indiquée - - - Error: No %s addresses available. - Erreur : Aucune adresse %s n’est disponible. - - - Error: This wallet already uses SQLite - Erreur : Ce portefeuille utilise déjà SQLite - - - Error: This wallet is already a descriptor wallet - Erreur : Ce portefeuille est déjà un portefeuille de descripteurs - - - Error: Unable to begin reading all records in the database - Erreur : Impossible de commencer à lire tous les enregistrements de la base de données - - - Error: Unable to make a backup of your wallet - Erreur : Impossible d'effectuer une sauvegarde de votre portefeuille - - - Error: Unable to parse version %u as a uint32_t - Erreur : Impossible d’analyser la version %u en tant que uint32_t - - - Error: Unable to read all records in the database - Erreur : Impossible de lire tous les enregistrements de la base de données - - - Error: Unable to read wallet's best block locator record - Erreur : Impossible de lire l’enregistrement du meilleur bloc du porte-monnaie. - - - Error: Unable to remove watchonly address book data - Erreur : Impossible de supprimer les données du carnet d'adresses en mode veille - - - Error: Unable to write data to disk for wallet %s - Erreur : Impossible d’écrire les données sur le disque pour le portemonnaie %s - - - Error: Unable to write record to new wallet - Erreur : Impossible d’écrire l’enregistrement dans le nouveau porte-monnaie - - - Error: Unable to write solvable wallet best block locator record - Erreur : Impossible d’écrire l’enregistrement du localisateur du meilleur bloc soluble du porte-monnaie - - - Error: Unable to write watchonly wallet best block locator record - Erreur : Impossible d’écrire l’enregistrement du localisateur du meilleur bloc du porte-monnaie juste-regarder - - - Error: database transaction cannot be executed for wallet %s - Erreur ; La transaction de la base de données ne peut pas être exécutée pour le porte-monnaie %s - - - Failed to connect best block (%s). - Échec de connexion du meilleur bloc (%s). - - - Failed to disconnect block. - Échec de déconnexion du bloc. - - - Failed to listen on any port. Use -listen=0 if you want this. - Échec d'écoute sur tous les ports. Si cela est voulu, utiliser -listen=0. - - - Failed to read block. - Échec de lecture du bloc. - - - Failed to rescan the wallet during initialization - Échec de réanalyse du porte-monnaie lors de l’initialisation - - - Failed to start indexes, shutting down.. - Échec du démarrage des index, arrêt. - - - Failed to verify database - Échec de vérification de la base de données - - - Failed to write block. - Échec d’écriture du bloc. - - - Failed to write to block index database. - Échec d’écriture dans la base de données d’index des blocs. - - - Failed to write to coin database. - Échec d’écriture dans la base de données des pièces. - - - Failed to write undo data. - Échec d’écriture des données d’annulation. - - - Failure removing transaction: %s - Échec de suppression de la transaction :%s - - - Fee rate (%s) is lower than the minimum fee rate setting (%s) - Le taux de frais (%s) est inférieur au taux minimal de frais défini (%s) - - - Ignoring duplicate -wallet %s. - Ignore -wallet %s en double. - - - Importing… - Importation… - - - Incorrect or no genesis block found. Wrong datadir for network? - Bloc de genèse incorrect ou introuvable. Mauvais datadir pour le réseau ? - - - Initialization sanity check failed. %s is shutting down. - Échec d’initialisation du test de cohérence. %s est en cours de fermeture. - - - Input not found or already spent - L’entrée est introuvable ou a déjà été dépensée - - - Insufficient dbcache for block verification - Insuffisance de dbcache pour la vérification des blocs - - - Insufficient funds - Les fonds sont insuffisants - - - Invalid -i2psam address or hostname: '%s' - L’adresse ou le nom d’hôte -i2psam est invalide : « %s » - - - Invalid -onion address or hostname: '%s' - L’adresse ou le nom d’hôte -onion est invalide : « %s » - - - Invalid -proxy address or hostname: '%s' - L’adresse ou le nom d’hôte -proxy est invalide : « %s » - - - Invalid P2P permission: '%s' - L’autorisation P2P est invalide : « %s » - - - Invalid amount for %s=<amount>: '%s' (must be at least %s) - Montant non valide pour %s=<amount> : '%s' (doit être au moins %s) - - - Invalid amount for %s=<amount>: '%s' - Montant non valide pour %s=<amount> : '%s' - - - Invalid amount for -%s=<amount>: '%s' - Le montant est invalide pour -%s=<amount> : « %s » - - - Invalid netmask specified in -whitelist: '%s' - Le masque réseau indiqué dans -whitelist est invalide : « %s » - - - Invalid port specified in %s: '%s' - Port non valide spécifié dans %s: '%s' - - - Invalid pre-selected input %s - Entrée présélectionnée non valide %s - - - Listening for incoming connections failed (listen returned error %s) - L'écoute des connexions entrantes a échoué ( l'écoute a renvoyé une erreur %s) - - - Loading P2P addresses… - Chargement des adresses P2P… - - - Loading banlist… - Chargement de la liste d’interdiction… - - - Loading block index… - Chargement de l’index des blocs… - - - Loading wallet… - Chargement du porte-monnaie… - - - Maximum transaction weight must be between %d and %d - Le poids maximal de la transaction doit être compris entre %d et %d - - - Missing amount - Le montant manque - - - Missing solving data for estimating transaction size - Il manque des données de résolution pour estimer la taille de la transaction - - - Need to specify a port with -whitebind: '%s' - Un port doit être indiqué avec -whitebind : « %s » - - - No addresses available - Aucune adresse n’est disponible - - - Not found pre-selected input %s - Entrée présélectionnée introuvable %s - - - Not solvable pre-selected input %s - Entrée présélectionnée non solvable %s - - - Only direction was set, no permissions: '%s' - Seule la direction a été définie, sans permissions : « %s » - - - Prune cannot be configured with a negative value. - L’élagage ne peut pas être configuré avec une valeur négative - - - Prune mode is incompatible with -txindex. - Le mode élagage n’est pas compatible avec -txindex - - - Pruning blockstore… - Élagage du magasin de blocs… - - - Reducing -maxconnections from %d to %d, because of system limitations. - Réduction de -maxconnections de %d à %d, due aux restrictions du système. - - - Replaying blocks… - Relecture des blocs… - - - Rescanning… - Réanalyse… - - - SQLiteDatabase: Failed to execute statement to verify database: %s - SQLiteDatabase : échec d’exécution de l’instruction pour vérifier la base de données : %s - - - SQLiteDatabase: Failed to prepare statement to verify database: %s - SQLiteDatabase : échec de préparation de l’instruction pour vérifier la base de données : %s - - - SQLiteDatabase: Failed to read database verification error: %s - SQLiteDatabase : échec de lecture de l’erreur de vérification de la base de données : %s - - - SQLiteDatabase: Unexpected application id. Expected %u, got %u - SQLiteDatabase : l’ID de l’application est inattendu. %u attendu, %u retourné - - - Section [%s] is not recognized. - La section [%s] n’est pas reconnue - - - Signer did not echo address - Le signataire n’a pas fait écho à l’adresse - - - Signer echoed unexpected address %s - Le signataire a renvoyé une adresse inattendue %s - - - Signer returned error: %s - Le signataire a renvoyé une erreur : %s - - - Signing transaction failed - Échec de signature de la transaction - - - Specified -walletdir "%s" does not exist - Le -walletdir indiqué « %s » n’existe pas - - - Specified -walletdir "%s" is a relative path - Le -walletdir indiqué « %s » est un chemin relatif - - - Specified -walletdir "%s" is not a directory - Le -walletdir indiqué « %s » n’est pas un répertoire - - - Specified blocks directory "%s" does not exist. - Le répertoire des blocs indiqué « %s » n’existe pas - - - Specified data directory "%s" does not exist. - Le répertoire de données spécifié "%s" n'existe pas. - - - Starting network threads… - Démarrage des processus réseau… - - - System error while flushing: %s - Erreur système lors du vidage : %s - - - System error while loading external block file: %s - Erreur système lors du chargement d’un fichier de blocs externe : %s - - - System error while saving block to disk: %s - Erreur système lors de l’enregistrement du bloc sur le disque : %s - - - The source code is available from %s. - Le code source est publié sur %s. - - - The specified config file %s does not exist - Le fichier de configuration indiqué %s n’existe pas - - - The transaction amount is too small to pay the fee - Le montant de la transaction est trop bas pour que les frais soient payés - - - The transactions removal process can only be executed within a db txn - Le processus de suppression des transactions ne peut être exécuté que dans une transaction .de base de données - - - The wallet will avoid paying less than the minimum relay fee. - Le porte-monnaie évitera de payer moins que les frais minimaux de relais. - - - There is no ScriptPubKeyManager for this address - Il n’y a pas de « ScriptPubKeyManager » pour cette adresse. - - - This is experimental software. - Ce logiciel est expérimental. - - - This is the minimum transaction fee you pay on every transaction. - Il s’agit des frais minimaux que vous payez pour chaque transaction. - - - This is the transaction fee you will pay if you send a transaction. - Il s’agit des frais minimaux que vous payerez si vous envoyez une transaction. - - - Transaction %s does not belong to this wallet - La transaction %s n’appartient pas à ce porte-monnaie - - - Transaction amount too small - Le montant de la transaction est trop bas - - - Transaction amounts must not be negative - Les montants des transactions ne doivent pas être négatifs - - - Transaction change output index out of range - L’index des sorties de monnaie des transactions est hors échelle - - - Transaction must have at least one recipient - La transaction doit comporter au moins un destinataire - - - Transaction needs a change address, but we can't generate it. - Une adresse de monnaie est nécessaire à la transaction, mais nous ne pouvons pas la générer. - - - Transaction too large - La transaction est trop grosse - - - Unable to bind to %s on this computer (bind returned error %s) - Impossible de se lier à %s sur cet ordinateur (la liaison a retourné l’erreur %s) - - - Unable to bind to %s on this computer. %s is probably already running. - Impossible de se lier à %s sur cet ordinateur. %s fonctionne probablement déjà - - - Unable to create the PID file '%s': %s - Impossible de créer le fichier PID « %s » : %s - - - Unable to find UTXO for external input - Impossible de trouver l'UTXO pour l'entrée externe - - - Unable to generate initial keys - Impossible de générer les clés initiales - - - Unable to generate keys - Impossible de générer les clés - - - Unable to open %s for writing - Impossible d’ouvrir %s en écriture - - - Unable to parse -maxuploadtarget: '%s' - Impossible d’analyser -maxuploadtarget : « %s » - - - Unable to start HTTP server. See debug log for details. - Impossible de démarrer le serveur HTTP. Consulter le journal de débogage pour plus de précisions. - - - Unable to unload the wallet before migrating - Impossible de vider le portefeuille avant la migration - - - Unknown -blockfilterindex value %s. - La valeur -blockfilterindex %s est inconnue. - - - Unknown address type '%s' - Le type d’adresse « %s » est inconnu - - - Unknown change type '%s' - Le type de monnaie « %s » est inconnu - - - Unknown network specified in -onlynet: '%s' - Un réseau inconnu est indiqué dans -onlynet : « %s » - - - Unknown new rules activated (versionbit %i) - Les nouvelles règles inconnues sont activées (versionbit %i) - - - Unrecognised option "%s" provided in -test=<option>. - Une option non reconnue « %s » a été indiquée dans -test=<option>. - - - Unsupported global logging level %s=%s. Valid values: %s. - Niveau de journalisation global non pris en charge %s=%s. Valeurs valides : %s. - - - Wallet file creation failed: %s - Échec de création du fichier du porte-monnaie : %s - - - acceptstalefeeestimates is not supported on %s chain. - acceptstalefeeestimates n'est pas pris en charge sur la chaîne %s. - - - Unsupported logging category %s=%s. - La catégorie de journalisation %s=%s n’est pas prise en charge - - - Do you want to rebuild the databases now? - Voulez-vous reconstruire les bases de données maintenant ? - - - Error: Could not add watchonly tx %s to watchonly wallet - Erreur : Impossible d’ajouter la transaction juste-regarder %s au portefeuille juste-regarder - - - Error: Could not delete watchonly transactions. - Erreur : Impossible d’effacer les transactions juste-regarder. - - - Error: Wallet does not exist - Erreur : Le portemonnaie n’existe pas - - - Error: cannot remove legacy wallet records - Erreur : Impossible de supprimer les enregistrements d’anciens portemonnaies - - - Not enough file descriptors available. %d available, %d required. - Trop peu de descripteurs de fichiers sont proposés. %d proposés, %d requis - - - User Agent comment (%s) contains unsafe characters. - Le commentaire de l’agent utilisateur (%s) comporte des caractères dangereux - - - Verifying blocks… - Vérification des blocs… - - - Verifying wallet(s)… - Vérification des porte-monnaie… - - - Wallet needed to be rewritten: restart %s to complete - Le porte-monnaie devait être réécrit : redémarrer %s pour terminer l’opération. - - - Settings file could not be read - Impossible de lire le fichier des paramètres - - - Settings file could not be written - Impossible d’écrire le fichier de paramètres - - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_fr_LU.ts b/src/qt/locale/bitcoin_fr_LU.ts deleted file mode 100644 index cf77a0360be..00000000000 --- a/src/qt/locale/bitcoin_fr_LU.ts +++ /dev/null @@ -1,5093 +0,0 @@ - - - AddressBookPage - - Right-click to edit address or label - Clic droit pour modifier l'adresse ou l'étiquette - - - Create a new address - Créer une nouvelle adresse - - - &New - &Nouvelle - - - Copy the currently selected address to the system clipboard - Copier l’adresse sélectionnée actuellement dans le presse-papiers - - - &Copy - &Copier - - - C&lose - &Fermer - - - Delete the currently selected address from the list - Supprimer l’adresse sélectionnée actuellement de la liste - - - Enter address or label to search - Saisir une adresse ou une étiquette à rechercher - - - Export the data in the current tab to a file - Exporter les données de l’onglet actuel vers un fichier - - - &Export - &Exporter - - - &Delete - &Supprimer - - - Choose the address to send coins to - Choisir l’adresse à laquelle envoyer des pièces - - - Choose the address to receive coins with - Choisir l’adresse avec laquelle recevoir des pièces - - - C&hoose - C&hoisir - - - These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Ce sont vos adresses Bitcoin pour envoyer des paiements. Vérifiez toujours le montant et l’adresse du destinataire avant d’envoyer des pièces. - - - These are your Bitcoin addresses for receiving payments. Use the 'Create new receiving address' button in the receive tab to create new addresses. -Signing is only possible with addresses of the type 'legacy'. - Il s'agit de vos adresses Bitcoin pour la réception des paiements. Utilisez le bouton "Créer une nouvelle adresse de réception" dans l'onglet "Recevoir" pour créer de nouvelles adresses. -La signature n'est possible qu'avec les adresses de type "patrimoine". - - - &Copy Address - &Copier l’adresse - - - Copy &Label - Copier l’é&tiquette - - - &Edit - &Modifier - - - Export Address List - Exporter la liste d’adresses - - - Comma separated file - Expanded name of the CSV file format. See: https://en.wikipedia.org/wiki/Comma-separated_values. - Fichier séparé par des virgules - - - There was an error trying to save the address list to %1. Please try again. - An error message. %1 is a stand-in argument for the name of the file we attempted to save to. - Une erreur est survenue lors de l'enregistrement de la liste d'adresses vers %1. Veuillez réessayer plus tard. - - - Receiving addresses - %1 - Adresses de réceptions - %1 - - - Exporting Failed - Échec d’exportation - - - - AddressTableModel - - Label - Étiquette - - - Address - Adresse - - - (no label) - (aucune étiquette) - - - - AskPassphraseDialog - - Passphrase Dialog - Fenêtre de dialogue de la phrase de passe - - - Enter passphrase - Saisir la phrase de passe - - - New passphrase - Nouvelle phrase de passe - - - Repeat new passphrase - Répéter la phrase de passe - - - Show passphrase - Afficher la phrase de passe - - - Encrypt wallet - Chiffrer le porte-monnaie - - - This operation needs your wallet passphrase to unlock the wallet. - Cette opération nécessite votre phrase de passe pour déverrouiller le porte-monnaie. - - - Unlock wallet - Déverrouiller le porte-monnaie - - - Change passphrase - Changer la phrase de passe - - - Confirm wallet encryption - Confirmer le chiffrement du porte-monnaie - - - Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - Avertissement : Si vous chiffrez votre porte-monnaie et perdez votre phrase de passe, vous <b>PERDREZ TOUS VOS BITCOINS</b> ! - - - Are you sure you wish to encrypt your wallet? - Voulez-vous vraiment chiffrer votre porte-monnaie ? - - - Wallet encrypted - Le porte-monnaie est chiffré - - - Enter the new passphrase for the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. - Saisissez la nouvelle phrase de passe du porte-monnaie.<br/>Veuillez utiliser une phrase de passe composée de <b>dix caractères aléatoires ou plus</b>, ou de <b>huit mots ou plus</b>. - - - Enter the old passphrase and new passphrase for the wallet. - Saisir l’ancienne puis la nouvelle phrase de passe du porte-monnaie. - - - Continue - Poursuivre - - - Back - Retour - - - Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. - N’oubliez pas que le chiffrement de votre porte-monnaie ne peut pas protéger entièrement vos bitcoins contre le vol par des programmes malveillants qui infecteraient votre ordinateur. - - - Wallet to be encrypted - Porte-monnaie à chiffrer - - - Your wallet is about to be encrypted. - Votre porte-monnaie est sur le point d’être chiffré. - - - Your wallet is now encrypted. - Votre porte-monnaie est désormais chiffré. - - - IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - IMPORTANT : Toutes les sauvegardes précédentes du fichier de votre porte-monnaie devraient être remplacées par le fichier du porte-monnaie chiffré nouvellement généré. Pour des raisons de sécurité, les sauvegardes précédentes de votre fichier de porte-monnaie non chiffré deviendront inutilisables dès que vous commencerez à utiliser le nouveau porte-monnaie chiffré. - - - Wallet encryption failed - Échec de chiffrement du porte-monnaie - - - Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Le chiffrement du porte-monnaie a échoué en raison d’une erreur interne. Votre porte-monnaie n’a pas été chiffré. - - - The supplied passphrases do not match. - Les phrases de passe saisies ne correspondent pas. - - - Wallet unlock failed - Échec de déverrouillage du porte-monnaie - - - The passphrase entered for the wallet decryption was incorrect. - La phrase de passe saisie pour déchiffrer le porte-monnaie était erronée. - - - The passphrase entered for the wallet decryption is incorrect. It contains a null character (ie - a zero byte). If the passphrase was set with a version of this software prior to 25.0, please try again with only the characters up to — but not including — the first null character. If this is successful, please set a new passphrase to avoid this issue in the future. - La phrase secrète saisie pour le décryptage du portefeuille est incorrecte. Elle contient un caractère nul (c'est-à-dire un octet de zéro). Si la phrase secrète a été définie avec une version de ce logiciel antérieure à la version 25.0, veuillez réessayer en ne saisissant que les caractères jusqu'au premier caractère nul (non compris). Si vous y parvenez, définissez une nouvelle phrase secrète afin d'éviter ce problème à l'avenir. - - - Wallet passphrase was successfully changed. - La phrase de passe du porte-monnaie a été modifiée avec succès. - - - Passphrase change failed - Le changement de phrase secrète a échoué - - - The old passphrase entered for the wallet decryption is incorrect. It contains a null character (ie - a zero byte). If the passphrase was set with a version of this software prior to 25.0, please try again with only the characters up to — but not including — the first null character. - L'ancienne phrase secrète introduite pour le décryptage du portefeuille est incorrecte. Elle contient un caractère nul (c'est-à-dire un octet de zéro). Si la phrase secrète a été définie avec une version de ce logiciel antérieure à la version 25.0, veuillez réessayer en ne saisissant que les caractères jusqu'au premier caractère nul (non compris). - - - Warning: The Caps Lock key is on! - Avertissement : La touche Verr. Maj. est activée - - - - BanTableModel - - IP/Netmask - IP/masque réseau - - - Banned Until - Banni jusqu’au - - - - BitcoinApplication - - Settings file %1 might be corrupt or invalid. - Le fichier de paramètres %1 est peut-être corrompu ou non valide. - - - Runaway exception - Exception excessive - - - A fatal error occurred. %1 can no longer continue safely and will quit. - Une erreur fatale est survenue. %1 ne peut plus poursuivre de façon sûre et va s’arrêter. - - - Internal error - Eurrer interne - - - An internal error occurred. %1 will attempt to continue safely. This is an unexpected bug which can be reported as described below. - Une erreur interne est survenue. %1 va tenter de poursuivre avec sécurité. Il s’agit d’un bogue inattendu qui peut être signalé comme décrit ci-dessous. - - - - QObject - - Do you want to reset settings to default values, or to abort without making changes? - Explanatory text shown on startup when the settings file cannot be read. Prompts user to make a choice between resetting or aborting. - Voulez-vous réinitialiser les paramètres à leur valeur par défaut ou abandonner sans aucun changement ? - - - A fatal error occurred. Check that settings file is writable, or try running with -nosettings. - Explanatory text shown on startup when the settings file could not be written. Prompts user to check that we have the ability to write to the file. Explains that the user has the option of running without a settings file. - Une erreur fatale est survenue. Vérifiez que le fichier des paramètres est modifiable ou essayer d’exécuter avec -nosettings. - - - Error: %1 - Erreur : %1 - - - %1 didn't yet exit safely… - %1 ne s’est pas encore fermer en toute sécurité… - - - unknown - inconnue - - - Embedded "%1" - Intégré « %1 » - - - Default system font "%1" - Police système par défaut « %1 » - - - Custom… - Persnnalisé… - - - Amount - Montant - - - Enter a Bitcoin address (e.g. %1) - Saisir une adresse Bitcoin (p. ex. %1) - - - Unroutable - Non routable - - - Inbound - An inbound connection from a peer. An inbound connection is a connection initiated by a peer. - Entrant - - - Outbound - An outbound connection to a peer. An outbound connection is a connection initiated by us. - Sortant - - - Full Relay - Peer connection type that relays all network information. - Relais intégral - - - Block Relay - Peer connection type that relays network information about blocks and not transactions or addresses. - Relais de blocs - - - Manual - Peer connection type established manually through one of several methods. - Manuelle - - - Feeler - Short-lived peer connection type that tests the aliveness of known addresses. - Palpeur - - - Address Fetch - Short-lived peer connection type that solicits known addresses from a peer. - Récupération d’adresses - - - %1 d - %1 j - - - %1 m - %1 min - - - None - Aucun - - - N/A - N.D. - - - %n second(s) - - %n seconde - %n secondes - - - - %n minute(s) - - %n minute - %n minutes - - - - %n hour(s) - - %n heure - %n heures - - - - %n day(s) - - %n jour - %n jours - - - - %n week(s) - - %n semaine - %n semaines - - - - %1 and %2 - %1 et %2 - - - %n year(s) - - %n an - %n ans - - - - %1 B - %1 o - - - %1 kB - %1 ko - - - %1 MB - %1 Mo - - - %1 GB - %1 Go - - - default wallet - porte-monnaie par défaut - - - - BitcoinGUI - - &Overview - &Vue d’ensemble - - - Show general overview of wallet - Afficher une vue d’ensemble du porte-monnaie - - - Browse transaction history - Parcourir l’historique transactionnel - - - E&xit - Q&uitter - - - Quit application - Fermer l’application - - - &About %1 - À &propos de %1 - - - Show information about %1 - Afficher des renseignements à propos de %1 - - - About &Qt - À propos de &Qt - - - Show information about Qt - Afficher des renseignements sur Qt - - - Modify configuration options for %1 - Modifier les options de configuration de %1 - - - Create a new wallet - Créer un nouveau porte-monnaie - - - &Minimize - &Réduire - - - Wallet: - Porte-monnaie : - - - Network activity disabled. - A substring of the tooltip. - L’activité réseau est désactivée. - - - Proxy is <b>enabled</b>: %1 - Le serveur mandataire est <b>activé</b> : %1 - - - Send coins to a Bitcoin address - Envoyer des pièces à une adresse Bitcoin - - - Backup wallet to another location - Sauvegarder le porte-monnaie vers un autre emplacement - - - Change the passphrase used for wallet encryption - Modifier la phrase de passe utilisée pour le chiffrement du porte-monnaie - - - &Send - &Envoyer - - - &Receive - &Recevoir - - - &Options… - &Choix - - - &Encrypt Wallet… - &Chiffrer le porte-monnaie… - - - Encrypt the private keys that belong to your wallet - Chiffrer les clés privées qui appartiennent à votre porte-monnaie - - - &Backup Wallet… - &auvegarder le porte-monnaie… - - - &Change Passphrase… - &Changer la phrase de passe… - - - Sign &message… - Signer un &message… - - - Sign messages with your Bitcoin addresses to prove you own them - Signer les messages avec vos adresses Bitcoin pour prouver que vous les détenez - - - &Verify message… - &Vérifier un message… - - - Verify messages to ensure they were signed with specified Bitcoin addresses - Vérifier les messages pour s’assurer qu’ils ont été signés avec les adresses Bitcoin indiquées - - - &Load PSBT from file… - &Charger une TBSP d’un fichier… - - - Open &URI… - Ouvrir une &URI… - - - Close Wallet… - Fermer le porte-monnaie… - - - Create Wallet… - Créer un porte-monnaie… - - - Close All Wallets… - Fermer tous les porte-monnaie… - - - &File - &Fichier - - - &Settings - &Paramètres - - - &Help - &Aide - - - Tabs toolbar - Barre d’outils des onglets - - - Syncing Headers (%1%)… - Synchronisation des en-têtes (%1)… - - - Synchronizing with network… - Synchronisation avec le réseau… - - - Indexing blocks on disk… - Indexation des blocs sur le disque… - - - Processing blocks on disk… - Traitement des blocs sur le disque… - - - Connecting to peers… - Connexion aux pairs… - - - Request payments (generates QR codes and bitcoin: URIs) - Demander des paiements (génère des codes QR et des URI bitcoin:) - - - Show the list of used sending addresses and labels - Afficher la liste d’adresses et d’étiquettes d’envoi utilisées - - - Show the list of used receiving addresses and labels - Afficher la liste d’adresses et d’étiquettes de réception utilisées - - - &Command-line options - Options de ligne de &commande - - - Processed %n block(s) of transaction history. - - %n bloc d’historique transactionnel a été traité. - %n blocs d’historique transactionnel ont été traités. - - - - %1 behind - en retard de %1 - - - Catching up… - Rattrapage… - - - Last received block was generated %1 ago. - Le dernier bloc reçu avait été généré il y a %1. - - - Transactions after this will not yet be visible. - Les transactions suivantes ne seront pas déjà visibles. - - - Error - Erreur - - - Warning - Avertissement - - - Information - Renseignements - - - Up to date - À jour - - - Load Partially Signed Bitcoin Transaction - Charger une transaction Bitcoin signée partiellement - - - Load PSBT from &clipboard… - Charger la TBSP du &presse-papiers… - - - Load Partially Signed Bitcoin Transaction from clipboard - Charger du presse-papiers une transaction Bitcoin signée partiellement - - - Node window - Fenêtre des nœuds - - - Open node debugging and diagnostic console - Ouvrir une console de débogage de nœuds et de diagnostic - - - &Sending addresses - &Adresses d’envoi - - - &Receiving addresses - &Adresses de réception - - - Open a bitcoin: URI - Ouvrir une URI bitcoin: - - - Open Wallet - Ouvrir le porte-monnaie - - - Open a wallet - Ouvrir un porte-monnaie - - - Close wallet - Fermer le porte-monnaie - - - Restore Wallet… - Name of the menu item that restores wallet from a backup file. - Restaurer le Portefeuille... - - - Restore a wallet from a backup file - Status tip for Restore Wallet menu item - Restaurer le Portefeuille depuis un fichier de sauvegarde - - - Close all wallets - Fermer tous les porte-monnaie - - - Migrate Wallet - Migrer le portefeuille - - - Migrate a wallet - Migrer un portefeuilles - - - Show the %1 help message to get a list with possible Bitcoin command-line options - Afficher le message d’aide de %1 pour obtenir la liste des options possibles en ligne de commande Bitcoin - - - &Mask values - &Masquer les montants - - - Mask the values in the Overview tab - Masquer les montants dans l’onglet Vue d’ensemble - - - No wallets available - Aucun porte-monnaie n’est disponible - - - Wallet Data - Name of the wallet data file format. - Données du porte-monnaie - - - Load Wallet Backup - The title for Restore Wallet File Windows - Lancer un Portefeuille de sauvegarde - - - Restore Wallet - Title of pop-up window shown when the user is attempting to restore a wallet. - Restaurer le portefeuille - - - Wallet Name - Label of the input field where the name of the wallet is entered. - Nom du porte-monnaie - - - &Window - &Fenêtre - - - Zoom - Zoomer - - - Main Window - Fenêtre principale - - - %1 client - Client %1 - - - &Hide - &Cacher - - - S&how - A&fficher - - - %n active connection(s) to Bitcoin network. - A substring of the tooltip. - - %n connexion active avec le réseau Bitcoin. - %n connexions actives avec le réseau Bitcoin. - - - - Click for more actions. - A substring of the tooltip. "More actions" are available via the context menu. - Cliquez pour afficher plus d’actions. - - - Show Peers tab - A context menu item. The "Peers tab" is an element of the "Node window". - Afficher l’onglet Pairs - - - Disable network activity - A context menu item. - Désactiver l’activité réseau - - - Enable network activity - A context menu item. The network activity was disabled previously. - Activer l’activité réseau - - - Pre-syncing Headers (%1%)… - En-têtes de pré-synchronisation (%1%)... - - - Error creating wallet - Erreur lors de la création du portefeuille - - - Cannot create new wallet, the software was compiled without sqlite support (required for descriptor wallets) - Impossible de créer un nouveau portefeuilles, le logiciel a été compilé sans support pour sqlite (nécessaire pour le portefeuille décris) - - - Error: %1 - Erreur : %1 - - - Warning: %1 - Avertissement : %1 - - - Date: %1 - - Date : %1 - - - - Amount: %1 - - Montant : %1 - - - - Wallet: %1 - - Porte-monnaie : %1 - - - - Type: %1 - - Type  : %1 - - - - Label: %1 - - Étiquette : %1 - - - - Address: %1 - - Adresse : %1 - - - - Sent transaction - Transaction envoyée - - - Incoming transaction - Transaction entrante - - - HD key generation is <b>enabled</b> - La génération de clé HD est <b>activée</b> - - - HD key generation is <b>disabled</b> - La génération de clé HD est <b>désactivée</b> - - - Private key <b>disabled</b> - La clé privée est <b>désactivée</b> - - - Wallet is <b>encrypted</b> and currently <b>unlocked</b> - Le porte-monnaie est <b>chiffré</b> et est actuellement <b>déverrouillé</b> - - - Wallet is <b>encrypted</b> and currently <b>locked</b> - Le porte-monnaie est <b>chiffré</b> et actuellement <b>verrouillé</b> - - - Original message: - Message original : - - - - UnitDisplayStatusBarControl - - Unit to show amounts in. Click to select another unit. - Unité d’affichage des montants. Cliquez pour sélectionner une autre unité. - - - - CoinControlDialog - - Coin Selection - Sélection des pièces - - - Quantity: - Quantité : - - - Bytes: - Octets : - - - Amount: - Montant : - - - Fee: - Frais : - - - After Fee: - Après les frais : - - - Change: - Monnaie : - - - (un)select all - Tout (des)sélectionner - - - Tree mode - Mode arborescence - - - List mode - Mode liste - - - Amount - Montant - - - Received with label - Reçu avec une étiquette - - - Received with address - Reçu avec une adresse - - - Confirmed - Confirmée - - - Copy amount - Copier le montant - - - &Copy address - &Copier l’adresse - - - Copy &label - Copier l’&étiquette - - - Copy &amount - Copier le &montant - - - Copy transaction &ID and output index - Copier l’ID de la transaction et l’index des sorties - - - L&ock unspent - &Verrouillé ce qui n’est pas dépensé - - - &Unlock unspent - &Déverrouiller ce qui n’est pas dépensé - - - Copy quantity - Copier la quantité - - - Copy fee - Copier les frais - - - Copy after fee - Copier après les frais - - - Copy bytes - Copier les octets - - - Copy change - Copier la monnaie - - - (%1 locked) - (%1 verrouillée) - - - Can vary +/- %1 satoshi(s) per input. - Peut varier +/- %1 satoshi(s) par entrée. - - - (no label) - (aucune étiquette) - - - change from %1 (%2) - monnaie de %1 (%2) - - - (change) - (monnaie) - - - - CreateWalletActivity - - Create Wallet - Title of window indicating the progress of creation of a new wallet. - Créer un porte-monnaie - - - Creating Wallet <b>%1</b>… - Descriptive text of the create wallet progress window which indicates to the user which wallet is currently being created. - Création du porte-monnaie <b>%1</b>… - - - Create wallet failed - Échec de création du porte-monnaie - - - Create wallet warning - Avertissement de création du porte-monnaie - - - Can't list signers - Impossible de lister les signataires - - - Too many external signers found - Trop de signataires externes trouvés - - - - LoadWalletsActivity - - Load Wallets - Title of progress window which is displayed when wallets are being loaded. - Charger les porte-monnaie - - - Loading wallets… - Descriptive text of the load wallets progress window which indicates to the user that wallets are currently being loaded. - Chargement des porte-monnaie… - - - - MigrateWalletActivity - - Migrate wallet - Migrer le portefeuille - - - Are you sure you wish to migrate the wallet <i>%1</i>? - Êtes-vous sûr de vouloir migrer le portefeuille <i>%1</i> - - - Migrating the wallet will convert this wallet to one or more descriptor wallets. A new wallet backup will need to be made. -If this wallet contains any watchonly scripts, a new wallet will be created which contains those watchonly scripts. -If this wallet contains any solvable but not watched scripts, a different and new wallet will be created which contains those scripts. - -The migration process will create a backup of the wallet before migrating. This backup file will be named <wallet name>-<timestamp>.legacy.bak and can be found in the directory for this wallet. In the event of an incorrect migration, the backup can be restored with the "Restore Wallet" functionality. - La migration du porte-monnaie convertira ce porte-monnaie en un ou plusieurs porte-monnaie de descripteurs. Une nouvelle sauvegarde du porte-monnaie devra être effectuée. -Si ce porte-monnaie contient des scripts en lecture seule, un nouveau porte-monnaie sera créé contenant ces scripts en lecture seule. -Si ce porte-monnaie contient des scripts solvables mais non surveillés, un autre nouveau porte-monnaie sera créé contenant ces scripts. - -Le processus de migration créera une sauvegarde du porte-monnaie avant la migration. Ce fichier de sauvegarde sera nommé <nom du porte-monnaie>-<horodatage>.legacy.bak et pourra être trouvé dans le répertoire de ce porte-monnaie. En cas de migration incorrecte, la sauvegarde peut être restaurée avec la fonctionnalité "Restaurer le porte-monnaie". - - - Migrate Wallet - Migrer le portefeuille - - - Migrating Wallet <b>%1</b>… - Migration du portefeuille <b>%1</b>… - - - The wallet '%1' was migrated successfully. - Le porte-monnaie '%1' a été migré avec succès. - - - Watchonly scripts have been migrated to a new wallet named '%1'. - Les scripts juste-regarder ont été migrés vers un nouveau porte-monnaie nommé « %1 ». - - - Solvable but not watched scripts have been migrated to a new wallet named '%1'. - Les scripts solubles, mais non surveillés ont été migrés vers un nouveau porte-monnaie nommé « %1 ». - - - Migration failed - La migration a échoué - - - Migration Successful - Migration réussie - - - - OpenWalletActivity - - Open wallet failed - Échec d’ouverture du porte-monnaie - - - Open wallet warning - Avertissement d’ouverture du porte-monnaie - - - Open Wallet - Title of window indicating the progress of opening of a wallet. - Ouvrir un porte-monnaie - - - Opening Wallet <b>%1</b>… - Descriptive text of the open wallet progress window which indicates to the user which wallet is currently being opened. - Ouverture du porte-monnaie <b>%1</b>… - - - - RestoreWalletActivity - - Restore Wallet - Title of progress window which is displayed when wallets are being restored. - Restaurer le portefeuille - - - Restoring Wallet <b>%1</b>… - Descriptive text of the restore wallets progress window which indicates to the user that wallets are currently being restored. - Restauration du Portefeuille<b>%1</b>... - - - Restore wallet failed - Title of message box which is displayed when the wallet could not be restored. - Échec de la restauration du portefeuille - - - Restore wallet warning - Title of message box which is displayed when the wallet is restored with some warning. - Avertissement de la récupération du Portefeuille - - - Restore wallet message - Title of message box which is displayed when the wallet is successfully restored. - Message du Portefeuille restauré - - - - WalletController - - Close wallet - Fermer le porte-monnaie - - - Are you sure you wish to close the wallet <i>%1</i>? - Voulez-vous vraiment fermer le porte-monnaie <i>%1</i> ? - - - Closing the wallet for too long can result in having to resync the entire chain if pruning is enabled. - Fermer le porte-monnaie trop longtemps peut impliquer de devoir resynchroniser la chaîne entière si l’élagage est activé. - - - Close all wallets - Fermer tous les porte-monnaie - - - Are you sure you wish to close all wallets? - Voulez-vous vraiment fermer tous les porte-monnaie ? - - - - CreateWalletDialog - - Create Wallet - Créer un porte-monnaie - - - You are one step away from creating your new wallet! - Vous n'êtes qu'à un pas de la création de votre nouveau portefeuille ! - - - Please provide a name and, if desired, enable any advanced options - Veuillez fournir un nom et, si désiré, activer toutes les options avancées. - - - Wallet Name - Nom du porte-monnaie - - - Wallet - Porte-monnaie - - - Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice. - Chiffrer le porte-monnaie. Le porte-monnaie sera chiffré avec une phrase de passe de votre choix. - - - Encrypt Wallet - Chiffrer le porte-monnaie - - - Advanced Options - Options avancées - - - Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets. - Désactiver les clés privées pour ce porte-monnaie. Les porte-monnaie pour lesquels les clés privées sont désactivées n’auront aucune clé privée et ne pourront ni avoir de graine HD ni de clés privées importées. Cela est idéal pour les porte-monnaie juste-regarder. - - - Disable Private Keys - Désactiver les clés privées - - - Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time. - Créer un porte-monnaie vide. Les porte-monnaie vides n’ont initialement ni clé privée ni script. Ultérieurement, des clés privées et des adresses peuvent être importées ou une graine HD peut être définie. - - - Make Blank Wallet - Créer un porte-monnaie vide - - - Use an external signing device such as a hardware wallet. Configure the external signer script in wallet preferences first. - Utiliser un appareil externe de signature tel qu’un porte-monnaie matériel. Configurer d’abord le script signataire externe dans les préférences du porte-monnaie. - - - External signer - Signataire externe - - - Create - Créer - - - Compiled without external signing support (required for external signing) - "External signing" means using devices such as hardware wallets. - Compilé sans prise en charge des signatures externes (requis pour la signature externe) - - - - EditAddressDialog - - Edit Address - Modifier l’adresse - - - &Label - É&tiquette - - - The label associated with this address list entry - L’étiquette associée à cette entrée de la liste d’adresses - - - The address associated with this address list entry. This can only be modified for sending addresses. - L’adresse associée à cette entrée de la liste d’adresses. Ne peut être modifié que pour les adresses d’envoi. - - - &Address - &Adresse - - - New sending address - Nouvelle adresse d’envoi - - - Edit receiving address - Modifier l’adresse de réception - - - Edit sending address - Modifier l’adresse d’envoi - - - The entered address "%1" is not a valid Bitcoin address. - L’adresse saisie « %1 » n’est pas une adresse Bitcoin valide. - - - Address "%1" already exists as a receiving address with label "%2" and so cannot be added as a sending address. - L’adresse « %1 » existe déjà en tant qu’adresse de réception avec l’étiquette « %2 » et ne peut donc pas être ajoutée en tant qu’adresse d’envoi. - - - The entered address "%1" is already in the address book with label "%2". - L’adresse saisie « %1 » est déjà présente dans le carnet d’adresses avec l’étiquette « %2 ». - - - Could not unlock wallet. - Impossible de déverrouiller le porte-monnaie. - - - New key generation failed. - Échec de génération de la nouvelle clé. - - - - FreespaceChecker - - A new data directory will be created. - Un nouveau répertoire de données sera créé. - - - name - nom - - - Directory already exists. Add %1 if you intend to create a new directory here. - Le répertoire existe déjà. Ajouter %1 si vous comptez créer un nouveau répertoire ici. - - - Path already exists, and is not a directory. - Le chemin existe déjà et n’est pas un répertoire. - - - Cannot create data directory here. - Impossible de créer un répertoire de données ici. - - - - Intro - - %n GB of space available - - %n Go d’espace libre - %n Go d’espace libre - - - - (of %n GB needed) - - (of %n GB needed) - (of %n GB needed) - - - - (%n GB needed for full chain) - - (%n GB needed for full chain) - (%n GB needed for full chain) - - - - Choose data directory - Choisissez un répertoire de donnée - - - At least %1 GB of data will be stored in this directory, and it will grow over time. - Au moins %1 Go de données seront stockés dans ce répertoire et sa taille augmentera avec le temps. - - - Approximately %1 GB of data will be stored in this directory. - Approximativement %1 Go de données seront stockés dans ce répertoire. - - - (sufficient to restore backups %n day(s) old) - Explanatory text on the capability of the current prune target. - - (suffisant pour restaurer les sauvegardes âgées de %n jour) - (suffisant pour restaurer les sauvegardes âgées de %n jours) - - - - %1 will download and store a copy of the Bitcoin block chain. - %1 téléchargera et stockera une copie de la chaîne de blocs Bitcoin. - - - The wallet will also be stored in this directory. - Le porte-monnaie sera aussi stocké dans ce répertoire. - - - Error: Specified data directory "%1" cannot be created. - Erreur : Le répertoire de données indiqué « %1 » ne peut pas être créé. - - - Error - Erreur - - - Welcome - Bienvenue - - - Welcome to %1. - Bienvenue à %1. - - - As this is the first time the program is launched, you can choose where %1 will store its data. - Comme le logiciel est lancé pour la première fois, vous pouvez choisir où %1 stockera ses données. - - - Limit block chain storage to - Limiter l’espace de stockage de chaîne de blocs à - - - Reverting this setting requires re-downloading the entire blockchain. It is faster to download the full chain first and prune it later. Disables some advanced features. - Rétablir ce paramètre à sa valeur antérieure exige de retélécharger la chaîne de blocs dans son intégralité. Il est plus rapide de télécharger la chaîne complète dans un premier temps et de l’élaguer ultérieurement. Désactive certaines fonctions avancées. - - - GB -  Go - - - This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off. - Cette synchronisation initiale est très exigeante et pourrait exposer des problèmes matériels dans votre ordinateur passés inaperçus auparavant. Chaque fois que vous exécuterez %1, le téléchargement reprendra où il s’était arrêté. - - - When you click OK, %1 will begin to download and process the full %4 block chain (%2 GB) starting with the earliest transactions in %3 when %4 initially launched. - Quand vous cliquerez sur Valider, %1 commencera à télécharger et à traiter l’intégralité de la chaîne de blocs %4 (%2 Go) en débutant avec les transactions les plus anciennes de %3, quand %4 a été lancé initialement. - - - If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low. - Si vous avez choisi de limiter le stockage de la chaîne de blocs (élagage), les données historiques doivent quand même être téléchargées et traitées, mais seront supprimées par la suite pour minimiser l’utilisation de votre espace disque. - - - Use the default data directory - Utiliser le répertoire de données par défaut - - - Use a custom data directory: - Utiliser un répertoire de données personnalisé : - - - - HelpMessageDialog - - About %1 - À propos de %1 - - - Command-line options - Options de ligne de commande - - - - ShutdownWindow - - %1 is shutting down… - %1 est en cours de fermeture… - - - Do not shut down the computer until this window disappears. - Ne pas éteindre l’ordinateur jusqu’à la disparition de cette fenêtre. - - - - ModalOverlay - - Form - Formulaire - - - Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below. - Les transactions récentes ne sont peut-être pas encore visibles et par conséquent le solde de votre porte-monnaie est peut-être erroné. Ces renseignements seront justes quand votre porte-monnaie aura fini de se synchroniser avec le réseau Bitcoin, comme décrit ci-dessous. - - - Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network. - Toute tentative de dépense de bitcoins affectés par des transactions qui ne sont pas encore affichées ne sera pas acceptée par le réseau. - - - Number of blocks left - Nombre de blocs restants - - - Unknown… - Inconnu… - - - calculating… - calcul en cours… - - - Last block time - Estampille temporelle du dernier bloc - - - Progress - Progression - - - Progress increase per hour - Avancement de la progression par heure - - - Estimated time left until synced - Temps estimé avant la fin de la synchronisation - - - Hide - Cacher - - - Esc - Échap - - - %1 is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain. - %1 est en cours de synchronisation. Il téléchargera les en-têtes et les blocs des pairs, et les validera jusqu’à ce qu’il atteigne la fin de la chaîne de blocs. - - - Unknown. Syncing Headers (%1, %2%)… - Inconnu. Synchronisation des en-têtes (%1, %2 %)… - - - Unknown. Pre-syncing Headers (%1, %2%)… - Inconnu. En-têtes de présynchronisation (%1, %2%)... - - - - OpenURIDialog - - Open bitcoin URI - Ouvrir une URI bitcoin - - - URI: - URI : - - - Paste address from clipboard - Tooltip text for button that allows you to paste an address that is in your clipboard. - Collez l’adresse du presse-papiers - - - - OptionsDialog - - &Main - &Principales - - - Automatically start %1 after logging in to the system. - Démarrer %1 automatiquement après avoir ouvert une session sur l’ordinateur. - - - &Start %1 on system login - &Démarrer %1 lors de l’ouverture d’une session - - - Enabling pruning significantly reduces the disk space required to store transactions. All blocks are still fully validated. Reverting this setting requires re-downloading the entire blockchain. - L’activation de l’élagage réduit considérablement l’espace disque requis pour stocker les transactions. Tous les blocs sont encore entièrement validés. L’annulation de ce paramètre exige de retélécharger la chaîne de blocs dans son intégralité. - - - Maximum database cache size. Make sure you have enough RAM. A larger cache can contribute to faster sync, after which the benefit is less pronounced for most use cases. Lowering the cache size will reduce memory usage. Unused mempool memory is shared for this cache. - Tooltip text for Options window setting that sets the size of the database cache. Explains the corresponding effects of increasing/decreasing this value. - Taille maximale du cache de la base de données. Assurez-vous d’avoir suffisamment de mémoire vive. Un cache plus grand peut accélérer la synchronisation, avec des avantages moindres par la suite dans la plupart des cas. Diminuer la taille du cache réduira l’utilisation de la mémoire. La mémoire non utilisée de la réserve de mémoire est partagée avec ce cache. - - - Size of &database cache - Taille du cache de la base de &données - - - Number of script &verification threads - Nombre de fils de &vérification de script - - - Full path to a %1 compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins! - Chemin complet vers un %1 script compatible (par exemple, C:\Downloads\hwi.exe ou /Users/you/Downloads/hwi.py). Attention : les malwares peuvent voler vos pièces ! - - - Automatically open the Bitcoin client port on the router. This only works when your router supports PCP or NAT-PMP and it is enabled. The external port could be random. - Ouvrir automatiquement le port du client Bitcoin sur le routeur. Cela ne fonctionne que si votre routeur prend en charge PCP ou NAT-PMP. Le port externe peut être aléatoire. - - - Map port using PCP or NA&T-PMP - Mapper le port avec PCP ou NA&T-PMP - - - IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) - Adresse IP du mandataire (p. ex. IPv4 : 127.0.0.1 / IPv6 : ::1) - - - Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type. - Indique si le mandataire SOCKS5 par défaut fourni est utilisé pour atteindre des pairs par ce type de réseau. - - - Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu. - Quand la fenêtre est fermée, la réduire au lieu de quitter l’application. Si cette option est activée, l’application ne sera fermée qu’en sélectionnant Quitter dans le menu. - - - Font in the Overview tab: - Police de l’onglet Vue d’ensemble : - - - Options set in this dialog are overridden by the command line: - Les options définies dans cette boîte de dialogue sont remplacées par la ligne de commande : - - - Open the %1 configuration file from the working directory. - Ouvrir le fichier de configuration %1 du répertoire de travail. - - - Open Configuration File - Ouvrir le fichier de configuration - - - Reset all client options to default. - Réinitialiser toutes les options du client aux valeurs par défaut. - - - &Reset Options - &Réinitialiser les options - - - &Network - &Réseau - - - Prune &block storage to - Élaguer l’espace de stockage des &blocs jusqu’à - - - GB - Go - - - Reverting this setting requires re-downloading the entire blockchain. - L’annulation de ce paramètre exige de retélécharger la chaîne de blocs dans son intégralité. - - - MiB - Mio - - - Set the number of script verification threads. Negative values correspond to the number of cores you want to leave free to the system. - Tooltip text for Options window setting that sets the number of script verification threads. Explains that negative values mean to leave these many cores free to the system. - Définissez le nombre de fils de vérification de script. Les valeurs négatives correspondent au nombre de cœurs que vous voulez laisser disponibles pour le système. - - - (0 = auto, <0 = leave that many cores free) - (0 = auto, < 0 = laisser ce nombre de cœurs inutilisés) - - - This allows you or a third party tool to communicate with the node through command-line and JSON-RPC commands. - Tooltip text for Options window setting that enables the RPC server. - Ceci vous permet ou permet à un outil tiers de communiquer avec le nœud grâce à la ligne de commande ou des commandes JSON-RPC. - - - Enable R&PC server - An Options window setting to enable the RPC server. - Activer le serveur R&PC - - - W&allet - &Porte-monnaie - - - Whether to set subtract fee from amount as default or not. - Tooltip text for Options window setting that sets subtracting the fee from a sending amount as default. - Définissez s’il faut soustraire par défaut les frais du montant ou non. - - - Subtract &fee from amount by default - An Options window setting to set subtracting the fee from a sending amount as default. - Soustraire par défaut les &frais du montant - - - Enable coin &control features - Activer les fonctions de &contrôle des pièces - - - If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed. - Si vous désactivé la dépense de la monnaie non confirmée, la monnaie d’une transaction ne peut pas être utilisée tant que cette transaction n’a pas reçu au moins une confirmation. Celai affecte aussi le calcul de votre solde. - - - &Spend unconfirmed change - &Dépenser la monnaie non confirmée - - - Enable &PSBT controls - An options window setting to enable PSBT controls. - Activer les contrôles &TBPS - - - Whether to show PSBT controls. - Tooltip text for options window setting that enables PSBT controls. - Affichez ou non les contrôles TBPS. - - - External Signer (e.g. hardware wallet) - Signataire externe (p. ex. porte-monnaie matériel) - - - &External signer script path - &Chemin du script signataire externe - - - Accept connections from outside. - Accepter les connexions provenant de l’extérieur. - - - Allow incomin&g connections - Permettre les connexions e&ntrantes - - - Connect to the Bitcoin network through a SOCKS5 proxy. - Se connecter au réseau Bitcoin par un mandataire SOCKS5. - - - &Connect through SOCKS5 proxy (default proxy): - Se &connecter par un mandataire SOCKS5 (mandataire par défaut) : - - - Proxy &IP: - &IP du mandataire : - - - &Port: - &Port : - - - Port of the proxy (e.g. 9050) - Port du mandataire (p. ex. 9050) - - - Used for reaching peers via: - Utilisé pour rejoindre les pairs par : - - - &Window - &Fenêtre - - - Show the icon in the system tray. - Afficher l’icône dans la zone de notification. - - - &Show tray icon - &Afficher l’icône dans la zone de notification - - - Show only a tray icon after minimizing the window. - Après réduction, n’afficher qu’une icône dans la zone de notification. - - - &Minimize to the tray instead of the taskbar - &Réduire dans la zone de notification au lieu de la barre des tâches - - - M&inimize on close - Ré&duire lors de la fermeture - - - &Display - &Affichage - - - User Interface &language: - &Langue de l’interface utilisateur : - - - The user interface language can be set here. This setting will take effect after restarting %1. - La langue de l’interface utilisateur peut être définie ici. Ce réglage sera pris en compte après redémarrage de %1. - - - &Unit to show amounts in: - &Unité d’affichage des montants : - - - Choose the default subdivision unit to show in the interface and when sending coins. - Choisir la sous-unité par défaut d’affichage dans l’interface et lors d’envoi de pièces. - - - Third-party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. - Les URL de tiers (p. ex. un explorateur de blocs) qui apparaissent dans l’onglet des transactions comme éléments du menu contextuel. Dans l’URL, %s est remplacé par le hachage de la transaction. Les URL multiples sont séparées par une barre verticale |. - - - &Third-party transaction URLs - URL de transaction de $tiers - - - Whether to show coin control features or not. - Afficher ou non les fonctions de contrôle des pièces. - - - Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor onion services. - Se connecter au réseau Bitcoin par un mandataire SOCKS5 séparé pour les services oignon de Tor. - - - Use separate SOCKS&5 proxy to reach peers via Tor onion services: - Utiliser un mandataire SOCKS&5 séparé pour atteindre les pairs par les services oignon de Tor : - - - &OK - &Valider - - - &Cancel - A&nnuler - - - Compiled without external signing support (required for external signing) - "External signing" means using devices such as hardware wallets. - Compilé sans prise en charge des signatures externes (requis pour la signature externe) - - - default - par défaut - - - none - aucune - - - Confirm options reset - Window title text of pop-up window shown when the user has chosen to reset options. - Confirmer la réinitialisation des options - - - Client restart required to activate changes. - Text explaining that the settings changed will not come into effect until the client is restarted. - Le redémarrage du client est exigé pour activer les changements. - - - Current settings will be backed up at "%1". - Text explaining to the user that the client's current settings will be backed up at a specific location. %1 is a stand-in argument for the backup location's path. - Les paramètres actuels vont être restaurés à "%1". - - - Client will be shut down. Do you want to proceed? - Text asking the user to confirm if they would like to proceed with a client shutdown. - Le client sera arrêté. Voulez-vous continuer ? - - - Configuration options - Window title text of pop-up box that allows opening up of configuration file. - Options de configuration - - - The configuration file is used to specify advanced user options which override GUI settings. Additionally, any command-line options will override this configuration file. - Explanatory text about the priority order of instructions considered by client. The order from high to low being: command-line, configuration file, GUI settings. - Le fichier de configuration est utilisé pour indiquer aux utilisateurs experts quelles options remplacent les paramètres de l’IUG. De plus, toute option de ligne de commande remplacera ce fichier de configuration. - - - Continue - Poursuivre - - - Cancel - Annuler - - - Error - Erreur - - - The configuration file could not be opened. - Impossible d’ouvrir le fichier de configuration. - - - This change would require a client restart. - Ce changement demanderait un redémarrage du client. - - - The supplied proxy address is invalid. - L’adresse de serveur mandataire fournie est invalide. - - - - OptionsModel - - Could not read setting "%1", %2. - Impossible de lire le paramètre "%1", %2. - - - - OverviewPage - - Form - Formulaire - - - The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. - Les renseignements affichés peuvent être obsolètes. Votre porte-monnaie se synchronise automatiquement avec le réseau Bitcoin dès qu’une connexion est établie, mais ce processus n’est pas encore achevé. - - - Watch-only: - Juste-regarder : - - - Available: - Disponible : - - - Your current spendable balance - Votre solde actuel disponible - - - Pending: - En attente : - - - Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance - Total des transactions qui doivent encore être confirmées et qui ne sont pas prises en compte dans le solde disponible - - - Immature: - Immature : - - - Mined balance that has not yet matured - Le solde miné n’est pas encore mûr - - - Balances - Soldes - - - Total: - Total : - - - Your current total balance - Votre solde total actuel - - - Your current balance in watch-only addresses - Votre balance actuelle en adresses juste-regarder - - - Spendable: - Disponible : - - - Recent transactions - Transactions récentes - - - Unconfirmed transactions to watch-only addresses - Transactions non confirmées vers des adresses juste-regarder - - - Mined balance in watch-only addresses that has not yet matured - Le solde miné dans des adresses juste-regarder, qui n’est pas encore mûr - - - Current total balance in watch-only addresses - Solde total actuel dans des adresses juste-regarder - - - Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings->Mask values. - Le mode privé est activé dans l’onglet Vue d’ensemble. Pour afficher les montants, décocher Paramètres -> Masquer les montants. - - - - PSBTOperationsDialog - - PSBT Operations - Opération PSBT - - - Sign Tx - Signer la transaction - - - Broadcast Tx - Diffuser la transaction - - - Copy to Clipboard - Copier dans le presse-papiers - - - Save… - Enregistrer… - - - Close - Fermer - - - Failed to load transaction: %1 - Échec de chargement de la transaction : %1 - - - Failed to sign transaction: %1 - Échec de signature de la transaction : %1 - - - Cannot sign inputs while wallet is locked. - Impossible de signer des entrées quand le porte-monnaie est verrouillé. - - - Could not sign any more inputs. - Aucune autre entrée n’a pu être signée. - - - Signed %1 inputs, but more signatures are still required. - %1 entrées ont été signées, mais il faut encore d’autres signatures. - - - Signed transaction successfully. Transaction is ready to broadcast. - La transaction a été signée avec succès et est prête à être diffusée. - - - Unknown error processing transaction. - Erreur inconnue lors de traitement de la transaction - - - Transaction broadcast successfully! Transaction ID: %1 - La transaction a été diffusée avec succès. ID de la transaction : %1 - - - Transaction broadcast failed: %1 - Échec de diffusion de la transaction : %1 - - - PSBT copied to clipboard. - La TBSP a été copiée dans le presse-papiers. - - - Save Transaction Data - Enregistrer les données de la transaction - - - Partially Signed Transaction (Binary) - Expanded name of the binary PSBT file format. See: BIP 174. - Transaction signée partiellement (fichier binaire) - - - PSBT saved to disk. - La TBSP a été enregistrée sur le disque. - - - Sends %1 to %2 - Envoie %1 à %2 - - - own address - votre adresse - - - Unable to calculate transaction fee or total transaction amount. - Impossible de calculer les frais de la transaction ou le montant total de la transaction. - - - Pays transaction fee: - Paye des frais de transaction : - - - Total Amount - Montant total - - - or - ou - - - Transaction has %1 unsigned inputs. - La transaction a %1 entrées non signées. - - - Transaction is missing some information about inputs. - Il manque des renseignements sur les entrées dans la transaction. - - - Transaction still needs signature(s). - La transaction a encore besoin d’une ou de signatures. - - - (But no wallet is loaded.) - (Mais aucun porte-monnaie n’est chargé.) - - - (But this wallet cannot sign transactions.) - (Mais ce porte-monnaie ne peut pas signer de transactions.) - - - (But this wallet does not have the right keys.) - (Mais ce porte-monnaie n’a pas les bonnes clés.) - - - Transaction is fully signed and ready for broadcast. - La transaction est complètement signée et prête à être diffusée. - - - Transaction status is unknown. - L’état de la transaction est inconnu. - - - - PaymentServer - - Payment request error - Erreur de demande de paiement - - - Cannot start bitcoin: click-to-pay handler - Impossible de démarrer le gestionnaire de cliquer-pour-payer bitcoin: - - - URI handling - Gestion des URI - - - 'bitcoin://' is not a valid URI. Use 'bitcoin:' instead. - 'bitcoin://' n’est pas une URI valide. Utilisez plutôt 'bitcoin:'. - - - Cannot process payment request because BIP70 is not supported. -Due to widespread security flaws in BIP70 it's strongly recommended that any merchant instructions to switch wallets be ignored. -If you are receiving this error you should request the merchant provide a BIP21 compatible URI. - Impossible de traiter la demande de paiement, car BIP70 n’est pas pris en charge. En raison des failles de sécurité généralisées de BIP70, il est fortement recommandé d’ignorer toute demande de marchand de changer de porte-monnaie. Si vous recevez cette erreur, vous devriez demander au marchand de vous fournir une URI compatible BIP21. - - - URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - L’URI ne peut pas être analysée. Cela peut être causé par une adresse Bitcoin invalide ou par des paramètres d’URI mal formés. - - - Payment request file handling - Gestion des fichiers de demande de paiement - - - - PeerTableModel - - User Agent - Title of Peers Table column which contains the peer's User Agent string. - Agent utilisateur - - - Peer - Title of Peers Table column which contains a unique number used to identify a connection. - Pair - - - Sent - Title of Peers Table column which indicates the total amount of network information we have sent to the peer. - Envoyé - - - Received - Title of Peers Table column which indicates the total amount of network information we have received from the peer. - Reçus - - - Address - Title of Peers Table column which contains the IP/Onion/I2P address of the connected peer. - Adresse - - - Network - Title of Peers Table column which states the network the peer connected through. - Réseau - - - Inbound - An Inbound Connection from a Peer. - Entrant - - - Outbound - An Outbound Connection to a Peer. - Sortant - - - - QRImageWidget - - &Save Image… - &Enregistrer l’image… - - - &Copy Image - &Copier l’image - - - Resulting URI too long, try to reduce the text for label / message. - L’URI résultante est trop longue. Essayez de réduire le texte de l’étiquette ou du message. - - - Error encoding URI into QR Code. - Erreur d’encodage de l’URI en code QR. - - - QR code support not available. - La prise en charge des codes QR n’est pas proposée. - - - Save QR Code - Enregistrer le code QR - - - PNG Image - Expanded name of the PNG file format. See: https://en.wikipedia.org/wiki/Portable_Network_Graphics. - Image PNG - - - - RPCConsole - - N/A - N.D. - - - Client version - Version du client - - - &Information - &Renseignements - - - General - Générales - - - Datadir - Répertoire des données - - - To specify a non-default location of the data directory use the '%1' option. - Pour indiquer un emplacement du répertoire des données différent de celui par défaut, utiliser l’option ’%1’. - - - Blocksdir - Répertoire des blocs - - - To specify a non-default location of the blocks directory use the '%1' option. - Pour indiquer un emplacement du répertoire des blocs différent de celui par défaut, utiliser l’option ’%1’. - - - Startup time - Heure de démarrage - - - Network - Réseau - - - Name - Nom - - - Number of connections - Nombre de connexions - - - Local Addresses - Adresses locales - - - Network addresses that your Bitcoin node is currently using to communicate with other nodes. - Adresses réseau que votre nœud Bitcoin utilise actuellement pour communiquer avec d’autres nœuds. - - - Block chain - Chaîne de blocs - - - Memory Pool - Réserve de mémoire - - - Current number of transactions - Nombre actuel de transactions - - - Memory usage - Utilisation de la mémoire - - - Wallet: - Porte-monnaie : - - - (none) - (aucun) - - - &Reset - &Réinitialiser - - - Received - Reçus - - - Sent - Envoyé - - - &Peers - &Pairs - - - Banned peers - Pairs bannis - - - Select a peer to view detailed information. - Sélectionnez un pair pour afficher des renseignements détaillés. - - - Hide Peers Detail - Cacher les détails des pairs - - - The transport layer version: %1 - La version de la couche de transport : %1 - - - Session ID - ID de session - - - Whether we relay transactions to this peer. - Si nous relayons des transactions à ce pair. - - - Transaction Relay - Relais de transaction - - - Starting Block - Bloc de départ - - - Synced Headers - En-têtes synchronisés - - - Synced Blocks - Blocs synchronisés - - - Last Transaction - Dernière transaction - - - The mapped Autonomous System used for diversifying peer selection. - Le système autonome mappé utilisé pour diversifier la sélection des pairs. - - - Mapped AS - SA mappé - - - Whether we relay addresses to this peer. - Tooltip text for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No). - Reliez ou non des adresses à ce pair. - - - Address Relay - Text title for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No). - Relais d’adresses - - - The total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). - Tooltip text for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). - Nombre total d'adresses reçues de ce pair qui ont été traitées (à l'exclusion des adresses qui ont été abandonnées en raison de la limitation du débit). - - - The total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - Tooltip text for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - Nombre total d'adresses reçues de ce pair qui ont été abandonnées (non traitées) en raison de la limitation du débit. - - - Addresses Processed - Text title for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). - Adresses traitées - - - Addresses Rate-Limited - Text title for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - Adresses ciblées par la limite de débit - - - User Agent - Agent utilisateur - - - Node window - Fenêtre des nœuds - - - Current block height - Hauteur du bloc courant - - - Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. - Ouvrir le fichier journal de débogage de %1 à partir du répertoire de données actuel. Cela peut prendre quelques secondes pour les fichiers journaux de grande taille. - - - Decrease font size - Diminuer la taille de police - - - Increase font size - Augmenter la taille de police - - - Permissions - Autorisations - - - The direction and type of peer connection: %1 - La direction et le type de la connexion au pair : %1 - - - The BIP324 session ID string in hex. - ID hexadécimale de la session BIP324. - - - The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS. - Le protocole réseau par lequel ce pair est connecté : IPv4, IPv6, Oignon, I2P ou CJDNS. - - - High bandwidth BIP152 compact block relay: %1 - Relais de blocs BIP152 compact à large bande passante : %1 - - - High Bandwidth - Large bande passante - - - Connection Time - Temps de connexion - - - Elapsed time since a novel block passing initial validity checks was received from this peer. - Temps écoulé depuis qu’un nouveau bloc qui a réussi les vérifications initiales de validité a été reçu par ce pair. - - - Last Block - Dernier bloc - - - Elapsed time since a novel transaction accepted into our mempool was received from this peer. - Tooltip text for the Last Transaction field in the peer details area. - Temps écoulé depuis qu’une nouvelle transaction acceptée dans notre réserve de mémoire a été reçue par ce pair. - - - Last Send - Dernier envoi - - - Last Receive - Dernière réception - - - Ping Time - Temps de ping - - - The duration of a currently outstanding ping. - La durée d’un ping en cours. - - - Ping Wait - Attente du ping - - - Min Ping - Ping min. - - - Time Offset - Décalage temporel - - - Last block time - Estampille temporelle du dernier bloc - - - &Open - &Ouvrir - - - &Network Traffic - Trafic &réseau - - - Totals - Totaux - - - Debug log file - Fichier journal de débogage - - - Clear console - Effacer la console - - - In: - Entrant : - - - Out: - Sortant : - - - Inbound: initiated by peer - Explanatory text for an inbound peer connection. - Entrant : établie par le pair - - - Outbound Full Relay: default - Explanatory text for an outbound peer connection that relays all network information. This is the default behavior for outbound connections. - Relais intégral sortant : par défaut - - - Outbound Block Relay: does not relay transactions or addresses - Explanatory text for an outbound peer connection that relays network information about blocks and not transactions or addresses. - Relais de bloc sortant : ne relaye ni transactions ni adresses - - - Outbound Manual: added using RPC %1 or %2/%3 configuration options - Explanatory text for an outbound peer connection that was established manually through one of several methods. The numbered arguments are stand-ins for the methods available to establish manual connections. - Manuelle sortante : ajoutée avec un RPC %1 ou les options de configuration %2/%3 - - - Outbound Feeler: short-lived, for testing addresses - Explanatory text for a short-lived outbound peer connection that is used to test the aliveness of known addresses. - Palpeur sortant : de courte durée, pour tester des adresses - - - Outbound Address Fetch: short-lived, for soliciting addresses - Explanatory text for a short-lived outbound peer connection that is used to request addresses from a peer. - Récupération d’adresse sortante : de courte durée, pour solliciter des adresses - - - detecting: peer could be v1 or v2 - Explanatory text for "detecting" transport type. - détection : paires pourrait être v1 ou v2 - - - v1: unencrypted, plaintext transport protocol - Explanatory text for v1 transport type. - v1: protocole de transport non chiffré en texte clair - - - v2: BIP324 encrypted transport protocol - Explanatory text for v2 transport type. - v2: Protocole de transport chiffré BIP324 - - - we selected the peer for high bandwidth relay - nous avons sélectionné le pair comme relais à large bande passante - - - the peer selected us for high bandwidth relay - le pair nous avons sélectionné comme relais à large bande passante - - - no high bandwidth relay selected - aucun relais à large bande passante n’a été sélectionné - - - &Copy address - Context menu action to copy the address of a peer. - &Copier l’adresse - - - &Disconnect - &Déconnecter - - - 1 &hour - 1 &heure - - - 1 d&ay - 1 &jour - - - 1 &week - 1 &semaine - - - 1 &year - 1 &an - - - &Copy IP/Netmask - Context menu action to copy the IP/Netmask of a banned peer. IP/Netmask is the combination of a peer's IP address and its Netmask. For IP address, see: https://en.wikipedia.org/wiki/IP_address. - &Copier l’IP, le masque réseau - - - &Unban - &Réhabiliter - - - Network activity disabled - L’activité réseau est désactivée - - - None - Aucun - - - Executing command without any wallet - Exécution de la commande sans aucun porte-monnaie - - - Node window - [%1] - Fenêtre des nœuds – [%1] - - - Executing command using "%1" wallet - Exécution de la commande en utilisant le porte-monnaie « %1 » - - - Welcome to the %1 RPC console. -Use up and down arrows to navigate history, and %2 to clear screen. -Use %3 and %4 to increase or decrease the font size. -Type %5 for an overview of available commands. -For more information on using this console, type %6. - -%7WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.%8 - RPC console welcome message. Placeholders %7 and %8 are style tags for the warning content, and they are not space separated from the rest of the text intentionally. - Bienvenue dans la console RPC de %1. -Utilisez les touches de déplacement vers le haut et vers le bas pour parcourir l’historique et %2 pour effacer l’écran. -Utilisez %3 et %4 pour augmenter ou diminuer la taille de la police. -Tapez %5 pour un aperçu des commandes proposées. -Pour plus de précisions sur cette console, tapez %6. -%7AVERTISSEMENT : des escrocs sont à l’œuvre et demandent aux utilisateurs de taper des commandes ici, volant ainsi le contenu de leur porte-monnaie. N’utilisez pas cette console sans entièrement comprendre les ramifications d’une commande. %8 - - - Executing… - A console message indicating an entered command is currently being executed. - Éxécution… - - - (peer: %1) - (pair : %1) - - - via %1 - par %1 - - - Yes - Oui - - - No - Non - - - To - À - - - From - De - - - Ban for - Bannir pendant - - - Never - Jamais - - - Unknown - Inconnu - - - - ReceiveCoinsDialog - - &Amount: - &Montant : - - - &Label: - &Étiquette : - - - &Message: - M&essage : - - - An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. - Un message facultatif à joindre à la demande de paiement et qui sera affiché à l’ouverture de celle-ci. Note : Le message ne sera pas envoyé avec le paiement par le réseau Bitcoin. - - - An optional label to associate with the new receiving address. - Un étiquette facultative à associer à la nouvelle adresse de réception. - - - Use this form to request payments. All fields are <b>optional</b>. - Utiliser ce formulaire pour demander des paiements. Tous les champs sont <b>facultatifs</b>. - - - An optional amount to request. Leave this empty or zero to not request a specific amount. - Un montant facultatif à demander. Ne rien saisir ou un zéro pour ne pas demander de montant précis. - - - An optional label to associate with the new receiving address (used by you to identify an invoice). It is also attached to the payment request. - Une étiquette facultative à associer à la nouvelle adresse de réception (utilisée par vous pour identifier une facture). Elle est aussi jointe à la demande de paiement. - - - An optional message that is attached to the payment request and may be displayed to the sender. - Un message facultatif joint à la demande de paiement et qui peut être présenté à l’expéditeur. - - - &Create new receiving address - &Créer une nouvelle adresse de réception - - - Clear all fields of the form. - Effacer tous les champs du formulaire. - - - Clear - Effacer - - - Requested payments history - Historique des paiements demandés - - - Show the selected request (does the same as double clicking an entry) - Afficher la demande sélectionnée (comme double-cliquer sur une entrée) - - - Show - Afficher - - - Remove the selected entries from the list - Retirer les entrées sélectionnées de la liste - - - Remove - Retirer - - - Copy &URI - Copier l’&URI - - - &Copy address - &Copier l’adresse - - - Copy &label - Copier l’&étiquette - - - Copy &message - Copier le &message - - - Copy &amount - Copier le &montant - - - Not recommended due to higher fees and less protection against typos. - Non recommandé en raison de frais élevés et d'une faible protection contre les fautes de frappe. - - - Generates an address compatible with older wallets. - Génère une adresse compatible avec les anciens portefeuilles. - - - Generates a native segwit address (BIP-173). Some old wallets don't support it. - Génère une adresse segwit native (BIP-173). Certains anciens portefeuilles ne le supportent pas. - - - Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited. - Bech32m (BIP-350) est une mise à jour de Bech32, la prise en charge du portefeuille est encore limitée. - - - Could not unlock wallet. - Impossible de déverrouiller le porte-monnaie. - - - Could not generate new %1 address - Impossible de générer la nouvelle adresse %1 - - - - ReceiveRequestDialog - - Request payment to … - Demander de paiement à… - - - Address: - Adresse : - - - Amount: - Montant : - - - Label: - Étiquette : - - - Message: - Message : - - - Wallet: - Porte-monnaie : - - - Copy &URI - Copier l’&URI - - - Copy &Address - Copier l’&adresse - - - &Verify - &Vérifier - - - Verify this address on e.g. a hardware wallet screen - Confirmer p. ex. cette adresse sur l’écran d’un porte-monnaie matériel - - - &Save Image… - &Enregistrer l’image… - - - Payment information - Renseignements de paiement - - - Request payment to %1 - Demande de paiement à %1 - - - - RecentRequestsTableModel - - Label - Étiquette - - - (no label) - (aucune étiquette) - - - (no message) - (aucun message) - - - (no amount requested) - (aucun montant demandé) - - - Requested - Demandée - - - - SendCoinsDialog - - Send Coins - Envoyer des pièces - - - Coin Control Features - Fonctions de contrôle des pièces - - - automatically selected - sélectionné automatiquement - - - Insufficient funds! - Les fonds sont insuffisants - - - Quantity: - Quantité : - - - Bytes: - Octets : - - - Amount: - Montant : - - - Fee: - Frais : - - - After Fee: - Après les frais : - - - Change: - Monnaie : - - - If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. - Si cette option est activée et l’adresse de monnaie est vide ou invalide, la monnaie sera envoyée vers une adresse nouvellement générée. - - - Custom change address - Adresse personnalisée de monnaie - - - Transaction Fee: - Frais de transaction : - - - Using the fallbackfee can result in sending a transaction that will take several hours or days (or never) to confirm. Consider choosing your fee manually or wait until you have validated the complete chain. - L’utilisation de l’option « fallbackfee » (frais de repli) peut avoir comme effet d’envoyer une transaction qui prendra plusieurs heures ou jours pour être confirmée, ou qui ne le sera jamais. Envisagez de choisir vos frais manuellement ou attendez d’avoir validé l’intégralité de la chaîne. - - - Warning: Fee estimation is currently not possible. - Avertissement : L’estimation des frais n’est actuellement pas possible. - - - per kilobyte - par kilo-octet - - - Hide - Cacher - - - Recommended: - Recommandés : - - - Custom: - Personnalisés : - - - Send to multiple recipients at once - Envoyer à plusieurs destinataires à la fois - - - Add &Recipient - Ajouter un &destinataire - - - Clear all fields of the form. - Effacer tous les champs du formulaire. - - - Choose… - Choisir… - - - Hide transaction fee settings - Cacher les paramètres de frais de transaction - - - Specify a custom fee per kB (1,000 bytes) of the transaction's virtual size. - -Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 satoshis per kvB" for a transaction size of 500 virtual bytes (half of 1 kvB) would ultimately yield a fee of only 50 satoshis. - Indiquer des frais personnalisés par Ko (1 000 octets) de la taille virtuelle de la transaction. - -Note : Les frais étant calculés par octet, un taux de frais de « 100 satoshis par Kov » pour une transaction d’une taille de 500 octets (la moitié de 1 Kov) donneront des frais de seulement 50 satoshis. - - - When there is less transaction volume than space in the blocks, miners as well as relaying nodes may enforce a minimum fee. Paying only this minimum fee is just fine, but be aware that this can result in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. - Quand le volume des transactions est inférieur à l’espace dans les blocs, les mineurs et les nœuds de relais peuvent imposer des frais minimaux. Il est correct de payer ces frais minimaux, mais soyez conscient que cette transaction pourrait n’être jamais confirmée si la demande en transactions de bitcoins dépassait la capacité de traitement du réseau. - - - A too low fee might result in a never confirming transaction (read the tooltip) - Si les frais sont trop bas, cette transaction pourrait n’être jamais confirmée (lire l’infobulle) - - - (Smart fee not initialized yet. This usually takes a few blocks…) - (Les frais intelligents ne sont pas encore initialisés. Cela prend habituellement quelques blocs…) - - - Confirmation time target: - Estimation du délai de confirmation : - - - Enable Replace-By-Fee - Activer Remplacer-par-des-frais - - - With Replace-By-Fee (BIP-125) you can increase a transaction's fee after it is sent. Without this, a higher fee may be recommended to compensate for increased transaction delay risk. - Avec Remplacer-par-des-frais (BIP-125), vous pouvez augmenter les frais de transaction après qu’elle est envoyée. Sans cela, des frais plus élevés peuvent être recommandés pour compenser le risque accru de retard transactionnel. - - - Clear &All - &Tout effacer - - - Balance: - Solde : - - - Confirm the send action - Confirmer l’action d’envoi - - - S&end - E&nvoyer - - - Copy quantity - Copier la quantité - - - Copy amount - Copier le montant - - - Copy fee - Copier les frais - - - Copy after fee - Copier après les frais - - - Copy bytes - Copier les octets - - - Copy change - Copier la monnaie - - - %1 (%2 blocks) - %1 (%2 blocs) - - - Sign on device - "device" usually means a hardware wallet. - Signer sur l’appareil externe - - - Connect your hardware wallet first. - Connecter d’abord le porte-monnaie matériel. - - - Set external signer script path in Options -> Wallet - "External signer" means using devices such as hardware wallets. - Définir le chemin script du signataire externe dans Options -> Porte-monnaie - - - Cr&eate Unsigned - Cr&éer une transaction non signée - - - Creates a Partially Signed Bitcoin Transaction (PSBT) for use with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet. - Crée une transaction Bitcoin signée partiellement (TBSP) à utiliser, par exemple, avec un porte-monnaie %1 hors ligne ou avec un porte-monnaie matériel compatible TBSP. - - - %1 to '%2' - %1 à '%2' - - - %1 to %2 - %1 à %2 - - - To review recipient list click "Show Details…" - Pour réviser la liste des destinataires, cliquez sur « Afficher les détails… » - - - Sign failed - Échec de signature - - - External signer not found - "External signer" means using devices such as hardware wallets. - Le signataire externe est introuvable - - - External signer failure - "External signer" means using devices such as hardware wallets. - Échec du signataire externe - - - Save Transaction Data - Enregistrer les données de la transaction - - - Partially Signed Transaction (Binary) - Expanded name of the binary PSBT file format. See: BIP 174. - Transaction signée partiellement (fichier binaire) - - - PSBT saved - Popup message when a PSBT has been saved to a file - La TBSP a été enregistrée - - - External balance: - Solde externe : - - - or - ou - - - You can increase the fee later (signals Replace-By-Fee, BIP-125). - Vous pouvez augmenter les frais ultérieurement (signale Remplacer-par-des-frais, BIP-125). - - - Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can save or copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet. - Text to inform a user attempting to create a transaction of their current options. At this stage, a user can only create a PSBT. This string is displayed when private keys are disabled and an external signer is not available. - Veuillez réviser votre proposition de transaction. Une transaction Bitcoin partiellement signée (TBSP) sera produite, que vous pourrez enregistrer ou copier puis signer avec, par exemple, un porte-monnaie %1 hors ligne ou avec un porte-monnaie matériel compatible TBSP. - - - %1 from wallet '%2' - %1 du porte-monnaie « %2 ». - - - Do you want to create this transaction? - Message displayed when attempting to create a transaction. Cautionary text to prompt the user to verify that the displayed transaction details represent the transaction the user intends to create. - Voulez-vous créer cette transaction ? - - - Please, review your transaction. You can create and send this transaction or create a Partially Signed Bitcoin Transaction (PSBT), which you can save or copy and then sign with, e.g., an offline %1 wallet, or a PSBT-compatible hardware wallet. - Text to inform a user attempting to create a transaction of their current options. At this stage, a user can send their transaction or create a PSBT. This string is displayed when both private keys and PSBT controls are enabled. - Veuillez réviser votre transaction. Vous pouvez créer et envoyer cette transaction ou créer une transaction Bitcoin partiellement signée (TBSP), que vous pouvez enregistrer ou copier, et ensuite avec laquelle signer, par ex., un porte-monnaie %1 hors ligne ou avec un porte-monnaie matériel compatible TBSP. - - - Please, review your transaction. - Text to prompt a user to review the details of the transaction they are attempting to send. - Veuillez vérifier votre transaction. - - - Transaction fee - Frais de transaction - - - Not signalling Replace-By-Fee, BIP-125. - Ne signale pas Remplacer-par-des-frais, BIP-125. - - - Total Amount - Montant total - - - Unsigned Transaction - PSBT copied - Caption of "PSBT has been copied" messagebox - Transaction non signée - - - The PSBT has been copied to the clipboard. You can also save it. - Le PSBT a été copié dans le presse-papiers. Vous pouvez également le sauvegarder. - - - PSBT saved to disk - PSBT sauvegardé sur le disque - - - Confirm send coins - Confirmer l’envoi de pièces - - - Watch-only balance: - Solde juste-regarder : - - - The recipient address is not valid. Please recheck. - L’adresse du destinataire est invalide. Veuillez la revérifier. - - - The amount to pay must be larger than 0. - Le montant à payer doit être supérieur à 0. - - - The amount exceeds your balance. - Le montant dépasse votre solde. - - - The total exceeds your balance when the %1 transaction fee is included. - Le montant dépasse votre solde quand les frais de transaction de %1 sont compris. - - - Duplicate address found: addresses should only be used once each. - Une adresse identique a été trouvée : chaque adresse ne devrait être utilisée qu’une fois. - - - Transaction creation failed! - Échec de création de la transaction - - - A fee higher than %1 is considered an absurdly high fee. - Des frais supérieurs à %1 sont considérés comme ridiculement élevés. - - - Estimated to begin confirmation within %n block(s). - - Début de confirmation estimé à %n bloc. - Début de confirmation estimé à %n blocs. - - - - Warning: Invalid Bitcoin address - Avertissement : L’adresse Bitcoin est invalide - - - Warning: Unknown change address - Avertissement : L’adresse de monnaie est inconnue - - - Confirm custom change address - Confirmer l’adresse personnalisée de monnaie - - - The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure? - L’adresse que vous avez sélectionnée pour la monnaie ne fait pas partie de ce porte-monnaie. Les fonds de ce porte-monnaie peuvent en partie ou en totalité être envoyés vers cette adresse. Êtes-vous certain ? - - - (no label) - (aucune étiquette) - - - - SendCoinsEntry - - A&mount: - &Montant : - - - Pay &To: - &Payer à : - - - &Label: - &Étiquette : - - - Choose previously used address - Choisir une adresse utilisée précédemment - - - The Bitcoin address to send the payment to - L’adresse Bitcoin à laquelle envoyer le paiement - - - Paste address from clipboard - Collez l’adresse du presse-papiers - - - Remove this entry - Supprimer cette entrée - - - The amount to send in the selected unit - Le montant à envoyer dans l’unité sélectionnée - - - The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally. - Les frais seront déduits du montant envoyé. Le destinataire recevra moins de bitcoins que le montant saisi dans le champ de montant. Si plusieurs destinataires sont sélectionnés, les frais seront partagés également. - - - S&ubtract fee from amount - S&oustraire les frais du montant - - - Use available balance - Utiliser le solde disponible - - - Message: - Message : - - - Enter a label for this address to add it to the list of used addresses - Saisir une étiquette pour cette adresse afin de l’ajouter à la liste d’adresses utilisées - - - A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network. - Un message qui était joint à l’URI bitcoin: et qui sera stocké avec la transaction pour référence. Note : Ce message ne sera pas envoyé par le réseau Bitcoin. - - - - SendConfirmationDialog - - Send - Envoyer - - - Create Unsigned - Créer une transaction non signée - - - - SignVerifyMessageDialog - - Signatures - Sign / Verify a Message - Signatures – Signer ou vérifier un message - - - &Sign Message - &Signer un message - - - You can sign messages/agreements with your legacy (P2PKH) addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. - Vous pouvez signer des messages ou des accords avec vos anciennes adresses (P2PKH) pour prouver que vous pouvez recevoir des bitcoins à ces dernières. Ne signer rien de vague ou au hasard, car des attaques d’hameçonnage pourraient essayer de vous faire signer avec votre identité afin de l’usurper. Ne signez que des déclarations entièrement détaillées et que vous acceptez. - - - The Bitcoin address to sign the message with - L’adresse Bitcoin avec laquelle signer le message - - - Choose previously used address - Choisir une adresse utilisée précédemment - - - Paste address from clipboard - Collez l’adresse du presse-papiers - - - Enter the message you want to sign here - Saisir ici le message que vous voulez signer - - - Copy the current signature to the system clipboard - Copier la signature actuelle dans le presse-papiers - - - Sign the message to prove you own this Bitcoin address - Signer le message afin de prouver que vous détenez cette adresse Bitcoin - - - Sign &Message - Signer le &message - - - Reset all sign message fields - Réinitialiser tous les champs de signature de message - - - Clear &All - &Tout effacer - - - &Verify Message - &Vérifier un message - - - Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction! - Saisissez ci-dessous l’adresse du destinataire, le message (assurez-vous de copier fidèlement les retours à la ligne, les espaces, les tabulations, etc.) et la signature pour vérifier le message. Faites attention à ne pas déduire davantage de la signature que ce qui est contenu dans le message signé même, pour éviter d’être trompé par une attaque de l’intercepteur. Notez que cela ne fait que prouver que le signataire reçoit avec l’adresse et ne peut pas prouver la provenance d’une transaction. - - - The Bitcoin address the message was signed with - L’adresse Bitcoin avec laquelle le message a été signé - - - The signed message to verify - Le message signé à vérifier - - - The signature given when the message was signed - La signature donnée quand le message a été signé - - - Verify the message to ensure it was signed with the specified Bitcoin address - Vérifier le message pour s’assurer qu’il a été signé avec l’adresse Bitcoin indiquée - - - Verify &Message - Vérifier le &message - - - Reset all verify message fields - Réinitialiser tous les champs de vérification de message - - - Click "Sign Message" to generate signature - Cliquez sur « Signer le message » pour générer la signature - - - The entered address is invalid. - L’adresse saisie est invalide. - - - Please check the address and try again. - Veuillez vérifier l’adresse et réessayer. - - - The entered address does not refer to a legacy (P2PKH) key. Message signing for SegWit and other non-P2PKH address types is not supported in this version of %1. Please check the address and try again. - L’adresse saisie ne fait pas référence à une ancienne clé (P2PKH). La signature des messages n’est pas prise en charge pour SegWit ni pour les autres types d’adresses non P2PKH dans cette version de %1. Vérifiez l’adresse et réessayez. - - - Wallet unlock was cancelled. - Le déverrouillage du porte-monnaie a été annulé. - - - No error - Aucune erreur - - - Private key for the entered address is not available. - La clé privée pour l’adresse saisie n’est pas disponible. - - - Message signing failed. - Échec de signature du message. - - - Message signed. - Le message a été signé. - - - The signature could not be decoded. - La signature n’a pu être décodée. - - - Please check the signature and try again. - Veuillez vérifier la signature et réessayer. - - - The signature did not match the message digest. - La signature ne correspond pas au condensé du message. - - - Message verification failed. - Échec de vérification du message. - - - Message verified. - Le message a été vérifié. - - - - SplashScreen - - (press q to shutdown and continue later) - (appuyer sur q pour fermer et poursuivre plus tard) - - - press q to shutdown - Appuyer sur q pour fermer - - - - TrafficGraphWidget - - kB/s - Ko/s - - - - TransactionDesc - - conflicted with a transaction with %1 confirmations - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that conflicts with a confirmed transaction. - est en conflit avec une transaction ayant %1 confirmations - - - 0/unconfirmed, in memory pool - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that is in the memory pool. - 0/non confirmé, dans la pool de mémoire - - - 0/unconfirmed, not in memory pool - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that is not in the memory pool. - 0/non confirmé, pas dans la pool de mémoire - - - abandoned - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an abandoned transaction. - abandonnée - - - %1/unconfirmed - Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents a transaction confirmed in at least one block, but less than 6 blocks. - %1/non confirmée - - - Status - État - - - Generated - Générée - - - From - De - - - unknown - inconnue - - - To - À - - - own address - votre adresse - - - watch-only - juste-regarder - - - label - étiquette - - - Credit - Crédit - - - matures in %n more block(s) - - arrivera à maturité dans %n bloc - arrivera à maturité dans %n blocs - - - - not accepted - non acceptée - - - Debit - Débit - - - Total debit - Débit total - - - Total credit - Crédit total - - - Transaction fee - Frais de transaction - - - Net amount - Montant net - - - Comment - Commentaire - - - Transaction ID - ID de la transaction - - - Transaction total size - Taille totale de la transaction - - - Transaction virtual size - Taille virtuelle de la transaction - - - Output index - Index des sorties - - - %1 (Certificate was not verified) - %1 (ce certificat n’a pas été vérifié) - - - Merchant - Marchand - - - Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. - Les pièces générées doivent mûrir pendant %1 blocs avant de pouvoir être dépensées. Quand vous avez généré ce bloc, il a été diffusé sur le réseau pour être ajouté à la chaîne de blocs. Si son intégration à la chaîne échoue, son état sera modifié en « non acceptée » et il ne sera pas possible de le dépenser. Cela peut arriver occasionnellement si un autre nœud génère un bloc à quelques secondes du vôtre. - - - Debug information - Renseignements de débogage - - - Inputs - Entrées - - - Amount - Montant - - - true - vrai - - - false - faux - - - - TransactionDescDialog - - This pane shows a detailed description of the transaction - Ce panneau affiche une description détaillée de la transaction - - - Details for %1 - Détails de %1 - - - - TransactionTableModel - - Label - Étiquette - - - Unconfirmed - Non confirmée - - - Abandoned - Abandonnée - - - Confirming (%1 of %2 recommended confirmations) - Confirmation (%1 sur %2 confirmations recommandées) - - - Confirmed (%1 confirmations) - Confirmée (%1 confirmations) - - - Conflicted - En conflit - - - Immature (%1 confirmations, will be available after %2) - Immature (%1 confirmations, sera disponible après %2) - - - Generated but not accepted - Générée mais non acceptée - - - Received with - Reçue avec - - - Received from - Reçue de - - - Sent to - Envoyée à - - - Mined - Miné - - - watch-only - juste-regarder - - - (n/a) - (n.d) - - - (no label) - (aucune étiquette) - - - Transaction status. Hover over this field to show number of confirmations. - État de la transaction. Survoler ce champ avec la souris pour afficher le nombre de confirmations. - - - Date and time that the transaction was received. - Date et heure de réception de la transaction. - - - Type of transaction. - Type de transaction. - - - Whether or not a watch-only address is involved in this transaction. - Une adresse juste-regarder est-elle ou non impliquée dans cette transaction. - - - User-defined intent/purpose of the transaction. - Intention, but de la transaction défini par l’utilisateur. - - - Amount removed from or added to balance. - Le montant a été ajouté ou soustrait du solde. - - - - TransactionView - - All - Toutes - - - Today - Aujourd’hui - - - This week - Cette semaine - - - This month - Ce mois - - - Last month - Le mois dernier - - - This year - Cette année - - - Received with - Reçue avec - - - Sent to - Envoyée à - - - Mined - Miné - - - Other - Autres - - - Enter address, transaction id, or label to search - Saisir l’adresse, l’ID de transaction ou l’étiquette à chercher - - - Min amount - Montant min. - - - Range… - Plage… - - - &Copy address - &Copier l’adresse - - - Copy &label - Copier l’&étiquette - - - Copy &amount - Copier le &montant - - - Copy transaction &ID - Copier l’&ID de la transaction - - - Copy &raw transaction - Copier la transaction &brute - - - Copy full transaction &details - Copier tous les &détails de la transaction - - - &Show transaction details - &Afficher les détails de la transaction - - - Increase transaction &fee - Augmenter les &frais de transaction - - - A&bandon transaction - A&bandonner la transaction - - - &Edit address label - &Modifier l’adresse de l’étiquette - - - Show in %1 - Transactions table context menu action to show the selected transaction in a third-party block explorer. %1 is a stand-in argument for the URL of the explorer. - Afficher dans %1 - - - Export Transaction History - Exporter l’historique transactionnel - - - Comma separated file - Expanded name of the CSV file format. See: https://en.wikipedia.org/wiki/Comma-separated_values. - Fichier séparé par des virgules - - - Confirmed - Confirmée - - - Watch-only - Juste-regarder - - - Label - Étiquette - - - Address - Adresse - - - ID - ID - - - Exporting Failed - Échec d’exportation - - - There was an error trying to save the transaction history to %1. - Une erreur est survenue lors de l’enregistrement de l’historique transactionnel vers %1. - - - Exporting Successful - L’exportation est réussie - - - The transaction history was successfully saved to %1. - L’historique transactionnel a été enregistré avec succès vers %1. - - - Range: - Plage : - - - to - à - - - - WalletFrame - - No wallet has been loaded. -Go to File > Open Wallet to load a wallet. -- OR - - Aucun porte-monnaie n’a été chargé. -Accédez à Fichier > Ouvrir un porte-monnaie pour en charger un. -– OU – - - - Create a new wallet - Créer un nouveau porte-monnaie - - - Error - Erreur - - - Unable to decode PSBT from clipboard (invalid base64) - Impossible de décoder la TBSP du presse-papiers (le Base64 est invalide) - - - Load Transaction Data - Charger les données de la transaction - - - Partially Signed Transaction (*.psbt) - Transaction signée partiellement (*.psbt) - - - PSBT file must be smaller than 100 MiB - Le fichier de la TBSP doit être inférieur à 100 Mio - - - Unable to decode PSBT - Impossible de décoder la TBSP - - - - WalletModel - - Send Coins - Envoyer des pièces - - - Fee bump error - Erreur d’augmentation des frais - - - Increasing transaction fee failed - Échec d’augmentation des frais de transaction - - - Do you want to increase the fee? - Asks a user if they would like to manually increase the fee of a transaction that has already been created. - Voulez-vous augmenter les frais ? - - - Current fee: - Frais actuels : - - - Increase: - Augmentation : - - - New fee: - Nouveaux frais : - - - Warning: This may pay the additional fee by reducing change outputs or adding inputs, when necessary. It may add a new change output if one does not already exist. These changes may potentially leak privacy. - Avertissement : Ceci pourrait payer les frais additionnel en réduisant les sorties de monnaie ou en ajoutant des entrées, si nécessaire. Une nouvelle sortie de monnaie pourrait être ajoutée si aucune n’existe déjà. Ces changements pourraient altérer la confidentialité. - - - Confirm fee bump - Confirmer l’augmentation des frais - - - Can't draft transaction. - Impossible de créer une ébauche de la transaction. - - - PSBT copied - La TBPS a été copiée - - - Fee-bump PSBT copied to clipboard - La TBSP des augmentations de frais a été copiée dans le presse-papiers. - - - Can't sign transaction. - Impossible de signer la transaction. - - - Could not commit transaction - Impossible de valider la transaction - - - Signer error - Erreur de signataire - - - Can't display address - Impossible d’afficher l’adresse - - - - WalletView - - &Export - &Exporter - - - Export the data in the current tab to a file - Exporter les données de l’onglet actuel vers un fichier - - - Backup Wallet - Sauvegarder le porte-monnaie - - - Wallet Data - Name of the wallet data file format. - Données du porte-monnaie - - - Backup Failed - Échec de sauvegarde - - - There was an error trying to save the wallet data to %1. - Une erreur est survenue lors de l’enregistrement des données du porte-monnaie vers %1. - - - Backup Successful - La sauvegarde est réussie - - - The wallet data was successfully saved to %1. - Les données du porte-monnaie ont été enregistrées avec succès vers %1. - - - Cancel - Annuler - - - - bitcoin-core - - The %s developers - Les développeurs de %s - - - %s corrupt. Try using the wallet tool bitcoin-wallet to salvage or restoring a backup. - %s est corrompu. Essayez l’outil bitcoin-wallet pour le sauver ou restaurez une sauvegarde. - - - %s failed to validate the -assumeutxo snapshot state. This indicates a hardware problem, or a bug in the software, or a bad software modification that allowed an invalid snapshot to be loaded. As a result of this, the node will shut down and stop using any state that was built on the snapshot, resetting the chain height from %d to %d. On the next restart, the node will resume syncing from %d without using any snapshot data. Please report this incident to %s, including how you obtained the snapshot. The invalid snapshot chainstate will be left on disk in case it is helpful in diagnosing the issue that caused this error. - %s a échoué à valider l'état instantané -assumeutxo. Cela indique un problème matériel, ou un bug dans le logiciel, ou une mauvaise modification du logiciel qui a permis de charger un instantané invalide. En conséquence, le nœud s'arrêtera et cessera d'utiliser tout état qui a été construit sur l'instantané, réinitialisant la hauteur de la chaîne de %d à %d. Au prochain redémarrage, le nœud reprendra la synchronisation à partir de %d sans utiliser de données d'instantané. Veuillez signaler cet incident à %s, en précisant comment vous avez obtenu l'instantané. L'état de chaîne d'instantané invalide sera conservé sur le disque au cas où il serait utile pour diagnostiquer le problème qui a causé cette erreur. - - - %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 doc/p2p-bad-ports.md for details and a full list. - %s demande d'écouter sur le port %u. Ce port est considéré comme "mauvais" et il est donc peu probable qu'un pair s'y connecte. Voir doc/p2p-bad-ports.md pour plus de détails et une liste complète. - - - Cannot downgrade wallet from version %i to version %i. Wallet version unchanged. - Impossible de rétrograder le porte-monnaie de la version %i à la version %i. La version du porte-monnaie reste inchangée. - - - Cannot upgrade a non HD split wallet from version %i to version %i without upgrading to support pre-split keypool. Please use version %i or no version specified. - Impossible de mettre à niveau un porte-monnaie divisé non-HD de la version %i vers la version %i sans mise à niveau pour prendre en charge la réserve de clés antérieure à la division. Veuillez utiliser la version %i ou ne pas indiquer de version. - - - Disk space for %s may not accommodate the block files. Approximately %u GB of data will be stored in this directory. - L'espace disque %s peut ne pas être suffisant pour les fichiers en bloc. Environ %u Go de données seront stockés dans ce répertoire. - - - Distributed under the MIT software license, see the accompanying file %s or %s - Distribué sous la licence MIT d’utilisation d’un logiciel, consultez le fichier joint %s ou %s - - - Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order when using assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height %s - Erreur de chargement du portefeuille. Le portefeuille nécessite le téléchargement de blocs, et le logiciel ne prend pas actuellement en charge le chargement de portefeuilles lorsque les blocs sont téléchargés dans le désordre lors de l'utilisation de snapshots assumeutxo. Le portefeuille devrait pouvoir être chargé avec succès une fois que la synchronisation des nœuds aura atteint la hauteur %s - - - Error reading %s! Transaction data may be missing or incorrect. Rescanning wallet. - Erreur de lecture de %s : soit les données de la transaction manquent soit elles sont incorrectes. Réanalyse du porte-monnaie. - - - Error starting/committing db txn for wallet transactions removal process - Erreur de lancement, de validation de la transaction de base de données pour la suppression des transactions du portemonnaie - - - Error: Dumpfile format record is incorrect. Got "%s", expected "format". - Erreur : L’enregistrement du format du fichier de vidage est incorrect. Est « %s », mais « format » est attendu. - - - Error: Dumpfile identifier record is incorrect. Got "%s", expected "%s". - Erreur : L’enregistrement de l’identificateur du fichier de vidage est incorrect. Est « %s », mais « %s » est attendu. - - - Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version %s - Erreur : La version du fichier de vidage n’est pas prise en charge. Cette version de bitcoin-wallet ne prend en charge que les fichiers de vidage version 1. Le fichier de vidage obtenu est de la version %s. - - - Error: Legacy wallets only support the "legacy", "p2sh-segwit", and "bech32" address types - Erreur : les porte-monnaie hérités ne prennent en charge que les types d’adresse « legacy », « p2sh-segwit », et « bech32 » - - - Error: Unable to produce descriptors for this legacy wallet. Make sure to provide the wallet's passphrase if it is encrypted. - Erreur : Impossible de produire des descripteurs pour ce portefeuille existant. Veillez à fournir la phrase secrète du portefeuille s'il est crypté. - - - File %s already exists. If you are sure this is what you want, move it out of the way first. - Le fichier %s existe déjà. Si vous confirmez l’opération, déplacez-le avant. - - - Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start. - peers.dat est invalide ou corrompu (%s). Si vous pensez que c’est un bogue, veuillez le signaler à %s. Pour y remédier, vous pouvez soit renommer, soit déplacer soit supprimer le fichier (%s) et un nouveau sera créé lors du prochain démarrage. - - - Invalid value detected for '-wallet' or '-nowallet'. '-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets - Une valeur invalide a été détectée pour « -wallet » ou pour « -nowallet ». « -wallet » nécessite une valeur de chaine alors que « -nowallet » n’accepte que « 1 » pour désactiver tous les portemonnaies - - - More than one onion bind address is provided. Using %s for the automatically created Tor onion service. - Plus d’une adresse oignon de liaison est indiquée. %s sera utilisée pour le service oignon de Tor créé automatiquement. - - - No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided. - Aucun fichier de vidage n’a été indiqué. Pour utiliser createfromdump, -dumpfile=<filename> doit être indiqué. - - - No dump file provided. To use dump, -dumpfile=<filename> must be provided. - Aucun fichier de vidage n’a été indiqué. Pour utiliser dump, -dumpfile=<filename> doit être indiqué. - - - No wallet file format provided. To use createfromdump, -format=<format> must be provided. - Aucun format de fichier de porte-monnaie n’a été indiqué. Pour utiliser createfromdump, -format=<format> doit être indiqué. - - - Option '-upnp' is set but UPnP support was dropped in version 29.0. Consider using '-natpmp' instead. - L’option « -upnp » est définie, mais la prise en charge d’UPnP a été abandonnée dans la version 29.0. Envisagez de la remplacer par « -natpmp ». - - - Please contribute if you find %s useful. Visit %s for further information about the software. - Si vous trouvez %s utile, veuillez y contribuer. Pour de plus de précisions sur le logiciel, rendez-vous sur %s. - - - Prune configured below the minimum of %d MiB. Please use a higher number. - L’élagage est configuré au-dessous du minimum de %d Mio. Veuillez utiliser un nombre plus élevé. - - - Prune mode is incompatible with -reindex-chainstate. Use full -reindex instead. - Le mode Prune est incompatible avec -reindex-chainstate. Utilisez plutôt -reindex complet. - - - Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) - Élagage : la dernière synchronisation de porte-monnaie va par-delà les données élaguées. Vous devez -reindex (réindexer, télécharger de nouveau toute la chaîne de blocs en cas de nœud élagué) - - - Rename of '%s' -> '%s' failed. You should resolve this by manually moving or deleting the invalid snapshot directory %s, otherwise you will encounter the same error again on the next startup. - La modification de '%s' -> '%s' a échoué. Vous devriez résoudre cela en déplaçant ou en supprimant manuellement le répertoire de snapshot invalide %s, sinon vous rencontrerez la même erreur à nouveau au prochain démarrage. - - - SQLiteDatabase: Unknown sqlite wallet schema version %d. Only version %d is supported - SQLiteDatabase : la version %d du schéma de porte-monnaie sqlite est inconnue. Seule la version %d est prise en charge - - - The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct - La base de données des blocs comprend un bloc qui semble provenir du futur. Cela pourrait être causé par la date et l’heure erronées de votre ordinateur. Ne reconstruisez la base de données des blocs que si vous êtes certain que la date et l’heure de votre ordinateur sont justes. - - - The transaction amount is too small to send after the fee has been deducted - Le montant de la transaction est trop bas pour être envoyé une fois que les frais ont été déduits - - - This error could occur if this wallet was not shutdown cleanly and was last loaded using a build with a newer version of Berkeley DB. If so, please use the software that last loaded this wallet - Cette erreur pourrait survenir si ce porte-monnaie n’a pas été fermé proprement et s’il a été chargé en dernier avec une nouvelle version de Berkeley DB. Si c’est le cas, veuillez utiliser le logiciel qui a chargé ce porte-monnaie en dernier. - - - This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - Ceci est une préversion de test — son utilisation est entièrement à vos risques — ne l’utilisez pour miner ou pour des applications marchandes - - - This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection. - Les frais maximaux de transaction que vous payez (en plus des frais habituels) afin de prioriser une dépense non partielle plutôt qu’une sélection normale de pièces. - - - This is the transaction fee you may discard if change is smaller than dust at this level - Les frais de transaction que vous pouvez ignorer si la monnaie rendue est inférieure à la poussière à ce niveau - - - This is the transaction fee you may pay when fee estimates are not available. - Il s’agit des frais de transaction que vous pourriez payer si aucune estimation de frais n’est proposée. - - - Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. - La taille totale de la chaîne de version de réseau (%i) dépasse la longueur maximale (%i). Réduire le nombre ou la taille de uacomments. - - - Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate. - Impossible de relire les blocs. Vous devrez reconstruire la base de données avec -reindex-chainstate. - - - Unknown wallet file format "%s" provided. Please provide one of "bdb" or "sqlite". - Le format de fichier porte-monnaie « %s » indiqué est inconnu. Veuillez soit indiquer « bdb » soit « sqlite ». - - - Unsupported category-specific logging level %1$s=%2$s. Expected %1$s=<category>:<loglevel>. Valid categories: %3$s. Valid loglevels: %4$s. - Niveau de journalisation spécifique à la catégorie non pris en charge %1$s=%2$s. Attendu %1$s=<catégorie>:<niveaudejournal>. Catégories valides : %3$s. Niveaux de journalisation valides : %4$s. - - - Unsupported chainstate database format found. Please restart with -reindex-chainstate. This will rebuild the chainstate database. - Le format de la base de données chainstate n'est pas supporté. Veuillez redémarrer avec -reindex-chainstate. Cela reconstruira la base de données chainstate. - - - Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future. - Portefeuille créé avec succès. Le type de portefeuille ancien est en cours de suppression et la prise en charge de la création et de l'ouverture des portefeuilles anciens sera supprimée à l'avenir. - - - Wallet loaded successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future. Legacy wallets can be migrated to a descriptor wallet with migratewallet. - Portefeuille chargé avec succès. Le type de portefeuille existant est obsolète et la prise en charge de la création et de l'ouverture de portefeuilles existants sera supprimée à l'avenir. Les anciens portefeuilles peuvent être migrés vers un portefeuille descripteur avec migratewallet. - - - Warning: Dumpfile wallet format "%s" does not match command line specified format "%s". - Avertissement : Le format du fichier de vidage de porte-monnaie « %s » ne correspond pas au format « %s » indiqué dans la ligne de commande. - - - Warning: Private keys detected in wallet {%s} with disabled private keys - Avertissement : Des clés privées ont été détectées dans le porte-monnaie {%s} avec des clés privées désactivées - - - Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. - Avertissement : Nous ne semblons pas être en accord complet avec nos pairs. Une mise à niveau pourrait être nécessaire pour vous ou pour d’autres nœuds du réseau. - - - Witness data for blocks after height %d requires validation. Please restart with -reindex. - Les données témoin pour les blocs postérieurs à la hauteur %d exigent une validation. Veuillez redémarrer avec -reindex. - - - You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain - Vous devez reconstruire la base de données en utilisant -reindex afin de revenir au mode sans élagage. Ceci retéléchargera complètement la chaîne de blocs. - - - %s is set very high! - La valeur %s est très élevée - - - -maxmempool must be at least %d MB - -maxmempool doit être d’au moins %d Mo - - - Cannot obtain a lock on directory %s. %s is probably already running. - Impossible d’obtenir un verrou sur le dossier %s. %s fonctionne probablement déjà. - - - Cannot resolve -%s address: '%s' - Impossible de résoudre l’adresse -%s : « %s » - - - Cannot set -forcednsseed to true when setting -dnsseed to false. - Impossible de définir -forcednsseed comme vrai si -dnsseed est défini comme faux. - - - Cannot set -peerblockfilters without -blockfilterindex. - Impossible de définir -peerblockfilters sans -blockfilterindex - - - %s is set very high! Fees this large could be paid on a single transaction. - %s est très élevé ! Des frais aussi importants pourraient être payés sur une seule transaction. - - - Cannot provide specific connections and have addrman find outgoing connections at the same time. - Il est impossible d’indiquer des connexions précises et en même temps de demander à addrman de trouver les connexions sortantes. - - - Error loading %s: External signer wallet being loaded without external signer support compiled - Erreur de chargement de %s : le porte-monnaie signataire externe est chargé sans que la prise en charge de signataires externes soit compilée - - - Error reading %s! All keys read correctly, but transaction data or address metadata may be missing or incorrect. - Erreur de lecture de %s! Toutes les clés ont été lues correctement, mais les données de transaction ou les métadonnées d'adresse peuvent être manquantes ou incorrectes. - - - Error: Address book data in wallet cannot be identified to belong to migrated wallets - Erreur : Les données du carnet d'adresses du portefeuille ne peuvent pas être identifiées comme appartenant à des portefeuilles migrés - - - Error: Duplicate descriptors created during migration. Your wallet may be corrupted. - Erreur : Descripteurs en double créés pendant la migration. Votre portefeuille est peut-être corrompu. - - - Error: Transaction %s in wallet cannot be identified to belong to migrated wallets - Erreur : La transaction %s dans le portefeuille ne peut pas être identifiée comme appartenant aux portefeuilles migrés. - - - Failed to calculate bump fees, because unconfirmed UTXOs depend on enormous cluster of unconfirmed transactions. - Échec du calcul des frais de majoration, car les UTXO non confirmés dépendent d'un énorme groupe de transactions non confirmées. - - - Failed to remove snapshot chainstate dir (%s). Manually remove it before restarting. - - Échec de suppression du répertoire de l’instantané d’état de la chaîne (%s). Supprimez-le manuellement avant de redémarrer. - - - Failed to rename invalid peers.dat file. Please move or delete it and try again. - Échec de renommage du fichier peers.dat invalide. Veuillez le déplacer ou le supprimer, puis réessayer. - - - Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s. - L'estimation des frais a échoué. Fallbackfee est désactivé. Attendez quelques blocs ou activez %s. - - - Flushing block file to disk failed. This is likely the result of an I/O error. - Échec de vidage du fichier des blocs sur le disque, probablement à cause d’une erreur d’E/S. - - - Flushing undo file to disk failed. This is likely the result of an I/O error. - Échec de vidage du fichier d’annulation sur le disque, probablement à cause d’une erreur d’E/S. - - - Incompatible options: -dnsseed=1 was explicitly specified, but -onlynet forbids connections to IPv4/IPv6 - Options incompatibles : -dnsseed=1 a été explicitement spécifié, mais -onlynet interdit les connexions vers IPv4/IPv6 - - - Invalid amount for %s=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) - Montant non valide pour %s=<amount> : '%s' (doit être au moins égal au minrelay fee de %s pour éviter les transactions bloquées) - - - Maximum transaction weight is less than transaction weight without inputs - Le poids maximal de la transaction est inférieur au poids de la transaction sans entrées - - - Maximum transaction weight is too low, can not accommodate change output - Le poids maximal de la transaction est trop faible et ne permet pas les sorties de monnaie - - - Outbound connections restricted to CJDNS (-onlynet=cjdns) but -cjdnsreachable is not provided - Connexions sortantes limitées à CJDNS (-onlynet=cjdns) mais -cjdnsreachable n'est pas fourni - - - Outbound connections restricted to Tor (-onlynet=onion) but the proxy for reaching the Tor network is explicitly forbidden: -onion=0 - Connexions sortantes limitées à Tor (-onlynet=onion) mais le proxy pour atteindre le réseau Tor est explicitement interdit : -onion=0 - - - Outbound connections restricted to Tor (-onlynet=onion) but the proxy for reaching the Tor network is not provided: none of -proxy, -onion or -listenonion is given - Connexions sortantes limitées à Tor (-onlynet=onion) mais le proxy pour atteindre le réseau Tor n'est pas fourni : aucun des paramètres -proxy, -onion ou -listenonion n'est donné - - - Outbound connections restricted to i2p (-onlynet=i2p) but -i2psam is not provided - Connexions sortantes limitées à i2p (-onlynet=i2p) mais -i2psam n'est pas fourni - - - Rename of '%s' -> '%s' failed. Cannot clean up the background chainstate leveldb directory. - Échec de renommage de « %s » en « %s ». Impossible de nettoyer le répertoire de la base de données d’état de chaîne d’arrière-plan. - - - Specified -blockmaxweight (%d) exceeds consensus maximum block weight (%d) - Le poids maximal de bloc -blockmaxweight indiqué (%d) dépasse le poids maximal de bloc du consensus (%d). - - - Specified -blockreservedweight (%d) exceeds consensus maximum block weight (%d) - Le poids réservé de bloc -blockreservedweight indiqué (%d) dépasse le poids maximal de bloc du consensus (%d). - - - Specified -blockreservedweight (%d) is lower than minimum safety value of (%d) - Le poids réservé de bloc -blockreservedweight indiqué (%d) est inférieur à la valeur minimale de sécurité de (%d) - - - The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs - La combinaison des entrées présélectionnées et de la sélection automatique des entrées du porte-monnaie dépasse le poids maximal de la transaction. Essayez d’envoyer un montant inférieur ou de consolider manuellement les UTXO de votre porte-monnaie. - - - The inputs size exceeds the maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs - La taille des entrées dépasse le poids maximum. Veuillez essayer d'envoyer un montant plus petit ou de consolider manuellement les UTXOs de votre portefeuille. - - - The preselected coins total amount does not cover the transaction target. Please allow other inputs to be automatically selected or include more coins manually - Le montant total des pièces présélectionnées ne couvre pas l'objectif de la transaction. Veuillez permettre à d'autres entrées d'être sélectionnées automatiquement ou inclure plus de pièces manuellement - - - Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input - La transaction nécessite une destination d'une valeur non nulle, un ratio de frais non nul, ou une entrée présélectionnée. - - - UTXO snapshot failed to validate. Restart to resume normal initial block download, or try loading a different snapshot. - La validation de la snapshot UTXO a échoué. Redémarrez pour reprendre le téléchargement normal du bloc initial, ou essayez de charger une autre snapshot. - - - Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool - Les UTXO non confirmés sont disponibles, mais les dépenser crée une chaîne de transactions qui sera rejetée par le mempool. - - - Unexpected legacy entry in descriptor wallet found. Loading wallet %s - -The wallet might have been tampered with or created with malicious intent. - - Une entrée héritée inattendue dans le portefeuille de descripteurs a été trouvée. Chargement du portefeuille %s - -Le portefeuille peut avoir été altéré ou créé avec des intentions malveillantes. - - - - Unrecognized descriptor found. Loading wallet %s - -The wallet might had been created on a newer version. -Please try running the latest software version. - - Descripteur non reconnu trouvé. Chargement du portefeuille %s - -Le portefeuille a peut-être été créé avec une version plus récente. -Veuillez essayer d'utiliser la dernière version du logiciel. - - - - Your computer's date and time appear to be more than %d minutes out of sync with the network, this may lead to consensus failure. After you've confirmed your computer's clock, this message should no longer appear when you restart your node. Without a restart, it should stop showing automatically after you've connected to a sufficient number of new outbound peers, which may take some time. You can inspect the `timeoffset` field of the `getpeerinfo` and `getnetworkinfo` RPC methods to get more info. - La date et l’heure de votre ordinateur semblent décalées de plus de %d minutes par rapport au réseau, ce qui peut entraîner un échec de consensus. Après avoir confirmé l’heure de votre ordinateur, ce message ne devrait plus s’afficher après redémarrage de votre nœud. Sans redémarrage, il devrait cesser de s’afficher automatiquement si vous vous connectez à suffisamment de nouveaux pairs sortants, ce qui peut prendre du temps. Pour plus de précisions, vous pouvez inspecter le champ `timeoffset` des méthodes RPC `getpeerinfo` et `getnetworkinfo`. - - - -Unable to cleanup failed migration - -Impossible de corriger l'échec de la migration - - - -Unable to restore backup of wallet. - -Impossible de restaurer la sauvegarde du portefeuille. - - - whitebind may only be used for incoming connections ("out" was passed) - « whitebind » ne peut être utilisé que pour les connexions entrantes (« out » a été passé) - - - A fatal internal error occurred, see debug.log for details: - Une erreur interne fatale est survenue. Pour plus de précisions, consultez debug.log : - - - Assumeutxo data not found for the given blockhash '%s'. - Les données Assumeutxo sont introuvables pour l’empreinte de bloc « %s » donnée. - - - Block verification was interrupted - La vérification des blocs a été interrompue - - - Cannot write to directory '%s'; check permissions. - Impossible d’écrire dans le dossier « %s » ; vérifiez les droits. - - - Config setting for %s only applied on %s network when in [%s] section. - Paramètre de configuration pour %s qui n’est appliqué sur le réseau %s que s’il se trouve dans la section [%s]. - - - Copyright (C) %i-%i - Tous droits réservés © %i à %i - - - Corrupt block found indicating potential hardware failure. - Un bloc corrompu a été détecté, ce qui indique une défaillance matérielle possible. - - - Corrupted block database detected - Une base de données des blocs corrompue a été détectée - - - Could not find asmap file %s - Le fichier asmap %s est introuvable - - - Could not parse asmap file %s - Impossible d’analyser le fichier asmap %s - - - Disk space is too low! - L’espace disque est trop faible - - - Done loading - Le chargement est terminé - - - Dump file %s does not exist. - Le fichier de vidage %s n’existe pas. - - - Elliptic curve cryptography sanity check failure. %s is shutting down. - Échec du contrôle d’intégrité de la cryptographie à courbe elliptique. Fermeture de %s. - - - Error creating %s - Erreur de création de %s - - - Error initializing block database - Erreur d’initialisation de la base de données des blocs - - - Error initializing wallet database environment %s! - Erreur d’initialisation de l’environnement de la base de données du porte-monnaie %s  - - - Error loading %s - Erreur de chargement de %s - - - Error loading %s: Private keys can only be disabled during creation - Erreur de chargement de %s : les clés privées ne peuvent être désactivées qu’à la création - - - Error loading %s: Wallet corrupted - Erreur de chargement de %s : le porte-monnaie est corrompu - - - Error loading %s: Wallet requires newer version of %s - Erreur de chargement de %s : le porte-monnaie exige une version plus récente de %s - - - Error loading block database - Erreur de chargement de la base de données des blocs - - - Error loading databases - Erreur de chargement des bases de données - - - Error opening block database - Erreur d’ouverture de la base de données des blocs - - - Error opening coins database - Erreur d’ouverture de la base de données des pièces - - - Error reading configuration file: %s - Erreur de lecture du fichier de configuration : %s - - - Error reading from database, shutting down. - Erreur de lecture de la base de données, fermeture en cours - - - Error reading next record from wallet database - Erreur de lecture de l’enregistrement suivant de la base de données du porte-monnaie - - - Error: Cannot extract destination from the generated scriptpubkey - Erreur : Impossible d'extraire la destination du scriptpubkey généré - - - Error: Couldn't create cursor into database - Erreur : Impossible de créer le curseur dans la base de données - - - Error: Disk space is low for %s - Erreur : Il reste peu d’espace disque sur %s - - - Error: Dumpfile checksum does not match. Computed %s, expected %s - Erreur : La somme de contrôle du fichier de vidage ne correspond pas. Calculée %s, attendue %s - - - Error: Failed to create new watchonly wallet - Erreur : Echec de la création d'un nouveau portefeuille watchonly - - - Error: Got key that was not hex: %s - Erreur : La clé obtenue n’était pas hexadécimale : %s - - - Error: Got value that was not hex: %s - Erreur : La valeur obtenue n’était pas hexadécimale : %s - - - Error: Keypool ran out, please call keypoolrefill first - Erreur : La réserve de clés est épuisée, veuillez d’abord appeler « keypoolrefill » - - - Error: Missing checksum - Erreur : Aucune somme de contrôle n’est indiquée - - - Error: No %s addresses available. - Erreur : Aucune adresse %s n’est disponible. - - - Error: This wallet already uses SQLite - Erreur : Ce portefeuille utilise déjà SQLite - - - Error: This wallet is already a descriptor wallet - Erreur : Ce portefeuille est déjà un portefeuille de descripteurs - - - Error: Unable to begin reading all records in the database - Erreur : Impossible de commencer à lire tous les enregistrements de la base de données - - - Error: Unable to make a backup of your wallet - Erreur : Impossible d'effectuer une sauvegarde de votre portefeuille - - - Error: Unable to parse version %u as a uint32_t - Erreur : Impossible d’analyser la version %u en tant que uint32_t - - - Error: Unable to read all records in the database - Erreur : Impossible de lire tous les enregistrements de la base de données - - - Error: Unable to read wallet's best block locator record - Erreur : Impossible de lire l’enregistrement du meilleur bloc du porte-monnaie. - - - Error: Unable to remove watchonly address book data - Erreur : Impossible de supprimer les données du carnet d'adresses en mode veille - - - Error: Unable to write data to disk for wallet %s - Erreur : Impossible d’écrire les données sur le disque pour le portemonnaie %s - - - Error: Unable to write record to new wallet - Erreur : Impossible d’écrire l’enregistrement dans le nouveau porte-monnaie - - - Error: Unable to write solvable wallet best block locator record - Erreur : Impossible d’écrire l’enregistrement du localisateur du meilleur bloc soluble du porte-monnaie - - - Error: Unable to write watchonly wallet best block locator record - Erreur : Impossible d’écrire l’enregistrement du localisateur du meilleur bloc du porte-monnaie juste-regarder - - - Error: database transaction cannot be executed for wallet %s - Erreur ; La transaction de la base de données ne peut pas être exécutée pour le porte-monnaie %s - - - Failed to connect best block (%s). - Échec de connexion du meilleur bloc (%s). - - - Failed to disconnect block. - Échec de déconnexion du bloc. - - - Failed to listen on any port. Use -listen=0 if you want this. - Échec d'écoute sur tous les ports. Si cela est voulu, utiliser -listen=0. - - - Failed to read block. - Échec de lecture du bloc. - - - Failed to rescan the wallet during initialization - Échec de réanalyse du porte-monnaie lors de l’initialisation - - - Failed to start indexes, shutting down.. - Échec du démarrage des index, arrêt. - - - Failed to verify database - Échec de vérification de la base de données - - - Failed to write block. - Échec d’écriture du bloc. - - - Failed to write to block index database. - Échec d’écriture dans la base de données d’index des blocs. - - - Failed to write to coin database. - Échec d’écriture dans la base de données des pièces. - - - Failed to write undo data. - Échec d’écriture des données d’annulation. - - - Failure removing transaction: %s - Échec de suppression de la transaction :%s - - - Fee rate (%s) is lower than the minimum fee rate setting (%s) - Le taux de frais (%s) est inférieur au taux minimal de frais défini (%s) - - - Ignoring duplicate -wallet %s. - Ignore -wallet %s en double. - - - Importing… - Importation… - - - Incorrect or no genesis block found. Wrong datadir for network? - Bloc de genèse incorrect ou introuvable. Mauvais datadir pour le réseau ? - - - Initialization sanity check failed. %s is shutting down. - Échec d’initialisation du test de cohérence. %s est en cours de fermeture. - - - Input not found or already spent - L’entrée est introuvable ou a déjà été dépensée - - - Insufficient dbcache for block verification - Insuffisance de dbcache pour la vérification des blocs - - - Insufficient funds - Les fonds sont insuffisants - - - Invalid -i2psam address or hostname: '%s' - L’adresse ou le nom d’hôte -i2psam est invalide : « %s » - - - Invalid -onion address or hostname: '%s' - L’adresse ou le nom d’hôte -onion est invalide : « %s » - - - Invalid -proxy address or hostname: '%s' - L’adresse ou le nom d’hôte -proxy est invalide : « %s » - - - Invalid P2P permission: '%s' - L’autorisation P2P est invalide : « %s » - - - Invalid amount for %s=<amount>: '%s' (must be at least %s) - Montant non valide pour %s=<amount> : '%s' (doit être au moins %s) - - - Invalid amount for %s=<amount>: '%s' - Montant non valide pour %s=<amount> : '%s' - - - Invalid amount for -%s=<amount>: '%s' - Le montant est invalide pour -%s=<amount> : « %s » - - - Invalid netmask specified in -whitelist: '%s' - Le masque réseau indiqué dans -whitelist est invalide : « %s » - - - Invalid port specified in %s: '%s' - Port non valide spécifié dans %s: '%s' - - - Invalid pre-selected input %s - Entrée présélectionnée non valide %s - - - Listening for incoming connections failed (listen returned error %s) - L'écoute des connexions entrantes a échoué ( l'écoute a renvoyé une erreur %s) - - - Loading P2P addresses… - Chargement des adresses P2P… - - - Loading banlist… - Chargement de la liste d’interdiction… - - - Loading block index… - Chargement de l’index des blocs… - - - Loading wallet… - Chargement du porte-monnaie… - - - Maximum transaction weight must be between %d and %d - Le poids maximal de la transaction doit être compris entre %d et %d - - - Missing amount - Le montant manque - - - Missing solving data for estimating transaction size - Il manque des données de résolution pour estimer la taille de la transaction - - - Need to specify a port with -whitebind: '%s' - Un port doit être indiqué avec -whitebind : « %s » - - - No addresses available - Aucune adresse n’est disponible - - - Not found pre-selected input %s - Entrée présélectionnée introuvable %s - - - Not solvable pre-selected input %s - Entrée présélectionnée non solvable %s - - - Only direction was set, no permissions: '%s' - Seule la direction a été définie, sans permissions : « %s » - - - Prune cannot be configured with a negative value. - L’élagage ne peut pas être configuré avec une valeur négative - - - Prune mode is incompatible with -txindex. - Le mode élagage n’est pas compatible avec -txindex - - - Pruning blockstore… - Élagage du magasin de blocs… - - - Reducing -maxconnections from %d to %d, because of system limitations. - Réduction de -maxconnections de %d à %d, due aux restrictions du système. - - - Replaying blocks… - Relecture des blocs… - - - Rescanning… - Réanalyse… - - - SQLiteDatabase: Failed to execute statement to verify database: %s - SQLiteDatabase : échec d’exécution de l’instruction pour vérifier la base de données : %s - - - SQLiteDatabase: Failed to prepare statement to verify database: %s - SQLiteDatabase : échec de préparation de l’instruction pour vérifier la base de données : %s - - - SQLiteDatabase: Failed to read database verification error: %s - SQLiteDatabase : échec de lecture de l’erreur de vérification de la base de données : %s - - - SQLiteDatabase: Unexpected application id. Expected %u, got %u - SQLiteDatabase : l’ID de l’application est inattendu. %u attendu, %u retourné - - - Section [%s] is not recognized. - La section [%s] n’est pas reconnue - - - Signer did not echo address - Le signataire n’a pas fait écho à l’adresse - - - Signer echoed unexpected address %s - Le signataire a renvoyé une adresse inattendue %s - - - Signer returned error: %s - Le signataire a renvoyé une erreur : %s - - - Signing transaction failed - Échec de signature de la transaction - - - Specified -walletdir "%s" does not exist - Le -walletdir indiqué « %s » n’existe pas - - - Specified -walletdir "%s" is a relative path - Le -walletdir indiqué « %s » est un chemin relatif - - - Specified -walletdir "%s" is not a directory - Le -walletdir indiqué « %s » n’est pas un répertoire - - - Specified blocks directory "%s" does not exist. - Le répertoire des blocs indiqué « %s » n’existe pas - - - Specified data directory "%s" does not exist. - Le répertoire de données spécifié "%s" n'existe pas. - - - Starting network threads… - Démarrage des processus réseau… - - - System error while flushing: %s - Erreur système lors du vidage : %s - - - System error while loading external block file: %s - Erreur système lors du chargement d’un fichier de blocs externe : %s - - - System error while saving block to disk: %s - Erreur système lors de l’enregistrement du bloc sur le disque : %s - - - The source code is available from %s. - Le code source est publié sur %s. - - - The specified config file %s does not exist - Le fichier de configuration indiqué %s n’existe pas - - - The transaction amount is too small to pay the fee - Le montant de la transaction est trop bas pour que les frais soient payés - - - The transactions removal process can only be executed within a db txn - Le processus de suppression des transactions ne peut être exécuté que dans une transaction .de base de données - - - The wallet will avoid paying less than the minimum relay fee. - Le porte-monnaie évitera de payer moins que les frais minimaux de relais. - - - There is no ScriptPubKeyManager for this address - Il n’y a pas de « ScriptPubKeyManager » pour cette adresse. - - - This is experimental software. - Ce logiciel est expérimental. - - - This is the minimum transaction fee you pay on every transaction. - Il s’agit des frais minimaux que vous payez pour chaque transaction. - - - This is the transaction fee you will pay if you send a transaction. - Il s’agit des frais minimaux que vous payerez si vous envoyez une transaction. - - - Transaction %s does not belong to this wallet - La transaction %s n’appartient pas à ce porte-monnaie - - - Transaction amount too small - Le montant de la transaction est trop bas - - - Transaction amounts must not be negative - Les montants des transactions ne doivent pas être négatifs - - - Transaction change output index out of range - L’index des sorties de monnaie des transactions est hors échelle - - - Transaction must have at least one recipient - La transaction doit comporter au moins un destinataire - - - Transaction needs a change address, but we can't generate it. - Une adresse de monnaie est nécessaire à la transaction, mais nous ne pouvons pas la générer. - - - Transaction too large - La transaction est trop grosse - - - Unable to bind to %s on this computer (bind returned error %s) - Impossible de se lier à %s sur cet ordinateur (la liaison a retourné l’erreur %s) - - - Unable to bind to %s on this computer. %s is probably already running. - Impossible de se lier à %s sur cet ordinateur. %s fonctionne probablement déjà - - - Unable to create the PID file '%s': %s - Impossible de créer le fichier PID « %s » : %s - - - Unable to find UTXO for external input - Impossible de trouver l'UTXO pour l'entrée externe - - - Unable to generate initial keys - Impossible de générer les clés initiales - - - Unable to generate keys - Impossible de générer les clés - - - Unable to open %s for writing - Impossible d’ouvrir %s en écriture - - - Unable to parse -maxuploadtarget: '%s' - Impossible d’analyser -maxuploadtarget : « %s » - - - Unable to start HTTP server. See debug log for details. - Impossible de démarrer le serveur HTTP. Consulter le journal de débogage pour plus de précisions. - - - Unable to unload the wallet before migrating - Impossible de vider le portefeuille avant la migration - - - Unknown -blockfilterindex value %s. - La valeur -blockfilterindex %s est inconnue. - - - Unknown address type '%s' - Le type d’adresse « %s » est inconnu - - - Unknown change type '%s' - Le type de monnaie « %s » est inconnu - - - Unknown network specified in -onlynet: '%s' - Un réseau inconnu est indiqué dans -onlynet : « %s » - - - Unknown new rules activated (versionbit %i) - Les nouvelles règles inconnues sont activées (versionbit %i) - - - Unrecognised option "%s" provided in -test=<option>. - Une option non reconnue « %s » a été indiquée dans -test=<option>. - - - Unsupported global logging level %s=%s. Valid values: %s. - Niveau de journalisation global non pris en charge %s=%s. Valeurs valides : %s. - - - Wallet file creation failed: %s - Échec de création du fichier du porte-monnaie : %s - - - acceptstalefeeestimates is not supported on %s chain. - acceptstalefeeestimates n'est pas pris en charge sur la chaîne %s. - - - Unsupported logging category %s=%s. - La catégorie de journalisation %s=%s n’est pas prise en charge - - - Do you want to rebuild the databases now? - Voulez-vous reconstruire les bases de données maintenant ? - - - Error: Could not add watchonly tx %s to watchonly wallet - Erreur : Impossible d’ajouter la transaction juste-regarder %s au portefeuille juste-regarder - - - Error: Could not delete watchonly transactions. - Erreur : Impossible d’effacer les transactions juste-regarder. - - - Error: Wallet does not exist - Erreur : Le portemonnaie n’existe pas - - - Error: cannot remove legacy wallet records - Erreur : Impossible de supprimer les enregistrements d’anciens portemonnaies - - - Not enough file descriptors available. %d available, %d required. - Trop peu de descripteurs de fichiers sont proposés. %d proposés, %d requis - - - User Agent comment (%s) contains unsafe characters. - Le commentaire de l’agent utilisateur (%s) comporte des caractères dangereux - - - Verifying blocks… - Vérification des blocs… - - - Verifying wallet(s)… - Vérification des porte-monnaie… - - - Wallet needed to be rewritten: restart %s to complete - Le porte-monnaie devait être réécrit : redémarrer %s pour terminer l’opération. - - - Settings file could not be read - Impossible de lire le fichier des paramètres - - - Settings file could not be written - Impossible d’écrire le fichier de paramètres - - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_hi.ts b/src/qt/locale/bitcoin_hi.ts index be431c33b37..19fe178d499 100644 --- a/src/qt/locale/bitcoin_hi.ts +++ b/src/qt/locale/bitcoin_hi.ts @@ -286,10 +286,40 @@ Signing is only possible with addresses of the type 'legacy'. unknown अनजान + + Embedded "%1" + अंतर्निहित "%1" + + + Default system font "%1" + डिफ़ॉल्ट सिस्टम फोंट "%1" + + + Custom… + पसंद के अनुसार + Amount राशि + + Onion + network name + Name of Tor network in peer info + अनियन + + + I2P + network name + Name of I2P network in peer info + आई२पी + + + CJDNS + network name + Name of CJDNS network in peer info + सीजेडीएनएस + %n second(s) @@ -675,6 +705,10 @@ The migration process will create a backup of the wallet before migrating. This You are one step away from creating your new wallet! आपके नए बटवे के निर्माण से आप सिर्फ एक कदम दूर है + + Please provide a name and, if desired, enable any advanced options + कृपया एक नाम प्रदान करें और अगर जरूरत हो तो किसी अन्य उच्च विकल्प को सक्षम करें + Intro @@ -727,9 +761,17 @@ The migration process will create a backup of the wallet before migrating. This Full path to a %1 compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins! %1 संगत स्क्रिप्ट का पूर्ण पथ (उदा. C:\Downloads\hwi.exe या /Users/you/Downloads/hwi.py). सावधान: मैलवेयर आपके सिक्के चुरा सकता है! + + Font in the Overview tab: + ओवरव्यू टैब का फोंट + PSBTOperationsDialog + + PSBT Operations + पीएसबीटी संचालन + Save Transaction Data लेन-देन डेटा सहेजें @@ -739,6 +781,10 @@ The migration process will create a backup of the wallet before migrating. This Expanded name of the binary PSBT file format. See: BIP 174. आंशिक रूप से हस्ताक्षरित लेनदेन (बाइनरी) + + Sends %1 to %2 + %1 को %2 के पास भेजता है + own address खुद का पता @@ -822,6 +868,14 @@ The migration process will create a backup of the wallet before migrating. This Number of connections कनेक्शन की संख्या + + Local Addresses + स्थानीय पते + + + Network addresses that your Bitcoin node is currently using to communicate with other nodes. + नेटवर्क पते जो आपका बिटकॉइन नोड वर्तमान में अन्य नोड्स के साथ संचार करने के लिए उपयोग कर रहा है। + Block chain ब्लॉक चेन @@ -870,6 +924,14 @@ The migration process will create a backup of the wallet before migrating. This Select a peer to view detailed information. विस्तृत जानकारी देखने के लिए किसी सहकर्मी का चयन करें। + + Hide Peers Detail + पियर विवरण छिपाएँ + + + Transport + परिवहन + Version संस्करण @@ -1280,6 +1342,14 @@ For more information on using this console, type %6. Copy &amount कॉपी &अमाउंट + + Not recommended due to higher fees and less protection against typos. + उच्च शुल्क और टाइपिंग त्रुटियों के प्रति कम सुरक्षा के कारण इसकी अनुशंसा नहीं की जाती। + + + Generates an address compatible with older wallets. + पुराने वॉलेट के साथ संगत पता बनाता है। + Could not generate new %1 address नया पता उत्पन्न नहीं कर सका %1 diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 3add3b3c06a..de4793f2fce 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -1589,6 +1589,11 @@ A migrációs folyamat készít biztonsági mentést a tárcáról migrálás el Enabling pruning significantly reduces the disk space required to store transactions. All blocks are still fully validated. Reverting this setting requires re-downloading the entire blockchain. A tárolt blokkok számának ritkításával jelentősen csökken a tranzakció történet tárolásához szükséges tárhely. Minden blokk továbbra is érvényesítve lesz. Ha ezt a beállítást később törölni szeretné újra le kell majd tölteni a teljes blokkláncot. + + Maximum database cache size. Make sure you have enough RAM. A larger cache can contribute to faster sync, after which the benefit is less pronounced for most use cases. Lowering the cache size will reduce memory usage. Unused mempool memory is shared for this cache. + Tooltip text for Options window setting that sets the size of the database cache. Explains the corresponding effects of increasing/decreasing this value. + Adatbázis gyorsítótár maximális mérete. Győződjön meg róla, hogy van elég RAM. Nagyobb gyorsítótár gyorsabb szinkronizálást eredményez utána viszont az előnyei kevésbé számottevők. A gyorsítótár méretének csökkentése a memóriafelhasználást is mérsékli. A használaton kívüli mempool memória is osztozik ezen a táron. + Size of &database cache A&datbázis gyorsítótár mérete @@ -1601,6 +1606,14 @@ A migrációs folyamat készít biztonsági mentést a tárcáról migrálás el Full path to a %1 compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins! Teljes elérési útvonal a %1 kompatibilis szkripthez (pl. C:\Downloads\hwi.exe vagy /Users/felhasznalo/Downloads/hwi.py). Vigyázat: rosszindulatú programok ellophatják az érméit! + + Automatically open the Bitcoin client port on the router. This only works when your router supports PCP or NAT-PMP and it is enabled. The external port could be random. + A Bitcoin kliens port automatikus megnyitása a routeren. Ez csak akkor működik, ha a router támogatja a PCP-t vagy NAT-PMP-t és engedélyezve is van. A külső port lehet véletlenszerűen választott. + + + Map port using PCP or NA&T-PMP + Külső port megnyitása PCP-vel vagy NA&T-PMP-vel + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) A proxy IP címe (pl.: IPv4: 127.0.0.1 / IPv6: ::1) @@ -4176,6 +4189,10 @@ A "Fájl > Tárca megnyitása" menüben tölthet be egyet. No wallet file format provided. To use createfromdump, -format=<format> must be provided. Nincs tárca fájlformátum megadva. A createfromdump használatához -format=<format> megadása kötelező. + + Option '-upnp' is set but UPnP support was dropped in version 29.0. Consider using '-natpmp' instead. + Az '-upnp' kapcsoló beállítva, de az UPnP támogatás megszűnt a 29.0 verzióval. Kérjük használja a '-natpmp' kapcsolót. + Please contribute if you find %s useful. Visit %s for further information about the software. Kérjük támogasson, ha hasznosnak találta a %s-t. Az alábbi linken további információt találhat a szoftverről: %s. @@ -4284,6 +4301,10 @@ A "Fájl > Tárca megnyitása" menüben tölthet be egyet. -maxmempool must be at least %d MB -maxmempool legalább %d MB kell legyen. + + Cannot obtain a lock on directory %s. %s is probably already running. + Nem zárolható ez a könyvtár: %s. A %s valószínűleg fut már. + Cannot resolve -%s address: '%s' -%s cím feloldása nem sikerült: '%s' @@ -4386,6 +4407,10 @@ A "Fájl > Tárca megnyitása" menüben tölthet be egyet. Rename of '%s' -> '%s' failed. Cannot clean up the background chainstate leveldb directory. Nem sikerült az '%s' -> '%s' átnevezés. Nem lehet kitisztítani a háttér láncállapot leveldb könyvtárat. + + Specified -blockmaxweight (%d) exceeds consensus maximum block weight (%d) + A megadott -blockmaxweight (%d) meghaladja a konszenzus maximum blokk súlyt (%d) + The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs Az előre kiválasztott bemenetek és a tárca automatikus bemeneteinek kombinációja meghaladja a maximális tranzakciós súlyt. Kérjük próbáljon kisebb összeget küldeni vagy kézzel egyesítse a tárca UTXO-it. @@ -4540,6 +4565,10 @@ A tárca biztonsági mentésének visszaállítása sikertelen. Error opening block database Hiba a blokk-adatbázis megnyitása közben. + + Error opening coins database + Hiba az érme-adatbázis megnyitása közben + Error reading configuration file: %s Hiba a konfigurációs fájl olvasása közben: %s @@ -5048,6 +5077,10 @@ A tárca biztonsági mentésének visszaállítása sikertelen. Unsupported logging category %s=%s. Nem támogatott naplózási kategória %s=%s + + Do you want to rebuild the databases now? + Újra akarja építeni az adatbázisokat most? + Error: Could not add watchonly tx %s to watchonly wallet Hiba: Nem sikerült hozzáadni a megfigyelt %s tranzakciót a figyelő tárcához @@ -5056,6 +5089,14 @@ A tárca biztonsági mentésének visszaállítása sikertelen. Error: Could not delete watchonly transactions. Hiba: Nem lehet törölni csak megfigyelt tranzakciókat. + + Error: Wallet does not exist + Hiba: Tárca nem létezik + + + Error: cannot remove legacy wallet records + Hiba: nem lehet eltávolítani a régi típusú tárca bejegyzéseit + User Agent comment (%s) contains unsafe characters. A felhasználói ügynök megjegyzés (%s) veszélyes karaktert tartalmaz. diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index f15d363a470..7946c67e5a0 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -572,7 +572,7 @@ E' possibile firmare solo con indirizzi di tipo "legacy". Syncing Headers (%1%)… - Sincronizzazione Intestazioni in corso (1%1%)... + Sincronizzazione Intestazioni in corso (%1%)... Synchronizing with network… diff --git a/src/qt/locale/bitcoin_kn.ts b/src/qt/locale/bitcoin_kn.ts index 1ef8b69c2c0..fd047e939ef 100644 --- a/src/qt/locale/bitcoin_kn.ts +++ b/src/qt/locale/bitcoin_kn.ts @@ -728,6 +728,18 @@ Signing is only possible with addresses of the type 'legacy'.     + + Specified -blockmaxweight (%d) exceeds consensus maximum block weight (%d) + ನಿರ್ದಿಷ್ಟ -ಬ್ಲಾಕ್‌ಮ್ಯಾಕ್ಸ್‌ವೈಟ್ (%d) ಸಮ್ಮತಿಯ ಗರಿಷ್ಠ ಬ್ಲಾಕ್ ತೂಕವನ್ನು (%d) ಮೀರಿದೆ + + + Specified -blockreservedweight (%d) exceeds consensus maximum block weight (%d) + ನಿರ್ದಿಷ್ಟ -ಬ್ಲಾಕ್‌ರಿಸರ್ವ್ಡ್‌ವೈಟ್ (%d) ಸಮ್ಮತಿಯ ಗರಿಷ್ಠ ಬ್ಲಾಕ್ ತೂಕವನ್ನು (%d) ಮೀರಿದೆ + + + Specified -blockreservedweight (%d) is lower than minimum safety value of (%d) + ನಿರ್ದಿಷ್ಟ -ಬ್ಲಾಕ್‌ರಿಸರ್ವ್ಡ್‌ವೈಟ್ (%d) ಕನಿಷ್ಠ ಸುರಕ್ಷತಾ ಮೌಲ್ಯಕ್ಕಿಂತ (%d) ಕಡಿಮೆಯಾಗಿದೆ + The wallet will avoid paying less than the minimum relay fee. ನೆಲೆಯ ರೆಲೇ ಶುಲ್ಕದಿಂದ ಕಡಿಮೆ ಶುಲ್ಕವನ್ನು ಕೊಡದಂತೆ ವಾಲೆಟ್ ನುಡಿಮುಟ್ಟುವುದು. diff --git a/src/qt/locale/bitcoin_ko.ts b/src/qt/locale/bitcoin_ko.ts index 2337ac42a0d..c62775b8aa7 100644 --- a/src/qt/locale/bitcoin_ko.ts +++ b/src/qt/locale/bitcoin_ko.ts @@ -2471,7 +2471,7 @@ BIP70의 광범위한 보안 결함으로 인해 모든 가맹점에서는 지 Outbound Manual: added using RPC %1 or %2/%3 configuration options Explanatory text for an outbound peer connection that was established manually through one of several methods. The numbered arguments are stand-ins for the methods available to establish manual connections. - 아웃바운드 매뉴얼 : RPC 1%1 이나 2%2/3%3 을 사용해서 환경설정 옵션을 추가 + 아웃바운드 매뉴얼 : RPC %1 이나 %2/%3 을 사용해서 환경설정 옵션을 추가 Outbound Feeler: short-lived, for testing addresses @@ -2555,12 +2555,12 @@ For more information on using this console, type %6. %7WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.%8 RPC console welcome message. Placeholders %7 and %8 are style tags for the warning content, and they are not space separated from the rest of the text intentionally. - 1%1 RPC 콘솔에 오신 것을 환영합니다. -위쪽 및 아래쪽 화살표를 사용하여 기록 탐색을하고 2%2를 사용하여 화면을 지우세요. -3%3과 4%4을 사용하여 글꼴 크기 증가 또는 감소하세요 -사용 가능한 명령의 개요를 보려면 5%5를 입력하십시오. -이 콘솔 사용에 대한 자세한 내용을 보려면 6%6을 입력하십시오. -7%7 경고: 사기꾼들은 사용자들에게 여기에 명령을 입력하라고 말하고 활발히 금품을 훔칩니다. 완전히 이해하지 않고 이 콘솔을 사용하지 마십시오. 8%8 + %1 RPC 콘솔에 오신 것을 환영합니다. +위쪽 및 아래쪽 화살표를 사용하여 기록 탐색을하고 %2를 사용하여 화면을 지우세요. +%3과 %4을 사용하여 글꼴 크기 증가 또는 감소하세요 +사용 가능한 명령의 개요를 보려면 %5를 입력하십시오. +이 콘솔 사용에 대한 자세한 내용을 보려면 %6을 입력하십시오. +%7 경고: 사기꾼들은 사용자들에게 여기에 명령을 입력하라고 말하고 활발히 금품을 훔칩니다. 완전히 이해하지 않고 이 콘솔을 사용하지 마십시오. %8 Executing… diff --git a/src/qt/locale/bitcoin_ml.ts b/src/qt/locale/bitcoin_ml.ts index 15cb5e8cfa6..9b732a3dacd 100644 --- a/src/qt/locale/bitcoin_ml.ts +++ b/src/qt/locale/bitcoin_ml.ts @@ -178,6 +178,14 @@ Signing is only possible with addresses of the type 'legacy'. Enter the old passphrase and new passphrase for the wallet. വാലെറ്റിന്റെ പഴയ രഹസ്യപദവും പുതിയ രഹസ്യപദവും നൽകുക. + + Continue + തുടരുക + + + Back + മടങ്ങിപ്പോവുക + Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. നിങ്ങളുടെ വാലറ്റ് എൻ‌ക്രിപ്റ്റ് ചെയ്യുന്നതിലൂടെ നിങ്ങളുടെ കമ്പ്യൂട്ടറിനെ ബാധിക്കുന്ന ക്ഷുദ്രവെയർ‌ മോഷ്ടിക്കുന്നതിൽ‌ നിന്നും നിങ്ങളുടെ ബിറ്റ്കോയിനുകളെ പൂർണ്ണമായി സംരക്ഷിക്കാൻ‌ കഴിയില്ല. @@ -482,6 +490,14 @@ Signing is only possible with addresses of the type 'legacy'. Close Wallet… വാലറ്റ് അടയ്ക്കുക + + Create Wallet… + വാലറ്റ് സൃഷ്ടിക്കുക + + + Close All Wallets… + എല്ലാ വാലറ്റുകളും അടയ്ക്കുക + &File & ഫയൽ @@ -502,6 +518,10 @@ Signing is only possible with addresses of the type 'legacy'. Synchronizing with network… നെറ്റ്‌വർക്കുമായി സമന്വയിപ്പിക്കുന്നു... + + Connecting to peers… + സമപ്രായക്കാരുമായി ബന്ധിപ്പിക്കുന്നു... + Request payments (generates QR codes and bitcoin: URIs) പേയ്‌മെന്റുകൾ അഭ്യർത്ഥിക്കുക (QR കോഡുകളും ബിറ്റ്കോയിനും സൃഷ്ടിക്കുന്നു: URI- കൾ) @@ -598,6 +618,10 @@ Signing is only possible with addresses of the type 'legacy'. Close all wallets എല്ലാ വാലറ്റുകളും അടയ്‌ക്കുക ... + + Migrate Wallet + വാലറ്റ് മൈഗ്രേറ്റ് ചെയ്യുക + Show the %1 help message to get a list with possible Bitcoin command-line options സാധ്യമായ ബിറ്റ്കോയിൻ കമാൻഡ്-ലൈൻ ഓപ്ഷനുകളുള്ള ഒരു ലിസ്റ്റ് ലഭിക്കുന്നതിന് %1 സഹായ സന്ദേശം കാണിക്കുക @@ -614,6 +638,11 @@ Signing is only possible with addresses of the type 'legacy'. No wallets available വാലറ്റ് ഒന്നും ലഭ്യം അല്ല + + Wallet Data + Name of the wallet data file format. + വാലറ്റ് അടിസ്ഥാനവിവരം + Load Wallet Backup The title for Restore Wallet File Windows @@ -862,6 +891,13 @@ Signing is only possible with addresses of the type 'legacy'. വാലറ്റ് രൂപീകരണത്തിലെ മുന്നറിയിപ്പ് + + MigrateWalletActivity + + Migrate Wallet + വാലറ്റ് മൈഗ്രേറ്റ് ചെയ്യുക + + OpenWalletActivity @@ -1081,6 +1117,10 @@ Signing is only possible with addresses of the type 'legacy'. &Window &ജാലകം + + Continue + തുടരുക + Error പിശക് @@ -1490,6 +1530,11 @@ Signing is only possible with addresses of the type 'legacy'. Export the data in the current tab to a file നിലവിലുള്ള ടാബിലെ വിവരങ്ങൾ ഒരു ഫയലിലേക്ക് എക്സ്പോർട്ട് ചെയ്യുക + + Wallet Data + Name of the wallet data file format. + വാലറ്റ് അടിസ്ഥാനവിവരം + bitcoin-core diff --git a/src/qt/locale/bitcoin_ne.ts b/src/qt/locale/bitcoin_ne.ts index 5c08b545569..2fb6abc6548 100644 --- a/src/qt/locale/bitcoin_ne.ts +++ b/src/qt/locale/bitcoin_ne.ts @@ -184,6 +184,14 @@ Signing is only possible with addresses of the type 'legacy'. Enter the old passphrase and new passphrase for the wallet. वालेटको लागि पुरानो पासफ्रेज र नयाँ पासफ्रेज प्रविष्ट गर्नुहोस्। + + Continue + जारी राख्नुहोस् + + + Back + फिर्ता जानुहोस् + Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. याद गर्नुहोस् कि तपाईको वालेट इन्क्रिप्ट गर्नाले तपाईको बिटकोइनलाई तपाईको कम्प्युटरमा मालवेयरले चोरी हुनबाट पूर्णतया सुरक्षित गर्न सक्दैन। @@ -282,6 +290,11 @@ Signing is only possible with addresses of the type 'legacy'. Explanatory text shown on startup when the settings file cannot be read. Prompts user to make a choice between resetting or aborting. के तपाइँ पूर्वनिर्धारित मानहरूमा सेटिङहरू रिसेट गर्न चाहनुहुन्छ, वा परिवर्तन नगरी रद्द गर्न चाहनुहुन्छ? + + A fatal error occurred. Check that settings file is writable, or try running with -nosettings. + Explanatory text shown on startup when the settings file could not be written. Prompts user to check that we have the ability to write to the file. Explains that the user has the option of running without a settings file. + एउटा ठूलो त्रुटि भयो। सेटिङ फाइल लेख्न मिल्छ कि मिल्दैन जाँच गर्नुहोस्, वा -nosettings लेखेर चलाउने प्रयास गर्नुहोस्। + Error: %1 त्रुटि: %1 @@ -684,6 +697,10 @@ Signing is only possible with addresses of the type 'legacy'. &OK &ठिक छ + + Continue + जारी राख्नुहोस् + OverviewPage diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index 3f9496981c4..900c3e29490 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -57,19 +57,49 @@ C&hoose Wybierz + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + To są twoje adresy Bitcoin do wysyłania płatności. Zawsze sprawdzaj kwotę oraz adres odbiorczy przed wysłaniem monet. + These are your Bitcoin addresses for receiving payments. Use the 'Create new receiving address' button in the receive tab to create new addresses. Signing is only possible with addresses of the type 'legacy'. To są twoje adresy Bitcoin do otrzymywania płatności. Użyj przycisku 'Utwórz nowy adres odbioru' na karcie odbioru, aby utworzyć nowe adresy. Podpisywanie jest możliwe tylko z adresami typu 'legacy'. + + &Copy Address + &Skopiuj adres + + + Copy &Label + Skopiuj &etykietę + + + &Edit + &Edytuj + + + Export Address List + Eksportuj listę adresów + + + Comma separated file + Expanded name of the CSV file format. See: https://en.wikipedia.org/wiki/Comma-separated_values. + Plik rozdzielany przecinkami + + + There was an error trying to save the address list to %1. Please try again. + An error message. %1 is a stand-in argument for the name of the file we attempted to save to. + Wystąpił błąd podczas próby zapisania listy adresów do %1. Spróbuj ponownie. + Sending addresses - %1 Wysyłające adresy - %1 Receiving addresses - %1 - Odbierające adresy - %1 + Adresy odbiorcze - %1 Exporting Failed @@ -95,11 +125,11 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. AskPassphraseDialog Passphrase Dialog - Okienko Hasła + Okienko Hasła Enter passphrase - Wpisz hasło + Wpisz hasło New passphrase @@ -107,16 +137,24 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Repeat new passphrase - Powtórz nowe hasło + Powtórz nowe hasło Show passphrase - Pokaż hasło + Pokaż hasło Encrypt wallet Zaszyfruj portfel + + This operation needs your wallet passphrase to unlock the wallet. + Ta operacja wymaga hasła do twojego portfela, aby go odblokować. + + + Unlock wallet + Odblokuj portfel + Change passphrase Zmień hasło @@ -127,7 +165,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - hasłoOstrzeżenie: Jeśli zaszyfrujesz swój portfel i zgubisz hasło - <b>STRACISZ WSZYSTKIE SWOJE BITCONY</b>! + Uwaga: Jeśli zaszyfrujesz swój portfel i zgubisz swoje hasło, <b>STRACISZ WSZYSTKIE SWOJE BITCOINY</b>! Are you sure you wish to encrypt your wallet? @@ -159,7 +197,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Wallet to be encrypted - Portfel do zaszyfrowania + Portfel do zaszyfrowania Your wallet is about to be encrypted. @@ -222,22 +260,22 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Banned Until - Blokada do + Zablokowany do BitcoinApplication Settings file %1 might be corrupt or invalid. - Plik ustawień 1%1 może być uszkodzony lub nieprawidłowy + Plik ustawień %1 może być uszkodzony lub nieprawidłowy Runaway exception - Błąd zapisu do portfela + Nieobsługiwany wyjątek A fatal error occurred. %1 can no longer continue safely and will quit. - Wystąpił fatalny błąd. %1 nie może być kontynuowany i zostanie zakończony. + Wystąpił krytyczny błąd. %1 nie może już bezpiecznie kontynuować i zostanie zamknięty. Internal error @@ -324,7 +362,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Feeler Short-lived peer connection type that tests the aliveness of known addresses. - Szczelinomierz + Połączenie testowe Address Fetch @@ -343,7 +381,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. %n second(s) %n sekunda - %n sekund + %n sekundy %n sekund @@ -351,7 +389,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. %n minute(s) %n minuta - %n minut + %n minuty %n minut @@ -359,7 +397,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. %n hour(s) %n godzina - %n godzin + %n godziny %n godzin @@ -376,7 +414,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. %n tydzień %n tygodnie - %n tygodnie + %n tygodni @@ -388,7 +426,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. %n rok %n lata - %n lata + %n lat @@ -521,7 +559,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. &Load PSBT from file… - Wczytaj PSBT z pliku... + &Wczytaj PSBT z pliku... Open &URI… @@ -533,7 +571,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Create Wallet… - Utwórz portfel... + Stwórz portfel... Close All Wallets… @@ -577,7 +615,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Request payments (generates QR codes and bitcoin: URIs) - Zażądaj płatności (wygeneruj QE code i bitcoin: URI) + Zażądaj płatności (generuje kody QR i URI bitcoin:) Show the list of used sending addresses and labels @@ -595,8 +633,8 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Processed %n block(s) of transaction history. Przetworzono %n blok historii transakcji. - Przetworzono 1%n bloków historii transakcji. - Przetworzono 1%n bloków historii transakcji. + Przetworzono %n bloki historii transakcji. + Przetworzono %n bloków historii transakcji. @@ -657,7 +695,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. &Receiving addresses - &Adresy odbioru + &Adresy odbiorcze Open a bitcoin: URI @@ -699,7 +737,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Show the %1 help message to get a list with possible Bitcoin command-line options - Pokaż pomoc %1 aby zobaczyć listę wszystkich opcji lnii poleceń. + Pokaż pomoc dla %1 aby zobaczyć listę możliwych opcji linii poleceń &Mask values @@ -753,12 +791,16 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. &Hide &Ukryj + + S&how + &Wyświetl + %n active connection(s) to Bitcoin network. A substring of the tooltip. %n aktywne połączenie z siecią Bitcoin. - %n aktywnych połączeń z siecią Bitcoin. + %n aktywne połączenia z siecią Bitcoin. %n aktywnych połączeń z siecią Bitcoin. @@ -942,11 +984,11 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Confirmed - Potwerdzone + Potwierdzone Copy amount - Kopiuj kwote + Skopiuj kwotę &Copy address @@ -958,7 +1000,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Copy &amount - Kopiuj kwotę + Skopiuj &kwotę Copy transaction &ID and output index @@ -978,7 +1020,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Copy fee - Skopiuj prowizję + Skopiuj opłatę Copy after fee @@ -986,7 +1028,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Copy bytes - Skopiuj ilość bajtów + Skopiuj bajty Copy change @@ -1018,7 +1060,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Create Wallet Title of window indicating the progress of creation of a new wallet. - Stwórz potrfel + Stwórz portfel Creating Wallet <b>%1</b>… @@ -1027,7 +1069,7 @@ Podpisywanie jest możliwe tylko z adresami typu 'legacy'. Create wallet failed - Nieudane tworzenie potrfela + Utworzenie portfela nie powiodło się Create wallet warning @@ -1114,7 +1156,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Open wallet warning - Ostrzeżenie przy otworzeniu potrfela + Ostrzeżenie podczas otwierania portfela Open Wallet @@ -1182,7 +1224,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za CreateWalletDialog Create Wallet - Stwórz potrfel + Stwórz portfel You are one step away from creating your new wallet! @@ -1243,7 +1285,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Compiled without external signing support (required for external signing) "External signing" means using devices such as hardware wallets. - Skompilowany bez obsługi podpisywania zewnętrznego (wymagany do podpisywania zewnętrzengo) + Skompilowany bez obsługi podpisywania zewnętrznego (wymagany do podpisywania zewnętrznego) @@ -1274,7 +1316,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Edit receiving address - Zmień adres odbioru + Zmień adres odbiorczy Edit sending address @@ -1510,11 +1552,11 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za %1 is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain. - %1 jest w trakcie synchronizacji. Trwa pobieranie i weryfikacja nagłówków oraz bloków z sieci w celu uzyskania aktualnego stanu łańcucha. + %1 jest w trakcie synchronizacji. Będzie pobierał oraz weryfikował nagłówki i bloki z sieci w celu uzyskania aktualnego stanu łańcucha. Unknown. Syncing Headers (%1, %2%)… - nieznany, Synchronizowanie nagłówków (1%1, 2%2%) + nieznany, Synchronizowanie nagłówków (%1, %2%) Unknown. Pre-syncing Headers (%1, %2%)… @@ -1555,6 +1597,11 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Enabling pruning significantly reduces the disk space required to store transactions. All blocks are still fully validated. Reverting this setting requires re-downloading the entire blockchain. Włączenie czyszczenia znacznie zmniejsza ilość miejsca na dysku wymaganego do przechowywania transakcji. Wszystkie bloki są nadal w pełni zweryfikowane. Przywrócenie tego ustawienia wymaga ponownego pobrania całego łańcucha bloków. + + Maximum database cache size. Make sure you have enough RAM. A larger cache can contribute to faster sync, after which the benefit is less pronounced for most use cases. Lowering the cache size will reduce memory usage. Unused mempool memory is shared for this cache. + Tooltip text for Options window setting that sets the size of the database cache. Explains the corresponding effects of increasing/decreasing this value. + Maksymalna wielkość pamięci podręcznej dla bazy danych osiągnięta. Upewnij się, że masz odpowiednią ilość pamięci RAM. Większa ilość pamięci podręcznej może przyśpieszyć synchronizację, z mniejszym wpływem w większości przypadków. Zmniejszenie wielkości tej pamięci zredukuje użycie pamięci. Nieużywana pamięć mempool jest współdzielona z cache. + Size of &database cache Wielkość bufora bazy &danych @@ -1567,6 +1614,10 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Full path to a %1 compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins! Pełna ścieżka do skryptu zgodnego z %1 (np. C:\Downloads\hwi.exe lub /Users/you/Downloads/hwi.py). Uwaga: złośliwe oprogramowanie może ukraść Twoje monety! + + Automatically open the Bitcoin client port on the router. This only works when your router supports PCP or NAT-PMP and it is enabled. The external port could be random. + Automatycznie przekieruj porty dla klienta Bitcoin na routerze. Ta opcja działa tylko i wyłącznie, jeżeli twój router wspiera PCP lub NAT-PMP oraz jest ono włączone. Zewnętrzny port może być losowy. + Map port using PCP or NA&T-PMP Mapuj port używając PCP lub NA&T-PMP @@ -1645,12 +1696,12 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Whether to set subtract fee from amount as default or not. Tooltip text for Options window setting that sets subtracting the fee from a sending amount as default. - Czy ustawić opłatę odejmowaną od kwoty jako domyślną, czy nie. + Ustawić domyślne odejmowanie opłaty od kwoty czy nie. Subtract &fee from amount by default An Options window setting to set subtracting the fee from a sending amount as default. - Domyślnie odejmij opłatę od kwoty + Domyślnie odejmuj &opłatę od kwoty Expert @@ -1658,7 +1709,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Enable coin &control features - Włącz funk&cje kontoli monet + Włącz funk&cje kontroli monet If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed. @@ -1708,7 +1759,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Port of the proxy (e.g. 9050) - Port proxy (np. 9050) + Port serwera proxy (np. 9050) Used for reaching peers via: @@ -1768,7 +1819,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Whether to show coin control features or not. - Wybierz pokazywanie lub nie funkcji kontroli monet. + Czy wyświetlać funkcje kontroli monet, czy nie. Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor onion services. @@ -1785,7 +1836,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Compiled without external signing support (required for external signing) "External signing" means using devices such as hardware wallets. - Skompilowany bez obsługi podpisywania zewnętrznego (wymagany do podpisywania zewnętrzengo) + Skompilowany bez obsługi podpisywania zewnętrznego (wymagany do podpisywania zewnętrznego) default @@ -1869,7 +1920,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Watch-only: - Tylko podglądaj: + Tylko do obserwacji: Available: @@ -1909,7 +1960,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Your current balance in watch-only addresses - Twoje obecne saldo na podglądanym adresie + Twoje obecne saldo na adresie tylko do obserwacji Spendable: @@ -1921,15 +1972,15 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Unconfirmed transactions to watch-only addresses - Niepotwierdzone transakcje na podglądanych adresach + Niepotwierdzone transakcje na adresach tylko do obserwacji Mined balance in watch-only addresses that has not yet matured - Wykopane monety na podglądanych adresach które jeszcze nie dojrzały + Saldo wydobytych monet na adresach tylko do obserwacji, które nie są jeszcze dojrzałe Current total balance in watch-only addresses - Łączna kwota na podglądanych adresach + Łączna kwota na adresach tylko do obserwacji Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings->Mask values. @@ -1984,12 +2035,16 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za Signed transaction successfully. Transaction is ready to broadcast. - transakcja + Transakcja została podpisana pomyślnie. Transakcja jest gotowa do rozgłoszenia. Unknown error processing transaction. Nieznany błąd podczas przetwarzania transakcji. + + Transaction broadcast successfully! Transaction ID: %1 + Transakcja została rozgłoszona pomyślnie! ID transakcji: %1 + Transaction broadcast failed: %1 Nie udało się rozgłosić transakscji: %1 @@ -2053,7 +2108,7 @@ Proces migracji utworzy kopię zapasową portfela przed migracją. Plik kopii za (But this wallet cannot sign transactions.) - (Ale ten portfel nie może podipisać transakcji.) + (Ale ten portfel nie może podpisywać transakcji.) (But this wallet does not have the right keys.) @@ -2173,7 +2228,7 @@ Jeśli pojawia się ten błąd, poproś sprzedawcę o podanie URI zgodnego z BIP Resulting URI too long, try to reduce the text for label / message. - Wynikowy URI jest zbyt długi, spróbuj zmniejszyć tekst etykiety / wiadomości + Wynikowy URI jest zbyt długi, spróbuj skrócić tekst etykiety / wiadomości Error encoding URI into QR Code. @@ -2356,12 +2411,12 @@ Jeśli pojawia się ten błąd, poproś sprzedawcę o podanie URI zgodnego z BIP The total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). Tooltip text for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). - Całkowita liczba adresów otrzymanych od tego węzła, które zostały przetworzone (wyklucza adresy, które zostały odrzucone ze względu na ograniczenie szybkości). + Łączna liczba adresów otrzymanych od tego węzła, które zostały przetworzone (z wyłączeniem adresów odrzuconych z powodu ograniczenia prędkości). The total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. Tooltip text for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - Całkowita liczba adresów otrzymanych od tego węzła, które zostały odrzucone (nieprzetworzone) z powodu ograniczenia szybkości. + Łączna liczba adresów otrzymanych od tego węzła, które zostały odrzucone (nieprzetworzone) z powodu ograniczenia prędkości. Addresses Processed @@ -2371,7 +2426,7 @@ Jeśli pojawia się ten błąd, poproś sprzedawcę o podanie URI zgodnego z BIP Addresses Rate-Limited Text title for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. - Wskaźnik-Ograniczeń Adresów + Adresy ograniczone limitem User Agent @@ -2383,7 +2438,7 @@ Jeśli pojawia się ten błąd, poproś sprzedawcę o podanie URI zgodnego z BIP Current block height - Obecna ilość bloków + Bieżąca wysokość bloku Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. @@ -2423,7 +2478,7 @@ Jeśli pojawia się ten błąd, poproś sprzedawcę o podanie URI zgodnego z BIP High bandwidth BIP152 compact block relay: %1 - Kompaktowy przekaźnik blokowy BIP152 o dużej przepustowości: 1 %1 + Przekaźnik skompaktowanych bloków o wysokiej przepustowości BIP152: %1 High Bandwidth @@ -2444,7 +2499,7 @@ Jeśli pojawia się ten błąd, poproś sprzedawcę o podanie URI zgodnego z BIP Elapsed time since a novel transaction accepted into our mempool was received from this peer. Tooltip text for the Last Transaction field in the peer details area. - Czas, który upłynął od otrzymania nowej transakcji przyjętej do naszej pamięci od tego partnera. + Czas, który upłynął od otrzymania nowej transakcji przyjętej do naszego mempoola od tego partnera. Last Send @@ -2460,7 +2515,7 @@ Jeśli pojawia się ten błąd, poproś sprzedawcę o podanie URI zgodnego z BIP The duration of a currently outstanding ping. - Czas trwania nadmiarowego pingu + Czas trwania aktualnie oczekującego pinga. Ping Wait @@ -2496,7 +2551,7 @@ Jeśli pojawia się ten błąd, poproś sprzedawcę o podanie URI zgodnego z BIP Debug log file - Plik logowania debugowania + Plik dziennika debugowania Clear console @@ -2523,17 +2578,17 @@ Jeśli pojawia się ten błąd, poproś sprzedawcę o podanie URI zgodnego z BIP Outbound Block Relay: does not relay transactions or addresses Explanatory text for an outbound peer connection that relays network information about blocks and not transactions or addresses. - Outbound Block Relay: nie przekazuje transakcji ani adresów + Wychodzący przekaźnik bloków: nie przekazuje transakcji ani adresów Outbound Manual: added using RPC %1 or %2/%3 configuration options Explanatory text for an outbound peer connection that was established manually through one of several methods. The numbered arguments are stand-ins for the methods available to establish manual connections. - Outbound Manual: dodano przy użyciu opcji konfiguracyjnych RPC 1%1 lub 2%2/3%3 + Połączenie wychodzące ręczne: dodano przy użyciu opcji konfiguracyjnych RPC %1 lub %2/%3 Outbound Feeler: short-lived, for testing addresses Explanatory text for a short-lived outbound peer connection that is used to test the aliveness of known addresses. - Outbound Feeler: krótkotrwały, do testowania adresów + Wychodzące połączenie testowe: krótkotrwałe, do testowania adresów Outbound Address Fetch: short-lived, for soliciting addresses @@ -2728,7 +2783,7 @@ Aby uzyskać więcej informacji na temat używania tej konsoli wpisz %6. Requested payments history - Żądanie historii płatności + Żądana historia płatności Show the selected request (does the same as double clicking an entry) @@ -2764,7 +2819,7 @@ Aby uzyskać więcej informacji na temat używania tej konsoli wpisz %6. Copy &amount - Kopiuj kwotę + Skopiuj &kwotę Not recommended due to higher fees and less protection against typos. @@ -3034,11 +3089,11 @@ Uwaga: Ponieważ opłata jest naliczana za każdy bajt, opłata "100 satoshi za Copy amount - Kopiuj kwote + Skopiuj kwotę Copy fee - Skopiuj prowizję + Skopiuj opłatę Copy after fee @@ -3054,7 +3109,7 @@ Uwaga: Ponieważ opłata jest naliczana za każdy bajt, opłata "100 satoshi za %1 (%2 blocks) - %1 (%2 bloków)github.com + %1 (%2 bloków) Sign on device @@ -3080,7 +3135,7 @@ Uwaga: Ponieważ opłata jest naliczana za każdy bajt, opłata "100 satoshi za %1 to '%2' - %1 do '%2'8f0451c0-ec7d-4357-a370-eff72fb0685f + %1 do '%2' %1 to %2 @@ -3147,7 +3202,7 @@ Uwaga: Ponieważ opłata jest naliczana za każdy bajt, opłata "100 satoshi za Please, review your transaction. You can create and send this transaction or create a Partially Signed Bitcoin Transaction (PSBT), which you can save or copy and then sign with, e.g., an offline %1 wallet, or a PSBT-compatible hardware wallet. Text to inform a user attempting to create a transaction of their current options. At this stage, a user can send their transaction or create a PSBT. This string is displayed when both private keys and PSBT controls are enabled. - Proszę przejrzeć propozycję transakcji. Zostanie utworzona częściowo podpisana transakcja (ang. PSBT), którą można skopiować, a następnie podpisać np. offline z portfelem %1 lub z innym portfelem zgodnym z PSBT. + Proszę przejrzeć transakcję. Możesz utworzyć i wysłać tę transakcję lub utworzyć częściowo podpisaną transakcję Bitcoin (PSBT), którą możesz zapisać lub skopiować, a następnie podpisać np. offline z portfelem %1 lub z kompatybilnym sprzętowo portfelem PSBT. Please, review your transaction. @@ -3186,11 +3241,11 @@ Uwaga: Ponieważ opłata jest naliczana za każdy bajt, opłata "100 satoshi za Watch-only balance: - Kwota na obserwowanych kontach: + Saldo na kontach tylko do obserwacji: The recipient address is not valid. Please recheck. - Adres odbiorcy jest nieprawidłowy, proszę sprawić ponownie. + Adres odbiorcy jest nieprawidłowy, proszę sprawdzić ponownie. The amount to pay must be larger than 0. @@ -3219,9 +3274,9 @@ Uwaga: Ponieważ opłata jest naliczana za każdy bajt, opłata "100 satoshi za Estimated to begin confirmation within %n block(s). - Szacuje się, że potwierdzenie rozpocznie się w %n bloku. - Szacuje się, że potwierdzenie rozpocznie się w %n bloków. - Szacuje się, że potwierdzenie rozpocznie się w %n bloków. + Szacuje się, że potwierdzenie rozpocznie się w ciągu %n bloku. + Szacuje się, że potwierdzenie rozpocznie się w ciągu %n bloków. + Szacuje się, że potwierdzenie rozpocznie się w ciągu %n bloków. @@ -3253,7 +3308,7 @@ Uwaga: Ponieważ opłata jest naliczana za każdy bajt, opłata "100 satoshi za Pay &To: - Zapłać &dla: + Płatność &dla: &Label: @@ -3281,11 +3336,11 @@ Uwaga: Ponieważ opłata jest naliczana za każdy bajt, opłata "100 satoshi za The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally. - Opłata zostanie odjęta od kwoty wysyłane.Odbiorca otrzyma mniej niż bitcoins wpisz w polu kwoty. Jeśli wybrano kilku odbiorców, opłata jest podzielona równo. + Opłata zostanie odjęta od kwoty wysyłanej. Odbiorca otrzyma mniej bitcoinów, niż wpiszesz w polu kwoty. Jeśli wybrano wielu odbiorców, opłata zostanie podzielona równo. S&ubtract fee from amount - Odejmij od wysokości opłaty + Odejmij opłatę od kwoty Use available balance @@ -3495,7 +3550,7 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw %1/unconfirmed Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents a transaction confirmed in at least one block, but less than 6 blocks. - %1/niezatwierdzone + %1/niepotwierdzone %1 confirmations @@ -3532,7 +3587,7 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw watch-only - tylko-obserwowany + tylko do obserwacji label @@ -3706,7 +3761,7 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw watch-only - tylko-obserwowany + tylko do obserwacji (n/a) @@ -3730,7 +3785,7 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Whether or not a watch-only address is involved in this transaction. - Czy adres tylko-obserwowany jest lub nie użyty w tej transakcji. + Czy w transakcji jest użyty adres tylko do obserwacji. User-defined intent/purpose of the transaction. @@ -3805,11 +3860,11 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Copy &amount - Kopiuj kwotę + Skopiuj &kwotę Copy transaction &ID - transakcjaSkopiuj &ID transakcji + Skopiuj &ID transakcji Copy &raw transaction @@ -3833,7 +3888,7 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw &Edit address label - Wy&edytuj adres etykiety + Wy&edytuj etykietę adresu Show in %1 @@ -3846,11 +3901,11 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Confirmed - Potwerdzone + Potwierdzone Watch-only - Tylko-obserwowany + Tylko do obserwacji Date @@ -3924,7 +3979,7 @@ Przejdź do Plik > Otwórz Portfel aby wgrać portfel. PSBT file must be smaller than 100 MiB - PSBT musi być mniejsze niż 100MB + PSBT musi być mniejsze niż 100MiB Unable to decode PSBT @@ -4049,6 +4104,14 @@ Przejdź do Plik > Otwórz Portfel aby wgrać portfel. %s corrupt. Try using the wallet tool bitcoin-wallet to salvage or restoring a backup. %s jest uszkodzony. Spróbuj użyć narzędzia bitcoin-portfel, aby uratować portfel lub przywrócić kopię zapasową. + + %s failed to validate the -assumeutxo snapshot state. This indicates a hardware problem, or a bug in the software, or a bad software modification that allowed an invalid snapshot to be loaded. As a result of this, the node will shut down and stop using any state that was built on the snapshot, resetting the chain height from %d to %d. On the next restart, the node will resume syncing from %d without using any snapshot data. Please report this incident to %s, including how you obtained the snapshot. The invalid snapshot chainstate will be left on disk in case it is helpful in diagnosing the issue that caused this error. + %snie udało się zwalidować stanu migawki -assumeutxo. Wskazuje to na problem ze sprzętem, błąd w oprogramowaniu lub nieprawidłową modyfikacją programu, która zezwoliła na załadowanie nieprawidłowej migawki. Z tego powodu węzeł zostanie zamknięty i przestanie używać danych zbudowanych na bazie migawki, resetując wysokość łańcucha z %d do %d. Po ponownym uruchomieniu, węzeł wznowi synchronizację od %d, bez wykorzystania jakichkolwiek danych z migawki. Prosimy zgłosić ten incydent do %s, wliczając w to jak wszedłeś w posiadanie tej migawki. Nieprawidłowy stan łańcucha w oparciu o tą migawkę zostanie zachowany na dysku w przypadku, gdyby okazał się przydatny w diagnostyce problemu, który spowodował ten błąd. + + + %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 doc/p2p-bad-ports.md for details and a full list. + %sżąda nasłuchiwania na porcie %u. Ten port jest uznany za "zły" i nie jest zbyt prawdopodobne, aby jakikolwiek węzeł połączył się do niego. Zobacz doc/p2p-bad-ports.md, aby dowiedzieć się więcej i zobaczyć pełną listę. + Cannot downgrade wallet from version %i to version %i. Wallet version unchanged. Nie można zmienić wersji portfela z wersji %ina wersje %i. Wersja portfela pozostaje niezmieniona. @@ -4071,15 +4134,19 @@ Przejdź do Plik > Otwórz Portfel aby wgrać portfel. Error reading %s! Transaction data may be missing or incorrect. Rescanning wallet. - Błąd odczytu 1%s! Może brakować danych transakcji lub mogą być one nieprawidłowe. Ponowne skanowanie portfela. + Błąd odczytu %s! Może brakować danych transakcji lub mogą być one nieprawidłowe. Ponowne skanowanie portfela. + + + Error starting/committing db txn for wallet transactions removal process + Wystąpił błąd podczas uruchamiania/przesyłania bazy danych transakcji dla procesu usuwania transakcji w portfelu Error: Dumpfile format record is incorrect. Got "%s", expected "format". - Błąd: rekord formatu pliku zrzutu jest nieprawidłowy. Otrzymano „1%s”, oczekiwany „format”. + Błąd: rekord formatu pliku zrzutu jest nieprawidłowy. Otrzymano „%s”, oczekiwany „format”. Error: Dumpfile identifier record is incorrect. Got "%s", expected "%s". - Błąd: rekord identyfikatora pliku zrzutu jest nieprawidłowy. Otrzymano „1%s”, oczekiwano „1%s”. + Błąd: rekord identyfikatora pliku zrzutu jest nieprawidłowy. Otrzymano „%s”, oczekiwano „%s”. Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version %s @@ -4095,27 +4162,31 @@ Przejdź do Plik > Otwórz Portfel aby wgrać portfel. File %s already exists. If you are sure this is what you want, move it out of the way first. - Plik 1%s już istnieje. Jeśli jesteś pewien, że tego chcesz, najpierw usuń to z drogi. + Plik %s już istnieje. Jeśli jesteś pewien, że tego chcesz, najpierw go przenieś. Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start. - Nieprawidłowy lub uszkodzony plik peers.dat (1%s). Jeśli uważasz, że to błąd, zgłoś go do 1%s. Jako obejście, możesz przenieść plik (1%s) z drogi (zmień nazwę, przenieś lub usuń), aby przy następnym uruchomieniu utworzyć nowy. + Nieprawidłowy lub uszkodzony plik peers.dat (%s). Jeśli uważasz, że to błąd, zgłoś go do %s. Jako obejście, możesz przenieść plik (%s) z drogi (zmień nazwę, przenieś lub usuń), aby przy następnym uruchomieniu utworzyć nowy. Invalid value detected for '-wallet' or '-nowallet'. '-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets Nieprawidłowa wartość wykryta dla '-wallet' lub '-nowallet'. '-wallet' wymaga ciągu znaków, podczas gdy '-nowallet' akceptuje jedynie '1' dla wyłączenia wszystkich portfeli + + More than one onion bind address is provided. Using %s for the automatically created Tor onion service. + Podano więcej niż jeden adres onion. Używam %s dla automatycznie utworzonej usługi Tor onion. + No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided. - Nie dostarczono pliku zrzutu. Aby użyć funkcji createfromdump, należy podać -dumpfile=<filename>. + Nie podano pliku zrzutu. Aby użyć funkcji -createfromdump, należy podać -dumpfile=<filename> No dump file provided. To use dump, -dumpfile=<filename> must be provided. - Nie dostarczono pliku zrzutu. Aby użyć funkcji createfromdump, należy podać -dumpfile=1. + Nie podano pliku zrzutu. Aby go użyć, należy podać -dumpfile=<filename> No wallet file format provided. To use createfromdump, -format=<format> must be provided. - Nie dostarczono pliku zrzutu. Aby użyć funkcji createfromdump, należy podać -dumpfile=<format>. + Nie podano formatu pliku portfela. Aby użyć funkcji -createfromdump, należy podać -format=<format> Option '-upnp' is set but UPnP support was dropped in version 29.0. Consider using '-natpmp' instead. @@ -4187,7 +4258,7 @@ Przejdź do Plik > Otwórz Portfel aby wgrać portfel. Unsupported category-specific logging level %1$s=%2$s. Expected %1$s=<category>:<loglevel>. Valid categories: %3$s. Valid loglevels: %4$s. - Nieobsługiwany poziom rejestrowania specyficzny dla kategorii %1$s=%2$s. Oczekiwano %1$s=<category>:<loglevel>. Poprawne kategorie %3$s. Poprawne poziomy logowania: %4 $s. + Nieobsługiwany poziom logowania specyficzny dla kategorii %1$s=%2$s. Oczekiwano %1$s=<category>:<loglevel>. Poprawne kategorie %3$s. Poprawne poziomy logowania: %4 $s. Unsupported chainstate database format found. Please restart with -reindex-chainstate. This will rebuild the chainstate database. @@ -4229,6 +4300,10 @@ Przejdź do Plik > Otwórz Portfel aby wgrać portfel. -maxmempool must be at least %d MB -maxmempool musi być przynajmniej %d MB + + Cannot obtain a lock on directory %s. %s is probably already running. + Nie można uzyskać blokady w katalogu %s. %s najprawdopodobniej jest już uruchomiony. + Cannot resolve -%s address: '%s' Nie można rozpoznać -%s adresu: '%s' @@ -4253,9 +4328,13 @@ Przejdź do Plik > Otwórz Portfel aby wgrać portfel. Error loading %s: External signer wallet being loaded without external signer support compiled Błąd ładowania %s: Ładowanie portfela zewnętrznego podpisu bez skompilowania wsparcia dla zewnętrznego podpisu. + + Error reading %s! All keys read correctly, but transaction data or address metadata may be missing or incorrect. + Błąd podczas odczytywania %s! Wszystkie klucze zostały odczytane poprawnie, ale może brakować danych transakcji lub wpisów w książce adresowej, albo mogą one być nieprawidłowe. + Error: Address book data in wallet cannot be identified to belong to migrated wallets - Błąd: Dane książki adresowej w portfelu nie można zidentyfikować jako należące do migrowanego portfela + Błąd: Danych książki adresowej w portfelu nie można zidentyfikować jako należących do zmigrowanych portfeli Error: Duplicate descriptors created during migration. Your wallet may be corrupted. @@ -4275,7 +4354,7 @@ Przejdź do Plik > Otwórz Portfel aby wgrać portfel. Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable %s. - Estymacja opłat nieudana. Domyślna opłata jest wyłączona. Poczekaj kilka bloków lub włącz -%s. + Estymacja opłat nie powiodła się. Fallbackfee jest wyłączone. Poczekaj kilka bloków lub włącz %s. Flushing block file to disk failed. This is likely the result of an I/O error. @@ -4313,13 +4392,37 @@ Przejdź do Plik > Otwórz Portfel aby wgrać portfel. Outbound connections restricted to i2p (-onlynet=i2p) but -i2psam is not provided Połączenia wychodzące ograniczone do i2p (-onlynet=i2p), lecz nie podano -i2psam + + Rename of '%s' -> '%s' failed. Cannot clean up the background chainstate leveldb directory. + Zmiana nazwy z '%s' na '%s' nie powiodła się. Nie można wyczyścić katalogu chainstate leveldb. + + + Specified -blockmaxweight (%d) exceeds consensus maximum block weight (%d) + Podany -blockmaxweight (%d) przekracza przekracza maksymalną wagę bloku dopuszczoną przez konsensus (%d) + + + Specified -blockreservedweight (%d) exceeds consensus maximum block weight (%d) + Podany -blockreservedweight (%d) przekracza przekracza maksymalną wagę bloku dopuszczoną przez konsensus (%d) + + + Specified -blockreservedweight (%d) is lower than minimum safety value of (%d) + Podany -blockreservedweight (%d) jest niższy niż minimalna bezpieczna wartrość (%d) + The preselected coins total amount does not cover the transaction target. Please allow other inputs to be automatically selected or include more coins manually Suma wstępnie wybranych monet nie pokrywa kwoty transakcji. Zezwól na automatyczne wybranie wejść lub ręcznie dołącz więcej monet Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input - Transakcja wymagana jednego celu o niezerowej wartości, niezerowej opłacie lub wstępnie wybranego wejścia + Transakcja wymaga jednego adresu docelowego z niezerową wartością, niezerowej stawki opłaty lub wcześniej wybranego wejścia. + + + Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool + Niepotwierdzone UTXO są dostępne, ale ich wydanie tworzy łańcuch transakcji, który zostanie odrzucony przez mempool. + + + Your computer's date and time appear to be more than %d minutes out of sync with the network, this may lead to consensus failure. After you've confirmed your computer's clock, this message should no longer appear when you restart your node. Without a restart, it should stop showing automatically after you've connected to a sufficient number of new outbound peers, which may take some time. You can inspect the `timeoffset` field of the `getpeerinfo` and `getnetworkinfo` RPC methods to get more info. + Data i godzina Twojego komputera wydają się być przesunięte o więcej %d minut względem sieci, co może prowadzić do błędów konsensusu. Po upewnieniu się, że zegar Twojego komputera jest poprawny, ta wiadomość nie powinna się już pojawiać po ponownym uruchomieniu Twojego węzła. Bez ponownego uruchamiania komunikat powinien zniknąć automatycznie po nawiązaniu przez węzeł wystarczającej liczby nowych połączeń wychodzących, co może zająć trochę czasu. Możesz sprawdzić pole timeoffset w metodach RPC getpeerinfo oraz getnetworkinfo, aby uzyskać więcej informacji. @@ -4455,7 +4558,7 @@ Nie można przywrócić kopii zapasowej portfela Error: Dumpfile checksum does not match. Computed %s, expected %s - Błąd: Plik zrzutu suma kontrolna nie pasuje. Obliczone %s, spodziewane %s + Błąd: Suma kontrolna pliku zrzutu nie zgadza się. Obliczona %s, oczekiwana %s Error: Failed to create new watchonly wallet @@ -4475,11 +4578,11 @@ Nie można przywrócić kopii zapasowej portfela Error: Missing checksum - Bład: Brak suma kontroly + Błąd: Brakuje sumy kontrolnej Error: No %s addresses available. - Błąd: %s adres nie dostępny + Błąd: Brak dostępnych adresów %s Error: This wallet already uses SQLite @@ -4521,6 +4624,10 @@ Nie można przywrócić kopii zapasowej portfela Error: Unable to write record to new wallet Błąd: Wpisanie rekordu do nowego portfela jest niemożliwe + + Error: Unable to write watchonly wallet best block locator record + Błąd: nie można zapisać rekordu lokalizatora najlepszego bloku portfela tylko do obserwacji + Error: database transaction cannot be executed for wallet %s Błąd: transakcja bazy danych nie może zostać wykonana dla portfela%s @@ -4639,7 +4746,7 @@ Nie można przywrócić kopii zapasowej portfela Invalid port specified in %s: '%s' - Nieprawidłowa maska sieci określona w %s: '%s' + Nieprawidłowy port podany w %s: '%s' Invalid pre-selected input %s @@ -4805,6 +4912,10 @@ Nie można przywrócić kopii zapasowej portfela The transaction amount is too small to pay the fee Zbyt niska kwota transakcji by zapłacić opłatę + + The transactions removal process can only be executed within a db txn + Proces usuwania transakcji może być wykonany tylko w ramach transakcji bazy danych. + The wallet will avoid paying less than the minimum relay fee. Portfel będzie unikał płacenia mniejszej niż przekazana opłaty. @@ -4931,7 +5042,7 @@ Nie można przywrócić kopii zapasowej portfela Unsupported logging category %s=%s. - Nieobsługiwana kategoria rejestrowania %s=%s. + Nieobsługiwana kategoria logowania %s=%s. Do you want to rebuild the databases now? @@ -4963,11 +5074,11 @@ Nie można przywrócić kopii zapasowej portfela Verifying blocks… - Weryfikowanie bloków... + Sprawdzanie bloków… Verifying wallet(s)… - Weryfikowanie porfela(li)... + Sprawdzanie portfela / portfeli… Wallet needed to be rewritten: restart %s to complete diff --git a/src/qt/locale/bitcoin_ro.ts b/src/qt/locale/bitcoin_ro.ts index 477680c81a1..3e7f2feefaf 100644 --- a/src/qt/locale/bitcoin_ro.ts +++ b/src/qt/locale/bitcoin_ro.ts @@ -184,6 +184,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Continue Continua + + Back + Înapoi + Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. Reţineti: criptarea portofelului dvs. nu vă poate proteja în totalitate bitcoin-urile împotriva furtului de malware care vă infectează computerul. @@ -291,6 +295,18 @@ Semnarea este posibilă numai cu adrese de tip "legacy". unknown necunoscut + + Embedded "%1" + „%1” încorporat + + + Default system font "%1" + Font de sistem implicit „%1” + + + Custom… + Personalizat... + Amount Sumă @@ -299,6 +315,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Enter a Bitcoin address (e.g. %1) Introduceţi o adresă Bitcoin (de exemplu %1) + + Unroutable + Nu poate fi rutabil + Inbound An inbound connection from a peer. An inbound connection is a connection initiated by a peer. @@ -761,6 +781,20 @@ Semnarea este posibilă numai cu adrese de tip "legacy". A substring of the tooltip. "More actions" are available via the context menu. Pulsează pentru mai multe acțiuni. + + Disable network activity + A context menu item. + Dezactivați activitatea în rețea + + + Enable network activity + A context menu item. The network activity was disabled previously. + Activați activitatea în rețea + + + Pre-syncing Headers (%1%)… + Se pre-sincronizează antetele (%1%)... + Error creating wallet Eroare creare portofel @@ -1469,6 +1503,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu. Minimizează fereastra în locul părăsirii programului în momentul închiderii ferestrei. Cînd acestă opţiune e activă, aplicaţia se va opri doar în momentul selectării comenzii 'Închide aplicaţia' din menu. + + Font in the Overview tab: + Font în fila Prezentare generală: + Open the %1 configuration file from the working directory. Deschide fisierul de configurare %1 din directorul curent. @@ -1757,10 +1795,22 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Failed to sign transaction: %1 Nu s-a reusit semnarea tranzactiei: %1 + + Could not sign any more inputs. + Nu s-au mai putut semna alte intrări. + + + Unknown error processing transaction. + Eroare necunoscută la procesarea tranzacției. + Save Transaction Data Salvați datele tranzacției + + Sends %1 to %2 + Trimite %1 la %2 + own address adresa proprie @@ -1781,6 +1831,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". or sau + + Transaction has %1 unsigned inputs. + Tranzacția are %1 intrări nesemnate. + Transaction status is unknown. Starea tranzacției este necunoscută. @@ -2012,6 +2066,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Node window Fereastra nodului + + Current block height + Înălțimea actuală a blocului + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. Deschide fişierul jurnal depanare %1 din directorul curent. Aceasta poate dura cateva secunde pentru fişierele mai mari. @@ -2040,6 +2098,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Connection Time Timp conexiune + + Last Block + Ultimul bloc + Last Send Ultima trimitere @@ -2141,6 +2203,11 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Executing command using "%1" wallet Executarea comenzii folosind portofelul "%1" + + Executing… + A console message indicating an entered command is currently being executed. + Se execută… + Yes Da @@ -2240,6 +2307,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Copy &label Copiaza si eticheteaza + + Copy &message + Copie și mesaj + Copy &amount copiaza &valoarea @@ -2251,6 +2322,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". ReceiveRequestDialog + + Request payment to … + Solicitați plata către... + Address: Adresa: @@ -2259,6 +2334,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Amount: Sumă: + + Label: + Eticheta: + Message: Mesaj: @@ -2413,6 +2492,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". Clear all fields of the form. Şterge toate câmpurile formularului. + + Inputs… + Intrări… + Choose… Alege... @@ -2493,6 +2576,11 @@ Semnarea este posibilă numai cu adrese de tip "legacy". You can increase the fee later (signals Replace-By-Fee, BIP-125). Puteti creste taxa mai tarziu (semnaleaza Replace-By-Fee, BIP-125). + + Do you want to create this transaction? + Message displayed when attempting to create a transaction. Cautionary text to prompt the user to verify that the displayed transaction details represent the transaction the user intends to create. + Doriți să creați această tranzacție? + Please, review your transaction. Text to prompt a user to review the details of the transaction they are attempting to send. @@ -2695,6 +2783,10 @@ Semnarea este posibilă numai cu adrese de tip "legacy". The Bitcoin address the message was signed with Introduceţi o adresă Bitcoin + + The signed message to verify + Mesajul semnat de verificat + Verify the message to ensure it was signed with the specified Bitcoin address Verificaţi mesajul pentru a vă asigura că a fost semnat cu adresa Bitcoin specificată diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 7ce4367d1ab..cc8c1b4e33b 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -5,6 +5,10 @@ Right-click to edit address or label Нажмите правой кнопкой мыши, чтобы изменить адрес или метку + + Create a new address + Создать новые адрес + &New &Новый @@ -93,6 +97,10 @@ Signing is only possible with addresses of the type 'legacy'. Sending addresses - %1 Адреса отправки - %1 + + Receiving addresses - %1 + Адреса получения - %1 + Exporting Failed Ошибка при экспорте diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index 2fa339132fa..48f1c11a55a 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -271,7 +271,7 @@ Signing is only possible with addresses of the type 'legacy'. A fatal error occurred. %1 can no longer continue safely and will quit. - Дошло је до фаталне грешке. 1%1 даље не може безбедно да настави, те ће се угасити. + Дошло је до фаталне грешке. %1 даље не може безбедно да настави, те ће се угасити. Internal error @@ -300,7 +300,7 @@ Signing is only possible with addresses of the type 'legacy'. %1 didn't yet exit safely… - 1%1 још увек није изашао безбедно… + %1 још увек није изашао безбедно… unknown diff --git a/src/qt/locale/bitcoin_sr@ijekavianlatin.ts b/src/qt/locale/bitcoin_sr@ijekavianlatin.ts index 38214ae8458..ce53ad65dc7 100644 --- a/src/qt/locale/bitcoin_sr@ijekavianlatin.ts +++ b/src/qt/locale/bitcoin_sr@ijekavianlatin.ts @@ -267,7 +267,7 @@ Signing is only possible with addresses of the type 'legacy'. A fatal error occurred. %1 can no longer continue safely and will quit. - Дошло је до фаталне грешке. 1%1 даље не може безбедно да настави, те ће се угасити. + Дошло је до фаталне грешке. %1 даље не може безбедно да настави, те ће се угасити. Internal error @@ -296,7 +296,7 @@ Signing is only possible with addresses of the type 'legacy'. %1 didn't yet exit safely… - 1%1 још увек није изашао безбедно… + %1 још увек није изашао безбедно… unknown diff --git a/src/qt/locale/bitcoin_sr@latin.ts b/src/qt/locale/bitcoin_sr@latin.ts index dd1df971e92..cf745a30290 100644 --- a/src/qt/locale/bitcoin_sr@latin.ts +++ b/src/qt/locale/bitcoin_sr@latin.ts @@ -267,7 +267,7 @@ Signing is only possible with addresses of the type 'legacy'. A fatal error occurred. %1 can no longer continue safely and will quit. - Дошло је до фаталне грешке. 1%1 даље не може безбедно да настави, те ће се угасити. + Дошло је до фаталне грешке. %1 даље не може безбедно да настави, те ће се угасити. Internal error @@ -296,7 +296,7 @@ Signing is only possible with addresses of the type 'legacy'. %1 didn't yet exit safely… - 1%1 још увек није изашао безбедно… + %1 још увек није изашао безбедно… unknown diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 49aa64f1aa8..cbc1daa5241 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -25,6 +25,10 @@ C&lose S&täng + + Delete the currently selected address from the list + Radera den markerade adressen från listan + Enter address or label to search Ange en adress eller etikett att söka efter @@ -45,6 +49,10 @@ Choose the address to send coins to Välj en adress att skicka transaktionen till + + Choose the address to receive coins with + Välj en adress att ` emot transaktionen med + C&hoose V&älj @@ -293,6 +301,10 @@ Försök igen. unknown okänd + + Embedded "%1" + Inbäddad "%1" + Custom… Anpassad... @@ -2119,6 +2131,10 @@ Om den här plånboken innehåller lösbara Number of connections Antalet anslutningar + + Local Addresses + Lokala adresser + Block chain Blockkedja @@ -3184,6 +3200,10 @@ Om den här plånboken innehåller lösbara Output index Utmatningsindex + + %1 (Certificate was not verified) + %1 (certifikatet verifierades inte) + Merchant Handlare @@ -3684,6 +3704,14 @@ Gå till Fil > Öppna plånbok för att läsa in en plånbok. Cannot set -peerblockfilters without -blockfilterindex. Kan inte använda -peerblockfilters utan -blockfilterindex. + + Maximum transaction weight is less than transaction weight without inputs + Maximal transaktionsvikt är mindre än transaktionsvikten utan inmatningar + + + Maximum transaction weight is too low, can not accommodate change output + Maximal transaktionsvikt är för låg, kan inte tillgodose ändrad utdata + Config setting for %s only applied on %s network when in [%s] section. Konfigurationsinställningar för %s tillämpas bara på nätverket %s när de är i avsnitt [%s]. diff --git a/src/qt/locale/bitcoin_ta.ts b/src/qt/locale/bitcoin_ta.ts index 6fd6c5214a6..f7b40d39357 100644 --- a/src/qt/locale/bitcoin_ta.ts +++ b/src/qt/locale/bitcoin_ta.ts @@ -93,6 +93,10 @@ Signing is only possible with addresses of the type 'legacy'. An error message. %1 is a stand-in argument for the name of the file we attempted to save to. முகவரி பட்டியலை %1 க்கு சேமிக்க முயற்சிக்கும் ஒரு பிழை ஏற்பட்டது. தயவுசெய்து மீண்டும் முயற்சிக்கவும். + + Receiving addresses - %1 + வரவேற்கும் முகவரிகள் - %1 + Exporting Failed ஏக்ஸ்போர்ட் தோல்வியடைந்தது @@ -175,6 +179,14 @@ Signing is only possible with addresses of the type 'legacy'. Enter the old passphrase and new passphrase for the wallet. பழைய கடவுச்சொல் மற்றும் புதிய கடுவுசொல்லை உள்ளிடுக. + + Continue + தொடரவும் + + + Back + பின் செல் + Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. வாலட்டை குறியாக்கம் செய்தால் மட்டும் உங்கள் பிட்காயினை வைரஸிடம் இருந்து பாதுகாக்க இயலாது. @@ -219,6 +231,10 @@ Signing is only possible with addresses of the type 'legacy'. Wallet passphrase was successfully changed. Wallet குறியாக்கம் தோல்வியடைந்தது + + Passphrase change failed + கடவுச்சொல் மாற்றம் தோல்வியடைந்தது + Warning: The Caps Lock key is on! எச்சரிக்கை: Caps Lock விசை இயக்கத்தில் உள்ளது! @@ -247,7 +263,7 @@ Signing is only possible with addresses of the type 'legacy'. An internal error occurred. %1 will attempt to continue safely. This is an unexpected bug which can be reported as described below. - உள் பிழை ஏற்பட்டது. 1%1 தொடர முயற்சிக்கும். இது எதிர்பாராத பிழை, கீழே விவரிக்கப்பட்டுள்ளபடி புகாரளிக்கலாம். + உள் பிழை ஏற்பட்டது. %1 தொடர முயற்சிக்கும். இது எதிர்பாராத பிழை, கீழே விவரிக்கப்பட்டுள்ளபடி புகாரளிக்கலாம். @@ -446,6 +462,10 @@ Signing is only possible with addresses of the type 'legacy'. &Backup Wallet… &பேக்கப் வாலட்... + + &Change Passphrase… + &கடவுச்சொல்லை மாற்றுக… + Sign messages with your Bitcoin addresses to prove you own them உங்கள் பிட்டினின் முகவரியுடன் செய்திகளை உங்களிடம் வைத்திருப்பதை நிரூபிக்க @@ -582,6 +602,11 @@ Signing is only possible with addresses of the type 'legacy'. No wallets available வாலட் எதுவும் இல்லை + + Restore Wallet + Title of pop-up window shown when the user is attempting to restore a wallet. + பணப்பையை மீட்டெடுக்க + Wallet Name Label of the input field where the name of the wallet is entered. @@ -603,6 +628,10 @@ Signing is only possible with addresses of the type 'legacy'. %1 client %1 கிளையன் + + S&how + காண்பி + %n active connection(s) to Bitcoin network. A substring of the tooltip. @@ -611,6 +640,15 @@ Signing is only possible with addresses of the type 'legacy'. + + Enable network activity + A context menu item. The network activity was disabled previously. + இணைய செயல்பாட்டை இயக்கு + + + Error creating wallet + பணப்பை உருவாக்க பிழை ஏற்பட்டது + Error: %1 பிழை: %1 @@ -838,6 +876,14 @@ Signing is only possible with addresses of the type 'legacy'. வாலட்டை திற + + RestoreWalletActivity + + Restore Wallet + Title of progress window which is displayed when wallets are being restored. + பணப்பையை மீட்டெடுக்க + + WalletController @@ -899,6 +945,10 @@ Signing is only possible with addresses of the type 'legacy'. Make Blank Wallet காலியான வாலட்டை உருவாக்கு + + Use an external signing device such as a hardware wallet. Configure the external signer script in wallet preferences first. + ஹார்ட்வேர் பணப்பை போன்ற வெளிப்புற கையொப்ப சாதனத்தை பயன்படுத்துங்கள். முதலில் பணப்பை விருப்பங்களில் வெளிப்புற கையொப்ப ஸ்கிரிப்டை உள்ளமைக்கவும். + Create உருவாக்கு @@ -1103,6 +1153,10 @@ Signing is only possible with addresses of the type 'legacy'. Number of blocks left மீதமுள்ள தொகுதிகள் உள்ளன + + calculating… + கணக்கிடுகிறது... + Last block time கடைசி தடுப்பு நேரம் @@ -1343,6 +1397,10 @@ Signing is only possible with addresses of the type 'legacy'. Explanatory text about the priority order of instructions considered by client. The order from high to low being: command-line, configuration file, GUI settings. GUI அமைப்புகளை மேலெழுதக்கூடிய மேம்பட்ட பயனர் விருப்பங்களைக் குறிப்பிட கட்டமைப்பு கோப்பு பயன்படுத்தப்படுகிறது. கூடுதலாக, எந்த கட்டளை வரி விருப்பங்கள் இந்த கட்டமைப்பு கோப்பு புறக்கணிக்க வேண்டும். + + Continue + தொடரவும் + Cancel ரத்து @@ -1691,6 +1749,10 @@ Signing is only possible with addresses of the type 'legacy'. Connection Time இணைப்பு நேரம் + + Last Block + கடைசி தொகுதி + Last Send கடைசி அனுப்பவும் @@ -1811,6 +1873,10 @@ Signing is only possible with addresses of the type 'legacy'. Ban for தடை செய் + + Never + ஒருபோதும் இல்லை + Unknown அறியப்படாத @@ -2900,6 +2966,10 @@ Signing is only possible with addresses of the type 'legacy'. Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate. பிளாக்களை இயக்க முடியவில்லை. -reindex-chainstate ஐப் பயன்படுத்தி டேட்டாபேசை மீண்டும் உருவாக்க வேண்டும். + + Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future. + பணப்பை வெற்றிகரமாக உருவாக்கப்பட்டது. பாரம்பரிய பணப்பை வகை படிப்படியாக கைவிடப்படுகிறது, மேலும் எதிர்காலத்தில் அதை உருவாக்கவும் திறக்கவும் ஆதரவு நீக்கப்படும். + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. எச்சரிக்கை: நாங்கள் எங்கள் பீர்களுடன் முழுமையாக உடன்படுவதாகத் தெரியவில்லை! நீங்கள் அப்க்ரேட் செய்ய வேண்டியிருக்கலாம், அல்லது மற்ற நோடுகள் அப்க்ரேட் செய்ய வேண்டியிருக்கலாம். diff --git a/src/qt/locale/bitcoin_th.ts b/src/qt/locale/bitcoin_th.ts index 464e39cbac0..1cae9d0af96 100644 --- a/src/qt/locale/bitcoin_th.ts +++ b/src/qt/locale/bitcoin_th.ts @@ -1,315 +1,2500 @@ + + AddressBookPage + + Right-click to edit address or label + คลิกขวาเพื่อแก้ไขที่อยู่หรือตัวระบุ + + + Create a new address + สร้างที่อยู่ใหม่ + + + &New + &ใหม่ + + + Copy the currently selected address to the system clipboard + คัดลอกที่อยู่ที่เลือกปัจจุบันไปยังคลิปบอร์ดของระบบ + + + &Copy + &คัดลอก + + + C&lose + &ปิด + + + Delete the currently selected address from the list + ลบที่อยู่ที่เลือกไว้ในปัจจุบันออกจากรายการ + + + Enter address or label to search + ป้อนที่อยู่หรือป้ายกำกับเพื่อค้นหา + + + Export the data in the current tab to a file + ส่งออกข้อมูลในแท็บปัจจุบันไปยังไฟล์ + + + &Export + &ส่งออก + + + &Delete + &ลบ + + + Choose the address to send coins to + เลือกที่อยู่เพื่อส่งเหรียญไป + + + Choose the address to receive coins with + เลือกที่อยู่เพื่อรับเหรียญ + + + C&hoose + เลือก + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + นี่คือลิงก์ที่อยู่ Bitcoin ของคุณสำหรับการส่งการชำระเงิน ควรตรวจสอบจำนวนเงินและที่อยู่ผู้รับก่อนการส่งเหรียญ + + + These are your Bitcoin addresses for receiving payments. Use the 'Create new receiving address' button in the receive tab to create new addresses. +Signing is only possible with addresses of the type 'legacy'. + นี่คือที่อยู่บิตคอยน์ของคุณสำหรับรับการชำระเงิน ใช้ปุ่ม 'สร้างที่อยู่รับใหม่' ในแท็บรับเพื่อสร้างที่อยู่ใหม่ การลงนามทำได้เฉพาะกับที่อยู่ประเภท 'legacy' + + + &Copy Address + ที่อยู่ + + + Copy &Label + คัดลอกและติดป้ายกำกับ + + + &Edit + &แก้ไข + + + Export Address List + รายชื่อที่อยู่ที่ส่งออก + + + Comma separated file + Expanded name of the CSV file format. See: https://en.wikipedia.org/wiki/Comma-separated_values. + ไฟล์ที่แยกด้วยเครื่องหมายจุลภาค + + + There was an error trying to save the address list to %1. Please try again. + An error message. %1 is a stand-in argument for the name of the file we attempted to save to. + เกิดข้อผิดพลาดในการพยายามบันทึกรายชื่อที่อยู่ไปยัง %1 กรุณาลองอีกครั้ง + + + Sending addresses - %1 + กำลังส่งที่อยู่ - %1 + + + Receiving addresses - %1 + กำลังรับที่อยู่ - %1 + + + Exporting Failed + การส่งออกล้มเหลว + + + + AddressTableModel + + Label + การส่งออกล้มเหลว + + + Address + ที่อยู่ + + + (no label) + ไม่มีป้ายกำกับ + + AskPassphraseDialog - Back - ย้อนกลับ + Passphrase Dialog + กล่องโต้ตอบรหัสผ่าน + + + Enter passphrase + ป้อนรหัสผ่านลับ + + + New passphrase + รหัสผ่านใหม่ + + + Repeat new passphrase + กรุณาใส่วลีผ่านใหม่อีกครั้ง + + + Show passphrase + แสดงรหัสผ่าน + + + Encrypt wallet + เข้ารหัสกระเป๋าเงิน + + + This operation needs your wallet passphrase to unlock the wallet. + การดำเนินการนี้ต้องใช้รหัสผ่านกระเป๋าเงินของคุณเพื่อปลดล็อกกระเป๋าเงิน + + + Unlock wallet + ปลดล็อกกระเป๋าเงิน + + + Change passphrase + เปลี่ยนรหัสผ่าน + + + Confirm wallet encryption + ยืนยันการเข้ารหัสกระเป๋าเงิน + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + คำเตือน: หากคุณเข้ารหัสกระเป๋าของคุณและสูญเสียรหัสผ่านของคุณ คุณจะสูญเสียบิตคอยน์ทั้งหมดของคุณ! + + + Are you sure you wish to encrypt your wallet? + คุณแน่ใจหรือว่าคุณต้องการเข้ารหัสกระเป๋าของคุณ? + + + Wallet encrypted + กระเป๋าเงินถูกเข้ารหัส + + + Enter the new passphrase for the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + ป้อนวลีรหัสใหม่สำหรับกระเป๋าสตางค์. 1.กรุณาใช้วลีรหัสผ่านของ 2.สิบตัวอักษรสุ่มหรือมากกว่า 2,หรือ 3แปดคำหรือมากกว่านั้น3 + + + Enter the old passphrase and new passphrase for the wallet. + ป้อนรหัสผ่านเก่าและรหัสผ่านใหม่สำหรับกระเป๋าเงิน + + + Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + จำไว้ว่าการเข้ารหัสกระเป๋าของคุณไม่สามารถปกป้องบิตคอยน์ของคุณจากการถูกขโมยโดยมัลแวร์ที่ติดเชื้อคอมพิวเตอร์ของคุณได้อย่างสมบูรณ์ + + + Wallet to be encrypted + กระเป๋าเงินจะถูกเข้ารหัส + + + Your wallet is about to be encrypted. + กระเป๋าเงินของคุณกำลังจะถูกเข้ารหัส + + + Your wallet is now encrypted. + กระเป๋าเงินของคุณได้รับการเข้ารหัสแล้ว + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + สำคัญ: สำรองข้อมูลที่คุณได้ทำไว้ก่อนหน้านี้ของไฟล์กระเป๋าเงินของคุณควรถูกแทนที่ด้วยไฟล์กระเป๋าเงินที่ถูกเข้ารหัสที่สร้างขึ้นใหม่ สำหรับเหตุผลด้านความปลอดภัย สำรองข้อมูลก่อนหน้านี้ของไฟล์กระเป๋าเงินที่ไม่ได้เข้ารหัสจะไม่สามารถใช้ได้ทันทีที่คุณเริ่มใช้ไฟล์กระเป๋าเงินที่เข้ารหัสใหม่ + + + Wallet encryption failed + การเข้ารหัสกระเป๋าเงินล้มเหลว + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + การเข้ารหัสกระเป๋าเงินล้มเหลวเนื่องจากข้อผิดพลาดภายใน กระเป๋าเงินของคุณไม่ได้ถูกเข้ารหัส + + + The supplied passphrases do not match. + รหัสผ่านที่ให้มาทั้งหมดไม่ตรงกัน + + + Wallet unlock failed + การปลดล็อกกระเป๋าเงินล้มเหลว + + + The passphrase entered for the wallet decryption was incorrect. + วลีรหัสที่ป้อนสำหรับถอดรหัสกระเป๋าเงินไม่ถูกต้อง + + + The passphrase entered for the wallet decryption is incorrect. It contains a null character (ie - a zero byte). If the passphrase was set with a version of this software prior to 25.0, please try again with only the characters up to — but not including — the first null character. If this is successful, please set a new passphrase to avoid this issue in the future. + วลีผ่านที่ป้อนเพื่อถอดรหัสกระเป๋าสตางค์ไม่ถูกต้อง เนื่องจากมีอักขระว่าง (เช่น ไบต์ศูนย์) หากวลีผ่านถูกตั้งค่าด้วยซอฟต์แวร์เวอร์ชันก่อนหน้า 25.0 กรุณาลองอีกครั้งโดยป้อนเฉพาะอักขระก่อนหน้าอักขระว่างตัวแรกเท่านั้น หากสำเร็จ กรุณาตั้งวลีผ่านใหม่เพื่อหลีกเลี่ยงปัญหานี้ในอนาคต + + + Wallet passphrase was successfully changed. + รหัสผ่านกระเป๋าเงินถูกเปลี่ยนสำเร็จเรียบร้อยแล้ว. + + + Passphrase change failed + การเปลี่ยนรหัสผ่านล้มเหลว + + + The old passphrase entered for the wallet decryption is incorrect. It contains a null character (ie - a zero byte). If the passphrase was set with a version of this software prior to 25.0, please try again with only the characters up to — but not including — the first null character. + รหัสผ่านเก่าที่ป้อนเพื่อถอดรหัสกระเป๋าไม่ถูกต้อง มันมีอักขระว่าง (เช่น - ไบต์ศูนย์) หากรหัสผ่านถูกตั้งด้วยเวอร์ชันของซอฟต์แวร์ก่อนเวอร์ชัน 25.0 กรุณาลองใหม่โดยใช้เฉพาะอักขระจนถึง — แต่ไม่รวม — อักขระว่างตัวแรก. + + + Warning: The Caps Lock key is on! + คำเตือน: ปุ่ม Caps Lock เปิดอยู่! + + + + BanTableModel + + IP/Netmask + ไอพี/หน้ากากเครือข่าย + + + Banned Until + ถูกแบนจนถึง + + + + BitcoinApplication + + Settings file %1 might be corrupt or invalid. + ไฟล์การตั้งค่า %1 อาจเสียหายหรือไม่ถูกต้อง + + + Runaway exception + ข้อยกเว้นที่ควบคุมไม่ได้ + + + A fatal error occurred. %1 can no longer continue safely and will quit. + เกิดข้อผิดพลาดร้ายแรง %1 ไม่สามารถดำเนินการต่อได้อย่างปลอดภัยและจะปิดตัวลง + + + Internal error + ข้อผิดพลาดภายใน + + + An internal error occurred. %1 will attempt to continue safely. This is an unexpected bug which can be reported as described below. + เกิดข้อผิดพลาดภายใน %1 จะพยายามดำเนินการต่ออย่างปลอดภัย นี่คือข้อผิดพลาดที่ไม่คาดคิดซึ่งสามารถรายงานได้ตามที่อธิบายไว้ด้านล่าง + + + + QObject + + Do you want to reset settings to default values, or to abort without making changes? + Explanatory text shown on startup when the settings file cannot be read. Prompts user to make a choice between resetting or aborting. + คุณต้องการรีเซ็ตการตั้งค่าเป็นค่าพื้นฐาน หรือยกเลิกโดยไม่ทำการเปลี่ยนแปลง? + + + A fatal error occurred. Check that settings file is writable, or try running with -nosettings. + Explanatory text shown on startup when the settings file could not be written. Prompts user to check that we have the ability to write to the file. Explains that the user has the option of running without a settings file. + เกิดข้อผิดพลาดร้ายแรง กรุณาตรวจสอบว่าไฟล์การตั้งค่าสามารถเขียนได้หรือไม่ หรือลองรันด้วยคำสั่ง + + + Error: %1 + ข้อผิดพลาด: %1 + + + %1 didn't yet exit safely… + %1 ยังไม่ได้ออกอย่างปลอดภัย… + + + Embedded "%1" + ฝัง "%1" + + + Default system font "%1" + ฟอนต์ระบบเริ่มต้น "%1" + + + Custom… + กำหนดเอง + + + Amount + จำนวน: + + + Enter a Bitcoin address (e.g. %1) + กรอกที่อยู่ Bitcoin (เช่น %1) + + + Unroutable + ไม่สามารถกำหนดเส้นทางได้ (Mai Samart Kamnot Sen Thang Dai) + + + IPv4 + network name + Name of IPv4 network in peer info + ไอพีวี4 + + + IPv6 + network name + Name of IPv6 network in peer info + ไอพีวี6 + + + Onion + network name + Name of Tor network in peer info + หัวหอม (Hua Khom) + + + CJDNS + network name + Name of CJDNS network in peer info + CJDNS (แปลงชื่อย่อ) + + + Inbound + An inbound connection from a peer. An inbound connection is a connection initiated by a peer. + ขาเข้า +(Pronunciation: kǎa-kâo) + + + Outbound + An outbound connection to a peer. An outbound connection is a connection initiated by us. + ออกเดินทาง (òk dern thāng) + + + Full Relay + Peer connection type that relays all network information. + การแข่งขันรีเลย์เต็มรูปแบบ + + + Block Relay + Peer connection type that relays network information about blocks and not transactions or addresses. + การวิ่งผลัดบล็อก + + + Manual + Peer connection type established manually through one of several methods. + คู่มือ + + + Feeler + Short-lived peer connection type that tests the aliveness of known addresses. + ตัวตรวจจับ (tua dtruat jap) + + + Address Fetch + Short-lived peer connection type that solicits known addresses from a peer. + ดึงที่อยู่ + + + %1 d + %1 วัน + + + %1 h + %1 ชม. + + + %1 m + %1 เมตร + + + %1 s + %1 วินาที + + + None + ไม่มี (Mai mee) + + + N/A + ไม่มี + + + %1 ms + %1 มิลลิวินาที + + + %n second(s) + + %n วินาที + + + + %n minute(s) + + %n นาที + + + + %n hour(s) + + %n ชั่วโมง + + + + %n day(s) + + %n วัน + + + + %n week(s) + + %n สัปดาห์ + + + + %1 and %2 + %1 และ %2 + + + %n year(s) + + %n ปี + + + + %1 B + %1 บ + + + %1 kB + %1 กิโลไบต์ + + + %1 MB + %1 เมกะไบต์ + + + %1 GB + %1 กิกะไบต์ + + + default wallet + กระเป๋าเงินเริ่มต้น + + + + BitcoinGUI + + &Overview + ภาพรวม + + + Show general overview of wallet + แสดงภาพรวมทั่วไปของกระเป๋าเงิน + + + &Transactions + ธุรกรรม + + + Browse transaction history + เรียกดูประวัติการทำธุรกรรม + + + E&xit + ออก + + + Quit application + ออกจากแอปพลิเคชัน + + + &About %1 + เกี่ยวกับ %1 + + + Show information about %1 + แสดงข้อมูลเกี่ยวกับ %1 + + + About &Qt + เกี่ยวกับ &Qt + + + Show information about Qt + แสดงข้อมูลเกี่ยวกับ Qt + + + Modify configuration options for %1 + แก้ไขตัวเลือกการตั้งค่าของ %1 + + + Create a new wallet + สร้างกระเป๋าใหม่ + + + &Minimize + ย่อ + + + Wallet: + กระเป๋าสตางค์ + + + Network activity disabled. + A substring of the tooltip. + กิจกรรมเครือข่ายถูกปิดใช้งาน + + + Proxy is <b>enabled</b>: %1 + เปิดใช้พร็อกซี: %1 + + + Send coins to a Bitcoin address + ส่งเหรียญไปยังที่อยู่บิตคอยน์ + + + Backup wallet to another location + สำรองกระเป๋าเงินไปยังตำแหน่งอื่น + + + Change the passphrase used for wallet encryption + เปลี่ยนรหัสผ่านที่ใช้สำหรับการเข้ารหัสกระเป๋าสตางค์ + + + &Send + ส่ง + + + &Receive + รับ + + + &Options… + ตัวเลือก + + + &Encrypt Wallet… + เข้ารหัสกระเป๋าเงิน + + + Encrypt the private keys that belong to your wallet + เข้ารหัสกุญแจส่วนตัวที่เป็นของกระเป๋าของคุณ + + + &Backup Wallet… + สำรองกระเป๋าเงิน + + + &Change Passphrase… + เปลี่ยนรหัสผ่าน... + + + Sign &message… + ป้าย & ข้อความ… + + + Sign messages with your Bitcoin addresses to prove you own them + ลงนามข้อความด้วยที่อยู่ Bitcoin ของคุณเพื่อพิสูจน์ว่าคุณเป็นเจ้าของ + + + &Verify message… + ตรวจสอบข้อความ... + + + Verify messages to ensure they were signed with specified Bitcoin addresses + ตรวจสอบข้อความเพื่อให้แน่ใจว่าข้อความเหล่านั้นได้รับการลงชื่อด้วยที่อยู่ Bitcoin ที่ระบุไว้ + + + &Load PSBT from file… + &โหลด PSBT จากไฟล์… + + + Open &URI… + เปิด &URI... + + + Close Wallet… + ปิดกระเป๋าสตางค์ + + + Create Wallet… + สร้างกระเป๋า... + + + Close All Wallets… + ปิดกระเป๋าทั้งหมด… + + + &File + &ไฟล์ + + + &Settings + &การตั้งค่า + + + &Help + &ช่วยเหลือ + + + Tabs toolbar + แถบเครื่องมือแท็บ + + + Syncing Headers (%1%)… + กำลังซิงค์หัวข้อ (%1%)… + + + Synchronizing with network… + กำลังซิงโครไนซ์กับเครือข่าย... + + + Indexing blocks on disk… + กำลังดัชนีบล็อกบนดิสก์… + + + Processing blocks on disk… + กำลังประมวลผลบล็อกบนดิสก์... + + + Connecting to peers… + กำลังเชื่อมต่อกับเพื่อนร่วมงาน... + + + Request payments (generates QR codes and bitcoin: URIs) + ขอการชำระเงิน (สร้างรหัส QR และ URI ของบิตคอยน์) + + + Show the list of used sending addresses and labels + แสดงรายการที่อยู่ที่ใช้ส่งและป้ายกำกับ + + + Show the list of used receiving addresses and labels + แสดงรายการที่อยู่รับและป้ายที่ใช้แล้ว + + + &Command-line options + &ตัวเลือกคำสั่งในบรรทัดคำสั่ง + + + Processed %n block(s) of transaction history. + + ประมวลผล %n บล็อกของประวัติการทำธุรกรรม. + + + + %1 behind + %1 ตามหลัง + + + Catching up… + ตามทัน... + + + Last received block was generated %1 ago. + บล็อกที่ได้รับล่าสุดถูกสร้างขึ้นเมื่อ %1 ที่แล้ว. + + + Transactions after this will not yet be visible. + ธุรกรรมหลังจากนี้จะยังไม่สามารถมองเห็นได้. + + + Error + ข้อผิดพลาด + + + Warning + คำเตือน + + + Information + ข้อมูล + + + Up to date + ทันสมัย + + + Load Partially Signed Bitcoin Transaction + โหลดธุรกรรม Bitcoin ที่ลงนามบางส่วน + + + Load PSBT from &clipboard… + โหลด PSBT จาก &คลิปบอร์ด… + + + Load Partially Signed Bitcoin Transaction from clipboard + โหลดธุรกรรม Bitcoin ที่ลงนามบางส่วนจากคลิปบอร์ด + + + Node window + หน้าต่างโหนด + + + Open node debugging and diagnostic console + เปิดคอนโซลดีบักและวินิจฉัยของโหนด + + + &Sending addresses + &ที่อยู่สำหรับการส่ง + + + &Receiving addresses + &ตัวเลือกคำสั่งในบรรทัดคำสั่ง + + + Open a bitcoin: URI + เปิดบิตคอยน์: URI + + + Open Wallet + เปิดกระเป๋า + + + Open a wallet + เปิดกระเป๋า + + + Close wallet + ปิดกระเป๋า + + + Restore Wallet… + Name of the menu item that restores wallet from a backup file. + กู้กระเป๋าเงิน… + + + Restore a wallet from a backup file + Status tip for Restore Wallet menu item + กู้คืนกระเป๋าเงินจากไฟล์สำรอง + + + Close all wallets + ปิดกระเป๋าทั้งหมด + + + Migrate Wallet + ย้ายกระเป๋าเงิน + + + Migrate a wallet + ย้ายกระเป๋าเงิน + + + Show the %1 help message to get a list with possible Bitcoin command-line options + แสดงข้อความช่วยเหลือ %1 เพื่อดูรายการตัวเลือกคำสั่งบิตคอยน์ที่เป็นไปได้ + + + &Mask values + &ค่าหน้ากาก + + + Mask the values in the Overview tab + ปิดบังค่าในแท็บภาพรวม + + + No wallets available + ไม่มีกระเป๋าสตางค์วางจำหน่าย + + + Wallet Data + Name of the wallet data file format. + ข้อมูลกระเป๋าเงิน + + + Load Wallet Backup + The title for Restore Wallet File Windows + โหลดสำรองกระเป๋าเงิน + + + Restore Wallet + Title of pop-up window shown when the user is attempting to restore a wallet. + กู้กระเป๋าเงิน + + + Wallet Name + Label of the input field where the name of the wallet is entered. + ชื่อกระเป๋าเงิน + + + &Window + หน้าต่าง + + + Ctrl+M + Ctrl+M (แป้นพิมพ์ลัด) + + + Main Window + หน้าต่างหลัก + + + %1 client + %1 ลูกค้า + + + &Hide + ซ่อน + + + %n active connection(s) to Bitcoin network. + A substring of the tooltip. + + การเชื่อมต่อที่ใช้งานอยู่ %n รายการไปยังเครือข่ายบิตคอยน์ + + + + Click for more actions. + A substring of the tooltip. "More actions" are available via the context menu. + คลิกเพื่อดูการกระทำเพิ่มเติม + + + Show Peers tab + A context menu item. The "Peers tab" is an element of the "Node window". + แสดงแท็บเพื่อนร่วมงาน + + + Disable network activity + A context menu item. + ปิดการใช้งานเครือข่าย + + + Enable network activity + A context menu item. The network activity was disabled previously. + เปิดใช้งานกิจกรรมเครือข่าย + + + Pre-syncing Headers (%1%)… + กำลังซิงค์หัวเรื่องล่วงหน้า (%1%)… + + + Error creating wallet + เกิดข้อผิดพลาดในการสร้างกระเป๋าเงิน + + + Cannot create new wallet, the software was compiled without sqlite support (required for descriptor wallets) + ไม่สามารถสร้างกระเป๋าใหม่ได้, ซอฟต์แวร์ถูกคอมไพล์โดยไม่มีการสนับสนุน sqlite (ซึ่งจำเป็นสำหรับกระเป๋า descriptor) + + + Error: %1 + ข้อผิดพลาด: %1 + + + Warning: %1 + คำเตือน: %1 + + + Date: %1 + + วันที่: %1 + + + Amount: %1 + + จำนวน: %1 + + + Wallet: %1 + + กระเป๋าเงิน: %1 + + + + Type: %1 + + ประเภท: %1 + + + + Label: %1 + + ป้ายกำกับ: %1 + + + + Address: %1 + + ที่อยู่: %1 + + + + Sent transaction + การทำธุรกรรมที่ส่งออก + + + Incoming transaction + การทำธุรกรรมที่เข้ามา + + + HD key generation is <b>enabled</b> + การสร้างคีย์ HD ถูกเปิดใช้งาน + + + HD key generation is <b>disabled</b> + การสร้างคีย์ HD คือ<b>พิการ</b> + + + Private key <b>disabled</b> + กุญแจส่วนตัว <b>พิการ</b> + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + กระเป๋าเงินคือ <b>เข้ารหัส</b> และปัจจุบัน <b>ปลดล็อก</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + กระเป๋าสตางค์คือ <b>เข้ารหัส</b> และปัจจุบัน <b>ล็อค</b> + + + Original message: + ข้อความต้นฉบับ + + + + UnitDisplayStatusBarControl + + Unit to show amounts in. Click to select another unit. + หน่วยเพื่อแสดงจำนวนใน. คลิกเพื่อเลือกหน่วยอื่น. + + + + CoinControlDialog + + Coin Selection + การเลือกเหรียญ + + + Quantity: + ปริมาณ: + + + Bytes: + ไบต์ + + + Amount: + จำนวน + + + Fee: + ค่าธรรมเนียม + + + After Fee: + หลังค่าธรรมเนียม: + + + Change: + การเปลี่ยนแปลง + + + (un)select all + เลือกทั้งหมด (ยกเลิก) + + + List mode + โหมดรายการ + + + Amount + จำนวน: + + + Received with label + ได้รับพร้อมป้าย + + + Received with address + รับพร้อมที่อยู่ + + + Date + วันที่ + + + Confirmations + การยืนยัน + + + Confirmed + ยืนยัน + + + Copy amount + จำนวนคัดลอก + + + &Copy address + ที่อยู่ &Copy + + + Copy &label + คัดลอก & ป้าย + + + Copy &amount + คัดลอก &จำนวน + + + Copy transaction &ID and output index + คัดลอกธุรกรรม &ID และดัชนีผลลัพธ์ + + + L&ock unspent + ปิดการใช้ที่ยังไม่ถูกใช้ + + + &Unlock unspent + &ปลดล็อกที่ยังไม่ได้ใช้ + + + Copy quantity + จำนวนสำเนา + + + Copy after fee + คัดลอกหลังค่าธรรมเนียม + + + Copy bytes + คัดลอกไบต์ + + + Copy change + การเปลี่ยนแปลงข้อความ + + + (%1 locked) + (*%1 ถูกล็อค) + + + Can vary +/- %1 satoshi(s) per input. + สามารถเปลี่ยนแปลงได้ +/- %1 ซาโตชิ (s) ต่อการป้อนข้อมูล + + + (no label) + ไม่มีป้ายกำกับ + + + change from %1 (%2) + เปลี่ยนจาก %1 (%2) + + + (change) + (เปลี่ยน) + + + + CreateWalletActivity + + Create Wallet + Title of window indicating the progress of creation of a new wallet. + สร้างกระเป๋า + + + Creating Wallet <b>%1</b>… + Descriptive text of the create wallet progress window which indicates to the user which wallet is currently being created. + การสร้างกระเป๋า <b>%1</b>… + + + Create wallet failed + สร้างกระเป๋าเงินล้มเหลว + + + Create wallet warning + คำเตือนการสร้างกระเป๋า + + + Can't list signers + ไม่สามารถระบุผู้ลงชื่อได้ + + + Too many external signers found + พบผู้ลงชื่อภายนอกมากเกินไป + + + + LoadWalletsActivity + + Load Wallets + Title of progress window which is displayed when wallets are being loaded. + โหลดกระเป๋า + + + Loading wallets… + Descriptive text of the load wallets progress window which indicates to the user that wallets are currently being loaded. + กำลังโหลดกระเป๋าเงิน… + + + + MigrateWalletActivity + + Migrate wallet + ย้ายกระเป๋าเงิน + + + Are you sure you wish to migrate the wallet <i>%1</i>? + คุณแน่ใจไหมว่าคุณต้องการย้ายกระเป๋า %1? + + + Migrating the wallet will convert this wallet to one or more descriptor wallets. A new wallet backup will need to be made. +If this wallet contains any watchonly scripts, a new wallet will be created which contains those watchonly scripts. +If this wallet contains any solvable but not watched scripts, a different and new wallet will be created which contains those scripts. + +The migration process will create a backup of the wallet before migrating. This backup file will be named <wallet name>-<timestamp>.legacy.bak and can be found in the directory for this wallet. In the event of an incorrect migration, the backup can be restored with the "Restore Wallet" functionality. + การย้ายกระเป๋าจะทำให้กระเป๋านี้กลายเป็นกระเป๋าหรือหลายๆ กระเป๋าที่มีคำอธิบาย (descriptor wallets) กระเป๋าสำรองใหม่จะต้องถูกสร้างขึ้น +หากกระเป๋านี้มีสคริปต์ที่ดูได้เท่านั้น (watchonly scripts) จะมีกระเป๋าใหม่ที่สร้างขึ้นซึ่งมีสคริปต์เหล่านั้น +หากกระเป๋านี้มีสคริปต์ที่แก้ไขได้แต่ไม่ได้ติดตาม (solvable but not watched scripts) จะมีกระเป๋าใหม่ที่แตกต่างออกไปซึ่งมีสคริปต์เหล่านั้น + + + Migrate Wallet + ย้ายกระเป๋าเงิน + + + Migrating Wallet <b>%1</b>… + กำลังย้ายกระเป๋าเงิน %1… + + + The wallet '%1' was migrated successfully. + กระเป๋าเงิน '%1' ถูกย้ายเรียบร้อยแล้ว + + + Watchonly scripts have been migrated to a new wallet named '%1'. + สคริปต์แบบดูเฉยๆ ถูกย้ายไปยังกระเป๋าใหม่ที่ชื่อว่า '%1' + + + Solvable but not watched scripts have been migrated to a new wallet named '%1'. + สคริปต์ที่สามารถแก้ไขได้แต่ไม่ได้ติดตามได้ถูกย้ายไปยังกระเป๋าใหม่ที่ชื่อว่า '%1' + + + Migration failed + การย้ายล้มเหลว + + + Migration Successful + การย้ายสำเร็จ + + + + OpenWalletActivity + + Open wallet failed + เปิดกระเป๋าล้มเหลว + + + Open wallet warning + คำเตือนเปิดกระเป๋า + + + Open Wallet + Title of window indicating the progress of opening of a wallet. + เปิดกระเป๋า + + + + RestoreWalletActivity + + Restore Wallet + Title of progress window which is displayed when wallets are being restored. + กู้กระเป๋าเงิน + + + Restore wallet failed + Title of message box which is displayed when the wallet could not be restored. + การกู้คืนกระเป๋าเงินล้มเหลว + + + Restore wallet warning + Title of message box which is displayed when the wallet is restored with some warning. + คำเตือนการกู้คืนกระเป๋าเงิน + + + Restore wallet message + Title of message box which is displayed when the wallet is successfully restored. + กู้คืนข้อความกระเป๋าเงิน + + + + WalletController + + Close wallet + ปิดกระเป๋า + + + Closing the wallet for too long can result in having to resync the entire chain if pruning is enabled. + การปิดกระเป๋าไว้เป็นเวลานานเกินไปอาจทำให้ต้องซิงค์ข้อมูลทั้งสายอีกครั้งหากเปิดใช้งานการตัดทอน + + + Close all wallets + ปิดกระเป๋าทั้งหมด + + + Are you sure you wish to close all wallets? + คุณมั่นใจไหมว่าคุณต้องการปิดกระเป๋าทั้งหมด? + + + + CreateWalletDialog + + Create Wallet + สร้างกระเป๋า + + + You are one step away from creating your new wallet! + คุณอยู่แค่ก้าวเดียวจากการสร้างกระเป๋าเงินใหม่ของคุณ! + + + Please provide a name and, if desired, enable any advanced options + กรุณาระบุชื่อและหากต้องการ โปรดเปิดใช้งานตัวเลือกขั้นสูง + + + Wallet Name + ชื่อกระเป๋าเงิน + + + Wallet + กระเป๋าสตางค์ + + + Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice. + เข้ารหัสกระเป๋าเงิน กระเป๋าเงินจะถูกเข้ารหัสด้วยรหัสผ่านที่คุณเลือก + + + Encrypt Wallet + เข้ารหัสกระเป๋าเงิน + + + Advanced Options + ตัวเลือกขั้นสูง + + + Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets. + "ปิดการใช้งานคีย์ส่วนตัวสำหรับกระเป๋านี้ กระเป๋าที่ปิดการใช้งานคีย์ส่วนตัวจะไม่มีคีย์ส่วนตัวและไม่สามารถมีเมล็ด HD หรือคีย์ส่วนตัวที่นำเข้าได้ นี่เหมาะสำหรับกระเป๋าที่ดูอย่างเดียว" + + + Disable Private Keys + ปิดกุญแจส่วนตัว + + + Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time. + สร้างกระเป๋าเปล่า กระเป๋าเปล่าเริ่มต้นจะไม่มีคีย์ส่วนตัวหรือสคริปต์ คีย์ส่วนตัวและที่อยู่สามารถนำเข้าได้ หรือสามารถตั้งค่า HD seed ในภายหลัง + + + Make Blank Wallet + ทำกระเป๋าว่าง + + + Use an external signing device such as a hardware wallet. Configure the external signer script in wallet preferences first. + ใช้อุปกรณ์เซ็นต์ภายนอก เช่น กระเป๋าเงินฮาร์ดแวร์ กำหนดสคริปต์เซ็นต์ภายนอกในการตั้งค่ากระเป๋าเงินก่อน + + + External signer + ผู้เซ็นภายนอก + + + Create + สร้าง + + + Compiled without external signing support (required for external signing) + "External signing" means using devices such as hardware wallets. + คอมไพล์โดยไม่มีการสนับสนุนการลงชื่อภายนอก (ซึ่งจำเป็นสำหรับการลงชื่อภายนอก) + + + + EditAddressDialog + + Edit Address + แก้ไขที่อยู่ + + + &Label + ป้าย + + + The label associated with this address list entry + ป้ายกำกับที่เกี่ยวข้องกับรายการที่อยู่ในรายการนี้ + + + The address associated with this address list entry. This can only be modified for sending addresses. + ที่อยู่ที่เชื่อมโยงกับรายการที่อยู่ในลิสต์นี้ นี้สามารถแก้ไขได้เฉพาะสำหรับที่อยู่ในการส่ง + + + New sending address + ที่อยู่สำหรับการส่งใหม่ + + + Edit receiving address + แก้ไขที่อยู่สำหรับการรับ + + + Edit sending address + แก้ไขที่อยู่การส่ง + + + The entered address "%1" is not a valid Bitcoin address. + อยู่ที่ป้อน "%1" ไม่ใช่ที่อยู่ Bitcoin ที่ถูกต้อง + + + Address "%1" already exists as a receiving address with label "%2" and so cannot be added as a sending address. + ที่อยู่ "%1" มีอยู่แล้วในฐานะที่อยู่รับที่มีป้ายชื่อ "%2" และดังนั้นจึงไม่สามารถเพิ่มเป็นที่อยู่ส่งได้ + + + The entered address "%1" is already in the address book with label "%2". + ที่อยู่ "%1" ที่ป้อนเข้าไปมีอยู่ในสมุดที่อยู่แล้วพร้อมป้ายกำกับ "%2" + + + Could not unlock wallet. + ไม่สามารถปลดล็อกกระเป๋าเงินได้ + + + New key generation failed. + การสร้างคีย์ใหม่ล้มเหลว + + + + FreespaceChecker + + A new data directory will be created. + ไดเรกทอรีข้อมูลใหม่จะถูกสร้างขึ้น + + + name + ชื่อ + + + Directory already exists. Add %1 if you intend to create a new directory here. + ไดเรกทอรีมีอยู่แล้ว เพิ่ม %1 หากคุณต้องการสร้างไดเรกทอรีใหม่ที่นี่ + + + Path already exists, and is not a directory. + เส้นทางมีอยู่แล้วและไม่ใช่ไดเรกทอรี + + + Cannot create data directory here. + ไม่สามารถสร้างไดเรกทอรีข้อมูลที่นี่ได้ + + + + Intro + + %n GB of space available + + %n GB ของพื้นที่ที่ว่าง + + + + (of %n GB needed) + + (ของ %n GB ที่ต้องการ) + + + + (%n GB needed for full chain) + + (%n GB ที่ต้องการสำหรับโซ่ทั้งหมด) + + + + Choose data directory + เลือกไดเรกทอรีข้อมูล + + + At least %1 GB of data will be stored in this directory, and it will grow over time. + อย่างน้อย %1 GB ของข้อมูลจะถูกจัดเก็บในไดเรกทอรีนี้ และมันจะเติบโตขึ้นตามเวลา + + + Approximately %1 GB of data will be stored in this directory. + ประมาณ %1 GB ของข้อมูลจะถูกเก็บไว้ในไดเรกทอรีนี้ + + + (sufficient to restore backups %n day(s) old) + Explanatory text on the capability of the current prune target. + + (เพียงพอสำหรับการกู้คืนข้อมูลสำรองที่มีอายุ %n วัน) + + + + %1 will download and store a copy of the Bitcoin block chain. + %1 จะดาวน์โหลดและเก็บสำเนาของบล็อกเชนของบิตคอยน์ + + + The wallet will also be stored in this directory. + กระเป๋าเงินจะถูกเก็บไว้ในไดเรกทอรี่นี้ด้วย + + + Error: Specified data directory "%1" cannot be created. + ข้อผิดพลาด: ไม่สามารถสร้างไดเรกทอรีข้อมูลที่ระบุ "%1" ได้ + + + Error + ข้อผิดพลาด + + + Welcome + ยินดีต้อนรับ + + + Welcome to %1. + ยินดีต้อนรับสู่ %1 + + + As this is the first time the program is launched, you can choose where %1 will store its data. + เนื่องจากนี่เป็นครั้งแรกที่โปรแกรมถูกเปิดใช้งาน, คุณสามารถเลือกที่ที่ %1 จะเก็บข้อมูลของมัน + + + Limit block chain storage to + จำกัดการจัดเก็บบล็อกเชนถึง + + + Reverting this setting requires re-downloading the entire blockchain. It is faster to download the full chain first and prune it later. Disables some advanced features. + การย้อนกลับการตั้งค่านี้ต้องการการดาวน์โหลดบล็อกเชนทั้งหมดใหม่ การดาวน์โหลดทั้งชุดเชนก่อนแล้วค่อยตัดทอนภายหลังจะเร็วกว่า ปิดการใช้งานคุณสมบัติขั้นสูงบางอย่าง + + + GB + กิกะไบต์ + + + This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off. + การซิงโครไนซ์เริ่มต้นนี้ต้องการทรัพยากรมาก และอาจเปิดเผยปัญหาฮาร์ดแวร์ที่เกิดขึ้นกับคอมพิวเตอร์ของคุณซึ่งก่อนหน้านี้อาจไม่ถูกสังเกตเห็น ทุกครั้งที่คุณเรียกใช้ %1 มันจะดำเนินการดาวน์โหลดต่อจากจุดที่มันหยุดไว้ + + + When you click OK, %1 will begin to download and process the full %4 block chain (%2 GB) starting with the earliest transactions in %3 when %4 initially launched. + "เมื่อคุณคลิกตกลง, %1 จะเริ่มดาวน์โหลดและประมวลผลบล็อกเชน %4 ทั้งหมด (%2 GB) โดยเริ่มจากธุรกรรมแรกสุดใน %3 เมื่อ %4 เริ่มต้นเปิดตัว" + + + If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low. + "ถ้าคุณได้เลือกที่จะจำกัดการจัดเก็บบล็อกเชน (การตัดทอน), ข้อมูลประวัติยังคงต้องถูกดาวน์โหลดและประมวลผล, แต่จะถูกลบหลังจากนั้นเพื่อรักษาการใช้งานดิสก์ของคุณให้ต่ำ." + + + Use the default data directory + ใช้ไดเร็กทอรีข้อมูลเริ่มต้น + + + Use a custom data directory: + ใช้ไดเรกทอรีข้อมูลที่กำหนดเอง: + + + + HelpMessageDialog + + version + เวอร์ชัน + + + About %1 + เกี่ยวกับ %1 + + + Command-line options + ตัวเลือกบรรทัดคำสั่ง + + + + ShutdownWindow + + %1 is shutting down… + %1 กำลังปิดการทำงาน… + + + Do not shut down the computer until this window disappears. + อย่าปิดเครื่องคอมพิวเตอร์จนกว่าหน้าต่างนี้จะหายไป + + + + ModalOverlay + + Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below. + ธุรกรรมล่าสุดอาจยังไม่ปรากฏ และดังนั้นยอดคงเหลือในกระเป๋าของคุณอาจไม่ถูกต้อง ข้อมูลนี้จะถูกต้องเมื่อกระเป๋าของคุณเสร็จสิ้นการซิงค์กับเครือข่ายบิตคอยน์ ตามที่อธิบายไว้ด้านล่าง + + + Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network. + การพยายามใช้บิตคอยน์ที่ได้รับผลกระทบจากธุรกรรมที่ยังไม่ได้แสดงจะไม่ได้รับการยอมรับจากเครือข่าย + + + Number of blocks left + จำนวนบล็อกที่เหลือ + + + calculating… + กำลังคำนวณ + + + Last block time + เวลาบล็อกสุดท้าย + + + Progress + ความก้าวหน้า + + + Progress increase per hour + ความก้าวหน้าที่เพิ่มขึ้นต่อชั่วโมง + + + Estimated time left until synced + เวลาที่เหลือที่คาดการณ์จนกว่าจะซิงค์เสร็จ + + + Hide + ซ่อน + + + Esc + "Esc" (อีสเคป) + + + %1 is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain. + %1 กำลังซิงค์อยู่ในขณะนี้ มันจะดาวน์โหลดหัวข้อและบล็อกจากเพื่อนและตรวจสอบพวกมันจนกว่าจะถึงจุดสูงสุดของบล็อกเชน + + + Unknown. Syncing Headers (%1, %2%)… + ไม่ทราบ กำลังซิงค์ส่วนหัว (%1, %2%)… + + + Unknown. Pre-syncing Headers (%1, %2%)… + ไม่รู้จัก กำลังเตรียมข้อมูลหัวข้อ (%1, %2%)… + + + + OpenURIDialog + + Open bitcoin URI + เปิด URI ของบิตคอยน์ + + + URI: + ยูอาร์ไอ: + + + Paste address from clipboard + Tooltip text for button that allows you to paste an address that is in your clipboard. + วางที่อยู่จากคลิปบอร์ด + + + + OptionsDialog + + Options + ตัวเลือก + + + &Main + &หลัก + + + Automatically start %1 after logging in to the system. + เริ่ม %1 อัตโนมัติหลังจากเข้าสู่ระบบ + + + &Start %1 on system login + เริ่ม %1 เมื่อเข้าสู่ระบบ + + + Enabling pruning significantly reduces the disk space required to store transactions. All blocks are still fully validated. Reverting this setting requires re-downloading the entire blockchain. + การเปิดใช้งานการตัดข้อมูลจะลดพื้นที่ดิสก์ที่จำเป็นในการเก็บข้อมูลธุรกรรมอย่างมีนัยสำคัญ บล็อกทั้งหมดยังคงได้รับการตรวจสอบความถูกต้องอย่างเต็มที่ การย้อนกลับการตั้งค่านี้ต้องดาวน์โหลดบล็อกเชนทั้งหมดใหม่อีกครั้ง + + + Size of &database cache + ขนาดของแคชฐานข้อมูล + + + Number of script &verification threads + จำนวนของสคริปต์และเธรดการตรวจสอบ + + + Full path to a %1 compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins! + เส้นทางเต็มไปยังสคริปต์ที่เข้ากันได้กับ %1 (เช่น C:\Downloads\hwi.exe หรือ /Users/you/Downloads/hwi.py). ระวัง: มัลแวร์อาจขโมยเหรียญของคุณ! + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + ที่อยู่ IP ของพร็อกซี (เช่น IPv4: 127.0.0.1 / IPv6: ::1) + + + Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type. + แสดงว่าการใช้พร็อกซี SOCKS5 ค่าเริ่มต้นที่จัดเตรียมไว้ถูกใช้เพื่อเข้าถึงเพื่อนผ่านประเภทเครือข่ายนี้ + + + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu. + ลดขนาดแทนที่จะปิดแอปพลิเคชันเมื่อปิดหน้าต่าง เมื่อเปิดใช้งานตัวเลือกนี้ แอปพลิเคชันจะถูกปิดเฉพาะเมื่อเลือก Exit ในเมนู + + + Font in the Overview tab: + ฟอนต์ในแท็บภาพรวม: + + + Options set in this dialog are overridden by the command line: + ตัวเลือกที่ตั้งค่าในกล่องโต้ตอบนี้จะถูกเขียนทับโดยบรรทัดคำสั่ง: + + + Open the %1 configuration file from the working directory. + เปิดไฟล์การตั้งค่า %1 จากไดเรกทอรีทำงาน + + + Open Configuration File + เปิดไฟล์การตั้งค่า + + + Reset all client options to default. + รีเซ็ตตัวเลือกทั้งหมดของลูกค้าเป็นค่าเริ่มต้น + + + &Reset Options + ตัวเลือกการรีเซ็ต + + + &Network + และเครือข่าย + + + Prune &block storage to + ตัดทอนและบล็อกที่เก็บข้อมูลไปที่ + + + Reverting this setting requires re-downloading the entire blockchain. + การคืนค่านี้ต้องการการดาวน์โหลดบล็อกเชนทั้งหมดอีกครั้ง + + + Connect to the Bitcoin network through a SOCKS5 proxy. + เชื่อมต่อกับเครือข่าย Bitcoin ผ่านพร็อกซี SOCKS5. + + + &Connect through SOCKS5 proxy (default proxy): + เชื่อมต่อผ่านพร็อกซี่ SOCKS5 (พร็อกซี่เริ่มต้น): + + + Proxy &IP: + พร็อกซี & ไอพี + + + Used for reaching peers via: + ใช้สำหรับการติดต่อเพื่อนร่วมงานผ่าน: + + + IPv4 + ไอพีวี4 + + + IPv6 + ไอพีวี6 + + + Tor + ทอร์. + + + &Window + หน้าต่าง + + + Show the icon in the system tray. + แสดงไอคอนในถาดระบบ + + + &Show tray icon + แสดงไอคอนถาด + + + Show only a tray icon after minimizing the window. + แสดงเฉพาะไอคอนถาดหลังจากย่อหน้าต่าง + + + &Minimize to the tray instead of the taskbar + ย่อไปที่ถาดแทนที่จะเป็นแถบงาน + + + &Display + แสดงผล + + + User Interface &language: + อินเตอร์เฟซผู้ใช้ & ภาษา + + + The user interface language can be set here. This setting will take effect after restarting %1. + คุณสามารถตั้งค่าภาษาอินเตอร์เฟซผู้ใช้ที่นี่ การตั้งค่านี้จะมีผลหลังจากการรีสตาร์ท %1 + + + &Unit to show amounts in: + หน่วยที่จะแสดงจำนวนใน: + + + Choose the default subdivision unit to show in the interface and when sending coins. + เลือกหน่วยย่อยเริ่มต้นที่จะแสดงในอินเทอร์เฟซและเมื่อส่งเหรียญ + + + Third-party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. + URL ของบุคคลที่สาม (เช่น ตัวสำรวจบล็อก) ที่ปรากฏในแท็บการทำธุรกรรมในฐานะตัวเลือกในเมนูบริบท โดยที่ %s ใน URL จะถูกแทนที่ด้วยแฮชของธุรกรรม และ URL หลายรายการจะถูกแยกด้วยเครื่องหมาย | + + + &Third-party transaction URLs + ลิงก์ธุรกรรมของบุคคลที่สาม + + + Whether to show coin control features or not. + จะแสดงคุณสมบัติการควบคุมเหรียญหรือไม่ + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor onion services. + เชื่อมต่อกับเครือข่าย Bitcoin ผ่านพร็อกซี SOCKS5 แยกต่างหากสำหรับบริการ Tor onion + + + Use separate SOCKS&5 proxy to reach peers via Tor onion services: + ใช้พร็อกซี่ SOCKS5 แยกต่างหากเพื่อเชื่อมต่อกับเพื่อนผ่านบริการ Tor onion + + + &OK + โอเค + + + &Cancel + ยกเลิก + + + Compiled without external signing support (required for external signing) + "External signing" means using devices such as hardware wallets. + คอมไพล์โดยไม่มีการสนับสนุนการลงชื่อภายนอก (ซึ่งจำเป็นสำหรับการลงชื่อภายนอก) + + + default + ค่าเริ่มต้น + + + none + ไม่มี + + + Confirm options reset + Window title text of pop-up window shown when the user has chosen to reset options. + ยืนยันการรีเซ็ตตัวเลือก + + + Client restart required to activate changes. + Text explaining that the settings changed will not come into effect until the client is restarted. + จำเป็นต้องรีสตาร์ทไคลเอนต์เพื่อเปิดใช้งานการเปลี่ยนแปลง + + + Current settings will be backed up at "%1". + Text explaining to the user that the client's current settings will be backed up at a specific location. %1 is a stand-in argument for the backup location's path. + การตั้งค่าปัจจุบันจะถูกสำรองไว้ที่ "%1" + + + Client will be shut down. Do you want to proceed? + Text asking the user to confirm if they would like to proceed with a client shutdown. + ลูกค้าจะถูกปิดลง คุณต้องการดำเนินการต่อไหม? + + + Configuration options + Window title text of pop-up box that allows opening up of configuration file. + ตัวเลือกการกำหนดค่า + + + The configuration file is used to specify advanced user options which override GUI settings. Additionally, any command-line options will override this configuration file. + Explanatory text about the priority order of instructions considered by client. The order from high to low being: command-line, configuration file, GUI settings. + ไฟล์การตั้งค่าถูกใช้เพื่อระบุทางเลือกผู้ใช้ขั้นสูงที่จะแทนที่การตั้งค่าของ GUI นอกจากนี้ ตัวเลือกจากบรรทัดคำสั่งใดๆ จะทับไฟล์การตั้งค่านี้ + + + Cancel + ยกเลิก + + + Error + ข้อผิดพลาด + + + The configuration file could not be opened. + ไม่สามารถเปิดไฟล์การตั้งค่าได้ + + + This change would require a client restart. + การเปลี่ยนแปลงนี้จะต้องการการรีสตาร์ทของไคลเอนต์ + + + The supplied proxy address is invalid. + ที่อยู่พร็อกซีที่ให้มานั้นไม่ถูกต้อง + + + + OptionsModel + + Could not read setting "%1", %2. + "ไม่สามารถอ่านการตั้งค่า "%1" ได้, %2" + + + + OverviewPage + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + ข้อมูลที่แสดงอาจจะล้าสมัย กระเป๋าของคุณจะทำการซิงค์อัตโนมัติกับเครือข่าย Bitcoin หลังจากที่เชื่อมต่อเสร็จสิ้นแล้ว แต่กระบวนการนี้ยังไม่เสร็จสมบูรณ์ + + + Watch-only: + ดูอย่างเดียว + + + Available: + พร้อมใช้งาน + + + Your current spendable balance + ยอดคงเหลือที่สามารถใช้ได้ในปัจจุบัน + + + Pending: + รอดำเนินการ + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + ยอดรวมของธุรกรรมที่ยังไม่ได้รับการยืนยัน และยังไม่นับรวมในยอดคงเหลือที่สามารถใช้จ่ายได้ + + + Immature: + ยังไม่โต + + + Mined balance that has not yet matured + ยอดที่ขุดได้ซึ่งยังไม่ครบกำหนด + + + Balances + ยอดคงเหลือ + + + Total: + รวม: + + + Your current total balance + ยอดคงเหลือทั้งหมดของคุณในปัจจุบัน + + + Your current balance in watch-only addresses + ยอดคงเหลือปัจจุบันของคุณในที่อยู่สำหรับดูอย่างเดียว + + + Spendable: + ใช้จ่ายได้ + + + Recent transactions + การทำธุรกรรมล่าสุด + + + Mined balance in watch-only addresses that has not yet matured + ยอดคงเหลือที่ถูกขุดในที่อยู่ที่ดูได้เท่านั้นซึ่งยังไม่ครบกำหนด + + + Current total balance in watch-only addresses + ยอดคงเหลือทั้งหมดปัจจุบันในที่อยู่ที่ดูได้อย่างเดียว + + + Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings->Mask values. + โหมดความเป็นส่วนตัวถูกเปิดใช้งานสำหรับแท็บภาพรวม หากต้องการแสดงค่า ให้ยกเลิกการเลือก การตั้งค่า->ปิดการซ่อนค่า + + + + PSBTOperationsDialog + + PSBT Operations + การดำเนินงาน + + + Sign Tx + ลงชื่อ Tx + + + Broadcast Tx + การออกอากาศ Tx + + + Copy to Clipboard + คัดลอกไปยังคลิปบอร์ด (Khat-lok pai yang klip-bord) + + + Save… + บันทึก... + + + Close + ปิด (bpit) + + + Failed to load transaction: %1 + ไม่สามารถโหลดธุรกรรมได้: %1 + + + Failed to sign transaction: %1 + ล้มเหลวในการเซ็นต์ธุรกรรม: %1 + + + Cannot sign inputs while wallet is locked. + ไม่สามารถเซ็นข้อมูลขาเข้าได้เมื่อกระเป๋าสตางค์ถูกล็อก + + + Could not sign any more inputs. + ไม่สามารถลงนามการป้อนข้อมูลเพิ่มเติมได้ (Mai samart long nam kan phon khomooht permum dai). + + + Signed %1 inputs, but more signatures are still required. + ลงชื่อ %1 ข้อมูลเข้าแล้ว แต่ยังต้องการลายเซ็นเพิ่มเติม + + + Signed transaction successfully. Transaction is ready to broadcast. + เซ็นธุรกรรมสำเร็จแล้ว ธุรกรรมพร้อมที่จะถ่ายทอด + + + Unknown error processing transaction. + เกิดข้อผิดพลาดที่ไม่รู้จักในการประมวลผลธุรกรรม + + + Transaction broadcast successfully! Transaction ID: %1 + การถ่ายทอดธุรกรรมสำเร็จ! รหัสธุรกรรม: %1 + + + Transaction broadcast failed: %1 + การส่งธุรกรรมล้มเหลว: %1 + + + PSBT copied to clipboard. + PSBT คัดลอกไปยังคลิปบอร์ดแล้ว + + + Save Transaction Data + บันทึกข้อมูลธุรกรรม + + + Partially Signed Transaction (Binary) + Expanded name of the binary PSBT file format. See: BIP 174. + ธุรกรรมที่ลงนามบางส่วน (ไบนารี) + + + PSBT saved to disk. + PSBT ถูกบันทึกลงดิสก์. + + + Sends %1 to %2 + ส่ง %1 ไปยัง %2 + + + own address + ที่อยู่ของตนเอง + + + Unable to calculate transaction fee or total transaction amount. + ไม่สามารถคำนวณค่าธรรมเนียมการทำรายการหรือยอดรวมการทำรายการได้ + + + Pays transaction fee: + ชำระค่าธรรมเนียมการทำธุรกรรม: + + + or + หรือ + + + Transaction has %1 unsigned inputs. + ธุรกรรมมีอินพุตที่ไม่ได้เซ็น %1 รายการ + + + Transaction is missing some information about inputs. + การทำธุรกรรมขาดข้อมูลบางอย่างเกี่ยวกับอินพุต + + + Transaction still needs signature(s). + การทำธุรกรรมยังต้องการลายเซ็น(s). + + + (But no wallet is loaded.) + (แต่ว่าไม่มีกระเป๋าเงินถูกโหลด.) + + + (But this wallet cannot sign transactions.) + (แต่กระเป๋าเงินนี้ไม่สามารถลงนามธุรกรรมได้) + + + (But this wallet does not have the right keys.) + (แต่กระเป๋าเงินนี้ไม่มีคีย์ที่ถูกต้อง) + + + Transaction is fully signed and ready for broadcast. + การทำธุรกรรมลงนามครบถ้วนแล้วและพร้อมสำหรับการประกาศ + + + Transaction status is unknown. + สถานะของธุรกรรมไม่ทราบแน่ชัด + + + + PaymentServer + + Payment request error + ข้อผิดพลาดในการขอชำระเงิน + + + Cannot start bitcoin: click-to-pay handler + ไม่สามารถเริ่มต้นบิตคอยน์: ตัวจัดการคลิกเพื่อจ่าย + + + URI handling + การจัดการ URI + + + 'bitcoin://' is not a valid URI. Use 'bitcoin:' instead. + 'bitcoin://' ไม่ใช่ URI ที่ถูกต้อง ใช้ 'bitcoin:' แทน + + + Cannot process payment request because BIP70 is not supported. +Due to widespread security flaws in BIP70 it's strongly recommended that any merchant instructions to switch wallets be ignored. +If you are receiving this error you should request the merchant provide a BIP21 compatible URI. + ไม่สามารถดำเนินการคำขอชำระเงินได้เนื่องจาก BIP70 ไม่ได้รับการรองรับ +เนื่องจากมีข้อบกพร่องด้านความปลอดภัยอย่างแพร่หลายในการใช้ BIP70 จึงขอแนะนำอย่างยิ่งให้เพิกเฉยต่อคำแนะนำของพ่อค้าในการเปลี่ยนกระเป๋าเงิน +หากคุณได้รับข้อผิดพลาดนี้คุณควรขอให้พ่อค้าจัดเตรียม URI ที่รองรับ BIP21 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + ไม่สามารถแยก URI ได้! สิ่งนี้อาจเกิดจากที่อยู่ Bitcoin ที่ไม่ถูกต้องหรือพารามิเตอร์ URI ที่ผิดรูปแบบ + + + Payment request file handling + การจัดการไฟล์คำขอการชำระเงิน + + + + PeerTableModel + + Peer + Title of Peers Table column which contains a unique number used to identify a connection. + เพื่อน (Phûuean) + + + Age + Title of Peers Table column which indicates the duration (length of time) since the peer connection started. + อายุ + + + Direction + Title of Peers Table column which indicates the direction the peer connection was initiated from. + ทิศทาง (Thít-thāng) + + + Sent + Title of Peers Table column which indicates the total amount of network information we have sent to the peer. + ส่ง (sòng) + + + Received + Title of Peers Table column which indicates the total amount of network information we have received from the peer. + ได้รับ + + + Address + Title of Peers Table column which contains the IP/Onion/I2P address of the connected peer. + ที่อยู่ + + + Type + Title of Peers Table column which describes the type of peer connection. The "type" describes why the connection exists. + ประเภท + + + Inbound + An Inbound Connection from a Peer. + ขาเข้า +(Pronunciation: kǎa-kâo) + + + Outbound + An Outbound Connection to a Peer. + ออกเดินทาง (òk dern thāng) + + + + RPCConsole + + Local Addresses + ที่อยู่ท้องถิ่น + + + Network addresses that your Bitcoin node is currently using to communicate with other nodes. + ที่อยู่เครือข่ายที่โหนด Bitcoin ของคุณกำลังใช้ในการสื่อสารกับโหนดอื่นๆ + + + Block chain + บล็อกเชน + + + Memory Pool + หน่วยความจำพูล + + + Current number of transactions + จำนวนธุรกรรมปัจจุบัน + + + Memory usage + การใช้งานหน่วยความจำ + + + Wallet: + กระเป๋าสตางค์ + + + (none) + (ไม่มี) + + + Received + ได้รับ + + + Sent + ส่ง (sòng) - - - QObject - %1 didn't yet exit safely… - %1 ยังไม่ออกอย่างปลอดภัย... + &Peers + เพื่อนร่วมงาน - - %n second(s) - - %n second(s) - + + Banned peers + เพื่อนที่ถูกแบน (Phuean thi thuk baen) - - %n minute(s) - - %n minute(s) - + + Select a peer to view detailed information. + เลือกเพื่อนร่วมงานเพื่อดูข้อมูลรายละเอียด - - %n hour(s) - - %n hour(s) - + + Hide Peers Detail + ซ่อนรายละเอียดเพื่อนร่วมงาน - - %n day(s) - - %n day(s) - + + Ctrl+X + ตัด (Tàd) - - %n week(s) - - %n week(s) - + + The transport layer version: %1 + เวอร์ชันของชั้นการขนส่ง: %1 - - %n year(s) - - %n year(s) - + + Session ID + รหัสเซสชัน (Rát sét-chân) - - - BitcoinGUI - Change the passphrase used for wallet encryption - เปลี่ยนรหัสผ่านที่ใช้สำหรับการเข้ารหัสกระเป๋าเงิน + Whether we relay transactions to this peer. + ไม่ว่าความเราจะส่งการทำธุรกรรมไปยังเพื่อนนี้หรือไม่ - Encrypt the private keys that belong to your wallet - เข้ารหัสกุญแจส่วนตัวที่เป็นของกระเป๋าสตางค์ของคุณ + Transaction Relay + การส่งต่อธุรกรรม (Kan song tor thurakham) - Sign messages with your Bitcoin addresses to prove you own them - เซ็นชื่อด้วยข้อความ ที่เก็บ Bitcoin เพื่อแสดงว่าท่านเป็นเจ้าของ bitcoin นี้จริง + Starting Block + บล็อกเริ่มต้น (Blók Rêrm Tôn) - Verify messages to ensure they were signed with specified Bitcoin addresses - ตรวจสอบ ข้อความ เพื่อให้แน่ใจว่า การเซ็นต์ชื่อ ด้วยที่เก็บ Bitcoin แล้ว + Synced Headers + หัวข้อที่ซิงค์ (Huākhāo thī sìngk) - &File - &ไฟล์ + Synced Blocks + บล็อกที่ซิงค์ (Blok thi sing) - &Settings - &การตั้งค่า + Last Transaction + ธุรกรรมล่าสุด (Thurakam lasut) - &Help - &ช่วยเหลือ + The mapped Autonomous System used for diversifying peer selection. + ระบบอัตโนมัติที่ทำการแมปเพื่อใช้ในการกระจายการเลือกเพื่อน - Tabs toolbar - แถบเครื่องมือแท็บ + Whether we relay addresses to this peer. + Tooltip text for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No). + เราจะส่งที่อยู่ให้กับเพื่อนคนนี้หรือไม่ - Connecting to peers… - กำลังเชื่อมต่อ ไปยัง peers… + Address Relay + Text title for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No). + การส่งต่อที่อยู่ (Kān sòng tōr thī̀ yùu) - Request payments (generates QR codes and bitcoin: URIs) - ขอการชำระเงิน (สร้างรหัส QR และ bitcoin: URIs) + The total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). + Tooltip text for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). + จำนวนที่อยู่ทั้งหมดที่ได้รับจากเพื่อนนี้ที่ได้รับการประมวลผล (ไม่รวมที่อยู่ที่ถูกยกเลิกเนื่องจากการจำกัดอัตรา) - Show the list of used sending addresses and labels - แสดงรายการที่ใช้ในการส่งแอดเดรสและเลเบลที่ใช้แล้ว + The total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. + Tooltip text for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. + จำนวนที่อยู่ทั้งหมดที่ได้รับจากเพื่อนนี้ที่ถูกทิ้ง (ไม่ได้ประมวลผล) เนื่องจากการจำกัดอัตรา - Show the list of used receiving addresses and labels - แสดงรายการที่ได้ใช้ในการรับแอดเดรสและเลเบล + Addresses Processed + Text title for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting). + ที่อยู่ที่ประมวลผล - &Command-line options - &ตัวเลือก Command-line + Addresses Rate-Limited + Text title for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting. + ที่อยู่ถูกจำกัดอัตรา - - Processed %n block(s) of transaction history. - - ประมวลผล %n บล็อกของประวัติการทำธุรกรรม - + + Node window + หน้าต่างโหนด - %1 behind - %1 เบื้องหลัง + Current block height + ความสูงของบล็อกปัจจุบัน (Khwam sung khong blok pachuban) - Catching up… - กำลังติดตามถึงรายการล่าสุด… + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + เปิดไฟล์บันทึกการดีบัก %1 จากไดเรกทอรีข้อมูลปัจจุบัน ซึ่งอาจใช้เวลาสักครู่สำหรับไฟล์บันทึกขนาดใหญ่ - Last received block was generated %1 ago. - บล็อกที่ได้รับล่าสุดถูกสร้างขึ้นเมื่อ %1 ที่แล้ว + Decrease font size + ลดขนาดตัวอักษร - Transactions after this will not yet be visible. - ธุรกรรมหลังจากนี้จะยังไม่ปรากฏให้เห็น + Increase font size + เพิ่มขนาดตัวอักษร (Pêr̂m khà-nàd tûa-òk-sŏn) - Error - ข้อผิดพลาด + Permissions + สิทธิ์ (Sìt) or การอนุญาต (Kān Anuyāt) - Warning - คำเตือน + The direction and type of peer connection: %1 + ทิศทางและประเภทของการเชื่อมต่อระหว่างเพื่อน: %1 - Information - ข้อมูล + Direction/Type + ทิศทาง/ประเภท (Títhāng / Bpràphêd) - Up to date - ปัจจุบัน + The BIP324 session ID string in hex. + สตริง ID เซสชัน BIP324 ในรูปแบบเฮกซ์ - Load PSBT from &clipboard… - โหลด PSBT จากคลิปบอร์ด... + The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS. + โปรโตคอลเครือข่ายที่เพื่อนนี้เชื่อมต่อผ่าน: IPv4, IPv6, Onion, I2P, หรือ CJDNS. - Node window - หน้าต่างโหนด + Services + บริการ (Borisat) - &Sending addresses - &ที่อยู่การส่ง + High bandwidth BIP152 compact block relay: %1 + การส่งข้อมูลบล็อกแบบคอมแพค BIP152 ความกว้างแบนด์วิธสูง: %1 - &Receiving addresses - &ที่อยู่การรับ + Connection Time + เวลาเชื่อมต่อ (Wela Chueamto) - Open Wallet - เปิดกระเป๋าสตางค์ + Elapsed time since a novel block passing initial validity checks was received from this peer. + เวลาที่ผ่านไปตั้งแต่ได้รับบล็อกใหม่ที่ผ่านการตรวจสอบความถูกต้องเบื้องต้นจากเพื่อนนี้ - Open a wallet - เปิดกระเป๋าสตางค์ + Last Block + บล็อกสุดท้าย (Blók Sùt Tái) - Close wallet - ปิดกระเป๋าสตางค์ + Elapsed time since a novel transaction accepted into our mempool was received from this peer. + Tooltip text for the Last Transaction field in the peer details area. + เวลาที่ผ่านไปตั้งแต่การทำธุรกรรมใหม่ที่ได้รับการยอมรับเข้าสู่ mempool ของเราได้รับจากเพื่อนนี้ - Restore Wallet… - Name of the menu item that restores wallet from a backup file. - กู้คืนวอลเล็ต… + Last Send + ส่งสุดท้าย (Song Soot Thai) - Restore a wallet from a backup file - Status tip for Restore Wallet menu item - กู้คืนวอลเล็ตจากไฟล์สำรองข้อมูล + Last Receive + ได้รับล่าสุด - Close all wallets - ปิด วอลเล็ต ทั้งหมด + Ping Time + เวลาในการปิง - &Mask values - &ค่ามาสก์ + The duration of a currently outstanding ping. + ระยะเวลาของปิงที่ยังค้างอยู่ในขณะนี้ - Load Wallet Backup - The title for Restore Wallet File Windows - โหลดสำรองข้อมูลวอลเล็ต + Ping Wait + รอปิง - - %n active connection(s) to Bitcoin network. - A substring of the tooltip. - - %n active connection(s) to Bitcoin network. - + + Min Ping + มินผิง - Click for more actions. - A substring of the tooltip. "More actions" are available via the context menu. - คลิกเพื่อดูการดำเนินการเพิ่มเติม + Time Offset + เวลาออฟเซ็ต - - - CoinControlDialog - L&ock unspent - L&ock ที่ไม่ได้ใข้ + Last block time + เวลาบล็อกสุดท้าย - &Unlock unspent - &ปลดล็อค ที่ไม่ไดใช้ + &Open + เปิด - (no label) - (ไม่มีเลเบล) + &Console + &คอนโซล - change from %1 (%2) - เปลี่ยน จาก %1 (%2) + &Network Traffic + การรับส่งข้อมูลเครือข่าย - (change) - (เปลี่ยน) + Totals + ผลรวม - - - CreateWalletActivity - Create Wallet - Title of window indicating the progress of creation of a new wallet. - สร้าง วอลเล็ต + Debug log file + ไฟล์บันทึกดีบัก - Creating Wallet <b>%1</b>… - Descriptive text of the create wallet progress window which indicates to the user which wallet is currently being created. - กำลังสร้าง วอลเล็ต <b>%1</b>… + Clear console + ล้างคอนโซล - Create wallet failed - การสร้าง วอลเล็ต ล้มเหลว + In: + ใน - Create wallet warning - คำเตือน การสร้าง วอลเล็ต + Out: + ออก - Can't list signers - ไม่สามารถ จัดรายการ ผู้เซ็น + Inbound: initiated by peer + Explanatory text for an inbound peer connection. + ขาเข้า: เริ่มต้นโดยปัสสาวะ - - - LoadWalletsActivity - Load Wallets - Title of progress window which is displayed when wallets are being loaded. - โหลด วอลเล็ต + Outbound Full Relay: default + Explanatory text for an outbound peer connection that relays all network information. This is the default behavior for outbound connections. + การส่งต่อแบบเต็มขาออก: ค่าเริ่มต้น - Loading wallets… - Descriptive text of the load wallets progress window which indicates to the user that wallets are currently being loaded. - กำลังโหลด วอลเล็ต... + Outbound Block Relay: does not relay transactions or addresses + Explanatory text for an outbound peer connection that relays network information about blocks and not transactions or addresses. + การส่งบล็อกขาออก: ไม่ส่งต่อธุรกรรมหรือที่อยู่ - + + &Copy address + Context menu action to copy the address of a peer. + ที่อยู่ &Copy + + + None + ไม่มี (Mai mee) + + - Intro - - %n GB of space available - - %n GB of space available - + ReceiveCoinsDialog + + &Copy address + ที่อยู่ &Copy - - (of %n GB needed) - - (of %n GB needed) - + + Copy &label + คัดลอก & ป้าย - - (%n GB needed for full chain) - - (%n GB needed for full chain) - + + Copy &amount + คัดลอก &จำนวน - - (sufficient to restore backups %n day(s) old) - Explanatory text on the capability of the current prune target. - - (sufficient to restore backups %n day(s) old) - + + Could not unlock wallet. + ไม่สามารถปลดล็อกกระเป๋าเงินได้ - RPCConsole + ReceiveRequestDialog - Node window - หน้าต่างโหนด + Amount: + จำนวน + + + Wallet: + กระเป๋าสตางค์ + + + &Save Image… + บันทึกรูปภาพ... RecentRequestsTableModel + + Date + วันที่ + + + Label + การส่งออกล้มเหลว + (no label) - (ไม่มีเลเบล) + ไม่มีป้ายกำกับ SendCoinsDialog + + Quantity: + ปริมาณ: + + + Bytes: + ไบต์ + + + Amount: + จำนวน + + + Fee: + ค่าธรรมเนียม + + + After Fee: + หลังค่าธรรมเนียม: + + + Change: + การเปลี่ยนแปลง + + + Hide + ซ่อน + + + Copy quantity + จำนวนสำเนา + + + Copy amount + จำนวนคัดลอก + + + Copy fee + ค่าลอกสำเนา (kâa lók sàm-náo) + + + Copy after fee + คัดลอกหลังค่าธรรมเนียม + + + Copy bytes + คัดลอกไบต์ + + + Copy change + การเปลี่ยนแปลงข้อความ + + + Save Transaction Data + บันทึกข้อมูลธุรกรรม + + + Partially Signed Transaction (Binary) + Expanded name of the binary PSBT file format. See: BIP 174. + ธุรกรรมที่ลงนามบางส่วน (ไบนารี) + + + or + หรือ + Estimated to begin confirmation within %n block(s). @@ -318,23 +2503,140 @@ (no label) - (ไม่มีเลเบล) + ไม่มีป้ายกำกับ + + SendCoinsEntry + + Paste address from clipboard + วางที่อยู่จากคลิปบอร์ด + + + + SignVerifyMessageDialog + + Paste address from clipboard + วางที่อยู่จากคลิปบอร์ด + + TransactionDesc + + Date + วันที่ + + + unknown + ไม่ทราบ (mai saap) + + + own address + ที่อยู่ของตนเอง + matures in %n more block(s) matures in %n more block(s) + + Amount + จำนวน: + TransactionTableModel + + Date + วันที่ + + + Type + ประเภท + + + Label + การส่งออกล้มเหลว + (no label) - (ไม่มีเลเบล) + ไม่มีป้ายกำกับ + + + + TransactionView + + &Copy address + ที่อยู่ &Copy + + + Copy &label + คัดลอก & ป้าย + + + Copy &amount + คัดลอก &จำนวน + + + Comma separated file + Expanded name of the CSV file format. See: https://en.wikipedia.org/wiki/Comma-separated_values. + ไฟล์ที่แยกด้วยเครื่องหมายจุลภาค + + + Confirmed + ยืนยัน + + + Date + วันที่ + + + Type + ประเภท + + + Label + การส่งออกล้มเหลว + + + Address + ที่อยู่ + + + Exporting Failed + การส่งออกล้มเหลว + + + + WalletFrame + + Create a new wallet + สร้างกระเป๋าใหม่ + + + Error + ข้อผิดพลาด + + WalletView + + &Export + &ส่งออก + + + Export the data in the current tab to a file + ส่งออกข้อมูลในแท็บปัจจุบันไปยังไฟล์ + + + Wallet Data + Name of the wallet data file format. + ข้อมูลกระเป๋าเงิน + + + Cancel + ยกเลิก + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_tl.ts b/src/qt/locale/bitcoin_tl.ts index f0e34993c48..49ce14378ad 100644 --- a/src/qt/locale/bitcoin_tl.ts +++ b/src/qt/locale/bitcoin_tl.ts @@ -90,7 +90,7 @@ Signing is only possible with addresses of the type 'legacy'. There was an error trying to save the address list to %1. Please try again. An error message. %1 is a stand-in argument for the name of the file we attempted to save to. - May mali sa pagsubok na i-save ang listahan ng address sa 1%1. Pakisubukan ulit. + May mali sa pagsubok na i-save ang listahan ng address sa %1. Pakisubukan ulit. Exporting Failed @@ -242,7 +242,7 @@ Signing is only possible with addresses of the type 'legacy'. A fatal error occurred. %1 can no longer continue safely and will quit. - Malubhang pagkakamali ay naganap. 1%1 hindi na pwedeng magpatuloy ng ligtas at ihihinto na. + Malubhang pagkakamali ay naganap. %1 hindi na pwedeng magpatuloy ng ligtas at ihihinto na. Internal error @@ -250,7 +250,7 @@ Signing is only possible with addresses of the type 'legacy'. An internal error occurred. %1 will attempt to continue safely. This is an unexpected bug which can be reported as described below. - May panloob na pagkakamali ang naganap. 1%1 ay magtatangkang ituloy na ligtas. Ito ay hindi inaasahan na problema na maaaring i-ulat katulad ng pagkalarawan sa ibaba. + May panloob na pagkakamali ang naganap. %1 ay magtatangkang ituloy na ligtas. Ito ay hindi inaasahan na problema na maaaring i-ulat katulad ng pagkalarawan sa ibaba. @@ -267,11 +267,11 @@ Signing is only possible with addresses of the type 'legacy'. Error: %1 - Pagkakamali: 1%1 + Pagkakamali: %1 %1 didn't yet exit safely… - 1%1 hindi pa nag-exit ng ligtas... + %1 hindi pa nag-exit ng ligtas... Amount @@ -352,11 +352,11 @@ Signing is only possible with addresses of the type 'legacy'. &About %1 - &Tungkol sa 1%1 + &Tungkol sa %1 Show information about %1 - Ipakita ang impormasyon tungkol sa 1%1 + Ipakita ang impormasyon tungkol sa %1 About &Qt @@ -368,7 +368,7 @@ Signing is only possible with addresses of the type 'legacy'. Modify configuration options for %1 - Baguhin ang mga pagpipilian sa ♦configuration♦ para sa 1%1 + Baguhin ang mga pagpipilian sa ♦configuration♦ para sa %1 Create a new wallet @@ -669,7 +669,7 @@ Signing is only possible with addresses of the type 'legacy'. Error: %1 - Pagkakamali: 1%1 + Pagkakamali: %1 Warning: %1 diff --git a/src/qt/locale/bitcoin_ur.ts b/src/qt/locale/bitcoin_ur.ts index 1bf6208f8ce..7e3f8630f7d 100644 --- a/src/qt/locale/bitcoin_ur.ts +++ b/src/qt/locale/bitcoin_ur.ts @@ -747,24 +747,24 @@ Signing is only possible with addresses of the type 'legacy'. Warning: %1 - 1%1 انتباہ + %1 انتباہ Date: %1 - 1%1' تاریخ۔ + %1' تاریخ۔ Amount: %1 - 1%1' مقدار + %1' مقدار Wallet: %1 - 1%1' والیٹ + %1' والیٹ @@ -776,13 +776,13 @@ Signing is only possible with addresses of the type 'legacy'. Label: %1 - 1%1'لیبل + %1'لیبل Address: %1 - 1%1' پتہ + %1' پتہ diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index ae29726a14a..bc0592b2ea0 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -3355,6 +3355,10 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 satos &Sign Message 消息签名(&S) + + You can sign messages/agreements with your legacy (P2PKH) addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + 您可以使用您的 (P2PKH)格式 地址签署消息 / 协议,以证明您对这个地址有发送或接收比特币的权限。钓鱼攻击可能试图欺骗您签署您的身份,所以请仔细分辨,不要签署任何含混不清的协议。只签署你完全认同并理解的协议 。 + The Bitcoin address to sign the message with 用来对消息签名的地址 From ca70d5cb2592d5227eab8b18288f060ed6305a99 Mon Sep 17 00:00:00 2001 From: laanwj <126646+laanwj@users.noreply.github.com> Date: Fri, 11 Apr 2025 08:09:45 +0200 Subject: [PATCH 028/314] Remove support for RNDR/RNDRRS for aarch64 on Linux This hardware feature is - rarely supported on SoCs (and broken on like half of the chips that support it in the first place) (#31817) - apparently not compiled into the release binary (https://github.com/bitcoin/bitcoin/issues/31817#issuecomment-2795885962) - hard to test in CI, due to unavailable of hardware Better to remove it. This reverts commit aee5404e02e203a256c1a97b629b9b107cc8bb07. Closes #31817. Github-Pull: #32248 Rebased-From: 7749d929a0d9dfe71541a22e557ea41e01df28ce --- src/random.cpp | 73 -------------------------------------------------- 1 file changed, 73 deletions(-) diff --git a/src/random.cpp b/src/random.cpp index 5b605e988d0..685beb1fdba 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -41,9 +41,6 @@ #ifdef HAVE_SYSCTL_ARND #include #endif -#if defined(HAVE_STRONG_GETAUXVAL) && defined(__aarch64__) -#include -#endif namespace { @@ -189,62 +186,6 @@ uint64_t GetRdSeed() noexcept #endif } -#elif defined(__aarch64__) && defined(HWCAP2_RNG) - -bool g_rndr_supported = false; - -void InitHardwareRand() -{ - if (getauxval(AT_HWCAP2) & HWCAP2_RNG) { - g_rndr_supported = true; - } -} - -void ReportHardwareRand() -{ - // This must be done in a separate function, as InitHardwareRand() may be indirectly called - // from global constructors, before logging is initialized. - if (g_rndr_supported) { - LogPrintf("Using RNDR and RNDRRS as additional entropy sources\n"); - } -} - -/** Read 64 bits of entropy using rndr. - * - * Must only be called when RNDR is supported. - */ -uint64_t GetRNDR() noexcept -{ - uint8_t ok = 0; - uint64_t r1; - do { - // https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/RNDR--Random-Number - __asm__ volatile("mrs %0, s3_3_c2_c4_0; cset %w1, ne;" - : "=r"(r1), "=r"(ok)::"cc"); - if (ok) break; - __asm__ volatile("yield"); - } while (true); - return r1; -} - -/** Read 64 bits of entropy using rndrrs. - * - * Must only be called when RNDRRS is supported. - */ -uint64_t GetRNDRRS() noexcept -{ - uint8_t ok = 0; - uint64_t r1; - do { - // https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/RNDRRS--Reseeded-Random-Number - __asm__ volatile("mrs %0, s3_3_c2_c4_1; cset %w1, ne;" - : "=r"(r1), "=r"(ok)::"cc"); - if (ok) break; - __asm__ volatile("yield"); - } while (true); - return r1; -} - #else /* Access to other hardware random number generators could be added here later, * assuming it is sufficiently fast (in the order of a few hundred CPU cycles). @@ -263,12 +204,6 @@ void SeedHardwareFast(CSHA512& hasher) noexcept { hasher.Write((const unsigned char*)&out, sizeof(out)); return; } -#elif defined(__aarch64__) && defined(HWCAP2_RNG) - if (g_rndr_supported) { - uint64_t out = GetRNDR(); - hasher.Write((const unsigned char*)&out, sizeof(out)); - return; - } #endif } @@ -294,14 +229,6 @@ void SeedHardwareSlow(CSHA512& hasher) noexcept { } return; } -#elif defined(__aarch64__) && defined(HWCAP2_RNG) - if (g_rndr_supported) { - for (int i = 0; i < 4; ++i) { - uint64_t out = GetRNDRRS(); - hasher.Write((const unsigned char*)&out, sizeof(out)); - } - return; - } #endif } From 85f3e1de68e845937ebc3568e26c12fc6a027a18 Mon Sep 17 00:00:00 2001 From: Brandon Odiwuor Date: Wed, 16 Apr 2025 14:18:48 +0300 Subject: [PATCH 029/314] test: Handle empty string returned by CLI as None in RPC tests Github-Pull: #32286 Rebased-From: a4041c77f0e20d004524868e70ff12508832c9eb --- test/functional/test_framework/test_node.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index f7d6ba78d23..e7ae3851f02 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -913,6 +913,8 @@ def send_cli(self, clicommand=None, *args, **kwargs): # Ignore cli_stdout, raise with cli_stderr raise subprocess.CalledProcessError(returncode, self.binary, output=cli_stderr) try: + if not cli_stdout.strip(): + return None return json.loads(cli_stdout, parse_float=decimal.Decimal) except (json.JSONDecodeError, decimal.InvalidOperation): return cli_stdout.rstrip("\n") From 64552c83b2b1e2d4da561d06900a70144ebfb054 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 1 Apr 2025 15:02:47 +0100 Subject: [PATCH 030/314] ci: Add workaround for vcpkg's libevent package This change is necessary for Windows GHA images, which provide CMake >= 4.0. Github-Pull: #32184 Rebased-From: ef00a28414daed2dd026b458082ed03fe9508074 --- .github/workflows/ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3b55c400f2..2cac4eab0b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,10 +194,12 @@ jobs: Write-Host "PowerShell version $($PSVersionTable.PSVersion.ToString())" - name: Using vcpkg with MSBuild + shell: bash run: | - Set-Location "$env:VCPKG_INSTALLATION_ROOT" - Add-Content -Path "triplets\x64-windows.cmake" -Value "set(VCPKG_BUILD_TYPE release)" - Add-Content -Path "triplets\x64-windows-static.cmake" -Value "set(VCPKG_BUILD_TYPE release)" + echo "set(VCPKG_BUILD_TYPE release)" >> "${VCPKG_INSTALLATION_ROOT}/triplets/x64-windows.cmake" + echo "set(VCPKG_BUILD_TYPE release)" >> "${VCPKG_INSTALLATION_ROOT}/triplets/x64-windows-static.cmake" + # Workaround for libevent, which requires CMake 3.1 but is incompatible with CMake >= 4.0. + sed -i '1s/^/set(ENV{CMAKE_POLICY_VERSION_MINIMUM} 3.5)\n/' "${VCPKG_INSTALLATION_ROOT}/scripts/ports.cmake" - name: vcpkg tools cache uses: actions/cache@v4 From 3dbd2b3d178176eb410270afb7d4a7db11ff08ae Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Tue, 1 Apr 2025 18:41:54 +0200 Subject: [PATCH 031/314] refactor: Remove spurious virtual from final ~CZMQNotificationInterface Github-Pull: #32187 Rebased-From: fa69c42fdf0aeec0546e951bc6132ab630edb9d4 --- src/zmq/zmqnotificationinterface.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index c879fdd0ddf..ad445bbd393 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -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 GetActiveNotifiers() const; From 4ed5c34abb242494dff36409f5eef68272827a03 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Thu, 24 Apr 2025 10:21:40 +0200 Subject: [PATCH 032/314] test: Add imports for util bpf_cflags This is required for the next commit. Github-Pull: #32336 Rebased-From: fa0c1baaf89805182de56d6a2e8eed2265a94b40 --- test/functional/interface_usdt_coinselection.py | 3 ++- test/functional/interface_usdt_mempool.py | 7 +++++-- test/functional/interface_usdt_net.py | 7 +++++-- test/functional/interface_usdt_utxocache.py | 7 +++++-- test/functional/interface_usdt_validation.py | 8 +++++--- test/functional/test_framework/util.py | 7 +++++++ 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/test/functional/interface_usdt_coinselection.py b/test/functional/interface_usdt_coinselection.py index 1f4d6d6fbf1..52cee9372a9 100755 --- a/test/functional/interface_usdt_coinselection.py +++ b/test/functional/interface_usdt_coinselection.py @@ -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 @@ assert_equal, assert_greater_than, assert_raises_rpc_error, + bpf_cflags, ) coinselection_tracepoints_program = """ diff --git a/test/functional/interface_usdt_mempool.py b/test/functional/interface_usdt_mempool.py index 75359541722..a5a0ee448e9 100755 --- a/test/functional/interface_usdt_mempool.py +++ b/test/functional/interface_usdt_mempool.py @@ -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. @@ -20,7 +20,10 @@ 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 = """ diff --git a/test/functional/interface_usdt_net.py b/test/functional/interface_usdt_net.py index ef67534e96c..624017a9eae 100755 --- a/test/functional/interface_usdt_net.py +++ b/test/functional/interface_usdt_net.py @@ -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,7 +17,10 @@ from test_framework.messages import CBlockHeader, MAX_HEADERS_RESULTS, msg_headers, msg_version from test_framework.p2p import P2PInterface from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal +from test_framework.util import ( + assert_equal, + bpf_cflags, +) # Tor v3 addresses are 62 chars + 6 chars for the port (':12345'). MAX_PEER_ADDR_LENGTH = 68 diff --git a/test/functional/interface_usdt_utxocache.py b/test/functional/interface_usdt_utxocache.py index 12a11409e03..4c887d035e2 100755 --- a/test/functional/interface_usdt_utxocache.py +++ b/test/functional/interface_usdt_utxocache.py @@ -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. @@ -15,7 +15,10 @@ pass from test_framework.messages import COIN 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 utxocache_changes_program = """ diff --git a/test/functional/interface_usdt_validation.py b/test/functional/interface_usdt_validation.py index 9b2e708d955..0a27e5eaefb 100755 --- a/test/functional/interface_usdt_validation.py +++ b/test/functional/interface_usdt_validation.py @@ -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. @@ -18,8 +18,10 @@ from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal - +from test_framework.util import ( + assert_equal, + bpf_cflags, +) validation_blockconnected_program = """ #include diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 14930ef6719..6cf04a2e266 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -317,6 +317,13 @@ def wait_until_helper_internal(predicate, *, timeout=60, lock=None, timeout_fact raise AssertionError("Predicate {} not true after {} seconds".format(predicate_source, timeout)) +def bpf_cflags(): + return [ + "-Wno-error=implicit-function-declaration", + "-Wno-duplicate-decl-specifier", # https://github.com/bitcoin/bitcoin/issues/32322 + ] + + def sha256sum_file(filename): h = hashlib.sha256() with open(filename, 'rb') as f: From 3665310808f58073c3cd72a5f99f19b22adccdf0 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Thu, 24 Apr 2025 10:26:11 +0200 Subject: [PATCH 033/314] scripted-diff: Use bpf_cflags -BEGIN VERIFY SCRIPT- ren() { sed --regexp-extended -i "s/$1/$2/g" $( git grep --extended-regexp -l "$1" ) ; } ren 'cflags=\["-Wno-error=implicit-function-declaration"\]' 'cflags=bpf_cflags()' -END VERIFY SCRIPT- Github-Pull: #32336 Rebased-From: facb9b327b9da39ce1e09ed56199be9efb19b5b8 --- test/functional/interface_usdt_coinselection.py | 2 +- test/functional/interface_usdt_mempool.py | 8 ++++---- test/functional/interface_usdt_net.py | 12 ++++++------ test/functional/interface_usdt_utxocache.py | 8 ++++---- test/functional/interface_usdt_validation.py | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/functional/interface_usdt_coinselection.py b/test/functional/interface_usdt_coinselection.py index 52cee9372a9..93acffd8318 100755 --- a/test/functional/interface_usdt_coinselection.py +++ b/test/functional/interface_usdt_coinselection.py @@ -176,7 +176,7 @@ def run_test(self): 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) diff --git a/test/functional/interface_usdt_mempool.py b/test/functional/interface_usdt_mempool.py index a5a0ee448e9..c356d0f010c 100755 --- a/test/functional/interface_usdt_mempool.py +++ b/test/functional/interface_usdt_mempool.py @@ -169,7 +169,7 @@ def added_test(self): 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)) @@ -206,7 +206,7 @@ def removed_test(self): 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)) @@ -252,7 +252,7 @@ def replaced_test(self): 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, __): event = ctypes.cast(data, ctypes.POINTER(MempoolReplaced)).contents @@ -305,7 +305,7 @@ def rejected_test(self): 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)) diff --git a/test/functional/interface_usdt_net.py b/test/functional/interface_usdt_net.py index 624017a9eae..4917dc488b6 100755 --- a/test/functional/interface_usdt_net.py +++ b/test/functional/interface_usdt_net.py @@ -286,7 +286,7 @@ def __repr__(self): fn_name="trace_inbound_message") ctx.enable_probe(probe="net:outbound_message", fn_name="trace_outbound_message") - bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) EXPECTED_INOUTBOUND_VERSION_MSG = 1 checked_inbound_version_msg = 0 @@ -344,7 +344,7 @@ def inbound_conn_tracepoint_test(self): ctx = USDT(pid=self.nodes[0].process.pid) ctx.enable_probe(probe="net:inbound_connection", fn_name="trace_inbound_connection") - bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) inbound_connections = [] EXPECTED_INBOUND_CONNECTIONS = 2 @@ -381,7 +381,7 @@ def outbound_conn_tracepoint_test(self): ctx = USDT(pid=self.nodes[0].process.pid) ctx.enable_probe(probe="net:outbound_connection", fn_name="trace_outbound_connection") - bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) # that the handle_* function succeeds. EXPECTED_OUTBOUND_CONNECTIONS = 2 @@ -422,7 +422,7 @@ def evicted_inbound_conn_tracepoint_test(self): ctx = USDT(pid=self.nodes[0].process.pid) ctx.enable_probe(probe="net:evicted_inbound_connection", fn_name="trace_evicted_inbound_connection") - bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) EXPECTED_EVICTED_CONNECTIONS = 2 evicted_connections = [] @@ -459,7 +459,7 @@ def misbehaving_conn_tracepoint_test(self): ctx = USDT(pid=self.nodes[0].process.pid) ctx.enable_probe(probe="net:misbehaving_connection", fn_name="trace_misbehaving_connection") - bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) EXPECTED_MISBEHAVING_CONNECTIONS = 2 misbehaving_connections = [] @@ -493,7 +493,7 @@ def closed_conn_tracepoint_test(self): ctx = USDT(pid=self.nodes[0].process.pid) ctx.enable_probe(probe="net:closed_connection", fn_name="trace_closed_connection") - bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) EXPECTED_CLOSED_CONNECTIONS = 2 closed_connections = [] diff --git a/test/functional/interface_usdt_utxocache.py b/test/functional/interface_usdt_utxocache.py index 4c887d035e2..0c9c696fae9 100755 --- a/test/functional/interface_usdt_utxocache.py +++ b/test/functional/interface_usdt_utxocache.py @@ -184,7 +184,7 @@ def test_uncache(self): ctx = USDT(pid=self.nodes[0].process.pid) ctx.enable_probe(probe="utxocache:uncache", fn_name="trace_utxocache_uncache") - bpf = BPF(text=utxocache_changes_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=utxocache_changes_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) # The handle_* function is a ctypes callback function called from C. When # we assert in the handle_* function, the AssertError doesn't propagate @@ -253,7 +253,7 @@ def test_add_spent(self): ctx.enable_probe(probe="utxocache:add", fn_name="trace_utxocache_add") ctx.enable_probe(probe="utxocache:spent", fn_name="trace_utxocache_spent") - bpf = BPF(text=utxocache_changes_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=utxocache_changes_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) # The handle_* function is a ctypes callback function called from C. When # we assert in the handle_* function, the AssertError doesn't propagate @@ -342,7 +342,7 @@ def test_flush(self): ctx = USDT(pid=self.nodes[0].process.pid) ctx.enable_probe(probe="utxocache:flush", fn_name="trace_utxocache_flush") - bpf = BPF(text=utxocache_flushes_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=utxocache_flushes_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) # The handle_* function is a ctypes callback function called from C. When # we assert in the handle_* function, the AssertError doesn't propagate @@ -399,7 +399,7 @@ def handle_utxocache_flush(_, data, __): ctx = USDT(pid=self.nodes[0].process.pid) ctx.enable_probe(probe="utxocache:flush", fn_name="trace_utxocache_flush") - bpf = BPF(text=utxocache_flushes_program, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + bpf = BPF(text=utxocache_flushes_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) bpf["utxocache_flush"].open_perf_buffer(handle_utxocache_flush) self.log.info("prune blockchain to trigger a flush for pruning") diff --git a/test/functional/interface_usdt_validation.py b/test/functional/interface_usdt_validation.py index 0a27e5eaefb..f7d518d8930 100755 --- a/test/functional/interface_usdt_validation.py +++ b/test/functional/interface_usdt_validation.py @@ -99,7 +99,7 @@ def __repr__(self): ctx.enable_probe(probe="validation:block_connected", fn_name="trace_block_connected") bpf = BPF(text=validation_blockconnected_program, - usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"]) + usdt_contexts=[ctx], debug=0, cflags=bpf_cflags()) def handle_blockconnected(_, data, __): event = ctypes.cast(data, ctypes.POINTER(Block)).contents From 5aa4956cd3ad42e6e511625fc548f55bf95a6575 Mon Sep 17 00:00:00 2001 From: furszy Date: Mon, 7 Apr 2025 11:38:48 -0400 Subject: [PATCH 034/314] gui: crash fix, disconnect numBlocksChanged() signal during shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The crash stems from the order of the shutdown procedure: We first unset the client model, then destroy the wallet controller—but we leave the internal wallet models ('m_wallets') untouched for a brief period. As a result, there’s a point in time where views still have connected signals and access to wallet models that are not connected to any wallet controller. Now.. since the clientModel is only replaced with nullptr locally and not destroyed yet, signals like numBlocksChanged can still emit. Thus, when wallet views receive them, they see a non-null wallet model ptr, and proceed to call backend functions from a model that is being torn down. As the shutdown procedure begins by unsetting clientModel from all views. It’s safe to ignore events when clientModel is nullptr. Github-Pull: gui#864 Rebased-From: 71656bdfaa6bfe08ce9651246a3ef606f923351b --- src/qt/sendcoinsdialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 0ee1b359fa9..1da03b8e3bc 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -851,6 +851,10 @@ void SendCoinsDialog::updateCoinControlState() } void SendCoinsDialog::updateNumberOfBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state) { + // During shutdown, clientModel will be nullptr. Attempting to update views at this point may cause a crash + // due to accessing backend models that might no longer exist. + if (!clientModel) return; + // Process event if (sync_state == SynchronizationState::POST_INIT) { updateSmartFeeLabel(); } From f4d9546425ec38d78ef128a5bc7580d816b707ce Mon Sep 17 00:00:00 2001 From: laanwj <126646+laanwj@users.noreply.github.com> Date: Thu, 24 Apr 2025 12:09:33 +0200 Subject: [PATCH 035/314] qt: Replace stray tfm::format to cerr with qWarning GUI warnings should go to the log, not to the console (which may not be connected at all). Github-Pull: gui#868 Rebased-From: edd46566bd66cea7d7f4116429fe1c11d2187ba2 --- src/qt/sendcoinsdialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 1da03b8e3bc..55349b1fca0 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -464,7 +465,7 @@ bool SendCoinsDialog::signWithExternalSigner(PartiallySignedTransaction& psbtx, return false; } if (err) { - tfm::format(std::cerr, "Failed to sign PSBT"); + qWarning() << "Failed to sign PSBT"; processSendCoinsReturn(WalletModel::TransactionCreationFailed); return false; } From 2f6c802b549c72393fdaff44d2fd4cb501f97926 Mon Sep 17 00:00:00 2001 From: monlovesmango Date: Fri, 25 Apr 2025 16:19:28 +0000 Subject: [PATCH 036/314] doc: Fix fuzz test_runner.py path This commit fixes the path listed in the documentation for the fuzz testing test_runner.py. Previously the --help option worked but running fuzz tests from the documented path did not. Github-Pull: #32353 Rebased-From: 61f238e84ac6d24d8f420c2eabcbb2980d7fcb1e --- doc/fuzzing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fuzzing.md b/doc/fuzzing.md index d3a0e42e9b3..20dfdc5e924 100644 --- a/doc/fuzzing.md +++ b/doc/fuzzing.md @@ -19,7 +19,7 @@ One can use `--preset=libfuzzer-nosan` to do the same without common sanitizers See [further](#run-without-sanitizers-for-increased-throughput) for more information. There is also a runner script to execute all fuzz targets. Refer to -`./test/fuzz/test_runner.py --help` for more details. +`./build_fuzz/test/fuzz/test_runner.py --help` for more details. ## Overview of Bitcoin Core fuzzing From 6ed087dede0839cac4e4528a746f573aecd5f5f2 Mon Sep 17 00:00:00 2001 From: monlovesmango Date: Thu, 1 May 2025 03:05:57 +0000 Subject: [PATCH 037/314] doc: Fix test_bitcoin path This commit fixes a couple command paths for interacting with the test_bitcoin binary within the Unit Test documentation. Github-Pull: #32389 Rebased-From: 6cbc28b8dd629062950f195facc009fd8ba86310 --- src/test/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/README.md b/src/test/README.md index c7e7ab911dc..6c49762ab3e 100644 --- a/src/test/README.md +++ b/src/test/README.md @@ -22,7 +22,7 @@ and tests weren't explicitly disabled. The unit tests can be run with `ctest --test-dir build`, which includes unit tests from subtrees. -Run `test_bitcoin --list_content` for the full list of tests. +Run `build/bin/test_bitcoin --list_content` for the full list of tests. To run the unit tests manually, launch `build/bin/test_bitcoin`. To recompile after a test file was modified, run `cmake --build build` and then run the test again. If you @@ -44,7 +44,7 @@ The `test_bitcoin` runner accepts command line arguments from the Boost framework. To see the list of arguments that may be passed, run: ``` -test_bitcoin --help +build/bin/test_bitcoin --help ``` For example, to run only the tests in the `getarg_tests` file, with full logging: From f9d2c67a0c78192ce365e6e4065bb5e9198d771c Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 26 Apr 2025 19:19:49 +0100 Subject: [PATCH 038/314] cmake: Respect user-provided configuration-specific flags Github-Pull: #32356 Rebased-From: edde96376a2961dec3730331b3d171ddf972589f --- CMakeLists.txt | 4 ++++ cmake/module/ProcessConfigurations.cmake | 15 +++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b8716c491e..e83a30ed1e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,10 @@ if(POLICY CMP0171) cmake_policy(SET CMP0171 NEW) endif() +# When adjusting CMake flag variables, we must not override those explicitly +# set by the user. These are a subset of the CACHE_VARIABLES property. +get_directory_property(precious_variables CACHE_VARIABLES) + #============================= # Project / Package metadata #============================= diff --git a/cmake/module/ProcessConfigurations.cmake b/cmake/module/ProcessConfigurations.cmake index 9a510a00a55..d5426f6e08f 100644 --- a/cmake/module/ProcessConfigurations.cmake +++ b/cmake/module/ProcessConfigurations.cmake @@ -105,14 +105,13 @@ function(remove_cxx_flag_from_all_configs flag) endfunction() function(replace_cxx_flag_in_config config old_flag new_flag) - string(TOUPPER "${config}" config_uppercase) - string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_CXX_FLAGS_${config_uppercase}}") - set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE) - set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" - CACHE STRING - "Flags used by the CXX compiler during ${config_uppercase} builds." - FORCE - ) + string(TOUPPER "CMAKE_CXX_FLAGS_${config}" var_name) + if("${var_name}" IN_LIST precious_variables) + return() + endif() + string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" ${var_name} "${${var_name}}") + set(${var_name} "${${var_name}}" PARENT_SCOPE) + set_property(CACHE ${var_name} PROPERTY VALUE "${${var_name}}") endfunction() set_default_config(RelWithDebInfo) From fabf4ff237ff99d5e77163fdfbac6cd425dd7fc7 Mon Sep 17 00:00:00 2001 From: William Casarin Date: Thu, 8 May 2025 22:01:12 -0700 Subject: [PATCH 039/314] tracing: fix invalid argument in mempool_monitor The mempool_monitor tracing tool is incorrectly reading the reason as the first argument. Fix this! Github-Pull: #32454 Rebased-From: 31c5ebc4007884b655f2f90ca09e36e0b9ada4da --- contrib/tracing/mempool_monitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/tracing/mempool_monitor.py b/contrib/tracing/mempool_monitor.py index 7c184cce46e..22efa91783f 100755 --- a/contrib/tracing/mempool_monitor.py +++ b/contrib/tracing/mempool_monitor.py @@ -80,7 +80,7 @@ void *phash = NULL, *preason = NULL; bpf_usdt_readarg(1, ctx, phash); bpf_probe_read_user(&removed.hash, sizeof(removed.hash), phash); - bpf_usdt_readarg(1, ctx, preason); + bpf_usdt_readarg(2, ctx, preason); bpf_probe_read_user_str(&removed.reason, sizeof(removed.reason), preason); bpf_usdt_readarg(3, ctx, &removed.vsize); bpf_usdt_readarg(4, ctx, &removed.fee); @@ -95,7 +95,7 @@ void *phash = NULL, *preason = NULL; bpf_usdt_readarg(1, ctx, phash); bpf_probe_read_user(&rejected.hash, sizeof(rejected.hash), phash); - bpf_usdt_readarg(1, ctx, preason); + bpf_usdt_readarg(2, ctx, preason); bpf_probe_read_user_str(&rejected.reason, sizeof(rejected.reason), preason); rejected_events.perf_submit(ctx, &rejected, sizeof(rejected)); return 0; From caec3cc41bf3cb265800624efff14241d297f36b Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 7 May 2025 11:15:59 +0100 Subject: [PATCH 040/314] crypto: disable ASan for sha256_sse4 with Clang This can alsofail to compile when optimisations are being used, see: https://github.com/bitcoin/bitcoin/issues/31913. So disable just ASan for this function under any optimisation level. Github-Pull: #32437 Rebased-From: 4e8ab5e00fa72016a7ec0e0505ca025d4e59e4d8 --- src/crypto/sha256_sse4.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/crypto/sha256_sse4.cpp b/src/crypto/sha256_sse4.cpp index f0e255a23cb..f68e226138e 100644 --- a/src/crypto/sha256_sse4.cpp +++ b/src/crypto/sha256_sse4.cpp @@ -13,13 +13,17 @@ namespace sha256_sse4 { void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks) -#if defined(__clang__) && !defined(__OPTIMIZE__) +#if defined(__clang__) /* clang is unable to compile this with -O0 and -fsanitize=address. - See upstream bug: https://github.com/llvm/llvm-project/issues/92182 + See upstream bug: https://github.com/llvm/llvm-project/issues/92182. + This also fails to compile with -O2, -fcf-protection & -fsanitize=address. + See https://github.com/bitcoin/bitcoin/issues/31913. */ +#if __has_feature(address_sanitizer) __attribute__((no_sanitize("address"))) #endif +#endif { static const uint32_t K256 alignas(16) [] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, From cc2fcdfc5e0649c2e7c16c0ec2df7a40e8a3c454 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 11 May 2025 17:06:01 +0100 Subject: [PATCH 041/314] cmake: Allow `WITH_DBUS` on all Unix-like systems This change makes the `WITH_DBUS` option available on all Unix-like systems, not just Linux, thereby fixing a regression that was overlooked during the migration from Autotools. Note: Enabling D-Bus support on macOS still makes no sense, since the `Notificator` class uses the User Notification Center regardless. Github-Pull: #32469 Rebased-From: 5b7ed460c7c181f1fd34a927a09aed36284083cb --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e83a30ed1e8..69683c24ebf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,7 +157,7 @@ if(WITH_QRENCODE) set(USE_QRCODE TRUE) endif() -cmake_dependent_option(WITH_DBUS "Enable DBus support." ON "CMAKE_SYSTEM_NAME STREQUAL \"Linux\" AND BUILD_GUI" OFF) +cmake_dependent_option(WITH_DBUS "Enable DBus support." ON "NOT CMAKE_SYSTEM_NAME MATCHES \"(Windows|Darwin)\" AND BUILD_GUI" OFF) option(WITH_MULTIPROCESS "Build multiprocess bitcoin-node and bitcoin-gui executables in addition to monolithic bitcoind and bitcoin-qt executables. Requires libmultiprocess library. Experimental." OFF) if(WITH_MULTIPROCESS) @@ -664,7 +664,7 @@ message(" external signer ..................... ${ENABLE_EXTERNAL_SIGNER}") message(" ZeroMQ .............................. ${WITH_ZMQ}") message(" USDT tracing ........................ ${WITH_USDT}") message(" QR code (GUI) ....................... ${WITH_QRENCODE}") -message(" DBus (GUI, Linux only) .............. ${WITH_DBUS}") +message(" DBus (GUI) .......................... ${WITH_DBUS}") message("Tests:") message(" test_bitcoin ........................ ${BUILD_TESTS}") message(" test_bitcoin-qt ..................... ${BUILD_GUI_TESTS}") From edd4073d70642b42cea9a9e5a2c6d34f413cf7d8 Mon Sep 17 00:00:00 2001 From: enoch Date: Mon, 21 Apr 2025 16:03:19 +0100 Subject: [PATCH 042/314] test: Fix nTimes typo in feature_pruning test Fix incorrect variable name in comment (nTimes -> nTime) in feature_pruning.py. This typo caused the test to always reset mine_large_blocks.nTime to 0, rather than only on the first run as intended. Github-Pull: #32312 Rebased-From: 772ba7f9ce09e836a51636524a8a96a23946d658 --- test/functional/feature_pruning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py index 8d924282cfc..eeb2a78ba6f 100755 --- a/test/functional/feature_pruning.py +++ b/test/functional/feature_pruning.py @@ -41,7 +41,7 @@ def mine_large_blocks(node, n): # Set the nTime if this is the first time this function has been called. # A static variable ensures that time is monotonicly increasing and is therefore # different for each block created => blockhash is unique. - if "nTimes" not in mine_large_blocks.__dict__: + if "nTime" not in mine_large_blocks.__dict__: mine_large_blocks.nTime = 0 # Get the block parameters for the first block From 6c4e3de2acb7e96ce81ca691a4dac3d5d594c4bc Mon Sep 17 00:00:00 2001 From: enoch Date: Mon, 21 Apr 2025 16:04:25 +0100 Subject: [PATCH 043/314] test: Use uninvolved pruned node in feature_pruning undo test After fixing the nTime variable name, the test_pruneheight_undo_presence test began failing because node 2, which is involved in reorg testing, could be on a different chain than other nodes. This caused failures when trying to fetch blocks from other nodes that didn't recognize node 2's chain. Switch to using node 5 instead, which is also a pruned node but isn't involved in reorg testing, ensuring it stays on the same chain as the other nodes. This allows the block fetching to work as intended in the test. Github-Pull: #32312 Rebased-From: 2aa63d511affdcc9980b58fc4ff18b8ad10b0f8c --- test/functional/feature_pruning.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py index eeb2a78ba6f..02f1191ffef 100755 --- a/test/functional/feature_pruning.py +++ b/test/functional/feature_pruning.py @@ -500,11 +500,11 @@ def test_scanblocks_pruned(self): "start", [{"desc": f"raw({false_positive_spk.hex()})"}], 0, 0, "basic", {"filter_false_positives": True}) def test_pruneheight_undo_presence(self): - node = self.nodes[2] + node = self.nodes[5] pruneheight = node.getblockchaininfo()["pruneheight"] fetch_block = node.getblockhash(pruneheight - 1) - self.connect_nodes(1, 2) + self.connect_nodes(1, 5) peers = node.getpeerinfo() node.getblockfrompeer(fetch_block, peers[0]["id"]) self.wait_until(lambda: not try_rpc(-1, "Block not available (pruned data)", node.getblock, fetch_block), timeout=5) From c9661584261b89d75d4d0869c69ef84cf51054ff Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Mon, 12 May 2025 16:26:17 -0400 Subject: [PATCH 044/314] test: Fix intermittent failure in wallet_basic.py There could be a race with outstanding TxAddedToMempool notifications being applied to the soon-to-be created wallet. Fixes an intermittent timeout reproducable by adding a sleep to AddToWallet. Github-Pull: #32483 Rebased-From: 07350e204dedfba20da461d9cdcd469dc95e01c3 --- test/functional/wallet_basic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index c968e4333a0..a4e3673040b 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -726,6 +726,8 @@ def run_test(self): txid_a = self.nodes[0].sendtoaddress(addr_a, 0.01) txid_b = self.nodes[0].sendtoaddress(addr_b, 0.01) self.generate(self.nodes[0], 1, sync_fun=self.no_op) + # Prevent race of listunspent with outstanding TxAddedToMempool notifications + self.nodes[0].syncwithvalidationinterfacequeue() # Now import the descriptors, make sure we can identify on which descriptor each coin was received. self.nodes[0].createwallet(wallet_name="wo", descriptors=True, disable_private_keys=True) wo_wallet = self.nodes[0].get_wallet_rpc("wo") From cf034172bf1fe7cc789c130f35ad470f0509d6d2 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Tue, 13 May 2025 11:40:42 -0400 Subject: [PATCH 045/314] test: fix another intermittent failure in wallet_basic.py During init, the test framework will start using rpc after the mempool was loaded. It will not wait for postInitProcess or outstanding transactionAddedToMempool notifications, leading to a possible race, in which listunspent is being called while the tx is still in Inactive status. Prevent this by processing outstanding notifications. Github-Pull: #32483 Rebased-From: e7ad86e1ca3b0b2f2795e91c2f9959486c67dd90 --- test/functional/wallet_basic.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index a4e3673040b..c228c8b5015 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -779,6 +779,9 @@ def run_test(self): # check that it works again with -spendzeroconfchange set (=default) self.restart_node(0, ["-spendzeroconfchange=1"]) + # Make sure the wallet knows the tx in the mempool + self.nodes[0].syncwithvalidationinterfacequeue() + zeroconf_wallet = self.nodes[0].get_wallet_rpc("zeroconf") utxos = zeroconf_wallet.listunspent(minconf=0) assert_equal(len(utxos), 1) From 25aa15ee7fc6d8f941fff7be5b3abed09a2ce12a Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Sun, 18 May 2025 11:39:51 -0700 Subject: [PATCH 046/314] walletdb: Log the wallet version after it has been read from disk Logging the wallet version before anything has been read from disk results in the wrong version being logged. Also split the last client version logging as it may not always be present to be logged. Github-Pull: #32553 Rebased-From: 359ecd3704993422eb53e3da2a7d0bea2f575ab0 --- src/wallet/walletdb.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index c939ebb1fd4..981f8c61617 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -471,6 +471,7 @@ static DBErrors LoadMinVersion(CWallet* pwallet, DatabaseBatch& batch) EXCLUSIVE AssertLockHeld(pwallet->cs_wallet); int nMinVersion = 0; if (batch.Read(DBKeys::MINVERSION, nMinVersion)) { + pwallet->WalletLogPrintf("Wallet file version = %d\n", nMinVersion); if (nMinVersion > FEATURE_LATEST) return DBErrors::TOO_NEW; pwallet->LoadMinVersion(nMinVersion); @@ -1181,7 +1182,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet) // Last client version to open this wallet int last_client = CLIENT_VERSION; bool has_last_client = m_batch->Read(DBKeys::VERSION, last_client); - pwallet->WalletLogPrintf("Wallet file version = %d, last client version = %d\n", pwallet->GetVersion(), last_client); + if (has_last_client) pwallet->WalletLogPrintf("Last client version = %d\n", last_client); try { if ((result = LoadMinVersion(pwallet, *m_batch)) != DBErrors::LOAD_OK) return result; From e685b4eca250a47e933c8447a2efe10cd14d2f2b Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Sun, 18 May 2025 11:55:18 -0700 Subject: [PATCH 047/314] test: Check that the correct versions are logged on wallet load Github-Pull: #32553 Rebased-From: 39a483c8e9dcfe8ec243fa72269e1df9e75059ab --- test/functional/wallet_createwallet.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/functional/wallet_createwallet.py b/test/functional/wallet_createwallet.py index 0232af1658f..1f74809ae98 100755 --- a/test/functional/wallet_createwallet.py +++ b/test/functional/wallet_createwallet.py @@ -188,6 +188,18 @@ def run_test(self): "warnings": [EMPTY_PASSPHRASE_MSG, LEGACY_WALLET_MSG], }) + self.log.info("Check that the version number is being logged correctly") + node.createwallet("version_check") + wallet = node.get_wallet_rpc("version_check") + wallet_version = wallet.getwalletinfo()["walletversion"] + client_version = node.getnetworkinfo()["version"] + wallet.unloadwallet() + with node.assert_debug_log( + expected_msgs=[f"Last client version = {client_version}", f"Wallet file version = {wallet_version}"], + unexpected_msgs=["Wallet file version = 10500"] + ): + node.loadwallet("version_check") + if __name__ == '__main__': CreateWalletTest(__file__).main() From 6c0f26d3bd8010391761feada93ae902b6b27221 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Sun, 18 May 2025 11:58:40 -0700 Subject: [PATCH 048/314] test: check that creating a wallet does not log version info Github-Pull: #32553 Rebased-From: 4b2cd0b41ff4800c8801f2c44883eaec60a035fa --- test/functional/wallet_createwallet.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/wallet_createwallet.py b/test/functional/wallet_createwallet.py index 1f74809ae98..06386bbbe98 100755 --- a/test/functional/wallet_createwallet.py +++ b/test/functional/wallet_createwallet.py @@ -189,7 +189,8 @@ def run_test(self): }) self.log.info("Check that the version number is being logged correctly") - node.createwallet("version_check") + with node.assert_debug_log(expected_msgs=[], unexpected_msgs=["Last client version = ", "Wallet file version = "]): + node.createwallet("version_check") wallet = node.get_wallet_rpc("version_check") wallet_version = wallet.getwalletinfo()["walletversion"] client_version = node.getnetworkinfo()["version"] From a0d1f69b555fa0c76df1a63a0b127c7816596107 Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 17 Apr 2025 11:45:06 +0100 Subject: [PATCH 049/314] doc: update release notes for 29.x --- doc/release-notes.md | 224 ++++++------------------------------------- 1 file changed, 30 insertions(+), 194 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 1a6fe22459e..0678887279f 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.0 is now available from: +Bitcoin Core version 29.x is now available from: - + This release includes new features, various bug fixes and performance improvements, as well as updated translations. @@ -37,226 +37,62 @@ unsupported systems. Notable changes =============== -### P2P and Network Changes +### Wallet -- Support for UPnP was dropped. If you want to open a port automatically, consider using the `-natpmp` -option instead, which uses PCP or NAT-PMP depending on router support. (#31130) +- #32553 wallet: Fix logging of wallet version -- libnatpmp was replaced with a built-in implementation of PCP and NAT-PMP (still enabled using the `-natpmp` option). This supports automatic IPv4 port forwarding as well as IPv6 pinholing. (#30043) +### Test -- When the `-port` configuration option is used, the default onion listening port will now -be derived to be that port + 1 instead of being set to a fixed value (8334 on mainnet). -This re-allows setups with multiple local nodes using different `-port` and not using `-bind`, -which would lead to a startup failure in v28.0 due to a port collision. -Note that a `HiddenServicePort` manually configured in `torrc` may need adjustment if used in -connection with the `-port` option. -For example, if you are using `-port=5555` with a non-standard value and not using `-bind=...=onion`, -previously Bitcoin Core would listen for incoming Tor connections on `127.0.0.1:8334`. -Now it would listen on `127.0.0.1:5556` (`-port` plus one). If you configured the hidden service manually -in torrc now you have to change it from `HiddenServicePort 8333 127.0.0.1:8334` to `HiddenServicePort 8333 -127.0.0.1:5556`, or configure bitcoind with `-bind=127.0.0.1:8334=onion` to get the previous behavior. -(#31223) +- #32286 test: Handle empty string returned by CLI as None in RPC tests +- #32312 test: Fix feature_pruning test after nTime typo fix +- #32336 test: Suppress upstream -Wduplicate-decl-specifier in bpfcc +- #32483 test: fix two intermittent failures in wallet_basic.py -- Upon receiving an orphan transaction (an unconfirmed transaction that spends unknown inputs), the node will attempt to download missing parents from all peers who announced the orphan. This change may increase bandwidth usage but make orphan-handling more reliable. (#31397) +### Util -### Mempool Policy and Mining Changes +- #32248 Remove support for RNDR/RNDRRS for aarch64 -- Ephemeral dust is a new concept that allows a single -dust output in a transaction, provided the transaction -is zero fee. In order to spend any unconfirmed outputs -from this transaction, the spender must also spend -this dust in addition to any other desired outputs. -In other words, this type of transaction -should be created in a transaction package where -the dust is both created and spent simultaneously. (#30239) +### Build -- Due to a bug, the default block reserved weight (`4,000 WU`) for fixed-size block header, transactions count, and coinbase transaction was reserved twice and could not be lowered. As a result the total reserved weight was always `8,000 WU`, meaning that even when specifying a `-blockmaxweight` higher than the default (even to the max of `4,000,000 WU`), the actual block size will never exceed `3,992,000 WU`. -The fix consolidates the reservation into a single place and introduces a new startup option, `-blockreservedweight` which specifies the reserved weight directly. The default value of `-blockreservedweight` is set to `8,000 WU` to ensure backward compatibility for users who relied on the previous behavior of `-blockmaxweight`. -The minimum value of `-blockreservedweight` is set to `2,000 WU`. Users setting `-blockreservedweight` below the default should ensure that the total weight of their block header, transaction count, and coinbase transaction does not exceed the reduced value or they may risk mining an invalid block. (#31384) +- #32356 cmake: Respect user-provided configuration-specific flags +- #32437 crypto: disable ASan for sha256_sse4 with Clang +- #32469 cmake: Allow WITH_DBUS on all Unix-like systems -### Updated RPCs +### Gui -- The RPC `testmempoolaccept` response now includes a `reject-details` field in some cases, -similar to the complete error messages returned by `sendrawtransaction` (#28121) +- #864 Crash fix, disconnect numBlocksChanged() signal during shutdown +- #868 Replace stray tfm::format to cerr with qWarning -- Duplicate blocks submitted with `submitblock` will now persist their block data -even if it was previously pruned. If pruning is activated, the data will be -pruned again eventually once the block file it is persisted in is selected for -pruning. This is consistent with the behaviour of `getblockfrompeer` where the -block is persisted as well even when pruning. (#31175) +### Doc -- `getmininginfo` now returns `nBits` and the current target in the `target` field. It also returns a `next` object which specifies the `height`, `nBits`, `difficulty`, and `target` for the next block. (#31583) +- #32353 doc: Fix fuzz test_runner.py path +- #32389 doc: Fix test_bitcoin path -- `getblock` and `getblockheader` now return the current target in the `target` field (#31583) +### CI -- `getblockchaininfo` and `getchainstates` now return `nBits` and the current target in the `target` field (#31583) +- #32184 ci: Add workaround for vcpkg's libevent package -- the `getblocktemplate` RPC `curtime` (BIP22) and `mintime` (BIP23) fields now - account for the timewarp fix proposed in BIP94 on all networks. This ensures - that, in the event a timewarp fix softfork activates on mainnet, un-upgraded - miners will not accidentally violate the timewarp rule. (#31376, #31600) -As a reminder, it's important that any software which uses the `getblocktemplate` -RPC takes these values into account (either `curtime` or `mintime` is fine). -Relying only on a clock can lead to invalid blocks under some circumstances, -especially once a timewarp fix is deployed. (#31600) +### Misc -### New RPCs - -- `getdescriptoractivity` can be used to find all spend/receive activity relevant to - a given set of descriptors within a set of specified blocks. This call can be used with - `scanblocks` to lessen the need for additional indexing programs. (#30708) - - -### Updated REST APIs - -- `GET /rest/block/.json` and `GET /rest/headers/.json` now return the current target in the `target` field - -### Updated Settings - -- The maximum allowed value for the `-dbcache` configuration option has been - dropped due to recent UTXO set growth. Note that before this change, large `-dbcache` - values were automatically reduced to 16 GiB (1 GiB on 32 bit systems). (#28358) - -- Handling of negated `-noseednode`, `-nobind`, `-nowhitebind`, `-norpcbind`, `-norpcallowip`, `-norpcwhitelist`, `-notest`, `-noasmap`, `-norpcwallet`, `-noonlynet`, and `-noexternalip` options has changed. Previously negating these options had various confusing and undocumented side effects. Now negating them just resets the settings and restores default behaviors, as if the options were not specified. - -- Starting with v28.0, the `-mempoolfullrbf` startup option was set to -default to `1`. With widespread adoption of this policy, users no longer -benefit from disabling it, so the option has been removed, making full -replace-by-fee the standard behavior. (#30592) - -- Setting `-upnp` will now log a warning and be interpreted as `-natpmp`. Consider using `-natpmp` directly instead. (#31130, #31916) - -- As a safety check, Bitcoin core will **fail to start** when `-blockreservedweight` init parameter value is lower than `2000` weight units. Bitcoin Core will also **fail to start** if the `-blockmaxweight` or `-blockreservedweight` init parameter exceeds consensus limit of `4,000,000 WU`. - -- Passing `-debug=0` or `-debug=none` now behaves like `-nodebug`: previously set debug categories will be cleared, but subsequent `-debug` options will still be applied. - -- The default for `-rpcthreads` has been changed from 4 to 16, and the default for `-rpcworkqueue` has been changed from 16 to 64. (#31215). - -### Build System - -The build system has been migrated from Autotools to CMake: - -1. The minimum required CMake version is 3.22. -2. In-source builds are not allowed. When using a subdirectory within the root source tree as a build directory, it is recommended that its name includes the substring "build". -3. CMake variables may be used to configure the build system. See [Autotools to CMake Options Mapping](https://github.com/bitcoin-core/bitcoin-devwiki/wiki/Autotools-to-CMake-Options-Mapping) for details. -4. For single-configuration generators, the default build configuration (`CMAKE_BUILD_TYPE`) is "RelWithDebInfo". However, for the "Release" configuration, CMake defaults to the compiler optimization flag `-O3`, which has not been extensively tested with Bitcoin Core. Therefore, the build system replaces it with `-O2`. -5. By default, the built executables and libraries are located in the `bin/` and `lib/` subdirectories of the build directory. -6. The build system supports component‐based installation. The names of the installable components coincide with the build target names. For example: -``` -cmake -B build -cmake --build build --target bitcoind -cmake --install build --component bitcoind -``` - -7. If any of the `CPPFLAGS`, `CFLAGS`, `CXXFLAGS` or `LDFLAGS` environment variables were used in your Autotools-based build process, you should instead use the corresponding CMake variables (`APPEND_CPPFLAGS`, `APPEND_CFLAGS`, `APPEND_CXXFLAGS` and `APPEND_LDFLAGS`). Alternatively, if you opt to use the dedicated `CMAKE_<...>_FLAGS` variables, you must ensure that the resulting compiler or linker invocations are as expected. - -For more detailed guidance on configuring and using CMake, please refer to the official [CMake documentation](https://cmake.org/cmake/help/latest/) and [CMake’s User Interaction Guide](https://cmake.org/cmake/help/latest/guide/user-interaction/index.html). Additionally, consult platform-specific `doc/build-*.md` build guides for instructions tailored to your operating system. - -## Low-Level Changes - -### Tools and Utilities - -- A new tool [`utxo_to_sqlite.py`](/contrib/utxo-tools/utxo_to_sqlite.py) - converts a compact-serialized UTXO snapshot (as created with the - `dumptxoutset` RPC) to a SQLite3 database. Refer to the script's `--help` - output for more details. (#27432) - -### Tests - -- The BIP94 timewarp attack mitigation (designed for testnet4) is no longer active on the regtest network. (#31156) - -### Dependencies - -- MiniUPnPc and libnatpmp have been removed as dependencies (#31130, #30043). +- #32187 refactor: Remove spurious virtual from final ~CZMQNotificationInterface +- #32454 tracing: fix invalid argument in mempool_monitor Credits ======= Thanks to everyone who directly contributed to this release: -- 0xb10c -- Adlai Chandrasekhar -- Afanti -- Alfonso Roman Zubeldia -- am-sq -- Andre -- Andre Alves -- Anthony Towns -- Antoine Poinsot -- Ash Manning -- Ava Chow -- Boris Nagaev +- achow101 - Brandon Odiwuor -- brunoerg -- Chris Stewart -- Cory Fields -- costcould -- Daniel Pfeifer -- Daniela Brozzoni -- David Gumberg -- dergoegge -- epysqyli -- espi3 -- Eval EXEC -- Fabian Jahr +- enirox001 - fanquake - furszy -- Gabriele Bocchi -- glozow -- Greg Sanders -- Gutflo - Hennadii Stepanov -- Hodlinator -- i-am-yuvi -- ion- -- ismaelsadeeq -- Jadi -- James O'Beirne -- Jeremy Rand -- Jon Atack -- jurraca -- Kay -- kevkevinpal -- l0rinc +- jb55 - laanwj -- Larry Ruane -- Lőrinc -- Maciej S. Szmigiero -- Mackain - MarcoFalke -- marcofleon -- Marnix -- Martin Leitner-Ankerl -- Martin Saposnic - Martin Zumsande -- Matthew Zipkin -- Max Edwards -- Michael Dietz -- naiyoma -- Nicola Leonardo Susca -- omahs -- pablomartin4btc -- Pieter Wuille -- Randall Naar -- RiceChuan -- rkrux -- Roman Zeyde -- Ryan Ofsky -- Sebastian Falbesoner -- secp512k2 -- Sergi Delgado Segura -- Simon -- Sjors Provoost -- stickies-v -- Suhas Daftuar -- tdb3 -- TheCharlatan -- tianzedavid -- Torkel Rogstad -- Vasil Dimov -- wgyt -- willcl-ark -- yancy +- monlovesmango As well as to everyone that helped with translations on [Transifex](https://www.transifex.com/bitcoin/bitcoin/). From 142153ee42747677db3c9d8bdb75ec5bd4cecc18 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 18 May 2025 14:45:55 +0100 Subject: [PATCH 050/314] cmake: Add missed `SSE41_CXXFLAGS` Github-Pull: #32551 Rebased-From: 800b7cc42ca63f2a6b245a4d327c7092289da6e1 --- src/crypto/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index 1109806a776..92653ade5a7 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -47,7 +47,7 @@ if(HAVE_SSE41 AND HAVE_X86_SHANI) target_compile_definitions(bitcoin_crypto PRIVATE ENABLE_SSE41 ENABLE_X86_SHANI) target_sources(bitcoin_crypto PRIVATE sha256_x86_shani.cpp) set_property(SOURCE sha256_x86_shani.cpp PROPERTY - COMPILE_OPTIONS ${X86_SHANI_CXXFLAGS} + COMPILE_OPTIONS ${SSE41_CXXFLAGS} ${X86_SHANI_CXXFLAGS} ) endif() From e34b6fbcad6d8a2a58713d86c9ff646a0d2f2890 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 7 May 2025 17:23:23 +0100 Subject: [PATCH 051/314] guix: accomodate migration to codeberg See https://guix.gnu.org/blog/2025/migrating-to-codeberg/. When interacting with the old repo you may now also see: ```bash warning: redirecting to https://codeberg.org/guix/guix/ ``` Github-Pull: #32439 Rebased-From: c8d9baae942c94d64ce47ae8f67d3710e6a296bd --- contrib/guix/INSTALL.md | 8 ++++---- contrib/guix/libexec/prelude.bash | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/guix/INSTALL.md b/contrib/guix/INSTALL.md index 515d4487d6e..910f8f25460 100644 --- a/contrib/guix/INSTALL.md +++ b/contrib/guix/INSTALL.md @@ -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 diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash index 428fc41e739..f7fc932dfd3 100644 --- a/contrib/guix/libexec/prelude.bash +++ b/contrib/guix/libexec/prelude.bash @@ -50,7 +50,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=53396a22afc04536ddf75d8f82ad2eafa5082725 \ --cores="$JOBS" \ --keep-failed \ From 17b31fc80209ecd8ba0410553ca0458049b26e6a Mon Sep 17 00:00:00 2001 From: nervana21 <205626986+nervana21@users.noreply.github.com> Date: Sun, 27 Apr 2025 22:06:40 -0400 Subject: [PATCH 052/314] doc: Add missing top-level description to pruneblockchain RPC Previously, the `pruneblockchain` RPC help output included only the method signature and arguments, with no top-level description explaining its purpose or constraints. This PR adds a concise top-level description, improving documentation consistency and alerting users to the potential impacts of using the command. Github-Pull: #32333 Rebased-From: 135a0f0aa711b95c50aa4cbe0c38d82d647f1c8b --- src/rpc/blockchain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index ac1ce6285f7..2c4e471babf 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -838,7 +838,9 @@ std::optional GetPruneHeight(const BlockManager& blockman, const CChain& ch static RPCHelpMan pruneblockchain() { - return RPCHelpMan{"pruneblockchain", "", + return RPCHelpMan{"pruneblockchain", + "Attempts to delete block and undo data up to a specified height or timestamp, if eligible for pruning.\n" + "Requires `-prune` to be enabled at startup. While pruned data may be re-fetched in some cases (e.g., via `getblockfrompeer`), local deletion is irreversible.\n", { {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block height to prune up to. May be set to a discrete height, or to a " + UNIX_EPOCH_TIME + "\n" " to prune blocks whose block time is at least 2 hours older than the provided timestamp."}, From 646fa1d028f091e281b7e9b0c45ca1040f4441d8 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Wed, 28 May 2025 10:59:10 -0400 Subject: [PATCH 053/314] test: fix sync function in rpc_psbt.py It currently only syncs between the first two nodes, which may do nothing when the block is created on the third node. Github-Pull: #32630 Rebased-From: 4df4df45d7bc2e8be99325d40cda936aab87c083 --- test/functional/rpc_psbt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index 8042bdf0715..f1c83b869b1 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -79,7 +79,7 @@ def test_psbt_incomplete_after_invalid_modification(self): wallet = node.get_wallet_rpc(self.default_wallet_name) address = wallet.getnewaddress() wallet.sendtoaddress(address=address, amount=1.0) - self.generate(node, nblocks=1, sync_fun=lambda: self.sync_all(self.nodes[:2])) + self.generate(node, nblocks=1) utxos = wallet.listunspent(addresses=[address]) psbt = wallet.createpsbt([{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}], [{wallet.getnewaddress(): 0.9999}]) From 4a1143b083db87b6bbe158b97a4912fe73f76d09 Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 20 May 2025 10:45:06 +0100 Subject: [PATCH 054/314] depends: use "mkdir -p" when installing xproto It looks like the mkdir detection in xproto is broken on Alpine. Ensure we always use `mkdir -p`. Fixes #32494. Github-Pull: #32568 Rebased-From: df9ebbf659d5d1282289f36d7f9ee7103aa33a17 --- depends/packages/xproto.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk index 29c349a21b5..0a534556ee4 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -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 From 247ee59f55cee2c6ee19203fa1d274efba054e7f Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Wed, 4 Jun 2025 17:56:06 +0100 Subject: [PATCH 055/314] doc: update tor docs to use bitcoind binary from path Github-Pull: #32679 Rebased-From: 4ce53495e5e18370b7935551b3b8700faa720a33 --- doc/tor.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/tor.md b/doc/tor.md index 30c2381049a..30eddb91e32 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -62,7 +62,7 @@ outgoing connections, but more is possible. In a typical situation, this suffices to run behind a Tor proxy: - ./bitcoind -proxy=127.0.0.1:9050 + bitcoind -proxy=127.0.0.1:9050 ## 2. Automatically create a Bitcoin Core onion service @@ -187,25 +187,25 @@ should be equal to binding address and port for inbound Tor connections (127.0.0 In a typical situation, where you're only reachable via Tor, this should suffice: - ./bitcoind -proxy=127.0.0.1:9050 -externalip=7zvj7a2imdgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -listen + bitcoind -proxy=127.0.0.1:9050 -externalip=7zvj7a2imdgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -listen (obviously, replace the .onion address with your own). It should be noted that you still listen on all devices and another node could establish a clearnet connection, when knowing your address. To mitigate this, additionally bind the address of your Tor proxy: - ./bitcoind ... -bind=127.0.0.1:8334=onion + bitcoind ... -bind=127.0.0.1:8334=onion If you don't care too much about hiding your node, and want to be reachable on IPv4 as well, use `discover` instead: - ./bitcoind ... -discover + bitcoind ... -discover and open port 8333 on your firewall (or use port mapping, i.e., `-natpmp`). If you only want to use Tor to reach .onion addresses, but not use it as a proxy for normal IPv4/IPv6 communication, use: - ./bitcoind -onion=127.0.0.1:9050 -externalip=7zvj7a2imdgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -discover + bitcoind -onion=127.0.0.1:9050 -externalip=7zvj7a2imdgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -discover ## 4. Privacy recommendations From c899334e36b63b530c44fe7273c951469762878c Mon Sep 17 00:00:00 2001 From: benthecarman Date: Fri, 23 May 2025 17:28:26 -0500 Subject: [PATCH 056/314] rpc: Note in fundrawtransaction doc, fee rate is for package Github-Pull: #32607 Rebased-From: f98e1aaf34e347088caa54403521e3b5cb55dd40 --- src/wallet/rpc/spend.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index 0cba830e2ab..64aae701ebc 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -749,7 +749,10 @@ RPCHelpMan fundrawtransaction() "Note that all inputs selected must be of standard form and P2SH scripts must be\n" "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n" - "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n", + "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only.\n" + "Note that if specifying an exact fee rate, the resulting transaction may have a higher fee rate\n" + "if the transaction has unconfirmed inputs. This is because the wallet will attempt to make the\n" + "entire package have the given fee rate, not the resulting transaction.\n", { {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"}, {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "For backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}", From 78688c84139b3e96148b17a4133e330bf8937c03 Mon Sep 17 00:00:00 2001 From: rkrux Date: Mon, 9 Jun 2025 15:11:42 +0530 Subject: [PATCH 057/314] rpc, doc: update `listdescriptors` RCP help This RPC lists all the descriptors present in the wallet, not only the ones that were imported, but also the ones generated when a new wallet is created. It can be verified by creating a new wallet and calling the `listdescriptors` RPC, which will contain 8 ranged descriptors that are created for every new wallet. Github-Pull: #32708 Rebased-From: b44514b876333a94ae242da8b1e4cee439c2d37e --- src/wallet/rpc/backup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp index ac23b092d40..64f3f95a178 100644 --- a/src/wallet/rpc/backup.cpp +++ b/src/wallet/rpc/backup.cpp @@ -1781,7 +1781,7 @@ RPCHelpMan listdescriptors() { return RPCHelpMan{ "listdescriptors", - "\nList descriptors imported into a descriptor-enabled wallet.\n", + "\nList all descriptors present in a descriptor-enabled wallet.\n", { {"private", RPCArg::Type::BOOL, RPCArg::Default{false}, "Show private descriptors."} }, From 876a7b2db5273ef8f6864bef9c304d36047409f4 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Mon, 9 Jun 2025 14:29:00 +0200 Subject: [PATCH 058/314] doc: add missing packages for BSDs (cmake, gmake, curl) to depends/README.md Github-Pull: #32711 Rebased-From: 89526deddf87904619b26319e8d149cf97466868 --- depends/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/README.md b/depends/README.md index 848137f03fa..e0aef7c1789 100644 --- a/depends/README.md +++ b/depends/README.md @@ -90,15 +90,15 @@ For linux S390X cross compilation: ### Install the required dependencies: FreeBSD - pkg install bash + pkg install bash cmake curl gmake ### Install the required dependencies: NetBSD - pkgin install bash gmake + pkgin install bash cmake curl gmake perl ### Install the required dependencies: OpenBSD - pkg_add bash gmake gtar + pkg_add bash cmake curl gmake gtar ### Dependency Options From 23e76ef520f5647993884e5affb54e33b9b66570 Mon Sep 17 00:00:00 2001 From: will Date: Wed, 4 Jun 2025 12:24:08 +0100 Subject: [PATCH 059/314] guix: warn and abort when SOURCE_DATE_EPOCH is set Current behaviour will by-default use SOURCE_DATE_EPOCH from the environment without warning. This breaks the default reproducibility from a guix build. Warn when and exit when this variable is set, and FORCE_SOURCE_DATE_EPOCH is unset. Github-Pull: #32678 Rebased-From: 5c4a0f8009cef758be9412428515bfed57b0c923 --- contrib/guix/guix-build | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index 2ea574fe4b9..715568c1543 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -69,6 +69,24 @@ fi mkdir -p "$VERSION_BASE" +################ +# SOURCE_DATE_EPOCH should not unintentionally be set +################ + +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 + ################ # Build directories should not exist ################ From aea8a394b1b9c595d6388b714145700dc63adfe6 Mon Sep 17 00:00:00 2001 From: Luis Schwab Date: Fri, 6 Jun 2025 19:40:57 -0300 Subject: [PATCH 060/314] doc: make `-DWITH_ZMQ=ON` explicit on `build-unix.md` Github-Pull: #32696 Rebased-From: 32d4e92b9ac81858d754487bfec2fef6bed13a57 --- doc/build-unix.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index d891aabc89f..85add7fa539 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -60,7 +60,7 @@ executables, which are based on BerkeleyDB 4.8. Otherwise, you can build Berkele To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode) -ZMQ dependencies (provides ZMQ API): +ZMQ-enabled binaries are compiled with `-DWITH_ZMQ=ON` and require the following dependency: sudo apt-get install libzmq3-dev @@ -108,7 +108,7 @@ are based on Berkeley DB 4.8. Otherwise, you can build Berkeley DB [yourself](#b To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode) -ZMQ dependencies (provides ZMQ API): +ZMQ-enabled binaries are compiled with `-DWITH_ZMQ=ON` and require the following dependency: sudo dnf install zeromq-devel From 1b51d750ad1384a67010d40d7a9f9a6b96a22e43 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Fri, 6 Jun 2025 01:48:41 +0200 Subject: [PATCH 061/314] depends: fix SHA256SUM command on OpenBSD (use GNU mode output) On OpenBSD, the `sha256` command by default outputs hashsums on files in "BSD" mode, looking like this: $ sha256 ~/.vimrc SHA256 (/home/thestack/.vimrc) = 6ba69d100e8c5ca0488ded6293d4e5f740a6a5d5ace96cbcf0599c18d27389e4 This is not compatible with our depends commands, which expect the hashes to be on the first column (to be extracted via `cut -d" " -f1`). Fix this by switching to GNU mode output, looking like this: $ sha256 -r ~/.vimrc 6ba69d100e8c5ca0488ded6293d4e5f740a6a5d5ace96cbcf0599c18d27389e4 /home/thestack/.vimrc Without this change, the multiprocess depends build fails with the following output: $ gmake -C depends MULTIPROCESS=1 NO_BOOST=1 NO_LIBEVENT=1 NO_QT=1 NO_QR=1 NO_WALLET=1 NO_ZMQ=1 NO_USDT=1 [ ..... ] Extracting native_libmultiprocess... sha256: /home/thestack/bitcoin/depends/work/build/x86_64-unknown-openbsd7.7/native_libmultiprocess/-2bc902f4693/.src-ipc-libmultiprocess.tar.hash: no properly formatted checksum lines found gmake: *** [funcs.mk:342: /home/thestack/bitcoin/depends/work/build/x86_64-unknown-openbsd7.7/native_libmultiprocess/-2bc902f4693/.stamp_extracted] Error 1 Github-Pull: #32690 Rebased-From: 8713e8060d504f561fed705b4aa5af7b96c36e75 --- depends/builders/openbsd.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/builders/openbsd.mk b/depends/builders/openbsd.mk index 9c94c4baae7..4b3214ae810 100644 --- a/depends/builders/openbsd.mk +++ b/depends/builders/openbsd.mk @@ -1,7 +1,7 @@ build_openbsd_CC = clang build_openbsd_CXX = clang++ -build_openbsd_SHA256SUM = sha256 +build_openbsd_SHA256SUM = sha256 -r build_openbsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o build_openbsd_TAR = gtar From 27c533052c307113bea548b7bcad40dbfd1fbcbe Mon Sep 17 00:00:00 2001 From: Hodlinator <172445034+hodlinator@users.noreply.github.com> Date: Tue, 10 Jun 2025 14:41:39 +0200 Subject: [PATCH 062/314] doc, windows: CompanyName "Bitcoin" => "Bitcoin Core project" Matches /share/setup.nsi.in:14 Github-Pull: #32719 Rebased-From: 239fc4d62e73511b3ef5117706d4c5131a921955 --- src/bitcoin-cli-res.rc | 2 +- src/bitcoin-tx-res.rc | 2 +- src/bitcoin-util-res.rc | 2 +- src/bitcoin-wallet-res.rc | 2 +- src/bitcoind-res.rc | 2 +- src/qt/res/bitcoin-qt-res.rc | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bitcoin-cli-res.rc b/src/bitcoin-cli-res.rc index e0d4ee5f3c4..dd7f01b1702 100644 --- a/src/bitcoin-cli-res.rc +++ b/src/bitcoin-cli-res.rc @@ -14,7 +14,7 @@ BEGIN BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN - VALUE "CompanyName", "Bitcoin" + VALUE "CompanyName", CLIENT_NAME " project" VALUE "FileDescription", "bitcoin-cli (JSON-RPC client for " CLIENT_NAME ")" VALUE "FileVersion", CLIENT_VERSION_STRING VALUE "InternalName", "bitcoin-cli" diff --git a/src/bitcoin-tx-res.rc b/src/bitcoin-tx-res.rc index d5d7e3b7ca2..77ffb6bdfa2 100644 --- a/src/bitcoin-tx-res.rc +++ b/src/bitcoin-tx-res.rc @@ -14,7 +14,7 @@ BEGIN BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN - VALUE "CompanyName", "Bitcoin" + VALUE "CompanyName", CLIENT_NAME " project" VALUE "FileDescription", "bitcoin-tx (CLI Bitcoin transaction editor utility)" VALUE "FileVersion", CLIENT_VERSION_STRING VALUE "InternalName", "bitcoin-tx" diff --git a/src/bitcoin-util-res.rc b/src/bitcoin-util-res.rc index e121d17f233..8dda22b77f0 100644 --- a/src/bitcoin-util-res.rc +++ b/src/bitcoin-util-res.rc @@ -14,7 +14,7 @@ BEGIN BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN - VALUE "CompanyName", "Bitcoin" + VALUE "CompanyName", CLIENT_NAME " project" VALUE "FileDescription", "bitcoin-util (CLI Bitcoin utility)" VALUE "FileVersion", CLIENT_VERSION_STRING VALUE "InternalName", "bitcoin-util" diff --git a/src/bitcoin-wallet-res.rc b/src/bitcoin-wallet-res.rc index 4c7895f48d1..cc3f272b3a9 100644 --- a/src/bitcoin-wallet-res.rc +++ b/src/bitcoin-wallet-res.rc @@ -14,7 +14,7 @@ BEGIN BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN - VALUE "CompanyName", "Bitcoin" + VALUE "CompanyName", CLIENT_NAME " project" VALUE "FileDescription", "bitcoin-wallet (CLI tool for " CLIENT_NAME " wallets)" VALUE "FileVersion", CLIENT_VERSION_STRING VALUE "InternalName", "bitcoin-wallet" diff --git a/src/bitcoind-res.rc b/src/bitcoind-res.rc index 4d689d7e16a..3a512c3db43 100644 --- a/src/bitcoind-res.rc +++ b/src/bitcoind-res.rc @@ -14,7 +14,7 @@ BEGIN BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN - VALUE "CompanyName", "Bitcoin" + VALUE "CompanyName", CLIENT_NAME " project" VALUE "FileDescription", "bitcoind (Bitcoin node with a JSON-RPC server)" VALUE "FileVersion", CLIENT_VERSION_STRING VALUE "InternalName", "bitcoind" diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc index 9a379f06d40..52cf91ffa8f 100644 --- a/src/qt/res/bitcoin-qt-res.rc +++ b/src/qt/res/bitcoin-qt-res.rc @@ -21,7 +21,7 @@ BEGIN BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN - VALUE "CompanyName", "Bitcoin" + VALUE "CompanyName", CLIENT_NAME " project" VALUE "FileDescription", CLIENT_NAME " (GUI node for Bitcoin)" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-qt" From 7264459c0df2b8dc0fa0d0ccab755b299878c588 Mon Sep 17 00:00:00 2001 From: josibake Date: Fri, 6 Jun 2025 16:51:36 +0200 Subject: [PATCH 063/314] build: patch cmake min version on freetype Patch cmake_minimum_required version for freetype, using the version from https://gitlab.freedesktop.org/freetype/freetype/-/merge_requests/352/diffs This fixes a failure when building with CMake 4, where compatibility with CMake versions < 3.5 has been removed (see https://cmake.org/cmake/help/latest/release/4.0.html#deprecated-and-removed-features) Github-Pull: #32693 Rebased-From: d7c37906e7b1dc1513439056d0cdb2bd341d00f1 --- depends/packages/freetype.mk | 5 +++++ depends/patches/freetype/cmake_minimum.patch | 13 +++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 depends/patches/freetype/cmake_minimum.patch diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index fef0beaa7b4..a97f82e7fea 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -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 diff --git a/depends/patches/freetype/cmake_minimum.patch b/depends/patches/freetype/cmake_minimum.patch new file mode 100644 index 00000000000..0a976f8ab8d --- /dev/null +++ b/depends/patches/freetype/cmake_minimum.patch @@ -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 From a18085a18bb58ef6d688889c6f2d9717d8581766 Mon Sep 17 00:00:00 2001 From: furszy Date: Wed, 29 Jan 2025 13:33:22 -0500 Subject: [PATCH 064/314] wallet: fix crash on double block disconnection The wallet crashes if it processes the same block disconnection event twice in a row due to an incompatible coinbase transaction state. This happens because 'disconnectBlock' provides 'TxStateInactive' without the "abandoned" flag for coinbase transactions to 'SyncTransaction', while 'AddToWallet()' internally modifies it to retain the abandoned state. The flow is as follows: 1) On the first disconnection, the transaction state transitions from "confirmed" to "inactive," bypassing the state equality check since the provided state differs. Then, 'AddToWallet' internally updates the state to "inactive + abandoned" 2) On the second disconnection, as we provide only the "inactive" state to 'SyncTransaction()', the state equality assertion fails and crashes the wallet. Github-Pull: #31757 Rebased-From: 9ef429b6ae65f6ad3e9ac11c2d9c0a6c52beb865 --- src/wallet/wallet.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 7abd17d31e9..09eda0c28e4 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1548,8 +1548,11 @@ void CWallet::blockDisconnected(const interfaces::BlockInfo& block) int disconnect_height = block.height; - for (const CTransactionRef& ptx : Assert(block.data)->vtx) { - SyncTransaction(ptx, TxStateInactive{}); + for (size_t index = 0; index < block.data->vtx.size(); index++) { + const CTransactionRef& ptx = Assert(block.data)->vtx[index]; + // Coinbase transactions are not only inactive but also abandoned, + // meaning they should never be relayed standalone via the p2p protocol. + SyncTransaction(ptx, TxStateInactive{/*abandoned=*/index == 0}); for (const CTxIn& tx_in : ptx->vin) { // No other wallet transactions conflicted with this transaction From 8246c6a65f5e17aeeb351a2d649799c216bbed63 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Tue, 18 Feb 2025 19:07:04 -0300 Subject: [PATCH 065/314] test: wallet, coverage for crash on dup block disconnection during unclean shutdown Co-authored-by: furszy Github-Pull: #31757 Rebased-From: 11f8ab140fe63857f6a93b81021efda8f90ceeda --- test/functional/wallet_reorgsrestore.py | 52 +++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/test/functional/wallet_reorgsrestore.py b/test/functional/wallet_reorgsrestore.py index a600930acd8..d9be3bd2e9a 100755 --- a/test/functional/wallet_reorgsrestore.py +++ b/test/functional/wallet_reorgsrestore.py @@ -19,6 +19,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, + assert_greater_than, assert_raises_rpc_error ) @@ -90,6 +91,54 @@ def test_coinbase_automatic_abandon_during_startup(self): # Verify the coinbase descendant was also marked as abandoned assert_equal(wallet0.gettransaction(descendant_tx_id)['details'][0]['abandoned'], True) + def test_reorg_handling_during_unclean_shutdown(self): + self.log.info("Test that wallet doesn't crash due to a duplicate block disconnection event after an unclean shutdown") + node = self.nodes[0] + # Receive coinbase reward on a new wallet + node.createwallet(wallet_name="reorg_crash", load_on_startup=True) + wallet = node.get_wallet_rpc("reorg_crash") + self.generatetoaddress(node, 1, wallet.getnewaddress(), sync_fun=self.no_op) + + # Restart to ensure node and wallet are flushed + self.restart_node(0) + wallet = node.get_wallet_rpc("reorg_crash") + assert_greater_than(wallet.getwalletinfo()['immature_balance'], 0) + + # Disconnect tip and sync wallet state + tip = wallet.getbestblockhash() + wallet.invalidateblock(tip) + wallet.syncwithvalidationinterfacequeue() + + # Tip was disconnected, ensure coinbase has been abandoned + assert_equal(wallet.getwalletinfo()['immature_balance'], 0) + coinbase_tx_id = wallet.getblock(tip, verbose=1)["tx"][0] + assert_equal(wallet.gettransaction(coinbase_tx_id)['details'][0]['abandoned'], True) + + # Abort process abruptly to mimic an unclean shutdown (no chain state flush to disk) + node.process.kill() + + # Restart the node and confirm that it has not persisted the last chain state changes to disk + self.start_node(0) + assert_equal(node.getbestblockhash(), tip) + + # Due to an existing bug, the wallet incorrectly keeps the transaction in an abandoned state, even though that's + # no longer the case (after the unclean shutdown, the node's chain returned to the pre-invalidation tip). + # This issue blocks any future spending and results in an incorrect balance display. + wallet = node.get_wallet_rpc("reorg_crash") + assert_equal(wallet.getwalletinfo()['immature_balance'], 0) # FIXME: #31824. + + # Previously, a bug caused the node to crash if two block disconnection events occurred consecutively. + # Ensure this is no longer the case by simulating a new reorg. + node.invalidateblock(tip) + assert(node.getbestblockhash() != tip) + # Ensure wallet state is consistent now + assert_equal(wallet.gettransaction(coinbase_tx_id)['details'][0]['abandoned'], True) + assert_equal(wallet.getwalletinfo()['immature_balance'], 0) + + # And finally, verify the state if the block ends up being into the best chain again + node.reconsiderblock(tip) + assert_equal(wallet.gettransaction(coinbase_tx_id)['details'][0]['abandoned'], False) + assert_greater_than(wallet.getwalletinfo()['immature_balance'], 0) def run_test(self): # Send a tx from which to conflict outputs later @@ -163,6 +212,9 @@ def run_test(self): # Verify we mark coinbase txs, and their descendants, as abandoned during startup self.test_coinbase_automatic_abandon_during_startup() + # Verify reorg behavior during an unclean shutdown + self.test_reorg_handling_during_unclean_shutdown() + if __name__ == '__main__': ReorgsRestoreTest(__file__).main() From ef6111bd18c28265daaa48a2d1466fb2eff5c200 Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 16 Jun 2025 10:53:57 +0100 Subject: [PATCH 066/314] depends: capnp 1.2.0 Github-Pull: #32760 Rebased-From: c7eaac326ac20a745d1bc6dbc6bc48c1b5eb46f8 --- depends/packages/native_capnp.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/native_capnp.mk b/depends/packages/native_capnp.mk index e67b103716f..a3a089d4faa 100644 --- a/depends/packages/native_capnp.mk +++ b/depends/packages/native_capnp.mk @@ -1,9 +1,9 @@ package=native_capnp -$(package)_version=1.1.0 +$(package)_version=1.2.0 $(package)_download_path=https://capnproto.org/ $(package)_download_file=capnproto-c++-$($(package)_version).tar.gz $(package)_file_name=capnproto-cxx-$($(package)_version).tar.gz -$(package)_sha256_hash=07167580e563f5e821e3b2af1c238c16ec7181612650c5901330fa9a0da50939 +$(package)_sha256_hash=ed00e44ecbbda5186bc78a41ba64a8dc4a861b5f8d4e822959b0144ae6fd42ef define $(package)_set_vars $(package)_config_opts := -DBUILD_TESTING=OFF From 616baf3c27ec767c530a47edac463ed60ddb8c5c Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Thu, 19 Jun 2025 11:15:00 +0200 Subject: [PATCH 067/314] doc: taproot became always active in v24.0 Github-Pull: #32776 Rebased-From: 8ee8a951c205c5365f7557253b8fffc12e6e670c --- doc/bips.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/bips.md b/doc/bips.md index a95b3159ecb..97645d0eebe 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -58,7 +58,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)). From 3e23b47a6fafd1a46dcb731e4732079baa04ab97 Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 19 Jun 2025 10:37:20 +0100 Subject: [PATCH 068/314] doc: fix transifex 404s Github-Pull: #32777 Rebased-From: 53a996f122663e271efa52c45b173613b8ac635e --- README.md | 2 +- doc/release-process.md | 4 ++-- doc/translation_process.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c5b6ce4588e..727bb2cec72 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,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. diff --git a/doc/release-process.md b/doc/release-process.md index 1c5810d0238..9159b8cc8c8 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -57,10 +57,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-x`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/bitcoin_en.xlf` to create it. + - Create [a new resource](https://app.transifex.com/bitcoin/bitcoin/content/) named after the major version with the slug `qt-translation-x`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/bitcoin_en.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) diff --git a/doc/translation_process.md b/doc/translation_process.md index 429e92b2b32..9bd7b142409 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -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. From 4c7ed36c9650065e5638d7ca5c7425c5cd50e3c7 Mon Sep 17 00:00:00 2001 From: zaidmstrr Date: Tue, 17 Jun 2025 20:38:21 +0530 Subject: [PATCH 069/314] test: Fix list index out of range error in feature_bip68_sequence.py Github-Pull: #32765 Rebased-From: e285e691b7a311e278f89e9fe423716de1ee268b --- test/functional/feature_bip68_sequence.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py index 2d61987e944..7f576464b80 100755 --- a/test/functional/feature_bip68_sequence.py +++ b/test/functional/feature_bip68_sequence.py @@ -148,8 +148,10 @@ def test_sequence_lock_confirmed_inputs(self): # 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 From 569760541407824687ef86dd1a5be9a492a5b16e Mon Sep 17 00:00:00 2001 From: David Gumberg Date: Wed, 18 Jun 2025 11:35:06 -0700 Subject: [PATCH 070/314] contrib: tracing: Correctly read msg type in p2p_monitor.py Github-Pull: #32771 Rebased-From: 3473986fe10e2689fe36cc93e1e50013649ac14b --- contrib/tracing/p2p_monitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/tracing/p2p_monitor.py b/contrib/tracing/p2p_monitor.py index 78225366d9c..7a7cc20e86c 100755 --- a/contrib/tracing/p2p_monitor.py +++ b/contrib/tracing/p2p_monitor.py @@ -54,7 +54,7 @@ bpf_probe_read_user_str(&msg.peer_addr, sizeof(msg.peer_addr), paddr); bpf_usdt_readarg(3, ctx, &pconn_type); bpf_probe_read_user_str(&msg.peer_conn_type, sizeof(msg.peer_conn_type), pconn_type); - bpf_usdt_readarg(4, ctx, &pconn_type); + bpf_usdt_readarg(4, ctx, &pmsg_type); bpf_probe_read_user_str(&msg.msg_type, sizeof(msg.msg_type), pmsg_type); bpf_usdt_readarg(5, ctx, &msg.msg_size); @@ -71,7 +71,7 @@ bpf_probe_read_user_str(&msg.peer_addr, sizeof(msg.peer_addr), paddr); bpf_usdt_readarg(3, ctx, &pconn_type); bpf_probe_read_user_str(&msg.peer_conn_type, sizeof(msg.peer_conn_type), pconn_type); - bpf_usdt_readarg(4, ctx, &pconn_type); + bpf_usdt_readarg(4, ctx, &pmsg_type); bpf_probe_read_user_str(&msg.msg_type, sizeof(msg.msg_type), pmsg_type); bpf_usdt_readarg(5, ctx, &msg.msg_size); From 0922f6bbc33ac2abe3f3d9dc98dade896718864f Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 22 May 2025 14:55:32 +0100 Subject: [PATCH 071/314] doc: update release notes for 29.x --- doc/release-notes.md | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 0678887279f..ae2ad5231fc 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -2,7 +2,7 @@ Bitcoin Core version 29.x is now available from: -This release includes new features, various bug fixes and performance +This release includes various bug fixes and performance improvements, as well as updated translations. Please report bugs using the issue tracker at GitHub: @@ -39,6 +39,7 @@ Notable changes ### Wallet +- #31757 wallet: fix crash on double block disconnection - #32553 wallet: Fix logging of wallet version ### Test @@ -47,6 +48,8 @@ Notable changes - #32312 test: Fix feature_pruning test after nTime typo fix - #32336 test: Suppress upstream -Wduplicate-decl-specifier in bpfcc - #32483 test: fix two intermittent failures in wallet_basic.py +- #32630 test: fix sync function in rpc_psbt.py +- #32765 test: Fix list index out of range error in feature_bip68_sequence.py ### Util @@ -57,6 +60,12 @@ Notable changes - #32356 cmake: Respect user-provided configuration-specific flags - #32437 crypto: disable ASan for sha256_sse4 with Clang - #32469 cmake: Allow WITH_DBUS on all Unix-like systems +- #32439 guix: accomodate migration to codeberg +- #32551 cmake: Add missed SSE41_CXXFLAGS +- #32568 depends: use "mkdir -p" when installing xproto +- #32678 guix: warn and abort when SOURCE_DATE_EPOCH is set +- #32690 depends: fix SHA256SUM command on OpenBSD (use GNU mode output) +- #32760 depends: capnp 1.2.0 ### Gui @@ -65,8 +74,18 @@ Notable changes ### Doc +- #32333 doc: Add missing top-level description to pruneblockchain RPC - #32353 doc: Fix fuzz test_runner.py path - #32389 doc: Fix test_bitcoin path +- #32607 rpc: Note in fundrawtransaction doc, fee rate is for package +- #32679 doc: update tor docs to use bitcoind binary from path +- #32693 depends: fix cmake compatibility error for freetype +- #32696 doc: make -DWITH_ZMQ=ON explicit on build-unix.md +- #32708 rpc, doc: update listdescriptors RCP help +- #32711 doc: add missing packages for BSDs (cmake, gmake, curl) to depends/README.md +- #32719 doc, windows: CompanyName "Bitcoin" => "Bitcoin Core project" +- #32776 doc: taproot became always active in v24.0 +- #32777 doc: fix Transifex 404s ### CI @@ -76,6 +95,7 @@ Notable changes - #32187 refactor: Remove spurious virtual from final ~CZMQNotificationInterface - #32454 tracing: fix invalid argument in mempool_monitor +- #32771 contrib: tracing: Fix read of pmsg_type in p2p_monitor.py Credits ======= @@ -83,16 +103,28 @@ Credits Thanks to everyone who directly contributed to this release: - achow101 +- benthecarman - Brandon Odiwuor +- davidgumberg - enirox001 - fanquake - furszy - Hennadii Stepanov +- hodlinator +- ismaelsadeeq - jb55 +- josibake - laanwj +- luisschwab - MarcoFalke - Martin Zumsande - monlovesmango +- nervana21 +- rkrux +- Sjors +- theStack +- willcl-ark +- zaidmstrr As well as to everyone that helped with translations on -[Transifex](https://www.transifex.com/bitcoin/bitcoin/). +[Transifex](https://explore.transifex.com/bitcoin/bitcoin/). From e37a70bf71d05d2e355e6d0ac49c58a4b446454f Mon Sep 17 00:00:00 2001 From: will Date: Mon, 23 Jun 2025 10:56:58 +0100 Subject: [PATCH 072/314] build: add root dir to CMAKE_PREFIX_PATH Nix patches cmake to remove the root directory `/` from `CMAKE_SYSTEM_PREFIX_PATH`: https://github.com/NixOS/nixpkgs/blob/428b49b28ebc8938a6d9f6c540d32d7a06713972/pkgs/by-name/cm/cmake/001-search-path.diff#L10 Without this, and when using the toolchain for depends builds, cmake's `find_path()` and `find_package()` do not know where to find dependencies, causing issues like: https://github.com/bitcoin/bitcoin/issues/32428 Adding this path back via CMAKE_PREFIX_PATH is harmless on other systems, and fixes the toolchain for Nix users. We append the `/` dir a maximum of once, as the toolchain may be called repeatedly during builds. Co-authored-by: Russell Yanofsky Co-authored-by: josibake Github-Pull: #32798 Rebased-From: e27a94596f2a1f5e04722a16165717cc6e891d36 --- depends/toolchain.cmake.in | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/depends/toolchain.cmake.in b/depends/toolchain.cmake.in index 65036d07a9e..c68de84b22e 100644 --- a/depends/toolchain.cmake.in +++ b/depends/toolchain.cmake.in @@ -92,6 +92,22 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(QT_TRANSLATIONS_DIR "${CMAKE_CURRENT_LIST_DIR}/translations") +# The following is only necessary when using cmake from Nix or NixOS, because +# Nix patches cmake to remove the root directory `/` from +# CMAKE_SYSTEM_PREFIX_PATH. Adding it back is harmless on other platforms and +# necessary on Nix because without it cmake find_path, find_package, etc +# functions do not know where to look in CMAKE_FIND_ROOT_PATH for dependencies +# (https://github.com/bitcoin/bitcoin/issues/32428). +# +# TODO: longer term, it may be possible to use a dependency provider, which +# would bring the find_package calls completely under our control, making this +# patch unnecessary. +# +# Make sure we only append once, as this file may be called repeatedly. +if(NOT "/" IN_LIST CMAKE_PREFIX_PATH) + list(APPEND CMAKE_PREFIX_PATH "/") +endif() + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_HOST_APPLE) # The find_package(Qt ...) function internally uses find_library() # calls for all dependencies to ensure their availability. From 5987c1b6abaefad61d8d2cca605349354432398a Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Fri, 13 Jun 2025 01:24:50 +0200 Subject: [PATCH 073/314] test: fix catchup loop in outbound eviction functional test The catchup loop in the outbound eviction functional test currently has a small flaw, as the contained waiting for a `getheaders` message just waits for any such message instead of one with the intended block hash. The reason is that the `prev_prev_hash` variable is set incorrectly, since the `tip_header` instance is not updated and its field `.hash` is None. Fix that by updating `tip_header` and use the correct field -- we want the tip header's previous hash (`.hashPrevBlock`). Github-Pull: #32742 Rebased-From: dd8447f70faf6419b4617da3c1b57098e9cd66a6 --- test/functional/p2p_outbound_eviction.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/p2p_outbound_eviction.py b/test/functional/p2p_outbound_eviction.py index 30ac85e32f3..3d6f154a34a 100755 --- a/test/functional/p2p_outbound_eviction.py +++ b/test/functional/p2p_outbound_eviction.py @@ -88,6 +88,7 @@ def test_outbound_eviction_unprotected(self): # Generate an additional block so the peers is 2 blocks behind prev_header = from_hex(CBlockHeader(), node.getblockheader(best_block_hash, False)) best_block_hash = self.generateblock(node, output="raw(42)", transactions=[])["hash"] + tip_header = from_hex(CBlockHeader(), node.getblockheader(best_block_hash, False)) peer.sync_with_ping() # Advance time but not enough to evict the peer @@ -100,7 +101,7 @@ def test_outbound_eviction_unprotected(self): # Send a header with the previous tip (so we go back to 1 block behind) peer.send_and_ping(msg_headers([prev_header])) - prev_prev_hash = tip_header.hash + prev_prev_hash = tip_header.hashPrevBlock self.log.info("Create an outbound connection and take some time to catch up, but do it in time") # Check that if the peer manages to catch up within time, the timeouts are removed (and the peer is not disconnected) From a990c1002b50a79ba051d322a2269670e6827dd9 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 24 Jun 2025 20:49:27 +0100 Subject: [PATCH 074/314] cmake: Use `HINTS` instead of `PATHS` in `find_*` commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the CMake documentation, `HINTS` "should be paths computed by system introspection, such as a hint provided by the location of another item already found", which is precisely the case in the `FindQRencode` module. Entries in `HINTS` are searched before those in `PATHS`. On macOS, Homebrew’s `libqrencode` will therefore be located at its real path rather than via the symlink in the default prefix. Github-Pull: #32805 Rebased-From: ead44687483e9c936ba970de890c01d5e7ad3485 --- cmake/module/FindQRencode.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/module/FindQRencode.cmake b/cmake/module/FindQRencode.cmake index 39e3b8b679b..575bfecc8b1 100644 --- a/cmake/module/FindQRencode.cmake +++ b/cmake/module/FindQRencode.cmake @@ -21,16 +21,16 @@ endif() find_path(QRencode_INCLUDE_DIR NAMES qrencode.h - PATHS ${PC_QRencode_INCLUDE_DIRS} + HINTS ${PC_QRencode_INCLUDE_DIRS} ) find_library(QRencode_LIBRARY_RELEASE NAMES qrencode - PATHS ${PC_QRencode_LIBRARY_DIRS} + HINTS ${PC_QRencode_LIBRARY_DIRS} ) find_library(QRencode_LIBRARY_DEBUG NAMES qrencoded qrencode - PATHS ${PC_QRencode_LIBRARY_DIRS} + HINTS ${PC_QRencode_LIBRARY_DIRS} ) include(SelectLibraryConfigurations) select_library_configurations(QRencode) From a3c1939d6eb45be4a790b9943c81a3b15af1418a Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 25 Jun 2025 18:45:43 +0100 Subject: [PATCH 075/314] cmake: Explicitly specify `Boost_ROOT` for Homebrew's package On macOS, this change ensures that the Boost package is located at its real path rather than via the symlink in the default prefix. Github-Pull: #32814 Rebased-From: 8800b5acc1ef7abe6c5260ae0be5386b1d593a19 --- cmake/module/AddBoostIfNeeded.cmake | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cmake/module/AddBoostIfNeeded.cmake b/cmake/module/AddBoostIfNeeded.cmake index ecd0d6f2aba..948021f5d5d 100644 --- a/cmake/module/AddBoostIfNeeded.cmake +++ b/cmake/module/AddBoostIfNeeded.cmake @@ -17,6 +17,18 @@ function(add_boost_if_needed) directory and other added INTERFACE properties. ]=] + if(CMAKE_HOST_APPLE) + find_program(HOMEBREW_EXECUTABLE brew) + if(HOMEBREW_EXECUTABLE) + execute_process( + COMMAND ${HOMEBREW_EXECUTABLE} --prefix boost + OUTPUT_VARIABLE Boost_ROOT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + endif() + # We cannot rely on find_package(Boost ...) to work properly without # Boost_NO_BOOST_CMAKE set until we require a more recent Boost because # upstream did not ship proper CMake files until 1.82.0. From eafea2393d972606678f3a825a71754558ac9d5c Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Thu, 15 May 2025 17:45:44 -0400 Subject: [PATCH 076/314] init: cap -maxmempool to 500 MB on 32-bit systems 32-bit architecture is limited to 4GiB, so it doesn't make sense to set a too high value. 500 MB is chosen as an arbitrary maximum value that seems reasonable. Github-Pull: #32530 Rebased-From: 2c43b6adebbfabb3c8dd82fe821ce0a5d6173b3b --- src/node/mempool_args.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/node/mempool_args.cpp b/src/node/mempool_args.cpp index e3bf5fb57cb..33ae697168e 100644 --- a/src/node/mempool_args.cpp +++ b/src/node/mempool_args.cpp @@ -25,6 +25,9 @@ using common::AmountErrMsg; using kernel::MemPoolLimits; using kernel::MemPoolOptions; +//! Maximum mempool size on 32-bit systems. +static constexpr int MAX_32BIT_MEMPOOL_MB{500}; + namespace { void ApplyArgsManOptions(const ArgsManager& argsman, MemPoolLimits& mempool_limits) { @@ -42,7 +45,13 @@ util::Result ApplyArgsManOptions(const ArgsManager& argsman, const CChainP { mempool_opts.check_ratio = argsman.GetIntArg("-checkmempool", mempool_opts.check_ratio); - if (auto mb = argsman.GetIntArg("-maxmempool")) mempool_opts.max_size_bytes = *mb * 1'000'000; + if (auto mb = argsman.GetIntArg("-maxmempool")) { + constexpr bool is_32bit{sizeof(void*) == 4}; + if (is_32bit && *mb > MAX_32BIT_MEMPOOL_MB) { + return util::Error{Untranslated(strprintf("-maxmempool is set to %i but can't be over %i MB on 32-bit systems", *mb, MAX_32BIT_MEMPOOL_MB))}; + } + mempool_opts.max_size_bytes = *mb * 1'000'000; + } if (auto hours = argsman.GetIntArg("-mempoolexpiry")) mempool_opts.expiry = std::chrono::hours{*hours}; From 1c0e19b93a876ba5503da15e1ce14315d804194b Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Fri, 16 May 2025 09:12:25 -0400 Subject: [PATCH 077/314] node: cap -dbcache to 1GiB on 32-bit architectures 32-bit architecture is limited to 4GiB, so it doesn't make sense to set a too high value. Since this setting is performance critical, pick an arbitrary value higher than for -maxmempool but still reasonable. Github-Pull: #32530 Rebased-From: 9f8e7b0b3b787b873045a4a8194e77d0b0a2b3b6 --- src/node/caches.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/node/caches.cpp b/src/node/caches.cpp index 8b432637c73..d5d69fc2044 100644 --- a/src/node/caches.cpp +++ b/src/node/caches.cpp @@ -19,6 +19,8 @@ static constexpr size_t MAX_TX_INDEX_CACHE{1024_MiB}; //! Max memory allocated to all block filter index caches combined in bytes. static constexpr size_t MAX_FILTER_INDEX_CACHE{1024_MiB}; +//! Maximum dbcache size on 32-bit systems. +static constexpr size_t MAX_32BIT_DBCACHE{1024_MiB}; namespace node { CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes) @@ -28,7 +30,8 @@ CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes) if (std::optional db_cache = args.GetIntArg("-dbcache")) { if (*db_cache < 0) db_cache = 0; uint64_t db_cache_bytes = SaturatingLeftShift(*db_cache, 20); - total_cache = std::max(MIN_DB_CACHE, std::min(db_cache_bytes, std::numeric_limits::max())); + constexpr auto max_db_cache{sizeof(void*) == 4 ? MAX_32BIT_DBCACHE : std::numeric_limits::max()}; + total_cache = std::max(MIN_DB_CACHE, std::min(db_cache_bytes, max_db_cache)); } IndexCacheSizes index_sizes; From 4b656e2023099f1ae5fe0aab6d46c97fe161d51f Mon Sep 17 00:00:00 2001 From: dergoegge Date: Mon, 30 Jun 2025 11:13:11 +0100 Subject: [PATCH 078/314] test: Add msgtype to msg_generic slots Github-Pull: #32833 Rebased-From: 7dc43ea503a2c145ffd4fe14b794300bfc2bcdee --- test/functional/test_framework/messages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index 9ebb683a9db..971427842ff 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -1358,7 +1358,7 @@ def __repr__(self): # for cases where a user needs tighter control over what is sent over the wire # note that the user must supply the name of the msgtype, and the data class msg_generic: - __slots__ = ("data") + __slots__ = ("msgtype", "data") def __init__(self, msgtype, data=None): self.msgtype = msgtype From ef2a013e31cf6fbded5735a998b4c992c176493d Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 25 Jun 2025 11:39:18 +0100 Subject: [PATCH 079/314] doc: update release notes for 29.x --- doc/release-notes.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index ae2ad5231fc..c60c728ad27 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -37,6 +37,13 @@ unsupported systems. Notable changes =============== +### Updated Settings + +- The `-maxmempool` and `-dbcache` startup parameters are now capped on + 32-bit systems to 500MB and 1GiB respectively. + +- #32530 node: cap -maxmempool and -dbcache values for 32-bit + ### Wallet - #31757 wallet: fix crash on double block disconnection @@ -50,6 +57,8 @@ Notable changes - #32483 test: fix two intermittent failures in wallet_basic.py - #32630 test: fix sync function in rpc_psbt.py - #32765 test: Fix list index out of range error in feature_bip68_sequence.py +- #32742 test: fix catchup loop in outbound eviction functional test +- #32833 test: Add msgtype to msg_generic slots ### Util @@ -66,6 +75,9 @@ Notable changes - #32678 guix: warn and abort when SOURCE_DATE_EPOCH is set - #32690 depends: fix SHA256SUM command on OpenBSD (use GNU mode output) - #32760 depends: capnp 1.2.0 +- #32798 build: add root dir to CMAKE_PREFIX_PATH in toolchain +- #32805 cmake: Use HINTS instead of PATHS in find_* commands +- #32814 cmake: Explicitly specify Boost_ROOT for Homebrew's package ### Gui @@ -106,6 +118,7 @@ Thanks to everyone who directly contributed to this release: - benthecarman - Brandon Odiwuor - davidgumberg +- dergoegge - enirox001 - fanquake - furszy From 222fbfcc6a02ec5bac367e156392d49fb215c066 Mon Sep 17 00:00:00 2001 From: brunoerg Date: Tue, 1 Jul 2025 11:54:04 -0300 Subject: [PATCH 080/314] test: check P2SH sigop count for coinbase tx Github-Pull: #32850 Rebased-From: d6aaffcb11adcf47480fcc5081af9dcb732decf3 --- src/test/script_p2sh_tests.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp index bb408b7b0f5..b46411185cd 100644 --- a/src/test/script_p2sh_tests.cpp +++ b/src/test/script_p2sh_tests.cpp @@ -364,6 +364,12 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4] BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txTo), coins), 22U); + CMutableTransaction coinbase_tx_mut; + coinbase_tx_mut.vin.resize(1); + CTransaction coinbase_tx{coinbase_tx_mut}; + BOOST_CHECK(coinbase_tx.IsCoinBase()); + BOOST_CHECK_EQUAL(GetP2SHSigOpCount(coinbase_tx, coins), 0U); + CMutableTransaction txToNonStd1; txToNonStd1.vout.resize(1); txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey())); From f82015ccfc7c719405e942ef31c4b59865ee576a Mon Sep 17 00:00:00 2001 From: pablomartin4btc Date: Fri, 27 Jun 2025 13:41:06 -0300 Subject: [PATCH 081/314] test: Clarify roles in outbound eviction comments Some ambiguous uses of "we" referring to either the node or the peer are replaced with clearer phrasing. Also rephrase some comments for consistency and readability. Applies to all relevant outbound eviction tests in p2p_eviction_logic.py. Github-Pull: #32823 Rebased-From: 26598ed21ea7228c4ecf85da24527c88f9c1f1c1 --- test/functional/p2p_outbound_eviction.py | 26 +++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/test/functional/p2p_outbound_eviction.py b/test/functional/p2p_outbound_eviction.py index 3d6f154a34a..cb95d49a12c 100755 --- a/test/functional/p2p_outbound_eviction.py +++ b/test/functional/p2p_outbound_eviction.py @@ -55,7 +55,7 @@ def test_outbound_eviction_unprotected(self): self.log.info("Test that the peer gets evicted") peer.wait_for_disconnect() - self.log.info("Create an outbound connection and send header but never catch up") + self.log.info("Create an outbound connection and send header but the peer never catches up") # Mimic a node that just falls behind for long enough # This should also apply for a node doing IBD that does not catch up in time # Connect a peer and make it send us headers ending in our tip's parent @@ -75,7 +75,7 @@ def test_outbound_eviction_unprotected(self): self.log.info("Create an outbound connection and keep lagging behind, but not too much") # Test that if the peer never catches up with our current tip, but it does with the # expected work that we set when setting the timer (that is, our tip at the time) - # we do not disconnect the peer + # the node does not disconnect the peer peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=0, connection_type="outbound-full-relay") self.log.info("Mine a block so our peer starts lagging") @@ -83,7 +83,7 @@ def test_outbound_eviction_unprotected(self): best_block_hash = self.generateblock(node, output="raw(42)", transactions=[])["hash"] peer.sync_with_ping() - self.log.info("Keep catching up with the old tip and check that we are not evicted") + self.log.info("The peer keeps catching up with the old tip; check that the node does not evict the peer") for i in range(10): # Generate an additional block so the peers is 2 blocks behind prev_header = from_hex(CBlockHeader(), node.getblockheader(best_block_hash, False)) @@ -96,21 +96,21 @@ def test_outbound_eviction_unprotected(self): node.setmocktime(cur_mock_time) peer.sync_with_ping() - # Wait until we get out last call (by receiving a getheaders) + # Make the peer wait until it gets node's last call (by receiving a getheaders) peer.wait_for_getheaders(block_hash=prev_prev_hash) - # Send a header with the previous tip (so we go back to 1 block behind) + # The peer sends a header with the previous tip (so the peer goes back to 1 block behind) peer.send_and_ping(msg_headers([prev_header])) prev_prev_hash = tip_header.hashPrevBlock self.log.info("Create an outbound connection and take some time to catch up, but do it in time") # Check that if the peer manages to catch up within time, the timeouts are removed (and the peer is not disconnected) - # We are reusing the peer from the previous case which already sent us a valid (but old) block and whose timer is ticking + # We are reusing the peer from the previous case which already sent the node a valid (but old) block and whose timer is ticking - # Send an updated headers message matching our tip + # Make the peer send an updated headers message matching our tip peer.send_and_ping(msg_headers([from_hex(CBlockHeader(), node.getblockheader(best_block_hash, False))])) - # Wait for long enough for the timeouts to have triggered and check that we are still connected + # Wait for long enough for the timeouts to have triggered and check that the peer is still connected cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) node.setmocktime(cur_mock_time) peer.sync_with_ping() @@ -123,8 +123,10 @@ def test_outbound_eviction_unprotected(self): def test_outbound_eviction_protected(self): # This tests the eviction logic for **protected** outbound peers (that is, PeerManagerImpl::ConsiderEviction) - # Outbound connections are flagged as protected as long as they have sent us a connecting block with at least as - # much work as our current tip and we have enough empty protected_peers slots. + # Outbound connections are flagged as protected if: + # - The peer sends a connecting block with at least as much work as our current tip. + # - There are still available slots in the node's protected_peers list. + # This test ensures that such protected outbound peers are not disconnected even after chain sync and headers timeouts. node = self.nodes[0] cur_mock_time = node.mocktime tip_header = from_hex(CBlockHeader(), node.getblockheader(node.getbestblockhash(), False)) @@ -145,7 +147,7 @@ def test_outbound_eviction_protected(self): peer.wait_for_getheaders(block_hash=tip_header.hashPrevBlock) cur_mock_time += (HEADERS_RESPONSE_TIME + 1) node.setmocktime(cur_mock_time) - self.log.info("Test that the node does not get evicted") + self.log.info("Test that the peer does not get evicted") peer.sync_with_ping() node.disconnect_p2ps() @@ -205,7 +207,7 @@ def test_outbound_eviction_mixed(self): cur_mock_time += (HEADERS_RESPONSE_TIME + 1) node.setmocktime(cur_mock_time) - self.log.info("Check how none of the honest nor protected peers was evicted but all the misbehaving unprotected were") + self.log.info("Check that none of the honest or protected peers were evicted, but all misbehaving unprotected peers were") for peer in protected_peers + honest_unprotected_peers: peer.sync_with_ping() for peer in misbehaving_unprotected_peers: From 3a57bfaaf9b0712ff080bd8a315c01552735b882 Mon Sep 17 00:00:00 2001 From: pablomartin4btc Date: Fri, 27 Jun 2025 13:46:42 -0300 Subject: [PATCH 082/314] test: Use rehash() in outbound eviction block-relay Ensure that tip_header.rehash() is used instead of tip_header.hash, which is None when the header is deserialized from hex. This avoids depending on wait_for_getheaders() falling back to any received message, making the test more explicit and robust. Github-Pull: #32823 Rebased-From: ec004cdb86e6471915e1033f390c76ee0428e415 --- test/functional/p2p_outbound_eviction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/p2p_outbound_eviction.py b/test/functional/p2p_outbound_eviction.py index cb95d49a12c..43458decbc9 100755 --- a/test/functional/p2p_outbound_eviction.py +++ b/test/functional/p2p_outbound_eviction.py @@ -235,7 +235,7 @@ def test_outbound_eviction_blocks_relay_only(self): cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) node.setmocktime(cur_mock_time) peer.sync_with_ping() - peer.wait_for_getheaders(block_hash=tip_header.hash) + peer.wait_for_getheaders(block_hash=tip_header.rehash()) cur_mock_time += (HEADERS_RESPONSE_TIME + 1) node.setmocktime(cur_mock_time) self.log.info("Test that the peer gets evicted") From 8a4a938db527636aadaa874d733542613b3d14b6 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 10 Jun 2025 14:59:46 +0100 Subject: [PATCH 083/314] depends: Override host compilers for FreeBSD and OpenBSD When building depends on FreeBSD/OpenBSD `aarch64`, the host compilers default to `default_host_{CC,CXX}`, which resolves to `gcc`/`g++`. This is incorrect on these systems, where Clang is the default system compiler. Github-Pull: #32716 Rebased-From: 4f10a57671c19cacca630b2401e42a213aacff1b --- depends/builders/freebsd.mk | 4 ++++ depends/builders/openbsd.mk | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/depends/builders/freebsd.mk b/depends/builders/freebsd.mk index 18316f492ee..910de28bf36 100644 --- a/depends/builders/freebsd.mk +++ b/depends/builders/freebsd.mk @@ -3,3 +3,7 @@ build_freebsd_CXX=clang++ build_freebsd_SHA256SUM = sha256sum build_freebsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o + +# freebsd host on freebsd builder: override freebsd host preferences. +freebsd_CC = clang +freebsd_CXX = clang++ diff --git a/depends/builders/openbsd.mk b/depends/builders/openbsd.mk index 4b3214ae810..6aeb1431258 100644 --- a/depends/builders/openbsd.mk +++ b/depends/builders/openbsd.mk @@ -7,3 +7,7 @@ build_openbsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CON build_openbsd_TAR = gtar # openBSD touch doesn't understand -h build_openbsd_TOUCH = touch -m -t 200001011200 + +# openbsd host on openbsd builder: override openbsd host preferences. +openbsd_CC = clang +openbsd_CXX = clang++ From 9f3690b9785a5e818d2b889a395b65f42fd78378 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Mon, 30 Jun 2025 17:00:24 -0400 Subject: [PATCH 084/314] feature_taproot: sample tx version border values more Currently if the version 3 is selected for an otherwise standard spender, the test will fail. It's unlikely but possible, so change the test to update expectations and sample more aggressively on border values to instigate failures much quicker in the future if another version is made standard. Github-Pull: #32841 Rebased-From: 4be81e9746e9e18923386d6f4945a33885fd98a7 --- test/functional/feature_taproot.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py index daf11a9ae6c..a7de240fa5e 100755 --- a/test/functional/feature_taproot.py +++ b/test/functional/feature_taproot.py @@ -641,6 +641,9 @@ def byte_popper(expr): DUST_LIMIT = 600 MIN_FEE = 50000 +TX_MAX_STANDARD_VERSION = 3 +TX_STANDARD_VERSIONS = [1, 2, TX_MAX_STANDARD_VERSION] + # === Actual test cases === @@ -1409,7 +1412,7 @@ def test_spenders(self, node, spenders, input_counts): while left: # Construct CTransaction with random version, nLocktime tx = CTransaction() - tx.version = random.choice([1, 2, random.getrandbits(32)]) + tx.version = random.choice(TX_STANDARD_VERSIONS + [0, TX_MAX_STANDARD_VERSION + 1, random.getrandbits(32)]) min_sequence = (tx.version != 1 and tx.version != 0) * 0x80000000 # The minimum sequence number to disable relative locktime if random.choice([True, False]): tx.nLockTime = random.randrange(LOCKTIME_THRESHOLD, self.lastblocktime - 7200) # all absolute locktimes in the past @@ -1501,8 +1504,7 @@ def test_spenders(self, node, spenders, input_counts): is_standard_tx = ( fail_input is None # Must be valid to be standard and (all(utxo.spender.is_standard for utxo in input_utxos)) # All inputs must be standard - and tx.version >= 1 # The tx version must be standard - and tx.version <= 2) + and tx.version in TX_STANDARD_VERSIONS) # The tx version must be standard tx.rehash() msg = ','.join(utxo.spender.comment + ("*" if n == fail_input else "") for n, utxo in enumerate(input_utxos)) if is_standard_tx: From 59a83fb8d1f9030111a70e8184091e61cef15c38 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Wed, 2 Jul 2025 11:05:21 -0400 Subject: [PATCH 085/314] functional test: correctly detect nonstd TRUC tx vsize in feature_taproot Github-Pull: #32859 Rebased-From: f0524cda3995cf65adab3d0ca8da0dee4e31c79b --- test/functional/feature_taproot.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py index a7de240fa5e..4acb7524fba 100755 --- a/test/functional/feature_taproot.py +++ b/test/functional/feature_taproot.py @@ -643,6 +643,7 @@ def byte_popper(expr): TX_MAX_STANDARD_VERSION = 3 TX_STANDARD_VERSIONS = [1, 2, TX_MAX_STANDARD_VERSION] +TRUC_MAX_VSIZE = 10000 # test doesn't cover in-mempool spends, so only this limit is hit # === Actual test cases === @@ -1504,7 +1505,9 @@ def test_spenders(self, node, spenders, input_counts): is_standard_tx = ( fail_input is None # Must be valid to be standard and (all(utxo.spender.is_standard for utxo in input_utxos)) # All inputs must be standard - and tx.version in TX_STANDARD_VERSIONS) # The tx version must be standard + and tx.version in TX_STANDARD_VERSIONS # The tx version must be standard + and not (tx.version == 3 and tx.get_vsize() > TRUC_MAX_VSIZE) # Topological standardness rules must be followed + ) tx.rehash() msg = ','.join(utxo.spender.comment + ("*" if n == fail_input else "") for n, utxo in enumerate(input_utxos)) if is_standard_tx: From e5a7575a6df8abd5153f29f1df2503146ac81810 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 2 Jul 2025 15:45:00 +0100 Subject: [PATCH 086/314] doc: Add workaround for vcpkg issue with paths with embedded spaces Github-Pull: #32858 Rebased-From: 0a1af4418ed2a135001cc0e10f0af44cbd64e521 --- doc/build-windows-msvc.md | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/doc/build-windows-msvc.md b/doc/build-windows-msvc.md index 915cf4f04b5..27da0bd0785 100644 --- a/doc/build-windows-msvc.md +++ b/doc/build-windows-msvc.md @@ -59,17 +59,6 @@ ctest --test-dir build --build-config Release # Use "-j N" for N parallel tests cmake --install build --config Release # Optional. ``` -If building with `BUILD_GUI=ON`, vcpkg installation during the build -configuration step might fail because of extremely long paths required during -vcpkg installation if your vcpkg instance is installed in the default Visual -Studio directory. This can be avoided without modifying your vcpkg root -directory by changing vcpkg's intermediate build directory with the -`--x-buildtrees-root` argument to something shorter, for example: - -```powershell -cmake -B build --preset vs2022-static -DVCPKG_INSTALL_OPTIONS="--x-buildtrees-root=C:\vcpkg" -``` - ### 5. Building with Dynamic Linking without GUI ``` @@ -78,9 +67,30 @@ cmake --build build --config Release # Use "-j N" for N parallel jobs. ctest --test-dir build --build-config Release # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` +### 6. vcpkg-specific Issues and Workarounds + +vcpkg installation during the configuration step might fail for various reasons unrelated to Bitcoin Core. + +If the failure is due to a "Buildtrees path … is too long" error, which is often encountered when building +with `BUILD_GUI=ON` and using the default vcpkg installation provided by Visual Studio, you can +specify a shorter path to store intermediate build files by using +the [`--x-buildtrees-root`](https://learn.microsoft.com/en-us/vcpkg/commands/common-options#buildtrees-root) option: + +```powershell +cmake -B build --preset vs2022-static -DVCPKG_INSTALL_OPTIONS="--x-buildtrees-root=C:\vcpkg" +``` + +If vcpkg installation fails with the message "Paths with embedded space may be handled incorrectly", which +can occur if your local Bitcoin Core repository path contains spaces, you can override the vcpkg install directory +by setting the [`VCPKG_INSTALLED_DIR`](https://github.com/microsoft/vcpkg-docs/blob/main/vcpkg/users/buildsystems/cmake-integration.md#vcpkg_installed_dir) variable: + +```powershell +cmake -B build --preset vs2022-static -DVCPKG_INSTALLED_DIR="C:\path_without_spaces" +``` + ## Performance Notes -### 6. vcpkg Manifest Default Features +### 7. vcpkg Manifest Default Features One can skip vcpkg manifest default features to speedup the configuration step. For example, the following invocation will skip all features except for "wallet" and "tests" and their dependencies: @@ -90,6 +100,6 @@ cmake -B build --preset vs2022 -DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON -DVCPKG_M Available features are listed in the [`vcpkg.json`](/vcpkg.json) file. -### 7. Antivirus Software +### 8. Antivirus Software To improve the build process performance, one might add the Bitcoin repository directory to the Microsoft Defender Antivirus exclusions. From 83ee49b1dc9b1a086c1ac910e3bcd2ec38dd6d69 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:20:36 +0200 Subject: [PATCH 087/314] doc: clarify that the "-j N" goes after the "--build build" part Also, capitalized the comments in build-unix.md for uniformity with the docs on other targets. Github-Pull: #32846 Rebased-From: 0e9f409db3b7b08aef75ce39765b018b69cc8e9d --- doc/build-freebsd.md | 4 ++-- doc/build-netbsd.md | 4 ++-- doc/build-openbsd.md | 4 ++-- doc/build-osx.md | 4 ++-- doc/build-unix.md | 4 ++-- doc/build-windows-msvc.md | 8 ++++---- doc/build-windows.md | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index 694224621eb..549d189e7d1 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -129,6 +129,6 @@ cmake -B build -DENABLE_WALLET=OFF ### 2. Compile ```bash -cmake --build build # Use "-j N" for N parallel jobs. -ctest --test-dir build # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. +cmake --build build # Append "-j N" for N parallel jobs. +ctest --test-dir build # Append "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index 988f3b93a7a..05b80eb7476 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -118,6 +118,6 @@ Run `cmake -B build -LH` to see the full list of available options. Build and run the tests: ```bash -cmake --build build # Use "-j N" for N parallel jobs. -ctest --test-dir build # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. +cmake --build build # Append "-j N" for N parallel jobs. +ctest --test-dir build # Append "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 1ad90f23bcc..7ab51054ad2 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -118,8 +118,8 @@ cmake -B build -DBerkeleyDB_INCLUDE_DIR:PATH="${BDB_PREFIX}/include" -DWITH_BDB= ### 2. Compile ```bash -cmake --build build # Use "-j N" for N parallel jobs. -ctest --test-dir build # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. +cmake --build build # Append "-j N" for N parallel jobs. +ctest --test-dir build # Append "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` ## Resource limits diff --git a/doc/build-osx.md b/doc/build-osx.md index 51f3446e44f..3c6c9ad09e6 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -187,8 +187,8 @@ After configuration, you are ready to compile. Run the following in your terminal to compile Bitcoin Core: ``` bash -cmake --build build # Use "-j N" here for N parallel jobs. -ctest --test-dir build # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. +cmake --build build # Append "-j N" here for N parallel jobs. +ctest --test-dir build # Append "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` ### 3. Deploy (optional) diff --git a/doc/build-unix.md b/doc/build-unix.md index 85add7fa539..9c46df2a9cb 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -9,8 +9,8 @@ To Build ```bash cmake -B build -cmake --build build # use "-j N" for N parallel jobs -cmake --install build # optional +cmake --build build # Append "-j N" for N parallel jobs +cmake --install build # Optional ``` See below for instructions on how to [install the dependencies on popular Linux diff --git a/doc/build-windows-msvc.md b/doc/build-windows-msvc.md index 27da0bd0785..0d10fecd855 100644 --- a/doc/build-windows-msvc.md +++ b/doc/build-windows-msvc.md @@ -54,8 +54,8 @@ In the following instructions, the "Debug" configuration can be specified instea ``` cmake -B build --preset vs2022-static # It might take a while if the vcpkg binary cache is unpopulated or invalidated. -cmake --build build --config Release # Use "-j N" for N parallel jobs. -ctest --test-dir build --build-config Release # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. +cmake --build build --config Release # Append "-j N" for N parallel jobs. +ctest --test-dir build --build-config Release # Append "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. cmake --install build --config Release # Optional. ``` @@ -63,8 +63,8 @@ cmake --install build --config Release # Optional. ``` cmake -B build --preset vs2022 -DBUILD_GUI=OFF # It might take a while if the vcpkg binary cache is unpopulated or invalidated. -cmake --build build --config Release # Use "-j N" for N parallel jobs. -ctest --test-dir build --build-config Release # Use "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. +cmake --build build --config Release # Append "-j N" for N parallel jobs. +ctest --test-dir build --build-config Release # Append "-j N" for N parallel tests. Some tests are disabled if Python 3 is not available. ``` ### 6. vcpkg-specific Issues and Workarounds diff --git a/doc/build-windows.md b/doc/build-windows.md index 03af0654cea..84db7fa4b5f 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -47,9 +47,9 @@ This means you cannot use a directory that is located directly on the host Windo Build using: - gmake -C depends HOST=x86_64-w64-mingw32 # Use "-j N" for N parallel jobs. + gmake -C depends HOST=x86_64-w64-mingw32 # Append "-j N" for N parallel jobs. cmake -B build --toolchain depends/x86_64-w64-mingw32/toolchain.cmake - cmake --build build # Use "-j N" for N parallel jobs. + cmake --build build # Append "-j N" for N parallel jobs. ## Depends system From 84c0c0e64b799f8f19791e8c71a7a6e10baa1c3b Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Thu, 26 Jun 2025 06:50:19 +0100 Subject: [PATCH 088/314] test: fix incorrect subtest in `feature_fee_estimation.py` - Update `check_smart_estimates` to calculate the fee rate ceiling by taking the maximum of fees seen, minrelaytxfee, and mempoolminfee. - Improve the subtest name and comments. Github-Pull: #32463 Rebased-From: 5c1236f04a24716b2cbd9b9b283863d3a8a6fa87 --- test/functional/feature_fee_estimation.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py index 974d8268a2a..3bde3a98bd8 100755 --- a/test/functional/feature_fee_estimation.py +++ b/test/functional/feature_fee_estimation.py @@ -90,19 +90,20 @@ def check_smart_estimates(node, fees_seen): """Call estimatesmartfee and verify that the estimates meet certain invariants.""" delta = 1.0e-6 # account for rounding error - last_feerate = float(max(fees_seen)) all_smart_estimates = [node.estimatesmartfee(i) for i in range(1, 26)] mempoolMinFee = node.getmempoolinfo()["mempoolminfee"] minRelaytxFee = node.getmempoolinfo()["minrelaytxfee"] + feerate_ceiling = max(max(fees_seen), float(mempoolMinFee), float(minRelaytxFee)) + last_feerate = feerate_ceiling for i, e in enumerate(all_smart_estimates): # estimate is for i+1 feerate = float(e["feerate"]) assert_greater_than(feerate, 0) assert_greater_than_or_equal(feerate, float(mempoolMinFee)) assert_greater_than_or_equal(feerate, float(minRelaytxFee)) - if feerate + delta < min(fees_seen) or feerate - delta > max(fees_seen): + if feerate + delta < min(fees_seen) or feerate - delta > feerate_ceiling: raise AssertionError( - f"Estimated fee ({feerate}) out of range ({min(fees_seen)},{max(fees_seen)})" + f"Estimated fee ({feerate}) out of range ({min(fees_seen)},{feerate_ceiling})" ) if feerate - delta > last_feerate: raise AssertionError( @@ -237,10 +238,10 @@ def sanity_check_estimates_range(self): self.log.info("Final estimates after emptying mempools") check_estimates(self.nodes[1], self.fees_per_kb) - def test_feerate_mempoolminfee(self): - high_val = 3 * self.nodes[1].estimatesmartfee(1)["feerate"] + def test_estimates_with_highminrelaytxfee(self): + high_val = 3 * self.nodes[1].estimatesmartfee(2)["feerate"] self.restart_node(1, extra_args=[f"-minrelaytxfee={high_val}"]) - check_estimates(self.nodes[1], self.fees_per_kb) + check_smart_estimates(self.nodes[1], self.fees_per_kb) self.restart_node(1) def sanity_check_rbf_estimates(self, utxos): @@ -451,11 +452,11 @@ def run_test(self): self.log.info("Test fee_estimates.dat is flushed periodically") self.test_estimate_dat_is_flushed_periodically() - # check that the effective feerate is greater than or equal to the mempoolminfee even for high mempoolminfee + # check that estimatesmartfee feerate is greater than or equal to maximum of mempoolminfee and minrelaytxfee self.log.info( - "Test fee rate estimation after restarting node with high MempoolMinFee" + "Test fee rate estimation after restarting node with high minrelaytxfee" ) - self.test_feerate_mempoolminfee() + self.test_estimates_with_highminrelaytxfee() self.log.info("Test acceptstalefeeestimates option") self.test_acceptstalefeeestimates_option() From f85d41c2249dfd9a343fdc3cfe139218371bf891 Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Thu, 26 Jun 2025 06:56:46 +0100 Subject: [PATCH 089/314] test: retain the intended behavior of `feature_fee_estimation.py` nodes - Increase block weight by 4000 for all nodes with custom -blockmaxweight. Prior to this commit, we generated blocks with 4000 weight units less worth of transactions. See https://github.com/bitcoin/bitcoin/issues/32461#issuecomment-2925282272 for details. This commit fixes it by increasing the block weight by 4000. Github-Pull: #32463 Rebased-From: 9b75cfda4d62a0a3bde402503244dd57e1621a12 --- test/functional/feature_fee_estimation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py index 3bde3a98bd8..d6e203290a4 100755 --- a/test/functional/feature_fee_estimation.py +++ b/test/functional/feature_fee_estimation.py @@ -145,8 +145,8 @@ def set_test_params(self): self.noban_tx_relay = True self.extra_args = [ [], - ["-blockmaxweight=68000"], - ["-blockmaxweight=32000"], + ["-blockmaxweight=72000"], + ["-blockmaxweight=36000"], ] def setup_network(self): From 58b1a65ab0883bb14cb8ffaf76580800a29a92d2 Mon Sep 17 00:00:00 2001 From: Jameson Lopp Date: Sun, 29 Jun 2025 13:07:06 -0400 Subject: [PATCH 090/314] add more bad p2p ports Github-Pull: #32826 Rebased-From: 6967e8e8abbc35ac98e8e3745a8bbed56e77526f --- doc/p2p-bad-ports.md | 5 +++++ src/netbase.cpp | 5 +++++ src/test/netbase_tests.cpp | 13 +++++-------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/doc/p2p-bad-ports.md b/doc/p2p-bad-ports.md index 4f717f97a29..5e78eb799d3 100644 --- a/doc/p2p-bad-ports.md +++ b/doc/p2p-bad-ports.md @@ -87,10 +87,14 @@ incoming connections. 1720: h323hostcall 1723: pptp 2049: nfs + 3306: MySQL + 3389: RDP / Windows Remote Desktop 3659: apple-sasl / PasswordServer 4045: lockd 5060: sip 5061: sips + 5432: PostgreSQL + 5900: VNC 6000: X11 6566: sane-port 6665: Alternate IRC @@ -100,6 +104,7 @@ incoming connections. 6669: Alternate IRC 6697: IRC + TLS 10080: Amanda + 27017: MongoDB For further information see: diff --git a/src/netbase.cpp b/src/netbase.cpp index eaca5a16c10..d3d54048272 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -861,10 +861,14 @@ bool IsBadPort(uint16_t port) case 1720: // h323hostcall case 1723: // pptp case 2049: // nfs + case 3306: // MySQL + case 3389: // RDP / Windows Remote Desktop case 3659: // apple-sasl / PasswordServer case 4045: // lockd case 5060: // sip case 5061: // sips + case 5432: // PostgreSQL + case 5900: // VNC case 6000: // X11 case 6566: // sane-port case 6665: // Alternate IRC @@ -874,6 +878,7 @@ bool IsBadPort(uint16_t port) case 6669: // Alternate IRC case 6697: // IRC + TLS case 10080: // Amanda + case 27017: // MongoDB return true; } return false; diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 3422cb80233..967378f5201 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -14,6 +14,7 @@ #include #include +#include #include @@ -603,14 +604,10 @@ BOOST_AUTO_TEST_CASE(isbadport) BOOST_CHECK(!IsBadPort(443)); BOOST_CHECK(!IsBadPort(8333)); - // Check all ports, there must be 80 bad ports in total. - size_t total_bad_ports{0}; - for (uint16_t port = std::numeric_limits::max(); port > 0; --port) { - if (IsBadPort(port)) { - ++total_bad_ports; - } - } - BOOST_CHECK_EQUAL(total_bad_ports, 80); + // Check all possible ports and ensure we only flag the expected amount as bad + std::list ports(std::numeric_limits::max()); + std::iota(ports.begin(), ports.end(), 1); + BOOST_CHECK_EQUAL(std::ranges::count_if(ports, IsBadPort), 85); } BOOST_AUTO_TEST_SUITE_END() From bc2147c884d971ec57c782004142b99af6175d9a Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 10 Jul 2025 17:55:34 +0100 Subject: [PATCH 091/314] depends: Force `CMAKE_EXPORT_NO_PACKAGE_REGISTRY=TRUE` When using CMake policies 3.14 and below, the `export(PACKAGE)` command by default populates the user package registry, which is stored outside the build tree. Setting the `CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable disables this side effect. In CMake 3.15 and later, this behavior is disabled by default, and the variable has no effect. Github-Pull: #32943 Rebased-From: 44f3bae300dcafbe53f9b07e6cc22a112833e579 --- depends/funcs.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/funcs.mk b/depends/funcs.mk index b07432adec9..dce45af9611 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -187,6 +187,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" From f798c317a08c1fdbc560fa70af624396ec4cb488 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sat, 12 Jul 2025 14:03:35 +0100 Subject: [PATCH 092/314] cmake: Drop no longer necessary "cmakeMinimumRequired" object Github-Pull: #32954 Rebased-From: 12a6959892cb24b940b3579828f2066651572153 --- CMakePresets.json | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakePresets.json b/CMakePresets.json index da838f2b0e3..a94cfa895ca 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,6 +1,5 @@ { "version": 3, - "cmakeMinimumRequired": {"major": 3, "minor": 21, "patch": 0}, "configurePresets": [ { "name": "vs2022", From 730886b92b661ae6fb2731f79f1371262187b1d5 Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 30 Jun 2025 17:41:22 +0100 Subject: [PATCH 093/314] depends: fix libevent _WIN32_WINNT usage Starting with version 13.x, the mingw headers will define the value of NTDDI_VERSION, based on the value of _WIN32_WINNT, if that version is < Windows 10. Given that libevent was undefining our _WIN32_WINNT, and redefining it to a value < Windows 10 (0x0501), NTDDI_VERSION was also being defined to that value, leading to functions not being exposed in the mingw-w64 headers; see here: https://github.com/mingw-w64/mingw-w64/blob/9c2668ef77e75ea4d8a6c7d100b14643269caec3/mingw-w64-headers/include/iphlpapi.h#L36-L41. Imports a commit from usptream (a14ff91254f40cf36e0fee199e26fb11260fab49). Fixes #32707. Github-Pull: #32837 Rebased-From: f5647c6c5ae85e9469cfc5df6fcac23752e1695a --- depends/packages/libevent.mk | 4 +- depends/patches/libevent/winver_fixup.patch | 122 ++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 depends/patches/libevent/winver_fixup.patch diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index 43c1f741b2d..1f139b1eec8 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -5,6 +5,7 @@ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb $(package)_patches=cmake_fixups.patch $(package)_patches += netbsd_fixup.patch +$(package)_patches += winver_fixup.patch $(package)_build_subdir=build # When building for Windows, we set _WIN32_WINNT to target the same Windows @@ -25,7 +26,8 @@ endef define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/cmake_fixups.patch && \ - patch -p1 < $($(package)_patch_dir)/netbsd_fixup.patch + patch -p1 < $($(package)_patch_dir)/netbsd_fixup.patch && \ + patch -p1 < $($(package)_patch_dir)/winver_fixup.patch endef define $(package)_config_cmds diff --git a/depends/patches/libevent/winver_fixup.patch b/depends/patches/libevent/winver_fixup.patch new file mode 100644 index 00000000000..4995c356f94 --- /dev/null +++ b/depends/patches/libevent/winver_fixup.patch @@ -0,0 +1,122 @@ +Cherry-picked from a14ff91254f40cf36e0fee199e26fb11260fab49. + +move _WIN32_WINNT defintions before first #include + +_WIN32_WINNT and WIN32_LEAN_AND_MEAN need to be defined +before the windows.h is included for the first time. +Avoid the confusion of indirect #include by defining +before any. + +diff --git a/event_iocp.c b/event_iocp.c +index 6b2a2e15..4955e426 100644 +--- a/event_iocp.c ++++ b/event_iocp.c +@@ -23,12 +23,14 @@ + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +-#include "evconfig-private.h" + + #ifndef _WIN32_WINNT + /* Minimum required for InitializeCriticalSectionAndSpinCount */ + #define _WIN32_WINNT 0x0403 + #endif ++ ++#include "evconfig-private.h" ++ + #include + #include + #include +diff --git a/evthread_win32.c b/evthread_win32.c +index 2ec80560..8647f72b 100644 +--- a/evthread_win32.c ++++ b/evthread_win32.c +@@ -23,18 +23,21 @@ + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +-#include "event2/event-config.h" +-#include "evconfig-private.h" + + #ifdef _WIN32 + #ifndef _WIN32_WINNT + /* Minimum required for InitializeCriticalSectionAndSpinCount */ + #define _WIN32_WINNT 0x0403 + #endif +-#include + #define WIN32_LEAN_AND_MEAN ++#endif ++ ++#include "event2/event-config.h" ++#include "evconfig-private.h" ++ ++#ifdef _WIN32 ++#include + #include +-#undef WIN32_LEAN_AND_MEAN + #include + #endif + +diff --git a/evutil.c b/evutil.c +index 9817f086..8537ffe8 100644 +--- a/evutil.c ++++ b/evutil.c +@@ -24,6 +24,14 @@ + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#ifdef _WIN32 ++#ifndef _WIN32_WINNT ++/* For structs needed by GetAdaptersAddresses */ ++#define _WIN32_WINNT 0x0501 ++#endif ++#define WIN32_LEAN_AND_MEAN ++#endif ++ + #include "event2/event-config.h" + #include "evconfig-private.h" + +@@ -31,15 +39,10 @@ + #include + #include + #include +-#define WIN32_LEAN_AND_MEAN + #include +-#undef WIN32_LEAN_AND_MEAN + #include + #include + #include +-#undef _WIN32_WINNT +-/* For structs needed by GetAdaptersAddresses */ +-#define _WIN32_WINNT 0x0501 + #include + #include + #endif +diff --git a/listener.c b/listener.c +index f5c00c9c..d1080e76 100644 +--- a/listener.c ++++ b/listener.c +@@ -24,16 +24,19 @@ + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#ifdef _WIN32 ++#ifndef _WIN32_WINNT ++/* Minimum required for InitializeCriticalSectionAndSpinCount */ ++#define _WIN32_WINNT 0x0403 ++#endif ++#endif ++ + #include "event2/event-config.h" + #include "evconfig-private.h" + + #include + + #ifdef _WIN32 +-#ifndef _WIN32_WINNT +-/* Minimum required for InitializeCriticalSectionAndSpinCount */ +-#define _WIN32_WINNT 0x0403 +-#endif + #include + #include + #include From 5300295083f2e199c22a7ad55e62a8dc7549a76e Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 3 Jul 2025 11:16:58 +0100 Subject: [PATCH 094/314] doc: update release notes for 29.x --- doc/release-notes.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index c60c728ad27..3a39efadbce 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -49,16 +49,25 @@ Notable changes - #31757 wallet: fix crash on double block disconnection - #32553 wallet: Fix logging of wallet version +### P2P + +- #32826 p2p: add more bad ports + ### Test - #32286 test: Handle empty string returned by CLI as None in RPC tests - #32312 test: Fix feature_pruning test after nTime typo fix - #32336 test: Suppress upstream -Wduplicate-decl-specifier in bpfcc +- #32463 test: fix an incorrect feature_fee_estimation.py subtest - #32483 test: fix two intermittent failures in wallet_basic.py - #32630 test: fix sync function in rpc_psbt.py - #32765 test: Fix list index out of range error in feature_bip68_sequence.py - #32742 test: fix catchup loop in outbound eviction functional test +- #32823 test: Fix wait_for_getheaders() call in test_outbound_eviction_blocks_relay_only() - #32833 test: Add msgtype to msg_generic slots +- #32841 feature_taproot: sample tx version border values more +- #32850 test: check P2SH sigop count for coinbase tx +- #32859 test: correctly detect nonstd TRUC tx vsize in feature_taproot ### Util @@ -74,10 +83,14 @@ Notable changes - #32568 depends: use "mkdir -p" when installing xproto - #32678 guix: warn and abort when SOURCE_DATE_EPOCH is set - #32690 depends: fix SHA256SUM command on OpenBSD (use GNU mode output) +- #32716 depends: Override host compilers for FreeBSD and OpenBSD - #32760 depends: capnp 1.2.0 - #32798 build: add root dir to CMAKE_PREFIX_PATH in toolchain - #32805 cmake: Use HINTS instead of PATHS in find_* commands - #32814 cmake: Explicitly specify Boost_ROOT for Homebrew's package +- #32837 depends: fix libevent _WIN32_WINNT usage +- #32943 depends: Force CMAKE_EXPORT_NO_PACKAGE_REGISTRY=TRUE +- #32954 cmake: Drop no longer necessary "cmakeMinimumRequired" object ### Gui @@ -98,6 +111,8 @@ Notable changes - #32719 doc, windows: CompanyName "Bitcoin" => "Bitcoin Core project" - #32776 doc: taproot became always active in v24.0 - #32777 doc: fix Transifex 404s +- #32846 doc: clarify that the "-j N" goes after the "--build build" part +- #32858 doc: Add workaround for vcpkg issue with paths with embedded spaces ### CI @@ -116,16 +131,21 @@ Thanks to everyone who directly contributed to this release: - achow101 - benthecarman +- bigspider - Brandon Odiwuor +- brunoerg +- darosior - davidgumberg - dergoegge - enirox001 - fanquake - furszy +- instagibbs - Hennadii Stepanov - hodlinator - ismaelsadeeq - jb55 +- jlopp - josibake - laanwj - luisschwab @@ -133,7 +153,9 @@ Thanks to everyone who directly contributed to this release: - Martin Zumsande - monlovesmango - nervana21 +- pablomartin4btc - rkrux +- ryanofsky - Sjors - theStack - willcl-ark From 204b96591542373dc75c6a6401b477f4b6615e69 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 19 Mar 2025 17:25:06 -0400 Subject: [PATCH 095/314] policy: make pathological transactions packed with legacy sigops non-standard. The Consensus Cleanup soft fork proposal includes a limit on the number of legacy signature operations potentially executed when validating a transaction. If this change is to be implemented here and activated by Bitcoin users in the future, we should prevent the ability for someone to broadcast a transaction through the p2p network that is not valid according to the new rules. This is because if it was possible it would be a trivial DoS to potentially unupgraded miners after the soft fork activates. We do not know for sure whether users will activate the Consensus Cleanup. However if they do such transactions must have been made non-standard long in advance, due to the time it takes for most nodes on the network to upgrade. In addition this limit may only be run into by pathological transactions which pad the Script with sigops but do not use actual signatures when spending, as otherwise they would run into the standard transaction size limit. Github-Pull: bitcoin/bitcoin#32521 Rebased-From: 5863315e33ba9b75a1e5189ee3da3d7311bbf193 --- src/policy/policy.cpp | 35 +++++++++++++++++++++++++++++++++++ src/policy/policy.h | 2 ++ 2 files changed, 37 insertions(+) diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index ed336928235..545387d150c 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -168,6 +168,35 @@ bool IsStandardTx(const CTransaction& tx, const std::optional& max_dat return true; } +/** + * Check the total number of non-witness sigops across the whole transaction, as per BIP54. + */ +static bool CheckSigopsBIP54(const CTransaction& tx, const CCoinsViewCache& inputs) +{ + Assert(!tx.IsCoinBase()); + + unsigned int sigops{0}; + for (const auto& txin: tx.vin) { + const auto& prev_txo{inputs.AccessCoin(txin.prevout).out}; + + // Unlike the existing block wide sigop limit which counts sigops present in the block + // itself (including the scriptPubKey which is not executed until spending later), BIP54 + // counts sigops in the block where they are potentially executed (only). + // This means sigops in the spent scriptPubKey count toward the limit. + // `fAccurate` means correctly accounting sigops for CHECKMULTISIGs(VERIFY) with 16 pubkeys + // or fewer. This method of accounting was introduced by BIP16, and BIP54 reuses it. + // The GetSigOpCount call on the previous scriptPubKey counts both bare and P2SH sigops. + sigops += txin.scriptSig.GetSigOpCount(/*fAccurate=*/true); + sigops += prev_txo.scriptPubKey.GetSigOpCount(txin.scriptSig); + + if (sigops > MAX_TX_LEGACY_SIGOPS) { + return false; + } + } + + return true; +} + /** * Check transaction inputs to mitigate two * potential denial-of-service attacks: @@ -185,6 +214,8 @@ bool IsStandardTx(const CTransaction& tx, const std::optional& max_dat * DUP CHECKSIG DROP ... repeated 100 times... OP_1 * * Note that only the non-witness portion of the transaction is checked here. + * + * We also check the total number of non-witness sigops across the whole transaction, as per BIP54. */ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) { @@ -192,6 +223,10 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; // Coinbases don't use vin normally } + if (!CheckSigopsBIP54(tx, mapInputs)) { + return false; + } + for (unsigned int i = 0; i < tx.vin.size(); i++) { const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out; diff --git a/src/policy/policy.h b/src/policy/policy.h index 2151ec13dd0..dab39aa4f8b 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -38,6 +38,8 @@ static constexpr unsigned int MIN_STANDARD_TX_NONWITNESS_SIZE{65}; 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}; +/** The maximum number of potentially executed legacy signature operations in a single standard tx */ +static constexpr unsigned int MAX_TX_LEGACY_SIGOPS{2'500}; /** Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or replacement **/ static constexpr unsigned int DEFAULT_INCREMENTAL_RELAY_FEE{1000}; /** Default for -bytespersigop */ From 0a4671d5eba2499a27e530536b48b86166319fe8 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 19 Mar 2025 17:35:14 -0400 Subject: [PATCH 096/314] qa: unit test standardness of inputs packed with legacy sigops Check bounds and different output types. Github-Pull: bitcoin/bitcoin#32521 Rebased-From: 367147954d16c961bbd28c361abf27b4cb665f10 --- src/test/transaction_tests.cpp | 96 ++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 8beeec49915..2db30e20331 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1048,4 +1049,99 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) CheckIsNotStandard(t, "dust"); } +BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops) +{ + CCoinsView coins_dummy; + CCoinsViewCache coins(&coins_dummy); + CKey key; + key.MakeNewKey(true); + + // Create a pathological P2SH script padded with as many sigops as is standard. + CScript max_sigops_redeem_script{CScript() << std::vector{} << key.GetPubKey()}; + for (unsigned i{0}; i < MAX_P2SH_SIGOPS - 1; ++i) max_sigops_redeem_script << OP_2DUP << OP_CHECKSIG << OP_DROP; + max_sigops_redeem_script << OP_CHECKSIG << OP_NOT; + const CScript max_sigops_p2sh{GetScriptForDestination(ScriptHash(max_sigops_redeem_script))}; + + // Create a transaction fanning out as many such P2SH outputs as is standard to spend in a + // single transaction, and a transaction spending them. + CMutableTransaction tx_create, tx_max_sigops; + const unsigned p2sh_inputs_count{MAX_TX_LEGACY_SIGOPS / MAX_P2SH_SIGOPS}; + tx_create.vout.reserve(p2sh_inputs_count); + for (unsigned i{0}; i < p2sh_inputs_count; ++i) { + tx_create.vout.emplace_back(424242 + i, max_sigops_p2sh); + } + auto prev_txid{tx_create.GetHash()}; + tx_max_sigops.vin.reserve(p2sh_inputs_count); + for (unsigned i{0}; i < p2sh_inputs_count; ++i) { + tx_max_sigops.vin.emplace_back(prev_txid, i, CScript() << ToByteVector(max_sigops_redeem_script)); + } + + // p2sh_inputs_count is truncated to 166 (from 166.6666..) + BOOST_CHECK_LT(p2sh_inputs_count * MAX_P2SH_SIGOPS, MAX_TX_LEGACY_SIGOPS); + AddCoins(coins, CTransaction(tx_create), 0, false); + + // 2490 sigops is below the limit. + BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(tx_max_sigops), coins), 2490); + BOOST_CHECK(::AreInputsStandard(CTransaction(tx_max_sigops), coins)); + + // Adding one more input will bump this to 2505, hitting the limit. + tx_create.vout.emplace_back(424242, max_sigops_p2sh); + prev_txid = tx_create.GetHash(); + for (unsigned i{0}; i < p2sh_inputs_count; ++i) { + tx_max_sigops.vin[i] = CTxIn(COutPoint(prev_txid, i), CScript() << ToByteVector(max_sigops_redeem_script)); + } + tx_max_sigops.vin.emplace_back(prev_txid, p2sh_inputs_count, CScript() << ToByteVector(max_sigops_redeem_script)); + AddCoins(coins, CTransaction(tx_create), 0, false); + BOOST_CHECK_GT((p2sh_inputs_count + 1) * MAX_P2SH_SIGOPS, MAX_TX_LEGACY_SIGOPS); + BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(tx_max_sigops), coins), 2505); + BOOST_CHECK(!::AreInputsStandard(CTransaction(tx_max_sigops), coins)); + + // Now, check the limit can be reached with regular P2PK outputs too. Use a separate + // preparation transaction, to demonstrate spending coins from a single tx is irrelevant. + CMutableTransaction tx_create_p2pk; + const auto p2pk_script{CScript() << key.GetPubKey() << OP_CHECKSIG}; + unsigned p2pk_inputs_count{10}; // From 2490 to 2500. + for (unsigned i{0}; i < p2pk_inputs_count; ++i) { + tx_create_p2pk.vout.emplace_back(212121 + i, p2pk_script); + } + prev_txid = tx_create_p2pk.GetHash(); + tx_max_sigops.vin.resize(p2sh_inputs_count); // Drop the extra input. + for (unsigned i{0}; i < p2pk_inputs_count; ++i) { + tx_max_sigops.vin.emplace_back(prev_txid, i); + } + AddCoins(coins, CTransaction(tx_create_p2pk), 0, false); + + // The transaction now contains exactly 2500 sigops, the check should pass. + BOOST_CHECK_EQUAL(p2sh_inputs_count * MAX_P2SH_SIGOPS + p2pk_inputs_count * 1, MAX_TX_LEGACY_SIGOPS); + BOOST_CHECK(::AreInputsStandard(CTransaction(tx_max_sigops), coins)); + + // Now, add some Segwit inputs. We add one for each defined Segwit output type. The limit + // is exclusively on non-witness sigops and therefore those should not be counted. + CMutableTransaction tx_create_segwit; + const auto witness_script{CScript() << key.GetPubKey() << OP_CHECKSIG}; + tx_create_segwit.vout.emplace_back(121212, GetScriptForDestination(WitnessV0KeyHash(key.GetPubKey()))); + tx_create_segwit.vout.emplace_back(131313, GetScriptForDestination(WitnessV0ScriptHash(witness_script))); + tx_create_segwit.vout.emplace_back(141414, GetScriptForDestination(WitnessV1Taproot{XOnlyPubKey(key.GetPubKey())})); + prev_txid = tx_create_segwit.GetHash(); + for (unsigned i{0}; i < tx_create_segwit.vout.size(); ++i) { + tx_max_sigops.vin.emplace_back(prev_txid, i); + } + + // The transaction now still contains exactly 2500 sigops, the check should pass. + AddCoins(coins, CTransaction(tx_create_segwit), 0, false); + BOOST_REQUIRE(::AreInputsStandard(CTransaction(tx_max_sigops), coins)); + + // Add one more P2PK input. We'll reach the limit. + tx_create_p2pk.vout.emplace_back(212121, p2pk_script); + prev_txid = tx_create_p2pk.GetHash(); + tx_max_sigops.vin.resize(p2sh_inputs_count); + ++p2pk_inputs_count; + for (unsigned i{0}; i < p2pk_inputs_count; ++i) { + tx_max_sigops.vin.emplace_back(prev_txid, i); + } + AddCoins(coins, CTransaction(tx_create_p2pk), 0, false); + BOOST_CHECK_GT(p2sh_inputs_count * MAX_P2SH_SIGOPS + p2pk_inputs_count * 1, MAX_TX_LEGACY_SIGOPS); + BOOST_CHECK(!::AreInputsStandard(CTransaction(tx_max_sigops), coins)); +} + BOOST_AUTO_TEST_SUITE_END() From 313023369b8e4ffb268cb642101680fe7f746fea Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Thu, 20 Mar 2025 09:44:10 -0400 Subject: [PATCH 097/314] qa: functional test a transaction running into the legacy sigop limit It's useful to have an end-to-end test in addition to the unit test to sanity check the RPC error as well as making sure the transaction is otherwise fully standard. Github-Pull: bitcoin/bitcoin#32521 Rebased-From: 96da68a38fa295d2414685739c41b8626e198d27 --- test/functional/mempool_sigoplimit.py | 45 +++++++++++++++++++ test/functional/test_framework/script_util.py | 6 +++ 2 files changed, 51 insertions(+) diff --git a/test/functional/mempool_sigoplimit.py b/test/functional/mempool_sigoplimit.py index 47df0c614ae..ec491ced230 100755 --- a/test/functional/mempool_sigoplimit.py +++ b/test/functional/mempool_sigoplimit.py @@ -3,6 +3,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test sigop limit mempool policy (`-bytespersigop` parameter)""" +from copy import deepcopy from decimal import Decimal from math import ceil @@ -17,23 +18,30 @@ ) from test_framework.script import ( CScript, + OP_2DUP, OP_CHECKMULTISIG, OP_CHECKSIG, + OP_DROP, OP_ENDIF, OP_FALSE, OP_IF, + OP_NOT, OP_RETURN, OP_TRUE, ) from test_framework.script_util import ( keys_to_multisig_script, script_to_p2wsh_script, + script_to_p2sh_script, + MAX_STD_LEGACY_SIGOPS, + MAX_STD_P2SH_SIGOPS, ) 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, ) from test_framework.wallet import MiniWallet from test_framework.wallet_util import generate_keypair @@ -176,6 +184,42 @@ def create_bare_multisig_tx(utxo_to_spend=None): # Transactions are tiny in weight assert_greater_than(2000, tx_parent.get_weight() + tx_child.get_weight()) + def test_legacy_sigops_stdness(self): + self.log.info("Test a transaction with too many legacy sigops in its inputs is non-standard.") + + # Restart with the default settings + self.restart_node(0) + + # Create a P2SH script with 15 sigops. + _, dummy_pubkey = generate_keypair() + packed_redeem_script = [dummy_pubkey] + for _ in range(MAX_STD_P2SH_SIGOPS - 1): + packed_redeem_script += [OP_2DUP, OP_CHECKSIG, OP_DROP] + packed_redeem_script = CScript(packed_redeem_script + [OP_CHECKSIG, OP_NOT]) + packed_p2sh_script = script_to_p2sh_script(packed_redeem_script) + + # Create enough outputs to reach the sigops limit when spending them all at once. + outpoints = [] + for _ in range(int(MAX_STD_LEGACY_SIGOPS / MAX_STD_P2SH_SIGOPS) + 1): + res = self.wallet.send_to(from_node=self.nodes[0], scriptPubKey=packed_p2sh_script, amount=1_000) + txid = int.from_bytes(bytes.fromhex(res["txid"]), byteorder="big") + outpoints.append(COutPoint(txid, res["sent_vout"])) + self.generate(self.nodes[0], 1) + + # Spending all these outputs at once accounts for 2505 legacy sigops and is non-standard. + nonstd_tx = CTransaction() + nonstd_tx.vin = [CTxIn(op, CScript([b"", packed_redeem_script])) for op in outpoints] + nonstd_tx.vout = [CTxOut(0, CScript([OP_RETURN, b""]))] + assert_raises_rpc_error(-26, "bad-txns-nonstandard-inputs", self.nodes[0].sendrawtransaction, nonstd_tx.serialize().hex()) + + # Spending one less accounts for 2490 legacy sigops and is standard. + std_tx = deepcopy(nonstd_tx) + std_tx.vin.pop() + self.nodes[0].sendrawtransaction(std_tx.serialize().hex()) + + # Make sure the original, non-standard, transaction can be mined. + self.generateblock(self.nodes[0], output="raw(42)", transactions=[nonstd_tx.serialize().hex()]) + def run_test(self): self.wallet = MiniWallet(self.nodes[0]) @@ -193,6 +237,7 @@ def run_test(self): self.generate(self.wallet, 1) self.test_sigops_package() + self.test_legacy_sigops_stdness() if __name__ == '__main__': diff --git a/test/functional/test_framework/script_util.py b/test/functional/test_framework/script_util.py index 938183ece4c..fce32e138ee 100755 --- a/test/functional/test_framework/script_util.py +++ b/test/functional/test_framework/script_util.py @@ -22,6 +22,12 @@ sha256, ) +# Maximum number of potentially executed legacy signature operations in validating a transaction. +MAX_STD_LEGACY_SIGOPS = 2_500 + +# Maximum number of sigops per standard P2SH redeemScript. +MAX_STD_P2SH_SIGOPS = 15 + # To prevent a "tx-size-small" policy rule error, a transaction has to have a # non-witness size of at least 65 bytes (MIN_STANDARD_TX_NONWITNESS_SIZE in # src/policy/policy.h). Considering a Tx with the smallest possible single From 79e1a3c9c6a4661562d419dc3427b35060ed0451 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Thu, 17 Jul 2025 13:00:05 +0200 Subject: [PATCH 098/314] test: Do not pass tests on unhandled exceptions This adds a missing catch for BaseException (e.g. SystemExit), which would otherwise be silently ignored. Also, remove the redundant other catches, which are just calling log.exception with a redundant log message. Github-Pull: #33001 Rebased-From: fa30b34026f76a5b8af997152fced2d281782e0d --- test/functional/test_framework/test_framework.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index d5b338f2ba2..1de527f7ba6 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -134,27 +134,18 @@ def main(self): else: self.run_test() - except JSONRPCException: - self.log.exception("JSONRPC error") - self.success = TestStatus.FAILED except SkipTest as e: self.log.warning("Test Skipped: %s" % e.message) self.success = TestStatus.SKIPPED - except AssertionError: - self.log.exception("Assertion failed") - self.success = TestStatus.FAILED - except KeyError: - self.log.exception("Key error") - self.success = TestStatus.FAILED except subprocess.CalledProcessError as e: self.log.exception("Called Process failed with '{}'".format(e.output)) self.success = TestStatus.FAILED - except Exception: - self.log.exception("Unexpected exception caught during testing") - self.success = TestStatus.FAILED except KeyboardInterrupt: self.log.warning("Exiting after keyboard interrupt") self.success = TestStatus.FAILED + except BaseException: + self.log.exception("Unexpected exception") + self.success = TestStatus.FAILED finally: exit_code = self.shutdown() sys.exit(exit_code) From 5e327e6703f10d3de12c56bb9701b07521a9f703 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Fri, 18 Jul 2025 07:36:32 +0200 Subject: [PATCH 099/314] test: Log KeyboardInterrupt as exception log.exception is more verbose and useful to debug timeouts. Also, log stderr for CalledProcessError to make debugging easier. Github-Pull: #33001 Rebased-From: faa3e684118bffa7a98cf76eeeb59243219df900 --- test/functional/test_framework/test_framework.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 1de527f7ba6..ab87cfa5ea6 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -138,10 +138,7 @@ def main(self): self.log.warning("Test Skipped: %s" % e.message) self.success = TestStatus.SKIPPED except subprocess.CalledProcessError as e: - self.log.exception("Called Process failed with '{}'".format(e.output)) - self.success = TestStatus.FAILED - except KeyboardInterrupt: - self.log.warning("Exiting after keyboard interrupt") + self.log.exception(f"Called Process failed with stdout='{e.stdout}'; stderr='{e.stderr}';") self.success = TestStatus.FAILED except BaseException: self.log.exception("Unexpected exception") From 411e15194b3a770ff455d413a0fe2495f0362297 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 23 Jul 2025 16:47:49 +0100 Subject: [PATCH 100/314] doc: update release notes for 29.x --- doc/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 3a39efadbce..d09772ff330 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -68,6 +68,7 @@ Notable changes - #32841 feature_taproot: sample tx version border values more - #32850 test: check P2SH sigop count for coinbase tx - #32859 test: correctly detect nonstd TRUC tx vsize in feature_taproot +- #33001 test: Do not pass tests on unhandled exceptions ### Util From f25dc84b2892e6bdbbd0471add9fcb2757700981 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Tue, 22 Jul 2025 08:49:12 -0400 Subject: [PATCH 101/314] doc: update release notes for 29.x --- doc/release-notes.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 3a39efadbce..65ea34a7ebe 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -37,6 +37,17 @@ unsupported systems. Notable changes =============== +### Mempool Policy + +- The maximum number of potentially executed legacy signature operations in a + single standard transaction is now limited to 2500. Signature operations in all + previous output scripts, in all input scripts, as well as all P2SH redeem + scripts (if there are any) are counted toward the limit. The new limit is + assumed to not affect any known typically formed standard transactions. The + change was done to prepare for a possible BIP54 deployment in the future. + +- #32521 policy: make pathological transactions packed with legacy sigops non-standard + ### Updated Settings - The `-maxmempool` and `-dbcache` startup parameters are now capped on @@ -130,11 +141,11 @@ Credits Thanks to everyone who directly contributed to this release: - achow101 +- Antoine Poinsot - benthecarman - bigspider - Brandon Odiwuor - brunoerg -- darosior - davidgumberg - dergoegge - enirox001 From 380b5aded21772f9b7a31418109c20b2e15d090e Mon Sep 17 00:00:00 2001 From: furszy Date: Fri, 14 Mar 2025 10:30:50 -0400 Subject: [PATCH 102/314] test: fix intermittent failure in wallet_reorgsrestore.py Wait until the node's process has fully stopped before starting a new instance. Since the same code is used in tool_wallet.py, this consolidates the behavior into a 'kill_process()' function. Github-Pull: bitcoin/bitcoin#32069 Rebased-From: 36b0713edc4655f6e0c291975d6d280fbc89cf2e --- test/functional/test_framework/test_node.py | 5 +++++ test/functional/tool_wallet.py | 5 +---- test/functional/wallet_reorgsrestore.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index e7ae3851f02..abca2b559b5 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -443,6 +443,11 @@ def wait_until_stopped(self, *, timeout=BITCOIND_PROC_WAIT_TIMEOUT, expect_error kwargs["expected_ret_code"] = 1 if expect_error else 0 # Whether node shutdown return EXIT_FAILURE or EXIT_SUCCESS self.wait_until(lambda: self.is_node_stopped(**kwargs), timeout=timeout) + def kill_process(self): + self.process.kill() + self.wait_until_stopped(expected_ret_code=1 if platform.system() == "Windows" else -9) + assert self.is_node_stopped() + def replace_in_config(self, replacements): """ Perform replacements in the configuration file. diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py index b0b9adab879..c7abc2da8d4 100755 --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -5,7 +5,6 @@ """Test bitcoin-wallet.""" import os -import platform import random import stat import string @@ -537,9 +536,7 @@ def test_dump_unclean_lsns(self): # Next cause a bunch of writes by filling the keypool wallet.keypoolrefill(wallet.getwalletinfo()["keypoolsize"] + 100) # Lastly kill bitcoind so that the LSNs don't get reset - self.nodes[0].process.kill() - self.nodes[0].wait_until_stopped(expected_ret_code=1 if platform.system() == "Windows" else -9) - assert self.nodes[0].is_node_stopped() + self.nodes[0].kill_process() wallet_dump = self.nodes[0].datadir_path / "unclean_lsn.dump" self.assert_raises_tool_error("LSNs are not reset, this database is not completely flushed. Please reopen then close the database with a version that has BDB support", "-wallet=unclean_lsn", f"-dumpfile={wallet_dump}", "dump") diff --git a/test/functional/wallet_reorgsrestore.py b/test/functional/wallet_reorgsrestore.py index d9be3bd2e9a..9c69c33680f 100755 --- a/test/functional/wallet_reorgsrestore.py +++ b/test/functional/wallet_reorgsrestore.py @@ -115,7 +115,7 @@ def test_reorg_handling_during_unclean_shutdown(self): assert_equal(wallet.gettransaction(coinbase_tx_id)['details'][0]['abandoned'], True) # Abort process abruptly to mimic an unclean shutdown (no chain state flush to disk) - node.process.kill() + node.kill_process() # Restart the node and confirm that it has not persisted the last chain state changes to disk self.start_node(0) From c6fe6971bfa52d8fe2901a051f18da9f3bcb26a9 Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 24 Jul 2025 14:47:15 +0100 Subject: [PATCH 103/314] doc: update release notes for 29.x --- doc/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index d09772ff330..1e978fd8340 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -55,6 +55,7 @@ Notable changes ### Test +- #32069 test: fix intermittent failure in wallet_reorgsrestore.py - #32286 test: Handle empty string returned by CLI as None in RPC tests - #32312 test: Fix feature_pruning test after nTime typo fix - #32336 test: Suppress upstream -Wduplicate-decl-specifier in bpfcc From 735ffad864ce6cc1f9a1c13f0cb15bcf30284dd6 Mon Sep 17 00:00:00 2001 From: glozow Date: Thu, 24 Jul 2025 12:40:27 -0400 Subject: [PATCH 104/314] [build] bump version to 29.1rc1 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 69683c24ebf..13ceac65f2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,9 +28,9 @@ get_directory_property(precious_variables CACHE_VARIABLES) #============================= set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) -set(CLIENT_VERSION_MINOR 0) +set(CLIENT_VERSION_MINOR 1) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 0) +set(CLIENT_VERSION_RC 1) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From 06eb42d83cf7eb76dc89bb6ca04f51eb17847d06 Mon Sep 17 00:00:00 2001 From: glozow Date: Thu, 24 Jul 2025 13:18:17 -0400 Subject: [PATCH 105/314] [doc] manpages for 29.1rc1 --- doc/man/bitcoin-cli.1 | 8 ++++---- doc/man/bitcoin-qt.1 | 8 ++++---- doc/man/bitcoin-tx.1 | 8 ++++---- doc/man/bitcoin-util.1 | 8 ++++---- doc/man/bitcoin-wallet.1 | 8 ++++---- doc/man/bitcoind.1 | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 168b486862e..dfc4d5ad40c 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. -.TH BITCOIN-CLI "1" "April 2025" "bitcoin-cli v29.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-CLI "1" "July 2025" "bitcoin-cli v29.1.0rc1" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.0.0 +bitcoin-cli \- manual page for bitcoin-cli v29.1.0rc1 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.0.0 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.0.0 +Bitcoin Core RPC client version v29.1.0rc1 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 0093d08b3f0..ca2bc8eb864 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. -.TH BITCOIN-QT "1" "April 2025" "bitcoin-qt v29.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-QT "1" "July 2025" "bitcoin-qt v29.1.0rc1" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.0.0 +bitcoin-qt \- manual page for bitcoin-qt v29.1.0rc1 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.0.0 +Bitcoin Core version v29.1.0rc1 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index f45d7094bbc..db199ff7408 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. -.TH BITCOIN-TX "1" "April 2025" "bitcoin-tx v29.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-TX "1" "July 2025" "bitcoin-tx v29.1.0rc1" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.0.0 +bitcoin-tx \- manual page for bitcoin-tx v29.1.0rc1 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.0.0 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.0.0 +Bitcoin Core bitcoin\-tx utility version v29.1.0rc1 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index 330e6944113..07d61d78454 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. -.TH BITCOIN-UTIL "1" "April 2025" "bitcoin-util v29.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-UTIL "1" "July 2025" "bitcoin-util v29.1.0rc1" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.0.0 +bitcoin-util \- manual page for bitcoin-util v29.1.0rc1 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.0.0 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.0.0 +Bitcoin Core bitcoin\-util utility version v29.1.0rc1 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index 5e0406b1485..636e8c5906d 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. -.TH BITCOIN-WALLET "1" "April 2025" "bitcoin-wallet v29.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIN-WALLET "1" "July 2025" "bitcoin-wallet v29.1.0rc1" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.0.0 +bitcoin-wallet \- manual page for bitcoin-wallet v29.1.0rc1 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.0.0 +Bitcoin Core bitcoin\-wallet utility version v29.1.0rc1 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index f4ec4d3ecd4..8e41a3a763a 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. -.TH BITCOIND "1" "April 2025" "bitcoind v29.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. +.TH BITCOIND "1" "July 2025" "bitcoind v29.1.0rc1" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.0.0 +bitcoind \- manual page for bitcoind v29.1.0rc1 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.0.0 +Bitcoin Core daemon version v29.1.0rc1 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From 4c2d285b706058ece7092d03f0e5ad1112c2097f Mon Sep 17 00:00:00 2001 From: glozow Date: Thu, 24 Jul 2025 15:54:16 -0400 Subject: [PATCH 106/314] [doc] update release notes for v29.1rc1 --- doc/release-notes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 6d3c5efaa69..0519f3b8366 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.x is now available from: +Bitcoin Core version 29.1rc1 is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. From 3cd8612cd7719c0a4dfa104bae3467b562d567d7 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Sat, 26 Jul 2025 13:52:59 +0300 Subject: [PATCH 107/314] doc/zmq: fix unix socket path example Following https://github.com/bitcoin/bitcoin/blob/75a5c8258ec5309fe506438aa3815608430b53d6/doc/release-notes/release-notes-28.0.md?plain=1#L105 Github-Pull: #33070 Rebased-From: e83699a626b8a41c8fb9d0450e14e06a29a98bb8 --- doc/zmq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zmq.md b/doc/zmq.md index 0a74d6eef97..44cdc0e2c26 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -84,7 +84,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 From 9437415024da7dd51705e46e4243f7e1694acaf5 Mon Sep 17 00:00:00 2001 From: deadmanoz Date: Tue, 29 Jul 2025 07:22:11 +0000 Subject: [PATCH 108/314] tracing: fix pointer argument handling in mempool_monitor.py The BPF code was incorrectly passing pointer variables by value to bpf_usdt_readarg(), causing the function to fail silently and resulting in transaction hashes and reason strings displaying as zeros or garbage. This fix adds the missing reference operator (&) when passing pointer variables to bpf_usdt_readarg(), allowing the function to properly write the pointer values and enabling correct display of transaction hashes and removal/rejection reasons. Fixes the regression introduced in ec47ba349d where bpf_usdt_readarg_p was replaced with bpf_usdt_readarg but the calling convention wasn't properly updated for pointer arguments. Github-Pull: #33086 Rebased-From: 0ce041ea88dbea2bdfaf21fd0e60a86012498f0a --- contrib/tracing/mempool_monitor.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contrib/tracing/mempool_monitor.py b/contrib/tracing/mempool_monitor.py index 22efa91783f..eb29b374158 100755 --- a/contrib/tracing/mempool_monitor.py +++ b/contrib/tracing/mempool_monitor.py @@ -66,7 +66,7 @@ int trace_added(struct pt_regs *ctx) { struct added_event added = {}; void *phash = NULL; - bpf_usdt_readarg(1, ctx, phash); + bpf_usdt_readarg(1, ctx, &phash); bpf_probe_read_user(&added.hash, sizeof(added.hash), phash); bpf_usdt_readarg(2, ctx, &added.vsize); bpf_usdt_readarg(3, ctx, &added.fee); @@ -78,9 +78,9 @@ int trace_removed(struct pt_regs *ctx) { struct removed_event removed = {}; void *phash = NULL, *preason = NULL; - bpf_usdt_readarg(1, ctx, phash); + bpf_usdt_readarg(1, ctx, &phash); bpf_probe_read_user(&removed.hash, sizeof(removed.hash), phash); - bpf_usdt_readarg(2, ctx, preason); + bpf_usdt_readarg(2, ctx, &preason); bpf_probe_read_user_str(&removed.reason, sizeof(removed.reason), preason); bpf_usdt_readarg(3, ctx, &removed.vsize); bpf_usdt_readarg(4, ctx, &removed.fee); @@ -93,9 +93,9 @@ int trace_rejected(struct pt_regs *ctx) { struct rejected_event rejected = {}; void *phash = NULL, *preason = NULL; - bpf_usdt_readarg(1, ctx, phash); + bpf_usdt_readarg(1, ctx, &phash); bpf_probe_read_user(&rejected.hash, sizeof(rejected.hash), phash); - bpf_usdt_readarg(2, ctx, preason); + bpf_usdt_readarg(2, ctx, &preason); bpf_probe_read_user_str(&rejected.reason, sizeof(rejected.reason), preason); rejected_events.perf_submit(ctx, &rejected, sizeof(rejected)); return 0; @@ -104,12 +104,12 @@ int trace_replaced(struct pt_regs *ctx) { struct replaced_event replaced = {}; void *phash_replaced = NULL, *phash_replacement = NULL; - bpf_usdt_readarg(1, ctx, phash_replaced); + bpf_usdt_readarg(1, ctx, &phash_replaced); bpf_probe_read_user(&replaced.replaced_hash, sizeof(replaced.replaced_hash), phash_replaced); bpf_usdt_readarg(2, ctx, &replaced.replaced_vsize); bpf_usdt_readarg(3, ctx, &replaced.replaced_fee); bpf_usdt_readarg(4, ctx, &replaced.replaced_entry_time); - bpf_usdt_readarg(5, ctx, phash_replacement); + bpf_usdt_readarg(5, ctx, &phash_replacement); bpf_probe_read_user(&replaced.replacement_hash, sizeof(replaced.replacement_hash), phash_replacement); bpf_usdt_readarg(6, ctx, &replaced.replacement_vsize); bpf_usdt_readarg(7, ctx, &replaced.replacement_fee); From a18b53f99e4bf7f038dac635f27bddf17d285010 Mon Sep 17 00:00:00 2001 From: will Date: Sun, 27 Jul 2025 21:51:39 +0100 Subject: [PATCH 109/314] guix: warn SOURCE_DATE_EPOCH set in guix-codesign Currently there is a warning for this in guix-build, but we also need one in guix-codesign, otherwise the codesigned hashes are not reproducible. Move common functionality into prelude and call the function in both guix actions. Github-Pull: #33073 Rebased-From: 1bed0f734b3f2dd876193b5cad303bfab1d250d5 --- contrib/guix/guix-build | 14 +------------- contrib/guix/guix-codesign | 6 ++++++ contrib/guix/libexec/prelude.bash | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index 715568c1543..ee285bf322c 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -73,19 +73,7 @@ mkdir -p "$VERSION_BASE" # SOURCE_DATE_EPOCH should not unintentionally be set ################ -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_source_date_epoch ################ # Build directories should not exist diff --git a/contrib/guix/guix-codesign b/contrib/guix/guix-codesign index dedee135b4a..ac7aae3a180 100755 --- a/contrib/guix/guix-codesign +++ b/contrib/guix/guix-codesign @@ -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 ################ diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash index f7fc932dfd3..d25c371a10c 100644 --- a/contrib/guix/libexec/prelude.bash +++ b/contrib/guix/libexec/prelude.bash @@ -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 ################ From 264418f80cea7fd5ae818a2a2887fab62de2b0a2 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Wed, 30 Jul 2025 10:27:05 -0500 Subject: [PATCH 110/314] doc: Add rel note for breaking change in dumptxoutset RPC This was missed in the v29.0 release notes. --- doc/release-notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 0519f3b8366..74355ba7442 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -48,6 +48,12 @@ Notable changes - #32521 policy: make pathological transactions packed with legacy sigops non-standard +### RPC + +- The `dumptxoutset` RPC now requires a `type` parameter to be specified. To maintain pre + v29.0 behavior, use the `latest` parameter. Documenting this change was missed in the v29.0 + release notes. (#30808) + ### Updated Settings - The `-maxmempool` and `-dbcache` startup parameters are now capped on From a08886d5640a808e302108575ffbebd7df5f8f11 Mon Sep 17 00:00:00 2001 From: Bufo Date: Tue, 13 May 2025 13:44:40 +0200 Subject: [PATCH 111/314] doc: move `cmake -B build -LH` up in Unix build docs Github-Pull: #33088 Rebased-From: 6757052fc439bedd1fa88ee1d23b4f17cf2c4f7a --- doc/build-unix.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/doc/build-unix.md b/doc/build-unix.md index 9c46df2a9cb..9696063cd1d 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -9,6 +9,10 @@ To Build ```bash cmake -B build +``` +Run `cmake -B build -LH` to see the full list of available options. + +```bash cmake --build build # Append "-j N" for N parallel jobs cmake --install build # Optional ``` @@ -171,13 +175,6 @@ In this case there is no dependency on SQLite or Berkeley DB. Mining is also possible in disable-wallet mode using the `getblocktemplate` RPC call. -Additional Configure Flags --------------------------- -A list of additional configure flags can be displayed with: - - cmake -B build -LH - - Setup and Build Example: Arch Linux ----------------------------------- This example lists the steps necessary to setup and build a command line only distribution of the latest changes on Arch Linux: From 4e8abca44506ac39166e4a7372f8ee0f6d1def0a Mon Sep 17 00:00:00 2001 From: 0xb10c Date: Mon, 4 Aug 2025 16:20:05 +0200 Subject: [PATCH 112/314] rpc: fix getpeerinfo ping duration unit docs The getpeerinfo docs incorrectly specified the ping durations as milliseconds. This was incorrectly changed in a3789c700b5a43efd4b366b4241ae840d63f2349 (released in v25; master since Sept. 2022). The correct duration unit is seconds. Also, remove the documentation of the getpeerinfo RPC response from the ping RPC since it's incomplete. Better to just reference the getpeerinfo RPC and it's documenation for this. Github-Pull: #33133 Rebased-From: 1252eeb997df2eb12c33d92eb1a5c9d6643a67ff --- src/rpc/net.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index bda07365e0e..9942386c7fc 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -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)"}, From 2b9738a0835f50845ed183e124347b07b7bcce10 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Fri, 1 Aug 2025 16:33:13 -0500 Subject: [PATCH 113/314] test: Fix 'getdescriptoractivity' RPCHelpMan, add test to verify 'spend_vin' is the correct field Github-Pull: #33119 Rebased-From: 3543bfdfec345cf2c952143c31674ef02de2a64b --- src/rpc/blockchain.cpp | 2 +- test/functional/rpc_getdescriptoractivity.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 2c4e471babf..8cbca51ccbf 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2625,7 +2625,7 @@ static RPCHelpMan getdescriptoractivity() {RPCResult::Type::STR_HEX, "blockhash", /*optional=*/true, "The blockhash this spend appears in (omitted if unconfirmed)"}, {RPCResult::Type::NUM, "height", /*optional=*/true, "Height of the spend (omitted if unconfirmed)"}, {RPCResult::Type::STR_HEX, "spend_txid", "The txid of the spending transaction"}, - {RPCResult::Type::NUM, "spend_vout", "The vout of the spend"}, + {RPCResult::Type::NUM, "spend_vin", "The input index of the spend"}, {RPCResult::Type::STR_HEX, "prevout_txid", "The txid of the prevout"}, {RPCResult::Type::NUM, "prevout_vout", "The vout of the prevout"}, {RPCResult::Type::OBJ, "prevout_spk", "", ScriptPubKeyDoc()}, diff --git a/test/functional/rpc_getdescriptoractivity.py b/test/functional/rpc_getdescriptoractivity.py index a0dc43718bc..6ddbdfd52d0 100755 --- a/test/functional/rpc_getdescriptoractivity.py +++ b/test/functional/rpc_getdescriptoractivity.py @@ -182,6 +182,7 @@ def test_receive_then_spend(self, node, wallet): assert result['activity'][2]['type'] == 'spend' assert result['activity'][2]['spend_txid'] == sent2['txid'] + assert result['activity'][2]['spend_vin'] == 0 assert result['activity'][2]['prevout_txid'] == sent1['txid'] assert result['activity'][2]['blockhash'] == blockhash_2 From b9e637bd0ee4d1da5f587ec33cbed9ee28c07daf Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 28 Jul 2025 10:29:43 +0100 Subject: [PATCH 114/314] doc: update release notes for 29.x --- doc/release-notes.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 74355ba7442..e4cf2f0b50d 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -110,6 +110,7 @@ Notable changes - #32837 depends: fix libevent _WIN32_WINNT usage - #32943 depends: Force CMAKE_EXPORT_NO_PACKAGE_REGISTRY=TRUE - #32954 cmake: Drop no longer necessary "cmakeMinimumRequired" object +- #33073 guix: warn SOURCE_DATE_EPOCH set in guix-codesign ### Gui @@ -132,6 +133,10 @@ Notable changes - #32777 doc: fix Transifex 404s - #32846 doc: clarify that the "-j N" goes after the "--build build" part - #32858 doc: Add workaround for vcpkg issue with paths with embedded spaces +- #33070 doc/zmq: fix unix socket path example +- #33088 doc: move cmake -B build -LH up in Unix build docs +- #33133 rpc: fix getpeerinfo ping duration unit docs +- #33119 rpc: Fix 'getdescriptoractivity' RPCHelpMan, add test to verify fix ### CI @@ -142,19 +147,24 @@ Notable changes - #32187 refactor: Remove spurious virtual from final ~CZMQNotificationInterface - #32454 tracing: fix invalid argument in mempool_monitor - #32771 contrib: tracing: Fix read of pmsg_type in p2p_monitor.py +- #33086 contrib: [tracing] fix pointer argument handling in mempool_monitor.py Credits ======= Thanks to everyone who directly contributed to this release: +- 0xB10C - achow101 - Antoine Poinsot - benthecarman - bigspider - Brandon Odiwuor - brunoerg +- Bufo +- Christewart - davidgumberg +- deadmanoz - dergoegge - enirox001 - fanquake @@ -174,6 +184,7 @@ Thanks to everyone who directly contributed to this release: - nervana21 - pablomartin4btc - rkrux +- romanz - ryanofsky - Sjors - theStack From 4987c035318536a76f3f5dd00beb417d8fb4b24c Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Thu, 5 Jun 2025 13:47:49 -0400 Subject: [PATCH 115/314] test: Mark ~DebugLogHelper as noexcept(false) We mark ~DebugLogHelper as noexcept(false) to be able to catch the exception it throws. This lets us use it in test in combination with BOOST_CHECK_THROW and BOOST_CHECK_NO_THROW to check that certain log messages are (not) logged. Co-Authored-By: Niklas Gogge Github-Pull: #32604 Rebased-From: df7972a6cfd919b972bcbba07de85f7797898529 --- src/test/util/logging.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/util/logging.h b/src/test/util/logging.h index 73ac23825f9..5d7e4f91e0f 100644 --- a/src/test/util/logging.h +++ b/src/test/util/logging.h @@ -33,7 +33,9 @@ class DebugLogHelper public: explicit DebugLogHelper(std::string message, MatchFn match = [](const std::string*){ return true; }); - ~DebugLogHelper() { check_found(); } + + //! Mark as noexcept(false) to catch any thrown exceptions. + ~DebugLogHelper() noexcept(false) { check_found(); } }; #define ASSERT_DEBUG_LOG(message) DebugLogHelper UNIQUE_NAME(debugloghelper)(message) From 41262cc4d53389ddadc59573e4eb246e085268ce Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Thu, 5 Jun 2025 12:19:28 -0400 Subject: [PATCH 116/314] log: introduce LogRateLimiter, LogLimitStats, Status LogRateLimiter will be used to keep track of source locations and our current time-based logging window. It contains an unordered_map and a m_suppressions_active bool to track source locations. The map is keyed by std::source_location, so a custom Hash function (SourceLocationHasher) and custom KeyEqual function (SourceLocationEqual) is provided. SourceLocationHasher uses CSipHasher(0,0) under the hood to get a uniform distribution. A public Reset method is provided so that a scheduler (e.g. the "b-scheduler" thread) can periodically reset LogRateLimiter's state when the time window has elapsed. The LogRateLimiter::Consume method checks if we have enough available bytes in our rate limiting budget to log an additional string. It returns a Status enum that denotes the rate limiting status and can be used by the caller to emit a warning, skip logging, etc. The Status enum has three states: - UNSUPPRESSED (logging was successful) - NEWLY_SUPPRESSED (logging was succcesful, next log will be suppressed) - STILL_SUPPRESSED (logging was unsuccessful) LogLimitStats counts the available bytes left for logging per source location for the current logging window. It does not track actual source locations; it is used as a value in m_source_locations. Also exposes a SuppressionsActive() method so the logger can use that in a later commit to prefix [*] to logs whenenever suppressions are active. Co-Authored-By: Niklas Gogge Co-Authored-By: stickies-v Github-Pull: #32604 Rebased-From: afb9e39ec5552e598a5febaa81820d5509b7c5d2 --- src/logging.cpp | 55 ++++++++++++++++++++++ src/logging.h | 95 ++++++++++++++++++++++++++++++++++++++ src/test/logging_tests.cpp | 77 ++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+) diff --git a/src/logging.cpp b/src/logging.cpp index 5f055566ef5..eca6eac6727 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -367,6 +367,30 @@ static size_t MemUsage(const BCLog::Logger::BufferedLog& buflog) return buflog.str.size() + buflog.logging_function.size() + buflog.source_file.size() + buflog.threadname.size() + memusage::MallocUsage(sizeof(memusage::list_node)); } +BCLog::LogRateLimiter::LogRateLimiter( + SchedulerFunction scheduler_func, + uint64_t max_bytes, + std::chrono::seconds reset_window) : m_max_bytes{max_bytes}, m_reset_window{reset_window} +{ + scheduler_func([this] { Reset(); }, reset_window); +} + +BCLog::LogRateLimiter::Status BCLog::LogRateLimiter::Consume( + const std::source_location& source_loc, + const std::string& str) +{ + StdLockGuard scoped_lock(m_mutex); + auto& counter{m_source_locations.try_emplace(source_loc, m_max_bytes).first->second}; + Status status{counter.GetDroppedBytes() > 0 ? Status::STILL_SUPPRESSED : Status::UNSUPPRESSED}; + + if (!counter.Consume(str.size()) && status == Status::UNSUPPRESSED) { + status = Status::NEWLY_SUPPRESSED; + m_suppression_active = true; + } + + return status; +} + void BCLog::Logger::FormatLogStrInPlace(std::string& str, BCLog::LogFlags category, BCLog::Level level, std::string_view source_file, int source_line, std::string_view logging_function, std::string_view threadname, SystemClock::time_point now, std::chrono::seconds mocktime) const { if (!str.ends_with('\n')) str.push_back('\n'); @@ -492,6 +516,37 @@ void BCLog::Logger::ShrinkDebugFile() fclose(file); } +void BCLog::LogRateLimiter::Reset() +{ + decltype(m_source_locations) source_locations; + { + StdLockGuard scoped_lock(m_mutex); + source_locations.swap(m_source_locations); + m_suppression_active = false; + } + for (const auto& [source_loc, counter] : source_locations) { + uint64_t dropped_bytes{counter.GetDroppedBytes()}; + if (dropped_bytes == 0) continue; + LogPrintLevel_( + LogFlags::ALL, Level::Info, + "Restarting logging from %s:%d (%s): %d bytes were dropped during the last %ss.\n", + source_loc.file_name(), source_loc.line(), source_loc.function_name(), + dropped_bytes, Ticks(m_reset_window)); + } +} + +bool BCLog::LogLimitStats::Consume(uint64_t bytes) +{ + if (bytes > m_available_bytes) { + m_dropped_bytes += bytes; + m_available_bytes = 0; + return false; + } + + m_available_bytes -= bytes; + return true; +} + bool BCLog::Logger::SetLogLevel(std::string_view level_str) { const auto level = GetLogLevel(level_str); diff --git a/src/logging.h b/src/logging.h index fdc12c79b32..7411d33f5f0 100644 --- a/src/logging.h +++ b/src/logging.h @@ -6,6 +6,7 @@ #ifndef BITCOIN_LOGGING_H #define BITCOIN_LOGGING_H +#include #include #include #include @@ -14,11 +15,14 @@ #include #include +#include #include #include #include +#include #include #include +#include #include static const bool DEFAULT_LOGTIMEMICROS = false; @@ -31,6 +35,24 @@ extern const char * const DEFAULT_DEBUGLOGFILE; extern bool fLogIPs; +struct SourceLocationEqual { + bool operator()(const std::source_location& lhs, const std::source_location& rhs) const noexcept + { + return lhs.line() == rhs.line() && std::string_view(lhs.file_name()) == std::string_view(rhs.file_name()); + } +}; + +struct SourceLocationHasher { + size_t operator()(const std::source_location& s) const noexcept + { + // Use CSipHasher(0, 0) as a simple way to get uniform distribution. + return static_cast(CSipHasher(0, 0) + .Write(std::hash{}(s.file_name())) + .Write(s.line()) + .Finalize()); + } +}; + struct LogCategory { std::string category; bool active; @@ -82,6 +104,79 @@ namespace BCLog { }; constexpr auto DEFAULT_LOG_LEVEL{Level::Debug}; constexpr size_t DEFAULT_MAX_LOG_BUFFER{1'000'000}; // buffer up to 1MB of log data prior to StartLogging + constexpr uint64_t RATELIMIT_MAX_BYTES{1024 * 1024}; // maximum number of bytes that can be logged within one window + + //! Keeps track of an individual source location and how many available bytes are left for logging from it. + class LogLimitStats + { + private: + //! Remaining bytes in the current window interval. + uint64_t m_available_bytes; + //! Number of bytes that were not consumed within the current window. + uint64_t m_dropped_bytes{0}; + + public: + LogLimitStats(uint64_t max_bytes) : m_available_bytes{max_bytes} {} + //! Consume bytes from the window if enough bytes are available. + //! + //! Returns whether enough bytes were available. + bool Consume(uint64_t bytes); + + uint64_t GetAvailableBytes() const + { + return m_available_bytes; + } + + uint64_t GetDroppedBytes() const + { + return m_dropped_bytes; + } + }; + + /** + * Fixed window rate limiter for logging. + */ + class LogRateLimiter + { + private: + mutable StdMutex m_mutex; + + //! Counters for each source location that has attempted to log something. + std::unordered_map m_source_locations GUARDED_BY(m_mutex); + //! True if at least one log location is suppressed. Cached view on m_source_locations for performance reasons. + std::atomic m_suppression_active{false}; + + public: + using SchedulerFunction = std::function, std::chrono::milliseconds)>; + /** + * @param scheduler_func Callable object used to schedule resetting the window. The first + * parameter is the function to be executed, and the second is the + * reset_window interval. + * @param max_bytes Maximum number of bytes that can be logged for each source + * location. + * @param reset_window Time window after which the byte counters are reset. + */ + LogRateLimiter(SchedulerFunction scheduler_func, uint64_t max_bytes, std::chrono::seconds reset_window); + //! Maximum number of bytes logged per location per window. + const uint64_t m_max_bytes; + //! Interval after which the window is reset. + const std::chrono::seconds m_reset_window; + //! Suppression status of a source log location. + enum class Status { + UNSUPPRESSED, // string fits within the limit + NEWLY_SUPPRESSED, // suppression has started since this string + STILL_SUPPRESSED, // suppression is still ongoing + }; + //! Consumes `source_loc`'s available bytes corresponding to the size of the (formatted) + //! `str` and returns its status. + [[nodiscard]] Status Consume( + const std::source_location& source_loc, + const std::string& str) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); + //! Resets all usage to zero. Called periodically by the scheduler. + void Reset() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); + //! Returns true if any log locations are currently being suppressed. + bool SuppressionsActive() const { return m_suppression_active; } + }; class Logger { diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index 77ec81e5977..5d24ad771c2 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -5,11 +5,13 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -276,4 +278,79 @@ BOOST_FIXTURE_TEST_CASE(logging_Conf, LogSetup) } } +void MockForwardAndSync(CScheduler& scheduler, std::chrono::seconds duration) +{ + scheduler.MockForward(duration); + std::promise promise; + scheduler.scheduleFromNow([&promise] { promise.set_value(); }, 0ms); + promise.get_future().wait(); +} + +BOOST_AUTO_TEST_CASE(logging_log_rate_limiter) +{ + CScheduler scheduler{}; + scheduler.m_service_thread = std::thread([&scheduler] { scheduler.serviceQueue(); }); + uint64_t max_bytes{1024}; + auto reset_window{1min}; + auto sched_func = [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }; + BCLog::LogRateLimiter limiter{sched_func, max_bytes, reset_window}; + + using Status = BCLog::LogRateLimiter::Status; + auto source_loc_1{std::source_location::current()}; + auto source_loc_2{std::source_location::current()}; + + // A fresh limiter should not have any suppressions + BOOST_CHECK(!limiter.SuppressionsActive()); + + // Resetting an unused limiter is fine + limiter.Reset(); + BOOST_CHECK(!limiter.SuppressionsActive()); + + // No suppression should happen until more than max_bytes have been consumed + BOOST_CHECK_EQUAL(limiter.Consume(source_loc_1, std::string(max_bytes - 1, 'a')), Status::UNSUPPRESSED); + BOOST_CHECK_EQUAL(limiter.Consume(source_loc_1, "a"), Status::UNSUPPRESSED); + BOOST_CHECK(!limiter.SuppressionsActive()); + BOOST_CHECK_EQUAL(limiter.Consume(source_loc_1, "a"), Status::NEWLY_SUPPRESSED); + BOOST_CHECK(limiter.SuppressionsActive()); + BOOST_CHECK_EQUAL(limiter.Consume(source_loc_1, "a"), Status::STILL_SUPPRESSED); + BOOST_CHECK(limiter.SuppressionsActive()); + + // Location 2 should not be affected by location 1's suppression + BOOST_CHECK_EQUAL(limiter.Consume(source_loc_2, std::string(max_bytes, 'a')), Status::UNSUPPRESSED); + BOOST_CHECK_EQUAL(limiter.Consume(source_loc_2, "a"), Status::NEWLY_SUPPRESSED); + BOOST_CHECK(limiter.SuppressionsActive()); + + // After reset_window time has passed, all suppressions should be cleared. + MockForwardAndSync(scheduler, reset_window); + + BOOST_CHECK(!limiter.SuppressionsActive()); + BOOST_CHECK_EQUAL(limiter.Consume(source_loc_1, std::string(max_bytes, 'a')), Status::UNSUPPRESSED); + BOOST_CHECK_EQUAL(limiter.Consume(source_loc_2, std::string(max_bytes, 'a')), Status::UNSUPPRESSED); + + scheduler.stop(); +} + +BOOST_AUTO_TEST_CASE(logging_log_limit_stats) +{ + BCLog::LogLimitStats counter{BCLog::RATELIMIT_MAX_BYTES}; + + // Check that counter gets initialized correctly. + BOOST_CHECK_EQUAL(counter.GetAvailableBytes(), BCLog::RATELIMIT_MAX_BYTES); + BOOST_CHECK_EQUAL(counter.GetDroppedBytes(), 0ull); + + const uint64_t MESSAGE_SIZE{512 * 1024}; + BOOST_CHECK(counter.Consume(MESSAGE_SIZE)); + BOOST_CHECK_EQUAL(counter.GetAvailableBytes(), BCLog::RATELIMIT_MAX_BYTES - MESSAGE_SIZE); + BOOST_CHECK_EQUAL(counter.GetDroppedBytes(), 0ull); + + BOOST_CHECK(counter.Consume(MESSAGE_SIZE)); + BOOST_CHECK_EQUAL(counter.GetAvailableBytes(), BCLog::RATELIMIT_MAX_BYTES - MESSAGE_SIZE * 2); + BOOST_CHECK_EQUAL(counter.GetDroppedBytes(), 0ull); + + // Consuming more bytes after already having consumed 1MB should fail. + BOOST_CHECK(!counter.Consume(500)); + BOOST_CHECK_EQUAL(counter.GetAvailableBytes(), 0ull); + BOOST_CHECK_EQUAL(counter.GetDroppedBytes(), 500ull); +} + BOOST_AUTO_TEST_SUITE_END() From a0992a842ed098ebcd5f955b232b9abb154d6f6e Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Thu, 5 Jun 2025 13:37:27 -0400 Subject: [PATCH 117/314] log: use std::source_location in place of __func__, __FILE__, __LINE__ The std::source_location conveniently stores the file name, line number, and function name of a source code location. We switch to using it instead of the __func__ identifier and the __FILE__ and __LINE__ macros. BufferedLog is changed to have a std::source_location member, replacing the source_file, source_line, and logging_function members. As a result, MemUsage no longer explicitly counts source_file or logging_function as the std::source_location memory usage is included in the MallocUsage call. This also changes the behavior of -logsourcelocations as std::source_location includes the entire function signature. Because of this, the functional test feature_config_args.py must be changed to no longer include the function signature as the function signature can differ across platforms. Co-Authored-By: Niklas Gogge Co-Authored-By: stickies-v Github-Pull: #32604 Rebased-From: a6a35cc0c23d0d529bfeb2f40d83d61f15ca7b40 --- src/logging.cpp | 38 +++++++++++++----------- src/logging.h | 16 +++++----- src/test/logging_tests.cpp | 41 +++++++++++++++++--------- test/functional/feature_config_args.py | 2 +- 4 files changed, 56 insertions(+), 41 deletions(-) diff --git a/src/logging.cpp b/src/logging.cpp index eca6eac6727..65cd993d7d0 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -12,8 +12,10 @@ #include #include +#include #include #include +#include using util::Join; using util::RemovePrefixView; @@ -73,12 +75,12 @@ bool BCLog::Logger::StartLogging() // dump buffered messages from before we opened the log m_buffering = false; if (m_buffer_lines_discarded > 0) { - LogPrintStr_(strprintf("Early logging buffer overflowed, %d log lines discarded.\n", m_buffer_lines_discarded), __func__, __FILE__, __LINE__, BCLog::ALL, Level::Info); + LogPrintStr_(strprintf("Early logging buffer overflowed, %d log lines discarded.\n", m_buffer_lines_discarded), std::source_location::current(), BCLog::ALL, Level::Info); } while (!m_msgs_before_open.empty()) { const auto& buflog = m_msgs_before_open.front(); std::string s{buflog.str}; - FormatLogStrInPlace(s, buflog.category, buflog.level, buflog.source_file, buflog.source_line, buflog.logging_function, buflog.threadname, buflog.now, buflog.mocktime); + FormatLogStrInPlace(s, buflog.category, buflog.level, buflog.source_loc, buflog.threadname, buflog.now, buflog.mocktime); m_msgs_before_open.pop_front(); if (m_print_to_file) FileWriteStr(s, m_fileout); @@ -364,7 +366,9 @@ std::string BCLog::Logger::GetLogPrefix(BCLog::LogFlags category, BCLog::Level l static size_t MemUsage(const BCLog::Logger::BufferedLog& buflog) { - return buflog.str.size() + buflog.logging_function.size() + buflog.source_file.size() + buflog.threadname.size() + memusage::MallocUsage(sizeof(memusage::list_node)); + return memusage::DynamicUsage(buflog.str) + + memusage::DynamicUsage(buflog.threadname) + + memusage::MallocUsage(sizeof(memusage::list_node)); } BCLog::LogRateLimiter::LogRateLimiter( @@ -391,14 +395,14 @@ BCLog::LogRateLimiter::Status BCLog::LogRateLimiter::Consume( return status; } -void BCLog::Logger::FormatLogStrInPlace(std::string& str, BCLog::LogFlags category, BCLog::Level level, std::string_view source_file, int source_line, std::string_view logging_function, std::string_view threadname, SystemClock::time_point now, std::chrono::seconds mocktime) const +void BCLog::Logger::FormatLogStrInPlace(std::string& str, BCLog::LogFlags category, BCLog::Level level, const std::source_location& source_loc, std::string_view threadname, SystemClock::time_point now, std::chrono::seconds mocktime) const { if (!str.ends_with('\n')) str.push_back('\n'); str.insert(0, GetLogPrefix(category, level)); if (m_log_sourcelocations) { - str.insert(0, strprintf("[%s:%d] [%s] ", RemovePrefixView(source_file, "./"), source_line, logging_function)); + str.insert(0, strprintf("[%s:%d] [%s] ", RemovePrefixView(source_loc.file_name(), "./"), source_loc.line(), source_loc.function_name())); } if (m_log_threadnames) { @@ -408,28 +412,26 @@ void BCLog::Logger::FormatLogStrInPlace(std::string& str, BCLog::LogFlags catego str.insert(0, LogTimestampStr(now, mocktime)); } -void BCLog::Logger::LogPrintStr(std::string_view str, std::string_view logging_function, std::string_view source_file, int source_line, BCLog::LogFlags category, BCLog::Level level) +void BCLog::Logger::LogPrintStr(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level) { StdLockGuard scoped_lock(m_cs); - return LogPrintStr_(str, logging_function, source_file, source_line, category, level); + return LogPrintStr_(str, std::move(source_loc), category, level); } -void BCLog::Logger::LogPrintStr_(std::string_view str, std::string_view logging_function, std::string_view source_file, int source_line, BCLog::LogFlags category, BCLog::Level level) +void BCLog::Logger::LogPrintStr_(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level) { std::string str_prefixed = LogEscapeMessage(str); if (m_buffering) { { BufferedLog buf{ - .now=SystemClock::now(), - .mocktime=GetMockTime(), - .str=str_prefixed, - .logging_function=std::string(logging_function), - .source_file=std::string(source_file), - .threadname=util::ThreadGetInternalName(), - .source_line=source_line, - .category=category, - .level=level, + .now = SystemClock::now(), + .mocktime = GetMockTime(), + .str = str_prefixed, + .threadname = util::ThreadGetInternalName(), + .source_loc = std::move(source_loc), + .category = category, + .level = level, }; m_cur_buffer_memusage += MemUsage(buf); m_msgs_before_open.push_back(std::move(buf)); @@ -448,7 +450,7 @@ void BCLog::Logger::LogPrintStr_(std::string_view str, std::string_view logging_ return; } - FormatLogStrInPlace(str_prefixed, category, level, source_file, source_line, logging_function, util::ThreadGetInternalName(), SystemClock::now(), GetMockTime()); + FormatLogStrInPlace(str_prefixed, category, level, source_loc, util::ThreadGetInternalName(), SystemClock::now(), GetMockTime()); if (m_print_to_console) { // print to console diff --git a/src/logging.h b/src/logging.h index 7411d33f5f0..6ad6739adf8 100644 --- a/src/logging.h +++ b/src/logging.h @@ -184,8 +184,8 @@ namespace BCLog { struct BufferedLog { SystemClock::time_point now; std::chrono::seconds mocktime; - std::string str, logging_function, source_file, threadname; - int source_line; + std::string str, threadname; + std::source_location source_loc; LogFlags category; Level level; }; @@ -210,7 +210,7 @@ namespace BCLog { /** Log categories bitfield. */ std::atomic m_categories{BCLog::NONE}; - void FormatLogStrInPlace(std::string& str, LogFlags category, Level level, std::string_view source_file, int source_line, std::string_view logging_function, std::string_view threadname, SystemClock::time_point now, std::chrono::seconds mocktime) const; + void FormatLogStrInPlace(std::string& str, LogFlags category, Level level, const std::source_location& source_loc, std::string_view threadname, SystemClock::time_point now, std::chrono::seconds mocktime) const; std::string LogTimestampStr(SystemClock::time_point now, std::chrono::seconds mocktime) const; @@ -218,7 +218,7 @@ namespace BCLog { std::list> m_print_callbacks GUARDED_BY(m_cs) {}; /** Send a string to the log output (internal) */ - void LogPrintStr_(std::string_view str, std::string_view logging_function, std::string_view source_file, int source_line, BCLog::LogFlags category, BCLog::Level level) + void LogPrintStr_(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level) EXCLUSIVE_LOCKS_REQUIRED(m_cs); std::string GetLogPrefix(LogFlags category, Level level) const; @@ -237,7 +237,7 @@ namespace BCLog { std::atomic m_reopen_file{false}; /** Send a string to the log output */ - void LogPrintStr(std::string_view str, std::string_view logging_function, std::string_view source_file, int source_line, BCLog::LogFlags category, BCLog::Level level) + void LogPrintStr(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level) EXCLUSIVE_LOCKS_REQUIRED(!m_cs); /** Returns whether logs will be written to any output */ @@ -334,7 +334,7 @@ static inline bool LogAcceptCategory(BCLog::LogFlags category, BCLog::Level leve bool GetLogCategory(BCLog::LogFlags& flag, std::string_view str); template -inline void LogPrintFormatInternal(std::string_view logging_function, std::string_view source_file, const int source_line, const BCLog::LogFlags flag, const BCLog::Level level, util::ConstevalFormatString fmt, const Args&... args) +inline void LogPrintFormatInternal(std::source_location&& source_loc, const BCLog::LogFlags flag, const BCLog::Level level, util::ConstevalFormatString fmt, const Args&... args) { if (LogInstance().Enabled()) { std::string log_msg; @@ -343,11 +343,11 @@ inline void LogPrintFormatInternal(std::string_view logging_function, std::strin } catch (tinyformat::format_error& fmterr) { log_msg = "Error \"" + std::string{fmterr.what()} + "\" while formatting log message: " + fmt.fmt; } - LogInstance().LogPrintStr(log_msg, logging_function, source_file, source_line, flag, level); + LogInstance().LogPrintStr(log_msg, std::move(source_loc), flag, level); } } -#define LogPrintLevel_(category, level, ...) LogPrintFormatInternal(__func__, __FILE__, __LINE__, category, level, __VA_ARGS__) +#define LogPrintLevel_(category, level, ...) LogPrintFormatInternal(std::source_location::current(), category, level, __VA_ARGS__) // Log unconditionally. // Be conservative when using functions that unconditionally log to debug.log! diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index 5d24ad771c2..8cf0735b086 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -7,12 +7,16 @@ #include #include #include +#include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -88,25 +92,34 @@ BOOST_AUTO_TEST_CASE(logging_timer) BOOST_FIXTURE_TEST_CASE(logging_LogPrintStr, LogSetup) { LogInstance().m_log_sourcelocations = true; - LogInstance().LogPrintStr("foo1: bar1", "fn1", "src1", 1, BCLog::LogFlags::NET, BCLog::Level::Debug); - LogInstance().LogPrintStr("foo2: bar2", "fn2", "src2", 2, BCLog::LogFlags::NET, BCLog::Level::Info); - LogInstance().LogPrintStr("foo3: bar3", "fn3", "src3", 3, BCLog::LogFlags::ALL, BCLog::Level::Debug); - LogInstance().LogPrintStr("foo4: bar4", "fn4", "src4", 4, BCLog::LogFlags::ALL, BCLog::Level::Info); - LogInstance().LogPrintStr("foo5: bar5", "fn5", "src5", 5, BCLog::LogFlags::NONE, BCLog::Level::Debug); - LogInstance().LogPrintStr("foo6: bar6", "fn6", "src6", 6, BCLog::LogFlags::NONE, BCLog::Level::Info); + + struct Case { + std::string msg; + BCLog::LogFlags category; + BCLog::Level level; + std::string prefix; + std::source_location loc; + }; + + std::vector cases = { + {"foo1: bar1", BCLog::NET, BCLog::Level::Debug, "[net] ", std::source_location::current()}, + {"foo2: bar2", BCLog::NET, BCLog::Level::Info, "[net:info] ", std::source_location::current()}, + {"foo3: bar3", BCLog::ALL, BCLog::Level::Debug, "[debug] ", std::source_location::current()}, + {"foo4: bar4", BCLog::ALL, BCLog::Level::Info, "", std::source_location::current()}, + {"foo5: bar5", BCLog::NONE, BCLog::Level::Debug, "[debug] ", std::source_location::current()}, + {"foo6: bar6", BCLog::NONE, BCLog::Level::Info, "", std::source_location::current()}, + }; + + std::vector expected; + for (auto& [msg, category, level, prefix, loc] : cases) { + expected.push_back(tfm::format("[%s:%s] [%s] %s%s", util::RemovePrefix(loc.file_name(), "./"), loc.line(), loc.function_name(), prefix, msg)); + LogInstance().LogPrintStr(msg, std::move(loc), category, level); + } std::ifstream file{tmp_log_path}; std::vector log_lines; for (std::string log; std::getline(file, log);) { log_lines.push_back(log); } - std::vector expected = { - "[src1:1] [fn1] [net] foo1: bar1", - "[src2:2] [fn2] [net:info] foo2: bar2", - "[src3:3] [fn3] [debug] foo3: bar3", - "[src4:4] [fn4] foo4: bar4", - "[src5:5] [fn5] [debug] foo5: bar5", - "[src6:6] [fn6] foo6: bar6", - }; BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), expected.begin(), expected.end()); } diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index c5e3c33b14d..12a82ced9c3 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -84,7 +84,7 @@ def test_negated_config(self): self.log.debug('Verifying that disabling of the config file means garbage inside of it does ' \ 'not prevent the node from starting, and message about existing config file is logged') - ignored_file_message = [f'[InitConfig] Data directory "{self.nodes[0].datadir_path}" contains a "bitcoin.conf" file which is explicitly ignored using -noconf.'] + ignored_file_message = [f'Data directory "{self.nodes[0].datadir_path}" contains a "bitcoin.conf" file which is explicitly ignored using -noconf.'] with self.nodes[0].assert_debug_log(timeout=60, expected_msgs=ignored_file_message): self.start_node(0, extra_args=settings + ['-noconf']) self.stop_node(0) From 0b6b096421ac9d1c7b0542ea147562269e1c5bec Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Thu, 5 Jun 2025 13:42:03 -0400 Subject: [PATCH 118/314] log: Add rate limiting to LogPrintf, LogInfo, LogWarning, LogError, LogPrintLevel To mitigate disk-filling attacks caused by unsafe usages of LogPrintf and friends, we rate-limit them by passing a should_ratelimit bool that eventually makes its way to LogPrintStr which may call LogRateLimiter::Consume. The rate limiting is accomplished by adding a LogRateLimiter member to BCLog::Logger which tracks source code locations for the given logging window. Every hour, a source location can log up to 1MiB of data. Source locations that exceed the limit will have their logs suppressed for the rest of the window determined by m_limiter. This change affects the public LogPrintLevel function if called with a level >= BCLog::Level::Info. The UpdateTipLog function has been changed to use the private LogPrintLevel_ macro with should_ratelimit set to false. This allows UpdateTipLog to log during IBD without hitting the rate limit. Note that on restart, a source location that was rate limited before the restart will be able to log until it hits the rate limit again. Co-Authored-By: Niklas Gogge Co-Authored-By: stickies-v Github-Pull: #32604 Rebased-From: d541409a64c60d127ff912dad9dea949d45dbd8c --- src/init.cpp | 5 ++ src/logging.cpp | 35 +++++++++--- src/logging.h | 45 ++++++++++------ src/test/logging_tests.cpp | 107 ++++++++++++++++++++++++++++++++++++- src/validation.cpp | 20 +++---- 5 files changed, 181 insertions(+), 31 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 7fdbf75dc66..0127fa3b452 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1384,6 +1384,11 @@ 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)); + assert(!node.validation_signals); node.validation_signals = std::make_unique(std::make_unique(scheduler)); auto& validation_signals = *node.validation_signals; diff --git a/src/logging.cpp b/src/logging.cpp index 65cd993d7d0..a090803652c 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -75,7 +75,7 @@ bool BCLog::Logger::StartLogging() // dump buffered messages from before we opened the log m_buffering = false; if (m_buffer_lines_discarded > 0) { - LogPrintStr_(strprintf("Early logging buffer overflowed, %d log lines discarded.\n", m_buffer_lines_discarded), std::source_location::current(), BCLog::ALL, Level::Info); + LogPrintStr_(strprintf("Early logging buffer overflowed, %d log lines discarded.\n", m_buffer_lines_discarded), std::source_location::current(), BCLog::ALL, Level::Info, /*should_ratelimit=*/false); } while (!m_msgs_before_open.empty()) { const auto& buflog = m_msgs_before_open.front(); @@ -412,13 +412,14 @@ void BCLog::Logger::FormatLogStrInPlace(std::string& str, BCLog::LogFlags catego str.insert(0, LogTimestampStr(now, mocktime)); } -void BCLog::Logger::LogPrintStr(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level) +void BCLog::Logger::LogPrintStr(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit) { StdLockGuard scoped_lock(m_cs); - return LogPrintStr_(str, std::move(source_loc), category, level); + return LogPrintStr_(str, std::move(source_loc), category, level, should_ratelimit); } -void BCLog::Logger::LogPrintStr_(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level) +// NOLINTNEXTLINE(misc-no-recursion) +void BCLog::Logger::LogPrintStr_(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit) { std::string str_prefixed = LogEscapeMessage(str); @@ -451,6 +452,28 @@ void BCLog::Logger::LogPrintStr_(std::string_view str, std::source_location&& so } FormatLogStrInPlace(str_prefixed, category, level, source_loc, util::ThreadGetInternalName(), SystemClock::now(), GetMockTime()); + bool ratelimit{false}; + if (should_ratelimit && m_limiter) { + auto status{m_limiter->Consume(source_loc, str_prefixed)}; + if (status == BCLog::LogRateLimiter::Status::NEWLY_SUPPRESSED) { + // NOLINTNEXTLINE(misc-no-recursion) + LogPrintStr_(strprintf( + "Excessive logging detected from %s:%d (%s): >%d bytes logged during " + "the last time window of %is. Suppressing logging to disk from this " + "source location until time window resets. Console logging " + "unaffected. Last log entry.\n", + source_loc.file_name(), source_loc.line(), source_loc.function_name(), + m_limiter->m_max_bytes, + Ticks(m_limiter->m_reset_window)), + std::source_location::current(), LogFlags::ALL, Level::Warning, /*should_ratelimit=*/false); // with should_ratelimit=false, this cannot lead to infinite recursion + } + ratelimit = status == BCLog::LogRateLimiter::Status::STILL_SUPPRESSED; + // To avoid confusion caused by dropped log messages when debugging an issue, + // we prefix log lines with "[*]" when there are any suppressed source locations. + if (m_limiter->SuppressionsActive()) { + str_prefixed.insert(0, "[*] "); + } + } if (m_print_to_console) { // print to console @@ -460,7 +483,7 @@ void BCLog::Logger::LogPrintStr_(std::string_view str, std::source_location&& so for (const auto& cb : m_print_callbacks) { cb(str_prefixed); } - if (m_print_to_file) { + if (m_print_to_file && !ratelimit) { assert(m_fileout != nullptr); // reopen the log file, if requested @@ -530,7 +553,7 @@ void BCLog::LogRateLimiter::Reset() uint64_t dropped_bytes{counter.GetDroppedBytes()}; if (dropped_bytes == 0) continue; LogPrintLevel_( - LogFlags::ALL, Level::Info, + LogFlags::ALL, Level::Info, /*should_ratelimit=*/false, "Restarting logging from %s:%d (%s): %d bytes were dropped during the last %ss.\n", source_loc.file_name(), source_loc.line(), source_loc.function_name(), dropped_bytes, Ticks(m_reset_window)); diff --git a/src/logging.h b/src/logging.h index 6ad6739adf8..c801e94e289 100644 --- a/src/logging.h +++ b/src/logging.h @@ -200,6 +200,9 @@ namespace BCLog { size_t m_cur_buffer_memusage GUARDED_BY(m_cs){0}; size_t m_buffer_lines_discarded GUARDED_BY(m_cs){0}; + //! Manages the rate limiting of each log location. + std::unique_ptr m_limiter GUARDED_BY(m_cs); + //! Category-specific log level. Overrides `m_log_level`. std::unordered_map m_category_log_levels GUARDED_BY(m_cs); @@ -218,7 +221,7 @@ namespace BCLog { std::list> m_print_callbacks GUARDED_BY(m_cs) {}; /** Send a string to the log output (internal) */ - void LogPrintStr_(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level) + void LogPrintStr_(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit) EXCLUSIVE_LOCKS_REQUIRED(m_cs); std::string GetLogPrefix(LogFlags category, Level level) const; @@ -237,7 +240,7 @@ namespace BCLog { std::atomic m_reopen_file{false}; /** Send a string to the log output */ - void LogPrintStr(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level) + void LogPrintStr(std::string_view str, std::source_location&& source_loc, BCLog::LogFlags category, BCLog::Level level, bool should_ratelimit) EXCLUSIVE_LOCKS_REQUIRED(!m_cs); /** Returns whether logs will be written to any output */ @@ -267,6 +270,12 @@ namespace BCLog { /** Only for testing */ void DisconnectTestLogger() EXCLUSIVE_LOCKS_REQUIRED(!m_cs); + void SetRateLimiting(std::unique_ptr&& limiter) EXCLUSIVE_LOCKS_REQUIRED(!m_cs) + { + StdLockGuard scoped_lock(m_cs); + m_limiter = std::move(limiter); + } + /** Disable logging * This offers a slight speedup and slightly smaller memory usage * compared to leaving the logging system in its default state. @@ -334,7 +343,7 @@ static inline bool LogAcceptCategory(BCLog::LogFlags category, BCLog::Level leve bool GetLogCategory(BCLog::LogFlags& flag, std::string_view str); template -inline void LogPrintFormatInternal(std::source_location&& source_loc, const BCLog::LogFlags flag, const BCLog::Level level, util::ConstevalFormatString fmt, const Args&... args) +inline void LogPrintFormatInternal(std::source_location&& source_loc, const BCLog::LogFlags flag, const BCLog::Level level, const bool should_ratelimit, util::ConstevalFormatString fmt, const Args&... args) { if (LogInstance().Enabled()) { std::string log_msg; @@ -343,19 +352,19 @@ inline void LogPrintFormatInternal(std::source_location&& source_loc, const BCLo } catch (tinyformat::format_error& fmterr) { log_msg = "Error \"" + std::string{fmterr.what()} + "\" while formatting log message: " + fmt.fmt; } - LogInstance().LogPrintStr(log_msg, std::move(source_loc), flag, level); + LogInstance().LogPrintStr(log_msg, std::move(source_loc), flag, level, should_ratelimit); } } -#define LogPrintLevel_(category, level, ...) LogPrintFormatInternal(std::source_location::current(), category, level, __VA_ARGS__) +#define LogPrintLevel_(category, level, should_ratelimit, ...) LogPrintFormatInternal(std::source_location::current(), category, level, should_ratelimit, __VA_ARGS__) -// Log unconditionally. +// Log unconditionally. Uses basic rate limiting to mitigate disk filling attacks. // Be conservative when using functions that unconditionally log to debug.log! // It should not be the case that an inbound peer can fill up a user's storage // with debug.log entries. -#define LogInfo(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Info, __VA_ARGS__) -#define LogWarning(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Warning, __VA_ARGS__) -#define LogError(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Error, __VA_ARGS__) +#define LogInfo(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Info, /*should_ratelimit=*/true, __VA_ARGS__) +#define LogWarning(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Warning, /*should_ratelimit=*/true, __VA_ARGS__) +#define LogError(...) LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Error, /*should_ratelimit=*/true, __VA_ARGS__) // Deprecated unconditional logging. #define LogPrintf(...) LogInfo(__VA_ARGS__) @@ -363,12 +372,18 @@ inline void LogPrintFormatInternal(std::source_location&& source_loc, const BCLo // Use a macro instead of a function for conditional logging to prevent // evaluating arguments when logging for the category is not enabled. -// Log conditionally, prefixing the output with the passed category name and severity level. -#define LogPrintLevel(category, level, ...) \ - do { \ - if (LogAcceptCategory((category), (level))) { \ - LogPrintLevel_(category, level, __VA_ARGS__); \ - } \ +// Log by prefixing the output with the passed category name and severity level. This can either +// log conditionally if the category is allowed or unconditionally if level >= BCLog::Level::Info +// is passed. If this function logs unconditionally, logging to disk is rate-limited. This is +// important so that callers don't need to worry about accidentally introducing a disk-fill +// vulnerability if level >= Info is used. Additionally, users specifying -debug are assumed to be +// developers or power users who are aware that -debug may cause excessive disk usage due to logging. +#define LogPrintLevel(category, level, ...) \ + do { \ + if (LogAcceptCategory((category), (level))) { \ + bool rate_limit{level >= BCLog::Level::Info}; \ + LogPrintLevel_(category, level, rate_limit, __VA_ARGS__); \ + } \ } while (0) // Log conditionally, prefixing the output with the passed category name. diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index 8cf0735b086..f7f9ea175a0 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -15,8 +16,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -113,7 +116,7 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintStr, LogSetup) std::vector expected; for (auto& [msg, category, level, prefix, loc] : cases) { expected.push_back(tfm::format("[%s:%s] [%s] %s%s", util::RemovePrefix(loc.file_name(), "./"), loc.line(), loc.function_name(), prefix, msg)); - LogInstance().LogPrintStr(msg, std::move(loc), category, level); + LogInstance().LogPrintStr(msg, std::move(loc), category, level, /*should_ratelimit=*/false); } std::ifstream file{tmp_log_path}; std::vector log_lines; @@ -366,4 +369,106 @@ BOOST_AUTO_TEST_CASE(logging_log_limit_stats) BOOST_CHECK_EQUAL(counter.GetDroppedBytes(), 500ull); } +void LogFromLocation(int location, std::string message) +{ + switch (location) { + case 0: + LogInfo("%s\n", message); + break; + case 1: + LogInfo("%s\n", message); + break; + case 2: + LogPrintLevel(BCLog::LogFlags::NONE, BCLog::Level::Info, "%s\n", message); + break; + case 3: + LogPrintLevel(BCLog::LogFlags::ALL, BCLog::Level::Info, "%s\n", message); + break; + } +} + +void LogFromLocationAndExpect(int location, std::string message, std::string expect) +{ + ASSERT_DEBUG_LOG(expect); + LogFromLocation(location, message); +} + +BOOST_FIXTURE_TEST_CASE(logging_filesize_rate_limit, LogSetup) +{ + bool prev_log_timestamps = LogInstance().m_log_timestamps; + LogInstance().m_log_timestamps = false; + bool prev_log_sourcelocations = LogInstance().m_log_sourcelocations; + LogInstance().m_log_sourcelocations = false; + bool prev_log_threadnames = LogInstance().m_log_threadnames; + LogInstance().m_log_threadnames = false; + + CScheduler scheduler{}; + scheduler.m_service_thread = std::thread([&] { scheduler.serviceQueue(); }); + auto sched_func = [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }; + auto limiter = std::make_unique(sched_func, 1024 * 1024, 20s); + LogInstance().SetRateLimiting(std::move(limiter)); + + // Log 1024-character lines (1023 plus newline) to make the math simple. + std::string log_message(1023, 'a'); + + std::string utf8_path{LogInstance().m_file_path.utf8string()}; + const char* log_path{utf8_path.c_str()}; + + // Use GetFileSize because fs::file_size may require a flush to be accurate. + std::streamsize log_file_size{static_cast(GetFileSize(log_path))}; + + // Logging 1 MiB should be allowed. + for (int i = 0; i < 1024; ++i) { + LogFromLocation(0, log_message); + } + BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "should be able to log 1 MiB from location 0"); + + log_file_size = GetFileSize(log_path); + + BOOST_CHECK_NO_THROW(LogFromLocationAndExpect(0, log_message, "Excessive logging detected")); + BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "the start of the suppression period should be logged"); + + log_file_size = GetFileSize(log_path); + for (int i = 0; i < 1024; ++i) { + LogFromLocation(0, log_message); + } + + BOOST_CHECK_MESSAGE(log_file_size == GetFileSize(log_path), "all further logs from location 0 should be dropped"); + + BOOST_CHECK_THROW(LogFromLocationAndExpect(1, log_message, "Excessive logging detected"), std::runtime_error); + BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "location 1 should be unaffected by other locations"); + + log_file_size = GetFileSize(log_path); + { + ASSERT_DEBUG_LOG("Restarting logging"); + MockForwardAndSync(scheduler, 1min); + } + + BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "the end of the suppression period should be logged"); + + BOOST_CHECK_THROW(LogFromLocationAndExpect(1, log_message, "Restarting logging"), std::runtime_error); + + // Attempt to log 1MiB from location 2 and 1MiB from location 3. These exempt locations should be allowed to log + // without limit. + log_file_size = GetFileSize(log_path); + for (int i = 0; i < 1024; ++i) { + BOOST_CHECK_THROW(LogFromLocationAndExpect(2, log_message, "Excessive logging detected"), std::runtime_error); + } + + BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "location 2 should be exempt from rate limiting"); + + log_file_size = GetFileSize(log_path); + for (int i = 0; i < 1024; ++i) { + BOOST_CHECK_THROW(LogFromLocationAndExpect(3, log_message, "Excessive logging detected"), std::runtime_error); + } + + BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "location 3 should be exempt from rate limiting"); + + LogInstance().m_log_timestamps = prev_log_timestamps; + LogInstance().m_log_sourcelocations = prev_log_sourcelocations; + LogInstance().m_log_threadnames = prev_log_threadnames; + scheduler.stop(); + LogInstance().SetRateLimiting(nullptr); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/validation.cpp b/src/validation.cpp index a1ac4e1e145..fde064458dc 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2995,15 +2995,17 @@ static void UpdateTipLog( { AssertLockHeld(::cs_main); - LogPrintf("%s%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", - prefix, func_name, - tip->GetBlockHash().ToString(), tip->nHeight, tip->nVersion, - log(tip->nChainWork.getdouble()) / log(2.0), tip->m_chain_tx_count, - FormatISO8601DateTime(tip->GetBlockTime()), - chainman.GuessVerificationProgress(tip), - coins_tip.DynamicMemoryUsage() * (1.0 / (1 << 20)), - coins_tip.GetCacheSize(), - !warning_messages.empty() ? strprintf(" warning='%s'", warning_messages) : ""); + + // Disable rate limiting in LogPrintLevel_ so this source location may log during IBD. + LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Info, /*should_ratelimit=*/false, "%s%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", + prefix, func_name, + tip->GetBlockHash().ToString(), tip->nHeight, tip->nVersion, + log(tip->nChainWork.getdouble()) / log(2.0), tip->m_chain_tx_count, + FormatISO8601DateTime(tip->GetBlockTime()), + chainman.GuessVerificationProgress(tip), + coins_tip.DynamicMemoryUsage() * (1.0 / (1 << 20)), + coins_tip.GetCacheSize(), + !warning_messages.empty() ? strprintf(" warning='%s'", warning_messages) : ""); } void Chainstate::UpdateTip(const CBlockIndex* pindexNew) From 24c793d06c93768be88e9f8d0bb62936e199f68c Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Mon, 23 Jun 2025 15:57:44 -0400 Subject: [PATCH 119/314] doc: add release notes for new rate limiting logging behavior Github-Pull: #32604 Rebased-From: 4c772cbd83e502a1339e8993d192ea6416ecd45c --- doc/release-notes.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index e4cf2f0b50d..b384763e155 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -48,6 +48,17 @@ Notable changes - #32521 policy: make pathological transactions packed with legacy sigops non-standard +### Logging + +Unconditional logging to disk is now rate limited by giving each source location +a quota of 1MiB per hour. Unconditional logging is any logging with a log level +higher than debug, that is `info`, `warning`, and `error`. All logs will be +prefixed with `[*]` if there is at least one source location that is currently +being suppressed. (#32604) + +When `-logsourcelocations` is enabled, the log output now contains the entire +function signature instead of just the function name. (#32604) + ### RPC - The `dumptxoutset` RPC now requires a `type` parameter to be specified. To maintain pre @@ -163,6 +174,7 @@ Thanks to everyone who directly contributed to this release: - brunoerg - Bufo - Christewart +- Crypt-iQ - davidgumberg - deadmanoz - dergoegge From 25f975b8df8ac4692cdfe9c423f2903e97f34a2c Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Fri, 18 Jul 2025 09:27:50 -0400 Subject: [PATCH 120/314] test: remove noexcept(false) comment in ~DebugLogHelper Github-Pull: #33011 Rebased-From: 616bc22f131132b9239ef362dca8c6bce000a539 --- src/test/util/logging.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/util/logging.h b/src/test/util/logging.h index 5d7e4f91e0f..62b11c28410 100644 --- a/src/test/util/logging.h +++ b/src/test/util/logging.h @@ -33,8 +33,6 @@ class DebugLogHelper public: explicit DebugLogHelper(std::string message, MatchFn match = [](const std::string*){ return true; }); - - //! Mark as noexcept(false) to catch any thrown exceptions. ~DebugLogHelper() noexcept(false) { check_found(); } }; From 9cde68fa984571d68177152af0a029b43fef7bab Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Fri, 25 Jul 2025 16:39:33 -0400 Subject: [PATCH 121/314] log: avoid double hashing in SourceLocationHasher Co-Authored-By: l0rinc Github-Pull: #33011 Rebased-From: b8e92fb3d4137f91fe6a54829867fc54357da648 --- src/logging.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/logging.h b/src/logging.h index c801e94e289..33742dcbe68 100644 --- a/src/logging.h +++ b/src/logging.h @@ -46,10 +46,10 @@ struct SourceLocationHasher { size_t operator()(const std::source_location& s) const noexcept { // Use CSipHasher(0, 0) as a simple way to get uniform distribution. - return static_cast(CSipHasher(0, 0) - .Write(std::hash{}(s.file_name())) - .Write(s.line()) - .Finalize()); + return size_t(CSipHasher(0, 0) + .Write(s.line()) + .Write(MakeUCharSpan(std::string_view{s.file_name()})) + .Finalize()); } }; From 273ffda2c878954f30554bb88d286896d1177add Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Fri, 18 Jul 2025 09:43:43 -0400 Subject: [PATCH 122/314] log: remove const qualifier from arguments in LogPrintFormatInternal Co-Authored-By: l0rinc Github-Pull: #33011 Rebased-From: 5f70bc80df06ca85d44e8201d47e7086e971fdea --- src/logging.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logging.h b/src/logging.h index 33742dcbe68..c753172545c 100644 --- a/src/logging.h +++ b/src/logging.h @@ -343,7 +343,7 @@ static inline bool LogAcceptCategory(BCLog::LogFlags category, BCLog::Level leve bool GetLogCategory(BCLog::LogFlags& flag, std::string_view str); template -inline void LogPrintFormatInternal(std::source_location&& source_loc, const BCLog::LogFlags flag, const BCLog::Level level, const bool should_ratelimit, util::ConstevalFormatString fmt, const Args&... args) +inline void LogPrintFormatInternal(std::source_location&& source_loc, BCLog::LogFlags flag, BCLog::Level level, bool should_ratelimit, util::ConstevalFormatString fmt, const Args&... args) { if (LogInstance().Enabled()) { std::string log_msg; From dfe4e19f66e0acd4f14f726f29aeb6ef7d8506c4 Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Fri, 18 Jul 2025 10:04:35 -0400 Subject: [PATCH 123/314] log: clarify RATELIMIT_MAX_BYTES comment, use RATELIMIT_WINDOW Co-Authored-By: stickies-v Github-Pull: #33011 Rebased-From: 8319a134684df2240057a5e8afaa6ae441fb8a58 --- src/init.cpp | 2 +- src/logging.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 0127fa3b452..9e9cb5d732f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1387,7 +1387,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) LogInstance().SetRateLimiting(std::make_unique( [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }, BCLog::RATELIMIT_MAX_BYTES, - 1h)); + BCLog::RATELIMIT_WINDOW)); assert(!node.validation_signals); node.validation_signals = std::make_unique(std::make_unique(scheduler)); diff --git a/src/logging.h b/src/logging.h index c753172545c..106de1f8d30 100644 --- a/src/logging.h +++ b/src/logging.h @@ -104,7 +104,8 @@ namespace BCLog { }; constexpr auto DEFAULT_LOG_LEVEL{Level::Debug}; constexpr size_t DEFAULT_MAX_LOG_BUFFER{1'000'000}; // buffer up to 1MB of log data prior to StartLogging - constexpr uint64_t RATELIMIT_MAX_BYTES{1024 * 1024}; // maximum number of bytes that can be logged within one window + constexpr uint64_t RATELIMIT_MAX_BYTES{1024 * 1024}; // maximum number of bytes per source location that can be logged within the RATELIMIT_WINDOW + constexpr auto RATELIMIT_WINDOW{1h}; // time window after which log ratelimit stats are reset //! Keeps track of an individual source location and how many available bytes are left for logging from it. class LogLimitStats From 7c3820ff63d91c9f5173e514d74814a34e647bdb Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Fri, 18 Jul 2025 10:18:59 -0400 Subject: [PATCH 124/314] log: change LogLimitStats to struct LogRateLimiter::Stats Clean up the noisy LogLimitStats and remove references to the time window. Co-Authored-By: stickies-v Github-Pull: #33011 Rebased-From: 3c7cae49b692bb6bf5cae5ee23479091bed0b8be --- src/logging.cpp | 15 ++++++------ src/logging.h | 50 +++++++++++++------------------------- src/test/logging_tests.cpp | 30 +++++++++++------------ 3 files changed, 39 insertions(+), 56 deletions(-) diff --git a/src/logging.cpp b/src/logging.cpp index a090803652c..befac8a03f8 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -384,10 +384,10 @@ BCLog::LogRateLimiter::Status BCLog::LogRateLimiter::Consume( const std::string& str) { StdLockGuard scoped_lock(m_mutex); - auto& counter{m_source_locations.try_emplace(source_loc, m_max_bytes).first->second}; - Status status{counter.GetDroppedBytes() > 0 ? Status::STILL_SUPPRESSED : Status::UNSUPPRESSED}; + auto& stats{m_source_locations.try_emplace(source_loc, m_max_bytes).first->second}; + Status status{stats.m_dropped_bytes > 0 ? Status::STILL_SUPPRESSED : Status::UNSUPPRESSED}; - if (!counter.Consume(str.size()) && status == Status::UNSUPPRESSED) { + if (!stats.Consume(str.size()) && status == Status::UNSUPPRESSED) { status = Status::NEWLY_SUPPRESSED; m_suppression_active = true; } @@ -549,18 +549,17 @@ void BCLog::LogRateLimiter::Reset() source_locations.swap(m_source_locations); m_suppression_active = false; } - for (const auto& [source_loc, counter] : source_locations) { - uint64_t dropped_bytes{counter.GetDroppedBytes()}; - if (dropped_bytes == 0) continue; + for (const auto& [source_loc, stats] : source_locations) { + if (stats.m_dropped_bytes == 0) continue; LogPrintLevel_( LogFlags::ALL, Level::Info, /*should_ratelimit=*/false, "Restarting logging from %s:%d (%s): %d bytes were dropped during the last %ss.\n", source_loc.file_name(), source_loc.line(), source_loc.function_name(), - dropped_bytes, Ticks(m_reset_window)); + stats.m_dropped_bytes, Ticks(m_reset_window)); } } -bool BCLog::LogLimitStats::Consume(uint64_t bytes) +bool BCLog::LogRateLimiter::Stats::Consume(uint64_t bytes) { if (bytes > m_available_bytes) { m_dropped_bytes += bytes; diff --git a/src/logging.h b/src/logging.h index 106de1f8d30..04e6e0974c4 100644 --- a/src/logging.h +++ b/src/logging.h @@ -107,44 +107,28 @@ namespace BCLog { constexpr uint64_t RATELIMIT_MAX_BYTES{1024 * 1024}; // maximum number of bytes per source location that can be logged within the RATELIMIT_WINDOW constexpr auto RATELIMIT_WINDOW{1h}; // time window after which log ratelimit stats are reset - //! Keeps track of an individual source location and how many available bytes are left for logging from it. - class LogLimitStats + //! Fixed window rate limiter for logging. + class LogRateLimiter { - private: - //! Remaining bytes in the current window interval. - uint64_t m_available_bytes; - //! Number of bytes that were not consumed within the current window. - uint64_t m_dropped_bytes{0}; - public: - LogLimitStats(uint64_t max_bytes) : m_available_bytes{max_bytes} {} - //! Consume bytes from the window if enough bytes are available. - //! - //! Returns whether enough bytes were available. - bool Consume(uint64_t bytes); - - uint64_t GetAvailableBytes() const - { - return m_available_bytes; - } - - uint64_t GetDroppedBytes() const - { - return m_dropped_bytes; - } - }; + //! Keeps track of an individual source location and how many available bytes are left for logging from it. + struct Stats { + //! Remaining bytes + uint64_t m_available_bytes; + //! Number of bytes that were consumed but didn't fit in the available bytes. + uint64_t m_dropped_bytes{0}; + + Stats(uint64_t max_bytes) : m_available_bytes{max_bytes} {} + //! Updates internal accounting and returns true if enough available_bytes were remaining + bool Consume(uint64_t bytes); + }; - /** - * Fixed window rate limiter for logging. - */ - class LogRateLimiter - { private: mutable StdMutex m_mutex; - //! Counters for each source location that has attempted to log something. - std::unordered_map m_source_locations GUARDED_BY(m_mutex); - //! True if at least one log location is suppressed. Cached view on m_source_locations for performance reasons. + //! Stats for each source location that has attempted to log something. + std::unordered_map m_source_locations GUARDED_BY(m_mutex); + //! Whether any log locations are suppressed. Cached view on m_source_locations for performance reasons. std::atomic m_suppression_active{false}; public: @@ -155,7 +139,7 @@ namespace BCLog { * reset_window interval. * @param max_bytes Maximum number of bytes that can be logged for each source * location. - * @param reset_window Time window after which the byte counters are reset. + * @param reset_window Time window after which the stats are reset. */ LogRateLimiter(SchedulerFunction scheduler_func, uint64_t max_bytes, std::chrono::seconds reset_window); //! Maximum number of bytes logged per location per window. diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index f7f9ea175a0..3fd66470246 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -348,25 +348,25 @@ BOOST_AUTO_TEST_CASE(logging_log_rate_limiter) BOOST_AUTO_TEST_CASE(logging_log_limit_stats) { - BCLog::LogLimitStats counter{BCLog::RATELIMIT_MAX_BYTES}; + BCLog::LogRateLimiter::Stats stats(BCLog::RATELIMIT_MAX_BYTES); - // Check that counter gets initialized correctly. - BOOST_CHECK_EQUAL(counter.GetAvailableBytes(), BCLog::RATELIMIT_MAX_BYTES); - BOOST_CHECK_EQUAL(counter.GetDroppedBytes(), 0ull); + // Check that stats gets initialized correctly. + BOOST_CHECK_EQUAL(stats.m_available_bytes, BCLog::RATELIMIT_MAX_BYTES); + BOOST_CHECK_EQUAL(stats.m_dropped_bytes, uint64_t{0}); - const uint64_t MESSAGE_SIZE{512 * 1024}; - BOOST_CHECK(counter.Consume(MESSAGE_SIZE)); - BOOST_CHECK_EQUAL(counter.GetAvailableBytes(), BCLog::RATELIMIT_MAX_BYTES - MESSAGE_SIZE); - BOOST_CHECK_EQUAL(counter.GetDroppedBytes(), 0ull); + const uint64_t MESSAGE_SIZE{BCLog::RATELIMIT_MAX_BYTES / 2}; + BOOST_CHECK(stats.Consume(MESSAGE_SIZE)); + BOOST_CHECK_EQUAL(stats.m_available_bytes, BCLog::RATELIMIT_MAX_BYTES - MESSAGE_SIZE); + BOOST_CHECK_EQUAL(stats.m_dropped_bytes, uint64_t{0}); - BOOST_CHECK(counter.Consume(MESSAGE_SIZE)); - BOOST_CHECK_EQUAL(counter.GetAvailableBytes(), BCLog::RATELIMIT_MAX_BYTES - MESSAGE_SIZE * 2); - BOOST_CHECK_EQUAL(counter.GetDroppedBytes(), 0ull); + BOOST_CHECK(stats.Consume(MESSAGE_SIZE)); + BOOST_CHECK_EQUAL(stats.m_available_bytes, BCLog::RATELIMIT_MAX_BYTES - MESSAGE_SIZE * 2); + BOOST_CHECK_EQUAL(stats.m_dropped_bytes, uint64_t{0}); - // Consuming more bytes after already having consumed 1MB should fail. - BOOST_CHECK(!counter.Consume(500)); - BOOST_CHECK_EQUAL(counter.GetAvailableBytes(), 0ull); - BOOST_CHECK_EQUAL(counter.GetDroppedBytes(), 500ull); + // Consuming more bytes after already having consumed RATELIMIT_MAX_BYTES should fail. + BOOST_CHECK(!stats.Consume(500)); + BOOST_CHECK_EQUAL(stats.m_available_bytes, uint64_t{0}); + BOOST_CHECK_EQUAL(stats.m_dropped_bytes, uint64_t{500}); } void LogFromLocation(int location, std::string message) From 81751341e9b5582fc5645ff88c5dd67cbd09cf43 Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Fri, 18 Jul 2025 10:39:45 -0400 Subject: [PATCH 125/314] log: clean up LogPrintStr_ and Reset, prefix all logs with "[*]" when there are suppressions In LogPrintStr_: - remove an unnecessary BCLog since we are in the BCLog namespace. - remove an unnecessary \n when rate limiting is triggered since FormatLogStrInPlace will add it. - move the ratelimit bool into an else if block. - prefix all log lines with [*] when suppressions exist. Previously this was only done if should_ratelimit was true. In Reset: - remove an unnecessary \n since FormatLogStrInPlace will add it. - Change Level::Info to Level::Warning. Github-Pull: #33011 Rebased-From: e8f9c37a3b4c9c88baddb556c4b33a4cbba1f614 --- src/logging.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/logging.cpp b/src/logging.cpp index befac8a03f8..0cad2905047 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -455,24 +455,26 @@ void BCLog::Logger::LogPrintStr_(std::string_view str, std::source_location&& so bool ratelimit{false}; if (should_ratelimit && m_limiter) { auto status{m_limiter->Consume(source_loc, str_prefixed)}; - if (status == BCLog::LogRateLimiter::Status::NEWLY_SUPPRESSED) { + if (status == LogRateLimiter::Status::NEWLY_SUPPRESSED) { // NOLINTNEXTLINE(misc-no-recursion) LogPrintStr_(strprintf( "Excessive logging detected from %s:%d (%s): >%d bytes logged during " "the last time window of %is. Suppressing logging to disk from this " "source location until time window resets. Console logging " - "unaffected. Last log entry.\n", + "unaffected. Last log entry.", source_loc.file_name(), source_loc.line(), source_loc.function_name(), m_limiter->m_max_bytes, Ticks(m_limiter->m_reset_window)), std::source_location::current(), LogFlags::ALL, Level::Warning, /*should_ratelimit=*/false); // with should_ratelimit=false, this cannot lead to infinite recursion + } else if (status == LogRateLimiter::Status::STILL_SUPPRESSED) { + ratelimit = true; } - ratelimit = status == BCLog::LogRateLimiter::Status::STILL_SUPPRESSED; - // To avoid confusion caused by dropped log messages when debugging an issue, - // we prefix log lines with "[*]" when there are any suppressed source locations. - if (m_limiter->SuppressionsActive()) { - str_prefixed.insert(0, "[*] "); - } + } + + // To avoid confusion caused by dropped log messages when debugging an issue, + // we prefix log lines with "[*]" when there are any suppressed source locations. + if (m_limiter && m_limiter->SuppressionsActive()) { + str_prefixed.insert(0, "[*] "); } if (m_print_to_console) { @@ -552,8 +554,8 @@ void BCLog::LogRateLimiter::Reset() for (const auto& [source_loc, stats] : source_locations) { if (stats.m_dropped_bytes == 0) continue; LogPrintLevel_( - LogFlags::ALL, Level::Info, /*should_ratelimit=*/false, - "Restarting logging from %s:%d (%s): %d bytes were dropped during the last %ss.\n", + LogFlags::ALL, Level::Warning, /*should_ratelimit=*/false, + "Restarting logging from %s:%d (%s): %d bytes were dropped during the last %ss.", source_loc.file_name(), source_loc.line(), source_loc.function_name(), stats.m_dropped_bytes, Ticks(m_reset_window)); } From acfa83d9d000abd263d8cb5ac3355cfd8cf49ec0 Mon Sep 17 00:00:00 2001 From: stickies-v Date: Wed, 23 Jul 2025 22:06:37 +0100 Subject: [PATCH 126/314] log: make m_limiter a shared_ptr This allows us to safely and explicitly manage the dual dependency on the limiter: one for the Logger, and one for the CScheduler. Github-Pull: #33011 Rebased-From: 3d630c2544e19480268426cda245796d4ce34ac3 --- src/init.cpp | 2 +- src/logging.cpp | 19 +++++++++++++------ src/logging.h | 11 ++++++++--- src/test/logging_tests.cpp | 8 +++++--- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 9e9cb5d732f..fa7ac6077d2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1384,7 +1384,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } }, std::chrono::minutes{5}); - LogInstance().SetRateLimiting(std::make_unique( + LogInstance().SetRateLimiting(BCLog::LogRateLimiter::Create( [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }, BCLog::RATELIMIT_MAX_BYTES, BCLog::RATELIMIT_WINDOW)); diff --git a/src/logging.cpp b/src/logging.cpp index 0cad2905047..2ed6835197b 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -371,12 +371,19 @@ static size_t MemUsage(const BCLog::Logger::BufferedLog& buflog) memusage::MallocUsage(sizeof(memusage::list_node)); } -BCLog::LogRateLimiter::LogRateLimiter( - SchedulerFunction scheduler_func, - uint64_t max_bytes, - std::chrono::seconds reset_window) : m_max_bytes{max_bytes}, m_reset_window{reset_window} -{ - scheduler_func([this] { Reset(); }, reset_window); +BCLog::LogRateLimiter::LogRateLimiter(uint64_t max_bytes, std::chrono::seconds reset_window) + : m_max_bytes{max_bytes}, m_reset_window{reset_window} {} + +std::shared_ptr BCLog::LogRateLimiter::Create( + SchedulerFunction&& scheduler_func, uint64_t max_bytes, std::chrono::seconds reset_window) +{ + auto limiter{std::shared_ptr(new LogRateLimiter(max_bytes, reset_window))}; + std::weak_ptr weak_limiter{limiter}; + auto reset = [weak_limiter] { + if (auto shared_limiter{weak_limiter.lock()}) shared_limiter->Reset(); + }; + scheduler_func(reset, limiter->m_reset_window); + return limiter; } BCLog::LogRateLimiter::Status BCLog::LogRateLimiter::Consume( diff --git a/src/logging.h b/src/logging.h index 04e6e0974c4..9419e245bdf 100644 --- a/src/logging.h +++ b/src/logging.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -130,6 +131,7 @@ namespace BCLog { std::unordered_map m_source_locations GUARDED_BY(m_mutex); //! Whether any log locations are suppressed. Cached view on m_source_locations for performance reasons. std::atomic m_suppression_active{false}; + LogRateLimiter(uint64_t max_bytes, std::chrono::seconds reset_window); public: using SchedulerFunction = std::function, std::chrono::milliseconds)>; @@ -141,7 +143,10 @@ namespace BCLog { * location. * @param reset_window Time window after which the stats are reset. */ - LogRateLimiter(SchedulerFunction scheduler_func, uint64_t max_bytes, std::chrono::seconds reset_window); + static std::shared_ptr Create( + SchedulerFunction&& scheduler_func, + uint64_t max_bytes, + std::chrono::seconds reset_window); //! Maximum number of bytes logged per location per window. const uint64_t m_max_bytes; //! Interval after which the window is reset. @@ -186,7 +191,7 @@ namespace BCLog { size_t m_buffer_lines_discarded GUARDED_BY(m_cs){0}; //! Manages the rate limiting of each log location. - std::unique_ptr m_limiter GUARDED_BY(m_cs); + std::shared_ptr m_limiter GUARDED_BY(m_cs); //! Category-specific log level. Overrides `m_log_level`. std::unordered_map m_category_log_levels GUARDED_BY(m_cs); @@ -255,7 +260,7 @@ namespace BCLog { /** Only for testing */ void DisconnectTestLogger() EXCLUSIVE_LOCKS_REQUIRED(!m_cs); - void SetRateLimiting(std::unique_ptr&& limiter) EXCLUSIVE_LOCKS_REQUIRED(!m_cs) + void SetRateLimiting(std::shared_ptr limiter) EXCLUSIVE_LOCKS_REQUIRED(!m_cs) { StdLockGuard scoped_lock(m_cs); m_limiter = std::move(limiter); diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index 3fd66470246..41c0b1dd32f 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -69,6 +69,7 @@ struct LogSetup : public BasicTestingSetup { LogInstance().SetLogLevel(BCLog::Level::Debug); LogInstance().SetCategoryLogLevel({}); + LogInstance().SetRateLimiting(nullptr); } ~LogSetup() @@ -82,6 +83,7 @@ struct LogSetup : public BasicTestingSetup { LogInstance().m_log_sourcelocations = prev_log_sourcelocations; LogInstance().SetLogLevel(prev_log_level); LogInstance().SetCategoryLogLevel(prev_category_levels); + LogInstance().SetRateLimiting(nullptr); } }; @@ -309,7 +311,8 @@ BOOST_AUTO_TEST_CASE(logging_log_rate_limiter) uint64_t max_bytes{1024}; auto reset_window{1min}; auto sched_func = [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }; - BCLog::LogRateLimiter limiter{sched_func, max_bytes, reset_window}; + auto limiter_{BCLog::LogRateLimiter::Create(sched_func, max_bytes, reset_window)}; + auto& limiter{*limiter_}; using Status = BCLog::LogRateLimiter::Status; auto source_loc_1{std::source_location::current()}; @@ -405,8 +408,7 @@ BOOST_FIXTURE_TEST_CASE(logging_filesize_rate_limit, LogSetup) CScheduler scheduler{}; scheduler.m_service_thread = std::thread([&] { scheduler.serviceQueue(); }); auto sched_func = [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }; - auto limiter = std::make_unique(sched_func, 1024 * 1024, 20s); - LogInstance().SetRateLimiting(std::move(limiter)); + LogInstance().SetRateLimiting(BCLog::LogRateLimiter::Create(sched_func, 1024 * 1024, 20s)); // Log 1024-character lines (1023 plus newline) to make the math simple. std::string log_message(1023, 'a'); From 4ed7a51642dfa83159be7207c158dc7544d35f65 Mon Sep 17 00:00:00 2001 From: stickies-v Date: Wed, 23 Jul 2025 22:29:01 +0100 Subject: [PATCH 127/314] test: add ReadDebugLogLines helper function Deduplicates repeated usage of the same functionality. Github-Pull: #33011 Rebased-From: 05d7c22479bf96bab9f8c8b8fa90368429ad2c88 --- src/test/logging_tests.cpp | 40 ++++++++++++++------------------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index 41c0b1dd32f..bb898eb141c 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -37,6 +37,16 @@ static void ResetLogger() LogInstance().SetCategoryLogLevel({}); } +static std::vector ReadDebugLogLines() +{ + std::vector lines; + std::ifstream ifs{LogInstance().m_file_path}; + for (std::string line; std::getline(ifs, line);) { + lines.push_back(std::move(line)); + } + return lines; +} + struct LogSetup : public BasicTestingSetup { fs::path prev_log_path; fs::path tmp_log_path; @@ -120,11 +130,7 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintStr, LogSetup) expected.push_back(tfm::format("[%s:%s] [%s] %s%s", util::RemovePrefix(loc.file_name(), "./"), loc.line(), loc.function_name(), prefix, msg)); LogInstance().LogPrintStr(msg, std::move(loc), category, level, /*should_ratelimit=*/false); } - std::ifstream file{tmp_log_path}; - std::vector log_lines; - for (std::string log; std::getline(file, log);) { - log_lines.push_back(log); - } + std::vector log_lines{ReadDebugLogLines()}; BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), expected.begin(), expected.end()); } @@ -136,11 +142,7 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacrosDeprecated, LogSetup) LogPrintLevel(BCLog::NET, BCLog::Level::Info, "foo8: %s\n", "bar8"); LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "foo9: %s\n", "bar9"); LogPrintLevel(BCLog::NET, BCLog::Level::Error, "foo10: %s\n", "bar10"); - std::ifstream file{tmp_log_path}; - std::vector log_lines; - for (std::string log; std::getline(file, log);) { - log_lines.push_back(log); - } + std::vector log_lines{ReadDebugLogLines()}; std::vector expected = { "foo5: bar5", "[net] foo7: bar7", @@ -158,11 +160,7 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacros, LogSetup) LogInfo("foo8: %s", "bar8"); LogWarning("foo9: %s", "bar9"); LogError("foo10: %s", "bar10"); - std::ifstream file{tmp_log_path}; - std::vector log_lines; - for (std::string log; std::getline(file, log);) { - log_lines.push_back(log); - } + std::vector log_lines{ReadDebugLogLines()}; std::vector expected = { "[net] foo7: bar7", "foo8: bar8", @@ -194,11 +192,7 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacros_CategoryName, LogSetup) expected.push_back(expected_log); } - std::ifstream file{tmp_log_path}; - std::vector log_lines; - for (std::string log; std::getline(file, log);) { - log_lines.push_back(log); - } + std::vector log_lines{ReadDebugLogLines()}; BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), expected.begin(), expected.end()); } @@ -227,11 +221,7 @@ BOOST_FIXTURE_TEST_CASE(logging_SeverityLevels, LogSetup) "[net:warning] foo5: bar5", "[net:error] foo7: bar7", }; - std::ifstream file{tmp_log_path}; - std::vector log_lines; - for (std::string log; std::getline(file, log);) { - log_lines.push_back(log); - } + std::vector log_lines{ReadDebugLogLines()}; BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), expected.begin(), expected.end()); } From 11538160b3d9a44990ac2c3a766764198a7e9127 Mon Sep 17 00:00:00 2001 From: stickies-v Date: Thu, 31 Jul 2025 12:18:06 +0100 Subject: [PATCH 128/314] test: don't leak log category mask across tests This ensures log tests behave consistently when other tests modify the log category mask. Github-Pull: #33011 Rebased-From: 350193e5e2efabb3eb66197b91869b946ec5428c --- src/test/logging_tests.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index bb898eb141c..f3100dac9ba 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -57,6 +57,7 @@ struct LogSetup : public BasicTestingSetup { bool prev_log_sourcelocations; std::unordered_map prev_category_levels; BCLog::Level prev_log_level; + BCLog::CategoryMask prev_category_mask; LogSetup() : prev_log_path{LogInstance().m_file_path}, tmp_log_path{m_args.GetDataDirBase() / "tmp_debug.log"}, @@ -66,7 +67,8 @@ struct LogSetup : public BasicTestingSetup { prev_log_threadnames{LogInstance().m_log_threadnames}, prev_log_sourcelocations{LogInstance().m_log_sourcelocations}, prev_category_levels{LogInstance().CategoryLevels()}, - prev_log_level{LogInstance().LogLevel()} + prev_log_level{LogInstance().LogLevel()}, + prev_category_mask{LogInstance().GetCategoryMask()} { LogInstance().m_file_path = tmp_log_path; LogInstance().m_reopen_file = true; @@ -78,6 +80,7 @@ struct LogSetup : public BasicTestingSetup { LogInstance().m_log_sourcelocations = false; LogInstance().SetLogLevel(BCLog::Level::Debug); + LogInstance().DisableCategory(BCLog::LogFlags::ALL); LogInstance().SetCategoryLogLevel({}); LogInstance().SetRateLimiting(nullptr); } @@ -94,6 +97,8 @@ struct LogSetup : public BasicTestingSetup { LogInstance().SetLogLevel(prev_log_level); LogInstance().SetCategoryLogLevel(prev_category_levels); LogInstance().SetRateLimiting(nullptr); + LogInstance().DisableCategory(BCLog::LogFlags::ALL); + LogInstance().EnableCategory(BCLog::LogFlags{prev_category_mask}); } }; @@ -136,6 +141,7 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintStr, LogSetup) BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacrosDeprecated, LogSetup) { + LogInstance().EnableCategory(BCLog::NET); LogPrintf("foo5: %s\n", "bar5"); LogPrintLevel(BCLog::NET, BCLog::Level::Trace, "foo4: %s\n", "bar4"); // not logged LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "foo7: %s\n", "bar7"); @@ -155,6 +161,7 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacrosDeprecated, LogSetup) BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacros, LogSetup) { + LogInstance().EnableCategory(BCLog::NET); LogTrace(BCLog::NET, "foo6: %s", "bar6"); // not logged LogDebug(BCLog::NET, "foo7: %s", "bar7"); LogInfo("foo8: %s", "bar8"); @@ -199,8 +206,6 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacros_CategoryName, LogSetup) BOOST_FIXTURE_TEST_CASE(logging_SeverityLevels, LogSetup) { LogInstance().EnableCategory(BCLog::LogFlags::ALL); - - LogInstance().SetLogLevel(BCLog::Level::Debug); LogInstance().SetCategoryLogLevel(/*category_str=*/"net", /*level_str=*/"info"); // Global log level From dfdd407c428030171213496c0cc2f30517bb86a1 Mon Sep 17 00:00:00 2001 From: stickies-v Date: Wed, 23 Jul 2025 22:30:07 +0100 Subject: [PATCH 129/314] test: logging_filesize_rate_limit improvements - Add helper functions and structs to improve readability and reusability of test code - Make tests more specific by comparing all produced log lines with expected log lines instead of relying on approximations or proxies. Github-Pull: #33011 Rebased-From: 9f3b017bcc067bba1d1682a5d4e65b5450dc10c4 --- src/test/logging_tests.cpp | 201 ++++++++++++++++++++----------------- 1 file changed, 109 insertions(+), 92 deletions(-) diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index f3100dac9ba..e208ea46926 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -291,23 +291,40 @@ BOOST_FIXTURE_TEST_CASE(logging_Conf, LogSetup) } } -void MockForwardAndSync(CScheduler& scheduler, std::chrono::seconds duration) -{ - scheduler.MockForward(duration); - std::promise promise; - scheduler.scheduleFromNow([&promise] { promise.set_value(); }, 0ms); - promise.get_future().wait(); -} +struct ScopedScheduler { + CScheduler scheduler{}; + + ScopedScheduler() + { + scheduler.m_service_thread = std::thread([this] { scheduler.serviceQueue(); }); + } + ~ScopedScheduler() + { + scheduler.stop(); + } + void MockForwardAndSync(std::chrono::seconds duration) + { + scheduler.MockForward(duration); + std::promise promise; + scheduler.scheduleFromNow([&promise] { promise.set_value(); }, 0ms); + promise.get_future().wait(); + } + std::shared_ptr GetLimiter(size_t max_bytes, std::chrono::seconds window) + { + auto sched_func = [this](auto func, auto w) { + scheduler.scheduleEvery(std::move(func), w); + }; + return BCLog::LogRateLimiter::Create(sched_func, max_bytes, window); + } +}; BOOST_AUTO_TEST_CASE(logging_log_rate_limiter) { - CScheduler scheduler{}; - scheduler.m_service_thread = std::thread([&scheduler] { scheduler.serviceQueue(); }); uint64_t max_bytes{1024}; auto reset_window{1min}; - auto sched_func = [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }; - auto limiter_{BCLog::LogRateLimiter::Create(sched_func, max_bytes, reset_window)}; - auto& limiter{*limiter_}; + ScopedScheduler scheduler{}; + auto limiter_{scheduler.GetLimiter(max_bytes, reset_window)}; + auto& limiter{*Assert(limiter_)}; using Status = BCLog::LogRateLimiter::Status; auto source_loc_1{std::source_location::current()}; @@ -335,13 +352,11 @@ BOOST_AUTO_TEST_CASE(logging_log_rate_limiter) BOOST_CHECK(limiter.SuppressionsActive()); // After reset_window time has passed, all suppressions should be cleared. - MockForwardAndSync(scheduler, reset_window); + scheduler.MockForwardAndSync(reset_window); BOOST_CHECK(!limiter.SuppressionsActive()); BOOST_CHECK_EQUAL(limiter.Consume(source_loc_1, std::string(max_bytes, 'a')), Status::UNSUPPRESSED); BOOST_CHECK_EQUAL(limiter.Consume(source_loc_2, std::string(max_bytes, 'a')), Status::UNSUPPRESSED); - - scheduler.stop(); } BOOST_AUTO_TEST_CASE(logging_log_limit_stats) @@ -367,105 +382,107 @@ BOOST_AUTO_TEST_CASE(logging_log_limit_stats) BOOST_CHECK_EQUAL(stats.m_dropped_bytes, uint64_t{500}); } -void LogFromLocation(int location, std::string message) -{ +namespace { + +enum class Location { + INFO_1, + INFO_2, + DEBUG_LOG, + INFO_NOLIMIT, +}; + +void LogFromLocation(Location location, const std::string& message) { switch (location) { - case 0: + case Location::INFO_1: LogInfo("%s\n", message); - break; - case 1: + return; + case Location::INFO_2: LogInfo("%s\n", message); - break; - case 2: - LogPrintLevel(BCLog::LogFlags::NONE, BCLog::Level::Info, "%s\n", message); - break; - case 3: - LogPrintLevel(BCLog::LogFlags::ALL, BCLog::Level::Info, "%s\n", message); - break; - } + return; + case Location::DEBUG_LOG: + LogDebug(BCLog::LogFlags::HTTP, "%s\n", message); + return; + case Location::INFO_NOLIMIT: + LogPrintLevel_(BCLog::LogFlags::ALL, BCLog::Level::Info, /*should_ratelimit=*/false, "%s\n", message); + return; + } // no default case, so the compiler can warn about missing cases + assert(false); } -void LogFromLocationAndExpect(int location, std::string message, std::string expect) +/** + * For a given `location` and `message`, ensure that the on-disk debug log behaviour resembles what + * we'd expect it to be for `status` and `suppressions_active`. + */ +void TestLogFromLocation(Location location, const std::string& message, + BCLog::LogRateLimiter::Status status, bool suppressions_active, + std::source_location source = std::source_location::current()) { - ASSERT_DEBUG_LOG(expect); + using Status = BCLog::LogRateLimiter::Status; + if (!suppressions_active) assert(status == Status::UNSUPPRESSED); // developer error + + std::ofstream ofs(LogInstance().m_file_path, std::ios::out | std::ios::trunc); // clear debug log LogFromLocation(location, message); + auto log_lines{ReadDebugLogLines()}; + + BOOST_TEST_CONTEXT("TestLogFromLocation failed from " << source.file_name() << ":" << source.line()) + { + if (status == Status::STILL_SUPPRESSED) { + BOOST_CHECK_EQUAL(log_lines.size(), 0); + return; + } + + if (status == Status::NEWLY_SUPPRESSED) { + BOOST_REQUIRE_EQUAL(log_lines.size(), 2); + BOOST_CHECK(log_lines[0].starts_with("[*] [warning] Excessive logging detected")); + log_lines.erase(log_lines.begin()); + } + BOOST_REQUIRE_EQUAL(log_lines.size(), 1); + auto& payload{log_lines.back()}; + BOOST_CHECK_EQUAL(suppressions_active, payload.starts_with("[*]")); + BOOST_CHECK(payload.ends_with(message)); + } } +} // namespace + BOOST_FIXTURE_TEST_CASE(logging_filesize_rate_limit, LogSetup) { - bool prev_log_timestamps = LogInstance().m_log_timestamps; + using Status = BCLog::LogRateLimiter::Status; LogInstance().m_log_timestamps = false; - bool prev_log_sourcelocations = LogInstance().m_log_sourcelocations; LogInstance().m_log_sourcelocations = false; - bool prev_log_threadnames = LogInstance().m_log_threadnames; LogInstance().m_log_threadnames = false; + LogInstance().EnableCategory(BCLog::LogFlags::HTTP); - CScheduler scheduler{}; - scheduler.m_service_thread = std::thread([&] { scheduler.serviceQueue(); }); - auto sched_func = [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }; - LogInstance().SetRateLimiting(BCLog::LogRateLimiter::Create(sched_func, 1024 * 1024, 20s)); - - // Log 1024-character lines (1023 plus newline) to make the math simple. - std::string log_message(1023, 'a'); - - std::string utf8_path{LogInstance().m_file_path.utf8string()}; - const char* log_path{utf8_path.c_str()}; - - // Use GetFileSize because fs::file_size may require a flush to be accurate. - std::streamsize log_file_size{static_cast(GetFileSize(log_path))}; - - // Logging 1 MiB should be allowed. - for (int i = 0; i < 1024; ++i) { - LogFromLocation(0, log_message); - } - BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "should be able to log 1 MiB from location 0"); + constexpr int64_t line_length{1024}; + constexpr int64_t num_lines{1024}; + constexpr int64_t bytes_quota{line_length * num_lines}; + constexpr auto time_window{20s}; - log_file_size = GetFileSize(log_path); + ScopedScheduler scheduler{}; + auto limiter{scheduler.GetLimiter(bytes_quota, time_window)}; + LogInstance().SetRateLimiting(limiter); - BOOST_CHECK_NO_THROW(LogFromLocationAndExpect(0, log_message, "Excessive logging detected")); - BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "the start of the suppression period should be logged"); + const std::string log_message(line_length - 1, 'a'); // subtract one for newline - log_file_size = GetFileSize(log_path); - for (int i = 0; i < 1024; ++i) { - LogFromLocation(0, log_message); + for (int i = 0; i < num_lines; ++i) { + TestLogFromLocation(Location::INFO_1, log_message, Status::UNSUPPRESSED, /*suppressions_active=*/false); } - - BOOST_CHECK_MESSAGE(log_file_size == GetFileSize(log_path), "all further logs from location 0 should be dropped"); - - BOOST_CHECK_THROW(LogFromLocationAndExpect(1, log_message, "Excessive logging detected"), std::runtime_error); - BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "location 1 should be unaffected by other locations"); - - log_file_size = GetFileSize(log_path); + TestLogFromLocation(Location::INFO_1, "a", Status::NEWLY_SUPPRESSED, /*suppressions_active=*/true); + TestLogFromLocation(Location::INFO_1, "b", Status::STILL_SUPPRESSED, /*suppressions_active=*/true); + TestLogFromLocation(Location::INFO_2, "c", Status::UNSUPPRESSED, /*suppressions_active=*/true); { - ASSERT_DEBUG_LOG("Restarting logging"); - MockForwardAndSync(scheduler, 1min); + scheduler.MockForwardAndSync(time_window); + BOOST_CHECK(ReadDebugLogLines().back().starts_with("[warning] Restarting logging")); } - - BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "the end of the suppression period should be logged"); - - BOOST_CHECK_THROW(LogFromLocationAndExpect(1, log_message, "Restarting logging"), std::runtime_error); - - // Attempt to log 1MiB from location 2 and 1MiB from location 3. These exempt locations should be allowed to log - // without limit. - log_file_size = GetFileSize(log_path); - for (int i = 0; i < 1024; ++i) { - BOOST_CHECK_THROW(LogFromLocationAndExpect(2, log_message, "Excessive logging detected"), std::runtime_error); + // Check that logging from previously suppressed location is unsuppressed again. + TestLogFromLocation(Location::INFO_1, log_message, Status::UNSUPPRESSED, /*suppressions_active=*/false); + // Check that conditional logging, and unconditional logging with should_ratelimit=false is + // not being ratelimited. + for (Location location : {Location::DEBUG_LOG, Location::INFO_NOLIMIT}) { + for (int i = 0; i < num_lines + 2; ++i) { + TestLogFromLocation(location, log_message, Status::UNSUPPRESSED, /*suppressions_active=*/false); + } } - - BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "location 2 should be exempt from rate limiting"); - - log_file_size = GetFileSize(log_path); - for (int i = 0; i < 1024; ++i) { - BOOST_CHECK_THROW(LogFromLocationAndExpect(3, log_message, "Excessive logging detected"), std::runtime_error); - } - - BOOST_CHECK_MESSAGE(log_file_size < GetFileSize(log_path), "location 3 should be exempt from rate limiting"); - - LogInstance().m_log_timestamps = prev_log_timestamps; - LogInstance().m_log_sourcelocations = prev_log_sourcelocations; - LogInstance().m_log_threadnames = prev_log_threadnames; - scheduler.stop(); - LogInstance().SetRateLimiting(nullptr); } BOOST_AUTO_TEST_SUITE_END() From 206f5902db5c5b0a08f0575b5ba6007730011e5f Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Fri, 1 Aug 2025 11:13:10 -0400 Subject: [PATCH 130/314] config: add DEBUG_ONLY -logratelimit Use -nologratelimit by default in functional tests if the bitcoind version supports it. Co-Authored-By: stickies-v Github-Pull: #33011 Rebased-From: 5c74a0b397cb3db94761bad78801eed4544155b9 --- src/init.cpp | 12 ++++++++---- src/init/common.cpp | 1 + src/logging.h | 1 + test/functional/test_framework/test_node.py | 2 ++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index fa7ac6077d2..70615a191be 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1384,10 +1384,14 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } }, std::chrono::minutes{5}); - LogInstance().SetRateLimiting(BCLog::LogRateLimiter::Create( - [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); }, - BCLog::RATELIMIT_MAX_BYTES, - BCLog::RATELIMIT_WINDOW)); + 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)); diff --git a/src/init/common.cpp b/src/init/common.cpp index 7191854c747..362db9d40d0 100644 --- a/src/init/common.cpp +++ b/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/src/logging.h b/src/logging.h index 9419e245bdf..723aeb790fb 100644 --- a/src/logging.h +++ b/src/logging.h @@ -107,6 +107,7 @@ namespace BCLog { constexpr size_t DEFAULT_MAX_LOG_BUFFER{1'000'000}; // buffer up to 1MB of log data prior to StartLogging constexpr uint64_t RATELIMIT_MAX_BYTES{1024 * 1024}; // maximum number of bytes per source location that can be logged within the RATELIMIT_WINDOW constexpr auto RATELIMIT_WINDOW{1h}; // time window after which log ratelimit stats are reset + constexpr bool DEFAULT_LOGRATELIMIT{true}; //! Fixed window rate limiter for logging. class LogRateLimiter diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index abca2b559b5..47ae2cc22da 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -137,6 +137,8 @@ def __init__(self, i, datadir_path, *, chain, rpchost, timewait, timeout_factor, self.args.append("-logsourcelocations") if self.version_is_at_least(239000): self.args.append("-loglevel=trace") + if self.version_is_at_least(299900): + self.args.append("-nologratelimit") # Default behavior from global -v2transport flag is added to args to persist it over restarts. # May be overwritten in individual tests, using extra_args. From 0022e25333a8eabf79c0341f94cf06db36e32f4f Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Mon, 18 Aug 2025 14:23:04 -0400 Subject: [PATCH 131/314] test: modify logging_filesize_rate_limit params Change time_window from 20s to 1h so Reset is not accidentally called if the test takes a while. Change num_lines from 1024 to 10 since LogRateLimiter is parameterized and does not require logging 1MiB of data. Co-Authored-By: stickies-v Github-Pull: #33211 Rebased-From: 5dda364c4b1965da586db7b81de8be90b6919414 --- src/test/logging_tests.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index e208ea46926..a2ccb5fdb19 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -417,30 +417,29 @@ void TestLogFromLocation(Location location, const std::string& message, BCLog::LogRateLimiter::Status status, bool suppressions_active, std::source_location source = std::source_location::current()) { + BOOST_TEST_INFO_SCOPE("TestLogFromLocation called from " << source.file_name() << ":" << source.line()); using Status = BCLog::LogRateLimiter::Status; if (!suppressions_active) assert(status == Status::UNSUPPRESSED); // developer error std::ofstream ofs(LogInstance().m_file_path, std::ios::out | std::ios::trunc); // clear debug log LogFromLocation(location, message); auto log_lines{ReadDebugLogLines()}; + BOOST_TEST_INFO_SCOPE(log_lines.size() << " log_lines read: \n" << util::Join(log_lines, "\n")); - BOOST_TEST_CONTEXT("TestLogFromLocation failed from " << source.file_name() << ":" << source.line()) - { - if (status == Status::STILL_SUPPRESSED) { - BOOST_CHECK_EQUAL(log_lines.size(), 0); - return; - } + if (status == Status::STILL_SUPPRESSED) { + BOOST_CHECK_EQUAL(log_lines.size(), 0); + return; + } - if (status == Status::NEWLY_SUPPRESSED) { - BOOST_REQUIRE_EQUAL(log_lines.size(), 2); - BOOST_CHECK(log_lines[0].starts_with("[*] [warning] Excessive logging detected")); - log_lines.erase(log_lines.begin()); - } - BOOST_REQUIRE_EQUAL(log_lines.size(), 1); - auto& payload{log_lines.back()}; - BOOST_CHECK_EQUAL(suppressions_active, payload.starts_with("[*]")); - BOOST_CHECK(payload.ends_with(message)); + if (status == Status::NEWLY_SUPPRESSED) { + BOOST_REQUIRE_EQUAL(log_lines.size(), 2); + BOOST_CHECK(log_lines[0].starts_with("[*] [warning] Excessive logging detected")); + log_lines.erase(log_lines.begin()); } + BOOST_REQUIRE_EQUAL(log_lines.size(), 1); + auto& payload{log_lines.back()}; + BOOST_CHECK_EQUAL(suppressions_active, payload.starts_with("[*]")); + BOOST_CHECK(payload.ends_with(message)); } } // namespace @@ -454,9 +453,9 @@ BOOST_FIXTURE_TEST_CASE(logging_filesize_rate_limit, LogSetup) LogInstance().EnableCategory(BCLog::LogFlags::HTTP); constexpr int64_t line_length{1024}; - constexpr int64_t num_lines{1024}; + constexpr int64_t num_lines{10}; constexpr int64_t bytes_quota{line_length * num_lines}; - constexpr auto time_window{20s}; + constexpr auto time_window{1h}; ScopedScheduler scheduler{}; auto limiter{scheduler.GetLimiter(bytes_quota, time_window)}; From 4e3cfa660d1ab1552881f2eedb5123ab7d0fe0b0 Mon Sep 17 00:00:00 2001 From: glozow Date: Thu, 31 Jul 2025 11:29:49 -0400 Subject: [PATCH 132/314] [test] check miner doesn't select 0fee transactions Github-Pull: #33106 Rebased-From: e5f896bb1f052fb8c7811c6024cb49143b427512 --- test/functional/mining_basic.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py index fea7ced3752..c354e2c71c4 100755 --- a/test/functional/mining_basic.py +++ b/test/functional/mining_basic.py @@ -36,6 +36,7 @@ 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, @@ -99,7 +100,7 @@ def test_blockmintxfee_parameter(self): node = self.nodes[0] # test default (no parameter), zero and a bunch of arbitrary blockmintxfee rates [sat/kvB] - for blockmintxfee_sat_kvb in (DEFAULT_BLOCK_MIN_TX_FEE, 0, 50, 100, 500, 2500, 5000, 21000, 333333, 2500000): + for blockmintxfee_sat_kvb in (DEFAULT_BLOCK_MIN_TX_FEE, 0, 1, 5, 10, 50, 100, 500, 2500, 5000, 21000, 333333, 2500000): blockmintxfee_btc_kvb = blockmintxfee_sat_kvb / Decimal(COIN) if blockmintxfee_sat_kvb == DEFAULT_BLOCK_MIN_TX_FEE: self.log.info(f"-> Default -blockmintxfee setting ({blockmintxfee_sat_kvb} sat/kvB)...") @@ -110,19 +111,27 @@ def test_blockmintxfee_parameter(self): self.wallet.rescan_utxos() # to avoid spending outputs of txs that are not in mempool anymore after restart # submit one tx with exactly the blockmintxfee rate, and one slightly below - tx_with_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=blockmintxfee_btc_kvb) + tx_with_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=blockmintxfee_btc_kvb, confirmed_only=True) assert_equal(tx_with_min_feerate["fee"], get_fee(tx_with_min_feerate["tx"].get_vsize(), blockmintxfee_btc_kvb)) - if blockmintxfee_btc_kvb > 0: + if blockmintxfee_sat_kvb > 5: lowerfee_btc_kvb = blockmintxfee_btc_kvb - Decimal(10)/COIN # 0.01 sat/vbyte lower - tx_below_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=lowerfee_btc_kvb) + tx_below_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=lowerfee_btc_kvb, confirmed_only=True) assert_equal(tx_below_min_feerate["fee"], get_fee(tx_below_min_feerate["tx"].get_vsize(), lowerfee_btc_kvb)) else: # go below zero fee by using modified fees - tx_below_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=blockmintxfee_btc_kvb) + tx_below_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=blockmintxfee_btc_kvb, confirmed_only=True) node.prioritisetransaction(tx_below_min_feerate["txid"], 0, -1) # check that tx below specified fee-rate is neither in template nor in the actual block block_template = node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS) block_template_txids = [tx['txid'] for tx in block_template['transactions']] + + # Unless blockmintxfee is 0, the template shouldn't contain free transactions. + # Note that the real block assembler uses package feerates, but we didn't create dependent transactions so it's ok to use base feerate. + if blockmintxfee_btc_kvb > 0: + for txid in block_template_txids: + tx = node.getmempoolentry(txid) + assert_greater_than(tx['fees']['base'], 0) + self.generate(self.wallet, 1, sync_fun=self.no_op) block = node.getblock(node.getbestblockhash(), verbosity=2) block_txids = [tx['txid'] for tx in block['tx']] From 03da7aff996eaaddce04448f8461d4f3d15d2a4a Mon Sep 17 00:00:00 2001 From: glozow Date: Thu, 31 Jul 2025 12:38:36 -0400 Subject: [PATCH 133/314] [test] check bypass of minrelay for various minrelaytxfee settings Github-Pull: #33106 Rebased-From: 85f498893f54ea7d84f2bdf12aa35d198edf8a72 --- test/functional/mempool_truc.py | 49 ++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/test/functional/mempool_truc.py b/test/functional/mempool_truc.py index 435b61f24f3..8850ba80028 100755 --- a/test/functional/mempool_truc.py +++ b/test/functional/mempool_truc.py @@ -10,6 +10,7 @@ assert_greater_than, assert_greater_than_or_equal, assert_raises_rpc_error, + get_fee, ) from test_framework.wallet import ( COIN, @@ -594,12 +595,57 @@ def test_reorg_sibling_eviction_1p2c(self): ) self.check_mempool([tx_with_multi_children["txid"], tx_with_sibling3_rbf["txid"], tx_with_sibling2["txid"]]) + @cleanup(extra_args=None) + def test_minrelay_in_package_combos(self): + node = self.nodes[0] + self.log.info("Test that only TRUC transactions can be under minrelaytxfee for various settings...") + + for minrelay_setting in (0, 5, 10, 100, 500, 1000, 5000, 333333, 2500000): + self.log.info(f"-> Test -minrelaytxfee={minrelay_setting}sat/kvB...") + setting_decimal = minrelay_setting / Decimal(COIN) + self.restart_node(0, extra_args=[f"-minrelaytxfee={setting_decimal:.8f}", "-persistmempool=0"]) + minrelayfeerate = node.getmempoolinfo()["minrelaytxfee"] + high_feerate = minrelayfeerate * 50 + + tx_v3_0fee_parent = self.wallet.create_self_transfer(fee=0, fee_rate=0, confirmed_only=True, version=3) + tx_v3_child = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_0fee_parent["new_utxo"], fee_rate=high_feerate, version=3) + total_v3_fee = tx_v3_child["fee"] + tx_v3_0fee_parent["fee"] + total_v3_size = tx_v3_child["tx"].get_vsize() + tx_v3_0fee_parent["tx"].get_vsize() + assert_greater_than_or_equal(total_v3_fee, get_fee(total_v3_size, minrelayfeerate)) + if minrelayfeerate > 0: + assert_greater_than(get_fee(tx_v3_0fee_parent["tx"].get_vsize(), minrelayfeerate), 0) + # Always need to pay at least 1 satoshi for entry, even if minimum feerate is very low + assert_greater_than(total_v3_fee, 0) + + tx_v2_0fee_parent = self.wallet.create_self_transfer(fee=0, fee_rate=0, confirmed_only=True, version=2) + tx_v2_child = self.wallet.create_self_transfer(utxo_to_spend=tx_v2_0fee_parent["new_utxo"], fee_rate=high_feerate, version=2) + total_v2_fee = tx_v2_child["fee"] + tx_v2_0fee_parent["fee"] + total_v2_size = tx_v2_child["tx"].get_vsize() + tx_v2_0fee_parent["tx"].get_vsize() + assert_greater_than_or_equal(total_v2_fee, get_fee(total_v2_size, minrelayfeerate)) + if minrelayfeerate > 0: + assert_greater_than(get_fee(tx_v2_0fee_parent["tx"].get_vsize(), minrelayfeerate), 0) + # Always need to pay at least 1 satoshi for entry, even if minimum feerate is very low + assert_greater_than(total_v2_fee, 0) + + result_truc = node.submitpackage([tx_v3_0fee_parent["hex"], tx_v3_child["hex"]], maxfeerate=0) + assert_equal(result_truc["package_msg"], "success") + + result_non_truc = node.submitpackage([tx_v2_0fee_parent["hex"], tx_v2_child["hex"]], maxfeerate=0) + if minrelayfeerate > 0: + assert_equal(result_non_truc["package_msg"], "transaction failed") + min_fee_parent = int(get_fee(tx_v2_0fee_parent["tx"].get_vsize(), minrelayfeerate) * COIN) + assert_equal(result_non_truc["tx-results"][tx_v2_0fee_parent["wtxid"]]["error"], f"min relay fee not met, 0 < {min_fee_parent}") + self.check_mempool([tx_v3_0fee_parent["txid"], tx_v3_child["txid"]]) + else: + assert_equal(result_non_truc["package_msg"], "success") + self.check_mempool([tx_v2_0fee_parent["txid"], tx_v2_child["txid"], tx_v3_0fee_parent["txid"], tx_v3_child["txid"]]) + def run_test(self): self.log.info("Generate blocks to create UTXOs") node = self.nodes[0] self.wallet = MiniWallet(node) - self.generate(self.wallet, 120) + self.generate(self.wallet, 200) self.test_truc_max_vsize() self.test_truc_acceptance() self.test_truc_replacement() @@ -613,6 +659,7 @@ def run_test(self): self.test_reorg_2child_rbf() self.test_truc_sibling_eviction() self.test_reorg_sibling_eviction_1p2c() + self.test_minrelay_in_package_combos() if __name__ == "__main__": From 6b5396c4b1b3561f79e0c4881dad5eb0ca7b44ae Mon Sep 17 00:00:00 2001 From: glozow Date: Thu, 31 Jul 2025 13:53:57 -0400 Subject: [PATCH 134/314] [test] RBF rule 4 for various incrementalrelayfee settings Github-Pull: #33106 Rebased-From: 72dc18467dbfc16cdbda2dd109b087243b397799 --- test/functional/feature_rbf.py | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py index c7f0cc5e432..3da41602c90 100755 --- a/test/functional/feature_rbf.py +++ b/test/functional/feature_rbf.py @@ -13,7 +13,10 @@ 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 @@ -77,6 +80,9 @@ def run_test(self): 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): @@ -587,6 +593,38 @@ def test_replacement_relay_fee(self): 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_vsize=5000) + 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): # BIP125 signaling is not respected From 567c3ee3cb937de09d3fe8b7e82e431993fac7c7 Mon Sep 17 00:00:00 2001 From: glozow Date: Mon, 11 Aug 2025 16:58:21 -0400 Subject: [PATCH 135/314] [test] explicitly check default -minrelaytxfee and -incrementalrelayfee Github-Pull: #33106 Rebased-From: 1fbee5d7b61b83e68e4230c8a97ca308de92c4c3 --- test/functional/mempool_accept.py | 9 +++++++++ test/functional/test_framework/mempool_util.py | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py index 27ecc3b4a84..2155b8de6b1 100755 --- a/test/functional/mempool_accept.py +++ b/test/functional/mempool_accept.py @@ -9,6 +9,10 @@ import math from test_framework.test_framework import BitcoinTestFramework +from test_framework.mempool_util import ( + DEFAULT_MIN_RELAY_TX_FEE, + DEFAULT_INCREMENTAL_RELAY_FEE, +) from test_framework.messages import ( MAX_BIP125_RBF_SEQUENCE, COIN, @@ -81,6 +85,11 @@ def run_test(self): assert_equal(node.getblockcount(), 200) assert_equal(node.getmempoolinfo()['size'], self.mempool_size) + self.log.info("Check default settings") + # Settings are listed in BTC/kvB + assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal(DEFAULT_MIN_RELAY_TX_FEE) / COIN) + assert_equal(node.getmempoolinfo()['incrementalrelayfee'], Decimal(DEFAULT_INCREMENTAL_RELAY_FEE) / COIN) + self.log.info('Should not accept garbage to testmempoolaccept') assert_raises_rpc_error(-3, 'JSON value of type string is not of expected type array', lambda: node.testmempoolaccept(rawtxs='ff00baar')) assert_raises_rpc_error(-8, 'Array must contain between 1 and 25 transactions.', lambda: node.testmempoolaccept(rawtxs=['ff22']*26)) diff --git a/test/functional/test_framework/mempool_util.py b/test/functional/test_framework/mempool_util.py index 0e9c821e2ea..1587c82e2f8 100644 --- a/test/functional/test_framework/mempool_util.py +++ b/test/functional/test_framework/mempool_util.py @@ -20,6 +20,10 @@ ) ORPHAN_TX_EXPIRE_TIME = 1200 +# Default for -minrelaytxfee in sat/kvB +DEFAULT_MIN_RELAY_TX_FEE = 1000 +# Default for -incrementalrelayfee in sat/kvB +DEFAULT_INCREMENTAL_RELAY_FEE = 1000 def assert_mempool_contents(test_framework, node, expected=None, sync=True): """Assert that all transactions in expected are in the mempool, From 3a7e093f948571e058db31dd971dc628d9729232 Mon Sep 17 00:00:00 2001 From: glozow Date: Mon, 11 Aug 2025 16:50:58 -0400 Subject: [PATCH 136/314] [doc] assert that default min relay feerate and incremental are the same Github-Pull: #33106 Rebased-From: d6213d6aa114aeed6804a585491d741386fd2739 --- src/node/mempool_args.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/node/mempool_args.cpp b/src/node/mempool_args.cpp index 33ae697168e..f2241f0caf5 100644 --- a/src/node/mempool_args.cpp +++ b/src/node/mempool_args.cpp @@ -65,6 +65,7 @@ util::Result ApplyArgsManOptions(const ArgsManager& argsman, const CChainP } } + static_assert(DEFAULT_MIN_RELAY_TX_FEE == DEFAULT_INCREMENTAL_RELAY_FEE); if (argsman.IsArgSet("-minrelaytxfee")) { if (std::optional min_relay_feerate = ParseMoney(argsman.GetArg("-minrelaytxfee", ""))) { // High fee check is done afterward in CWallet::Create() From 1c1970fb45896dc5fa7b16370408c34964ed4c19 Mon Sep 17 00:00:00 2001 From: glozow Date: Tue, 29 Jul 2025 13:32:38 -0400 Subject: [PATCH 137/314] [miner] lower default -blockmintxfee to 1sat/kvB Back when we implemented coin age priority as a miner policy, miners mempools might admit transactions paying very low fees, but then want to set a higher fee for block inclusion. However, since coin age priority was removed in v0.15, the block assembly policy is solely based on fees, so we do not need to apply minimum feerate rules in multiple places. In fact, the block assembly policy ignoring transactions that are added to the mempool is likely undesirable as we waste resources accepting and storing this transaction. Instead, rely on mempool policy to enforce a minimum entry feerate to the mempool (minrelaytxfee). Set the minimum block feerate to the minimum non-zero amount (1sat/kvB) so it collects everything it finds in mempool into the block. Github-Pull: #33106 Rebased-From: 5f2df0ef78be7b24798d0983c9b962740608f1f4 --- src/policy/policy.h | 2 +- src/test/miner_tests.cpp | 4 ++++ test/functional/mining_basic.py | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/policy/policy.h b/src/policy/policy.h index dab39aa4f8b..fe8006729bb 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -29,7 +29,7 @@ static constexpr unsigned int DEFAULT_BLOCK_RESERVED_WEIGHT{8000}; * Setting a lower value is prevented at startup. */ static constexpr unsigned int MINIMUM_BLOCK_RESERVED_WEIGHT{2000}; /** 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 */ diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 5bfcde77183..10f8be4b324 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -210,6 +211,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(); AddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(true).FromTx(tx)); diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py index c354e2c71c4..72f92c85a09 100755 --- a/test/functional/mining_basic.py +++ b/test/functional/mining_basic.py @@ -49,7 +49,7 @@ MAX_TIMEWARP = 600 VERSIONBITS_TOP_BITS = 0x20000000 VERSIONBITS_DEPLOYMENT_TESTDUMMY_BIT = 28 -DEFAULT_BLOCK_MIN_TX_FEE = 1000 # default `-blockmintxfee` setting [sat/kvB] +DEFAULT_BLOCK_MIN_TX_FEE = 1 # default `-blockmintxfee` setting [sat/kvB] def assert_template(node, block, expect, rehash=True): @@ -100,7 +100,7 @@ def test_blockmintxfee_parameter(self): node = self.nodes[0] # test default (no parameter), zero and a bunch of arbitrary blockmintxfee rates [sat/kvB] - for blockmintxfee_sat_kvb in (DEFAULT_BLOCK_MIN_TX_FEE, 0, 1, 5, 10, 50, 100, 500, 2500, 5000, 21000, 333333, 2500000): + for blockmintxfee_sat_kvb in (DEFAULT_BLOCK_MIN_TX_FEE, 0, 5, 10, 50, 100, 500, 1000, 2500, 5000, 21000, 333333, 2500000): blockmintxfee_btc_kvb = blockmintxfee_sat_kvb / Decimal(COIN) if blockmintxfee_sat_kvb == DEFAULT_BLOCK_MIN_TX_FEE: self.log.info(f"-> Default -blockmintxfee setting ({blockmintxfee_sat_kvb} sat/kvB)...") From a0ae3fc8a764121b17e11e3a99330e73c0e44c2d Mon Sep 17 00:00:00 2001 From: glozow Date: Tue, 29 Jul 2025 14:08:06 -0400 Subject: [PATCH 138/314] [prep/test] replace magic number 1000 with respective feerate vars Github-Pull: #33106 Rebased-From: 3eab8b724044dc321f70e5eed66b149713158a04 --- src/test/mempool_tests.cpp | 16 ++++++++-------- test/functional/mempool_limit.py | 9 +++------ test/functional/test_framework/mempool_util.py | 15 ++++++--------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index f0094dce59f..e96dd6e430b 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -482,7 +482,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) 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); + BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE); CMutableTransaction tx4 = CMutableTransaction(); tx4.vin.resize(2); @@ -559,28 +559,28 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) std::vector 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&& output_values, std::vector&& inputs=std::vector(), std::vector&& input_indices=std::vector()) diff --git a/test/functional/mempool_limit.py b/test/functional/mempool_limit.py index 85d158d6111..737b3c4b52b 100755 --- a/test/functional/mempool_limit.py +++ b/test/functional/mempool_limit.py @@ -94,8 +94,7 @@ def test_mid_package_eviction_success(self): assert_equal(node.getrawmempool(), []) # Restarting the node resets mempool minimum feerate - assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) - assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) + assert_equal(node.getmempoolinfo()['minrelaytxfee'], node.getmempoolinfo()["mempoolminfee"]) fill_mempool(self, node) current_info = node.getmempoolinfo() @@ -278,8 +277,7 @@ def test_mid_package_replacement(self): self.restart_node(0, extra_args=self.extra_args[0]) # Restarting the node resets mempool minimum feerate - assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) - assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) + assert_equal(node.getmempoolinfo()['minrelaytxfee'], node.getmempoolinfo()["mempoolminfee"]) fill_mempool(self, node) current_info = node.getmempoolinfo() @@ -352,8 +350,7 @@ def run_test(self): relayfee = node.getnetworkinfo()['relayfee'] self.log.info('Check that mempoolminfee is minrelaytxfee') - assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) - assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) + assert_equal(node.getmempoolinfo()['minrelaytxfee'], node.getmempoolinfo()["mempoolminfee"]) fill_mempool(self, node) diff --git a/test/functional/test_framework/mempool_util.py b/test/functional/test_framework/mempool_util.py index 1587c82e2f8..e00fea23d99 100644 --- a/test/functional/test_framework/mempool_util.py +++ b/test/functional/test_framework/mempool_util.py @@ -3,7 +3,6 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Helpful routines for mempool testing.""" -from decimal import Decimal from .blocktools import ( COINBASE_MATURITY, @@ -52,9 +51,7 @@ def fill_mempool(test_framework, node, *, tx_sync_fun=None): """ test_framework.log.info("Fill the mempool until eviction is triggered and the mempoolminfee rises") txouts = gen_return_txouts() - relayfee = node.getnetworkinfo()['relayfee'] - - assert_equal(relayfee, Decimal('0.00001000')) + minrelayfee = node.getnetworkinfo()['relayfee'] tx_batch_size = 1 num_of_batches = 75 @@ -74,7 +71,7 @@ def fill_mempool(test_framework, node, *, tx_sync_fun=None): test_framework.log.debug("Create a mempool tx that will be evicted") tx_to_be_evicted_id = ephemeral_miniwallet.send_self_transfer( - from_node=node, utxo_to_spend=confirmed_utxos.pop(0), fee_rate=relayfee)["txid"] + from_node=node, utxo_to_spend=confirmed_utxos.pop(0), fee_rate=minrelayfee)["txid"] def send_batch(fee): utxos = confirmed_utxos[:tx_batch_size] @@ -84,14 +81,14 @@ def send_batch(fee): # Increase the tx fee rate to give the subsequent transactions a higher priority in the mempool # The tx has an approx. vsize of 65k, i.e. multiplying the previous fee rate (in sats/kvB) # by 130 should result in a fee that corresponds to 2x of that fee rate - base_fee = relayfee * 130 + base_fee = minrelayfee * 130 batch_fees = [(i + 1) * base_fee for i in range(num_of_batches)] test_framework.log.debug("Fill up the mempool with txs with higher fee rate") for fee in batch_fees[:-3]: send_batch(fee) tx_sync_fun() if tx_sync_fun else test_framework.sync_mempools() # sync before any eviction - assert_equal(node.getmempoolinfo()["mempoolminfee"], Decimal("0.00001000")) + assert_equal(node.getmempoolinfo()["mempoolminfee"], minrelayfee) for fee in batch_fees[-3:]: send_batch(fee) tx_sync_fun() if tx_sync_fun else test_framework.sync_mempools() # sync after all evictions @@ -103,8 +100,8 @@ def send_batch(fee): assert tx_to_be_evicted_id not in node.getrawmempool() test_framework.log.debug("Check that mempoolminfee is larger than minrelaytxfee") - assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) - assert_greater_than(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) + assert_equal(node.getmempoolinfo()['minrelaytxfee'], minrelayfee) + assert_greater_than(node.getmempoolinfo()['mempoolminfee'], minrelayfee) def tx_in_orphanage(node, tx: CTransaction) -> bool: """Returns true if the transaction is in the orphanage.""" From da30ca0efadd3861016f6435636d9b399da65162 Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 30 Jul 2025 15:48:34 -0400 Subject: [PATCH 139/314] [prep/util] help MockMempoolMinFee handle more precise feerates Use a virtual size of 1000 to keep precision when using a feerate (which is rounded to the nearest satoshi per kvb) that isn't just an integer. Github-Pull: #33106 Rebased-From: 457cfb61b5323a13218b3cfb5a6a6d8b3a7c5f7f --- src/test/util/setup_common.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index bf26997c076..29327d461ba 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -571,6 +572,9 @@ void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate) CMutableTransaction mtx = CMutableTransaction(); mtx.vin.emplace_back(COutPoint{Txid::FromUint256(m_rng.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. From bbdab3ef7b7e8f3da4e571f35692bc3264c384db Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 30 Jul 2025 15:55:07 -0400 Subject: [PATCH 140/314] [prep/test] make wallet_fundrawtransaction's minrelaytxfee assumption explicit Github-Pull: #33106 Rebased-From: 2e515d2897eaa5a9b012eb78aef105e1cf80d42b --- test/functional/wallet_fundrawtransaction.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/functional/wallet_fundrawtransaction.py b/test/functional/wallet_fundrawtransaction.py index 827f27b431c..2c67aaafb91 100755 --- a/test/functional/wallet_fundrawtransaction.py +++ b/test/functional/wallet_fundrawtransaction.py @@ -44,6 +44,10 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 4 + self.extra_args = [[ + "-deprecatedrpc=settxfee", + "-minrelaytxfee=0.00001000", + ] for i in range(self.num_nodes)] self.setup_clean_chain = True # whitelist peers to speed up tx relay / mempool sync self.noban_tx_relay = True From 9dd7efc8c3fc30cd65ae18a8a91e292c71fe7c16 Mon Sep 17 00:00:00 2001 From: glozow Date: Tue, 29 Jul 2025 14:37:16 -0400 Subject: [PATCH 141/314] [policy] lower default minrelaytxfee and incrementalrelayfee to 100sat/kvB Let's say an attacker wants to use/exhaust the network's bandwidth, and has the choice between renting resources from a commercial provider and getting the network to "spam" itself it by sending unconfirmed transactions. We'd like the latter to be more expensive than the former. The bandwidth for relaying a transaction across the network is roughly its serialized size (plus relay overhead) x number of nodes. A 1000vB transaction is 1000-4000B serialized. With 100k nodes, that's 0.1-0.4GB If the going rate for commercial services is 10c/GB, that's like 1-4c per kvB of transaction data, so a 1000vB transaction should pay at least $0.04. At a price of 120k USD/BTC, 100sat is about $0.12. This price allows us to tolerate a large decrease in the conversion rate or increase in the number of nodes. Github-Pull: #33106 Rebased-From: 6da5de58cabc4133c379baa50845e30e5bc6b3e4 --- src/policy/policy.h | 4 ++-- src/test/mempool_tests.cpp | 24 +++++++++---------- src/test/rbf_tests.cpp | 8 +++---- test/functional/feature_rbf.py | 2 +- test/functional/mempool_ephemeral_dust.py | 2 +- test/functional/mempool_limit.py | 16 ++++++------- test/functional/mempool_package_rbf.py | 9 +++---- test/functional/p2p_1p1c_network.py | 17 +++++++------ test/functional/p2p_ibd_txrelay.py | 8 +++---- test/functional/p2p_opportunistic_1p1c.py | 8 ++++--- .../functional/test_framework/mempool_util.py | 4 ++-- test/functional/wallet_bumpfee.py | 4 ++-- 12 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/policy/policy.h b/src/policy/policy.h index fe8006729bb..bf6224af3db 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -41,7 +41,7 @@ static constexpr unsigned int MAX_STANDARD_TX_SIGOPS_COST{MAX_BLOCK_SIGOPS_COST/ /** The maximum number of potentially executed legacy signature operations in a single standard tx */ static constexpr unsigned int MAX_TX_LEGACY_SIGOPS{2'500}; /** 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 */ @@ -63,7 +63,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 */ diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index e96dd6e430b..aa6333321f1 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -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; - AddToMempool(pool, entry.Fee(10000LL).FromTx(tx1)); + AddToMempool(pool, 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; - AddToMempool(pool, entry.Fee(5000LL).FromTx(tx2)); + AddToMempool(pool, 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; - AddToMempool(pool, entry.Fee(20000LL).FromTx(tx3)); + AddToMempool(pool, 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,7 +481,7 @@ 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))); + 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(); @@ -532,10 +532,10 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; tx7.vout[1].nValue = 10 * COIN; - AddToMempool(pool, entry.Fee(7000LL).FromTx(tx4)); - AddToMempool(pool, entry.Fee(1000LL).FromTx(tx5)); - AddToMempool(pool, entry.Fee(1100LL).FromTx(tx6)); - AddToMempool(pool, entry.Fee(9000LL).FromTx(tx7)); + AddToMempool(pool, entry.Fee(700LL).FromTx(tx4)); + AddToMempool(pool, entry.Fee(100LL).FromTx(tx5)); + AddToMempool(pool, entry.Fee(110LL).FromTx(tx6)); + AddToMempool(pool, 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()))) - AddToMempool(pool, entry.Fee(1000LL).FromTx(tx5)); - AddToMempool(pool, entry.Fee(9000LL).FromTx(tx7)); + AddToMempool(pool, entry.Fee(100LL).FromTx(tx5)); + AddToMempool(pool, 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,8 +553,8 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) BOOST_CHECK(pool.exists(GenTxid::Txid(tx6.GetHash()))); BOOST_CHECK(!pool.exists(GenTxid::Txid(tx7.GetHash()))); - AddToMempool(pool, entry.Fee(1000LL).FromTx(tx5)); - AddToMempool(pool, entry.Fee(9000LL).FromTx(tx7)); + AddToMempool(pool, entry.Fee(100LL).FromTx(tx5)); + AddToMempool(pool, entry.Fee(900LL).FromTx(tx7)); std::vector vtx; SetMockTime(42); diff --git a/src/test/rbf_tests.cpp b/src/test/rbf_tests.cpp index c6d06c937c5..db328f87412 100644 --- a/src/test/rbf_tests.cpp +++ b/src/test/rbf_tests.cpp @@ -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); diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py index 3da41602c90..81f117a759d 100755 --- a/test/functional/feature_rbf.py +++ b/test/functional/feature_rbf.py @@ -589,7 +589,7 @@ def test_replacement_relay_fee(self): # 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()) diff --git a/test/functional/mempool_ephemeral_dust.py b/test/functional/mempool_ephemeral_dust.py index 004db3656ed..8963c3b5cb0 100755 --- a/test/functional/mempool_ephemeral_dust.py +++ b/test/functional/mempool_ephemeral_dust.py @@ -215,7 +215,7 @@ def test_non_truc(self): res = self.nodes[0].submitpackage([dusty_tx["hex"], sweep_tx["hex"]]) assert_equal(res["package_msg"], "transaction failed") - assert_equal(res["tx-results"][dusty_tx["wtxid"]]["error"], "min relay fee not met, 0 < 147") + assert_equal(res["tx-results"][dusty_tx["wtxid"]]["error"], "min relay fee not met, 0 < 15") assert_equal(self.nodes[0].getrawmempool(), []) diff --git a/test/functional/mempool_limit.py b/test/functional/mempool_limit.py index 737b3c4b52b..5051f8a0301 100755 --- a/test/functional/mempool_limit.py +++ b/test/functional/mempool_limit.py @@ -185,8 +185,8 @@ def test_mid_package_eviction(self): self.restart_node(0, extra_args=self.extra_args[0]) # Restarting the node resets mempool minimum feerate - assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) - assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) + assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00000100')) + assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00000100')) fill_mempool(self, node) current_info = node.getmempoolinfo() @@ -215,7 +215,7 @@ def test_mid_package_eviction(self): # coin is no longer available, but the cache could still contains the tx. cpfp_parent = self.wallet.create_self_transfer( utxo_to_spend=mempool_evicted_tx["new_utxo"], - fee_rate=mempoolmin_feerate - Decimal('0.00001'), + fee_rate=mempoolmin_feerate / 2, confirmed_only=True) package_hex.append(cpfp_parent["hex"]) parent_utxos.append(cpfp_parent["new_utxo"]) @@ -230,7 +230,7 @@ def test_mid_package_eviction(self): # Need to be large enough to trigger eviction # (note that the mempool usage of a tx is about three times its vsize) assert_greater_than(parent_vsize * num_big_parents * 3, current_info["maxmempool"] - current_info["bytes"]) - parent_feerate = 100 * mempoolmin_feerate + parent_feerate = 10 * mempoolmin_feerate big_parent_txids = [] for i in range(num_big_parents): @@ -249,7 +249,7 @@ def test_mid_package_eviction(self): # Specific number of satoshis to fit within a small window. The parent_cpfp + child package needs to be # - When there is mid-package eviction, high enough feerate to meet the new mempoolminfee # - When there is no mid-package eviction, low enough feerate to be evicted immediately after submission. - magic_satoshis = 1200 + magic_satoshis = 120 cpfp_satoshis = int(cpfp_fee * COIN) + magic_satoshis child = self.wallet.create_self_transfer_multi(utxos_to_spend=parent_utxos, fee_per_output=cpfp_satoshis) @@ -302,7 +302,7 @@ def test_mid_package_replacement(self): # coin is no longer available, but the cache could still contain the tx. cpfp_parent = self.wallet.create_self_transfer( utxo_to_spend=replaced_tx["new_utxo"], - fee_rate=mempoolmin_feerate - Decimal('0.00001'), + fee_rate=mempoolmin_feerate - Decimal('0.000001'), confirmed_only=True) self.wallet.rescan_utxos() @@ -408,9 +408,9 @@ def run_test(self): target_vsize_each = 50000 assert_greater_than(target_vsize_each * 2 * 3, node.getmempoolinfo()["maxmempool"] - node.getmempoolinfo()["bytes"]) # Should be a true CPFP: parent's feerate is just below mempool min feerate - parent_feerate = mempoolmin_feerate - Decimal("0.000001") # 0.1 sats/vbyte below min feerate + parent_feerate = mempoolmin_feerate - Decimal("0.0000001") # 0.01 sats/vbyte below min feerate # Parent + child is above mempool minimum feerate - child_feerate = (worst_feerate_btcvb * 1000) - Decimal("0.000001") # 0.1 sats/vbyte below worst feerate + child_feerate = (worst_feerate_btcvb * 1000) - Decimal("0.0000001") # 0.01 sats/vbyte below worst feerate # However, when eviction is triggered, these transactions should be at the bottom. # This assertion assumes parent and child are the same size. miniwallet.rescan_utxos() diff --git a/test/functional/mempool_package_rbf.py b/test/functional/mempool_package_rbf.py index 4dc6f8fe364..892d819a0e2 100755 --- a/test/functional/mempool_package_rbf.py +++ b/test/functional/mempool_package_rbf.py @@ -163,13 +163,13 @@ def test_package_rbf_additional_fees(self): self.log.info("Check replacement pays for incremental bandwidth") _, placeholder_txns3 = self.create_simple_package(coin) package_3_size = sum([tx.get_vsize() for tx in placeholder_txns3]) - incremental_sats_required = Decimal(package_3_size) / COIN - incremental_sats_short = incremental_sats_required - Decimal("0.00000001") + incremental_sats_required = (Decimal(package_3_size * 0.1) / COIN).quantize(Decimal("0.00000001")) + incremental_sats_short = incremental_sats_required - Decimal("0.00000005") # Recreate the package with slightly higher fee once we know the size of the new package, but still short of required fee failure_package_hex3, failure_package_txns3 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE + incremental_sats_short) assert_equal(package_3_size, sum([tx.get_vsize() for tx in failure_package_txns3])) pkg_results3 = node.submitpackage(failure_package_hex3) - assert_equal(f"package RBF failed: insufficient anti-DoS fees, rejecting replacement {failure_package_txns3[1].rehash()}, not enough additional fees to relay; {incremental_sats_short} < {incremental_sats_required}", pkg_results3["package_msg"]) + assert_equal(f"package RBF failed: insufficient anti-DoS fees, rejecting replacement {failure_package_txns3[1].rehash()}, not enough additional fees to relay; {incremental_sats_short:.8f} < {incremental_sats_required:.8f}", pkg_results3["package_msg"]) self.assert_mempool_contents(expected=package_txns1) success_package_hex3, success_package_txns3 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE + incremental_sats_required) @@ -563,12 +563,13 @@ def test_child_conflicts_parent_mempool_ancestor(self): ) node.sendrawtransaction(grandparent_result["hex"]) + minrelayfeerate = node.getnetworkinfo()["relayfee"] # Now make package of two descendants that looks # like a cpfp where the parent can't get in on its own self.ctr += 1 parent_result = self.wallet.create_self_transfer( - fee_rate=Decimal('0.00001000'), + fee_rate=minrelayfeerate, utxo_to_spend=grandparent_result["new_utxo"], sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, ) diff --git a/test/functional/p2p_1p1c_network.py b/test/functional/p2p_1p1c_network.py index e48e5b88b67..4f03542168d 100755 --- a/test/functional/p2p_1p1c_network.py +++ b/test/functional/p2p_1p1c_network.py @@ -13,9 +13,11 @@ from math import ceil from test_framework.mempool_util import ( + DEFAULT_MIN_RELAY_TX_FEE, fill_mempool, ) from test_framework.messages import ( + COIN, msg_tx, ) from test_framework.p2p import ( @@ -31,9 +33,6 @@ MiniWalletMode, ) -# 1sat/vB feerate denominated in BTC/KvB -FEERATE_1SAT_VB = Decimal("0.00001000") - class PackageRelayTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True @@ -51,12 +50,12 @@ def raise_network_minfee(self): self.log.debug("Check that all nodes' mempool minimum feerates are above min relay feerate") for node in self.nodes: - assert_equal(node.getmempoolinfo()['minrelaytxfee'], FEERATE_1SAT_VB) - assert_greater_than(node.getmempoolinfo()['mempoolminfee'], FEERATE_1SAT_VB) + assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal(DEFAULT_MIN_RELAY_TX_FEE) / COIN) + assert_greater_than(node.getmempoolinfo()['mempoolminfee'], Decimal(DEFAULT_MIN_RELAY_TX_FEE) / COIN) def create_basic_1p1c(self, wallet): - low_fee_parent = wallet.create_self_transfer(fee_rate=FEERATE_1SAT_VB, confirmed_only=True) - high_fee_child = wallet.create_self_transfer(utxo_to_spend=low_fee_parent["new_utxo"], fee_rate=999*FEERATE_1SAT_VB) + low_fee_parent = wallet.create_self_transfer(fee_rate=Decimal(DEFAULT_MIN_RELAY_TX_FEE) / COIN, confirmed_only=True) + high_fee_child = wallet.create_self_transfer(utxo_to_spend=low_fee_parent["new_utxo"], fee_rate=999*Decimal(DEFAULT_MIN_RELAY_TX_FEE)/ COIN) package_hex_basic = [low_fee_parent["hex"], high_fee_child["hex"]] return package_hex_basic, low_fee_parent["tx"], high_fee_child["tx"] @@ -87,8 +86,8 @@ def create_package_2outs(self, wallet): return [low_fee_parent_2outs["hex"], high_fee_child_2outs["hex"]], low_fee_parent_2outs["tx"], high_fee_child_2outs["tx"] def create_package_2p1c(self, wallet): - parent1 = wallet.create_self_transfer(fee_rate=FEERATE_1SAT_VB*10, confirmed_only=True) - parent2 = wallet.create_self_transfer(fee_rate=FEERATE_1SAT_VB*20, confirmed_only=True) + parent1 = wallet.create_self_transfer(fee_rate=Decimal(DEFAULT_MIN_RELAY_TX_FEE) / COIN * 10, confirmed_only=True) + parent2 = wallet.create_self_transfer(fee_rate=Decimal(DEFAULT_MIN_RELAY_TX_FEE) / COIN * 20, confirmed_only=True) child = wallet.create_self_transfer_multi( utxos_to_spend=[parent1["new_utxo"], parent2["new_utxo"]], fee_per_output=999*parent1["tx"].get_vsize(), diff --git a/test/functional/p2p_ibd_txrelay.py b/test/functional/p2p_ibd_txrelay.py index 870324d76c3..0cd0ac05b2c 100755 --- a/test/functional/p2p_ibd_txrelay.py +++ b/test/functional/p2p_ibd_txrelay.py @@ -28,8 +28,8 @@ ) from test_framework.test_framework import BitcoinTestFramework -MAX_FEE_FILTER = Decimal(9170997) / COIN -NORMAL_FEE_FILTER = Decimal(100) / COIN +MAX_FEE_FILTER = Decimal(9936506) / COIN +NORMAL_FEE_FILTER = Decimal(10) / COIN class P2PIBDTxRelayTest(BitcoinTestFramework): @@ -37,8 +37,8 @@ def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 self.extra_args = [ - ["-minrelaytxfee={}".format(NORMAL_FEE_FILTER)], - ["-minrelaytxfee={}".format(NORMAL_FEE_FILTER)], + ["-minrelaytxfee={:.8f}".format(NORMAL_FEE_FILTER)], + ["-minrelaytxfee={:.8f}".format(NORMAL_FEE_FILTER)], ] def run_test(self): diff --git a/test/functional/p2p_opportunistic_1p1c.py b/test/functional/p2p_opportunistic_1p1c.py index 5cf616b3ef8..5fdbf74a573 100755 --- a/test/functional/p2p_opportunistic_1p1c.py +++ b/test/functional/p2p_opportunistic_1p1c.py @@ -9,10 +9,12 @@ from decimal import Decimal import time from test_framework.mempool_util import ( + DEFAULT_MIN_RELAY_TX_FEE, fill_mempool, ) from test_framework.messages import ( CInv, + COIN, CTxInWitness, MAX_BIP125_RBF_SEQUENCE, MSG_WTX, @@ -65,13 +67,13 @@ def set_test_params(self): self.supports_cli = False def create_tx_below_mempoolminfee(self, wallet): - """Create a 1-input 1sat/vB transaction using a confirmed UTXO. Decrement and use + """Create a 1-input 0.1sat/vB transaction using a confirmed UTXO. Decrement and use self.sequence so that subsequent calls to this function result in unique transactions.""" self.sequence -= 1 - assert_greater_than(self.nodes[0].getmempoolinfo()["mempoolminfee"], FEERATE_1SAT_VB) + assert_greater_than(self.nodes[0].getmempoolinfo()["mempoolminfee"], Decimal(DEFAULT_MIN_RELAY_TX_FEE) / COIN) - return wallet.create_self_transfer(fee_rate=FEERATE_1SAT_VB, sequence=self.sequence, confirmed_only=True) + return wallet.create_self_transfer(fee_rate=Decimal(DEFAULT_MIN_RELAY_TX_FEE) / COIN, sequence=self.sequence, confirmed_only=True) @cleanup def test_basic_child_then_parent(self): diff --git a/test/functional/test_framework/mempool_util.py b/test/functional/test_framework/mempool_util.py index e00fea23d99..56a9b4d262e 100644 --- a/test/functional/test_framework/mempool_util.py +++ b/test/functional/test_framework/mempool_util.py @@ -20,9 +20,9 @@ ORPHAN_TX_EXPIRE_TIME = 1200 # Default for -minrelaytxfee in sat/kvB -DEFAULT_MIN_RELAY_TX_FEE = 1000 +DEFAULT_MIN_RELAY_TX_FEE = 100 # Default for -incrementalrelayfee in sat/kvB -DEFAULT_INCREMENTAL_RELAY_FEE = 1000 +DEFAULT_INCREMENTAL_RELAY_FEE = 100 def assert_mempool_contents(test_framework, node, expected=None, sync=True): """Assert that all transactions in expected are in the mempool, diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 061e9f2caa1..9cec77fb184 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -534,7 +534,7 @@ def test_dust_to_fee(self, rbf_node, dest_address): def test_settxfee(self, rbf_node, dest_address): self.log.info('Test settxfee') - assert_raises_rpc_error(-8, "txfee cannot be less than min relay tx fee", rbf_node.settxfee, Decimal('0.000005')) + assert_raises_rpc_error(-8, "txfee cannot be less than min relay tx fee", rbf_node.settxfee, Decimal('0.0000005')) assert_raises_rpc_error(-8, "txfee cannot be less than wallet min fee", rbf_node.settxfee, Decimal('0.000015')) # check that bumpfee reacts correctly to the use of settxfee (paytxfee) rbfid = spend_one_input(rbf_node, dest_address) @@ -846,7 +846,7 @@ def test_bumpfee_with_feerate_ignores_walletincrementalrelayfee(self, rbf_node, # Ensure you can not fee bump if the fee_rate is more than original fee_rate but the total fee from new fee_rate is # less than (original fee + incrementalrelayfee) - assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2.8}) + assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2.05}) # You can fee bump as long as the new fee set from fee_rate is at least (original fee + incrementalrelayfee) rbf_node.bumpfee(tx["txid"], {"fee_rate": 3}) From f9f1ca5445fc216c770b583c1db999aaf910f96f Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 20 Aug 2025 09:24:49 -0400 Subject: [PATCH 142/314] [doc] update release notes Release notes are from 18720bc5d5b4d3acf91060859180d72cbfdf59b7 --- doc/release-notes.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index b384763e155..f5a91e1adad 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.1rc1 is now available from: +Bitcoin Core version 29.1rc2 is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. @@ -48,6 +48,20 @@ Notable changes - #32521 policy: make pathological transactions packed with legacy sigops non-standard +- 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 + ### Logging Unconditional logging to disk is now rate limited by giving each source location @@ -181,6 +195,7 @@ Thanks to everyone who directly contributed to this release: - enirox001 - fanquake - furszy +- glozow - instagibbs - Hennadii Stepanov - hodlinator From eb1574af0c6cba4918957d704c5c0f17235a10b5 Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 20 Aug 2025 09:41:47 -0400 Subject: [PATCH 143/314] [build] bump version to 29.1rc2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 13ceac65f2b..50160dede3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 1) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 1) +set(CLIENT_VERSION_RC 2) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From 0034dcfba9dc599449e7569ed1b30e58d4f4434f Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 20 Aug 2025 09:45:13 -0400 Subject: [PATCH 144/314] [doc] man pages for 29.1rc2 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 10 +++++----- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 10 +++++----- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index dfc4d5ad40c..7a5523b7589 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "July 2025" "bitcoin-cli v29.1.0rc1" "User Commands" +.TH BITCOIN-CLI "1" "August 2025" "bitcoin-cli v29.1.0rc2" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.1.0rc1 +bitcoin-cli \- manual page for bitcoin-cli v29.1.0rc2 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.1.0rc1 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.1.0rc1 +Bitcoin Core RPC client version v29.1.0rc2 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index ca2bc8eb864..68db7bd3ad8 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "July 2025" "bitcoin-qt v29.1.0rc1" "User Commands" +.TH BITCOIN-QT "1" "August 2025" "bitcoin-qt v29.1.0rc2" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.1.0rc1 +bitcoin-qt \- manual page for bitcoin-qt v29.1.0rc2 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.1.0rc1 +Bitcoin Core version v29.1.0rc2 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP @@ -702,7 +702,7 @@ this size or less (default: 83) \fB\-minrelaytxfee=\fR .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 +729,7 @@ Set maximum BIP141 block weight (default: 4000000) \fB\-blockmintxfee=\fR .IP Set lowest fee rate (in BTC/kvB) for transactions to be included in -block creation. (default: 0.00001) +block creation. (default: 0.00000001) .HP \fB\-blockreservedweight=\fR .IP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index db199ff7408..288e8bf3e50 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "July 2025" "bitcoin-tx v29.1.0rc1" "User Commands" +.TH BITCOIN-TX "1" "August 2025" "bitcoin-tx v29.1.0rc2" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.1.0rc1 +bitcoin-tx \- manual page for bitcoin-tx v29.1.0rc2 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.1.0rc1 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.1.0rc1 +Bitcoin Core bitcoin\-tx utility version v29.1.0rc2 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index 07d61d78454..ebe0641225d 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "July 2025" "bitcoin-util v29.1.0rc1" "User Commands" +.TH BITCOIN-UTIL "1" "August 2025" "bitcoin-util v29.1.0rc2" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.1.0rc1 +bitcoin-util \- manual page for bitcoin-util v29.1.0rc2 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.1.0rc1 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.1.0rc1 +Bitcoin Core bitcoin\-util utility version v29.1.0rc2 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index 636e8c5906d..4110979bf3b 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "July 2025" "bitcoin-wallet v29.1.0rc1" "User Commands" +.TH BITCOIN-WALLET "1" "August 2025" "bitcoin-wallet v29.1.0rc2" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.1.0rc1 +bitcoin-wallet \- manual page for bitcoin-wallet v29.1.0rc2 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.1.0rc1 +Bitcoin Core bitcoin\-wallet utility version v29.1.0rc2 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 8e41a3a763a..da7af79b20f 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "July 2025" "bitcoind v29.1.0rc1" "User Commands" +.TH BITCOIND "1" "August 2025" "bitcoind v29.1.0rc2" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.1.0rc1 +bitcoind \- manual page for bitcoind v29.1.0rc2 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.1.0rc1 +Bitcoin Core daemon version v29.1.0rc2 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP @@ -702,7 +702,7 @@ this size or less (default: 83) \fB\-minrelaytxfee=\fR .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 +729,7 @@ Set maximum BIP141 block weight (default: 4000000) \fB\-blockmintxfee=\fR .IP Set lowest fee rate (in BTC/kvB) for transactions to be included in -block creation. (default: 0.00001) +block creation. (default: 0.00000001) .HP \fB\-blockreservedweight=\fR .IP From 65dc198d2cf7160f54a469a0c806232e83dc7599 Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 21 Aug 2025 11:42:27 +0100 Subject: [PATCH 145/314] doc: update example bitcoin conf for 29.1rc2 --- share/examples/bitcoin.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/examples/bitcoin.conf b/share/examples/bitcoin.conf index d3999ecb4ac..d7c170da358 100644 --- a/share/examples/bitcoin.conf +++ b/share/examples/bitcoin.conf @@ -581,7 +581,7 @@ #datacarriersize=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= # Relay transactions creating non-P2SH multisig outputs (default: 1) @@ -605,7 +605,7 @@ #blockmaxweight= # Set lowest fee rate (in BTC/kvB) for transactions to be included in -# block creation. (default: 0.00001) +# block creation. (default: 0.00000001) #blockmintxfee= # Reserve space for the fixed-size block header plus the largest coinbase From 16b1710d97464f134a526634a412a4b1b6cc8639 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Mon, 18 Aug 2025 21:36:01 +0200 Subject: [PATCH 146/314] index: don't commit state in BaseIndex::Rewind The committed state of an index should never be ahead of the flushed chainstate. Otherwise, in the case of an unclean shutdown, the blocks necessary to revert from the prematurely committed state would not be available, which would corrupt the coinstatsindex in particular. Instead, the index state will be committed with the next ChainStateFlushed notification. Github-Pull: #33212 Rebased-From: 01b95ac6f496e24e525b2fc9d69ee8b543da65ff --- src/index/base.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/index/base.cpp b/src/index/base.cpp index 1169a1c86b7..e08f9083992 100644 --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -253,18 +253,13 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti return false; } - // In the case of a reorg, ensure persisted block locator is not stale. + // Don't commit here - the committed index state must never be ahead of the + // flushed chainstate, otherwise unclean restarts would lead to index corruption. // Pruning has a minimum of 288 blocks-to-keep and getting the index // out of sync may be possible but a users fault. // In case we reorg beyond the pruned depth, ReadBlock would // throw and lead to a graceful shutdown SetBestBlockIndex(new_tip); - if (!Commit()) { - // If commit fails, revert the best block index to avoid corruption. - SetBestBlockIndex(current_tip); - return false; - } - return true; } From fcac8022d839572f5d8781096eec14ca7ea2e0dd Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Mon, 18 Aug 2025 21:21:48 +0200 Subject: [PATCH 147/314] test: index with an unclean restart after a reorg This test fails without the previous commit. Github-Pull: #33212 Rebased-From: a602f6fb7bf5f9e57299f4d6e246c82379fad8d2 --- test/functional/feature_coinstatsindex.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/functional/feature_coinstatsindex.py b/test/functional/feature_coinstatsindex.py index 764f027c857..dd1484f8b3e 100755 --- a/test/functional/feature_coinstatsindex.py +++ b/test/functional/feature_coinstatsindex.py @@ -322,6 +322,21 @@ def _test_init_index_after_reorg(self): res1 = index_node.gettxoutsetinfo(hash_type='muhash', hash_or_height=None, use_index=True) assert_equal(res["muhash"], res1["muhash"]) + self.log.info("Test index with an unclean restart after a reorg") + self.restart_node(1, extra_args=self.extra_args[1]) + committed_height = index_node.getblockcount() + self.generate(index_node, 2, sync_fun=self.no_op) + self.sync_index_node() + block2 = index_node.getbestblockhash() + index_node.invalidateblock(block2) + self.generatetoaddress(index_node, 1, getnewdestination()[2], sync_fun=self.no_op) + self.sync_index_node() + index_node.kill_process() + self.start_node(1, extra_args=self.extra_args[1]) + self.sync_index_node() + # Because of the unclean shutdown above, indexes reset to the point we last committed them to disk. + assert_equal(index_node.getindexinfo()['coinstatsindex']['best_block_height'], committed_height) + if __name__ == '__main__': CoinStatsIndexTest(__file__).main() From 6448ebb5a7c942949a70ffc4a1d2a93338fac130 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Thu, 21 Aug 2025 14:04:03 +0200 Subject: [PATCH 148/314] doc: Remove wrong and redundant doxygen tag Remove it in feerate. Fix it in the other places. Github-Pull: #33236 Rebased-From: 966666de9a6211b8748f43d682490c924e132e58 --- src/policy/feerate.h | 3 --- src/wallet/coinselection.cpp | 14 +++++++------- src/wallet/spend.h | 30 +++++++++++++++--------------- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/policy/feerate.h b/src/policy/feerate.h index d742a43acc7..6bcb5ddf5b6 100644 --- a/src/policy/feerate.h +++ b/src/policy/feerate.h @@ -44,9 +44,6 @@ class CFeeRate /** * 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); diff --git a/src/wallet/coinselection.cpp b/src/wallet/coinselection.cpp index 6e6d7e053bd..1302ec99d65 100644 --- a/src/wallet/coinselection.cpp +++ b/src/wallet/coinselection.cpp @@ -589,15 +589,15 @@ util::Result SelectCoinsSRD(const std::vector& 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& groups, const CAmount& nTotalLower, const CAmount& nTargetValue, diff --git a/src/wallet/spend.h b/src/wallet/spend.h index 62a7b4e4c89..4bdc8484648 100644 --- a/src/wallet/spend.h +++ b/src/wallet/spend.h @@ -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 AttemptSelection(interfaces::Chain& chain, const CAmount& nTargetValue, OutputGroupTypeMap& groups, @@ -141,13 +141,13 @@ util::Result 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 ChooseSelectionResult(interfaces::Chain& chain, const CAmount& nTargetValue, Groups& groups, const CoinSelectionParams& coin_selection_params); @@ -181,10 +181,10 @@ util::Result 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") From 99ab2e70e782bf5ca753ad636f69642da6054283 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 27 Aug 2025 10:58:40 +0100 Subject: [PATCH 149/314] ci: return to using dash in CentOS job Github-Pull: #33261 Rebased-From: 509ffea40abbc706ef8b8fc449b7de8677fc5096 --- ci/test/00_setup_env_native_centos.sh | 2 +- ci/test/03_test_script.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/test/00_setup_env_native_centos.sh b/ci/test/00_setup_env_native_centos.sh index c423d788eb8..af27a5ebe1b 100755 --- a/ci/test/00_setup_env_native_centos.sh +++ b/ci/test/00_setup_env_native_centos.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_native_centos export CI_IMAGE_NAME_TAG="quay.io/centos/centos:stream10" -export CI_BASE_PACKAGES="gcc-c++ glibc-devel libstdc++-devel ccache make git python3 python3-pip which patch xz procps-ng ksh rsync coreutils bison e2fsprogs cmake" +export CI_BASE_PACKAGES="gcc-c++ glibc-devel libstdc++-devel ccache make git python3 python3-pip which patch xz procps-ng rsync coreutils bison e2fsprogs cmake dash" export PIP_PACKAGES="pyzmq" export DEP_OPTS="DEBUG=1" # Temporarily enable a DEBUG=1 build to check for GCC-bug-117966 regressions. This can be removed once the minimum GCC version is bumped to 12 in the previous releases task, see https://github.com/bitcoin/bitcoin/issues/31436#issuecomment-2530717875 export GOAL="install" diff --git a/ci/test/03_test_script.sh b/ci/test/03_test_script.sh index 3dd44807c9e..b218e7b9d1a 100755 --- a/ci/test/03_test_script.sh +++ b/ci/test/03_test_script.sh @@ -92,7 +92,7 @@ fi if [ -z "$NO_DEPENDS" ]; then if [[ $CI_IMAGE_NAME_TAG == *centos* ]]; then - SHELL_OPTS="CONFIG_SHELL=/bin/ksh" # Temporarily use ksh instead of dash, until https://bugzilla.redhat.com/show_bug.cgi?id=2335416 is fixed. + SHELL_OPTS="CONFIG_SHELL=/bin/dash" else SHELL_OPTS="CONFIG_SHELL=" fi From b0d88bcc501bf0fc06e64c2f0a295b99a1101073 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 29 Aug 2025 14:47:16 +0100 Subject: [PATCH 150/314] doc: finalise release notes for 29.1 --- doc/release-notes.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index f5a91e1adad..923d34a99bb 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.1rc2 is now available from: +Bitcoin Core version 29.1 is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. @@ -113,6 +113,10 @@ function signature instead of just the function name. (#32604) - #32859 test: correctly detect nonstd TRUC tx vsize in feature_taproot - #33001 test: Do not pass tests on unhandled exceptions +### Indexes + +- #33212 index: Don't commit state in BaseIndex::Rewind + ### Util - #32248 Remove support for RNDR/RNDRRS for aarch64 @@ -162,10 +166,12 @@ function signature instead of just the function name. (#32604) - #33088 doc: move cmake -B build -LH up in Unix build docs - #33133 rpc: fix getpeerinfo ping duration unit docs - #33119 rpc: Fix 'getdescriptoractivity' RPCHelpMan, add test to verify fix +- #33236 doc: Remove wrong and redundant doxygen tag ### CI - #32184 ci: Add workaround for vcpkg's libevent package +- #33261 ci: return to using dash in CentOS job ### Misc From 37d115c67eafec68128649651a7e921c3e2635ce Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 3 Sep 2025 13:23:09 +0100 Subject: [PATCH 151/314] build: bump version to v29.1 final --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50160dede3d..dc613a7655f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 1) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 2) +set(CLIENT_VERSION_RC 0) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From 084c95a18c9978c0a047ffe219a9eef8ab327ea6 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 3 Sep 2025 13:41:57 +0100 Subject: [PATCH 152/314] doc: update manual pages for v29.1 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 7a5523b7589..428ddd3e2a2 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "August 2025" "bitcoin-cli v29.1.0rc2" "User Commands" +.TH BITCOIN-CLI "1" "September 2025" "bitcoin-cli v29.1.0" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.1.0rc2 +bitcoin-cli \- manual page for bitcoin-cli v29.1.0 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.1.0rc2 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.1.0rc2 +Bitcoin Core RPC client version v29.1.0 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 68db7bd3ad8..3665a6a48ae 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "August 2025" "bitcoin-qt v29.1.0rc2" "User Commands" +.TH BITCOIN-QT "1" "September 2025" "bitcoin-qt v29.1.0" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.1.0rc2 +bitcoin-qt \- manual page for bitcoin-qt v29.1.0 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.1.0rc2 +Bitcoin Core version v29.1.0 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 288e8bf3e50..16058f1bf94 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "August 2025" "bitcoin-tx v29.1.0rc2" "User Commands" +.TH BITCOIN-TX "1" "September 2025" "bitcoin-tx v29.1.0" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.1.0rc2 +bitcoin-tx \- manual page for bitcoin-tx v29.1.0 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.1.0rc2 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.1.0rc2 +Bitcoin Core bitcoin\-tx utility version v29.1.0 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index ebe0641225d..a103bf40a5b 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "August 2025" "bitcoin-util v29.1.0rc2" "User Commands" +.TH BITCOIN-UTIL "1" "September 2025" "bitcoin-util v29.1.0" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.1.0rc2 +bitcoin-util \- manual page for bitcoin-util v29.1.0 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.1.0rc2 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.1.0rc2 +Bitcoin Core bitcoin\-util utility version v29.1.0 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index 4110979bf3b..b63494dc479 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "August 2025" "bitcoin-wallet v29.1.0rc2" "User Commands" +.TH BITCOIN-WALLET "1" "September 2025" "bitcoin-wallet v29.1.0" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.1.0rc2 +bitcoin-wallet \- manual page for bitcoin-wallet v29.1.0 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.1.0rc2 +Bitcoin Core bitcoin\-wallet utility version v29.1.0 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index da7af79b20f..b8ee6bab52a 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "August 2025" "bitcoind v29.1.0rc2" "User Commands" +.TH BITCOIND "1" "September 2025" "bitcoind v29.1.0" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.1.0rc2 +bitcoind \- manual page for bitcoind v29.1.0 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.1.0rc2 +Bitcoin Core daemon version v29.1.0 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From 10cbf2255d9e74166f5f41e82fefa4a7f890e73f Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Wed, 12 Feb 2025 17:39:52 +0100 Subject: [PATCH 153/314] ci: Use APT_LLVM_V in msan task Also, use update-alternatives to avoid having to manually specify clang-${APT_LLVM_V} or llvm-symbolizer-${APT_LLVM_V} everywhere. Github-Pull: #32999 Rebased-From: fad040a5787a8ac0a13aef5c54e5a675de239e92 --- ci/test/00_setup_env_native_asan.sh | 4 +-- ci/test/00_setup_env_native_fuzz.sh | 5 ++-- ci/test/00_setup_env_native_msan.sh | 3 ++- ci/test/00_setup_env_native_tsan.sh | 2 +- ci/test/01_base_install.sh | 40 ++++++++++++++++++----------- 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh index ead550a43ce..9f562df4647 100755 --- a/ci/test/00_setup_env_native_asan.sh +++ b/ci/test/00_setup_env_native_asan.sh @@ -26,8 +26,8 @@ export GOAL="install" export BITCOIN_CONFIG="\ -DWITH_USDT=ON -DWITH_ZMQ=ON -DWITH_BDB=ON -DWARN_INCOMPATIBLE_BDB=OFF -DBUILD_GUI=ON \ -DSANITIZERS=address,float-divide-by-zero,integer,undefined \ - -DCMAKE_C_COMPILER=clang-${APT_LLVM_V} \ - -DCMAKE_CXX_COMPILER=clang++-${APT_LLVM_V} \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_C_FLAGS='-ftrivial-auto-var-init=pattern' \ -DCMAKE_CXX_FLAGS='-ftrivial-auto-var-init=pattern -Wno-error=deprecated-declarations' \ -DAPPEND_CXXFLAGS='-std=c++23' \ diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh index c5220211fc5..f80c4d988de 100755 --- a/ci/test/00_setup_env_native_fuzz.sh +++ b/ci/test/00_setup_env_native_fuzz.sh @@ -19,9 +19,8 @@ export CI_CONTAINER_CAP="--cap-add SYS_PTRACE" # If run with (ASan + LSan), the export BITCOIN_CONFIG="\ -DBUILD_FOR_FUZZING=ON \ -DSANITIZERS=fuzzer,address,undefined,float-divide-by-zero,integer \ - -DCMAKE_C_COMPILER=clang-${APT_LLVM_V} \ - -DCMAKE_CXX_COMPILER=clang++-${APT_LLVM_V} \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_C_FLAGS='-ftrivial-auto-var-init=pattern' \ -DCMAKE_CXX_FLAGS='-ftrivial-auto-var-init=pattern' \ " -export LLVM_SYMBOLIZER_PATH="/usr/bin/llvm-symbolizer-${APT_LLVM_V}" diff --git a/ci/test/00_setup_env_native_msan.sh b/ci/test/00_setup_env_native_msan.sh index 8784aaa5b7b..effd8a9413d 100755 --- a/ci/test/00_setup_env_native_msan.sh +++ b/ci/test/00_setup_env_native_msan.sh @@ -7,13 +7,14 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" +export APT_LLVM_V="20" LIBCXX_DIR="/msan/cxx_build/" export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls" LIBCXX_FLAGS="-nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}" export CONTAINER_NAME="ci_native_msan" -export PACKAGES="ninja-build" +export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} llvm-${APT_LLVM_V}-dev libclang-${APT_LLVM_V}-dev libclang-rt-${APT_LLVM_V}-dev ninja-build" # BDB generates false-positives and will be removed in future export DEP_OPTS="DEBUG=1 NO_BDB=1 NO_QT=1 CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" export GOAL="install" diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index b341adfec53..c8d9c8455f4 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -10,7 +10,7 @@ export CONTAINER_NAME=ci_native_tsan export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export APT_LLVM_V="20" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev libc++abi-${APT_LLVM_V}-dev libc++-${APT_LLVM_V}-dev python3-zmq" -export DEP_OPTS="CC=clang-${APT_LLVM_V} CXX='clang++-${APT_LLVM_V} -stdlib=libc++'" +export DEP_OPTS="CC=clang CXX='clang++ -stdlib=libc++'" export GOAL="install" export BITCOIN_CONFIG="-DWITH_ZMQ=ON -DSANITIZERS=thread \ -DAPPEND_CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES'" diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index 1344563268f..36a7c43b3f1 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -43,27 +43,37 @@ elif [ "$CI_OS_NAME" != "macos" ]; then ${CI_RETRY_EXE} bash -c "apt-get install --no-install-recommends --no-upgrade -y $PACKAGES $CI_BASE_PACKAGES" fi +if [ -n "${APT_LLVM_V}" ]; then + update-alternatives --install /usr/bin/clang++ clang++ "/usr/bin/clang++-${APT_LLVM_V}" 100 + update-alternatives --install /usr/bin/clang clang "/usr/bin/clang-${APT_LLVM_V}" 100 + update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer "/usr/bin/llvm-symbolizer-${APT_LLVM_V}" 100 +fi + if [ -n "$PIP_PACKAGES" ]; then # shellcheck disable=SC2086 ${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES fi if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then - ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-20.1.0" /msan/llvm-project - - cmake -G Ninja -B /msan/clang_build/ \ - -DLLVM_ENABLE_PROJECTS="clang" \ - -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_TARGETS_TO_BUILD=Native \ - -DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \ - -S /msan/llvm-project/llvm - - ninja -C /msan/clang_build/ "$MAKEJOBS" - ninja -C /msan/clang_build/ install-runtimes - - update-alternatives --install /usr/bin/clang++ clang++ /msan/clang_build/bin/clang++ 100 - update-alternatives --install /usr/bin/clang clang /msan/clang_build/bin/clang 100 - update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer /msan/clang_build/bin/llvm-symbolizer 100 + if [ -n "${APT_LLVM_V}" ]; then + ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-$( clang --version | sed --silent 's@.*clang version \([0-9.]*\).*@\1@p' )" /msan/llvm-project + else + ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-20.1.8" /msan/llvm-project + + cmake -G Ninja -B /msan/clang_build/ \ + -DLLVM_ENABLE_PROJECTS="clang" \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_TARGETS_TO_BUILD=Native \ + -DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \ + -S /msan/llvm-project/llvm + + ninja -C /msan/clang_build/ "$MAKEJOBS" + ninja -C /msan/clang_build/ install-runtimes + + update-alternatives --install /usr/bin/clang++ clang++ /msan/clang_build/bin/clang++ 100 + update-alternatives --install /usr/bin/clang clang /msan/clang_build/bin/clang 100 + update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer /msan/clang_build/bin/llvm-symbolizer 100 + fi cmake -G Ninja -B /msan/cxx_build/ \ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ From 0fba5ae02101b358aa4938d35471356b75e0e615 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 30 Jul 2025 11:10:16 +0100 Subject: [PATCH 154/314] ci: allow libc++ instrumentation other than msan Github-Pull: #33099 Rebased-From: 6653cafd0b70b0e7a29c6cfe236d3bf9d1bce91e --- ci/test/00_setup_env_native_fuzz_with_msan.sh | 4 +-- ci/test/00_setup_env_native_msan.sh | 4 +-- ci/test/01_base_install.sh | 32 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ci/test/00_setup_env_native_fuzz_with_msan.sh b/ci/test/00_setup_env_native_fuzz_with_msan.sh index a6e53dc8a2f..27b704017c4 100755 --- a/ci/test/00_setup_env_native_fuzz_with_msan.sh +++ b/ci/test/00_setup_env_native_fuzz_with_msan.sh @@ -7,7 +7,7 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" -LIBCXX_DIR="/msan/cxx_build/" +LIBCXX_DIR="/cxx_build/" export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls" LIBCXX_FLAGS="-nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}" @@ -27,7 +27,7 @@ export BITCOIN_CONFIG="\ -DSANITIZERS=fuzzer,memory \ -DAPPEND_CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE -U_FORTIFY_SOURCE' \ " -export USE_MEMORY_SANITIZER="true" +export USE_INSTRUMENTED_LIBCPP="MemoryWithOrigins" export RUN_UNIT_TESTS="false" export RUN_FUNCTIONAL_TESTS="false" export RUN_FUZZ_TESTS=true diff --git a/ci/test/00_setup_env_native_msan.sh b/ci/test/00_setup_env_native_msan.sh index effd8a9413d..b450a2ea1eb 100755 --- a/ci/test/00_setup_env_native_msan.sh +++ b/ci/test/00_setup_env_native_msan.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export APT_LLVM_V="20" -LIBCXX_DIR="/msan/cxx_build/" +LIBCXX_DIR="/cxx_build/" export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls" LIBCXX_FLAGS="-nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}" @@ -27,4 +27,4 @@ export BITCOIN_CONFIG="\ -DSANITIZERS=memory \ -DAPPEND_CPPFLAGS='-U_FORTIFY_SOURCE' \ " -export USE_MEMORY_SANITIZER="true" +export USE_INSTRUMENTED_LIBCPP="MemoryWithOrigins" diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index 36a7c43b3f1..4746a1f69d0 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -54,31 +54,31 @@ if [ -n "$PIP_PACKAGES" ]; then ${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES fi -if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then +if [[ -n "${USE_INSTRUMENTED_LIBCPP}" ]]; then if [ -n "${APT_LLVM_V}" ]; then - ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-$( clang --version | sed --silent 's@.*clang version \([0-9.]*\).*@\1@p' )" /msan/llvm-project + ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-$( clang --version | sed --silent 's@.*clang version \([0-9.]*\).*@\1@p' )" /llvm-project else - ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-20.1.8" /msan/llvm-project + ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-20.1.8" /llvm-project - cmake -G Ninja -B /msan/clang_build/ \ + cmake -G Ninja -B /clang_build/ \ -DLLVM_ENABLE_PROJECTS="clang" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_TARGETS_TO_BUILD=Native \ -DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \ - -S /msan/llvm-project/llvm + -S /llvm-project/llvm - ninja -C /msan/clang_build/ "$MAKEJOBS" - ninja -C /msan/clang_build/ install-runtimes + ninja -C /clang_build/ "$MAKEJOBS" + ninja -C /clang_build/ install-runtimes - update-alternatives --install /usr/bin/clang++ clang++ /msan/clang_build/bin/clang++ 100 - update-alternatives --install /usr/bin/clang clang /msan/clang_build/bin/clang 100 - update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer /msan/clang_build/bin/llvm-symbolizer 100 + update-alternatives --install /usr/bin/clang++ clang++ /clang_build/bin/clang++ 100 + update-alternatives --install /usr/bin/clang clang /clang_build/bin/clang 100 + update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer /clang_build/bin/llvm-symbolizer 100 fi - cmake -G Ninja -B /msan/cxx_build/ \ + cmake -G Ninja -B /cxx_build/ \ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_USE_SANITIZER=MemoryWithOrigins \ + -DLLVM_USE_SANITIZER="${USE_INSTRUMENTED_LIBCPP}" \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DLLVM_TARGETS_TO_BUILD=Native \ @@ -86,13 +86,13 @@ if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ -DLIBCXX_ABI_DEFINES="_LIBCPP_ABI_BOUNDED_ITERATORS;_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY;_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING;_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR;_LIBCPP_ABI_BOUNDED_UNIQUE_PTR" \ -DLIBCXX_HARDENING_MODE=debug \ - -S /msan/llvm-project/runtimes + -S /llvm-project/runtimes - ninja -C /msan/cxx_build/ "$MAKEJOBS" + ninja -C /cxx_build/ "$MAKEJOBS" # Clear no longer needed source folder - du -sh /msan/llvm-project - rm -rf /msan/llvm-project + du -sh /llvm-project + rm -rf /llvm-project fi if [[ "${RUN_TIDY}" == "true" ]]; then From f9939cdbe01fa090bd2ece90f5cbfb17120c2f24 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 30 Jul 2025 11:15:33 +0100 Subject: [PATCH 155/314] ci: instrument libc++ in TSAN job Qt is disabled, as the build is now taking a very long time. Github-Pull: #33099 Rebased-From: b09af2ce508185086bb551bfeb1409355c897e7b --- .cirrus.yml | 2 +- ci/test/00_setup_env_native_tsan.sh | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 393237af66b..6e70dc15fec 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -158,7 +158,7 @@ task: FILE_ENV: "./ci/test/00_setup_env_native_previous_releases.sh" task: - name: 'TSan, depends, gui' + name: 'TSan, depends, no gui' << : *GLOBAL_TASK_TEMPLATE persistent_worker: labels: diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index c8d9c8455f4..dce63d51515 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -9,8 +9,11 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_native_tsan export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export APT_LLVM_V="20" -export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev libc++abi-${APT_LLVM_V}-dev libc++-${APT_LLVM_V}-dev python3-zmq" -export DEP_OPTS="CC=clang CXX='clang++ -stdlib=libc++'" +LIBCXX_DIR="/cxx_build/" +LIBCXX_FLAGS="-fsanitize=thread -nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" +export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} llvm-${APT_LLVM_V}-dev libclang-${APT_LLVM_V}-dev libclang-rt-${APT_LLVM_V}-dev python3-zmq ninja-build" +export DEP_OPTS="CC=clang CXX=clang++ CXXFLAGS='${LIBCXX_FLAGS}' NO_QT=1" export GOAL="install" export BITCOIN_CONFIG="-DWITH_ZMQ=ON -DSANITIZERS=thread \ -DAPPEND_CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES'" +export USE_INSTRUMENTED_LIBCPP="Thread" From 5513516241463333548600f691a861dba4c1d5c5 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 30 Jul 2025 11:15:54 +0100 Subject: [PATCH 156/314] ci: remove DEBUG_LOCKORDER from TSAN job Github-Pull: #33099 Rebased-From: 7aa5b67132dfb71e915675a3dbcb806284e08197 --- ci/test/00_setup_env_native_tsan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index dce63d51515..7d8d0cf203c 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -15,5 +15,5 @@ export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} llvm-${APT_LLVM_V}-dev l export DEP_OPTS="CC=clang CXX=clang++ CXXFLAGS='${LIBCXX_FLAGS}' NO_QT=1" export GOAL="install" export BITCOIN_CONFIG="-DWITH_ZMQ=ON -DSANITIZERS=thread \ --DAPPEND_CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES'" +-DAPPEND_CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES'" export USE_INSTRUMENTED_LIBCPP="Thread" From ea40fa95d9af004d85187bee9d8efe278c888d8f Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 26 Aug 2025 16:49:38 +0100 Subject: [PATCH 157/314] ci: use LLVM 21 Github-Pull: #33258 Rebased-From: 4cf0ae474ba03830c86653f1abae4ab4d38c94e4 --- ci/test/00_setup_env_native_asan.sh | 2 +- ci/test/00_setup_env_native_fuzz.sh | 2 +- ci/test/00_setup_env_native_msan.sh | 2 +- ci/test/00_setup_env_native_tsan.sh | 2 +- ci/test/01_base_install.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh index 9f562df4647..dbfcc259d66 100755 --- a/ci/test/00_setup_env_native_asan.sh +++ b/ci/test/00_setup_env_native_asan.sh @@ -19,7 +19,7 @@ else fi export CONTAINER_NAME=ci_native_asan -export APT_LLVM_V="20" +export APT_LLVM_V="21" export PACKAGES="systemtap-sdt-dev clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev python3-zmq qtbase5-dev qttools5-dev qttools5-dev-tools libevent-dev libboost-dev libdb5.3++-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE}" export NO_DEPENDS=1 export GOAL="install" diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh index f80c4d988de..d81cbcf228f 100755 --- a/ci/test/00_setup_env_native_fuzz.sh +++ b/ci/test/00_setup_env_native_fuzz.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export CONTAINER_NAME=ci_native_fuzz -export APT_LLVM_V="20" +export APT_LLVM_V="21" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev libevent-dev libboost-dev libsqlite3-dev" export NO_DEPENDS=1 export RUN_UNIT_TESTS=false diff --git a/ci/test/00_setup_env_native_msan.sh b/ci/test/00_setup_env_native_msan.sh index b450a2ea1eb..879e82d55a4 100755 --- a/ci/test/00_setup_env_native_msan.sh +++ b/ci/test/00_setup_env_native_msan.sh @@ -7,7 +7,7 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" -export APT_LLVM_V="20" +export APT_LLVM_V="21" LIBCXX_DIR="/cxx_build/" export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls" LIBCXX_FLAGS="-nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index 7d8d0cf203c..6286e39d842 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_native_tsan export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" -export APT_LLVM_V="20" +export APT_LLVM_V="21" LIBCXX_DIR="/cxx_build/" LIBCXX_FLAGS="-fsanitize=thread -nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} llvm-${APT_LLVM_V}-dev libclang-${APT_LLVM_V}-dev libclang-rt-${APT_LLVM_V}-dev python3-zmq ninja-build" diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index 4746a1f69d0..25a03d5f503 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -58,7 +58,7 @@ if [[ -n "${USE_INSTRUMENTED_LIBCPP}" ]]; then if [ -n "${APT_LLVM_V}" ]; then ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-$( clang --version | sed --silent 's@.*clang version \([0-9.]*\).*@\1@p' )" /llvm-project else - ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-20.1.8" /llvm-project + ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-21.1.0" /llvm-project cmake -G Ninja -B /clang_build/ \ -DLLVM_ENABLE_PROJECTS="clang" \ From 7c6be9acae5a16956a7f8e53ae3f944a187a6713 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 5 Sep 2025 12:04:09 +0100 Subject: [PATCH 158/314] doc: update release notes for 29.x --- doc/release-notes.md | 183 ++----------------------------------------- 1 file changed, 5 insertions(+), 178 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 923d34a99bb..b73e52dc570 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.1 is now available from: +Bitcoin Core version 29.x is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. @@ -37,192 +37,19 @@ unsupported systems. Notable changes =============== -### Mempool Policy - -- The maximum number of potentially executed legacy signature operations in a - single standard transaction is now limited to 2500. Signature operations in all - previous output scripts, in all input scripts, as well as all P2SH redeem - scripts (if there are any) are counted toward the limit. The new limit is - assumed to not affect any known typically formed standard transactions. The - change was done to prepare for a possible BIP54 deployment in the future. - -- #32521 policy: make pathological transactions packed with legacy sigops non-standard - -- 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 - -### Logging - -Unconditional logging to disk is now rate limited by giving each source location -a quota of 1MiB per hour. Unconditional logging is any logging with a log level -higher than debug, that is `info`, `warning`, and `error`. All logs will be -prefixed with `[*]` if there is at least one source location that is currently -being suppressed. (#32604) - -When `-logsourcelocations` is enabled, the log output now contains the entire -function signature instead of just the function name. (#32604) - -### RPC - -- The `dumptxoutset` RPC now requires a `type` parameter to be specified. To maintain pre - v29.0 behavior, use the `latest` parameter. Documenting this change was missed in the v29.0 - release notes. (#30808) - -### Updated Settings - -- The `-maxmempool` and `-dbcache` startup parameters are now capped on - 32-bit systems to 500MB and 1GiB respectively. - -- #32530 node: cap -maxmempool and -dbcache values for 32-bit - -### Wallet - -- #31757 wallet: fix crash on double block disconnection -- #32553 wallet: Fix logging of wallet version - -### P2P - -- #32826 p2p: add more bad ports - -### Test - -- #32069 test: fix intermittent failure in wallet_reorgsrestore.py -- #32286 test: Handle empty string returned by CLI as None in RPC tests -- #32312 test: Fix feature_pruning test after nTime typo fix -- #32336 test: Suppress upstream -Wduplicate-decl-specifier in bpfcc -- #32463 test: fix an incorrect feature_fee_estimation.py subtest -- #32483 test: fix two intermittent failures in wallet_basic.py -- #32630 test: fix sync function in rpc_psbt.py -- #32765 test: Fix list index out of range error in feature_bip68_sequence.py -- #32742 test: fix catchup loop in outbound eviction functional test -- #32823 test: Fix wait_for_getheaders() call in test_outbound_eviction_blocks_relay_only() -- #32833 test: Add msgtype to msg_generic slots -- #32841 feature_taproot: sample tx version border values more -- #32850 test: check P2SH sigop count for coinbase tx -- #32859 test: correctly detect nonstd TRUC tx vsize in feature_taproot -- #33001 test: Do not pass tests on unhandled exceptions - -### Indexes - -- #33212 index: Don't commit state in BaseIndex::Rewind - -### Util - -- #32248 Remove support for RNDR/RNDRRS for aarch64 - -### Build - -- #32356 cmake: Respect user-provided configuration-specific flags -- #32437 crypto: disable ASan for sha256_sse4 with Clang -- #32469 cmake: Allow WITH_DBUS on all Unix-like systems -- #32439 guix: accomodate migration to codeberg -- #32551 cmake: Add missed SSE41_CXXFLAGS -- #32568 depends: use "mkdir -p" when installing xproto -- #32678 guix: warn and abort when SOURCE_DATE_EPOCH is set -- #32690 depends: fix SHA256SUM command on OpenBSD (use GNU mode output) -- #32716 depends: Override host compilers for FreeBSD and OpenBSD -- #32760 depends: capnp 1.2.0 -- #32798 build: add root dir to CMAKE_PREFIX_PATH in toolchain -- #32805 cmake: Use HINTS instead of PATHS in find_* commands -- #32814 cmake: Explicitly specify Boost_ROOT for Homebrew's package -- #32837 depends: fix libevent _WIN32_WINNT usage -- #32943 depends: Force CMAKE_EXPORT_NO_PACKAGE_REGISTRY=TRUE -- #32954 cmake: Drop no longer necessary "cmakeMinimumRequired" object -- #33073 guix: warn SOURCE_DATE_EPOCH set in guix-codesign - -### Gui - -- #864 Crash fix, disconnect numBlocksChanged() signal during shutdown -- #868 Replace stray tfm::format to cerr with qWarning - -### Doc - -- #32333 doc: Add missing top-level description to pruneblockchain RPC -- #32353 doc: Fix fuzz test_runner.py path -- #32389 doc: Fix test_bitcoin path -- #32607 rpc: Note in fundrawtransaction doc, fee rate is for package -- #32679 doc: update tor docs to use bitcoind binary from path -- #32693 depends: fix cmake compatibility error for freetype -- #32696 doc: make -DWITH_ZMQ=ON explicit on build-unix.md -- #32708 rpc, doc: update listdescriptors RCP help -- #32711 doc: add missing packages for BSDs (cmake, gmake, curl) to depends/README.md -- #32719 doc, windows: CompanyName "Bitcoin" => "Bitcoin Core project" -- #32776 doc: taproot became always active in v24.0 -- #32777 doc: fix Transifex 404s -- #32846 doc: clarify that the "-j N" goes after the "--build build" part -- #32858 doc: Add workaround for vcpkg issue with paths with embedded spaces -- #33070 doc/zmq: fix unix socket path example -- #33088 doc: move cmake -B build -LH up in Unix build docs -- #33133 rpc: fix getpeerinfo ping duration unit docs -- #33119 rpc: Fix 'getdescriptoractivity' RPCHelpMan, add test to verify fix -- #33236 doc: Remove wrong and redundant doxygen tag - ### CI -- #32184 ci: Add workaround for vcpkg's libevent package -- #33261 ci: return to using dash in CentOS job - -### Misc - -- #32187 refactor: Remove spurious virtual from final ~CZMQNotificationInterface -- #32454 tracing: fix invalid argument in mempool_monitor -- #32771 contrib: tracing: Fix read of pmsg_type in p2p_monitor.py -- #33086 contrib: [tracing] fix pointer argument handling in mempool_monitor.py +- #32999 ci: Use APT_LLVM_V in msan task +- #33099 ci: allow for any libc++ intrumentation & use it for TSAN +- #33258 ci: use LLVM 21 Credits ======= Thanks to everyone who directly contributed to this release: -- 0xB10C -- achow101 -- Antoine Poinsot -- benthecarman -- bigspider -- Brandon Odiwuor -- brunoerg -- Bufo -- Christewart -- Crypt-iQ -- davidgumberg -- deadmanoz -- dergoegge -- enirox001 - fanquake -- furszy -- glozow -- instagibbs -- Hennadii Stepanov -- hodlinator -- ismaelsadeeq -- jb55 -- jlopp -- josibake -- laanwj -- luisschwab - MarcoFalke -- Martin Zumsande -- monlovesmango -- nervana21 -- pablomartin4btc -- rkrux -- romanz -- ryanofsky -- Sjors -- theStack -- willcl-ark -- zaidmstrr As well as to everyone that helped with translations on [Transifex](https://explore.transifex.com/bitcoin/bitcoin/). From 2717331981ec94fd616a08f31e643391a2118639 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 8 Sep 2025 12:11:47 +0100 Subject: [PATCH 159/314] Fix benchmark CSV output The `SHA256AutoDetect` return output is used, among other use cases, to name benchmarks. Using a comma breaks the CSV output. This change replaces the comma with a semicolon, which fixes the issue. Github-Pull: #33340 Rebased-From: 790b440197bde322432a5bab161f1869b667e681 --- src/crypto/sha256.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 09c5d3123e8..c5f495708d6 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -627,7 +627,7 @@ std::string SHA256AutoDetect(sha256_implementation::UseImplementation use_implem Transform = sha256_x86_shani::Transform; TransformD64 = TransformD64Wrapper; 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; TransformD64_2way = sha256d64_arm_shani::Transform_2way; - ret = "arm_shani(1way,2way)"; + ret = "arm_shani(1way;2way)"; } #endif #endif // DISABLE_OPTIMIZED_SHA256 From 324caa84977cc74ac19df605503483e59739773e Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 10 Sep 2025 09:12:40 +0100 Subject: [PATCH 160/314] ci: always use tag for LLVM checkout Rather than trying to match the apt installed clang version, which is prone to intermittent issues. i.e #33345. Github-Pull: #33364 Rebased-From: b736052e39f1f466f63f261ace3dd2deba171e8a --- ci/test/01_base_install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index 25a03d5f503..1b624f38942 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -55,10 +55,9 @@ if [ -n "$PIP_PACKAGES" ]; then fi if [[ -n "${USE_INSTRUMENTED_LIBCPP}" ]]; then + ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-21.1.1" /llvm-project + if [ -n "${APT_LLVM_V}" ]; then - ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-$( clang --version | sed --silent 's@.*clang version \([0-9.]*\).*@\1@p' )" /llvm-project - else - ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-21.1.0" /llvm-project cmake -G Ninja -B /clang_build/ \ -DLLVM_ENABLE_PROJECTS="clang" \ From e97588fc3d1e1a02382312ade7d529c5b4b60016 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 4 Sep 2025 19:25:33 +0000 Subject: [PATCH 161/314] trace: Workaround GCC bug compiling with old systemtap Github-Pull: #33310 Rebased-From: 93a29ff2830162c8129d35c7b9beb43fab984503 --- cmake/module/FindUSDT.cmake | 4 ++++ src/util/trace.h | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/cmake/module/FindUSDT.cmake b/cmake/module/FindUSDT.cmake index 0be7c28ff58..234a099f3fd 100644 --- a/cmake/module/FindUSDT.cmake +++ b/cmake/module/FindUSDT.cmake @@ -36,6 +36,10 @@ if(USDT_INCLUDE_DIR) include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_INCLUDES ${USDT_INCLUDE_DIR}) check_cxx_source_compiles(" + #if defined(__arm__) + # define STAP_SDT_ARG_CONSTRAINT g + #endif + // Setting SDT_USE_VARIADIC lets systemtap (sys/sdt.h) know that we want to use // the optional variadic macros to define tracepoints. #define SDT_USE_VARIADIC 1 diff --git a/src/util/trace.h b/src/util/trace.h index 3deefeade37..ab005dd8bce 100644 --- a/src/util/trace.h +++ b/src/util/trace.h @@ -9,6 +9,13 @@ #ifdef ENABLE_TRACING +// Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103395 +// systemtap 4.6 on 32-bit ARM triggers internal compiler error +// (this workaround is included in systemtap 4.7+) +#if defined(__arm__) +# define STAP_SDT_ARG_CONSTRAINT g +#endif + // Setting SDT_USE_VARIADIC lets systemtap (sys/sdt.h) know that we want to use // the optional variadic macros to define tracepoints. #define SDT_USE_VARIADIC 1 From 9b95ab5e9db1691be5f26fc5bc1c186777d2dc5b Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Wed, 21 May 2025 13:36:43 -0400 Subject: [PATCH 162/314] p2p: Add witness mutation check inside FillBlock Since #29412, we have not allowed mutated blocks to continue being processed immediately the block is received, but this is only done for the legacy BLOCK message. Extend these checks as belt-and-suspenders to not allow similar mutation strategies to affect relay by honest peers by applying the check inside PartiallyDownloadedBlock::FillBlock, immediately before returning READ_STATUS_OK. This also removes the extraneous CheckBlock call. Github-Pull: #32646 Rebased-From: bac9ee4830664c86c1cb3d38a5b19c722aae2f54 --- src/blockencodings.cpp | 17 +++------ src/blockencodings.h | 7 ++-- src/net_processing.cpp | 10 ++++- src/test/blockencodings_tests.cpp | 16 ++++---- src/test/fuzz/partially_downloaded_block.cpp | 39 ++++++-------------- 5 files changed, 37 insertions(+), 52 deletions(-) diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 5f4061a71dc..5975a99faab 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -180,7 +180,7 @@ bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const return txn_available[index] != nullptr; } -ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector& vtx_missing) +ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector& vtx_missing, bool segwit_active) { if (header.IsNull()) return READ_STATUS_INVALID; @@ -205,16 +205,11 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector< if (vtx_missing.size() != tx_missing_offset) return READ_STATUS_INVALID; - BlockValidationState state; - CheckBlockFn check_block = m_check_block_mock ? m_check_block_mock : CheckBlock; - if (!check_block(block, state, Params().GetConsensus(), /*fCheckPoW=*/true, /*fCheckMerkleRoot=*/true)) { - // TODO: We really want to just check merkle tree manually here, - // but that is expensive, and CheckBlock caches a block's - // "checked-status" (in the CBlock?). CBlock should be able to - // check its own merkle root and cache that check. - if (state.GetResult() == BlockValidationResult::BLOCK_MUTATED) - return READ_STATUS_FAILED; // Possible Short ID collision - return READ_STATUS_CHECKBLOCK_FAILED; + // Check for possible mutations early now that we have a seemingly good block + IsBlockMutatedFn check_mutated{m_check_block_mutated_mock ? m_check_block_mutated_mock : IsBlockMutated}; + if (check_mutated(/*block=*/block, + /*check_witness_root=*/segwit_active)) { + return READ_STATUS_FAILED; // Possible Short ID collision } LogDebug(BCLog::CMPCTBLOCK, "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool (incl at least %lu from extra pool) and %lu txn requested\n", hash.ToString(), prefilled_count, mempool_count, extra_count, vtx_missing.size()); diff --git a/src/blockencodings.h b/src/blockencodings.h index c92aa05e805..b1f82d18c5d 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -141,15 +141,16 @@ class PartiallyDownloadedBlock { CBlockHeader header; // Can be overridden for testing - using CheckBlockFn = std::function; - CheckBlockFn m_check_block_mock{nullptr}; + using IsBlockMutatedFn = std::function; + IsBlockMutatedFn m_check_block_mutated_mock{nullptr}; explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {} // extra_txn is a list of extra orphan/conflicted/etc transactions to look at ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector& extra_txn); bool IsTxAvailable(size_t index) const; - ReadStatus FillBlock(CBlock& block, const std::vector& vtx_missing); + // segwit_active enforces witness mutation checks just before reporting a healthy status + ReadStatus FillBlock(CBlock& block, const std::vector& vtx_missing, bool segwit_active); }; #endif // BITCOIN_BLOCKENCODINGS_H diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 1da3ec9d211..0f1d6d98aa4 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3314,7 +3314,11 @@ void PeerManagerImpl::ProcessCompactBlockTxns(CNode& pfrom, Peer& peer, const Bl } PartiallyDownloadedBlock& partialBlock = *range_flight.first->second.second->partialBlock; - ReadStatus status = partialBlock.FillBlock(*pblock, block_transactions.txn); + + // We should not have gotten this far in compact block processing unless it's attached to a known header + const CBlockIndex* prev_block{Assume(m_chainman.m_blockman.LookupBlockIndex(partialBlock.header.hashPrevBlock))}; + ReadStatus status = partialBlock.FillBlock(*pblock, block_transactions.txn, + /*segwit_active=*/DeploymentActiveAfter(prev_block, m_chainman, Consensus::DEPLOYMENT_SEGWIT)); if (status == READ_STATUS_INVALID) { RemoveBlockRequest(block_transactions.blockhash, pfrom.GetId()); // Reset in-flight state in case Misbehaving does not result in a disconnect Misbehaving(peer, "invalid compact block/non-matching block transactions"); @@ -4462,7 +4466,9 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, return; } std::vector dummy; - status = tempBlock.FillBlock(*pblock, dummy); + const CBlockIndex* prev_block{Assume(m_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.hashPrevBlock))}; + status = tempBlock.FillBlock(*pblock, dummy, + /*segwit_active=*/DeploymentActiveAfter(prev_block, m_chainman, Consensus::DEPLOYMENT_SEGWIT)); if (status == READ_STATUS_OK) { fBlockReconstructed = true; } diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index ed95a8831e3..d40a0a94aef 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -95,21 +95,21 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest) CBlock block2; { PartiallyDownloadedBlock tmp = partialBlock; - BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_INVALID); // No transactions + BOOST_CHECK(partialBlock.FillBlock(block2, {}, /*segwit_active=*/true) == READ_STATUS_INVALID); // No transactions partialBlock = tmp; } // Wrong transaction { PartiallyDownloadedBlock tmp = partialBlock; - partialBlock.FillBlock(block2, {block.vtx[2]}); // Current implementation doesn't check txn here, but don't require that + partialBlock.FillBlock(block2, {block.vtx[2]}, /*segwit_active=*/true); // Current implementation doesn't check txn here, but don't require that partialBlock = tmp; } bool mutated; BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated)); CBlock block3; - BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[1]}) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[1]}, /*segwit_active=*/true) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString()); BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString()); BOOST_CHECK(!mutated); @@ -182,14 +182,14 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) CBlock block2; { PartiallyDownloadedBlock tmp = partialBlock; - BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_INVALID); // No transactions + BOOST_CHECK(partialBlock.FillBlock(block2, {}, /*segwit_active=*/true) == READ_STATUS_INVALID); // No transactions partialBlock = tmp; } // Wrong transaction { PartiallyDownloadedBlock tmp = partialBlock; - partialBlock.FillBlock(block2, {block.vtx[1]}); // Current implementation doesn't check txn here, but don't require that + partialBlock.FillBlock(block2, {block.vtx[1]}, /*segwit_active=*/true); // Current implementation doesn't check txn here, but don't require that partialBlock = tmp; } BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 2); // +2 because of partialBlock and block2 @@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) CBlock block3; PartiallyDownloadedBlock partialBlockCopy = partialBlock; - BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[0]}) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[0]}, /*segwit_active=*/true) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString()); BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString()); BOOST_CHECK(!mutated); @@ -252,7 +252,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest) CBlock block2; PartiallyDownloadedBlock partialBlockCopy = partialBlock; - BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.FillBlock(block2, {}, /*segwit_active=*/true) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString()); bool mutated; BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString()); @@ -300,7 +300,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest) CBlock block2; std::vector vtx_missing; - BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing, /*segwit_active=*/true) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString()); BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString()); BOOST_CHECK(!mutated); diff --git a/src/test/fuzz/partially_downloaded_block.cpp b/src/test/fuzz/partially_downloaded_block.cpp index 82d781cd53c..1a06ef8b0af 100644 --- a/src/test/fuzz/partially_downloaded_block.cpp +++ b/src/test/fuzz/partially_downloaded_block.cpp @@ -32,14 +32,10 @@ void initialize_pdb() g_setup = testing_setup.get(); } -PartiallyDownloadedBlock::CheckBlockFn FuzzedCheckBlock(std::optional result) +PartiallyDownloadedBlock::IsBlockMutatedFn FuzzedIsBlockMutated(bool result) { - return [result](const CBlock&, BlockValidationState& state, const Consensus::Params&, bool, bool) { - if (result) { - return state.Invalid(*result); - } - - return true; + return [result](const CBlock& block, bool) { + return result; }; } @@ -111,36 +107,23 @@ FUZZ_TARGET(partially_downloaded_block, .init = initialize_pdb) skipped_missing |= (!pdb.IsTxAvailable(i) && skip); } - // Mock CheckBlock - bool fail_check_block{fuzzed_data_provider.ConsumeBool()}; - auto validation_result = - fuzzed_data_provider.PickValueInArray( - {BlockValidationResult::BLOCK_RESULT_UNSET, - BlockValidationResult::BLOCK_CONSENSUS, - BlockValidationResult::BLOCK_CACHED_INVALID, - BlockValidationResult::BLOCK_INVALID_HEADER, - BlockValidationResult::BLOCK_MUTATED, - BlockValidationResult::BLOCK_MISSING_PREV, - BlockValidationResult::BLOCK_INVALID_PREV, - BlockValidationResult::BLOCK_TIME_FUTURE, - BlockValidationResult::BLOCK_CHECKPOINT, - BlockValidationResult::BLOCK_HEADER_LOW_WORK}); - pdb.m_check_block_mock = FuzzedCheckBlock( - fail_check_block ? - std::optional{validation_result} : - std::nullopt); + bool segwit_active{fuzzed_data_provider.ConsumeBool()}; + + // Mock IsBlockMutated + bool fail_block_mutated{fuzzed_data_provider.ConsumeBool()}; + pdb.m_check_block_mutated_mock = FuzzedIsBlockMutated(fail_block_mutated); CBlock reconstructed_block; - auto fill_status{pdb.FillBlock(reconstructed_block, missing)}; + auto fill_status{pdb.FillBlock(reconstructed_block, missing, segwit_active)}; switch (fill_status) { case READ_STATUS_OK: assert(!skipped_missing); - assert(!fail_check_block); + assert(!fail_block_mutated); assert(block->GetHash() == reconstructed_block.GetHash()); break; case READ_STATUS_CHECKBLOCK_FAILED: [[fallthrough]]; case READ_STATUS_FAILED: - assert(fail_check_block); + assert(fail_block_mutated); break; case READ_STATUS_INVALID: break; From 4c940d47897bc380d3387dd6663c37c46b4020ec Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Tue, 3 Jun 2025 10:29:00 -0400 Subject: [PATCH 163/314] p2p: remove vestigial READ_STATUS_CHECKBLOCK_FAILED Github-Pull: #32646 Rebased-From: 28299ce77636d7563ec545d043cf1b61bd2f01c1 --- src/blockencodings.h | 2 -- src/net_processing.cpp | 18 +----------------- src/test/fuzz/partially_downloaded_block.cpp | 1 - 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/src/blockencodings.h b/src/blockencodings.h index b1f82d18c5d..fce59bc5614 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -84,8 +84,6 @@ typedef enum ReadStatus_t READ_STATUS_OK, READ_STATUS_INVALID, // Invalid object, peer is sending bogus crap READ_STATUS_FAILED, // Failed to process object - READ_STATUS_CHECKBLOCK_FAILED, // Used only by FillBlock to indicate a - // failure in CheckBlock. } ReadStatus; class CBlockHeaderAndShortTxIDs { diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 0f1d6d98aa4..fa27ceb38ac 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3335,23 +3335,7 @@ void PeerManagerImpl::ProcessCompactBlockTxns(CNode& pfrom, Peer& peer, const Bl return; } } else { - // Block is either okay, or possibly we received - // READ_STATUS_CHECKBLOCK_FAILED. - // Note that CheckBlock can only fail for one of a few reasons: - // 1. bad-proof-of-work (impossible here, because we've already - // accepted the header) - // 2. merkleroot doesn't match the transactions given (already - // caught in FillBlock with READ_STATUS_FAILED, so - // impossible here) - // 3. the block is otherwise invalid (eg invalid coinbase, - // block is too big, too many legacy sigops, etc). - // So if CheckBlock failed, #3 is the only possibility. - // Under BIP 152, we don't discourage the peer unless proof of work is - // invalid (we don't require all the stateless checks to have - // been run). This is handled below, so just treat this as - // though the block was successfully read, and rely on the - // handling in ProcessNewBlock to ensure the block index is - // updated, etc. + // Block is okay for further processing RemoveBlockRequest(block_transactions.blockhash, pfrom.GetId()); // it is now an empty pointer fBlockRead = true; // mapBlockSource is used for potentially punishing peers and diff --git a/src/test/fuzz/partially_downloaded_block.cpp b/src/test/fuzz/partially_downloaded_block.cpp index 1a06ef8b0af..c9635cae8cd 100644 --- a/src/test/fuzz/partially_downloaded_block.cpp +++ b/src/test/fuzz/partially_downloaded_block.cpp @@ -121,7 +121,6 @@ FUZZ_TARGET(partially_downloaded_block, .init = initialize_pdb) assert(!fail_block_mutated); assert(block->GetHash() == reconstructed_block.GetHash()); break; - case READ_STATUS_CHECKBLOCK_FAILED: [[fallthrough]]; case READ_STATUS_FAILED: assert(fail_block_mutated); break; From 569ceb0df46fc619eed33f56b5b36f617c37bae7 Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Wed, 3 Sep 2025 12:44:23 -0400 Subject: [PATCH 164/314] net: check for empty header before calling FillBlock Previously in debug builds, this would cause an Assume crash if FillBlock had been called previously. This could happen when multiple blocktxn messages were received. Co-Authored-By: Greg Sanders Github-Pull: #33296 Rebased-From: 5e585a0fc4fd68dd7b4982054b34deae2e7aeb89 --- src/net_processing.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index fa27ceb38ac..d9c2163c1d2 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3315,6 +3315,16 @@ void PeerManagerImpl::ProcessCompactBlockTxns(CNode& pfrom, Peer& peer, const Bl PartiallyDownloadedBlock& partialBlock = *range_flight.first->second.second->partialBlock; + if (partialBlock.header.IsNull()) { + // It is possible for the header to be empty if a previous call to FillBlock wiped the header, but left + // the PartiallyDownloadedBlock pointer around (i.e. did not call RemoveBlockRequest). In this case, we + // should not call LookupBlockIndex below. + RemoveBlockRequest(block_transactions.blockhash, pfrom.GetId()); + Misbehaving(peer, "previous compact block reconstruction attempt failed"); + LogDebug(BCLog::NET, "Peer %d sent compact block transactions multiple times", pfrom.GetId()); + return; + } + // We should not have gotten this far in compact block processing unless it's attached to a known header const CBlockIndex* prev_block{Assume(m_chainman.m_blockman.LookupBlockIndex(partialBlock.header.hashPrevBlock))}; ReadStatus status = partialBlock.FillBlock(*pblock, block_transactions.txn, @@ -3326,6 +3336,9 @@ void PeerManagerImpl::ProcessCompactBlockTxns(CNode& pfrom, Peer& peer, const Bl } else if (status == READ_STATUS_FAILED) { if (first_in_flight) { // Might have collided, fall back to getdata now :( + // We keep the failed partialBlock to disallow processing another compact block announcement from the same + // peer for the same block. We let the full block download below continue under the same m_downloading_since + // timer. std::vector invs; invs.emplace_back(MSG_BLOCK | GetFetchFlags(peer), block_transactions.blockhash); MakeAndPushMessage(pfrom, NetMsgType::GETDATA, invs); From 1288d44804cd6ecd8601d0aef55e6fbf500d2f31 Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Wed, 3 Sep 2025 12:44:52 -0400 Subject: [PATCH 165/314] test: send duplicate blocktxn message in p2p_compactblocks.py Add test_multiple_blocktxn_response that checks that the peer is disconnected. Github-Pull: #33296 Rebased-From: 8b6264768030db1840041abeeaeefd6c227a2644 --- test/functional/p2p_compactblocks.py | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py index ca36b2fbc06..da8a0aed9ac 100755 --- a/test/functional/p2p_compactblocks.py +++ b/test/functional/p2p_compactblocks.py @@ -566,6 +566,42 @@ def test_incorrect_blocktxn_response(self, test_node): test_node.send_and_ping(msg_block(block)) assert_equal(int(node.getbestblockhash(), 16), block.sha256) + # Multiple blocktxn responses will cause a node to get disconnected. + def test_multiple_blocktxn_response(self, test_node): + node = self.nodes[0] + utxo = self.utxos[0] + + block = self.build_block_with_transactions(node, utxo, 2) + + # Send compact block + comp_block = HeaderAndShortIDs() + comp_block.initialize_from_block(block, prefill_list=[0], use_witness=True) + test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + absolute_indexes = [] + with p2p_lock: + assert "getblocktxn" in test_node.last_message + absolute_indexes = test_node.last_message["getblocktxn"].block_txn_request.to_absolute() + assert_equal(absolute_indexes, [1, 2]) + + # Send a blocktxn that does not succeed in reconstruction, triggering + # getdata fallback. + msg = msg_blocktxn() + msg.block_transactions = BlockTransactions(block.sha256, [block.vtx[2]] + [block.vtx[1]]) + test_node.send_and_ping(msg) + + # Tip should not have updated + assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) + + # We should receive a getdata request + test_node.wait_for_getdata([block.sha256], timeout=10) + assert test_node.last_message["getdata"].inv[0].type == MSG_BLOCK or \ + test_node.last_message["getdata"].inv[0].type == MSG_BLOCK | MSG_WITNESS_FLAG + + # Send the same blocktxn and assert the sender gets disconnected. + with node.assert_debug_log(['previous compact block reconstruction attempt failed']): + test_node.send_message(msg) + test_node.wait_for_disconnect() + def test_getblocktxn_handler(self, test_node): node = self.nodes[0] # bitcoind will not send blocktxn responses for blocks whose height is @@ -957,6 +993,12 @@ def run_test(self): self.log.info("Testing handling of invalid compact blocks...") self.test_invalid_tx_in_compactblock(self.segwit_node) + self.log.info("Testing handling of multiple blocktxn responses...") + self.test_multiple_blocktxn_response(self.segwit_node) + + # The previous test will lead to a disconnection. Reconnect before continuing. + self.segwit_node = self.nodes[0].add_p2p_connection(TestP2PConn()) + self.log.info("Testing invalid index in cmpctblock message...") self.test_invalid_cmpctblock_message() From 61cdc04a832cc5dfe98c48f8592c4de513258304 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Fri, 12 Sep 2025 17:29:04 -0400 Subject: [PATCH 166/314] net: Do not apply whitelist permission to onion inbounds Tor inbound connections do not reveal the peer's actual network address. Therefore do not apply whitelist permissions to them. Co-authored-by: Vasil Dimov Github-Pull: #33395 Rebased-From: f563ce90818d486d2a199439d2f6ba39cd106352 --- src/net.cpp | 11 +++++++---- src/net.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 735985a8414..7684877ec35 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -575,9 +575,9 @@ void CNode::CloseSocketDisconnect() m_i2p_sam_session.reset(); } -void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr, const std::vector& ranges) const { +void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, std::optional addr, const std::vector& 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); } } @@ -1767,7 +1767,11 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr&& 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{} : addr, vWhitelistedRangeIncoming); { LOCK(m_nodes_mutex); @@ -1822,7 +1826,6 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr&& 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(); diff --git a/src/net.h b/src/net.h index e64d9a67f46..e025b20bcde 100644 --- a/src/net.h +++ b/src/net.h @@ -1364,7 +1364,7 @@ class CConnman 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& ranges) const; + void AddWhitelistPermissionFlags(NetPermissionFlags& flags, std::optional addr, const std::vector& ranges) const; void DeleteNode(CNode* pnode); From 9bc4afb62cf04a41b62fe279f0db3d87e700cb3d Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 9 Sep 2025 10:15:08 +0100 Subject: [PATCH 167/314] doc: update release notes for 29.x --- doc/release-notes.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index b73e52dc570..0325d3a3e28 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.x is now available from: +Bitcoin Core version 29.2rc1 is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. @@ -37,19 +37,37 @@ unsupported systems. Notable changes =============== +### P2P + +- #32646 p2p: Add witness mutation check inside FillBlock +- #33296 net: check for empty header before calling FillBlock +- #33395 net: do not apply whitelist permissions to onion inbounds + ### CI - #32999 ci: Use APT_LLVM_V in msan task - #33099 ci: allow for any libc++ intrumentation & use it for TSAN - #33258 ci: use LLVM 21 +- #33364 ci: always use tag for LLVM checkout + +### Misc + +- #33310 trace: Workaround GCC bug compiling with old systemtap +- #33340 Fix benchmark CSV output Credits ======= Thanks to everyone who directly contributed to this release: +- Eugene Siegel - fanquake +- Greg Sanders +- Hennadii Stepanov +- Luke Dashjr - MarcoFalke +- Martin Zumsande +- Vasil Dimov As well as to everyone that helped with translations on [Transifex](https://explore.transifex.com/bitcoin/bitcoin/). From 461dd13fafa6f8175e2be4d96e8728e667ba4d69 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 17 Sep 2025 15:47:34 +0100 Subject: [PATCH 168/314] build: bump version to v29.2rc1 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc613a7655f..05a86a1d97f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,9 +28,9 @@ get_directory_property(precious_variables CACHE_VARIABLES) #============================= set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) -set(CLIENT_VERSION_MINOR 1) +set(CLIENT_VERSION_MINOR 2) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 0) +set(CLIENT_VERSION_RC 1) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From f2bd79f80c74a2b77f14954ac65679417697a332 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 17 Sep 2025 15:54:29 +0100 Subject: [PATCH 169/314] doc: update manual pages for v29.2rc1 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 428ddd3e2a2..a8dc092a6cc 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "September 2025" "bitcoin-cli v29.1.0" "User Commands" +.TH BITCOIN-CLI "1" "September 2025" "bitcoin-cli v29.2.0rc1" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.1.0 +bitcoin-cli \- manual page for bitcoin-cli v29.2.0rc1 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.1.0 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.1.0 +Bitcoin Core RPC client version v29.2.0rc1 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 3665a6a48ae..7821b8fb440 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "September 2025" "bitcoin-qt v29.1.0" "User Commands" +.TH BITCOIN-QT "1" "September 2025" "bitcoin-qt v29.2.0rc1" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.1.0 +bitcoin-qt \- manual page for bitcoin-qt v29.2.0rc1 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.1.0 +Bitcoin Core version v29.2.0rc1 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 16058f1bf94..a14a6be6024 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "September 2025" "bitcoin-tx v29.1.0" "User Commands" +.TH BITCOIN-TX "1" "September 2025" "bitcoin-tx v29.2.0rc1" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.1.0 +bitcoin-tx \- manual page for bitcoin-tx v29.2.0rc1 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.1.0 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.1.0 +Bitcoin Core bitcoin\-tx utility version v29.2.0rc1 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index a103bf40a5b..e0cc27e2d77 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "September 2025" "bitcoin-util v29.1.0" "User Commands" +.TH BITCOIN-UTIL "1" "September 2025" "bitcoin-util v29.2.0rc1" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.1.0 +bitcoin-util \- manual page for bitcoin-util v29.2.0rc1 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.1.0 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.1.0 +Bitcoin Core bitcoin\-util utility version v29.2.0rc1 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index b63494dc479..58bbf2715b3 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "September 2025" "bitcoin-wallet v29.1.0" "User Commands" +.TH BITCOIN-WALLET "1" "September 2025" "bitcoin-wallet v29.2.0rc1" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.1.0 +bitcoin-wallet \- manual page for bitcoin-wallet v29.2.0rc1 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.1.0 +Bitcoin Core bitcoin\-wallet utility version v29.2.0rc1 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index b8ee6bab52a..0846f3e0619 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "September 2025" "bitcoind v29.1.0" "User Commands" +.TH BITCOIND "1" "September 2025" "bitcoind v29.2.0rc1" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.1.0 +bitcoind \- manual page for bitcoind v29.2.0rc1 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.1.0 +Bitcoin Core daemon version v29.2.0rc1 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From f63b8e960d5d06cdbbc360aaf781c13fd5aca172 Mon Sep 17 00:00:00 2001 From: will Date: Sat, 26 Jul 2025 09:41:10 +0100 Subject: [PATCH 170/314] ci: add configure environment action Github-Pull: #32989 Rebased-From: b8fcc9fcbcd --- .../actions/configure-environment/action.yml | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/actions/configure-environment/action.yml diff --git a/.github/actions/configure-environment/action.yml b/.github/actions/configure-environment/action.yml new file mode 100644 index 00000000000..aae5016bdce --- /dev/null +++ b/.github/actions/configure-environment/action.yml @@ -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" From 301aa5d814b620287b65d93399a20a794659cc79 Mon Sep 17 00:00:00 2001 From: will Date: Mon, 16 Jun 2025 20:02:20 +0100 Subject: [PATCH 171/314] ci: add caching actions Github-Pull: #32989 Rebased-From: b232b0fa5e9 Add "Restore" and "Save" caching actions. These actions reduce boilerplate in the main ci.yml configuration file. These actions are implemented so that caches will be saved on `push` only. When a pull request is opened it will cache hit on the caches from the lastest push, or in the case of depends will hit on any matching depends hash, falling back to partial matches. Depends caches are hashed using `$(git ls-tree HEAD depends "ci/test/$FILE_ENV" | sha256sum | cut -d' ' -f1)` and this hash is passed in as an input to the actions. This means we direct cache hit in cases where depends would not be re-built, otherwise falling back to a partial match. Previous releases cache is hashed similarly to depends, but using the test/get_previous_releases.py file. The cirruslabs cache action will fallback transparently to GitHub's cache in the case that the job is not being run on a Cirrus Runner, making these compatible with running on forks (on free GH hardware). --- .github/actions/restore-caches/action.yml | 47 +++++++++++++++++++++++ .github/actions/save-caches/action.yml | 39 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 .github/actions/restore-caches/action.yml create mode 100644 .github/actions/save-caches/action.yml diff --git a/.github/actions/restore-caches/action.yml b/.github/actions/restore-caches/action.yml new file mode 100644 index 00000000000..8dc35d4902e --- /dev/null +++ b/.github/actions/restore-caches/action.yml @@ -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 diff --git a/.github/actions/save-caches/action.yml b/.github/actions/save-caches/action.yml new file mode 100644 index 00000000000..0e3b31246c6 --- /dev/null +++ b/.github/actions/save-caches/action.yml @@ -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 }} From 954c1a55e4a6322267071f5bffeb3188a6ac7d59 Mon Sep 17 00:00:00 2001 From: will Date: Mon, 28 Jul 2025 16:05:32 +0100 Subject: [PATCH 172/314] ci: add REPO_USE_CIRRUS_RUNNERS Github-Pull: #32989 Rebased-From: 33ba073df7a If set, Cirrus runners will be used on pushes to, and pull requests against, this repository. Forks can set this if they have their own cirrus runners. --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2cac4eab0b3..3ce17dff3e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,7 @@ 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' + REPO_USE_CIRRUS_RUNNERS: 'bitcoin/bitcoin' # Use cirrus runners and cache for this repo, instead of falling back to the slow GHA runners jobs: test-each-commit: From 1faf918a169b76e69a486eb7fc8d88429b77b4b6 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:37:26 +0100 Subject: [PATCH 173/314] ci: add configure-docker action Github-Pull: #32989 Rebased-From: fdf64e55324 Another action to reduce boilerplate in the main ci.yml file. This action will set up a docker builder compatible with caching build layers to a container registry using the `gha` build driver. It will then configure the docker build cache args. --- .github/actions/configure-docker/action.yml | 52 +++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/actions/configure-docker/action.yml diff --git a/.github/actions/configure-docker/action.yml b/.github/actions/configure-docker/action.yml new file mode 100644 index 00000000000..c78df86b6cf --- /dev/null +++ b/.github/actions/configure-docker/action.yml @@ -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 From f3089fb2cfdba533fba1298e909628e5fe7dabb9 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 174/314] ci: use buildx in ci Github-Pull: #32989 Rebased-From: 94a09325475 Using buildx is required to properly load the correct driver, for use with registry caching. Neither build, nor BUILDKIT=1 currently do this properly. Use of `docker buildx build` is compatible with podman. --- ci/test/02_run_container.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ci/test/02_run_container.sh b/ci/test/02_run_container.sh index 8351fd4e02a..087b4c67809 100755 --- a/ci/test/02_run_container.sh +++ b/ci/test/02_run_container.sh @@ -46,8 +46,10 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then DOCKER_BUILD_CACHE_ARG="--cache-from type=local,src=${DOCKER_BUILD_CACHE_OLD_DIR} --cache-to type=local,dest=${DOCKER_BUILD_CACHE_NEW_DIR},mode=max" fi + # 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_BUILDKIT=1 docker build \ + 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}" \ From 0a649d07c994b1a6957131c8bb3a1d2e8d53e559 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 175/314] ci: use docker build cache arg directly Github-Pull: #32989 Rebased-From: 18f6be09d02 Reverts: e87429a2d0f23eb59526d335844fa5ff5b50b21f This was added in PR #31545 with the intention that self-hosted runners might use it to save build cache. As we are not using hosted runners with a registry build cache, the bulk of this commit can be reverted, simply using the value of $DOCKER_BUILD_CACHE_ARG in the script. link: https://github.com/bitcoin/bitcoin/pull/31545 --- ci/test/02_run_container.sh | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/ci/test/02_run_container.sh b/ci/test/02_run_container.sh index 087b4c67809..2031dbd85a5 100755 --- a/ci/test/02_run_container.sh +++ b/ci/test/02_run_container.sh @@ -23,29 +23,6 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then fi echo "Creating $CI_IMAGE_NAME_TAG container to run in" - DOCKER_BUILD_CACHE_ARG="" - DOCKER_BUILD_CACHE_TEMPDIR="" - DOCKER_BUILD_CACHE_OLD_DIR="" - DOCKER_BUILD_CACHE_NEW_DIR="" - # If set, use an `docker build` cache directory on the CI host - # to cache docker image layers for the CI container image. - # This cache can be multiple GB in size. Prefixed with DANGER - # as setting it removes (old cache) files from the host. - if [ "$DANGER_DOCKER_BUILD_CACHE_HOST_DIR" ]; then - # Directory where the current cache for this run could be. If not existing - # or empty, "docker build" will warn, but treat it as cache-miss and continue. - DOCKER_BUILD_CACHE_OLD_DIR="${DANGER_DOCKER_BUILD_CACHE_HOST_DIR}/${CONTAINER_NAME}" - # Temporary directory for a newly created cache. We can't write the new - # cache into OLD_DIR directly, as old cache layers would not be removed. - # The NEW_DIR contents are moved to OLD_DIR after OLD_DIR has been cleared. - # This happens after `docker build`. If a task fails or is aborted, the - # DOCKER_BUILD_CACHE_TEMPDIR might be retained on the host. If the host isn't - # ephemeral, it has to take care of cleaning old TEMPDIR's up. - DOCKER_BUILD_CACHE_TEMPDIR="$(mktemp --directory ci-docker-build-cache-XXXXXXXXXX)" - DOCKER_BUILD_CACHE_NEW_DIR="${DOCKER_BUILD_CACHE_TEMPDIR}/${CONTAINER_NAME}" - DOCKER_BUILD_CACHE_ARG="--cache-from type=local,src=${DOCKER_BUILD_CACHE_OLD_DIR} --cache-to type=local,dest=${DOCKER_BUILD_CACHE_NEW_DIR},mode=max" - fi - # 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 @@ -60,15 +37,6 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then $DOCKER_BUILD_CACHE_ARG \ "${BASE_READ_ONLY_DIR}" - if [ "$DANGER_DOCKER_BUILD_CACHE_HOST_DIR" ]; then - if [ -e "${DOCKER_BUILD_CACHE_NEW_DIR}/index.json" ]; then - echo "Removing the existing docker build cache in ${DOCKER_BUILD_CACHE_OLD_DIR}" - rm -rf "${DOCKER_BUILD_CACHE_OLD_DIR}" - echo "Moving the contents of ${DOCKER_BUILD_CACHE_NEW_DIR} to ${DOCKER_BUILD_CACHE_OLD_DIR}" - mv "${DOCKER_BUILD_CACHE_NEW_DIR}" "${DOCKER_BUILD_CACHE_OLD_DIR}" - fi - fi - docker volume create "${CONTAINER_NAME}_ccache" || true docker volume create "${CONTAINER_NAME}_depends" || true docker volume create "${CONTAINER_NAME}_depends_sources" || true From af086431e86c82a5e40b05270f39c70cfe413c7b Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 176/314] ci: have base install run in right dir Github-Pull: #32989 Rebased-From: 9c2b96e0d03 This sets the build dir at build time so that Apple SDK gets installed in the correct/expected location for the runtime to find it. Co-authored-by: Max Edwards --- ci/test/02_run_container.sh | 1 + ci/test_imagefile | 3 +++ 2 files changed, 4 insertions(+) diff --git a/ci/test/02_run_container.sh b/ci/test/02_run_container.sh index 2031dbd85a5..131b3c61481 100755 --- a/ci/test/02_run_container.sh +++ b/ci/test/02_run_container.sh @@ -30,6 +30,7 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then --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}" \ $MAYBE_CPUSET \ --platform="${CI_IMAGE_PLATFORM}" \ --label="${CI_IMAGE_LABEL}" \ diff --git a/ci/test_imagefile b/ci/test_imagefile index f8b5eea1c88..224141b138f 100644 --- a/ci/test_imagefile +++ b/ci/test_imagefile @@ -10,6 +10,9 @@ 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/ From f9f3e8b68616dfb9e18082d191b87a457c4100da Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 177/314] ci: add Cirrus cache host Github-Pull: #32989 Rebased-From: 020069e6b71 Whilst the action cirruslabs/actions/cache will automatically set this host, the docker `gha` build cache backend will not be aware of it. Set the value here, which will later be used in the docker build args to enable docker build cache on the cirrus cache. --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ce17dff3e5..cf4c02e1d7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,7 @@ 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 + 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. MAKEJOBS: '-j10' REPO_USE_CIRRUS_RUNNERS: 'bitcoin/bitcoin' # Use cirrus runners and cache for this repo, instead of falling back to the slow GHA runners From 849993377d76c64cc5ea14336e6523434608deb3 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 178/314] ci: add job to determine runner type Github-Pull: #32989 Rebased-From: cc1735d7771 To remove multiple occurances of the respository name, against which we compare `${{ github.repository }}` to check if we should use Cirrus Runners, introduce a helper job which can check a single environment variable and output this as an input to subsequent jobs. Forks can maintain a trivial patch of their repo name against the `REPO_USE_CIRRUS_RUNNERS` variable in ci.yml if they have Cirrus Runners of their own, which will then enable cache actions and docker build cache to use Cirrus Cache. It's not possible to use `${{ env.USE_CIRRUS_RUNNERS }}` in the `runs-on:` directive as the context is not supported by GitHub. If it was, this job would no longer be necessary. --- .github/workflows/ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf4c02e1d7e..4bd496d7a84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,22 @@ env: 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 From 82c60a31515a2004976faaa26f8caad9e2bb022d Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 179/314] ci: port arm 32-bit job Github-Pull: #32989 Rebased-From: f253031cb8e Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4bd496d7a84..297f8c0eec5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -324,3 +324,46 @@ jobs: 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 }} + + 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: + DANGER_CI_ON_HOST_FOLDERS: 1 + FILE_ENV: ${{ matrix.file-env }} + + strategy: + fail-fast: false + matrix: + include: + - 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 + fallback-runner: 'ubuntu-24.04-arm' + timeout-minutes: 120 + file-env: './ci/test/00_setup_env_arm.sh' + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Configure environment + uses: ./.github/actions/configure-environment + + - name: Restore caches + id: restore-cache + uses: ./.github/actions/restore-caches + + - name: Configure Docker + uses: ./.github/actions/configure-docker + with: + use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }} + + - name: CI script + run: ./ci/test_run_all.sh + + - name: Save caches + uses: ./.github/actions/save-caches From 894a3cbe42bf900788b858faf59b3d97412e7d47 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 180/314] ci: update windows-cross job Github-Pull: #32989 Rebased-From: 04e7bfbceb0 Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 297f8c0eec5..d88bb462e3c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -346,6 +346,11 @@ jobs: timeout-minutes: 120 file-env: './ci/test/00_setup_env_arm.sh' + - name: 'win64 Cross' + 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_win64.sh' steps: - name: Checkout uses: actions/checkout@v5 From 819ee09af31687dedd38de68aef98b0ecc19608f Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 181/314] ci: update asan-lsan-ubsan Github-Pull: #32989 Rebased-From: 884251441bb Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 55 ++++++++++------------------------------ 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d88bb462e3c..0dab0e8a5f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -283,48 +283,6 @@ jobs: run: | py -3 test\fuzz\test_runner.py --par %NUMBER_OF_PROCESSORS% --loglevel DEBUG %RUNNER_TEMP%\qa-assets\fuzz_corpora - 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 - if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} - timeout-minutes: 120 - env: - FILE_ENV: "./ci/test/00_setup_env_native_asan.sh" - DANGER_CI_ON_HOST_FOLDERS: 1 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set CI directories - run: | - echo "CCACHE_DIR=${{ runner.temp }}/ccache_dir" >> "$GITHUB_ENV" - echo "BASE_ROOT_DIR=${{ runner.temp }}" >> "$GITHUB_ENV" - echo "BASE_BUILD_DIR=${{ runner.temp }}/build-asan" >> "$GITHUB_ENV" - - - name: Restore Ccache cache - id: ccache-cache - uses: actions/cache/restore@v4 - with: - path: ${{ env.CCACHE_DIR }} - key: ${{ github.job }}-ccache-${{ github.run_id }} - restore-keys: ${{ github.job }}-ccache- - - - name: Enable bpfcc script - # 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: 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' - 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 }} - ci-matrix: name: ${{ matrix.name }} needs: runners @@ -351,6 +309,13 @@ jobs: 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-lg' # 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' + steps: - name: Checkout uses: actions/checkout@v5 @@ -367,6 +332,12 @@ jobs: with: 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: CI script run: ./ci/test_run_all.sh From a91567a980adb93a05f12ec63b628ee3faaa4681 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 182/314] ci: force reinstall of kernel headers in asan Github-Pull: #32989 Rebased-From: 2c990d84a3d When using hosted runners in combination with cached docker images, there is the possibility that the host runner image is updated, rendering the linux-headers package (stored in the cached docker image) incompatible. Fix this by doing a re-install of the headers package in 03_test_script.sh. If the underlying runner kernel has not changed thie has no effect, but prevents the job from failing if it has. --- ci/test/03_test_script.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ci/test/03_test_script.sh b/ci/test/03_test_script.sh index b218e7b9d1a..c2ef2291bd5 100755 --- a/ci/test/03_test_script.sh +++ b/ci/test/03_test_script.sh @@ -24,6 +24,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 From 835b5b8bb18a318026ada74d3c63b89d6aab742b Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 183/314] ci: port mac-cross-gui-notests Github-Pull: #32989 Rebased-From: 9c2514de534 Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0dab0e8a5f7..941ab095095 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -316,6 +316,12 @@ jobs: 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' + steps: - name: Checkout uses: actions/checkout@v5 From e826c3daa55d3b4cbd0e2c13765f9158eb225bfd Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 184/314] ci: port nowallet-libbitcoinkernel Github-Pull: #32989 Rebased-From: 2a00b12d73b Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 941ab095095..37556d42c97 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -322,6 +322,12 @@ jobs: 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-md' + fallback-runner: 'ubuntu-24.04' + timeout-minutes: 120 + file-env: './ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh' + steps: - name: Checkout uses: actions/checkout@v5 From 544f902b2a9cf14cd0445f27802cd11c5c945b00 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 185/314] ci: port i686-multiprocess-DEBUG Github-Pull: #32989 Rebased-From: f2068f26c12 Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37556d42c97..5b15fdb2652 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -328,6 +328,12 @@ jobs: 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' + steps: - name: Checkout uses: actions/checkout@v5 From 85ec6c6882b40adb35c9cb88d37d22e3e58eaa68 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 186/314] ci: port fuzzer-address-undefined-integer-nodepends Github-Pull: #32989 Rebased-From: 341196d75c3 Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b15fdb2652..1eabc0ec8a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -334,6 +334,12 @@ jobs: 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' + steps: - name: Checkout uses: actions/checkout@v5 From 5057b9a6ffd360dbd96ad8585e10852961392361 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 187/314] ci: port previous-releases-depends-debug Github-Pull: #32989 Rebased-From: 58e38c3a042 Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1eabc0ec8a9..ca8748fd80a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -340,6 +340,12 @@ jobs: 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' + steps: - name: Checkout uses: actions/checkout@v5 From b4286cf354a8111ed54fb63547dc1a7be7257b92 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 188/314] ci: port centos-depends-gui Github-Pull: #32989 Rebased-From: 549074bc643 Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca8748fd80a..69fe9f0f978 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -346,6 +346,12 @@ jobs: timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_previous_releases.sh' + - name: 'CentOS, depends, 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_native_centos.sh' + steps: - name: Checkout uses: actions/checkout@v5 From 3b2dcc8b9aea8706a25690a0cd08ba60896d3542 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 189/314] ci: port tidy Github-Pull: #32989 Rebased-From: bf7d5364527 Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69fe9f0f978..65903b40fd0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -352,6 +352,12 @@ jobs: timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_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' + steps: - name: Checkout uses: actions/checkout@v5 From 643385b22d9908f7665bf2addc734ba0323967b0 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 190/314] ci: port tsan-depends Github-Pull: #32989 Rebased-From: 9bbae61e3b4 Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65903b40fd0..95d5686f2f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -358,6 +358,12 @@ jobs: timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_tidy.sh' + - name: 'TSan, depends, no 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_native_tsan.sh' + steps: - name: Checkout uses: actions/checkout@v5 @@ -380,6 +386,11 @@ jobs: # 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' }} + # 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 From 0f0378fe3c590e835aa30be092f37109ddd63b86 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 191/314] ci: port msan-depends Github-Pull: #32989 Rebased-From: d290a8e6eab Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 95d5686f2f2..607d96f9663 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -364,6 +364,12 @@ jobs: 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@v5 @@ -387,7 +393,7 @@ jobs: 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' }} + 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 From 06424fb004f916b06e4f0ab90fd6f7623049a360 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 192/314] ci: port lint Github-Pull: #32989 Rebased-From: bc41848d00f Co-authored-by: Max Edwards --- .github/workflows/ci.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 607d96f9663..6d9f920e68b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -402,3 +402,32 @@ jobs: - 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-sm' || '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: + 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" From a08c3cc51c6875ba67f25c85143fdb61a8ba3e03 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 193/314] ci: remove .cirrus.yml Github-Pull: #32989 Rebased-From: 4393ffdd837 Removed as unused. --- .cirrus.yml | 214 ---------------------------------------------------- 1 file changed, 214 deletions(-) delete mode 100644 .cirrus.yml diff --git a/.cirrus.yml b/.cirrus.yml deleted file mode 100644 index 6e70dc15fec..00000000000 --- a/.cirrus.yml +++ /dev/null @@ -1,214 +0,0 @@ -env: # Global defaults - CIRRUS_CLONE_DEPTH: 1 - CIRRUS_LOG_TIMESTAMP: true - 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 - -# 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, with at least 2 vCPUs and 8 GB of memory. -# - medium: For an x86_64 machine, with at least 4 vCPUs and 16 GB of memory. -# - arm64: For an aarch64 machine, with at least 2 vCPUs 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: -# - 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 uidmap slirp4netns 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: - # Require git (used in fingerprint_script). - - git --version || ( apt-get update && apt-get install -y 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-cross' - << : *GLOBAL_TASK_TEMPLATE - persistent_worker: - labels: - type: small - env: - FILE_ENV: "./ci/test/00_setup_env_win64.sh" - -task: - name: 'CentOS, depends, gui' - << : *GLOBAL_TASK_TEMPLATE - persistent_worker: - labels: - type: small - env: - FILE_ENV: "./ci/test/00_setup_env_native_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, no 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 - timeout_in: 240m # larger timeout, due to the high CPU demand - 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" From c7f290b826fc4928c6e1e0a9649da85d4752717b Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 194/314] ci: dynamically match makejobs with cores Github-Pull: #32989 Rebased-From: 3f339e99e00 Previously jobs were running on a large multi-core server where 10 jobs as default made sense (or may even have been on the low side). Using hosted runners with fixed (and lower) numbers of vCPUs we should adapt compilation to match the number of cpus we have dynamically. This is cross-platform compatible with macos and linux only. --- .github/workflows/ci.yml | 1 - ci/test/00_setup_env.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d9f920e68b..60cb41b8f98 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,6 @@ 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 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. - MAKEJOBS: '-j10' REPO_USE_CIRRUS_RUNNERS: 'bitcoin/bitcoin' # Use cirrus runners and cache for this repo, instead of falling back to the slow GHA runners jobs: diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh index 9f794c25235..8a5cd4b2435 100755 --- a/ci/test/00_setup_env.sh +++ b/ci/test/00_setup_env.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} From 4339787379d2d246846e60f10ab9582805a6845e Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 195/314] doc: Detail configuration of hosted CI runners Github-Pull: #32989 Rebased-From: f4272844833dd660c2b9db587856baa408889302 --- ci/README.md | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/ci/README.md b/ci/README.md index 377aae7fa0b..81e048ce687 100644 --- a/ci/README.md +++ b/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*. From 773e4cda9446a03c0b23468ef8a9e38496b4566b Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 196/314] ci: add ccache hit-rate warning when < 75% Github-Pull: #32989 Rebased-From: dd1c5903e8d Print the ccache hit-rate for the job using a GitHub annotation if it was below 75%. --- ci/test/00_setup_env_mac_native.sh | 1 + ci/test/00_setup_env_mac_native_fuzz.sh | 1 + ci/test/03_test_script.sh | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/ci/test/00_setup_env_mac_native.sh b/ci/test/00_setup_env_mac_native.sh index e01a56895bf..9de51f93291 100755 --- a/ci/test/00_setup_env_mac_native.sh +++ b/ci/test/00_setup_env_mac_native.sh @@ -8,6 +8,7 @@ export LC_ALL=C.UTF-8 # 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 CMAKE_GENERATOR="Ninja" diff --git a/ci/test/00_setup_env_mac_native_fuzz.sh b/ci/test/00_setup_env_mac_native_fuzz.sh index cacf2423ac3..22b6bc97ab3 100755 --- a/ci/test/00_setup_env_mac_native_fuzz.sh +++ b/ci/test/00_setup_env_mac_native_fuzz.sh @@ -6,6 +6,7 @@ export LC_ALL=C.UTF-8 +export CONTAINER_NAME="ci_mac_native_fuzz" # macos does not use a container, but the env var is needed for logging export CMAKE_GENERATOR="Ninja" export BITCOIN_CONFIG="-DBUILD_FOR_FUZZING=ON" export CI_OS_NAME="macos" diff --git a/ci/test/03_test_script.sh b/ci/test/03_test_script.sh index c2ef2291bd5..36f8b9dfc2d 100755 --- a/ci/test/03_test_script.sh +++ b/ci/test/03_test_script.sh @@ -137,6 +137,12 @@ bash -c "cmake -S $BASE_ROOT_DIR $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( (cat $ bash -c "cmake --build . $MAKEJOBS --target all $GOAL" || ( echo "Build failure. Verbose build follows." && cmake --build . --target all "$GOAL" --verbose ; 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}" From 4e8b64b181e1bb7d82789699eaac24dc1242afa3 Mon Sep 17 00:00:00 2001 From: will Date: Tue, 5 Aug 2025 14:41:09 +0100 Subject: [PATCH 197/314] ci: fix annoying docker warning Github-Pull: #32989 Rebased-From: 2aa288efdda Docker currently warns that we are missing a default value. Set this to scratch which will error if an appropriate image tag is not passed in to silence the warning. --- ci/test_imagefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/test_imagefile b/ci/test_imagefile index 224141b138f..f9cf3187a25 100644 --- a/ci/test_imagefile +++ b/ci/test_imagefile @@ -4,7 +4,8 @@ # 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 From 6ded1fe11752372c52169d2aec7f0658bf9b0455 Mon Sep 17 00:00:00 2001 From: willcl-ark Date: Fri, 8 Aug 2025 10:31:56 +0200 Subject: [PATCH 198/314] ci: remove un-needed lint_run*.sh files Github-Pull: #32989 Rebased-From: 3c5da69a232 ci/lint_run_all.sh: Only used in .cirrus.yml. Refer to test/lint/README.md on how to run locally. --- ci/lint_run_all.sh | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100755 ci/lint_run_all.sh diff --git a/ci/lint_run_all.sh b/ci/lint_run_all.sh deleted file mode 100755 index c57261d21a6..00000000000 --- a/ci/lint_run_all.sh +++ /dev/null @@ -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 From 4a034cbeb42763c6b7a82089973c4a30cb0cd1c4 Mon Sep 17 00:00:00 2001 From: will Date: Thu, 4 Sep 2025 19:53:45 +0100 Subject: [PATCH 199/314] ci: reduce runner sizes on various jobs Github-Pull: #33319 Rebased-From: 5eeb2facbbbbf68a2c30ef9e6747e39c85d7b116 These jobs can use reduced runner size to avoid wasting CPU, as much of the long-running part of the job is single-threaded. Suggested in: https://github.com/bitcoin/bitcoin/pull/32989#discussion_r2321775620 Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60cb41b8f98..2b774b6afde 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -310,7 +310,7 @@ jobs: 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-lg' # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools + 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' @@ -322,7 +322,7 @@ jobs: file-env: './ci/test/00_setup_env_mac_cross.sh' - name: 'No wallet, libbitcoinkernel' - cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' + 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' @@ -358,7 +358,7 @@ jobs: file-env: './ci/test/00_setup_env_native_tidy.sh' - name: 'TSan, depends, no gui' - cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg' + 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' @@ -405,7 +405,7 @@ jobs: lint: name: 'lint' needs: runners - runs-on: ${{ needs.runners.outputs.use-cirrus-runners == 'true' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' || 'ubuntu-24.04' }} + 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: From 78d93effd03278b46e21ae8ef79f61f4ec32f855 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Thu, 4 Sep 2025 11:21:45 +0200 Subject: [PATCH 200/314] ci: Checkout latest merged pulls Github-Pull: #33303 Rebased-From: fa8f081af31 --- .github/workflows/ci.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b774b6afde..ae614d5bb29 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,8 +123,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: | @@ -192,8 +196,7 @@ jobs: job-name: 'Win64 native fuzz, VS 2022' steps: - - name: Checkout - uses: actions/checkout@v4 + - *CHECKOUT - name: Configure Developer Command Prompt for Microsoft Visual C++ # Using microsoft/setup-msbuild is not enough. @@ -370,8 +373,7 @@ jobs: file-env: './ci/test/00_setup_env_native_msan.sh' steps: - - name: Checkout - uses: actions/checkout@v5 + - *CHECKOUT - name: Configure environment uses: ./.github/actions/configure-environment @@ -414,6 +416,7 @@ jobs: - name: Checkout uses: actions/checkout@v5 with: + ref: *CHECKOUT_REF_TMPL fetch-depth: 0 - name: Configure Docker From 5750355139eb7fc2bd11124adf46bf053be6b690 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 1 Aug 2025 09:48:30 +0100 Subject: [PATCH 201/314] ci: link against -lstdc++ in native fuzz with msan job Github-Pull: #33425 Rebased-From: b77137a5644e09a08442aed7d8a4a9290fb53526 --- ci/test/00_setup_env_native_fuzz_with_msan.sh | 6 ++++-- ci/test/01_base_install.sh | 17 ----------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/ci/test/00_setup_env_native_fuzz_with_msan.sh b/ci/test/00_setup_env_native_fuzz_with_msan.sh index 27b704017c4..655fe609c0d 100755 --- a/ci/test/00_setup_env_native_fuzz_with_msan.sh +++ b/ci/test/00_setup_env_native_fuzz_with_msan.sh @@ -7,14 +7,16 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" +export APT_LLVM_V="21" LIBCXX_DIR="/cxx_build/" export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls" -LIBCXX_FLAGS="-nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" +# -lstdc++ to resolve link issues due to upstream packaging +LIBCXX_FLAGS="-nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument -lstdc++" export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}" export CONTAINER_NAME="ci_native_fuzz_msan" -export PACKAGES="ninja-build" # BDB generates false-positives and will be removed in future +export PACKAGES="ninja-build clang-${APT_LLVM_V} llvm-${APT_LLVM_V} llvm-${APT_LLVM_V}-dev libclang-${APT_LLVM_V}-dev libclang-rt-${APT_LLVM_V}-dev" export DEP_OPTS="DEBUG=1 NO_BDB=1 NO_QT=1 CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" export GOAL="all" # Setting CMAKE_{C,CXX}_FLAGS_DEBUG flags to an empty string ensures that the flags set in MSAN_FLAGS remain unaltered. diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index 1b624f38942..65f68351c89 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -57,23 +57,6 @@ fi if [[ -n "${USE_INSTRUMENTED_LIBCPP}" ]]; then ${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-21.1.1" /llvm-project - if [ -n "${APT_LLVM_V}" ]; then - - cmake -G Ninja -B /clang_build/ \ - -DLLVM_ENABLE_PROJECTS="clang" \ - -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_TARGETS_TO_BUILD=Native \ - -DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \ - -S /llvm-project/llvm - - ninja -C /clang_build/ "$MAKEJOBS" - ninja -C /clang_build/ install-runtimes - - update-alternatives --install /usr/bin/clang++ clang++ /clang_build/bin/clang++ 100 - update-alternatives --install /usr/bin/clang clang /clang_build/bin/clang 100 - update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer /clang_build/bin/llvm-symbolizer 100 - fi - cmake -G Ninja -B /cxx_build/ \ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ -DCMAKE_BUILD_TYPE=Release \ From 118abf4c305c01e6359a8588327a0b011ca52944 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Sat, 20 Sep 2025 21:32:41 +0200 Subject: [PATCH 202/314] test: add block 2016 to mock mainnet The next commit requires an additional mainnet block which changes the difficulty. Also fix a few minor mistakes in the test (suite): - rename the create_coinbase retarger_period argument to halving_period. Before bitcoin#31583 this was hardcoded for regtest where these values are the same. - drop unused fees argument from mine helper Finally the CPU miner instructions for generating the alternative mainnet chain are expanded. Github-Pull: #33446 Rebased-From: 4c3c1f42cf705e039751395799240da33ca969bd --- test/functional/data/README.md | 14 +++++++++++--- test/functional/data/mainnet_alt.json | 6 ++++-- test/functional/mining_mainnet.py | 19 +++++++++++++------ test/functional/test_framework/blocktools.py | 4 ++-- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/test/functional/data/README.md b/test/functional/data/README.md index bb03422f95f..956394e385c 100644 --- a/test/functional/data/README.md +++ b/test/functional/data/README.md @@ -11,9 +11,10 @@ The alternate mainnet chain was generated as follows: - restart node with a faketime 2 minutes later ```sh -for i in {1..2015} +for i in {1..2016} do - faketime "`date -d @"$(( 1231006505 + $i * 120 ))" +'%Y-%m-%d %H:%M:%S'`" \ + t=$(( 1231006505 + $i * 120 )) + faketime "`date -d @$t +'%Y-%m-%d %H:%M:%S'`" \ bitcoind -connect=0 -nocheckpoints -stopatheight=$i done ``` @@ -21,7 +22,9 @@ done The CPU miner is kept running as follows: ```sh -./minerd --coinbase-addr 1NQpH6Nf8QtR2HphLRcvuVqfhXBXsiWn8r --no-stratum --algo sha256d --no-longpoll --scantime 3 --retry-pause 1 +./minerd -u ... -p ... -o http://127.0.0.1:8332 --no-stratum \ + --coinbase-addr 1NQpH6Nf8QtR2HphLRcvuVqfhXBXsiWn8r \ + --algo sha256d --no-longpoll --scantime 3 --retry-pause 1 ``` The payout address is derived from first BIP32 test vector master key: @@ -40,3 +43,8 @@ The timestamp was not kept constant because at difficulty 1 it's not sufficient to only grind the nonce. Grinding the extra_nonce or version field instead would have required additional (stratum) software. It would also make it more complicated to reconstruct the blocks in this test. + +The `getblocktemplate` RPC code needs to be patched to ignore not being connected +to any peers, and to ignore the IBD status check. + +On macOS use `faketime "@$t"` instead. diff --git a/test/functional/data/mainnet_alt.json b/test/functional/data/mainnet_alt.json index a4a072d2c5b..96821a36f41 100644 --- a/test/functional/data/mainnet_alt.json +++ b/test/functional/data/mainnet_alt.json @@ -2014,7 +2014,8 @@ 1231247971, 1231248071, 1231248198, - 1231248322 + 1231248322, + 1231248621 ], "nonces": [ 2345621585, @@ -4031,6 +4032,7 @@ 3658502865, 2519048297, 1915965760, - 1183846025 + 1183846025, + 2713372123 ] } diff --git a/test/functional/mining_mainnet.py b/test/functional/mining_mainnet.py index c2757b61574..c58c4784b4d 100755 --- a/test/functional/mining_mainnet.py +++ b/test/functional/mining_mainnet.py @@ -54,15 +54,15 @@ def add_options(self, parser): self.add_wallet_options(parser) - def mine(self, height, prev_hash, blocks, node, fees=0): + def mine(self, height, prev_hash, blocks, node): self.log.debug(f"height={height}") block = CBlock() block.nVersion = 0x20000000 block.hashPrevBlock = int(prev_hash, 16) block.nTime = blocks['timestamps'][height - 1] - block.nBits = DIFF_1_N_BITS + block.nBits = DIFF_1_N_BITS if height < 2016 else DIFF_4_N_BITS block.nNonce = blocks['nonces'][height - 1] - block.vtx = [create_coinbase(height=height, script_pubkey=bytes.fromhex(COINBASE_SCRIPT_PUBKEY), retarget_period=2016)] + block.vtx = [create_coinbase(height=height, script_pubkey=bytes.fromhex(COINBASE_SCRIPT_PUBKEY), halving_period=210000)] block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block_hex = block.serialize(with_witness=False).hex() @@ -81,12 +81,15 @@ def run_test(self): self.log.info("Load alternative mainnet blocks") path = os.path.join(os.path.dirname(os.path.realpath(__file__)), self.options.datafile) prev_hash = node.getbestblockhash() + blocks = None with open(path, encoding='utf-8') as f: blocks = json.load(f) n_blocks = len(blocks['timestamps']) - assert_equal(n_blocks, 2015) - for i in range(2015): - prev_hash = self.mine(i + 1, prev_hash, blocks, node) + assert_equal(n_blocks, 2016) + + # Mine up to the last block of the first retarget period + for i in range(2015): + prev_hash = self.mine(i + 1, prev_hash, blocks, node) assert_equal(node.getblockcount(), 2015) @@ -101,5 +104,9 @@ def run_test(self): assert_equal(mining_info['next']['bits'], nbits_str(DIFF_4_N_BITS)) assert_equal(mining_info['next']['target'], target_str(DIFF_4_TARGET)) + # Mine first block of the second retarget period + height = 2016 + prev_hash = self.mine(height, prev_hash, blocks, node) + assert_equal(node.getblockcount(), height) if __name__ == '__main__': MiningMainnetTest(__file__).main() diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py index 38600bc005a..49e2518887f 100644 --- a/test/functional/test_framework/blocktools.py +++ b/test/functional/test_framework/blocktools.py @@ -143,7 +143,7 @@ def script_BIP34_coinbase_height(height): return CScript([CScriptNum(height)]) -def create_coinbase(height, pubkey=None, *, script_pubkey=None, extra_output_script=None, fees=0, nValue=50, retarget_period=REGTEST_RETARGET_PERIOD): +def create_coinbase(height, pubkey=None, *, script_pubkey=None, extra_output_script=None, fees=0, nValue=50, halving_period=REGTEST_RETARGET_PERIOD): """Create a coinbase transaction. If pubkey is passed in, the coinbase output will be a P2PK output; @@ -156,7 +156,7 @@ def create_coinbase(height, pubkey=None, *, script_pubkey=None, extra_output_scr coinbaseoutput = CTxOut() coinbaseoutput.nValue = nValue * COIN if nValue == 50: - halvings = int(height / retarget_period) + halvings = int(height / halving_period) coinbaseoutput.nValue >>= halvings coinbaseoutput.nValue += fees if pubkey is not None: From 22ab141243eeb4a929e589ef70a6f54a5aaed3ba Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Sat, 20 Sep 2025 21:33:13 +0200 Subject: [PATCH 203/314] rpc: fix getblock(header) returns target for tip A target field was added to the getblock and getblockheader RPC calls in bitcoin#31583, but it mistakingly always used the tip value. Because regtest does not have difficulty adjustment, a test is added for mainnet instead. Github-Pull: #33446 Rebased-From: bf7996cbc3becf329d8b1cd2f1007fec9b3a3188 --- src/rpc/blockchain.cpp | 2 +- test/functional/mining_mainnet.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 8cbca51ccbf..edda17d3697 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -164,7 +164,7 @@ UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex result.pushKV("mediantime", blockindex.GetMedianTimePast()); result.pushKV("nonce", blockindex.nNonce); result.pushKV("bits", strprintf("%08x", blockindex.nBits)); - result.pushKV("target", GetTarget(tip, pow_limit).GetHex()); + result.pushKV("target", GetTarget(blockindex, pow_limit).GetHex()); result.pushKV("difficulty", GetDifficulty(blockindex)); result.pushKV("chainwork", blockindex.nChainWork.GetHex()); result.pushKV("nTx", blockindex.nTx); diff --git a/test/functional/mining_mainnet.py b/test/functional/mining_mainnet.py index c58c4784b4d..456381af55a 100755 --- a/test/functional/mining_mainnet.py +++ b/test/functional/mining_mainnet.py @@ -108,5 +108,17 @@ def run_test(self): height = 2016 prev_hash = self.mine(height, prev_hash, blocks, node) assert_equal(node.getblockcount(), height) + + mining_info = node.getmininginfo() + assert_equal(mining_info['difficulty'], 4) + + self.log.info("getblock RPC should show historical target") + block_info = node.getblock(node.getblockhash(1)) + + assert_equal(block_info['difficulty'], 1) + assert_equal(block_info['bits'], nbits_str(DIFF_1_N_BITS)) + assert_equal(block_info['target'], target_str(DIFF_1_TARGET)) + + if __name__ == '__main__': MiningMainnetTest(__file__).main() From 9d9baafc6f9357179e57fdcc6cf2ce36d65dd16d Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Fri, 26 Sep 2025 19:25:26 +0200 Subject: [PATCH 204/314] doc: rpc: fix case typo in `finalizepsbt` help (final_scriptwitness) Github-Pull: #33484 Rebased-From: ff05bebcc4262966b117082a67dc4c63a3f67d2d --- src/rpc/rawtransaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 421656152cb..77e8fd49e11 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1494,7 +1494,7 @@ static RPCHelpMan finalizepsbt() return RPCHelpMan{"finalizepsbt", "Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a\n" "network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be\n" - "created which has the final_scriptSig and final_scriptWitness fields filled for inputs that are complete.\n" + "created which has the final_scriptSig and final_scriptwitness fields filled for inputs that are complete.\n" "Implements the Finalizer and Extractor roles.\n", { {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}, From 6f23ead4a2d97e245f4fc1824b1dd956dc06cc42 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Mon, 29 Sep 2025 15:47:07 -0400 Subject: [PATCH 205/314] fuzz: don't bypass_limits for most mempool harnesses Using bypass_limits=true is essentially fuzzing part of a reorg only, and results in TRUC invariants unable to be checked. Remove most instances of bypassing limits, leaving one harness able to do so. Github-Pull: #33504 Rebased-From: bbe8e9063c15dc230553e0cbf16d603f5ad0e4cf --- src/test/fuzz/package_eval.cpp | 2 +- src/test/fuzz/tx_pool.cpp | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/test/fuzz/package_eval.cpp b/src/test/fuzz/package_eval.cpp index 8e3d84a9e63..37b18a59414 100644 --- a/src/test/fuzz/package_eval.cpp +++ b/src/test/fuzz/package_eval.cpp @@ -324,7 +324,7 @@ FUZZ_TARGET(ephemeral_package_eval, .init = initialize_tx_pool) return ProcessNewPackage(chainstate, tx_pool, txs, /*test_accept=*/single_submit, /*client_maxfeerate=*/{})); const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, txs.back(), GetTime(), - /*bypass_limits=*/fuzzed_data_provider.ConsumeBool(), /*test_accept=*/!single_submit)); + /*bypass_limits=*/false, /*test_accept=*/!single_submit)); if (!single_submit && result_package.m_state.GetResult() != PackageValidationResult::PCKG_POLICY) { // We don't know anything about the validity since transactions were randomly generated, so diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp index a697ee9d838..98feadf516e 100644 --- a/src/test/fuzz/tx_pool.cpp +++ b/src/test/fuzz/tx_pool.cpp @@ -295,7 +295,6 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool) std::set added; auto txr = std::make_shared(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. @@ -310,7 +309,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); @@ -393,6 +392,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); @@ -411,13 +413,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); From 666aec7d49506c587ecbbcd71f6e8f1e7bb4e4cd Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Fri, 26 Sep 2025 14:47:47 -0400 Subject: [PATCH 206/314] Mempool: Do not enforce TRUC checks on reorg Not enforcing TRUC topology on reorg was the intended behavior, but the appropriate bypass argument was not checked. This mistake means we could potentially invalidate a long chain of perfectly incentive-compatible transactions that were made historically, including subsequent non-TRUC transactions, all of which may have been very high feerate. Lastly, it wastes CPU cycles doing topology checks since this behavior cannot actually enforce the topology in general for the reorg setting. Github-Pull: #33504 Rebased-From: 26e71c237d9d2197824b547f55ee3a0a60149f92 --- src/validation.cpp | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index fde064458dc..85504d1e290 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1025,26 +1025,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); - - // 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); + 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); + } } } From a8bb76b61f49e1abd681f21a754f970eef206ced Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Fri, 26 Sep 2025 14:49:06 -0400 Subject: [PATCH 207/314] test: add more TRUC reorg coverge Github-Pull: #33504 Rebased-From: 06df14ba75be5f48cf9c417424900ace17d1cf4d --- test/functional/mempool_truc.py | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/test/functional/mempool_truc.py b/test/functional/mempool_truc.py index 8850ba80028..d095033a847 100755 --- a/test/functional/mempool_truc.py +++ b/test/functional/mempool_truc.py @@ -164,23 +164,36 @@ def test_truc_replacement(self): def test_truc_reorg(self): node = self.nodes[0] self.log.info("Test that, during a reorg, TRUC rules are not enforced") - tx_v2_block = self.wallet.send_self_transfer(from_node=node, version=2) - tx_v3_block = self.wallet.send_self_transfer(from_node=node, version=3) - tx_v3_block2 = self.wallet.send_self_transfer(from_node=node, version=3) - self.check_mempool([tx_v3_block["txid"], tx_v2_block["txid"], tx_v3_block2["txid"]]) + self.check_mempool([]) + + # Testing 2<-3 versions allowed + tx_v2_block = self.wallet.create_self_transfer(version=2) + + # Testing 3<-2 versions allowed + tx_v3_block = self.wallet.create_self_transfer(version=3) + + # Testing overly-large child size + tx_v3_block2 = self.wallet.create_self_transfer(version=3) + + # Also create a linear chain of 3 TRUC transactions that will be directly mined, followed by one v2 in-mempool after block is made + tx_chain_1 = self.wallet.create_self_transfer(version=3) + tx_chain_2 = self.wallet.create_self_transfer(utxo_to_spend=tx_chain_1["new_utxo"], version=3) + tx_chain_3 = self.wallet.create_self_transfer(utxo_to_spend=tx_chain_2["new_utxo"], version=3) + + tx_to_mine = [tx_v3_block["hex"], tx_v2_block["hex"], tx_v3_block2["hex"], tx_chain_1["hex"], tx_chain_2["hex"], tx_chain_3["hex"]] + block = self.generateblock(node, output="raw(42)", transactions=tx_to_mine) - block = self.generate(node, 1) self.check_mempool([]) tx_v2_from_v3 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_block["new_utxo"], version=2) tx_v3_from_v2 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v2_block["new_utxo"], version=3) tx_v3_child_large = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_block2["new_utxo"], target_vsize=1250, version=3) assert_greater_than(node.getmempoolentry(tx_v3_child_large["txid"])["vsize"], TRUC_CHILD_MAX_VSIZE) - self.check_mempool([tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"]]) - node.invalidateblock(block[0]) - self.check_mempool([tx_v3_block["txid"], tx_v2_block["txid"], tx_v3_block2["txid"], tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"]]) - # This is needed because generate() will create the exact same block again. - node.reconsiderblock(block[0]) + tx_chain_4 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_chain_3["new_utxo"], version=2) + self.check_mempool([tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"], tx_chain_4["txid"]]) + # Reorg should have all block transactions re-accepted, ignoring TRUC enforcement + node.invalidateblock(block["hash"]) + self.check_mempool([tx_v3_block["txid"], tx_v2_block["txid"], tx_v3_block2["txid"], tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"], tx_chain_1["txid"], tx_chain_2["txid"], tx_chain_3["txid"], tx_chain_4["txid"]]) @cleanup(extra_args=["-limitdescendantsize=10", "-datacarriersize=40000"]) def test_nondefault_package_limits(self): From 2d7ebd2d913ea63c1a23fefa0a09ee06fb069161 Mon Sep 17 00:00:00 2001 From: fanquake Date: Wed, 24 Sep 2025 10:35:55 -0400 Subject: [PATCH 208/314] doc: update release notes for 29.x --- doc/release-notes.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 0325d3a3e28..8a79e99ad27 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.2rc1 is now available from: +Bitcoin Core version 29.2rc2 is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. @@ -43,6 +43,14 @@ Notable changes - #33296 net: check for empty header before calling FillBlock - #33395 net: do not apply whitelist permissions to onion inbounds +### Mempool + +- #33504 mempool: Do not enforce TRUC checks on reorg + +### RPC + +- #33446 rpc: fix getblock(header) returns target for tip + ### CI - #32999 ci: Use APT_LLVM_V in msan task @@ -50,6 +58,10 @@ Notable changes - #33258 ci: use LLVM 21 - #33364 ci: always use tag for LLVM checkout +### Doc + +- #33484 doc: rpc: fix case typo in `finalizepsbt` help + ### Misc - #33310 trace: Workaround GCC bug compiling with old systemtap @@ -67,6 +79,8 @@ Thanks to everyone who directly contributed to this release: - Luke Dashjr - MarcoFalke - Martin Zumsande +- Sebastian Falbesoner +- Sjors Provoost - Vasil Dimov As well as to everyone that helped with translations on From 6b3c1dbc5c0df4357ee7f57ac238bcdff55526af Mon Sep 17 00:00:00 2001 From: amisha Date: Wed, 10 Sep 2025 21:04:57 +0530 Subject: [PATCH 209/314] contrib: fix using macdploy script without translations. QT translations are optional, but the script would error when 'translations_dir' falls back to its default value NULL. This PR fixes it by moving the set-up of QT translations under the check for 'translations_dir' presence. Github-Pull: #33482 Rebased-From: 7b5261f7ef3d88361204c40eb10c0d9dc44f5ed7 --- contrib/macdeploy/macdeployqtplus | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index eaa7b896be9..51205376269 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -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)) # ------------------------------------------------ From eea16f7de7c4382e4491f3b018ecd0c36678affb Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 3 Oct 2025 14:27:43 +0100 Subject: [PATCH 210/314] build: bump version to v29.2rc2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 05a86a1d97f..681926a1e4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 2) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 1) +set(CLIENT_VERSION_RC 2) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From 513cef75ee06bc5d310a22d366a5f3c815aa1499 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 3 Oct 2025 14:39:17 +0100 Subject: [PATCH 211/314] doc: update manual pages for v29.2rc2 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index a8dc092a6cc..707ccfc322b 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "September 2025" "bitcoin-cli v29.2.0rc1" "User Commands" +.TH BITCOIN-CLI "1" "October 2025" "bitcoin-cli v29.2.0rc2" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.2.0rc1 +bitcoin-cli \- manual page for bitcoin-cli v29.2.0rc2 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.2.0rc1 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.2.0rc1 +Bitcoin Core RPC client version v29.2.0rc2 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 7821b8fb440..a02b52ea2e7 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "September 2025" "bitcoin-qt v29.2.0rc1" "User Commands" +.TH BITCOIN-QT "1" "October 2025" "bitcoin-qt v29.2.0rc2" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.2.0rc1 +bitcoin-qt \- manual page for bitcoin-qt v29.2.0rc2 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.2.0rc1 +Bitcoin Core version v29.2.0rc2 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index a14a6be6024..a7df27545c2 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "September 2025" "bitcoin-tx v29.2.0rc1" "User Commands" +.TH BITCOIN-TX "1" "October 2025" "bitcoin-tx v29.2.0rc2" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.2.0rc1 +bitcoin-tx \- manual page for bitcoin-tx v29.2.0rc2 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.2.0rc1 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.2.0rc1 +Bitcoin Core bitcoin\-tx utility version v29.2.0rc2 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index e0cc27e2d77..d127ddf4cb3 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "September 2025" "bitcoin-util v29.2.0rc1" "User Commands" +.TH BITCOIN-UTIL "1" "October 2025" "bitcoin-util v29.2.0rc2" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.2.0rc1 +bitcoin-util \- manual page for bitcoin-util v29.2.0rc2 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.2.0rc1 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.2.0rc1 +Bitcoin Core bitcoin\-util utility version v29.2.0rc2 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index 58bbf2715b3..b471ac1a246 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "September 2025" "bitcoin-wallet v29.2.0rc1" "User Commands" +.TH BITCOIN-WALLET "1" "October 2025" "bitcoin-wallet v29.2.0rc2" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.2.0rc1 +bitcoin-wallet \- manual page for bitcoin-wallet v29.2.0rc2 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.2.0rc1 +Bitcoin Core bitcoin\-wallet utility version v29.2.0rc2 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 0846f3e0619..3e7e394b1af 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "September 2025" "bitcoind v29.2.0rc1" "User Commands" +.TH BITCOIND "1" "October 2025" "bitcoind v29.2.0rc2" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.2.0rc1 +bitcoind \- manual page for bitcoind v29.2.0rc2 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.2.0rc1 +Bitcoin Core daemon version v29.2.0rc2 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From d82fc69829cd8cabbaf2c3a969597b40c32edc86 Mon Sep 17 00:00:00 2001 From: fanquake Date: Fri, 3 Oct 2025 18:04:23 +0100 Subject: [PATCH 212/314] doc: update release notes for 29.2rc2 --- doc/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 8a79e99ad27..30cb763a0c7 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -53,6 +53,7 @@ Notable changes ### CI +- #32989 ci: Migrate CI to hosted Cirrus Runners - #32999 ci: Use APT_LLVM_V in msan task - #33099 ci: allow for any libc++ intrumentation & use it for TSAN - #33258 ci: use LLVM 21 @@ -66,12 +67,14 @@ Notable changes - #33310 trace: Workaround GCC bug compiling with old systemtap - #33340 Fix benchmark CSV output +- #33482 contrib: fix macOS deployment with no translations Credits ======= Thanks to everyone who directly contributed to this release: +- Amisha Chhajed - Eugene Siegel - fanquake - Greg Sanders @@ -82,6 +85,7 @@ Thanks to everyone who directly contributed to this release: - Sebastian Falbesoner - Sjors Provoost - Vasil Dimov +- Will Clark As well as to everyone that helped with translations on [Transifex](https://explore.transifex.com/bitcoin/bitcoin/). From abf4a6eeaee116917dafd56eb9caee03e13048d2 Mon Sep 17 00:00:00 2001 From: fanquake Date: Tue, 7 Oct 2025 13:31:04 +0100 Subject: [PATCH 213/314] build: fix depends Qt download link --- depends/packages/qt.mk | 2 +- doc/dependencies.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index d41ac4e784e..abd8a6fa8d2 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,6 +1,6 @@ package=qt $(package)_version=5.15.16 -$(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=b04815058c18058b6ba837206756a2c87d1391f07a0dcb0dd314f970fd041592 diff --git a/doc/dependencies.md b/doc/dependencies.md index 7c866a433db..d3f6b74367b 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -30,7 +30,7 @@ Bitcoin Core requires one of the following compilers. | [Fontconfig](../depends/packages/fontconfig.mk) (gui) | [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) (gui) | [link](https://freetype.org) | [2.11.0](https://github.com/bitcoin/bitcoin/commit/01544dd78ccc0b0474571da854e27adef97137fb) | 2.3.0 | Yes | | [qrencode](../depends/packages/qrencode.mk) (gui) | [link](https://fukuchi.org/works/qrencode/) | [4.1.1](https://github.com/bitcoin/bitcoin/pull/27312) | N/A | No | -| [Qt](../depends/packages/qt.mk) (gui) | [link](https://download.qt.io/official_releases/qt/) | [5.15.16](https://github.com/bitcoin/bitcoin/pull/30774) | [5.11.3](https://github.com/bitcoin/bitcoin/pull/24132) | No | +| [Qt](../depends/packages/qt.mk) (gui) | [link](https://download.qt.io/archive/qt/) | [5.15.16](https://github.com/bitcoin/bitcoin/pull/30774) | [5.11.3](https://github.com/bitcoin/bitcoin/pull/24132) | No | | [ZeroMQ](../depends/packages/zeromq.mk) (notifications) | [link](https://github.com/zeromq/libzmq/releases) | [4.3.4](https://github.com/bitcoin/bitcoin/pull/23956) | 4.0.0 | No | | [Berkeley DB](../depends/packages/bdb.mk) (legacy wallet) | [link](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.30 | 4.8.x | No | | [SQLite](../depends/packages/sqlite.mk) (wallet) | [link](https://sqlite.org) | [3.38.5](https://github.com/bitcoin/bitcoin/pull/25378) | [3.7.17](https://github.com/bitcoin/bitcoin/pull/19077) | No | From 3226616493289b111997bb107e569fef54386743 Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 6 Oct 2025 16:35:18 +0100 Subject: [PATCH 214/314] doc: update release notes for 29.2 --- doc/release-notes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 30cb763a0c7..b981b8a7f54 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.2rc2 is now available from: +Bitcoin Core version 29.2 is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. From b2026fa290f0aef9a0dcfe45750121f113e2ce7d Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 6 Oct 2025 16:35:38 +0100 Subject: [PATCH 215/314] build: bump version to v29.2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 681926a1e4b..70f672132b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 2) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 2) +set(CLIENT_VERSION_RC 0) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From 46d9b9091baa096da30da5e14329a32f1264229a Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 6 Oct 2025 16:39:57 +0100 Subject: [PATCH 216/314] doc: update manual pages for v29.2 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index 707ccfc322b..ce6f35c198e 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "October 2025" "bitcoin-cli v29.2.0rc2" "User Commands" +.TH BITCOIN-CLI "1" "October 2025" "bitcoin-cli v29.2.0" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.2.0rc2 +bitcoin-cli \- manual page for bitcoin-cli v29.2.0 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.2.0rc2 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.2.0rc2 +Bitcoin Core RPC client version v29.2.0 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index a02b52ea2e7..5efc9e96172 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "October 2025" "bitcoin-qt v29.2.0rc2" "User Commands" +.TH BITCOIN-QT "1" "October 2025" "bitcoin-qt v29.2.0" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.2.0rc2 +bitcoin-qt \- manual page for bitcoin-qt v29.2.0 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.2.0rc2 +Bitcoin Core version v29.2.0 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index a7df27545c2..90a233619fa 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "October 2025" "bitcoin-tx v29.2.0rc2" "User Commands" +.TH BITCOIN-TX "1" "October 2025" "bitcoin-tx v29.2.0" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.2.0rc2 +bitcoin-tx \- manual page for bitcoin-tx v29.2.0 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.2.0rc2 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.2.0rc2 +Bitcoin Core bitcoin\-tx utility version v29.2.0 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index d127ddf4cb3..4186bd3f5a7 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "October 2025" "bitcoin-util v29.2.0rc2" "User Commands" +.TH BITCOIN-UTIL "1" "October 2025" "bitcoin-util v29.2.0" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.2.0rc2 +bitcoin-util \- manual page for bitcoin-util v29.2.0 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.2.0rc2 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.2.0rc2 +Bitcoin Core bitcoin\-util utility version v29.2.0 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index b471ac1a246..97c6144f81a 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "October 2025" "bitcoin-wallet v29.2.0rc2" "User Commands" +.TH BITCOIN-WALLET "1" "October 2025" "bitcoin-wallet v29.2.0" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.2.0rc2 +bitcoin-wallet \- manual page for bitcoin-wallet v29.2.0 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.2.0rc2 +Bitcoin Core bitcoin\-wallet utility version v29.2.0 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 3e7e394b1af..82804a50c83 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "October 2025" "bitcoind v29.2.0rc2" "User Commands" +.TH BITCOIND "1" "October 2025" "bitcoind v29.2.0" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.2.0rc2 +bitcoind \- manual page for bitcoind v29.2.0 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.2.0rc2 +Bitcoin Core daemon version v29.2.0 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From c7979f429a86a2971a4ff024bd0e9cd7a6b7222f Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 8 Oct 2025 14:47:00 -0700 Subject: [PATCH 217/314] ci: Properly include $FILE_ENV in DEPENDS_HASH $FILE_ENV has a full relative path already, prepending with ci/test/ results in a non-existent path which means that DEPENDS_HASH was not actually committing to the test's environment file. Github-Pull: #33581 Rebased-From: ceeb53adcd0a6a87a65c8ebbb20472c15c502dfd --- .github/actions/configure-environment/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/configure-environment/action.yml b/.github/actions/configure-environment/action.yml index aae5016bdce..e2a26b7184d 100644 --- a/.github/actions/configure-environment/action.yml +++ b/.github/actions/configure-environment/action.yml @@ -17,7 +17,7 @@ runs: - 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 "DEPENDS_HASH=$(git ls-tree HEAD depends "$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 From 16e10f928cc65b2096046c8c5e0fe715fc5b9d72 Mon Sep 17 00:00:00 2001 From: willcl-ark Date: Tue, 30 Sep 2025 11:00:26 +0100 Subject: [PATCH 218/314] ci: expose all ACTIONS_* vars When using `docker buildx build` in conjunction with the `gha` backend cache type, it's important to specify the URL and TOKEN needed to authenticate. On Cirrus runners this is working with only `ACTIONS_CACHE_URL` and `ACTIONS_RUNTIME_TOKEN`, but this is not enough for the GitHub backend. Fix this by exporting all `ACTIONS_*` variables. This fixes cache restore/save on forks or where GH-hosted runners are being used. Github-Pull: #33508 Rebased-From: bc706955d740f8a59bec78e44d33e80d1cca373b --- .github/actions/configure-docker/action.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/actions/configure-docker/action.yml b/.github/actions/configure-docker/action.yml index c78df86b6cf..131fdb1ccc3 100644 --- a/.github/actions/configure-docker/action.yml +++ b/.github/actions/configure-docker/action.yml @@ -19,8 +19,12 @@ runs: 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']) + Object.keys(process.env).forEach(function (key) { + if (key.startsWith('ACTIONS_')) { + core.info(`Exporting ${key}`); + core.exportVariable(key, process.env[key]); + } + }); - name: Construct docker build cache args shell: bash From 554ff3f7f33651db3a7071d6b8dc5438a303ac03 Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Mon, 13 Oct 2025 11:29:19 -0400 Subject: [PATCH 219/314] test: change log rate limit version gate from 299900 to 290100 Github-Pull: #33612 Rebased-From: 7b544341c0021dd713f05bc439ee190de911930c --- test/functional/test_framework/test_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 47ae2cc22da..919d48b37ae 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -137,7 +137,7 @@ def __init__(self, i, datadir_path, *, chain, rpchost, timewait, timeout_factor, self.args.append("-logsourcelocations") if self.version_is_at_least(239000): self.args.append("-loglevel=trace") - if self.version_is_at_least(299900): + if self.version_is_at_least(290100): self.args.append("-nologratelimit") # Default behavior from global -v2transport flag is added to args to persist it over restarts. From 4917d0c0de50da204b002bd4ae0c53cafd268f0c Mon Sep 17 00:00:00 2001 From: fanquake Date: Mon, 13 Oct 2025 16:21:50 +0100 Subject: [PATCH 220/314] doc: update release notes for 29.x --- doc/release-notes.md | 48 ++++++++------------------------------------ 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index b981b8a7f54..4e2071dfa67 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.2 is now available from: +Bitcoin Core version 29.x is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. @@ -37,55 +37,23 @@ unsupported systems. Notable changes =============== -### P2P +### Test -- #32646 p2p: Add witness mutation check inside FillBlock -- #33296 net: check for empty header before calling FillBlock -- #33395 net: do not apply whitelist permissions to onion inbounds - -### Mempool - -- #33504 mempool: Do not enforce TRUC checks on reorg - -### RPC - -- #33446 rpc: fix getblock(header) returns target for tip - -### CI - -- #32989 ci: Migrate CI to hosted Cirrus Runners -- #32999 ci: Use APT_LLVM_V in msan task -- #33099 ci: allow for any libc++ intrumentation & use it for TSAN -- #33258 ci: use LLVM 21 -- #33364 ci: always use tag for LLVM checkout - -### Doc - -- #33484 doc: rpc: fix case typo in `finalizepsbt` help +- #33612 test: change log rate limit version gate ### Misc -- #33310 trace: Workaround GCC bug compiling with old systemtap -- #33340 Fix benchmark CSV output -- #33482 contrib: fix macOS deployment with no translations +- #33508 ci: fix buildx gha cache authentication on forks +- #33581 ci: Properly include $FILE_ENV in DEPENDS_HASH Credits ======= Thanks to everyone who directly contributed to this release: -- Amisha Chhajed +- Ava Chow - Eugene Siegel -- fanquake -- Greg Sanders -- Hennadii Stepanov -- Luke Dashjr -- MarcoFalke -- Martin Zumsande -- Sebastian Falbesoner -- Sjors Provoost -- Vasil Dimov -- Will Clark +- willcl-ark As well as to everyone that helped with translations on [Transifex](https://explore.transifex.com/bitcoin/bitcoin/). From 97088fa75aa0af5355587ce3522320f459e35204 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Mon, 4 Aug 2025 14:06:27 -0400 Subject: [PATCH 221/314] qa: test witness stripping in p2p_segwit A stripped witness is detected as a special case in mempool acceptance to make sure we do not add the wtxid (which is =txid since witness is stripped) to the reject filter. This is because it may interfere with 1p1c parent relay which currently uses orphan reconciliation (and originally it was until wtxid-relay was widely adopted on the network. This commit adds a test for this special case in the p2p_segwit function test, both when spending a native segwit output and when spending a p2sh-wrapped segwit output. Thanks to Eugene Siegel for pointing out the p2sh-wrapped detection did not have test coverage by finding a bug in a related patch of mine. Github-Pull: #33105 Rebased-From: eb073209db9efdbc2c94bc1f535a27ec6b20d954 --- test/functional/p2p_segwit.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py index 9caf5a19aad..e8f7f7e0f4e 100755 --- a/test/functional/p2p_segwit.py +++ b/test/functional/p2p_segwit.py @@ -707,6 +707,12 @@ def test_p2sh_witness(self): expected_msgs=[spend_tx.hash, 'was not accepted: mandatory-script-verify-flag-failed (Witness program was passed an empty witness)']): test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False) + # The transaction was detected as witness stripped above and not added to the reject + # filter. Trying again will check it again and result in the same error. + with self.nodes[0].assert_debug_log( + expected_msgs=[spend_tx.hash, 'was not accepted: mandatory-script-verify-flag-failed (Witness program was passed an empty witness)']): + test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False) + # Try to put the witness script in the scriptSig, should also fail. spend_tx.vin[0].scriptSig = CScript([p2wsh_pubkey, b'a']) spend_tx.rehash() @@ -1282,6 +1288,13 @@ def test_tx_relay_after_segwit_activation(self): test_transaction_acceptance(self.nodes[0], self.test_node, tx2, with_witness=True, accepted=True) test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=False) + # Now do the opposite: strip the witness entirely. This will be detected as witness stripping and + # the (w)txid won't be added to the reject filter: we can try again and get the same error. + tx3.wit.vtxinwit[0].scriptWitness.stack = [] + reason = "was not accepted: mandatory-script-verify-flag-failed (Witness program was passed an empty witness)" + test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=False, accepted=False, reason=reason) + test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=False, accepted=False, reason=reason) + # Get rid of the extra witness, and verify acceptance. tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_script] # Also check that old_node gets a tx announcement, even though this is From 56626300b80dced9e111a39d5c560b0b81276cb8 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Mon, 4 Aug 2025 13:11:33 -0400 Subject: [PATCH 222/314] policy: introduce a helper to detect whether a transaction spends Segwit outputs We will use this helper in later commits to detect witness stripping without having to execute every input Script three times in a row. Github-Pull: #33105 Rebased-From: 2907b58834ab011f7dd0c42d323e440abd227c25 --- src/policy/policy.cpp | 36 ++++++++ src/policy/policy.h | 5 ++ src/test/transaction_tests.cpp | 155 +++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 545387d150c..5942747d609 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -344,6 +344,42 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } +bool SpendsNonAnchorWitnessProg(const CTransaction& tx, const CCoinsViewCache& prevouts) +{ + if (tx.IsCoinBase()) { + return false; + } + + int version; + std::vector program; + for (const auto& txin: tx.vin) { + const auto& prev_spk{prevouts.AccessCoin(txin.prevout).out.scriptPubKey}; + + // Note this includes not-yet-defined witness programs. + if (prev_spk.IsWitnessProgram(version, program) && !prev_spk.IsPayToAnchor(version, program)) { + return true; + } + + // For P2SH extract the redeem script and check if it spends a non-Taproot witness program. Note + // this is fine to call EvalScript (as done in AreInputsStandard/IsWitnessStandard) because this + // function is only ever called after IsStandardTx, which checks the scriptsig is pushonly. + if (prev_spk.IsPayToScriptHash()) { + // If EvalScript fails or results in an empty stack, the transaction is invalid by consensus. + std::vector > stack; + if (!EvalScript(stack, txin.scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker{}, SigVersion::BASE) + || stack.empty()) { + continue; + } + const CScript redeem_script{stack.back().begin(), stack.back().end()}; + if (redeem_script.IsWitnessProgram(version, program)) { + return true; + } + } + } + + return false; +} + int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop) { return (std::max(nWeight, nSigOpCost * bytes_per_sigop) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; diff --git a/src/policy/policy.h b/src/policy/policy.h index bf6224af3db..a6ce608bcfa 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -167,6 +167,11 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) * Also enforce a maximum stack item size limit and no annexes for tapscript spends. */ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); +/** + * Check whether this transaction spends any witness program but P2A, including not-yet-defined ones. + * May return `false` early for consensus-invalid transactions. + */ +bool SpendsNonAnchorWitnessProg(const CTransaction& tx, const CCoinsViewCache& prevouts); /** Compute the virtual transaction size (weight reinterpreted as bytes). */ int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 2db30e20331..5844ab23bc8 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1144,4 +1144,159 @@ BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops) BOOST_CHECK(!::AreInputsStandard(CTransaction(tx_max_sigops), coins)); } +/** Sanity check the return value of SpendsNonAnchorWitnessProg for various output types. */ +BOOST_AUTO_TEST_CASE(spends_witness_prog) +{ + CCoinsView coins_dummy; + CCoinsViewCache coins(&coins_dummy); + CKey key; + key.MakeNewKey(true); + const CPubKey pubkey{key.GetPubKey()}; + CMutableTransaction tx_create{}, tx_spend{}; + tx_create.vout.emplace_back(0, CScript{}); + tx_spend.vin.emplace_back(Txid{}, 0); + std::vector> sol_dummy; + + // CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, + // WitnessV1Taproot, PayToAnchor, WitnessUnknown. + static_assert(std::variant_size_v == 9); + + // Go through all defined output types and sanity check SpendsNonAnchorWitnessProg. + + // P2PK + tx_create.vout[0].scriptPubKey = GetScriptForDestination(PubKeyDestination{pubkey}); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::PUBKEY); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // P2PKH + tx_create.vout[0].scriptPubKey = GetScriptForDestination(PKHash{pubkey}); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::PUBKEYHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // P2SH + auto redeem_script{CScript{} << OP_1 << OP_CHECKSIG}; + tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash{redeem_script}); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + tx_spend.vin[0].scriptSig = CScript{} << OP_0 << ToByteVector(redeem_script); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + tx_spend.vin[0].scriptSig.clear(); + + // native P2WSH + const auto witness_script{CScript{} << OP_12 << OP_HASH160 << OP_DUP << OP_EQUAL}; + tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash{witness_script}); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_V0_SCRIPTHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // P2SH-wrapped P2WSH + redeem_script = tx_create.vout[0].scriptPubKey; + tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script)); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + tx_spend.vin[0].scriptSig.clear(); + BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // native P2WPKH + tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessV0KeyHash{pubkey}); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_V0_KEYHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // P2SH-wrapped P2WPKH + redeem_script = tx_create.vout[0].scriptPubKey; + tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script)); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + tx_spend.vin[0].scriptSig.clear(); + BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // P2TR + tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessV1Taproot{XOnlyPubKey{pubkey}}); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_V1_TAPROOT); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // P2SH-wrapped P2TR (undefined, non-standard) + redeem_script = tx_create.vout[0].scriptPubKey; + tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script)); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + tx_spend.vin[0].scriptSig.clear(); + BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // P2A + tx_create.vout[0].scriptPubKey = GetScriptForDestination(PayToAnchor{}); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::ANCHOR); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // P2SH-wrapped P2A (undefined, non-standard) + redeem_script = tx_create.vout[0].scriptPubKey; + tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script)); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + tx_spend.vin[0].scriptSig.clear(); + + // Undefined version 1 witness program + tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessUnknown{1, {0x42, 0x42}}); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_UNKNOWN); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // P2SH-wrapped undefined version 1 witness program + redeem_script = tx_create.vout[0].scriptPubKey; + tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script)); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + tx_spend.vin[0].scriptSig.clear(); + BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // Various undefined version >1 32-byte witness programs. + const auto program{ToByteVector(XOnlyPubKey{pubkey})}; + for (int i{2}; i <= 16; ++i) { + tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessUnknown{i, program}); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_UNKNOWN); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + + // It's also detected within P2SH. + redeem_script = tx_create.vout[0].scriptPubKey; + tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script)); + BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH); + tx_spend.vin[0].prevout.hash = tx_create.GetHash(); + tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script); + AddCoins(coins, CTransaction{tx_create}, 0, false); + BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + tx_spend.vin[0].scriptSig.clear(); + BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins)); + } +} + BOOST_AUTO_TEST_SUITE_END() From 020ed613bed1148888692cb37e3522202bfca44e Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 30 Jul 2025 15:56:57 -0400 Subject: [PATCH 223/314] validation: detect witness stripping without re-running Script checks Since it was introduced in 4eb515574e1012bc8ea5dafc3042dcdf4c766f26 (#18044), the detection of a stripped witness relies on running the Script checks 3 times. In the worst case, this consists in running Script validation 3 times for every single input. Detection of a stripped witness is necessary because in this case wtxid==txid, and the transaction's wtxid must not be added to the reject filter or it could allow a malicious peer to interfere with txid-based orphan resolution as used in 1p1c package relay. However it is not necessary to run Script validation to detect a stripped witness (much less so doing it 3 times in a row). There are 3 types of witness program: defined program types (Taproot, P2WPKH, P2WSH), undefined types, and the Pay-to-anchor carve-out. For defined program types, Script validation with an empty witness will always fail (by consensus). For undefined program types, Script validation is always going to fail regardless of the witness (by standardness). For P2A, an empty witness is never going to lead to a failure. Therefore it holds that we can always detect a stripped witness without re-running Script validation. However this might lead to more "false positives" (cases where we return witness stripping for an otherwise invalid transaction) than the existing implementation. For instance a transaction with one P2PKH input with an invalid signature and one P2WPKH input with its witness stripped. The existing implementation would treat it as consensus invalid while the implementation in this commit would always consider it witness stripped. Github-Pull: #33105 Rebased-From: 27aefac42505e9c083fa131d3d7edbec7803f3c0 --- src/validation.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index fde064458dc..36734bc6122 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1236,13 +1236,8 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws) // Check input scripts and signatures. // This is done last to help prevent CPU exhaustion denial-of-service attacks. if (!CheckInputScripts(tx, state, m_view, scriptVerifyFlags, true, false, ws.m_precomputed_txdata, GetValidationCache())) { - // SCRIPT_VERIFY_CLEANSTACK requires SCRIPT_VERIFY_WITNESS, so we - // need to turn both off, and compare against just turning off CLEANSTACK - // to see if the failure is specifically due to witness validation. - TxValidationState state_dummy; // Want reported failures to be from first CheckInputScripts - if (!tx.HasWitness() && CheckInputScripts(tx, state_dummy, m_view, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, false, ws.m_precomputed_txdata, GetValidationCache()) && - !CheckInputScripts(tx, state_dummy, m_view, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, false, ws.m_precomputed_txdata, GetValidationCache())) { - // Only the witness is missing, so the transaction itself may be fine. + // Detect a failure due to a missing witness so that p2p code can handle rejection caching appropriately. + if (!tx.HasWitness() && SpendsNonAnchorWitnessProg(tx, m_view)) { state.Invalid(TxValidationResult::TX_WITNESS_STRIPPED, state.GetRejectReason(), state.GetDebugMessage()); } From 5a0506eea03e423121dd2112c2ba5fb4320022e3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 25 Apr 2025 16:13:25 -0400 Subject: [PATCH 224/314] tests: add sighash caching tests to feature_taproot Github-Pull: #32473 Rebased-From: 9014d4016ad9351cb59b587541895e55f5d589cc --- test/functional/feature_taproot.py | 98 ++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 5 deletions(-) diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py index 4acb7524fba..198bec7df53 100755 --- a/test/functional/feature_taproot.py +++ b/test/functional/feature_taproot.py @@ -71,6 +71,7 @@ OP_PUSHDATA1, OP_RETURN, OP_SWAP, + OP_TUCK, OP_VERIFY, SIGHASH_DEFAULT, SIGHASH_ALL, @@ -171,9 +172,9 @@ def get(ctx, name): ctx[name] = expr return expr.value -def getter(name): +def getter(name, **kwargs): """Return a callable that evaluates name in its passed context.""" - return lambda ctx: get(ctx, name) + return lambda ctx: get({**ctx, **kwargs}, name) def override(expr, **kwargs): """Return a callable that evaluates expr in a modified context.""" @@ -217,6 +218,20 @@ def default_controlblock(ctx): """Default expression for "controlblock": combine leafversion, negflag, pubkey_internal, merklebranch.""" return bytes([get(ctx, "leafversion") + get(ctx, "negflag")]) + get(ctx, "pubkey_internal") + get(ctx, "merklebranch") +def default_scriptcode_suffix(ctx): + """Default expression for "scriptcode_suffix", the actually used portion of the scriptcode.""" + scriptcode = get(ctx, "scriptcode") + codesepnum = get(ctx, "codesepnum") + if codesepnum == -1: + return scriptcode + codeseps = 0 + for (opcode, data, sop_idx) in scriptcode.raw_iter(): + if opcode == OP_CODESEPARATOR: + if codeseps == codesepnum: + return CScript(scriptcode[sop_idx+1:]) + codeseps += 1 + assert False + def default_sigmsg(ctx): """Default expression for "sigmsg": depending on mode, compute BIP341, BIP143, or legacy sigmsg.""" tx = get(ctx, "tx") @@ -236,12 +251,12 @@ def default_sigmsg(ctx): return TaprootSignatureMsg(tx, utxos, hashtype, idx, scriptpath=False, annex=annex) elif mode == "witv0": # BIP143 signature hash - scriptcode = get(ctx, "scriptcode") + scriptcode = get(ctx, "scriptcode_suffix") utxos = get(ctx, "utxos") return SegwitV0SignatureMsg(scriptcode, tx, idx, hashtype, utxos[idx].nValue) else: # Pre-segwit signature hash - scriptcode = get(ctx, "scriptcode") + scriptcode = get(ctx, "scriptcode_suffix") return LegacySignatureMsg(scriptcode, tx, idx, hashtype)[0] def default_sighash(ctx): @@ -301,7 +316,12 @@ def default_hashtype_actual(ctx): def default_bytes_hashtype(ctx): """Default expression for "bytes_hashtype": bytes([hashtype_actual]) if not 0, b"" otherwise.""" - return bytes([x for x in [get(ctx, "hashtype_actual")] if x != 0]) + mode = get(ctx, "mode") + hashtype_actual = get(ctx, "hashtype_actual") + if mode != "taproot" or hashtype_actual != 0: + return bytes([hashtype_actual]) + else: + return bytes() def default_sign(ctx): """Default expression for "sign": concatenation of signature and bytes_hashtype.""" @@ -379,6 +399,8 @@ def default_scriptsig(ctx): "key_tweaked": default_key_tweaked, # The tweak to use (None for script path spends, the actual tweak for key path spends). "tweak": default_tweak, + # The part of the scriptcode after the last executed OP_CODESEPARATOR. + "scriptcode_suffix": default_scriptcode_suffix, # The sigmsg value (preimage of sighash) "sigmsg": default_sigmsg, # The sighash value (32 bytes) @@ -409,6 +431,8 @@ def default_scriptsig(ctx): "annex": None, # The codeseparator position (only when mode=="taproot"). "codeseppos": -1, + # Which OP_CODESEPARATOR is the last executed one in the script (in legacy/P2SH/P2WSH). + "codesepnum": -1, # The redeemscript to add to the scriptSig (if P2SH; None implies not P2SH). "script_p2sh": None, # The script to add to the witness in (if P2WSH; None implies P2WPKH) @@ -1210,6 +1234,70 @@ def predict_sigops_ratio(n, dummy_size): standard = hashtype in VALID_SIGHASHES_ECDSA and (p2sh or witv0) add_spender(spenders, "compat/nocsa", hashtype=hashtype, p2sh=p2sh, witv0=witv0, standard=standard, script=CScript([OP_IF, OP_11, pubkey1, OP_CHECKSIGADD, OP_12, OP_EQUAL, OP_ELSE, pubkey1, OP_CHECKSIG, OP_ENDIF]), key=eckey1, sigops_weight=4-3*witv0, inputs=[getter("sign"), b''], failure={"inputs": [getter("sign"), b'\x01']}, **ERR_UNDECODABLE) + # == sighash caching tests == + + # Sighash caching in legacy. + for p2sh in [False, True]: + for witv0 in [False, True]: + eckey1, pubkey1 = generate_keypair(compressed=compressed) + for _ in range(10): + # Construct a script with 20 checksig operations (10 sighash types, each 2 times), + # randomly ordered and interleaved with 4 OP_CODESEPARATORS. + ops = [1, 2, 3, 0x21, 0x42, 0x63, 0x81, 0x83, 0xe1, 0xc2, -1, -1] * 2 + # Make sure no OP_CODESEPARATOR appears last. + while True: + random.shuffle(ops) + if ops[-1] != -1: + break + script = [pubkey1] + inputs = [] + codeseps = -1 + for pos, op in enumerate(ops): + if op == -1: + codeseps += 1 + script.append(OP_CODESEPARATOR) + elif pos + 1 != len(ops): + script += [OP_TUCK, OP_CHECKSIGVERIFY] + inputs.append(getter("sign", codesepnum=codeseps, hashtype=op)) + else: + script += [OP_CHECKSIG] + inputs.append(getter("sign", codesepnum=codeseps, hashtype=op)) + inputs.reverse() + script = CScript(script) + add_spender(spenders, "sighashcache/legacy", p2sh=p2sh, witv0=witv0, standard=False, script=script, inputs=inputs, key=eckey1, sigops_weight=12*8*(4-3*witv0), no_fail=True) + + # Sighash caching in tapscript. + for _ in range(10): + # Construct a script with 700 checksig operations (7 sighash types, each 100 times), + # randomly ordered and interleaved with 100 OP_CODESEPARATORS. + ops = [0, 1, 2, 3, 0x81, 0x82, 0x83, -1] * 100 + # Make sure no OP_CODESEPARATOR appears last. + while True: + random.shuffle(ops) + if ops[-1] != -1: + break + script = [pubs[1]] + inputs = [] + opcount = 1 + codeseppos = -1 + for pos, op in enumerate(ops): + if op == -1: + codeseppos = opcount + opcount += 1 + script.append(OP_CODESEPARATOR) + elif pos + 1 != len(ops): + opcount += 2 + script += [OP_TUCK, OP_CHECKSIGVERIFY] + inputs.append(getter("sign", codeseppos=codeseppos, hashtype=op)) + else: + opcount += 1 + script += [OP_CHECKSIG] + inputs.append(getter("sign", codeseppos=codeseppos, hashtype=op)) + inputs.reverse() + script = CScript(script) + tap = taproot_construct(pubs[0], [("leaf", script)]) + add_spender(spenders, "sighashcache/taproot", tap=tap, leaf="leaf", inputs=inputs, standard=True, key=secs[1], no_fail=True) + return spenders From 354d46bc10c61c45140be7a425c5c29fed934d32 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 25 Apr 2025 13:11:30 -0400 Subject: [PATCH 225/314] script: (refactor) prepare for introducing sighash midstate cache Github-Pull: #32473 Rebased-From: 8f3ddb0bccebc930836b4a6745a7cf29b41eb302 --- src/script/interpreter.cpp | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index a35306b6935..0e304973a98 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1569,6 +1569,18 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn { assert(nIn < txTo.vin.size()); + if (sigversion != SigVersion::WITNESS_V0) { + // Check for invalid use of SIGHASH_SINGLE + if ((nHashType & 0x1f) == SIGHASH_SINGLE) { + if (nIn >= txTo.vout.size()) { + // nOut out of range + return uint256::ONE; + } + } + } + + HashWriter ss{}; + if (sigversion == SigVersion::WITNESS_V0) { uint256 hashPrevouts; uint256 hashSequence; @@ -1583,16 +1595,14 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn hashSequence = cacheready ? cache->hashSequence : SHA256Uint256(GetSequencesSHA256(txTo)); } - if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { hashOutputs = cacheready ? cache->hashOutputs : SHA256Uint256(GetOutputsSHA256(txTo)); } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { - HashWriter ss{}; - ss << txTo.vout[nIn]; - hashOutputs = ss.GetHash(); + HashWriter inner_ss{}; + inner_ss << txTo.vout[nIn]; + hashOutputs = inner_ss.GetHash(); } - HashWriter ss{}; // Version ss << txTo.version; // Input prevouts/nSequence (none/all, depending on flags) @@ -1609,26 +1619,16 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn ss << hashOutputs; // Locktime ss << txTo.nLockTime; - // Sighash type - ss << nHashType; - - return ss.GetHash(); - } + } else { + // Wrapper to serialize only the necessary parts of the transaction being signed + CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType); - // Check for invalid use of SIGHASH_SINGLE - if ((nHashType & 0x1f) == SIGHASH_SINGLE) { - if (nIn >= txTo.vout.size()) { - // nOut out of range - return uint256::ONE; - } + // Serialize + ss << txTmp; } - // Wrapper to serialize only the necessary parts of the transaction being signed - CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType); - - // Serialize and hash - HashWriter ss{}; - ss << txTmp << nHashType; + // Add sighash type and hash. + ss << nHashType; return ss.GetHash(); } From ddfb9150b80c0c692c06b91cefa988c7773b15ff Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 25 Apr 2025 13:31:18 -0400 Subject: [PATCH 226/314] script: (optimization) introduce sighash midstate caching Github-Pull: #32473 Rebased-From: 92af9f74d74e76681f7d98f293eab226972137b4 --- src/script/interpreter.cpp | 43 ++++++++++++++++++++++++++++++++++++-- src/script/interpreter.h | 22 ++++++++++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 0e304973a98..4b7bfcedc6c 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1564,8 +1564,35 @@ bool SignatureHashSchnorr(uint256& hash_out, ScriptExecutionData& execdata, cons return true; } +int SigHashCache::CacheIndex(int32_t hash_type) const noexcept +{ + // Note that we do not distinguish between BASE and WITNESS_V0 to determine the cache index, + // because no input can simultaneously use both. + return 3 * !!(hash_type & SIGHASH_ANYONECANPAY) + + 2 * ((hash_type & 0x1f) == SIGHASH_SINGLE) + + 1 * ((hash_type & 0x1f) == SIGHASH_NONE); +} + +bool SigHashCache::Load(int32_t hash_type, const CScript& script_code, HashWriter& writer) const noexcept +{ + auto& entry = m_cache_entries[CacheIndex(hash_type)]; + if (entry.has_value()) { + if (script_code == entry->first) { + writer = HashWriter(entry->second); + return true; + } + } + return false; +} + +void SigHashCache::Store(int32_t hash_type, const CScript& script_code, const HashWriter& writer) noexcept +{ + auto& entry = m_cache_entries[CacheIndex(hash_type)]; + entry.emplace(script_code, writer); +} + template -uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int32_t nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache) +uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int32_t nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache, SigHashCache* sighash_cache) { assert(nIn < txTo.vin.size()); @@ -1581,6 +1608,13 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn HashWriter ss{}; + // Try to compute using cached SHA256 midstate. + if (sighash_cache && sighash_cache->Load(nHashType, scriptCode, ss)) { + // Add sighash type and hash. + ss << nHashType; + return ss.GetHash(); + } + if (sigversion == SigVersion::WITNESS_V0) { uint256 hashPrevouts; uint256 hashSequence; @@ -1627,6 +1661,11 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn ss << txTmp; } + // If a cache object was provided, store the midstate there. + if (sighash_cache != nullptr) { + sighash_cache->Store(nHashType, scriptCode, ss); + } + // Add sighash type and hash. ss << nHashType; return ss.GetHash(); @@ -1661,7 +1700,7 @@ bool GenericTransactionSignatureChecker::CheckECDSASignature(const std::vecto // Witness sighashes need the amount. if (sigversion == SigVersion::WITNESS_V0 && amount < 0) return HandleMissingData(m_mdb); - uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata); + uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata, &m_sighash_cache); if (!VerifyECDSASignature(vchSig, pubkey, sighash)) return false; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index e2fb1998f0b..d613becb8f6 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -239,8 +239,27 @@ extern const HashWriter HASHER_TAPSIGHASH; //!< Hasher with tag "TapSighash" pre extern const HashWriter HASHER_TAPLEAF; //!< Hasher with tag "TapLeaf" pre-fed to it. extern const HashWriter HASHER_TAPBRANCH; //!< Hasher with tag "TapBranch" pre-fed to it. +/** Data structure to cache SHA256 midstates for the ECDSA sighash calculations + * (bare, P2SH, P2WPKH, P2WSH). */ +class SigHashCache +{ + /** For each sighash mode (ALL, SINGLE, NONE, ALL|ANYONE, SINGLE|ANYONE, NONE|ANYONE), + * optionally store a scriptCode which the hash is for, plus a midstate for the SHA256 + * computation just before adding the hash_type itself. */ + std::optional> m_cache_entries[6]; + + /** Given a hash_type, find which of the 6 cache entries is to be used. */ + int CacheIndex(int32_t hash_type) const noexcept; + +public: + /** Load into writer the SHA256 midstate if found in this cache. */ + [[nodiscard]] bool Load(int32_t hash_type, const CScript& script_code, HashWriter& writer) const noexcept; + /** Store into this cache object the provided SHA256 midstate. */ + void Store(int32_t hash_type, const CScript& script_code, const HashWriter& writer) noexcept; +}; + template -uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int32_t nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr); +uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int32_t nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr, SigHashCache* sighash_cache = nullptr); class BaseSignatureChecker { @@ -289,6 +308,7 @@ class GenericTransactionSignatureChecker : public BaseSignatureChecker unsigned int nIn; const CAmount amount; const PrecomputedTransactionData* txdata; + mutable SigHashCache m_sighash_cache; protected: virtual bool VerifyECDSASignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; From 73d3ab8fc93119f14f72a6c5f3cdd9eedcb36a20 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Tue, 22 Jul 2025 18:40:23 -0400 Subject: [PATCH 227/314] qa: simple differential fuzzing for sighash with/without caching Github-Pull: #32473 Rebased-From: b221aa80a081579b8d3b460e3403f7ac0daa7139 --- src/test/fuzz/script_interpreter.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/test/fuzz/script_interpreter.cpp b/src/test/fuzz/script_interpreter.cpp index 9e3ad02b2e5..2c2ce855d47 100644 --- a/src/test/fuzz/script_interpreter.cpp +++ b/src/test/fuzz/script_interpreter.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -45,3 +46,27 @@ FUZZ_TARGET(script_interpreter) (void)CastToBool(ConsumeRandomLengthByteVector(fuzzed_data_provider)); } } + +/** Differential fuzzing for SignatureHash with and without cache. */ +FUZZ_TARGET(sighash_cache) +{ + FuzzedDataProvider provider(buffer.data(), buffer.size()); + + // Get inputs to the sighash function that won't change across types. + const auto scriptcode{ConsumeScript(provider)}; + const auto tx{ConsumeTransaction(provider, std::nullopt)}; + if (tx.vin.empty()) return; + const auto in_index{provider.ConsumeIntegralInRange(0, tx.vin.size() - 1)}; + const auto amount{ConsumeMoney(provider)}; + const auto sigversion{(SigVersion)provider.ConsumeIntegralInRange(0, 1)}; + + // Check the sighash function will give the same result for 100 fuzzer-generated hash types whether or not a cache is + // provided. The cache is conserved across types to exercise cache hits. + SigHashCache sighash_cache{}; + for (int i{0}; i < 100; ++i) { + const auto hash_type{((i & 2) == 0) ? provider.ConsumeIntegral() : provider.ConsumeIntegral()}; + const auto nocache_res{SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion)}; + const auto cache_res{SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &sighash_cache)}; + Assert(nocache_res == cache_res); + } +} From f24291bd96f92ecc0fc04317fd93747eeb2d557a Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Tue, 22 Jul 2025 11:23:16 -0400 Subject: [PATCH 228/314] qa: unit test sighash caching Github-Pull: #32473 Rebased-From: 83950275eddacac56c58a7a3648ed435a5593328 --- src/test/sighash_tests.cpp | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index d3320878ec0..6e2ec800e74 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -207,4 +207,94 @@ BOOST_AUTO_TEST_CASE(sighash_from_data) BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest); } } + +BOOST_AUTO_TEST_CASE(sighash_caching) +{ + // Get a script, transaction and parameters as inputs to the sighash function. + CScript scriptcode; + RandomScript(scriptcode); + CScript diff_scriptcode{scriptcode}; + diff_scriptcode << OP_1; + CMutableTransaction tx; + RandomTransaction(tx, /*fSingle=*/false); + const auto in_index{static_cast(m_rng.randrange(tx.vin.size()))}; + const auto amount{m_rng.rand()}; + + // Exercise the sighash function under both legacy and segwit v0. + for (const auto sigversion: {SigVersion::BASE, SigVersion::WITNESS_V0}) { + // For each, run it against all the 6 standard hash types and a few additional random ones. + std::vector hash_types{{SIGHASH_ALL, SIGHASH_SINGLE, SIGHASH_NONE, SIGHASH_ALL | SIGHASH_ANYONECANPAY, + SIGHASH_SINGLE | SIGHASH_ANYONECANPAY, SIGHASH_NONE | SIGHASH_ANYONECANPAY, + SIGHASH_ANYONECANPAY, 0, std::numeric_limits::max()}}; + for (int i{0}; i < 10; ++i) { + hash_types.push_back(i % 2 == 0 ? m_rng.rand() : m_rng.rand()); + } + + // Reuse the same cache across script types. This must not cause any issue as the cached value for one hash type must never + // be confused for another (instantiating the cache within the loop instead would prevent testing this). + SigHashCache cache; + for (const auto hash_type: hash_types) { + const bool expect_one{sigversion == SigVersion::BASE && ((hash_type & 0x1f) == SIGHASH_SINGLE) && in_index >= tx.vout.size()}; + + // The result of computing the sighash should be the same with or without cache. + const auto sighash_with_cache{SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &cache)}; + const auto sighash_no_cache{SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, nullptr)}; + BOOST_CHECK_EQUAL(sighash_with_cache, sighash_no_cache); + + // Calling the cached version again should return the same value again. + BOOST_CHECK_EQUAL(sighash_with_cache, SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &cache)); + + // While here we might as well also check that the result for legacy is the same as for the old SignatureHash() function. + if (sigversion == SigVersion::BASE) { + BOOST_CHECK_EQUAL(sighash_with_cache, SignatureHashOld(scriptcode, CTransaction(tx), in_index, hash_type)); + } + + // Calling with a different scriptcode (for instance in case a CODESEP is encountered) will not return the cache value but + // overwrite it. The sighash will always be different except in case of legacy SIGHASH_SINGLE bug. + const auto sighash_with_cache2{SignatureHash(diff_scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &cache)}; + const auto sighash_no_cache2{SignatureHash(diff_scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, nullptr)}; + BOOST_CHECK_EQUAL(sighash_with_cache2, sighash_no_cache2); + if (!expect_one) { + BOOST_CHECK_NE(sighash_with_cache, sighash_with_cache2); + } else { + BOOST_CHECK_EQUAL(sighash_with_cache, sighash_with_cache2); + BOOST_CHECK_EQUAL(sighash_with_cache, uint256::ONE); + } + + // Calling the cached version again should return the same value again. + BOOST_CHECK_EQUAL(sighash_with_cache2, SignatureHash(diff_scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &cache)); + + // And if we store a different value for this scriptcode and hash type it will return that instead. + { + HashWriter h{}; + h << 42; + cache.Store(hash_type, scriptcode, h); + const auto stored_hash{h.GetHash()}; + BOOST_CHECK(cache.Load(hash_type, scriptcode, h)); + const auto loaded_hash{h.GetHash()}; + BOOST_CHECK_EQUAL(stored_hash, loaded_hash); + } + + // And using this mutated cache with the sighash function will return the new value (except in the legacy SIGHASH_SINGLE bug + // case in which it'll return 1). + if (!expect_one) { + BOOST_CHECK_NE(SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &cache), sighash_with_cache); + HashWriter h{}; + BOOST_CHECK(cache.Load(hash_type, scriptcode, h)); + h << hash_type; + const auto new_hash{h.GetHash()}; + BOOST_CHECK_EQUAL(SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &cache), new_hash); + } else { + BOOST_CHECK_EQUAL(SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &cache), uint256::ONE); + } + + // Wipe the cache and restore the correct cached value for this scriptcode and hash_type before starting the next iteration. + HashWriter dummy{}; + cache.Store(hash_type, diff_scriptcode, dummy); + (void)SignatureHash(scriptcode, tx, in_index, hash_type, amount, sigversion, nullptr, &cache); + BOOST_CHECK(cache.Load(hash_type, scriptcode, dummy) || expect_one); + } + } +} + BOOST_AUTO_TEST_SUITE_END() From 65bcbbc538234957b1f7f76b2f21ad7c138efb87 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Wed, 23 Jul 2025 10:50:33 +1000 Subject: [PATCH 229/314] net_processing: drop MaybePunishNodeForTx Do not discourage nodes even when they send us consensus invalid transactions. Because we do not discourage nodes for transactions we consider non-standard, we don't get any DoS protection from this check in adversarial scenarios, so remove the check entirely both to simplify the code and reduce the risk of splitting the network due to changes in tx relay policy. NOTE: Backport required additional adjustment in test/functional/p2p_invalid_tx Github-Pull: #33050 Rebased-From: 266dd0e10d08c0bfde63205db15d6c210a021b90 --- src/net_processing.cpp | 34 ----------------------- test/functional/data/invalid_txs.py | 20 ++++++------- test/functional/p2p_invalid_tx.py | 5 ++-- test/functional/p2p_opportunistic_1p1c.py | 6 ++-- 4 files changed, 16 insertions(+), 49 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 1da3ec9d211..b25819c821b 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -553,12 +553,6 @@ class PeerManagerImpl final : public PeerManager bool via_compact_block, const std::string& message = "") EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); - /** - * Potentially disconnect and discourage a node based on the contents of a TxValidationState object - */ - void MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state) - EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); - /** Maybe disconnect a peer and discourage future connections from its address. * * @param[in] pnode The node to check. @@ -1805,32 +1799,6 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati } } -void PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state) -{ - PeerRef peer{GetPeerRef(nodeid)}; - switch (state.GetResult()) { - case TxValidationResult::TX_RESULT_UNSET: - break; - // The node is providing invalid data: - case TxValidationResult::TX_CONSENSUS: - if (peer) Misbehaving(*peer, ""); - return; - // Conflicting (but not necessarily invalid) data or different policy: - case TxValidationResult::TX_INPUTS_NOT_STANDARD: - case TxValidationResult::TX_NOT_STANDARD: - case TxValidationResult::TX_MISSING_INPUTS: - case TxValidationResult::TX_PREMATURE_SPEND: - case TxValidationResult::TX_WITNESS_MUTATED: - case TxValidationResult::TX_WITNESS_STRIPPED: - case TxValidationResult::TX_CONFLICT: - case TxValidationResult::TX_MEMPOOL_POLICY: - case TxValidationResult::TX_NO_MEMPOOL: - case TxValidationResult::TX_RECONSIDERABLE: - case TxValidationResult::TX_UNKNOWN: - break; - } -} - bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex) { AssertLockHeld(cs_main); @@ -2987,8 +2955,6 @@ std::optional PeerManagerImpl::ProcessInvalidTx(NodeId if (peer) AddKnownTx(*peer, parent_txid); } - MaybePunishNodeForTx(nodeid, state); - return package_to_validate; } diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py index d2d7202d860..48ec88fde0d 100644 --- a/test/functional/data/invalid_txs.py +++ b/test/functional/data/invalid_txs.py @@ -89,7 +89,7 @@ def get_tx(self, *args, **kwargs): class OutputMissing(BadTxTemplate): reject_reason = "bad-txns-vout-empty" - expect_disconnect = True + expect_disconnect = False def get_tx(self): tx = CTransaction() @@ -100,7 +100,7 @@ def get_tx(self): class InputMissing(BadTxTemplate): reject_reason = "bad-txns-vin-empty" - expect_disconnect = True + expect_disconnect = False # We use a blank transaction here to make sure # it is interpreted as a non-witness transaction. @@ -149,7 +149,7 @@ def get_tx(self): class DuplicateInput(BadTxTemplate): reject_reason = 'bad-txns-inputs-duplicate' - expect_disconnect = True + expect_disconnect = False def get_tx(self): tx = CTransaction() @@ -162,7 +162,7 @@ def get_tx(self): class PrevoutNullInput(BadTxTemplate): reject_reason = 'bad-txns-prevout-null' - expect_disconnect = True + expect_disconnect = False def get_tx(self): tx = CTransaction() @@ -188,7 +188,7 @@ def get_tx(self): class SpendTooMuch(BadTxTemplate): reject_reason = 'bad-txns-in-belowout' - expect_disconnect = True + expect_disconnect = False def get_tx(self): return create_tx_with_script( @@ -197,7 +197,7 @@ def get_tx(self): class CreateNegative(BadTxTemplate): reject_reason = 'bad-txns-vout-negative' - expect_disconnect = True + expect_disconnect = False def get_tx(self): return create_tx_with_script(self.spend_tx, 0, amount=-1) @@ -205,7 +205,7 @@ def get_tx(self): class CreateTooLarge(BadTxTemplate): reject_reason = 'bad-txns-vout-toolarge' - expect_disconnect = True + expect_disconnect = False def get_tx(self): return create_tx_with_script(self.spend_tx, 0, amount=MAX_MONEY + 1) @@ -213,7 +213,7 @@ def get_tx(self): class CreateSumTooLarge(BadTxTemplate): reject_reason = 'bad-txns-txouttotal-toolarge' - expect_disconnect = True + expect_disconnect = False def get_tx(self): tx = create_tx_with_script(self.spend_tx, 0, amount=MAX_MONEY) @@ -224,7 +224,7 @@ def get_tx(self): class InvalidOPIFConstruction(BadTxTemplate): reject_reason = "mandatory-script-verify-flag-failed (Invalid OP_IF construction)" - expect_disconnect = True + expect_disconnect = False valid_in_block = True def get_tx(self): @@ -266,7 +266,7 @@ def get_tx(self): class NonStandardAndInvalid(BadTxTemplate): """A non-standard transaction which is also consensus-invalid should return the consensus error.""" reject_reason = "mandatory-script-verify-flag-failed (OP_RETURN was encountered)" - expect_disconnect = True + expect_disconnect = False valid_in_block = False def get_tx(self): diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py index ee8c6c16ca3..3785f725fef 100755 --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -73,7 +73,7 @@ def run_test(self): tx = template.get_tx() node.p2ps[0].send_txs_and_test( [tx], node, success=False, - expect_disconnect=template.expect_disconnect, + expect_disconnect=False, reject_reason=template.reject_reason, ) @@ -144,7 +144,6 @@ def run_test(self): # tx_orphan_2_no_fee, because it has too low fee (p2ps[0] is not disconnected for relaying that tx) # tx_orphan_2_invalid, because it has negative fee (p2ps[1] is disconnected for relaying that tx) - self.wait_until(lambda: 1 == len(node.getpeerinfo()), timeout=12) # p2ps[1] is no longer connected assert_equal(expected_mempool, set(node.getrawmempool())) self.log.info('Test orphan pool overflow') @@ -165,7 +164,7 @@ def run_test(self): node.p2ps[0].send_txs_and_test([rejected_parent], node, success=False) self.log.info('Test that a peer disconnection causes erase its transactions from the orphan pool') - with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=26']): + with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=']): self.reconnect_p2p(num_connections=1) self.log.info('Test that a transaction in the orphan pool is included in a new tip block causes erase this transaction from the orphan pool') diff --git a/test/functional/p2p_opportunistic_1p1c.py b/test/functional/p2p_opportunistic_1p1c.py index 5fdbf74a573..def70b733a6 100755 --- a/test/functional/p2p_opportunistic_1p1c.py +++ b/test/functional/p2p_opportunistic_1p1c.py @@ -251,8 +251,10 @@ def test_orphan_consensus_failure(self): assert tx_orphan_bad_wit.rehash() not in node_mempool # 5. Have the other peer send the tx too, so that tx_orphan_bad_wit package is attempted. - bad_orphan_sender.send_message(msg_tx(low_fee_parent["tx"])) - bad_orphan_sender.wait_for_disconnect() + bad_orphan_sender.send_and_ping(msg_tx(low_fee_parent["tx"])) + + # The bad orphan sender should not be disconnected. + bad_orphan_sender.sync_with_ping() # The peer that didn't provide the orphan should not be disconnected. parent_sender.sync_with_ping() From be0857745a5a0154d89a2aa9ddaa2a84e912598a Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Wed, 23 Jul 2025 10:51:06 +1000 Subject: [PATCH 230/314] validation: only check input scripts once Previously, we would check failing input scripts twice when considering a transaction for the mempool, in order to distinguish policy failures from consensus failures. This allowed us both to provide a different error message and to discourage peers for consensus failures. Because we are no longer discouraging peers for consensus failures during tx relay, and because checking a script can be expensive, only do this once. Also renames non-mandatory-script-verify-flag error to mempool-script-verify-flag-failed. NOTE: Backport required additional adjustment in test/functional/feature_block Github-Pull: #33050 Rebased-From: b29ae9efdfeeff774e32ee433ce67d8ed8ecd49f --- src/validation.cpp | 35 +++++++--------------------- test/functional/data/invalid_txs.py | 7 +++--- test/functional/feature_block.py | 5 +++- test/functional/feature_cltv.py | 18 +++++++------- test/functional/feature_dersig.py | 4 ++-- test/functional/feature_nulldummy.py | 12 +++++----- test/functional/feature_segwit.py | 24 +++++++++---------- test/functional/mempool_accept.py | 2 +- test/functional/p2p_segwit.py | 14 +++++------ test/functional/rpc_packages.py | 4 ++-- 10 files changed, 57 insertions(+), 68 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 36734bc6122..ebeb67ac78a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2207,34 +2207,17 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state, if (pvChecks) { pvChecks->emplace_back(std::move(check)); } else if (auto result = check(); result.has_value()) { + // Tx failures never trigger disconnections/bans. + // This is so that network splits aren't triggered + // either due to non-consensus relay policies (such as + // non-standard DER encodings or non-null dummy + // arguments) or due to new consensus rules introduced in + // soft forks. if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) { - // Check whether the failure was caused by a - // non-mandatory script verification check, such as - // non-standard DER encodings or non-null dummy - // arguments; if so, ensure we return NOT_STANDARD - // instead of CONSENSUS to avoid downstream users - // splitting the network between upgraded and - // non-upgraded nodes by banning CONSENSUS-failing - // data providers. - CScriptCheck check2(txdata.m_spent_outputs[i], tx, validation_cache.m_signature_cache, i, - flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata); - auto mandatory_result = check2(); - if (!mandatory_result.has_value()) { - return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(result->first)), result->second); - } else { - // If the second check failed, it failed due to a mandatory script verification - // flag, but the first check might have failed on a non-mandatory script - // verification flag. - // - // Avoid reporting a mandatory script check failure with a non-mandatory error - // string by reporting the error from the second check. - result = mandatory_result; - } + return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("mempool-script-verify-flag-failed (%s)", ScriptErrorString(result->first)), result->second); + } else { + return state.Invalid(TxValidationResult::TX_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(result->first)), result->second); } - - // MANDATORY flag failures correspond to - // TxValidationResult::TX_CONSENSUS. - return state.Invalid(TxValidationResult::TX_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(result->first)), result->second); } } diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py index 48ec88fde0d..bb1931be2df 100644 --- a/test/functional/data/invalid_txs.py +++ b/test/functional/data/invalid_txs.py @@ -223,7 +223,7 @@ def get_tx(self): class InvalidOPIFConstruction(BadTxTemplate): - reject_reason = "mandatory-script-verify-flag-failed (Invalid OP_IF construction)" + reject_reason = "mempool-script-verify-flag-failed (Invalid OP_IF construction)" expect_disconnect = False valid_in_block = True @@ -264,8 +264,9 @@ def get_tx(self): }) class NonStandardAndInvalid(BadTxTemplate): - """A non-standard transaction which is also consensus-invalid should return the consensus error.""" - reject_reason = "mandatory-script-verify-flag-failed (OP_RETURN was encountered)" + """A non-standard transaction which is also consensus-invalid should return the first error.""" + reject_reason = "mempool-script-verify-flag-failed (Using OP_CODESEPARATOR in non-witness script)" + block_reject_reason = "mandatory-script-verify-flag-failed (OP_RETURN was encountered)" expect_disconnect = False valid_in_block = False diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py index 2dfa568c5b6..222b2387853 100755 --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -164,9 +164,12 @@ def run_test(self): self.sign_tx(badtx, attempt_spend_tx) badtx.rehash() badblock = self.update_block(blockname, [badtx]) + reject_reason = (template.block_reject_reason or template.reject_reason) + if reject_reason and reject_reason.startswith("mempool-script-verify-flag-failed"): + reject_reason = "mandatory-script-verify-flag-failed" + reject_reason[33:] self.send_blocks( [badblock], success=False, - reject_reason=(template.block_reject_reason or template.reject_reason), + reject_reason=reject_reason, reconnect=True, timeout=2) self.move_tip(2) diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py index 60b3fb4e20b..81cc10a5adf 100755 --- a/test/functional/feature_cltv.py +++ b/test/functional/feature_cltv.py @@ -154,12 +154,14 @@ def run_test(self): coin_vout = coin.prevout.n cltv_invalidate(spendtx, i) + blk_rej = "mandatory-script-verify-flag-failed" + tx_rej = "mempool-script-verify-flag-failed" expected_cltv_reject_reason = [ - "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", - "mandatory-script-verify-flag-failed (Negative locktime)", - "mandatory-script-verify-flag-failed (Locktime requirement not satisfied)", - "mandatory-script-verify-flag-failed (Locktime requirement not satisfied)", - "mandatory-script-verify-flag-failed (Locktime requirement not satisfied)", + " (Operation not valid with the current stack size)", + " (Negative locktime)", + " (Locktime requirement not satisfied)", + " (Locktime requirement not satisfied)", + " (Locktime requirement not satisfied)", ][i] # First we show that this tx is valid except for CLTV by getting it # rejected from the mempool for exactly that reason. @@ -170,8 +172,8 @@ def run_test(self): 'txid': spendtx_txid, 'wtxid': spendtx_wtxid, 'allowed': False, - 'reject-reason': expected_cltv_reject_reason, - 'reject-details': expected_cltv_reject_reason + f", input 0 of {spendtx_txid} (wtxid {spendtx_wtxid}), spending {coin_txid}:{coin_vout}" + 'reject-reason': tx_rej + expected_cltv_reject_reason, + 'reject-details': tx_rej + expected_cltv_reject_reason + f", input 0 of {spendtx_txid} (wtxid {spendtx_wtxid}), spending {coin_txid}:{coin_vout}" }], self.nodes[0].testmempoolaccept(rawtxs=[spendtx.serialize().hex()], maxfeerate=0), ) @@ -181,7 +183,7 @@ def run_test(self): block.hashMerkleRoot = block.calc_merkle_root() block.solve() - with self.nodes[0].assert_debug_log(expected_msgs=[f'Block validation error: {expected_cltv_reject_reason}']): + with self.nodes[0].assert_debug_log(expected_msgs=[f'Block validation error: {blk_rej + expected_cltv_reject_reason}']): peer.send_and_ping(msg_block(block)) assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) peer.sync_with_ping() diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py index 0c3b0f12243..2a7eb0d0f47 100755 --- a/test/functional/feature_dersig.py +++ b/test/functional/feature_dersig.py @@ -123,8 +123,8 @@ def run_test(self): 'txid': spendtx_txid, 'wtxid': spendtx_wtxid, 'allowed': False, - 'reject-reason': 'mandatory-script-verify-flag-failed (Non-canonical DER signature)', - 'reject-details': 'mandatory-script-verify-flag-failed (Non-canonical DER signature), ' + + 'reject-reason': 'mempool-script-verify-flag-failed (Non-canonical DER signature)', + 'reject-details': 'mempool-script-verify-flag-failed (Non-canonical DER signature), ' + f"input 0 of {spendtx_txid} (wtxid {spendtx_wtxid}), spending {coin_txid}:0" }], self.nodes[0].testmempoolaccept(rawtxs=[spendtx.serialize().hex()], maxfeerate=0), diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py index 885bc4855b0..e7fe7d65e48 100755 --- a/test/functional/feature_nulldummy.py +++ b/test/functional/feature_nulldummy.py @@ -37,8 +37,8 @@ from test_framework.wallet import getnewdestination from test_framework.wallet_util import generate_keypair -NULLDUMMY_ERROR = "mandatory-script-verify-flag-failed (Dummy CHECKMULTISIG argument must be zero)" - +NULLDUMMY_TX_ERROR = "mempool-script-verify-flag-failed (Dummy CHECKMULTISIG argument must be zero)" +NULLDUMMY_BLK_ERROR = "mandatory-script-verify-flag-failed (Dummy CHECKMULTISIG argument must be zero)" def invalidate_nulldummy_tx(tx): """Transform a NULLDUMMY compliant tx (i.e. scriptSig starts with OP_0) @@ -105,7 +105,7 @@ def run_test(self): addr=self.ms_address, amount=47, privkey=self.privkey) invalidate_nulldummy_tx(test2tx) - assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test2tx.serialize_with_witness().hex(), 0) + assert_raises_rpc_error(-26, NULLDUMMY_TX_ERROR, self.nodes[0].sendrawtransaction, test2tx.serialize_with_witness().hex(), 0) self.log.info(f"Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [{COINBASE_MATURITY + 4}]") self.block_submit(self.nodes[0], [test2tx], accept=True) @@ -116,7 +116,7 @@ def run_test(self): privkey=self.privkey) test6txs = [CTransaction(test4tx)] invalidate_nulldummy_tx(test4tx) - assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test4tx.serialize_with_witness().hex(), 0) + assert_raises_rpc_error(-26, NULLDUMMY_TX_ERROR, self.nodes[0].sendrawtransaction, test4tx.serialize_with_witness().hex(), 0) self.block_submit(self.nodes[0], [test4tx], accept=False) self.log.info("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation") @@ -126,7 +126,7 @@ def run_test(self): privkey=self.privkey) test6txs.append(CTransaction(test5tx)) test5tx.wit.vtxinwit[0].scriptWitness.stack[0] = b'\x01' - assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test5tx.serialize_with_witness().hex(), 0) + assert_raises_rpc_error(-26, NULLDUMMY_TX_ERROR, self.nodes[0].sendrawtransaction, test5tx.serialize_with_witness().hex(), 0) self.block_submit(self.nodes[0], [test5tx], with_witness=True, accept=False) self.log.info(f"Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [{COINBASE_MATURITY + 5}]") @@ -142,7 +142,7 @@ def block_submit(self, node, txs, *, with_witness=False, accept): if with_witness: add_witness_commitment(block) block.solve() - assert_equal(None if accept else NULLDUMMY_ERROR, node.submitblock(block.serialize().hex())) + assert_equal(None if accept else NULLDUMMY_BLK_ERROR, node.submitblock(block.serialize().hex())) if accept: assert_equal(node.getbestblockhash(), block.hash) self.lastblockhash = block.hash diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py index f98f326e8f4..cc664a83aa3 100755 --- a/test/functional/feature_segwit.py +++ b/test/functional/feature_segwit.py @@ -193,8 +193,8 @@ def run_test(self): assert_equal(self.nodes[2].getbalance(), 20 * Decimal("49.999")) self.log.info("Verify unsigned p2sh witness txs without a redeem script are invalid") - self.fail_accept(self.nodes[2], "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_2][P2WPKH][1], sign=False) - self.fail_accept(self.nodes[2], "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_2][P2WSH][1], sign=False) + self.fail_accept(self.nodes[2], "mempool-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_2][P2WPKH][1], sign=False) + self.fail_accept(self.nodes[2], "mempool-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_2][P2WSH][1], sign=False) self.generate(self.nodes[0], 1) # block 164 @@ -213,13 +213,13 @@ def run_test(self): self.log.info("Verify default node can't accept txs with missing witness") # unsigned, no scriptsig - self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Witness program hash mismatch)", wit_ids[NODE_0][P2WPKH][0], sign=False) - self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Witness program was passed an empty witness)", wit_ids[NODE_0][P2WSH][0], sign=False) - self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_0][P2WPKH][0], sign=False) - self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_0][P2WSH][0], sign=False) + self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Witness program hash mismatch)", wit_ids[NODE_0][P2WPKH][0], sign=False) + self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Witness program was passed an empty witness)", wit_ids[NODE_0][P2WSH][0], sign=False) + self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_0][P2WPKH][0], sign=False) + self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_0][P2WSH][0], sign=False) # unsigned with redeem script - self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Witness program hash mismatch)", p2sh_ids[NODE_0][P2WPKH][0], sign=False, redeem_script=witness_script(False, self.pubkey[0])) - self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Witness program was passed an empty witness)", p2sh_ids[NODE_0][P2WSH][0], sign=False, redeem_script=witness_script(True, self.pubkey[0])) + self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Witness program hash mismatch)", p2sh_ids[NODE_0][P2WPKH][0], sign=False, redeem_script=witness_script(False, self.pubkey[0])) + self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Witness program was passed an empty witness)", p2sh_ids[NODE_0][P2WSH][0], sign=False, redeem_script=witness_script(True, self.pubkey[0])) # Coinbase contains the witness commitment nonce, check that RPC shows us coinbase_txid = self.nodes[2].getblock(blockhash)['tx'][0] @@ -230,10 +230,10 @@ def run_test(self): assert_equal(witnesses[0], '00' * 32) self.log.info("Verify witness txs without witness data are invalid after the fork") - self.fail_accept(self.nodes[2], 'mandatory-script-verify-flag-failed (Witness program hash mismatch)', wit_ids[NODE_2][P2WPKH][2], sign=False) - self.fail_accept(self.nodes[2], 'mandatory-script-verify-flag-failed (Witness program was passed an empty witness)', wit_ids[NODE_2][P2WSH][2], sign=False) - self.fail_accept(self.nodes[2], 'mandatory-script-verify-flag-failed (Witness program hash mismatch)', p2sh_ids[NODE_2][P2WPKH][2], sign=False, redeem_script=witness_script(False, self.pubkey[2])) - self.fail_accept(self.nodes[2], 'mandatory-script-verify-flag-failed (Witness program was passed an empty witness)', p2sh_ids[NODE_2][P2WSH][2], sign=False, redeem_script=witness_script(True, self.pubkey[2])) + self.fail_accept(self.nodes[2], 'mempool-script-verify-flag-failed (Witness program hash mismatch)', wit_ids[NODE_2][P2WPKH][2], sign=False) + self.fail_accept(self.nodes[2], 'mempool-script-verify-flag-failed (Witness program was passed an empty witness)', wit_ids[NODE_2][P2WSH][2], sign=False) + self.fail_accept(self.nodes[2], 'mempool-script-verify-flag-failed (Witness program hash mismatch)', p2sh_ids[NODE_2][P2WPKH][2], sign=False, redeem_script=witness_script(False, self.pubkey[2])) + self.fail_accept(self.nodes[2], 'mempool-script-verify-flag-failed (Witness program was passed an empty witness)', p2sh_ids[NODE_2][P2WSH][2], sign=False, redeem_script=witness_script(True, self.pubkey[2])) self.log.info("Verify default node can now use witness txs") self.success_mine(self.nodes[0], wit_ids[NODE_0][P2WPKH][0], True) diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py index 2155b8de6b1..32d8f7f6eac 100755 --- a/test/functional/mempool_accept.py +++ b/test/functional/mempool_accept.py @@ -441,7 +441,7 @@ def run_test(self): nested_anchor_spend.rehash() self.check_mempool_result( - result_expected=[{'txid': nested_anchor_spend.rehash(), 'allowed': False, 'reject-reason': 'non-mandatory-script-verify-flag (Witness version reserved for soft-fork upgrades)'}], + result_expected=[{'txid': nested_anchor_spend.rehash(), 'allowed': False, 'reject-reason': 'mempool-script-verify-flag-failed (Witness version reserved for soft-fork upgrades)'}], rawtxs=[nested_anchor_spend.serialize().hex()], maxfeerate=0, ) diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py index e8f7f7e0f4e..7815d6ea84e 100755 --- a/test/functional/p2p_segwit.py +++ b/test/functional/p2p_segwit.py @@ -704,20 +704,20 @@ def test_p2sh_witness(self): # segwit activation. Note that older bitcoind's that are not # segwit-aware would also reject this for failing CLEANSTACK. with self.nodes[0].assert_debug_log( - expected_msgs=[spend_tx.hash, 'was not accepted: mandatory-script-verify-flag-failed (Witness program was passed an empty witness)']): + expected_msgs=[spend_tx.hash, 'was not accepted: mempool-script-verify-flag-failed (Witness program was passed an empty witness)']): test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False) # The transaction was detected as witness stripped above and not added to the reject # filter. Trying again will check it again and result in the same error. with self.nodes[0].assert_debug_log( - expected_msgs=[spend_tx.hash, 'was not accepted: mandatory-script-verify-flag-failed (Witness program was passed an empty witness)']): + expected_msgs=[spend_tx.hash, 'was not accepted: mempool-script-verify-flag-failed (Witness program was passed an empty witness)']): test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False) # Try to put the witness script in the scriptSig, should also fail. spend_tx.vin[0].scriptSig = CScript([p2wsh_pubkey, b'a']) spend_tx.rehash() with self.nodes[0].assert_debug_log( - expected_msgs=[spend_tx.hash, 'was not accepted: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)']): + expected_msgs=[spend_tx.hash, 'was not accepted: mempool-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)']): test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False) # Now put the witness script in the witness, should succeed after @@ -1291,7 +1291,7 @@ def test_tx_relay_after_segwit_activation(self): # Now do the opposite: strip the witness entirely. This will be detected as witness stripping and # the (w)txid won't be added to the reject filter: we can try again and get the same error. tx3.wit.vtxinwit[0].scriptWitness.stack = [] - reason = "was not accepted: mandatory-script-verify-flag-failed (Witness program was passed an empty witness)" + reason = "was not accepted: mempool-script-verify-flag-failed (Witness program was passed an empty witness)" test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=False, accepted=False, reason=reason) test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=False, accepted=False, reason=reason) @@ -1490,7 +1490,7 @@ def test_uncompressed_pubkey(self): sign_input_segwitv0(tx2, 0, script, tx.vout[0].nValue, key) # Should fail policy test. - test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, 'mempool-script-verify-flag-failed (Using non-compressed keys in segwit)') # But passes consensus. block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx2]) @@ -1509,7 +1509,7 @@ def test_uncompressed_pubkey(self): sign_p2pk_witness_input(witness_script, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key) # Should fail policy test. - test_transaction_acceptance(self.nodes[0], self.test_node, tx3, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + test_transaction_acceptance(self.nodes[0], self.test_node, tx3, True, False, 'mempool-script-verify-flag-failed (Using non-compressed keys in segwit)') # But passes consensus. block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx3]) @@ -1526,7 +1526,7 @@ def test_uncompressed_pubkey(self): sign_p2pk_witness_input(witness_script, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key) # Should fail policy test. - test_transaction_acceptance(self.nodes[0], self.test_node, tx4, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + test_transaction_acceptance(self.nodes[0], self.test_node, tx4, True, False, 'mempool-script-verify-flag-failed (Using non-compressed keys in segwit)') block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx4]) test_witness_block(self.nodes[0], self.test_node, block, accepted=True) diff --git a/test/functional/rpc_packages.py b/test/functional/rpc_packages.py index a2f9210f94d..539e9d09add 100755 --- a/test/functional/rpc_packages.py +++ b/test/functional/rpc_packages.py @@ -122,8 +122,8 @@ def test_independent(self, coin): assert_equal(testres_bad_sig, self.independent_txns_testres + [{ "txid": tx_bad_sig_txid, "wtxid": tx_bad_sig_wtxid, "allowed": False, - "reject-reason": "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", - "reject-details": "mandatory-script-verify-flag-failed (Operation not valid with the current stack size), " + + "reject-reason": "mempool-script-verify-flag-failed (Operation not valid with the current stack size)", + "reject-details": "mempool-script-verify-flag-failed (Operation not valid with the current stack size), " + f"input 0 of {tx_bad_sig_txid} (wtxid {tx_bad_sig_wtxid}), spending {coin['txid']}:{coin['vout']}" }]) From 6f136cd3914b001752cce02adde00fccaed0ad48 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Fri, 8 Aug 2025 23:15:17 +1000 Subject: [PATCH 231/314] tests: drop expect_disconnect behaviour for tx relay Github-Pull: #33050 Rebased-From: 876dbdfb4702410dfd4037614dc9298a0c09c63e --- test/functional/data/invalid_txs.py | 18 ------------------ test/functional/p2p_invalid_tx.py | 5 ----- test/functional/test_framework/p2p.py | 8 ++------ 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py index bb1931be2df..f96059d4ee8 100644 --- a/test/functional/data/invalid_txs.py +++ b/test/functional/data/invalid_txs.py @@ -69,9 +69,6 @@ class BadTxTemplate: # Only specified if it differs from mempool acceptance error. block_reject_reason = "" - # Do we expect to be disconnected after submitting this tx? - expect_disconnect = False - # Is this tx considered valid when included in a block, but not for acceptance into # the mempool (i.e. does it violate policy but not consensus)? valid_in_block = False @@ -89,7 +86,6 @@ def get_tx(self, *args, **kwargs): class OutputMissing(BadTxTemplate): reject_reason = "bad-txns-vout-empty" - expect_disconnect = False def get_tx(self): tx = CTransaction() @@ -100,7 +96,6 @@ def get_tx(self): class InputMissing(BadTxTemplate): reject_reason = "bad-txns-vin-empty" - expect_disconnect = False # We use a blank transaction here to make sure # it is interpreted as a non-witness transaction. @@ -117,7 +112,6 @@ def get_tx(self): # tree depth commitment (CVE-2017-12842) class SizeTooSmall(BadTxTemplate): reject_reason = "tx-size-small" - expect_disconnect = False valid_in_block = True def get_tx(self): @@ -134,7 +128,6 @@ class BadInputOutpointIndex(BadTxTemplate): # Won't be rejected - nonexistent outpoint index is treated as an orphan since the coins # database can't distinguish between spent outpoints and outpoints which never existed. reject_reason = None - expect_disconnect = False def get_tx(self): num_indices = len(self.spend_tx.vin) @@ -149,7 +142,6 @@ def get_tx(self): class DuplicateInput(BadTxTemplate): reject_reason = 'bad-txns-inputs-duplicate' - expect_disconnect = False def get_tx(self): tx = CTransaction() @@ -162,7 +154,6 @@ def get_tx(self): class PrevoutNullInput(BadTxTemplate): reject_reason = 'bad-txns-prevout-null' - expect_disconnect = False def get_tx(self): tx = CTransaction() @@ -175,7 +166,6 @@ def get_tx(self): class NonexistentInput(BadTxTemplate): reject_reason = None # Added as an orphan tx. - expect_disconnect = False def get_tx(self): tx = CTransaction() @@ -188,7 +178,6 @@ def get_tx(self): class SpendTooMuch(BadTxTemplate): reject_reason = 'bad-txns-in-belowout' - expect_disconnect = False def get_tx(self): return create_tx_with_script( @@ -197,7 +186,6 @@ def get_tx(self): class CreateNegative(BadTxTemplate): reject_reason = 'bad-txns-vout-negative' - expect_disconnect = False def get_tx(self): return create_tx_with_script(self.spend_tx, 0, amount=-1) @@ -205,7 +193,6 @@ def get_tx(self): class CreateTooLarge(BadTxTemplate): reject_reason = 'bad-txns-vout-toolarge' - expect_disconnect = False def get_tx(self): return create_tx_with_script(self.spend_tx, 0, amount=MAX_MONEY + 1) @@ -213,7 +200,6 @@ def get_tx(self): class CreateSumTooLarge(BadTxTemplate): reject_reason = 'bad-txns-txouttotal-toolarge' - expect_disconnect = False def get_tx(self): tx = create_tx_with_script(self.spend_tx, 0, amount=MAX_MONEY) @@ -224,7 +210,6 @@ def get_tx(self): class InvalidOPIFConstruction(BadTxTemplate): reject_reason = "mempool-script-verify-flag-failed (Invalid OP_IF construction)" - expect_disconnect = False valid_in_block = True def get_tx(self): @@ -236,7 +221,6 @@ def get_tx(self): class TooManySigops(BadTxTemplate): reject_reason = "bad-txns-too-many-sigops" block_reject_reason = "bad-blk-sigops, out-of-bounds SigOpCount" - expect_disconnect = False def get_tx(self): lotsa_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS)) @@ -258,7 +242,6 @@ def get_tx(self): return type('DisabledOpcode_' + str(opcode), (BadTxTemplate,), { 'reject_reason': "disabled opcode", - 'expect_disconnect': True, 'get_tx': get_tx, 'valid_in_block' : True }) @@ -267,7 +250,6 @@ class NonStandardAndInvalid(BadTxTemplate): """A non-standard transaction which is also consensus-invalid should return the first error.""" reject_reason = "mempool-script-verify-flag-failed (Using OP_CODESEPARATOR in non-witness script)" block_reject_reason = "mandatory-script-verify-flag-failed (OP_RETURN was encountered)" - expect_disconnect = False valid_in_block = False def get_tx(self): diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py index 3785f725fef..439735d178a 100755 --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -73,14 +73,9 @@ def run_test(self): tx = template.get_tx() node.p2ps[0].send_txs_and_test( [tx], node, success=False, - expect_disconnect=False, reject_reason=template.reject_reason, ) - if template.expect_disconnect: - self.log.info("Reconnecting to peer") - self.reconnect_p2p() - # Make two p2p connections to provide the node with orphans # * p2ps[0] will send valid orphan txs (one with low fee) # * p2ps[1] will send an invalid orphan tx (and is later disconnected for that) diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py index 207d19137b1..c5e518238ce 100755 --- a/test/functional/test_framework/p2p.py +++ b/test/functional/test_framework/p2p.py @@ -893,13 +893,12 @@ def send_blocks_and_test(self, blocks, node, *, success=True, force_send=False, else: assert node.getbestblockhash() != blocks[-1].hash - def send_txs_and_test(self, txs, node, *, success=True, expect_disconnect=False, reject_reason=None): + def send_txs_and_test(self, txs, node, *, success=True, reject_reason=None): """Send txs to test node and test whether they're accepted to the mempool. - add all txs to our tx_store - send tx messages for all txs - if success is True/False: assert that the txs are/are not accepted to the mempool - - if expect_disconnect is True: Skip the sync with ping - if reject_reason is set: assert that the correct reject message is logged.""" with p2p_lock: @@ -911,10 +910,7 @@ def send_txs_and_test(self, txs, node, *, success=True, expect_disconnect=False, for tx in txs: self.send_message(msg_tx(tx)) - if expect_disconnect: - self.wait_for_disconnect() - else: - self.sync_with_ping() + self.sync_with_ping() raw_mempool = node.getrawmempool() if success: From 2cf352fd8e6a77003e38d954b6c879b20d4b960a Mon Sep 17 00:00:00 2001 From: will Date: Tue, 14 Oct 2025 13:57:20 +0100 Subject: [PATCH 232/314] doc: document capnproto and libmultiprocess deps These dependencies are both undocumented, and libmultiprocess has a relatively special requirement in that v6.0 and later are known to not work with v29.x of Bitcoin Core due to https://github.com/bitcoin-core/libmultiprocess/pull/160 --- depends/packages/native_libmultiprocess.mk | 4 ++-- doc/dependencies.md | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/depends/packages/native_libmultiprocess.mk b/depends/packages/native_libmultiprocess.mk index 4467dee76f5..a76304f9f05 100644 --- a/depends/packages/native_libmultiprocess.mk +++ b/depends/packages/native_libmultiprocess.mk @@ -1,8 +1,8 @@ package=native_libmultiprocess -$(package)_version=1954f7f65661d49e700c344eae0fc8092decf975 +$(package)_version=v5.0 $(package)_download_path=https://github.com/bitcoin-core/libmultiprocess/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=fc014bd74727c1d5d30b396813685012c965d079244dd07b53bc1c75c610a2cb +$(package)_sha256_hash=401984715b271a3446e1910f21adf048ba390d31cc93cc3073742e70d56fa3ea $(package)_dependencies=native_capnp define $(package)_config_cmds diff --git a/doc/dependencies.md b/doc/dependencies.md index d3f6b74367b..a042f8f2ea7 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -36,3 +36,7 @@ Bitcoin Core requires one of the following compilers. | [SQLite](../depends/packages/sqlite.mk) (wallet) | [link](https://sqlite.org) | [3.38.5](https://github.com/bitcoin/bitcoin/pull/25378) | [3.7.17](https://github.com/bitcoin/bitcoin/pull/19077) | No | | Python (scripts, tests) | [link](https://www.python.org) | N/A | [3.10](https://github.com/bitcoin/bitcoin/pull/30527) | No | | [systemtap](../depends/packages/systemtap.mk) ([tracing](tracing.md)) | [link](https://sourceware.org/systemtap/) | [4.8](https://github.com/bitcoin/bitcoin/pull/26945)| N/A | No | +| [capnproto](../depends/packages/capnp.mk) ([multiprocess](multiprocess.md)) | [link](https://capnproto.org/) | [1.2.0](https://github.com/bitcoin/bitcoin/pull/32760)| [0.7.0](https://github.com/bitcoin-core/libmultiprocess/pull/88) | No | +| [libmultiprocess](../depends/packages/libmultiprocess.mk) ([multiprocess](multiprocess.md)) | [link](https://github.com/bitcoin-core/libmultiprocess) | [5.0](https://github.com/bitcoin/bitcoin/pull/31945)| [v5.0-pre1](https://github.com/bitcoin/bitcoin/pull/31740)* | No | + +\* Libmultiprocess 5.x versions should be compatible, but 6.0 and later are not due to bitcoin-core/libmultiprocess#160. From abaf1e37a79bdf7481cef1cd5ae5e102fdce09be Mon Sep 17 00:00:00 2001 From: furszy Date: Wed, 11 Dec 2024 13:05:21 -0500 Subject: [PATCH 233/314] refactor: remove sqlite dir path back-and-forth conversion Github-Pull: bitcoin/bitcoin#31423 Rebased-From: d04f6a97ba9a55aa9455e1a805feeed4d630f59a --- src/wallet/sqlite.cpp | 6 +++--- src/wallet/sqlite.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp index a8c9f8a8ab6..896a2fc0f33 100644 --- a/src/wallet/sqlite.cpp +++ b/src/wallet/sqlite.cpp @@ -112,12 +112,12 @@ Mutex SQLiteDatabase::g_sqlite_mutex; int SQLiteDatabase::g_sqlite_count = 0; SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, bool mock) - : WalletDatabase(), m_mock(mock), m_dir_path(fs::PathToString(dir_path)), m_file_path(fs::PathToString(file_path)), m_write_semaphore(1), m_use_unsafe_sync(options.use_unsafe_sync) + : WalletDatabase(), m_mock(mock), m_dir_path(dir_path), m_file_path(fs::PathToString(file_path)), m_write_semaphore(1), m_use_unsafe_sync(options.use_unsafe_sync) { { LOCK(g_sqlite_mutex); LogPrintf("Using SQLite Version %s\n", SQLiteDatabaseVersion()); - LogPrintf("Using wallet %s\n", m_dir_path); + LogPrintf("Using wallet %s\n", fs::PathToString(m_dir_path)); if (++g_sqlite_count == 1) { // Setup logging @@ -253,7 +253,7 @@ void SQLiteDatabase::Open() if (m_db == nullptr) { if (!m_mock) { - TryCreateDirectories(fs::PathFromString(m_dir_path)); + TryCreateDirectories(m_dir_path); } int ret = sqlite3_open_v2(m_file_path.c_str(), &m_db, flags, nullptr); if (ret != SQLITE_OK) { diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h index 78a3accf890..eb3c0217f55 100644 --- a/src/wallet/sqlite.h +++ b/src/wallet/sqlite.h @@ -105,7 +105,7 @@ class SQLiteDatabase : public WalletDatabase private: const bool m_mock{false}; - const std::string m_dir_path; + const fs::path m_dir_path; const std::string m_file_path; From 01c04d32aa3e1c323b304b1c6a573dd933b8b598 Mon Sep 17 00:00:00 2001 From: furszy Date: Wed, 11 Dec 2024 13:10:01 -0500 Subject: [PATCH 234/314] wallet: introduce method to return all db created files Github-Pull: bitcoin/bitcoin#31423 Rebased-From: 1de423e0a08bbc63eed36c8772e9ef8b48e80fb8 --- src/wallet/bdb.h | 15 +++++++++++++++ src/wallet/db.h | 3 +++ src/wallet/migrate.h | 1 + src/wallet/salvage.cpp | 1 + src/wallet/sqlite.h | 8 ++++++++ src/wallet/test/util.h | 1 + 6 files changed, 29 insertions(+) diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h index f3fe8a19c19..ec773fd1770 100644 --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -132,6 +132,21 @@ class BerkeleyDatabase : public WalletDatabase /** Return path to main database filename */ std::string Filename() override { return fs::PathToString(env->Directory() / m_filename); } + std::vector Files() override + { + std::vector files; + files.emplace_back(env->Directory() / m_filename); + if (env->m_databases.size() == 1) { + files.emplace_back(env->Directory() / "db.log"); + files.emplace_back(env->Directory() / ".walletlock"); + files.emplace_back(env->Directory() / "database" / "log.0000000001"); + files.emplace_back(env->Directory() / "database"); + // Note that this list is not exhaustive as BDB may create more log files, and possibly other ones too + // However it should be good enough for the only calls to Files() + } + return files; + } + std::string Format() override { return "bdb"; } /** * Pointer to shared database environment. diff --git a/src/wallet/db.h b/src/wallet/db.h index e8790006a4d..5f13ca29ff9 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -170,6 +170,9 @@ class WalletDatabase /** Return path to main database file for logs and error messages. */ virtual std::string Filename() = 0; + /** Return paths to all database created files */ + virtual std::vector Files() = 0; + virtual std::string Format() = 0; std::atomic nUpdateCounter; diff --git a/src/wallet/migrate.h b/src/wallet/migrate.h index 16eadeb019d..82359f9d4bb 100644 --- a/src/wallet/migrate.h +++ b/src/wallet/migrate.h @@ -65,6 +65,7 @@ class BerkeleyRODatabase : public WalletDatabase /** Return path to main database file for logs and error messages. */ std::string Filename() override { return fs::PathToString(m_filepath); } + std::vector Files() override { return {m_filepath}; } std::string Format() override { return "bdb_ro"; } diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp index b924239073c..443f80893ff 100644 --- a/src/wallet/salvage.cpp +++ b/src/wallet/salvage.cpp @@ -63,6 +63,7 @@ class DummyDatabase : public WalletDatabase void IncrementUpdateCounter() override { ++nUpdateCounter; } void ReloadDbEnv() override {} std::string Filename() override { return "dummy"; } + std::vector Files() override { return {}; } std::string Format() override { return "dummy"; } std::unique_ptr MakeBatch(bool flush_on_close = true) override { return std::make_unique(); } }; diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h index eb3c0217f55..c78cd29afc2 100644 --- a/src/wallet/sqlite.h +++ b/src/wallet/sqlite.h @@ -166,6 +166,14 @@ class SQLiteDatabase : public WalletDatabase void IncrementUpdateCounter() override { ++nUpdateCounter; } std::string Filename() override { return m_file_path; } + /** Return paths to all database created files */ + std::vector Files() override + { + std::vector files; + files.emplace_back(m_dir_path / fs::PathFromString(m_file_path)); + files.emplace_back(m_dir_path / fs::PathFromString(m_file_path + "-journal")); + return files; + } std::string Format() override { return "sqlite"; } /** Make a SQLiteBatch connected to this database */ diff --git a/src/wallet/test/util.h b/src/wallet/test/util.h index b055c6c6930..59e3a9c75f7 100644 --- a/src/wallet/test/util.h +++ b/src/wallet/test/util.h @@ -123,6 +123,7 @@ class MockableDatabase : public WalletDatabase void ReloadDbEnv() override {} std::string Filename() override { return "mockable"; } + std::vector Files() override { return {}; } std::string Format() override { return "mock"; } std::unique_ptr MakeBatch(bool flush_on_close = true) override { return std::make_unique(m_records, m_pass); } }; From cc324aa2bed30afa713625dfb9cf83c438dd15c1 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Tue, 6 Jan 2026 16:09:38 -0800 Subject: [PATCH 235/314] wallettool: do not use fs::remove_all in createfromdump cleanup Github-Pull: bitcoin/bitcoin#34215 Rebased-From: f78f6f1dc8e16d5a8a23749e77bc3bf17c91ae42 --- src/wallet/dump.cpp | 8 +++++++- test/functional/tool_wallet.py | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp index db2756e0ca8..20aa5d453ed 100644 --- a/src/wallet/dump.cpp +++ b/src/wallet/dump.cpp @@ -288,11 +288,17 @@ bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs:: dump_file.close(); } + // On failure, gather the paths to remove + std::vector paths_to_remove = wallet->GetDatabase().Files(); + if (!name.empty()) paths_to_remove.push_back(wallet_path); + wallet.reset(); // The pointer deleter will close the wallet for us. // Remove the wallet dir if we have a failure if (!ret) { - fs::remove_all(wallet_path); + for (const auto& p : paths_to_remove) { + fs::remove(p); + } } return ret; diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py index c7abc2da8d4..979804a5fea 100755 --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -409,6 +409,18 @@ def test_dump_createfromdump(self): self.write_dump(dump_data, bad_sum_wallet_dump) self.assert_raises_tool_error('Error: Checksum is not the correct size', '-wallet=badload', '-dumpfile={}'.format(bad_sum_wallet_dump), 'createfromdump') assert not (self.nodes[0].wallets_path / "badload").is_dir() + if not self.options.descriptors: + os.rename(self.nodes[0].wallets_path / "wallet.dat", self.nodes[0].wallets_path / "default.wallet.dat") + self.assert_raises_tool_error('Error: Checksum is not the correct size', '-wallet=', '-dumpfile={}'.format(bad_sum_wallet_dump), 'createfromdump') + assert self.nodes[0].wallets_path.exists() + assert not (self.nodes[0].wallets_path / "wallet.dat").exists() + + self.log.info('Checking createfromdump with an unnamed wallet') + self.do_tool_createfromdump("", "wallet.dump") + assert (self.nodes[0].wallets_path / "wallet.dat").exists() + os.unlink(self.nodes[0].wallets_path / "wallet.dat") + if not self.options.descriptors: + os.rename(self.nodes[0].wallets_path / "default.wallet.dat", self.nodes[0].wallets_path / "wallet.dat") def test_chainless_conflicts(self): self.log.info("Test wallet tool when wallet contains conflicting transactions") From d91f56e1e3f1aee99b0c09c23db70622ad6ed1b4 Mon Sep 17 00:00:00 2001 From: furszy Date: Mon, 5 Jan 2026 18:12:40 -0500 Subject: [PATCH 236/314] wallet: RestoreWallet failure, erase only what was created Track what RestoreWallet creates so only those files and directories are removed during a failure and nothing else. Preexisting paths must be left untouched. Note: Using fs::remove_all() instead of fs::remove() in RestoreWallet does not cause any problems currently, but the change is necessary for the next commit which extends RestoreWallet to work with existing directories, which may contain files that must not be deleted. Github-Pull: bitcoin/bitcoin#34156 Rebased-From: 4ed0693a3f2a427ef9e7ad016930ec29fa244995 --- src/wallet/wallet.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 09eda0c28e4..32c902b7680 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -501,6 +501,8 @@ std::shared_ptr RestoreWallet(WalletContext& context, const fs::path& b const fs::path wallet_path = fsbridge::AbsPathJoin(GetWalletDir(), fs::u8path(wallet_name)); auto wallet_file = wallet_path / "wallet.dat"; std::shared_ptr wallet; + bool wallet_file_copied = false; + bool created_parent_dir = false; try { if (!fs::exists(backup_file)) { @@ -509,13 +511,22 @@ std::shared_ptr RestoreWallet(WalletContext& context, const fs::path& b return nullptr; } - if (fs::exists(wallet_path) || !TryCreateDirectories(wallet_path)) { + if (fs::exists(wallet_path)) { error = Untranslated(strprintf("Failed to create database path '%s'. Database already exists.", fs::PathToString(wallet_path))); status = DatabaseStatus::FAILED_ALREADY_EXISTS; return nullptr; + } else { + // The directory doesn't exist, create it + if (!TryCreateDirectories(wallet_path)) { + error = Untranslated(strprintf("Failed to restore database path '%s'.", fs::PathToString(wallet_path))); + status = DatabaseStatus::FAILED_ALREADY_EXISTS; + return nullptr; + } + created_parent_dir = true; } fs::copy_file(backup_file, wallet_file, fs::copy_options::none); + wallet_file_copied = true; if (load_after_restore) { wallet = LoadWallet(context, wallet_name, load_on_start, options, status, error, warnings); @@ -528,7 +539,13 @@ std::shared_ptr RestoreWallet(WalletContext& context, const fs::path& b // Remove created wallet path only when loading fails if (load_after_restore && !wallet) { - fs::remove_all(wallet_path); + if (wallet_file_copied) fs::remove(wallet_file); + // Clean up the parent directory if we created it during restoration. + // As we have created it, it must be empty after deleting the wallet file. + if (created_parent_dir) { + Assume(fs::is_empty(wallet_path)); + fs::remove(wallet_path); + } } return wallet; From a074d36254ab0c666f0438fe071cd213715f82de Mon Sep 17 00:00:00 2001 From: furszy Date: Fri, 26 Dec 2025 20:22:55 -0500 Subject: [PATCH 237/314] wallet: fix unnamed wallet migration failure When migrating any legacy unnamed wallet, a failed migration would cause the cleanup logic to remove its parent directory. Since this type of legacy wallet lives directly in the main '/wallets/' folder, this resulted in unintentionally erasing all wallets, including the backup file. To be fully safe, we will no longer call `fs::remove_all`. Instead, we only erase the individual db files we have created, leaving everything else intact. The created wallets parent directories are erased only if they are empty. As part of this last change, `RestoreWallet` was modified to allow an existing directory as the destination, since we no longer remove the original wallet directory (we only remove the files we created inside it). This also fixes the restore of top-level default wallets during failures, which were failing due to the directory existence check that always returns true for the /wallets/ directory. This bug started after: https://github.com/bitcoin/bitcoin/commit/f6ee59b6e2995a3916fb4f0d4cbe15ece2054494 Previously, the `fs::copy_file` call was failing for top-level wallets, which prevented the `fs::remove_all` call from being reached. Github-Pull: bitcoin/bitcoin#34156 Rebased-From: f4c7e28e80bf9af50b03a770b641fd309a801589 --- src/wallet/wallet.cpp | 72 +++++++++++++++++++++++--------- test/functional/wallet_backup.py | 2 +- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 32c902b7680..119a99d601d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -511,10 +511,22 @@ std::shared_ptr RestoreWallet(WalletContext& context, const fs::path& b return nullptr; } + // Wallet directories are allowed to exist, but must not contain a .dat file. + // Any existing wallet database is treated as a hard failure to prevent overwriting. if (fs::exists(wallet_path)) { - error = Untranslated(strprintf("Failed to create database path '%s'. Database already exists.", fs::PathToString(wallet_path))); - status = DatabaseStatus::FAILED_ALREADY_EXISTS; - return nullptr; + // If this is a file, it is the db and we don't want to overwrite it. + if (!fs::is_directory(wallet_path)) { + error = Untranslated(strprintf("Failed to restore wallet. Database file exists '%s'.", fs::PathToString(wallet_path))); + status = DatabaseStatus::FAILED_ALREADY_EXISTS; + return nullptr; + } + + // Check we are not going to overwrite an existing db file + if (fs::exists(wallet_file)) { + error = Untranslated(strprintf("Failed to restore wallet. Database file exists in '%s'.", fs::PathToString(wallet_file))); + status = DatabaseStatus::FAILED_ALREADY_EXISTS; + return nullptr; + } } else { // The directory doesn't exist, create it if (!TryCreateDirectories(wallet_path)) { @@ -4559,26 +4571,43 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr } } - // In case of reloading failure, we need to remember the wallet dirs to remove - // Set is used as it may be populated with the same wallet directory paths multiple times, - // both before and after reloading. This ensures the set is complete even if one of the wallets - // fails to reload. - std::set wallet_dirs; + // In case of loading failure, we need to remember the wallet files we have created to remove. + // A `set` is used as it may be populated with the same wallet directory paths multiple times, + // both before and after loading. This ensures the set is complete even if one of the wallets + // fails to load. + std::set wallet_files_to_remove; + std::set wallet_empty_dirs_to_remove; + + // Helper to track wallet files and directories for cleanup on failure. + // Only directories of wallets created during migration (not the main wallet) are tracked. + auto track_for_cleanup = [&](const CWallet& wallet) { + const auto files = wallet.GetDatabase().Files(); + wallet_files_to_remove.insert(files.begin(), files.end()); + if (wallet.GetName() != wallet_name) { + // If this isn’t the main wallet, mark its directory for removal. + // This applies to the watch-only and solvable wallets. + // Wallets stored directly as files in the top-level directory + // (e.g. default unnamed wallets) don’t have a removable parent directory. + wallet_empty_dirs_to_remove.insert(fs::PathFromString(wallet.GetDatabase().Filename()).parent_path()); + } + }; + + if (success) { // Migration successful, unload all wallets locally, then reload them. // Reload the main wallet - wallet_dirs.insert(fs::PathFromString(local_wallet->GetDatabase().Filename()).parent_path()); + track_for_cleanup(*local_wallet); success = reload_wallet(local_wallet); res.wallet = local_wallet; res.wallet_name = wallet_name; if (success && res.watchonly_wallet) { // Reload watchonly - wallet_dirs.insert(fs::PathFromString(res.watchonly_wallet->GetDatabase().Filename()).parent_path()); + track_for_cleanup(*res.watchonly_wallet); success = reload_wallet(res.watchonly_wallet); } if (success && res.solvables_wallet) { // Reload solvables - wallet_dirs.insert(fs::PathFromString(res.solvables_wallet->GetDatabase().Filename()).parent_path()); + track_for_cleanup(*res.solvables_wallet); success = reload_wallet(res.solvables_wallet); } } @@ -4586,7 +4615,7 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr // Migration failed, cleanup // Before deleting the wallet's directory, copy the backup file to the top-level wallets dir fs::path temp_backup_location = fsbridge::AbsPathJoin(GetWalletDir(), backup_filename); - fs::copy_file(backup_path, temp_backup_location, fs::copy_options::none); + fs::rename(backup_path, temp_backup_location); // Make list of wallets to cleanup std::vector> created_wallets; @@ -4595,8 +4624,8 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr if (res.solvables_wallet) created_wallets.push_back(std::move(res.solvables_wallet)); // Get the directories to remove after unloading - for (std::shared_ptr& w : created_wallets) { - wallet_dirs.emplace(fs::PathFromString(w->GetDatabase().Filename()).parent_path()); + for (std::shared_ptr& wallet : created_wallets) { + track_for_cleanup(*wallet); } // Unload the wallets @@ -4615,9 +4644,15 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr } } - // Delete the wallet directories - for (const fs::path& dir : wallet_dirs) { - fs::remove_all(dir); + // First, delete the db files we have created throughout this process and nothing else + for (const fs::path& file : wallet_files_to_remove) { + fs::remove(file); + } + + // Second, delete the created wallet directories and nothing else. They must be empty at this point. + for (const fs::path& dir : wallet_empty_dirs_to_remove) { + Assume(fs::is_empty(dir)); + fs::remove(dir); } // Restore the backup @@ -4631,8 +4666,7 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr } // The wallet directory has been restored, but just in case, copy the previously created backup to the wallet dir - fs::copy_file(temp_backup_location, backup_path, fs::copy_options::none); - fs::remove(temp_backup_location); + fs::rename(temp_backup_location, backup_path); // Verify that there is no dangling wallet: when the wallet wasn't loaded before, expect null. // This check is performed after restoration to avoid an early error before saving the backup. diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py index 7c88f64dcf3..7ad83bdf870 100755 --- a/test/functional/wallet_backup.py +++ b/test/functional/wallet_backup.py @@ -136,7 +136,7 @@ def restore_wallet_existent_name(self): backup_file = self.nodes[0].datadir_path / 'wallet.bak' wallet_name = "res0" wallet_file = node.wallets_path / wallet_name - error_message = "Failed to create database path '{}'. Database already exists.".format(wallet_file) + error_message = "Failed to restore wallet. Database file exists in '{}'.".format(wallet_file / "wallet.dat") assert_raises_rpc_error(-36, error_message, node.restorewallet, wallet_name, backup_file) assert wallet_file.exists() From 833848e9b8eab430629da116f753f8d4433f51e2 Mon Sep 17 00:00:00 2001 From: furszy Date: Fri, 26 Dec 2025 20:23:02 -0500 Subject: [PATCH 238/314] test: add coverage for unnamed wallet migration failure Verifies that a failed migration of the unnamed (default) wallet does not erase the main /wallets/ directory, and also that the backup file exists. Github-Pull: bitcoin/bitcoin#34156 Rebased-From: 36093bde63286e19821a9e62cdff1712b6245dc7 --- test/functional/wallet_migration.py | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py index ce8dc19460d..3ca053043bb 100755 --- a/test/functional/wallet_migration.py +++ b/test/functional/wallet_migration.py @@ -4,6 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test Migrating a wallet from legacy to descriptor.""" +import os import random import shutil import struct @@ -548,6 +549,39 @@ def test_default_wallet(self): self.master_node.setmocktime(0) + def test_default_wallet_failure(self): + self.log.info("Test failure during unnamed (default) wallet migration") + master_wallet = self.master_node.get_wallet_rpc(self.default_wallet_name) + wallet = self.create_legacy_wallet("", blank=True) + wallet.importaddress(master_wallet.getnewaddress(address_type="legacy")) + + # Create wallet directory with the watch-only name and a wallet file. + # Because the wallet dir exists, this will cause migration to fail. + watch_only_dir = self.master_node.wallets_path / "_watchonly" + os.mkdir(watch_only_dir) + shutil.copyfile(self.old_node.wallets_path / "wallet.dat", watch_only_dir / "wallet.dat") + + mocked_time = int(time.time()) + self.master_node.setmocktime(mocked_time) + assert_raises_rpc_error(-4, "Failed to create database", self.migrate_and_get_rpc, "") + self.master_node.setmocktime(0) + + # Verify the /wallets/ path exists + assert self.master_node.wallets_path.exists() + # Check backup file exists. Because the wallet has no name, the backup is prefixed with 'default_wallet' + backup_path = self.master_node.wallets_path / f"default_wallet_{mocked_time}.legacy.bak" + assert backup_path.exists() + # Verify the original unnamed wallet was restored + assert (self.master_node.wallets_path / "wallet.dat").exists() + # And verify it is still a BDB wallet + with open(self.master_node.wallets_path / "wallet.dat", "rb") as f: + data = f.read(16) + _, _, magic = struct.unpack("QII", data) + assert_equal(magic, BTREE_MAGIC) + + # Test cleanup: clear default wallet for next test + os.remove(self.old_node.wallets_path / "wallet.dat") + def test_direct_file(self): self.log.info("Test migration of a wallet that is not in a wallet directory") wallet = self.create_legacy_wallet("plainfile") @@ -1372,6 +1406,7 @@ def run_test(self): self.test_encrypted() self.test_nonexistent() self.test_unloaded_by_path() + self.test_default_wallet_failure() self.test_default_wallet() self.test_direct_file() self.test_addressbook() From 9ea84c08d7e24ffefa6f18d6bd2af28ec38cfd98 Mon Sep 17 00:00:00 2001 From: furszy Date: Mon, 5 Jan 2026 16:08:13 -0500 Subject: [PATCH 239/314] test: restorewallet, coverage for existing dirs, unnamed wallet and prune failure The first test verifies that restoring into an existing empty directory or a directory with no .dat db files succeeds, while restoring into a dir with a .dat file fails. The second test covers restoring into the default unnamed wallet (wallet.dat), which also implicitly exercises the recovery path used after a failed migration. The third test covers failure during restore on a prune node. When the wallet last sync was beyond the pruning height. Github-Pull: bitcoin/bitcoin#34156 Rebased-From: f011e0f0680a8c39988ae57dae57eb86e92dd449 --- test/functional/wallet_backup.py | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py index 7ad83bdf870..3ff798d3d37 100755 --- a/test/functional/wallet_backup.py +++ b/test/functional/wallet_backup.py @@ -40,6 +40,7 @@ from test_framework.util import ( assert_equal, assert_raises_rpc_error, + sha256sum_file, ) @@ -140,6 +141,67 @@ def restore_wallet_existent_name(self): assert_raises_rpc_error(-36, error_message, node.restorewallet, wallet_name, backup_file) assert wallet_file.exists() + def test_restore_existent_dir(self): + self.log.info("Test restore on an existent empty directory") + node = self.nodes[3] + backup_file = self.nodes[0].datadir_path / 'wallet.bak' + wallet_name = "restored_wallet" + wallet_dir = node.wallets_path / wallet_name + os.mkdir(wallet_dir) + res = node.restorewallet(wallet_name, backup_file) + assert_equal(res['name'], wallet_name) + node.unloadwallet(wallet_name) + + self.log.info("Test restore succeeds when the target directory contains non-wallet files") + wallet_file = node.wallets_path / wallet_name / "wallet.dat" + os.remove(wallet_file) + extra_file = node.wallets_path / wallet_name / "not_a_wallet.txt" + extra_file.touch() + res = node.restorewallet(wallet_name, backup_file) + assert_equal(res['name'], wallet_name) + assert extra_file.exists() # extra file was not removed by mistake + node.unloadwallet(wallet_name) + + self.log.info("Test restore failure due to existing db file in the destination directory") + original_shasum = sha256sum_file(wallet_file) + error_message = "Failed to restore wallet. Database file exists in '{}'.".format(wallet_dir / "wallet.dat") + assert_raises_rpc_error(-36, error_message, node.restorewallet, wallet_name, backup_file) + # Ensure the wallet file remains untouched + assert wallet_dir.exists() + assert_equal(original_shasum, sha256sum_file(wallet_file)) + + self.log.info("Test restore succeeds when the .dat file in the destination has a different name") + second_wallet = wallet_dir / "hidden_storage.dat" + os.rename(wallet_dir / "wallet.dat", second_wallet) + original_shasum = sha256sum_file(second_wallet) + res = node.restorewallet(wallet_name, backup_file) + assert_equal(res['name'], wallet_name) + assert (wallet_dir / "hidden_storage.dat").exists() + assert_equal(original_shasum, sha256sum_file(second_wallet)) + node.unloadwallet(wallet_name) + + # Clean for follow-up tests + os.remove(wallet_file) + + def test_restore_into_unnamed_wallet(self): + self.log.info("Test restore into a default unnamed wallet") + # This is also useful to test the migration recovery after failure logic + node = self.nodes[3] + if not self.options.descriptors: + node.unloadwallet("") + os.rename(node.wallets_path / "wallet.dat", node.wallets_path / "default.wallet.dat") + backup_file = self.nodes[0].datadir_path / 'wallet.bak' + wallet_name = "" + res = node.restorewallet(wallet_name, backup_file) + assert_equal(res['name'], "") + assert (node.wallets_path / "wallet.dat").exists() + # Clean for follow-up tests + node.unloadwallet("") + os.remove(node.wallets_path / "wallet.dat") + if not self.options.descriptors: + os.rename(node.wallets_path / "default.wallet.dat", node.wallets_path / "wallet.dat") + node.loadwallet("") + def test_pruned_wallet_backup(self): self.log.info("Test loading backup on a pruned node when the backup was created close to the prune height of the restoring node") node = self.nodes[3] @@ -159,6 +221,19 @@ def test_pruned_wallet_backup(self): # the backup to load successfully this close to the prune height node.restorewallet('pruned', node.datadir_path / 'wallet_pruned.bak') + self.log.info("Test restore on a pruned node when the backup was beyond the pruning point") + if not self.options.descriptors: + node.unloadwallet("") + os.rename(node.wallets_path / "wallet.dat", node.wallets_path / "default.wallet.dat") + backup_file = self.nodes[0].datadir_path / 'wallet.bak' + wallet_name = "" + error_message = "Wallet loading failed. Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)" + assert_raises_rpc_error(-4, error_message, node.restorewallet, wallet_name, backup_file) + assert node.wallets_path.exists() # ensure the wallets dir exists + if not self.options.descriptors: + os.rename(node.wallets_path / "default.wallet.dat", node.wallets_path / "wallet.dat") + node.loadwallet("") + def run_test(self): self.log.info("Generating initial blockchain") self.generate(self.nodes[0], 1) @@ -227,6 +302,8 @@ def run_test(self): assert_equal(res2_rpc.getbalance(), balance2) self.restore_wallet_existent_name() + self.test_restore_existent_dir() + self.test_restore_into_unnamed_wallet() if not self.options.descriptors: self.log.info("Restoring using dumped wallet") From a7e2d106db8f193259420bacbccec80ba3beebf1 Mon Sep 17 00:00:00 2001 From: furszy Date: Sat, 27 Dec 2025 13:54:59 -0500 Subject: [PATCH 240/314] wallet: improve post-migration logging Right now, after migration the last message users see is "migration completed", but the migration isn't actually finished yet. We still need to load the new wallets to ensure consistency, and if that fails, the migration will be rolled back. This can be confusing for users. This change logs the post-migration loading step and if a wallet fails to load and the migration will be rolled back. Github-Pull: bitcoin/bitcoin#34156 Rebased-From: d70b159c42008ac3b63d1c43d99d4f1316d2f1ef --- src/wallet/wallet.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 119a99d601d..b54cf0be0f7 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4515,7 +4515,12 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr std::string name = to_reload->GetName(); to_reload.reset(); to_reload = LoadWallet(context, name, /*load_on_start=*/std::nullopt, options, status, error, warnings); - return to_reload != nullptr; + if (!to_reload) { + LogError("Failed to load wallet '%s' after migration. Rolling back migration to preserve consistency. " + "Error cause: %s\n", wallet_name, error.original); + return false; + } + return true; }; // Before anything else, check if there is something to migrate. @@ -4596,6 +4601,7 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr if (success) { // Migration successful, unload all wallets locally, then reload them. // Reload the main wallet + LogInfo("Loading new wallets after migration...\n"); track_for_cleanup(*local_wallet); success = reload_wallet(local_wallet); res.wallet = local_wallet; From 5e8ad98163af9749e7a3c44a9107cc241c5bd7ab Mon Sep 17 00:00:00 2001 From: furszy Date: Sat, 27 Dec 2025 14:32:11 -0500 Subject: [PATCH 241/314] wallet: migration, fix watch-only and solvables wallets names Because the default wallet has no name, the watch-only and solvables wallets created during migration end up having no name either. This fixes it by applying the same prefix name we use for the backup file for an unnamed default wallet. Before: watch-only wallet named "_watchonly" After: watch-only wallet named "default_wallet_watchonly" Github-Pull: bitcoin/bitcoin#34156 Rebased-From: 82caa8193a3e36f248dcc949e0cd41def191efac --- src/wallet/wallet.cpp | 15 ++++++++-- test/functional/wallet_migration.py | 45 +++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b54cf0be0f7..2397d84a6f5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4326,6 +4326,15 @@ bool CWallet::CanGrindR() const return !IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER); } +// Returns wallet prefix for migration. +// Used to name the backup file and newly created wallets. +// E.g. a watch-only wallet is named "_watchonly". +static std::string MigrationPrefixName(CWallet& wallet) +{ + const std::string& name{wallet.GetName()}; + return name.empty() ? "default_wallet" : name; +} + bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error, MigrationResult& res) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) { AssertLockHeld(wallet.cs_wallet); @@ -4357,7 +4366,7 @@ bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error, DatabaseStatus status; std::vector warnings; - std::string wallet_name = wallet.GetName() + "_watchonly"; + std::string wallet_name = MigrationPrefixName(wallet) + "_watchonly"; std::unique_ptr database = MakeWalletDatabase(wallet_name, options, status, error); if (!database) { error = strprintf(_("Wallet file creation failed: %s"), error); @@ -4394,7 +4403,7 @@ bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error, DatabaseStatus status; std::vector warnings; - std::string wallet_name = wallet.GetName() + "_solvables"; + std::string wallet_name = MigrationPrefixName(wallet) + "_solvables"; std::unique_ptr database = MakeWalletDatabase(wallet_name, options, status, error); if (!database) { error = strprintf(_("Wallet file creation failed: %s"), error); @@ -4533,7 +4542,7 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr // Make a backup of the DB fs::path this_wallet_dir = fs::absolute(fs::PathFromString(local_wallet->GetDatabase().Filename())).parent_path(); - fs::path backup_filename = fs::PathFromString(strprintf("%s_%d.legacy.bak", (wallet_name.empty() ? "default_wallet" : wallet_name), GetTime())); + fs::path backup_filename = fs::PathFromString(strprintf("%s_%d.legacy.bak", MigrationPrefixName(*local_wallet), GetTime())); fs::path backup_path = this_wallet_dir / backup_filename; if (!local_wallet->BackupWallet(fs::PathToString(backup_path))) { if (was_loaded) { diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py index 3ca053043bb..c11986226df 100755 --- a/test/functional/wallet_migration.py +++ b/test/functional/wallet_migration.py @@ -5,6 +5,7 @@ """Test Migrating a wallet from legacy to descriptor.""" import os +from pathlib import Path import random import shutil import struct @@ -25,6 +26,7 @@ from test_framework.script_util import key_to_p2pkh_script, key_to_p2pk_script, script_to_p2sh_script, script_to_p2wsh_script from test_framework.util import ( assert_equal, + assert_greater_than, assert_raises_rpc_error, find_vout_for_address, sha256sum_file, @@ -523,6 +525,14 @@ def test_unloaded_by_path(self): assert_equal(bals, wallet.getbalances()) + def clear_default_wallet(self, backup_file): + # Test cleanup: Clear unnamed default wallet for subsequent tests + (self.old_node.wallets_path / "wallet.dat").unlink() + (self.master_node.wallets_path / "wallet.dat").unlink(missing_ok=True) + shutil.rmtree(self.master_node.wallets_path / "default_wallet_watchonly", ignore_errors=True) + shutil.rmtree(self.master_node.wallets_path / "default_wallet_solvables", ignore_errors=True) + backup_file.unlink() + def test_default_wallet(self): self.log.info("Test migration of the wallet named as the empty string") wallet = self.create_legacy_wallet("") @@ -549,6 +559,36 @@ def test_default_wallet(self): self.master_node.setmocktime(0) + wallet.unloadwallet() + self.clear_default_wallet(backup_file=Path(res["backup_path"])) + + def test_default_wallet_watch_only(self): + self.log.info("Test unnamed (default) watch-only wallet migration") + master_wallet = self.master_node.get_wallet_rpc(self.default_wallet_name) + wallet = self.create_legacy_wallet("", blank=True) + wallet.importaddress(master_wallet.getnewaddress(address_type="legacy")) + + res, def_wallet = self.migrate_and_get_rpc("") + wallet = self.master_node.get_wallet_rpc("default_wallet_watchonly") + + info = wallet.getwalletinfo() + assert_equal(info["descriptors"], True) + assert_equal(info["format"], "sqlite") + assert_equal(info["private_keys_enabled"], False) + assert_equal(info["walletname"], "default_wallet_watchonly") + + # The default wallet will still exist and have newly generated descriptors + assert (self.master_node.wallets_path / "wallet.dat").exists() + def_wallet_info = def_wallet.getwalletinfo() + assert_equal(def_wallet_info["descriptors"], True) + assert_equal(def_wallet_info["format"], "sqlite") + assert_equal(def_wallet_info["private_keys_enabled"], True) + assert_equal(def_wallet_info["walletname"], "") + assert_greater_than(def_wallet_info["keypoolsize"], 0) + + wallet.unloadwallet() + self.clear_default_wallet(backup_file=Path(res["backup_path"])) + def test_default_wallet_failure(self): self.log.info("Test failure during unnamed (default) wallet migration") master_wallet = self.master_node.get_wallet_rpc(self.default_wallet_name) @@ -557,7 +597,7 @@ def test_default_wallet_failure(self): # Create wallet directory with the watch-only name and a wallet file. # Because the wallet dir exists, this will cause migration to fail. - watch_only_dir = self.master_node.wallets_path / "_watchonly" + watch_only_dir = self.master_node.wallets_path / "default_wallet_watchonly" os.mkdir(watch_only_dir) shutil.copyfile(self.old_node.wallets_path / "wallet.dat", watch_only_dir / "wallet.dat") @@ -580,7 +620,7 @@ def test_default_wallet_failure(self): assert_equal(magic, BTREE_MAGIC) # Test cleanup: clear default wallet for next test - os.remove(self.old_node.wallets_path / "wallet.dat") + self.clear_default_wallet(backup_path) def test_direct_file(self): self.log.info("Test migration of a wallet that is not in a wallet directory") @@ -1408,6 +1448,7 @@ def run_test(self): self.test_unloaded_by_path() self.test_default_wallet_failure() self.test_default_wallet() + self.test_default_wallet_watch_only() self.test_direct_file() self.test_addressbook() self.test_migrate_raw_p2sh() From 9405e915e79d86d262779ea38104624d37add2a3 Mon Sep 17 00:00:00 2001 From: furszy Date: Sun, 4 Jan 2026 12:25:21 -0500 Subject: [PATCH 242/314] test: coverage for migration failure when last sync is beyond prune height Github-Pull: bitcoin/bitcoin#34156 Rebased-From: b7c34d08dd9549a95cffc6ec1ffa4bb4f81e35eb --- test/functional/wallet_migration.py | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py index c11986226df..5424fda2ab2 100755 --- a/test/functional/wallet_migration.py +++ b/test/functional/wallet_migration.py @@ -1431,6 +1431,42 @@ def test_solvable_no_privs(self): assert_equal(addr_info["solvable"], True) assert "hex" in addr_info + def unsynced_wallet_on_pruned_node_fails(self): + self.log.info("Test migration of an unsynced wallet on a pruned node fails gracefully") + wallet = self.create_legacy_wallet("", load_on_startup=False) + last_wallet_synced_block = wallet.getwalletinfo()['lastprocessedblock']['height'] + wallet.unloadwallet() + + shutil.copyfile(self.old_node.wallets_path / "wallet.dat", self.master_node.wallets_path / "wallet.dat") + + # Generate blocks just so the wallet best block is pruned + self.restart_node(0, ["-fastprune", "-prune=1", "-nowallet"]) + self.connect_nodes(0, 1) + self.generate(self.master_node, 450, sync_fun=self.no_op) + self.master_node.pruneblockchain(250) + # Ensure next block to sync is unavailable + assert_raises_rpc_error(-1, "Block not available (pruned data)", self.master_node.getblock, self.master_node.getblockhash(last_wallet_synced_block + 1)) + + # Check migration failure + mocked_time = int(time.time()) + self.master_node.setmocktime(mocked_time) + assert_raises_rpc_error(-4, "last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)", self.master_node.migratewallet, wallet_name="") + self.master_node.setmocktime(0) + + # Verify the /wallets/ path exists, the wallet is still BDB and the backup file is there. + assert self.master_node.wallets_path.exists() + + with open(self.master_node.wallets_path / "wallet.dat", "rb") as f: + data = f.read(16) + _, _, magic = struct.unpack("QII", data) + assert_equal(magic, BTREE_MAGIC) + + backup_path = self.master_node.wallets_path / f"default_wallet_{mocked_time}.legacy.bak" + assert backup_path.exists() + + self.clear_default_wallet(backup_path) + + def run_test(self): self.master_node = self.nodes[0] self.old_node = self.nodes[1] @@ -1466,5 +1502,8 @@ def run_test(self): self.test_taproot() self.test_solvable_no_privs() + # Note: After this test the first 250 blocks of 'master_node' are pruned + self.unsynced_wallet_on_pruned_node_fails() + if __name__ == '__main__': WalletMigrationTest(__file__).main() From 76cdeb7b06232050c7d20ffa1395697cc4e53295 Mon Sep 17 00:00:00 2001 From: David Gumberg Date: Wed, 7 Jan 2026 16:02:58 -0800 Subject: [PATCH 243/314] wallet: test: Failed migration cleanup Refactor a common way to perform the failed migration test that exists for default wallets, and add relative-path wallets and absolute-path wallets. Github-Pull: 34226 Rebased-From: eeaf28dbe0e09819ab0e95bb7762b29536bdeef6 --- test/functional/wallet_migration.py | 79 ++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py index 5424fda2ab2..8129baf4388 100755 --- a/test/functional/wallet_migration.py +++ b/test/functional/wallet_migration.py @@ -589,38 +589,72 @@ def test_default_wallet_watch_only(self): wallet.unloadwallet() self.clear_default_wallet(backup_file=Path(res["backup_path"])) - def test_default_wallet_failure(self): - self.log.info("Test failure during unnamed (default) wallet migration") + def test_migration_failure(self, wallet_name): + is_default = wallet_name == "" + wallet_pretty_name = "unnamed (default)" if is_default else f'"{wallet_name}"' + self.log.info(f"Test failure during migration of wallet named: {wallet_pretty_name}") + # Preface, set up legacy wallet and unload it master_wallet = self.master_node.get_wallet_rpc(self.default_wallet_name) - wallet = self.create_legacy_wallet("", blank=True) + wallet = self.create_legacy_wallet(wallet_name, blank=True) wallet.importaddress(master_wallet.getnewaddress(address_type="legacy")) + wallet.unloadwallet() - # Create wallet directory with the watch-only name and a wallet file. - # Because the wallet dir exists, this will cause migration to fail. - watch_only_dir = self.master_node.wallets_path / "default_wallet_watchonly" + if os.path.isabs(wallet_name): + old_path = master_path = Path(wallet_name) + else: + old_path = self.old_node.wallets_path / wallet_name + master_path = self.master_node.wallets_path / wallet_name + os.makedirs(master_path, exist_ok=True) + shutil.copyfile(old_path / "wallet.dat", master_path / "wallet.dat") + + # This will be the watch-only directory the migration tries to create, + # we make migration fail by placing a wallet.dat file there. + wo_prefix = wallet_name or "default_wallet" + # wo_prefix might have path characters in it, this corresponds with + # DoMigration(). + wo_dirname = f"{wo_prefix}_watchonly" + watch_only_dir = self.master_node.wallets_path / wo_dirname os.mkdir(watch_only_dir) - shutil.copyfile(self.old_node.wallets_path / "wallet.dat", watch_only_dir / "wallet.dat") + shutil.copyfile(old_path / "wallet.dat", watch_only_dir / "wallet.dat") + + # Make a file in the wallets dir that must still exist after migration + survive_path = self.master_node.wallets_path / "survive" + open(survive_path, "wb").close() + assert survive_path.exists() mocked_time = int(time.time()) self.master_node.setmocktime(mocked_time) - assert_raises_rpc_error(-4, "Failed to create database", self.migrate_and_get_rpc, "") + assert_raises_rpc_error(-4, "Failed to create database", self.master_node.migratewallet, wallet_name) self.master_node.setmocktime(0) - # Verify the /wallets/ path exists + # Verify the /wallets/ path exists. assert self.master_node.wallets_path.exists() - # Check backup file exists. Because the wallet has no name, the backup is prefixed with 'default_wallet' - backup_path = self.master_node.wallets_path / f"default_wallet_{mocked_time}.legacy.bak" + + # Verify survive is still there + assert survive_path.exists() + # Verify both wallet paths exist. + assert Path(old_path / "wallet.dat").exists() + assert Path(master_path / "wallet.dat").exists() + + backup_prefix = "default_wallet" if is_default else wallet_name + backup_path = master_path / f"{backup_prefix}_{mocked_time}.legacy.bak" assert backup_path.exists() - # Verify the original unnamed wallet was restored - assert (self.master_node.wallets_path / "wallet.dat").exists() - # And verify it is still a BDB wallet - with open(self.master_node.wallets_path / "wallet.dat", "rb") as f: + + with open(self.master_node.wallets_path / wallet_name / self.wallet_data_filename, "rb") as f: data = f.read(16) _, _, magic = struct.unpack("QII", data) assert_equal(magic, BTREE_MAGIC) - # Test cleanup: clear default wallet for next test - self.clear_default_wallet(backup_path) + + # Cleanup + if is_default: + self.clear_default_wallet(backup_path) + else: + backup_path.unlink() + Path(watch_only_dir / "wallet.dat").unlink() + Path(watch_only_dir).rmdir() + Path(master_path / "wallet.dat").unlink() + Path(old_path / "wallet.dat").unlink(missing_ok=True) def test_direct_file(self): self.log.info("Test migration of a wallet that is not in a wallet directory") @@ -1482,7 +1516,16 @@ def run_test(self): self.test_encrypted() self.test_nonexistent() self.test_unloaded_by_path() - self.test_default_wallet_failure() + + migration_failure_cases = [ + "", + "../", + os.path.abspath(self.master_node.datadir_path / "absolute_path"), + "normallynamedwallet" + ] + for wallet_name in migration_failure_cases: + self.test_migration_failure(wallet_name=wallet_name) + self.test_default_wallet() self.test_default_wallet_watch_only() self.test_direct_file() From 2e4688618ba6a68df0936df0cc86b657ec35b4ef Mon Sep 17 00:00:00 2001 From: ismaelsadeeq Date: Wed, 24 Sep 2025 16:31:38 +0200 Subject: [PATCH 244/314] miner: fix `addPackageTxs` unsigned integer overflow Github-Pull: #33475 Rebased-From: b807dfcdc5929c314d43b790c9e705d5bf0a86e8 --- src/node/miner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node/miner.cpp b/src/node/miner.cpp index 33eeaf91fb2..b9ecd855f0a 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -394,8 +394,8 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda ++nConsecutiveFailed; - if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight > - m_options.nBlockMaxWeight - m_options.block_reserved_weight) { + if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight + + m_options.block_reserved_weight > m_options.nBlockMaxWeight) { // Give up if we're close to full and haven't succeeded in a while break; } From 7a71850a6d1d2eaf09e19d9d0af574a90487ec2b Mon Sep 17 00:00:00 2001 From: SatsAndSports Date: Tue, 28 Oct 2025 16:52:35 +0100 Subject: [PATCH 245/314] Remove unreliable seed from chainparams.cpp, and the associated README Github-Pull: #33723 Rebased-From: b0c706795ce6a3a00bf068a81ee99fef2ee9bf7e --- contrib/seeds/README.md | 3 +-- src/kernel/chainparams.cpp | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md index a1a2e34b5de..58d7f41130f 100644 --- a/contrib/seeds/README.md +++ b/contrib/seeds/README.md @@ -10,14 +10,13 @@ to addrman with). Update `MIN_BLOCKS` in `makeseeds.py` and the `-m`/`--minblocks` arguments below, as needed. -The seeds compiled into the release are created from sipa's, achow101's and luke-jr's +The seeds compiled into the release are created from sipa's and achow101's DNS seed, virtu's crawler, and asmap community AS map data. Run the following commands from the `/contrib/seeds` directory: ``` curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt curl https://21.ninja/seeds.txt.gz | gzip -dc >> seeds_main.txt -curl https://luke.dashjr.org/programs/bitcoin/files/charts/seeds.txt >> seeds_main.txt curl https://mainnet.achownodes.xyz/seeds.txt.gz | gzip -dc >> seeds_main.txt curl https://signet.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_signet.txt curl https://testnet.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_test.txt diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp index ac3fc9eadad..0f193eff74d 100644 --- a/src/kernel/chainparams.cpp +++ b/src/kernel/chainparams.cpp @@ -146,7 +146,6 @@ class CMainParams : public CChainParams { // release ASAP to avoid it where possible. vSeeds.emplace_back("seed.bitcoin.sipa.be."); // Pieter Wuille, only supports x1, x5, x9, and xd vSeeds.emplace_back("dnsseed.bluematt.me."); // Matt Corallo, only supports x9 - vSeeds.emplace_back("dnsseed.bitcoin.dashjr-list-of-p2p-nodes.us."); // Luke Dashjr vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch."); // Jonas Schnelli, only supports x1, x5, x9, and xd vSeeds.emplace_back("seed.btc.petertodd.net."); // Peter Todd, only supports x1, x5, x9, and xd vSeeds.emplace_back("seed.bitcoin.sprovoost.nl."); // Sjors Provoost From daef5852f02513521654e15d62748648765acf92 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 8 Jan 2026 12:45:14 +0000 Subject: [PATCH 246/314] guix: Fix `osslsigncode` tests Github-Pull: #34227 Rebased-From: 194114daf385a5db50e1507fda79a1a93240d494 --- contrib/guix/manifest.scm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 4e7e9552182..176fcee0464 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -2,6 +2,7 @@ ((gnu packages bash) #:select (bash-minimal)) (gnu packages bison) ((gnu packages certs) #:select (nss-certs)) + ((gnu packages check) #:select (libfaketime)) ((gnu packages cmake) #:select (cmake-minimal)) (gnu packages commencement) (gnu packages compression) @@ -209,7 +210,17 @@ and abstract ELF, PE and MachO formats.") (base32 "1j47vwq4caxfv0xw68kw5yh00qcpbd56d7rq6c483ma3y7s96yyz")))) (build-system cmake-build-system) - (inputs (list openssl)) + (arguments + (list + #:phases + #~(modify-phases %standard-phases + (replace 'check + (lambda* (#:key tests? #:allow-other-keys) + (if tests? + (invoke "faketime" "-f" "@2025-01-01 00:00:00" ;; Tests fail after 2025. + "ctest" "--output-on-failure" "--no-tests=error") + (format #t "test suite not run~%"))))))) + (inputs (list libfaketime openssl)) (home-page "https://github.com/mtrojnar/osslsigncode") (synopsis "Authenticode signing and timestamping tool") (description "osslsigncode is a small tool that implements part of the From 71633a9b5c10f0d6a1a1e31bcbf51de2e27649d9 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Mon, 1 Sep 2025 13:38:28 -0700 Subject: [PATCH 247/314] test: Test wallet 'from me' status change If something is imported into the wallet, it can change the 'from me' status of a transaction. This status is only visible through gettransaction's "fee" field which is only shown for transactions that are 'from me'. Github-Pull: #33268 Rebased-From: e76c2f7a4111f87080e31539f83c21390fcd8f3b --- test/functional/wallet_listtransactions.py | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py index 6263278a6c2..ce528657278 100755 --- a/test/functional/wallet_listtransactions.py +++ b/test/functional/wallet_listtransactions.py @@ -5,9 +5,11 @@ """Test the listtransactions API.""" from decimal import Decimal +import time import os import shutil +from test_framework.blocktools import MAX_FUTURE_BLOCK_TIME from test_framework.messages import ( COIN, tx_from_hex, @@ -17,7 +19,9 @@ assert_array_result, assert_equal, assert_raises_rpc_error, + find_vout_for_address, ) +from test_framework.wallet_util import get_generate_key class ListTransactionsTest(BitcoinTestFramework): @@ -114,6 +118,8 @@ def run_test(self): self.run_invalid_parameters_test() self.test_op_return() + self.test_from_me_status_change() + def run_rbf_opt_in_test(self): """Test the opt-in-rbf flag for sent and received transactions.""" @@ -327,6 +333,47 @@ def test_op_return(self): assert 'address' not in op_ret_tx + def test_from_me_status_change(self): + self.log.info("Test gettransaction after changing a transaction's 'from me' status") + self.nodes[0].createwallet("fromme") + default_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name) + wallet = self.nodes[0].get_wallet_rpc("fromme") + + # The 'fee' field of gettransaction is only added when the transaction is 'from me' + # Run twice, once for a transaction in the mempool, again when it confirms + for confirm in [False, True]: + key = get_generate_key() + default_wallet.importprivkey(key.privkey) + + send_res = default_wallet.send(outputs=[{key.p2wpkh_addr: 1}, {wallet.getnewaddress(): 1}]) + assert_equal(send_res["complete"], True) + vout = find_vout_for_address(self.nodes[0], send_res["txid"], key.p2wpkh_addr) + utxos = [{"txid": send_res["txid"], "vout": vout}] + self.generate(self.nodes[0], 1, sync_fun=self.no_op) + + # Send to the test wallet, ensuring that one input is for the descriptor we will import, + # and that there are other inputs belonging to only the sending wallet + send_res = default_wallet.send(outputs=[{wallet.getnewaddress(): 1.5}], inputs=utxos, add_inputs=True) + assert_equal(send_res["complete"], True) + txid = send_res["txid"] + self.nodes[0].syncwithvalidationinterfacequeue() + tx_info = wallet.gettransaction(txid) + assert "fee" not in tx_info + assert_equal(any(detail["category"] == "send" for detail in tx_info["details"]), False) + + if confirm: + self.generate(self.nodes[0], 1, sync_fun=self.no_op) + # Mock time forward and generate blocks so that the import does not rescan the transaction + self.nodes[0].setmocktime(int(time.time()) + MAX_FUTURE_BLOCK_TIME + 1) + self.generate(self.nodes[0], 10, sync_fun=self.no_op) + + wallet.importprivkey(key.privkey) + # TODO: We should check that the fee matches, but since the transaction spends inputs + # not known to the wallet, it is incorrectly calculating the fee. + # assert_equal(wallet.gettransaction(txid)["fee"], fee) + tx_info = wallet.gettransaction(txid) + assert "fee" in tx_info + assert_equal(any(detail["category"] == "send" for detail in tx_info["details"]), True) if __name__ == '__main__': ListTransactionsTest(__file__).main() From bab1ac827b4fdd4984661f32f6b899d56261da5d Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Thu, 28 Aug 2025 13:39:46 -0700 Subject: [PATCH 248/314] wallet: Determine IsFromMe by checking for TXOs of inputs Instead of checking whether the total amount of inputs known by the wallet is greater than 0, we should be checking for whether the input is known by the wallet. This enables us to determine whether a transaction spends an of output with an amount of 0, which is necessary for marking 0-value dust outputs as spent. Github-Pull: #33268 Rebased-From: 39a7dbdd277d1dea9a70314d8cc5ae057999ee88 --- src/wallet/wallet.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2397d84a6f5..913c7453205 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1702,7 +1702,13 @@ isminetype CWallet::IsMine(const COutPoint& outpoint) const bool CWallet::IsFromMe(const CTransaction& tx) const { - return (GetDebit(tx, ISMINE_ALL) > 0); + LOCK(cs_wallet); + for (const CTxIn& txin : tx.vin) { + if (IsMine(txin.prevout)) { + return true; + } + } + return false; } CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const From c6e7765c0a03c124fcc86b452d6870b6d2797130 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Thu, 28 Aug 2025 15:13:36 -0700 Subject: [PATCH 249/314] wallet: Throw an error in sendall if the tx size cannot be calculated Github-Pull: #33268 Rebased-From: c40dc822d74aea46e4a21774ca282e008f609c2a --- src/wallet/rpc/spend.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index 64aae701ebc..5c0b1db23e6 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -1486,7 +1486,6 @@ RPCHelpMan sendall() CoinFilterParams coins_params; coins_params.min_amount = 0; for (const COutput& output : AvailableCoins(*pwallet, &coin_control, fee_rate, coins_params).All()) { - CHECK_NONFATAL(output.input_bytes > 0); if (send_max && fee_rate.GetFee(output.input_bytes) > output.txout.nValue) { continue; } @@ -1505,6 +1504,9 @@ RPCHelpMan sendall() // estimate final size of tx const TxSize tx_size{CalculateMaximumSignedTxSize(CTransaction(rawTx), pwallet.get())}; + if (tx_size.vsize == -1) { + throw JSONRPCError(RPC_WALLET_ERROR, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors"); + } const CAmount fee_from_size{fee_rate.GetFee(tx_size.vsize)}; const std::optional total_bump_fees{pwallet->chain().calculateCombinedBumpFee(outpoints_spent, fee_rate)}; CAmount effective_value = total_input_value - fee_from_size - total_bump_fees.value_or(0); From f4b78c42e557aec29f5ed5e570fb55bf70d2b3b4 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Thu, 28 Aug 2025 15:13:23 -0700 Subject: [PATCH 250/314] test: Add a test for anchor outputs in the wallet Github-Pull: #33268 Rebased-From: 609d265ebc51abfe9a9ce570da647b6839dc1214 --- test/functional/test_framework/script_util.py | 1 + test/functional/test_runner.py | 2 + test/functional/wallet_anchor.py | 128 ++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100755 test/functional/wallet_anchor.py diff --git a/test/functional/test_framework/script_util.py b/test/functional/test_framework/script_util.py index fce32e138ee..d97120fd730 100755 --- a/test/functional/test_framework/script_util.py +++ b/test/functional/test_framework/script_util.py @@ -50,6 +50,7 @@ assert len(DUMMY_MIN_OP_RETURN_SCRIPT) == MIN_PADDING PAY_TO_ANCHOR = CScript([OP_1, bytes.fromhex("4e73")]) +ANCHOR_ADDRESS = "bcrt1pfeesnyr2tx" def key_to_p2pk_script(key): key = check_key(key) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 1fa22b1cc61..000407b118f 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -170,6 +170,8 @@ 'wallet_listreceivedby.py --descriptors', 'wallet_abandonconflict.py --legacy-wallet', 'wallet_abandonconflict.py --descriptors', + 'wallet_anchor.py --legacy-wallet', + 'wallet_anchor.py --descriptors', 'feature_reindex.py', 'feature_reindex_readonly.py', 'wallet_labels.py --legacy-wallet', diff --git a/test/functional/wallet_anchor.py b/test/functional/wallet_anchor.py new file mode 100755 index 00000000000..f641f3f9ee1 --- /dev/null +++ b/test/functional/wallet_anchor.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +# Copyright (c) 2025-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php. + +import time + +from test_framework.blocktools import MAX_FUTURE_BLOCK_TIME +from test_framework.descriptors import descsum_create +from test_framework.messages import ( + COutPoint, + CTxIn, + CTxInWitness, + CTxOut, +) +from test_framework.script_util import ( + ANCHOR_ADDRESS, + PAY_TO_ANCHOR, +) +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + assert_raises_rpc_error, +) +from test_framework.wallet import MiniWallet + +class WalletAnchorTest(BitcoinTestFramework): + def add_options(self, parser): + self.add_wallet_options(parser) + + def set_test_params(self): + self.num_nodes = 1 + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + + def test_0_value_anchor_listunspent(self): + self.log.info("Test that 0-value anchor outputs are detected as UTXOs") + + # Create an anchor output, and spend it + sender = MiniWallet(self.nodes[0]) + anchor_tx = sender.create_self_transfer(fee_rate=0, version=3)["tx"] + anchor_tx.vout.append(CTxOut(0, PAY_TO_ANCHOR)) + anchor_tx.rehash() # Rehash after modifying anchor_tx + anchor_spend = sender.create_self_transfer(version=3)["tx"] + anchor_spend.vin.append(CTxIn(COutPoint(anchor_tx.sha256, 1), b"")) + anchor_spend.wit.vtxinwit.append(CTxInWitness()) + anchor_spend.rehash() # Rehash after modifying anchor_spend + submit_res = self.nodes[0].submitpackage([anchor_tx.serialize().hex(), anchor_spend.serialize().hex()]) + assert_equal(submit_res["package_msg"], "success") + anchor_txid = anchor_tx.hash + anchor_spend_txid = anchor_spend.hash + + # Mine each tx in separate blocks + self.generateblock(self.nodes[0], sender.get_address(), [anchor_tx.serialize().hex()]) + anchor_tx_height = self.nodes[0].getblockcount() + self.generateblock(self.nodes[0], sender.get_address(), [anchor_spend.serialize().hex()]) + + # Mock time forward and generate some blocks to avoid rescanning of latest blocks + self.nodes[0].setmocktime(int(time.time()) + MAX_FUTURE_BLOCK_TIME + 1) + self.generate(self.nodes[0], 10) + + self.nodes[0].createwallet(wallet_name="anchor", disable_private_keys=True) + wallet = self.nodes[0].get_wallet_rpc("anchor") + + wallet.importaddress(ANCHOR_ADDRESS, rescan=False) + + # The wallet should have no UTXOs, and not know of the anchor tx or its spend + assert_equal(wallet.listunspent(), []) + assert_raises_rpc_error(-5, "Invalid or non-wallet transaction id", wallet.gettransaction, anchor_txid) + assert_raises_rpc_error(-5, "Invalid or non-wallet transaction id", wallet.gettransaction, anchor_spend_txid) + + # Rescanning the block containing the anchor so that listunspent will list the output + wallet.rescanblockchain(0, anchor_tx_height) + utxos = wallet.listunspent() + assert_equal(len(utxos), 1) + assert_equal(utxos[0]["txid"], anchor_txid) + assert_equal(utxos[0]["address"], ANCHOR_ADDRESS) + assert_equal(utxos[0]["amount"], 0) + wallet.gettransaction(anchor_txid) + assert_raises_rpc_error(-5, "Invalid or non-wallet transaction id", wallet.gettransaction, anchor_spend_txid) + + # Rescan the rest of the blockchain to see the anchor was spent + wallet.rescanblockchain() + assert_equal(wallet.listunspent(), []) + wallet.gettransaction(anchor_spend_txid) + + def test_cannot_sign_anchors(self): + self.log.info("Test that the wallet cannot spend anchor outputs") + for disable_privkeys in [False, True]: + self.nodes[0].createwallet(wallet_name=f"anchor_spend_{disable_privkeys}", disable_private_keys=disable_privkeys) + wallet = self.nodes[0].get_wallet_rpc(f"anchor_spend_{disable_privkeys}") + if self.options.descriptors: + import_res = wallet.importdescriptors([ + {"desc": descsum_create(f"addr({ANCHOR_ADDRESS})"), "timestamp": "now"}, + {"desc": descsum_create(f"raw({PAY_TO_ANCHOR.hex()})"), "timestamp": "now"} + ]) + assert_equal(import_res[0]["success"], disable_privkeys) + assert_equal(import_res[1]["success"], disable_privkeys) + else: + wallet.importaddress(ANCHOR_ADDRESS) + + anchor_txid = self.default_wallet.sendtoaddress(ANCHOR_ADDRESS, 1) + self.generate(self.nodes[0], 1) + + wallet = self.nodes[0].get_wallet_rpc("anchor_spend_True") + utxos = wallet.listunspent() + assert_equal(len(utxos), 1) + assert_equal(utxos[0]["txid"], anchor_txid) + assert_equal(utxos[0]["address"], ANCHOR_ADDRESS) + assert_equal(utxos[0]["amount"], 1) + + if self.options.descriptors: + assert_raises_rpc_error(-4, "Missing solving data for estimating transaction size", wallet.send, [{self.default_wallet.getnewaddress(): 0.9999}]) + assert_raises_rpc_error(-4, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors", wallet.sendall, recipients=[self.default_wallet.getnewaddress()]) + else: + assert_raises_rpc_error(-4, "Insufficient funds", wallet.send, [{self.default_wallet.getnewaddress(): 0.9999}]) + assert_raises_rpc_error(-6, "Total value of UTXO pool too low to pay for transaction. Try using lower feerate or excluding uneconomic UTXOs with 'send_max' option.", wallet.sendall, recipients=[self.default_wallet.getnewaddress()]) + assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", wallet.sendtoaddress, self.default_wallet.getnewaddress(), 0.9999) + assert_raises_rpc_error(-4, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors", wallet.sendall, recipients=[self.default_wallet.getnewaddress()], inputs=utxos) + + def run_test(self): + self.default_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name) + self.test_0_value_anchor_listunspent() + self.test_cannot_sign_anchors() + +if __name__ == '__main__': + WalletAnchorTest(__file__).main() From e973b61dbb431141e23846d95a86221b01587900 Mon Sep 17 00:00:00 2001 From: glozow Date: Mon, 12 Jan 2026 14:29:54 -0800 Subject: [PATCH 251/314] [doc] update release notes for 29.3rc1 --- doc/release-notes.md | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 4e2071dfa67..263ee553d1e 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.x is now available from: +Bitcoin Core version 29.3rc1 is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. @@ -37,6 +37,36 @@ unsupported systems. Notable changes =============== +### P2P + +- #33050 net, validation: don't punish peers for consensus-invalid txs +- #33723 chainparams: remove dnsseed.bitcoin.dashjr-list-of-p2p-nodes.us + +### Validation + +- #32473 Introduce per-txin sighash midstate cache for legacy/p2sh/segwitv0 scripts +- #33105 validation: detect witness stripping without re-running Script checks + +### Wallet + +- #33268 wallet: Identify transactions spending 0-value outputs, and add tests for anchor outputs in a wallet +- #34156 wallet: fix unnamed legacy wallet migration failure +- #34226 wallet: test: Relative wallet failed migration cleanup +- #34123 wallet: migration, avoid creating spendable wallet from a watch-only legacy wallet +- #34215 wallettool: fix unnamed createfromdump failure walletsdir deletion + +### Mining + +- #33475 bugfix: miner: fix `addPackageTxs` unsigned integer overflow + +### Build + +- #34227 guix: Fix `osslsigncode` tests + +### Documentation + +- #33623 doc: document capnproto and libmultiprocess deps in 29.x + ### Test - #33612 test: change log rate limit version gate @@ -51,8 +81,17 @@ Credits Thanks to everyone who directly contributed to this release: +- Anthony Towns +- Antoine Poinsot - Ava Chow +- David Gumberg - Eugene Siegel +- fanquake +- furszy +- Hennadii Stepanov +- ismaelsadeeq +- Pieter Wuille +- SatsAndSports - willcl-ark As well as to everyone that helped with translations on From e9c978391ff74e99724fbda9fb50f0c45fb13008 Mon Sep 17 00:00:00 2001 From: glozow Date: Mon, 12 Jan 2026 14:36:12 -0800 Subject: [PATCH 252/314] [build] bump version to 29.3rc1 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70f672132b4..8337d69535b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,9 +28,9 @@ get_directory_property(precious_variables CACHE_VARIABLES) #============================= set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) -set(CLIENT_VERSION_MINOR 2) +set(CLIENT_VERSION_MINOR 3) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 0) +set(CLIENT_VERSION_RC 1) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From b834447fb2f2073e25164a80ba197a3120610b92 Mon Sep 17 00:00:00 2001 From: glozow Date: Mon, 12 Jan 2026 14:37:04 -0800 Subject: [PATCH 253/314] [doc] generate manpages 29.3rc1 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index ce6f35c198e..aad8ffd52bd 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "October 2025" "bitcoin-cli v29.2.0" "User Commands" +.TH BITCOIN-CLI "1" "January 2026" "bitcoin-cli v29.3.0rc1" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.2.0 +bitcoin-cli \- manual page for bitcoin-cli v29.3.0rc1 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.2.0 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.2.0 +Bitcoin Core RPC client version v29.3.0rc1 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 5efc9e96172..ba38159542f 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "October 2025" "bitcoin-qt v29.2.0" "User Commands" +.TH BITCOIN-QT "1" "January 2026" "bitcoin-qt v29.3.0rc1" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.2.0 +bitcoin-qt \- manual page for bitcoin-qt v29.3.0rc1 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.2.0 +Bitcoin Core version v29.3.0rc1 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 90a233619fa..4be1d582911 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "October 2025" "bitcoin-tx v29.2.0" "User Commands" +.TH BITCOIN-TX "1" "January 2026" "bitcoin-tx v29.3.0rc1" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.2.0 +bitcoin-tx \- manual page for bitcoin-tx v29.3.0rc1 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.2.0 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.2.0 +Bitcoin Core bitcoin\-tx utility version v29.3.0rc1 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index 4186bd3f5a7..f4bc33f4da3 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "October 2025" "bitcoin-util v29.2.0" "User Commands" +.TH BITCOIN-UTIL "1" "January 2026" "bitcoin-util v29.3.0rc1" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.2.0 +bitcoin-util \- manual page for bitcoin-util v29.3.0rc1 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.2.0 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.2.0 +Bitcoin Core bitcoin\-util utility version v29.3.0rc1 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index 97c6144f81a..000fb2a814d 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "October 2025" "bitcoin-wallet v29.2.0" "User Commands" +.TH BITCOIN-WALLET "1" "January 2026" "bitcoin-wallet v29.3.0rc1" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.2.0 +bitcoin-wallet \- manual page for bitcoin-wallet v29.3.0rc1 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.2.0 +Bitcoin Core bitcoin\-wallet utility version v29.3.0rc1 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 82804a50c83..f0005de61c8 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "October 2025" "bitcoind v29.2.0" "User Commands" +.TH BITCOIND "1" "January 2026" "bitcoind v29.3.0rc1" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.2.0 +bitcoind \- manual page for bitcoind v29.3.0rc1 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.2.0 +Bitcoin Core daemon version v29.3.0rc1 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From 7475d134f6a3a6039ab6b9d39706ade47c764aa8 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 15 Jan 2026 19:01:19 +0000 Subject: [PATCH 254/314] Wallet/bdb: Safely and correctly list files only used by the single wallet If any other files exist in the directory, we cannot assume the sharable files are exclusively for this wallet. But if they are, this also cleans up other log.* files --- src/wallet/bdb.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++ src/wallet/bdb.h | 15 +-------------- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp index 79851dff33f..f5a18266edb 100644 --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -340,6 +341,53 @@ bool BerkeleyDatabase::Verify(bilingual_str& errorStr) return true; } +std::vector BerkeleyDatabase::Files() +{ + std::vector files; + // If the wallet is the *only* file, clean up the entire BDB environment + constexpr auto build_files_list = [](std::vector& files, const std::shared_ptr& env, const fs::path& filename) { + if (env->m_databases.size() != 1) return false; + + const auto env_dir = env->Directory(); + const auto db_subdir = env_dir / "database"; + if (fs::exists(db_subdir)) { + if (!fs::is_directory(db_subdir)) return false; + for (const auto& entry : fs::directory_iterator(db_subdir)) { + const auto& path = entry.path().filename(); + if (!fs::PathToString(path).starts_with("log.")) { + return false; + } + files.emplace_back(entry.path()); + } + } + const std::set allowed_paths = { + filename, + "db.log", + ".walletlock", + "database" + }; + for (const auto& entry : fs::directory_iterator(env_dir)) { + const auto& path = entry.path().filename(); + if (allowed_paths.contains(path)) { + files.emplace_back(entry.path()); + } else if (fs::is_directory(entry.path())) { + // Subdirectories can't possibly be using this db env, and is expected if this is a non-directory wallet + // Do not include them in Files, but still allow the env cleanup + } else { + return false; + } + } + return true; + }; + try { + if (build_files_list(files, env, m_filename)) return files; + } catch (...) { + // Give up building the comprehensive file list if any error occurs + } + // Otherwise, it's only really safe to delete the one wallet file + return {env->Directory() / m_filename}; +} + void BerkeleyEnvironment::CheckpointLSN(const std::string& strFile) { dbenv->txn_checkpoint(0, 0, 0); diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h index ec773fd1770..a7cf953ed21 100644 --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -132,20 +132,7 @@ class BerkeleyDatabase : public WalletDatabase /** Return path to main database filename */ std::string Filename() override { return fs::PathToString(env->Directory() / m_filename); } - std::vector Files() override - { - std::vector files; - files.emplace_back(env->Directory() / m_filename); - if (env->m_databases.size() == 1) { - files.emplace_back(env->Directory() / "db.log"); - files.emplace_back(env->Directory() / ".walletlock"); - files.emplace_back(env->Directory() / "database" / "log.0000000001"); - files.emplace_back(env->Directory() / "database"); - // Note that this list is not exhaustive as BDB may create more log files, and possibly other ones too - // However it should be good enough for the only calls to Files() - } - return files; - } + std::vector Files() override; std::string Format() override { return "bdb"; } /** From 60f529027c6eacbdc298fab50192f8c60d7082a1 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 15 Jan 2026 19:03:23 +0000 Subject: [PATCH 255/314] Wallet/Migration: If loading the new watchonly or solvables wallet fails, log the correct wallet name in error message --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 913c7453205..992b02a9895 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4532,7 +4532,7 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr to_reload = LoadWallet(context, name, /*load_on_start=*/std::nullopt, options, status, error, warnings); if (!to_reload) { LogError("Failed to load wallet '%s' after migration. Rolling back migration to preserve consistency. " - "Error cause: %s\n", wallet_name, error.original); + "Error cause: %s\n", name, error.original); return false; } return true; From cef01d0be5223e9d33efc897d7fbe5d0a08692c0 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 15 Jan 2026 19:27:23 +0000 Subject: [PATCH 256/314] Wallet/Migration: Skip moving the backup file back and forth for no reason Since we no longer delete the wallet directory, there's no need to vacate it The moving only served to risk errors by crossing filesystem boundaries (which fs::rename can't handle) --- src/wallet/wallet.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 992b02a9895..df53f904cc2 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4634,9 +4634,6 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr } if (!success) { // Migration failed, cleanup - // Before deleting the wallet's directory, copy the backup file to the top-level wallets dir - fs::path temp_backup_location = fsbridge::AbsPathJoin(GetWalletDir(), backup_filename); - fs::rename(backup_path, temp_backup_location); // Make list of wallets to cleanup std::vector> created_wallets; @@ -4680,15 +4677,12 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr // Convert the backup file to the wallet db file by renaming it and moving it into the wallet's directory. // Reload it into memory if the wallet was previously loaded. bilingual_str restore_error; - const auto& ptr_wallet = RestoreWallet(context, temp_backup_location, wallet_name, /*load_on_start=*/std::nullopt, status, restore_error, warnings, /*load_after_restore=*/was_loaded); + const auto& ptr_wallet = RestoreWallet(context, backup_path, wallet_name, /*load_on_start=*/std::nullopt, status, restore_error, warnings, /*load_after_restore=*/was_loaded); if (!restore_error.empty()) { error += restore_error + _("\nUnable to restore backup of wallet."); return util::Error{error}; } - // The wallet directory has been restored, but just in case, copy the previously created backup to the wallet dir - fs::rename(temp_backup_location, backup_path); - // Verify that there is no dangling wallet: when the wallet wasn't loaded before, expect null. // This check is performed after restoration to avoid an early error before saving the backup. bool wallet_reloaded = ptr_wallet != nullptr; From 69a6b9b1152ba0bb3edab6d2a54509fd416b24c8 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 20 Jan 2026 18:20:14 +0000 Subject: [PATCH 257/314] Bugfix: Wallet/Migration: Move backup into wallet directory when migrating from non-directory While 30.x+ keep backup files in walletdir, 29.x places them in the migrated wallet directory --- src/wallet/wallet.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index df53f904cc2..45adda65ead 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4581,6 +4581,12 @@ util::Result MigrateLegacyToDescriptor(std::shared_ptr // First change to using SQLite if (!local_wallet->MigrateToSQLite(error)) return util::Error{error}; + // In case we're migrating from file to directory, move the backup into it + this_wallet_dir = fs::absolute(fs::PathFromString(local_wallet->GetDatabase().Filename())).parent_path(); + backup_path = this_wallet_dir / backup_filename; + fs::rename(res.backup_path, backup_path); + res.backup_path = backup_path; + // Do the migration of keys and scripts for non-blank wallets, and cleanup if it fails success = local_wallet->IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET); if (!success) { From 65173944ed60df3b9cffca95932aed8720921478 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 21 Jan 2026 21:32:40 +0000 Subject: [PATCH 258/314] QA: tool_wallet: Check that db.log is deleted with a lone legacy wallet, but not with a shared db environment --- test/functional/tool_wallet.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py index 979804a5fea..788d9b0ee8d 100755 --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -410,17 +410,30 @@ def test_dump_createfromdump(self): self.assert_raises_tool_error('Error: Checksum is not the correct size', '-wallet=badload', '-dumpfile={}'.format(bad_sum_wallet_dump), 'createfromdump') assert not (self.nodes[0].wallets_path / "badload").is_dir() if not self.options.descriptors: - os.rename(self.nodes[0].wallets_path / "wallet.dat", self.nodes[0].wallets_path / "default.wallet.dat") + os.rename(self.nodes[0].wallets_path / "wallet.dat", self.nodes[0].wallets_path / "../default.wallet.dat") + (self.nodes[0].wallets_path / "db.log").unlink(missing_ok=True) self.assert_raises_tool_error('Error: Checksum is not the correct size', '-wallet=', '-dumpfile={}'.format(bad_sum_wallet_dump), 'createfromdump') assert self.nodes[0].wallets_path.exists() assert not (self.nodes[0].wallets_path / "wallet.dat").exists() + if not self.options.descriptors: + assert not (self.nodes[0].wallets_path / "db.log").exists() self.log.info('Checking createfromdump with an unnamed wallet') self.do_tool_createfromdump("", "wallet.dump") assert (self.nodes[0].wallets_path / "wallet.dat").exists() os.unlink(self.nodes[0].wallets_path / "wallet.dat") if not self.options.descriptors: - os.rename(self.nodes[0].wallets_path / "default.wallet.dat", self.nodes[0].wallets_path / "wallet.dat") + os.rename(self.nodes[0].wallets_path / "../default.wallet.dat", self.nodes[0].wallets_path / "wallet.dat") + + self.log.info('Checking createfromdump with multiple non-directory wallets') + assert not (self.nodes[0].wallets_path / "wallet.dat").is_dir() + assert (self.nodes[0].wallets_path / "db.log").exists() + os.rename(self.nodes[0].wallets_path / "wallet.dat", self.nodes[0].wallets_path / "test.dat") + self.assert_raises_tool_error('Error: Checksum is not the correct size', '-wallet=', '-dumpfile={}'.format(bad_sum_wallet_dump), 'createfromdump') + assert not (self.nodes[0].wallets_path / "wallet.dat").exists() + assert (self.nodes[0].wallets_path / "test.dat").exists() + assert (self.nodes[0].wallets_path / "db.log").exists() + os.rename(self.nodes[0].wallets_path / "test.dat", self.nodes[0].wallets_path / "wallet.dat") def test_chainless_conflicts(self): self.log.info("Test wallet tool when wallet contains conflicting transactions") From c57009eefcf30091d86fccaa07f0722f6f235cb9 Mon Sep 17 00:00:00 2001 From: Padraic Slattery Date: Mon, 19 Jan 2026 17:45:37 +0100 Subject: [PATCH 259/314] chore: Update outdated GitHub Actions versions Github-Pull: #34344 Rebased-From: 9482f00df0b05e8ef710a7f0fac3262855ce335f --- .github/actions/configure-docker/action.yml | 2 +- .github/workflows/ci.yml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/configure-docker/action.yml b/.github/actions/configure-docker/action.yml index 131fdb1ccc3..9bf970ee78f 100644 --- a/.github/actions/configure-docker/action.yml +++ b/.github/actions/configure-docker/action.yml @@ -16,7 +16,7 @@ runs: # This is required to allow buildkit to access the actions cache - name: Expose actions cache variables - uses: actions/github-script@v6 + uses: actions/github-script@v8 with: script: | Object.keys(process.env).forEach(function (key) { diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae614d5bb29..88e52a627ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,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@v6 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: ${{ env.FETCH_DEPTH }} @@ -125,7 +125,7 @@ jobs: steps: - &CHECKOUT name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 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 || '' }} @@ -164,7 +164,7 @@ jobs: FILE_ENV: ${{ matrix.file-env }} - name: Save Ccache cache - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' with: path: ${{ env.CCACHE_DIR }} @@ -222,13 +222,13 @@ jobs: sed -i '1s/^/set(ENV{CMAKE_POLICY_VERSION_MINIMUM} 3.5)\n/' "${VCPKG_INSTALLATION_ROOT}/scripts/ports.cmake" - name: vcpkg tools cache - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: C:/vcpkg/downloads/tools key: ${{ github.job }}-vcpkg-tools - name: Restore vcpkg binary cache - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 id: vcpkg-binary-cache with: path: ~/AppData/Local/vcpkg/archives @@ -239,7 +239,7 @@ jobs: cmake -B build --preset vs2022-static -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" ${{ matrix.generate-options }} - name: Save vcpkg binary cache - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 if: github.event_name != 'pull_request' && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' && matrix.job-type == 'standard' with: path: ~/AppData/Local/vcpkg/archives @@ -414,7 +414,7 @@ jobs: CONTAINER_NAME: "bitcoin-linter" steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: ref: *CHECKOUT_REF_TMPL fetch-depth: 0 From 6aec0958f12a65567a354a1d08d4bfed126cf34b Mon Sep 17 00:00:00 2001 From: Max Edwards Date: Thu, 25 Sep 2025 18:11:37 +0100 Subject: [PATCH 260/314] ci: remove 3rd party js from windows dll gha job We can use vswhere.exe directly to create a vs developer prompt and so can remove this third party dependency. Co-authored-by: David Gumberg Github-Pull: #32513 Rebased-From: 7ae0497eef8f5b37fc1184897a5bbc9f023dfa67 --- .github/workflows/ci.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88e52a627ee..b0af3eb95fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -198,11 +198,15 @@ jobs: steps: - *CHECKOUT - - name: Configure Developer Command Prompt for Microsoft Visual C++ - # Using microsoft/setup-msbuild is not enough. - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: x64 + - name: Set up VS Developer Prompt + shell: pwsh -Command "$PSVersionTable; $PSNativeCommandUseErrorActionPreference = $true; $ErrorActionPreference = 'Stop'; & '{0}'" + run: | + $vswherePath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + $installationPath = & $vswherePath -latest -property installationPath + & "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | foreach-object { + $name, $value = $_ -split '=', 2 + echo "$name=$value" >> $env:GITHUB_ENV + } - name: Get tool information run: | From 3835e16e5fe9d77d10fe1ce819157980dcea65f8 Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 29 Jan 2026 14:21:13 +0000 Subject: [PATCH 261/314] doc: update release notes for v29.x --- doc/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 263ee553d1e..4970d195e85 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -73,8 +73,10 @@ Notable changes ### Misc +- #32513 ci: remove 3rd party js from windows dll gha job - #33508 ci: fix buildx gha cache authentication on forks - #33581 ci: Properly include $FILE_ENV in DEPENDS_HASH +- #34344 ci: update GitHub Actions versions Credits ======= @@ -90,6 +92,8 @@ Thanks to everyone who directly contributed to this release: - furszy - Hennadii Stepanov - ismaelsadeeq +- m3dwards +- Padraic Slattery - Pieter Wuille - SatsAndSports - willcl-ark From 340b58a8cee1ee9d108af500129896f2928c8681 Mon Sep 17 00:00:00 2001 From: sedited Date: Thu, 8 Jan 2026 19:59:15 +0100 Subject: [PATCH 262/314] Add sedited to trusted-keys Github-Pull: bitcoin/bitcoin#34236 Rebased-From: d1b227f3ad19e1364c74fcb3b34717bb2b9b9243 --- contrib/verify-commits/trusted-keys | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys index f25486776f9..0121f290b04 100644 --- a/contrib/verify-commits/trusted-keys +++ b/contrib/verify-commits/trusted-keys @@ -3,3 +3,4 @@ D1DBF2C4B96F2DEBF4C16654410108112E7EA81F 152812300785C96444D3334D17565732E08E5E41 6B002C6EA3F91B1B0DF0C9BC8F617F1200A6D25C 4D1B3D5ECBA1A7E05371EEBE46800E30FC748A66 +A8FC55F3B04BA3146F3492E79303B33A305224CB From 16493e35cd3dff081cc24285543ea65fc881b6ae Mon Sep 17 00:00:00 2001 From: sedited Date: Thu, 29 Jan 2026 18:01:16 +0100 Subject: [PATCH 263/314] Bump version to 29.3rc2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8337d69535b..ed59b307cd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 3) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 1) +set(CLIENT_VERSION_RC 2) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From 75c2108a684d395dc59a224968bed9801628a35d Mon Sep 17 00:00:00 2001 From: sedited Date: Thu, 29 Jan 2026 18:03:29 +0100 Subject: [PATCH 264/314] [doc] update release notes for 29.3rc2 --- doc/release-notes.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 4970d195e85..4aebc143d7d 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.3rc1 is now available from: +Bitcoin Core version 29.3rc2 is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. @@ -54,6 +54,7 @@ Notable changes - #34226 wallet: test: Relative wallet failed migration cleanup - #34123 wallet: migration, avoid creating spendable wallet from a watch-only legacy wallet - #34215 wallettool: fix unnamed createfromdump failure walletsdir deletion +- #34370 wallet: Additional cleanups for migration, and fixes for createfromdump with BDB ### Mining @@ -92,10 +93,12 @@ Thanks to everyone who directly contributed to this release: - furszy - Hennadii Stepanov - ismaelsadeeq +- luke-jr - m3dwards - Padraic Slattery - Pieter Wuille - SatsAndSports +- sedited - willcl-ark As well as to everyone that helped with translations on From 2b2c4daa5357d4d6abefe2c87eb74caf12c09342 Mon Sep 17 00:00:00 2001 From: sedited Date: Thu, 29 Jan 2026 18:08:10 +0100 Subject: [PATCH 265/314] [doc] generate manpages 29.3rc2 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index aad8ffd52bd..e762c0fa39d 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "January 2026" "bitcoin-cli v29.3.0rc1" "User Commands" +.TH BITCOIN-CLI "1" "January 2026" "bitcoin-cli v29.3.0rc2" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.3.0rc1 +bitcoin-cli \- manual page for bitcoin-cli v29.3.0rc2 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.3.0rc1 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.3.0rc1 +Bitcoin Core RPC client version v29.3.0rc2 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index ba38159542f..4a990e8082b 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "January 2026" "bitcoin-qt v29.3.0rc1" "User Commands" +.TH BITCOIN-QT "1" "January 2026" "bitcoin-qt v29.3.0rc2" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.3.0rc1 +bitcoin-qt \- manual page for bitcoin-qt v29.3.0rc2 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.3.0rc1 +Bitcoin Core version v29.3.0rc2 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 4be1d582911..7b3b996afd8 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "January 2026" "bitcoin-tx v29.3.0rc1" "User Commands" +.TH BITCOIN-TX "1" "January 2026" "bitcoin-tx v29.3.0rc2" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.3.0rc1 +bitcoin-tx \- manual page for bitcoin-tx v29.3.0rc2 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.3.0rc1 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.3.0rc1 +Bitcoin Core bitcoin\-tx utility version v29.3.0rc2 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index f4bc33f4da3..d10f4b48b35 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "January 2026" "bitcoin-util v29.3.0rc1" "User Commands" +.TH BITCOIN-UTIL "1" "January 2026" "bitcoin-util v29.3.0rc2" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.3.0rc1 +bitcoin-util \- manual page for bitcoin-util v29.3.0rc2 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.3.0rc1 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.3.0rc1 +Bitcoin Core bitcoin\-util utility version v29.3.0rc2 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index 000fb2a814d..c8737d7989c 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "January 2026" "bitcoin-wallet v29.3.0rc1" "User Commands" +.TH BITCOIN-WALLET "1" "January 2026" "bitcoin-wallet v29.3.0rc2" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.3.0rc1 +bitcoin-wallet \- manual page for bitcoin-wallet v29.3.0rc2 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.3.0rc1 +Bitcoin Core bitcoin\-wallet utility version v29.3.0rc2 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index f0005de61c8..bcf23544521 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "January 2026" "bitcoind v29.3.0rc1" "User Commands" +.TH BITCOIND "1" "January 2026" "bitcoind v29.3.0rc2" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.3.0rc1 +bitcoind \- manual page for bitcoind v29.3.0rc2 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.3.0rc1 +Bitcoin Core daemon version v29.3.0rc2 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From 824de1e6b32c898408c8a03fb75f09454eb8dcca Mon Sep 17 00:00:00 2001 From: sedited Date: Mon, 9 Feb 2026 10:14:48 +0100 Subject: [PATCH 266/314] build: Bump version to 29.3 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed59b307cd7..6e2c8680892 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(CLIENT_NAME "Bitcoin Core") set(CLIENT_VERSION_MAJOR 29) set(CLIENT_VERSION_MINOR 3) set(CLIENT_VERSION_BUILD 0) -set(CLIENT_VERSION_RC 2) +set(CLIENT_VERSION_RC 0) set(CLIENT_VERSION_IS_RELEASE "true") set(COPYRIGHT_YEAR "2025") From ea6af54a637bb06e66a233a2a6ff3b9d145f9414 Mon Sep 17 00:00:00 2001 From: sedited Date: Mon, 9 Feb 2026 10:16:24 +0100 Subject: [PATCH 267/314] doc: Update release notes for 29.3 --- doc/release-notes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 4aebc143d7d..98713c6ceaa 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.3rc2 is now available from: +Bitcoin Core version 29.3 is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. From c9a7bd90eb5a60657e68f33a03782f2a9ceefe86 Mon Sep 17 00:00:00 2001 From: sedited Date: Mon, 9 Feb 2026 10:24:53 +0100 Subject: [PATCH 268/314] doc: Update man pages for v29.3 --- doc/man/bitcoin-cli.1 | 6 +++--- doc/man/bitcoin-qt.1 | 6 +++--- doc/man/bitcoin-tx.1 | 6 +++--- doc/man/bitcoin-util.1 | 6 +++--- doc/man/bitcoin-wallet.1 | 6 +++--- doc/man/bitcoind.1 | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1 index e762c0fa39d..6146224cdd1 100644 --- a/doc/man/bitcoin-cli.1 +++ b/doc/man/bitcoin-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-CLI "1" "January 2026" "bitcoin-cli v29.3.0rc2" "User Commands" +.TH BITCOIN-CLI "1" "February 2026" "bitcoin-cli v29.3.0" "User Commands" .SH NAME -bitcoin-cli \- manual page for bitcoin-cli v29.3.0rc2 +bitcoin-cli \- manual page for bitcoin-cli v29.3.0 .SH SYNOPSIS .B bitcoin-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] @@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v29.3.0rc2 .B bitcoin-cli [\fI\,options\/\fR] \fI\,help \/\fR .SH DESCRIPTION -Bitcoin Core RPC client version v29.3.0rc2 +Bitcoin Core RPC client version v29.3.0 .PP The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server. .PP diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 4a990e8082b..a4fec08c7a5 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-QT "1" "January 2026" "bitcoin-qt v29.3.0rc2" "User Commands" +.TH BITCOIN-QT "1" "February 2026" "bitcoin-qt v29.3.0" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v29.3.0rc2 +bitcoin-qt \- manual page for bitcoin-qt v29.3.0 .SH SYNOPSIS .B bitcoin-qt [\fI\,options\/\fR] [\fI\,URI\/\fR] .SH DESCRIPTION -Bitcoin Core version v29.3.0rc2 +Bitcoin Core version v29.3.0 .PP The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core. .PP diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 7b3b996afd8..a58bfea152a 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-TX "1" "January 2026" "bitcoin-tx v29.3.0rc2" "User Commands" +.TH BITCOIN-TX "1" "February 2026" "bitcoin-tx v29.3.0" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v29.3.0rc2 +bitcoin-tx \- manual page for bitcoin-tx v29.3.0 .SH SYNOPSIS .B bitcoin-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] @@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v29.3.0rc2 .B bitcoin-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v29.3.0rc2 +Bitcoin Core bitcoin\-tx utility version v29.3.0 .PP The bitcoin\-tx tool is used for creating and modifying bitcoin transactions. .PP diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1 index d10f4b48b35..b7e0127ae1e 100644 --- a/doc/man/bitcoin-util.1 +++ b/doc/man/bitcoin-util.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-UTIL "1" "January 2026" "bitcoin-util v29.3.0rc2" "User Commands" +.TH BITCOIN-UTIL "1" "February 2026" "bitcoin-util v29.3.0" "User Commands" .SH NAME -bitcoin-util \- manual page for bitcoin-util v29.3.0rc2 +bitcoin-util \- manual page for bitcoin-util v29.3.0 .SH SYNOPSIS .B bitcoin-util [\fI\,options\/\fR] [\fI\,command\/\fR] @@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v29.3.0rc2 .B bitcoin-util [\fI\,options\/\fR] \fI\,grind \/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-util utility version v29.3.0rc2 +Bitcoin Core bitcoin\-util utility version v29.3.0 .PP The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below. .SH OPTIONS diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1 index c8737d7989c..96c2f4e1c9b 100644 --- a/doc/man/bitcoin-wallet.1 +++ b/doc/man/bitcoin-wallet.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIN-WALLET "1" "January 2026" "bitcoin-wallet v29.3.0rc2" "User Commands" +.TH BITCOIN-WALLET "1" "February 2026" "bitcoin-wallet v29.3.0" "User Commands" .SH NAME -bitcoin-wallet \- manual page for bitcoin-wallet v29.3.0rc2 +bitcoin-wallet \- manual page for bitcoin-wallet v29.3.0 .SH SYNOPSIS .B bitcoin-wallet [\fI\,options\/\fR] \fI\,\/\fR .SH DESCRIPTION -Bitcoin Core bitcoin\-wallet utility version v29.3.0rc2 +Bitcoin Core bitcoin\-wallet utility version v29.3.0 .PP bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. .PP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index bcf23544521..10ec23f6956 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH BITCOIND "1" "January 2026" "bitcoind v29.3.0rc2" "User Commands" +.TH BITCOIND "1" "February 2026" "bitcoind v29.3.0" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v29.3.0rc2 +bitcoind \- manual page for bitcoind v29.3.0 .SH SYNOPSIS .B bitcoind [\fI\,options\/\fR] .SH DESCRIPTION -Bitcoin Core daemon version v29.3.0rc2 +Bitcoin Core daemon version v29.3.0 .PP The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses. .PP From 5910bd3b5d7588a96ff8137ece49b5c827aca6b4 Mon Sep 17 00:00:00 2001 From: jayvaliya Date: Thu, 5 Feb 2026 14:07:25 +0530 Subject: [PATCH 269/314] doc: fix broken bpftrace installation link The bpftrace project moved from iovisor/bpftrace to bpftrace/bpftraceand removed the separate INSTALL.md file. Installation instructionsare now in the README.md Quick Start section. Github-Pull: #34510 Rebased-From: 42ee31e80c99bdb4d6affdc9dc22a0f3d5da7b59 --- contrib/tracing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/tracing/README.md b/contrib/tracing/README.md index 252053e7b87..192182e17d6 100644 --- a/contrib/tracing/README.md +++ b/contrib/tracing/README.md @@ -22,7 +22,7 @@ corresponding packages. See [installing bpftrace] and [installing BCC] for more information. For development there exist a [bpftrace Reference Guide], a [BCC Reference Guide], and a [bcc Python Developer Tutorial]. -[installing bpftrace]: https://github.com/iovisor/bpftrace/blob/master/INSTALL.md +[installing bpftrace]: https://github.com/bpftrace/bpftrace/blob/master/README.md#quick-start [installing BCC]: https://github.com/iovisor/bcc/blob/master/INSTALL.md [bpftrace Reference Guide]: https://github.com/iovisor/bpftrace/blob/master/docs/reference_guide.md [BCC Reference Guide]: https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md From 532afe909e3ea983c7e2c07df7074158f671a2a7 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Wed, 25 Feb 2026 19:51:24 +0100 Subject: [PATCH 270/314] doc: Update Guix install for Debian/Ubuntu Fixes https://github.com/bitcoin/bitcoin/issues/33982 Co-authored-by: Purple Ninja <129023353+ToRyVand@users.noreply.github.com> Github-Pull: #34671 Rebased-From: faa70ca7642bd653cbd2e544c17fa58d2672afa4 --- contrib/guix/INSTALL.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/guix/INSTALL.md b/contrib/guix/INSTALL.md index 910f8f25460..df2728332af 100644 --- a/contrib/guix/INSTALL.md +++ b/contrib/guix/INSTALL.md @@ -71,13 +71,13 @@ https://repology.org/project/guix/versions ### Debian / Ubuntu -Guix is available as a distribution package in [Debian -](https://packages.debian.org/search?keywords=guix) and [Ubuntu -](https://packages.ubuntu.com/search?keywords=guix). +Currently, the `guix` package is no longer present in recent Debian or Ubuntu +repositories. Any other installation option mentioned in this document may be +used. -To install: +If you previously installed `guix` via `apt`, you can remove it with: ```sh -sudo apt install guix +sudo apt purge guix ``` ### Arch Linux From 98af76f875af47fea2aadb57086046c6cd858f0b Mon Sep 17 00:00:00 2001 From: SomberNight Date: Wed, 11 Feb 2026 16:16:50 +0000 Subject: [PATCH 271/314] wallet: rpc: manpage: fix example missing `fee_rate` argument The function signature for the `send` RPC is: ``` send [{"address":amount,...},{"data":"hex"},...] ( conf_target "estimate_mode" fee_rate options version ) ``` The last example in the manpage is missing the `fee_rate` arg, but is trying to specify the `options` arg, by index. The parser confuses the intended `options` arg as the missing `fee_rate` arg. See: ``` $ bitcoin-cli -rpcuser=doggman -rpcpassword=donkey -rpcport=18554 -regtest send '{"bcrt1qusm48zmlzwr32csxdw4ar7atw260h22c9ten9l": 0.1}' 1 economical '{"add_to_wallet": false, "inputs": [{"txid":"0b7e1a471dc948b7a6187936b16e6d7d9833629b2f9dd8a392eb89928f63aaad", "vout":0}]}' error code: -8 error message: Cannot specify both conf_target and fee_rate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate. ``` vs ``` $ bitcoin-cli -rpcuser=doggman -rpcpassword=donkey -rpcport=18554 -regtest send '{"bcrt1qusm48zmlzwr32csxdw4ar7atw260h22c9ten9l": 0.1}' 1 economical null '{"add_to_wallet": false, "inputs": [{"txid":"0b7e1a471dc948b7a6187936b16e6d7d9833629b2f9dd8a392eb89928f63aaad", "vout":0}]}' { "psbt": "cHNidP8BAHECAAAAAa2qY4+SieuSo9idL5tiM5h9bW6xNnkYprdIyR1HGn4LAAAAAAD9////AkR2DwQAAAAAFgAUpLDwJu+wFRHLQAgKAb0psk7UVd2AlpgAAAAAABYAFOQ3U4t/E4cVYgZrq9H7q3K0+6lYAAAAAAABAIUCAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////wQC4wMA/////wLIF6gEAAAAABYAFLMY1zihXrefAA0DA5nld4MCPjkrAAAAAAAAAAAmaiSqIant4vYcP3HR3v0/qZnfo2lTdVxpBol5mWK0i+vYNpdOjPkAAAAAAQEfyBeoBAAAAAAWABSzGNc4oV63nwANAwOZ5XeDAj45KwEIawJHMEQCIElTV4pbUrsPR9qHWcioowVv3QVWHizxwevfD0u/I8YyAiBCY3OzF81PSLM00h4ueQkehYuxDFZu7Jk51iejphKnnwEhA0VKdYVSyBpWoxBwTDOupB58Fi3mEBs+u+OOqEYVd2sZACICA98YLWyH7dBCfXVxe7woiLSTgV1mJN8Zc8KgZ77pVSg+GNBMeT5UAACAAQAAgAAAAIABAAAAbAAAAAAA", "txid": "625b71b314a6ac4f738634e29dc007cd5edc0427c1ae96ab706d06a62910cea2", "hex": "02000000000101adaa638f9289eb92a3d89d2f9b6233987d6d6eb1367918a6b748c91d471a7e0b0000000000fdffffff0244760f0400000000160014a4b0f026efb01511cb40080a01bd29b24ed455dd8096980000000000160014e437538b7f13871562066babd1fbab72b4fba9580247304402204953578a5b52bb0f47da8759c8a8a3056fdd05561e2cf1c1ebdf0f4bbf23c6320220426373b317cd4f48b334d21e2e79091e858bb10c566eec9939d627a3a612a79f012103454a758552c81a56a310704c33aea41e7c162de6101b3ebbe38ea84615776b1900000000", "complete": true } ``` Github-Pull: #34561 Rebased-From: 50cf6838e6aa51e0d712cbc1e13d686253bc8fe0 --- src/wallet/rpc/spend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index 5c0b1db23e6..53692f85114 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -1279,7 +1279,7 @@ RPCHelpMan send() "Send 0.3 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n" + HelpExampleCli("-named send", "outputs='{\"" + EXAMPLE_ADDRESS[0] + "\": 0.3}' fee_rate=25\n") + "Create a transaction that should confirm the next block, with a specific input, and return result without adding to wallet or broadcasting to the network\n" - + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 1 economical '{\"add_to_wallet\": false, \"inputs\": [{\"txid\":\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\", \"vout\":1}]}'") + + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 1 economical null '{\"add_to_wallet\": false, \"inputs\": [{\"txid\":\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\", \"vout\":1}]}'") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { From 490cd874a40a1ca5845b720cf9c6f6a59472454d Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Sun, 14 Dec 2025 13:50:23 +0100 Subject: [PATCH 272/314] netif: fix compilation warning in QueryDefaultGatewayImpl() ``` src/common/netif.cpp:137:51: error: comparison of integers of different signs: 'int64_t' (aka 'long') and 'unsigned long' [-Werror,-Wsign-compare] 137 | for (nlmsghdr* hdr = (nlmsghdr*)response; NLMSG_OK(hdr, recv_result); hdr = NLMSG_NEXT(hdr, recv_result)) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/netlink/netlink.h:220:31: note: expanded from macro 'NLMSG_OK' 220 | #define NLMSG_OK(_hdr, _len) NL_ITEM_OK(_hdr, _len, NLMSG_HDRLEN, _NLMSG_LEN) | ^ ~~~~ ~~~~~~~~~~~~ /usr/include/netlink/netlink.h:203:10: note: expanded from macro 'NL_ITEM_OK' 203 | ((_len) >= _hlen && _LEN_M(_ptr) >= _hlen && _LEN_M(_ptr) <= (_len)) | ~~~~ ^ ~~~~~ 1 error generated. ``` Happens on FreeBSD 15.0, with the default compiler (Clang 19). On FreeBSD 14, `/usr/include/netlink/netlink.h` contains: ``` #define NLMSG_HDRLEN ((int)sizeof(struct nlmsghdr)) ``` On FreeBSD 15, `/usr/include/netlink/netlink.h` contains: ``` #define NLMSG_HDRLEN (sizeof(struct nlmsghdr)) ``` Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Github-Pull: #34093 Rebased-From: c1361fc42dd60606fcd6273cede1083cd88866a2 --- src/common/netif.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/netif.cpp b/src/common/netif.cpp index 7424f977c7e..276be8e2f6a 100644 --- a/src/common/netif.cpp +++ b/src/common/netif.cpp @@ -29,6 +29,8 @@ #include #endif +#include + namespace { // Linux and FreeBSD 14.0+. For FreeBSD 13.2 the code can be compiled but @@ -93,7 +95,9 @@ std::optional QueryDefaultGatewayImpl(sa_family_t family) return std::nullopt; } - for (nlmsghdr* hdr = (nlmsghdr*)response; NLMSG_OK(hdr, recv_result); hdr = NLMSG_NEXT(hdr, recv_result)) { + using recv_result_t = std::conditional_t, int64_t, decltype(NLMSG_HDRLEN)>; + + for (nlmsghdr* hdr = (nlmsghdr*)response; NLMSG_OK(hdr, static_cast(recv_result)); hdr = NLMSG_NEXT(hdr, recv_result)) { rtmsg* r = (rtmsg*)NLMSG_DATA(hdr); int remaining_len = RTM_PAYLOAD(hdr); From 98ea6caed5259c279f7f4794fbafb67ab078e9ae Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 26 Feb 2026 09:55:45 +0000 Subject: [PATCH 273/314] doc: update release notes for v29.x --- doc/release-notes.md | 67 ++++++++------------------------------------ 1 file changed, 12 insertions(+), 55 deletions(-) diff --git a/doc/release-notes.md b/doc/release-notes.md index 98713c6ceaa..764f778e5d4 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,6 +1,6 @@ -Bitcoin Core version 29.3 is now available from: +Bitcoin Core version 29.x is now available from: - + This release includes various bug fixes and performance improvements, as well as updated translations. @@ -37,69 +37,26 @@ unsupported systems. Notable changes =============== -### P2P +### Net -- #33050 net, validation: don't punish peers for consensus-invalid txs -- #33723 chainparams: remove dnsseed.bitcoin.dashjr-list-of-p2p-nodes.us +- #34093 netif: fix compilation warning in QueryDefaultGatewayImpl() -### Validation +### Doc -- #32473 Introduce per-txin sighash midstate cache for legacy/p2sh/segwitv0 scripts -- #33105 validation: detect witness stripping without re-running Script checks - -### Wallet - -- #33268 wallet: Identify transactions spending 0-value outputs, and add tests for anchor outputs in a wallet -- #34156 wallet: fix unnamed legacy wallet migration failure -- #34226 wallet: test: Relative wallet failed migration cleanup -- #34123 wallet: migration, avoid creating spendable wallet from a watch-only legacy wallet -- #34215 wallettool: fix unnamed createfromdump failure walletsdir deletion -- #34370 wallet: Additional cleanups for migration, and fixes for createfromdump with BDB - -### Mining - -- #33475 bugfix: miner: fix `addPackageTxs` unsigned integer overflow - -### Build - -- #34227 guix: Fix `osslsigncode` tests - -### Documentation - -- #33623 doc: document capnproto and libmultiprocess deps in 29.x - -### Test - -- #33612 test: change log rate limit version gate - -### Misc - -- #32513 ci: remove 3rd party js from windows dll gha job -- #33508 ci: fix buildx gha cache authentication on forks -- #33581 ci: Properly include $FILE_ENV in DEPENDS_HASH -- #34344 ci: update GitHub Actions versions +- #34510 doc: fix broken bpftrace installation link +- #34561 wallet: rpc: manpage: fix example missing `fee_rate` argument +- #34671 doc: Update Guix install for Debian/Ubuntu Credits ======= Thanks to everyone who directly contributed to this release: -- Anthony Towns -- Antoine Poinsot -- Ava Chow -- David Gumberg -- Eugene Siegel -- fanquake -- furszy - Hennadii Stepanov -- ismaelsadeeq -- luke-jr -- m3dwards -- Padraic Slattery -- Pieter Wuille -- SatsAndSports -- sedited -- willcl-ark +- jayvaliya +- MarcoFalke +- SomberNight +- ToRyVand As well as to everyone that helped with translations on [Transifex](https://explore.transifex.com/bitcoin/bitcoin/). From 0fb5e167e8e332e3d40659406b3222a22747aa0e Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Wed, 18 Mar 2026 10:43:28 +0100 Subject: [PATCH 274/314] cmake: Migrate away from deprecated SQLite3 target CMake version 4.3 deprecated the imported target `Sqlite::Sqlite3`. Use the preferred name `Sqlite3::Sqlite3` instead and provide an alias for older versions of CMake. Also define the same alias when using vcpkg. Github-Pull: #34848 Rebased-From: 498b6eb6b5e8aceb372d3097df2715d9c7fc416b --- CMakeLists.txt | 4 ++++ src/wallet/CMakeLists.txt | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e2c8680892..3c31bd08dde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,8 +111,12 @@ if(WITH_SQLITE) if(VCPKG_TARGET_TRIPLET) # Use of the `unofficial::` namespace is a vcpkg package manager convention. find_package(unofficial-sqlite3 CONFIG REQUIRED) + add_library(SQLite3::SQLite3 ALIAS unofficial::sqlite3::sqlite3) else() find_package(SQLite3 3.7.17 REQUIRED) + if(NOT TARGET SQLite3::SQLite3) # CMake < 4.3 + add_library(SQLite3::SQLite3 ALIAS SQLite::SQLite3) + endif() endif() set(USE_SQLITE ON) endif() diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 121e6e3c837..ee81c6b17a2 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -49,8 +49,7 @@ if(USE_SQLITE) target_sources(bitcoin_wallet PRIVATE sqlite.cpp) target_link_libraries(bitcoin_wallet PRIVATE - $ - $ + SQLite3::SQLite3 ) endif() if(USE_BDB) From 546598b73675bd5663de6df8f4e3a23a0e7eceb7 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 28 Apr 2026 18:00:36 +0000 Subject: [PATCH 275/314] multi_index: fix compilation failure with boost >= 1.91 This effectively reverts a3cb309e7c31853f272bffaa65fb6ab0a7cc4083 from PR #30194. That PR reduced the multi_index type signatures as recommended upstream, but this is no longer supported as of boost 1.91 because it is no longer necessary. 1.91 drops support for the pre-c++11 work-arounds that bloated the type signatures to begin with. The upstream `BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT` define is meant to provide compatibility with removed features, but it does not work for this case. Using `indexed_by` directly when defining the `multi_index` (as opposed to inheriting from it) works with all versions, and avoids the use of the back-compat define. This is a slight regression when building against boost < 1.91 because the bloated type signatures are reintroduced in that case, but it's not significant enough to go to the trouble of introducing version detection and ifdefs. Github-Pull: #35175 Rebased-From: 0bc9d354dfd8074d1c36a891a69b6585a8775c65 --- src/node/miner.h | 11 ++++------- src/txmempool.h | 10 ++++------ src/txrequest.cpp | 12 +++++------- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/node/miner.h b/src/node/miner.h index 56101561b11..c45c97100d8 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -102,7 +102,9 @@ struct CompareTxIterByAncestorCount { }; -struct CTxMemPoolModifiedEntry_Indices final : boost::multi_index::indexed_by< +using indexed_modified_transaction_set = boost::multi_index_container< + CTxMemPoolModifiedEntry, + boost::multi_index::indexed_by< boost::multi_index::ordered_unique< modifiedentry_iter, CompareCTxMemPoolIter @@ -115,12 +117,7 @@ struct CTxMemPoolModifiedEntry_Indices final : boost::multi_index::indexed_by< CompareTxMemPoolEntryByAncestorFee > > -{}; - -typedef boost::multi_index_container< - CTxMemPoolModifiedEntry, - CTxMemPoolModifiedEntry_Indices -> indexed_modified_transaction_set; +>; typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter; typedef indexed_modified_transaction_set::index::type::iterator modtxscoreiter; diff --git a/src/txmempool.h b/src/txmempool.h index 10acb2aa22f..acc52aef1d9 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -329,7 +329,9 @@ class CTxMemPool static const int ROLLING_FEE_HALFLIFE = 60 * 60 * 12; // public only for testing - struct CTxMemPoolEntry_Indices final : boost::multi_index::indexed_by< + using indexed_transaction_set = boost::multi_index_container< + CTxMemPoolEntry, + boost::multi_index::indexed_by< // sorted by txid boost::multi_index::hashed_unique, // sorted by wtxid @@ -357,11 +359,7 @@ class CTxMemPool CompareTxMemPoolEntryByAncestorFee > > - {}; - typedef boost::multi_index_container< - CTxMemPoolEntry, - CTxMemPoolEntry_Indices - > indexed_transaction_set; + >; /** * This mutex needs to be locked when accessing `mapTx` or other members diff --git a/src/txrequest.cpp b/src/txrequest.cpp index 5909146427b..521ddec901d 100644 --- a/src/txrequest.cpp +++ b/src/txrequest.cpp @@ -212,17 +212,15 @@ struct ByTimeViewExtractor } }; -struct Announcement_Indices final : boost::multi_index::indexed_by< - boost::multi_index::ordered_unique, ByPeerViewExtractor>, - boost::multi_index::ordered_non_unique, ByTxHashViewExtractor>, - boost::multi_index::ordered_non_unique, ByTimeViewExtractor> -> -{}; /** Data type for the main data structure (Announcement objects with ByPeer/ByTxHash/ByTime indexes). */ using Index = boost::multi_index_container< Announcement, - Announcement_Indices + boost::multi_index::indexed_by< + boost::multi_index::ordered_unique, ByPeerViewExtractor>, + boost::multi_index::ordered_non_unique, ByTxHashViewExtractor>, + boost::multi_index::ordered_non_unique, ByTimeViewExtractor> + > >; /** Helper type to simplify syntax of iterator types. */ From 9ad085bd8397287e8876673d6b8613add9cf73a1 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Tue, 5 May 2026 07:52:08 -0400 Subject: [PATCH 276/314] validation: correct lifetime of precomputed tx data This makes sure `txsdata` always outlives the Script check queue (since local objects are destructed in reverse order of construction). This is the root cause for a security vulnerability reported by Cory Fields in 2024 that could be exploited by crafting an invalid block to cause nodes to read freed memory. The vulnerability was covertly fixed in commit `492e1f09943fcb6145c21d470299305a19e17d8b`. See security advisory for CVE-2024-52911 for more details. Github-Pull: #35209 Rebased-From: 1ed799fb21db51a12cbd5579420a61b9b5b3ee7d --- src/validation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/validation.cpp b/src/validation.cpp index 3d6ebd30e5b..90711c2089a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2615,8 +2615,8 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state, // in multiple threads). Preallocate the vector size so a new allocation // doesn't invalidate pointers into the vector, and keep txsdata in scope // for as long as `control`. - CCheckQueueControl control(fScriptChecks && parallel_script_checks ? &m_chainman.GetCheckQueue() : nullptr); std::vector txsdata(block.vtx.size()); + CCheckQueueControl control(fScriptChecks && parallel_script_checks ? &m_chainman.GetCheckQueue() : nullptr); std::vector prevheights; CAmount nFees = 0; From 18739ec4886f3e66a1062777e01dc4e181e0019e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Sun, 3 May 2026 15:36:47 +0200 Subject: [PATCH 277/314] ci: unconfine seccomp for i686 no IPC Docker 29.4.2 blocks `socketcall(2)` in the default seccomp profile: https://docs.docker.com/engine/release-notes/29/#2942 https://github.com/moby/profiles/releases/tag/seccomp%2Fv0.2.2 https://github.com/moby/moby/pull/52501 That affects the `i686, no IPC` job because it runs 32-bit Linux test binaries inside Docker. Add Docker's documented `--security-opt seccomp=unconfined` workaround to this job's `CI_CONTAINER_CAP` - the hook `ci/test/02_run_container.py` already appends to `docker run`. This restores socket availability for the 32-bit test binaries throughout the job: https://docs.docker.com/engine/security/seccomp/#run-without-the-default-seccomp-profile Github-Pull: #35202 Rebased-From: 11c9ef92a8daf030f75f88f324396b2248c65a64 --- ci/test/00_setup_env_i686_multiprocess.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/test/00_setup_env_i686_multiprocess.sh b/ci/test/00_setup_env_i686_multiprocess.sh index d7c8e3ef1b9..44bc38e319c 100755 --- a/ci/test/00_setup_env_i686_multiprocess.sh +++ b/ci/test/00_setup_env_i686_multiprocess.sh @@ -10,6 +10,7 @@ export HOST=i686-pc-linux-gnu export CONTAINER_NAME=ci_i686_multiprocess export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export CI_IMAGE_PLATFORM="linux/amd64" +export CI_CONTAINER_CAP="--security-opt seccomp=unconfined" export PACKAGES="llvm clang g++-multilib" export DEP_OPTS="DEBUG=1 MULTIPROCESS=1" export GOAL="install" From 83b46506a1096154f9619066e81b1b234c71a274 Mon Sep 17 00:00:00 2001 From: fanquake Date: Thu, 19 Mar 2026 14:44:15 +0800 Subject: [PATCH 278/314] doc: update release notes for v29.x --- doc/release-notes.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/release-notes.md b/doc/release-notes.md index 764f778e5d4..c69faf32572 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -41,19 +41,34 @@ Notable changes - #34093 netif: fix compilation warning in QueryDefaultGatewayImpl() +### Build + +- #34848 cmake: Migrate away from deprecated SQLite3 target + ### Doc - #34510 doc: fix broken bpftrace installation link - #34561 wallet: rpc: manpage: fix example missing `fee_rate` argument - #34671 doc: Update Guix install for Debian/Ubuntu +### CI + +- #35202 ci: restore sockets in i686, no IPC job + +### Misc + +- #35175 multi_index: fix compilation failure with boost >= 1.91 + Credits ======= Thanks to everyone who directly contributed to this release: +- Cory Fields +- Daniel Pfeifer - Hennadii Stepanov - jayvaliya +- Lőrinc - MarcoFalke - SomberNight - ToRyVand From e1c714f2d5f7b6caeaaf3631ce9547045e96c6a2 Mon Sep 17 00:00:00 2001 From: Tom Trevethan Date: Mon, 11 May 2026 15:53:53 +0100 Subject: [PATCH 279/314] remove deprecated rpc check for create_bdb wallets --- CMakeLists.txt | 4 ++-- src/wallet/rpc/wallet.cpp | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a540db7b7c4..3b183c93ce7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,7 +94,7 @@ option(BUILD_DAEMON "Build elementsd executable." ON) option(BUILD_GUI "Build elements-qt executable." OFF) option(BUILD_CLI "Build elements-cli executable." ON) -option(BUILD_TESTS "Build test_bitcoin executable." ON) +option(BUILD_TESTS "Build test_elements executable." ON) option(BUILD_TX "Build elements-tx executable." ${BUILD_TESTS}) option(BUILD_UTIL "Build elements-util executable." ${BUILD_TESTS}) @@ -670,7 +670,7 @@ message(" USDT tracing ........................ ${WITH_USDT}") message(" QR code (GUI) ....................... ${WITH_QRENCODE}") message(" DBus (GUI, Linux only) .............. ${WITH_DBUS}") message("Tests:") -message(" test_bitcoin ........................ ${BUILD_TESTS}") +message(" test_elements ........................ ${BUILD_TESTS}") message(" test_elements-qt .................... ${BUILD_GUI_TESTS}") message(" bench_bitcoin ....................... ${BUILD_BENCH}") message(" fuzz binary ......................... ${BUILD_FUZZ_BINARY}") diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp index f4d140076c7..ac49e615f6f 100644 --- a/src/wallet/rpc/wallet.cpp +++ b/src/wallet/rpc/wallet.cpp @@ -416,12 +416,15 @@ static RPCHelpMan createwallet() throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without sqlite support (required for descriptor wallets)"); #endif flags |= WALLET_FLAG_DESCRIPTORS; - } else { + } + /* ELEMENTS: Remove the IsDeprecatedRPCEnabled("create_bdb") check so descriptors=false always works without a runtime flag + else { if (!context.chain->rpcEnableDeprecated("create_bdb")) { throw JSONRPCError(RPC_WALLET_ERROR, "BDB wallet creation is deprecated and will be removed in a future release." " In this release it can be re-enabled temporarily with the -deprecatedrpc=create_bdb setting."); } } + */ if (!request.params[7].isNull() && request.params[7].get_bool()) { #ifdef ENABLE_EXTERNAL_SIGNER flags |= WALLET_FLAG_EXTERNAL_SIGNER; From f29fe12e1e8e3b8c9611ca4717c2c75b38c65d5d Mon Sep 17 00:00:00 2001 From: Tom Trevethan Date: Mon, 11 May 2026 23:57:42 +0100 Subject: [PATCH 280/314] rename test_bitcoin to test_elements --- ci/test/03_test_script.sh | 2 +- cmake/module/AddBoostIfNeeded.cmake | 2 +- cmake/module/GenerateSetupNsi.cmake | 2 +- cmake/module/Maintenance.cmake | 6 +++--- cmake/script/Coverage.cmake | 12 +++++------ .../devtools/test_deterministic_coverage.sh | 2 +- contrib/valgrind.supp | 6 +++--- src/test/CMakeLists.txt | 20 +++++++++---------- src/wallet/test/CMakeLists.txt | 4 ++-- vcpkg.json | 2 +- 10 files changed, 29 insertions(+), 29 deletions(-) diff --git a/ci/test/03_test_script.sh b/ci/test/03_test_script.sh index a9b8f73fe6d..4a07fa71a98 100755 --- a/ci/test/03_test_script.sh +++ b/ci/test/03_test_script.sh @@ -179,7 +179,7 @@ if [ "$RUN_UNIT_TESTS" = "true" ]; then fi if [ "$RUN_UNIT_TESTS_SEQUENTIAL" = "true" ]; then - DIR_UNIT_TEST_DATA="${DIR_UNIT_TEST_DATA}" LD_LIBRARY_PATH="${DEPENDS_DIR}/${HOST}/lib" "${BASE_OUTDIR}"/bin/test_bitcoin --catch_system_errors=no -l test_suite + DIR_UNIT_TEST_DATA="${DIR_UNIT_TEST_DATA}" LD_LIBRARY_PATH="${DEPENDS_DIR}/${HOST}/lib" "${BASE_OUTDIR}"/bin/test_elements --catch_system_errors=no -l test_suite fi if [ "$RUN_FUNCTIONAL_TESTS" = "true" ]; then diff --git a/cmake/module/AddBoostIfNeeded.cmake b/cmake/module/AddBoostIfNeeded.cmake index ecd0d6f2aba..589c88bf744 100644 --- a/cmake/module/AddBoostIfNeeded.cmake +++ b/cmake/module/AddBoostIfNeeded.cmake @@ -71,7 +71,7 @@ function(add_boost_if_needed) include(CheckIncludeFileCXX) check_include_file_cxx(boost/test/included/unit_test.hpp HAVE_BOOST_INCLUDED_UNIT_TEST_H) if(NOT HAVE_BOOST_INCLUDED_UNIT_TEST_H) - message(FATAL_ERROR "Building test_bitcoin executable requested but boost/test/included/unit_test.hpp header not available.") + message(FATAL_ERROR "Building test_elements executable requested but boost/test/included/unit_test.hpp header not available.") endif() endif() diff --git a/cmake/module/GenerateSetupNsi.cmake b/cmake/module/GenerateSetupNsi.cmake index f4b825a0f0a..39a141e123b 100644 --- a/cmake/module/GenerateSetupNsi.cmake +++ b/cmake/module/GenerateSetupNsi.cmake @@ -12,7 +12,7 @@ function(generate_setup_nsi) set(BITCOIN_CLI_NAME "elements-cli") set(BITCOIN_TX_NAME "elements-tx") set(BITCOIN_WALLET_TOOL_NAME "elements-wallet") - set(BITCOIN_TEST_NAME "test_bitcoin") + set(BITCOIN_TEST_NAME "test_elements") set(EXEEXT ${CMAKE_EXECUTABLE_SUFFIX}) configure_file(${PROJECT_SOURCE_DIR}/share/setup.nsi.in ${PROJECT_BINARY_DIR}/elements-win64-setup.nsi USE_SOURCE_PERMISSIONS @ONLY) endfunction() diff --git a/cmake/module/Maintenance.cmake b/cmake/module/Maintenance.cmake index 522d5844ac3..13e6b95ac7e 100644 --- a/cmake/module/Maintenance.cmake +++ b/cmake/module/Maintenance.cmake @@ -23,7 +23,7 @@ function(add_maintenance_targets) return() endif() - foreach(target IN ITEMS elementsd elements-qt elements-cli elements-tx elements-util elements-wallet test_bitcoin bench_bitcoin) + foreach(target IN ITEMS elementsd elements-qt elements-cli elements-tx elements-util elements-wallet test_elements bench_bitcoin) if(TARGET ${target}) list(APPEND executables $) endif() @@ -43,7 +43,7 @@ function(add_maintenance_targets) endfunction() function(add_windows_deploy_target) - if(MINGW AND TARGET elements-qt AND TARGET elementsd AND TARGET elements-cli AND TARGET elements-tx AND TARGET elements-wallet AND TARGET elements-util AND TARGET test_bitcoin) + if(MINGW AND TARGET elements-qt AND TARGET elementsd AND TARGET elements-cli AND TARGET elements-tx AND TARGET elements-wallet AND TARGET elements-util AND TARGET test_elements) # TODO: Consider replacing this code with the CPack NSIS Generator. # See https://cmake.org/cmake/help/latest/cpack_gen/nsis.html include(GenerateSetupNsi) @@ -57,7 +57,7 @@ function(add_windows_deploy_target) COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ + COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ COMMAND makensis -V2 ${PROJECT_BINARY_DIR}/elements-win64-setup.nsi VERBATIM ) diff --git a/cmake/script/Coverage.cmake b/cmake/script/Coverage.cmake index 72587a5eb6a..7394e5157dc 100644 --- a/cmake/script/Coverage.cmake +++ b/cmake/script/Coverage.cmake @@ -19,7 +19,7 @@ execute_process( COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${LCOV_COMMAND} --capture --directory src --test-name test_bitcoin --output-file test_bitcoin.info + COMMAND ${LCOV_COMMAND} --capture --directory src --test-name test_elements --output-file test_elements.info WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) @@ -29,22 +29,22 @@ execute_process( COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${LCOV_FILTER_COMMAND} test_bitcoin.info test_bitcoin_filtered.info + COMMAND ${LCOV_FILTER_COMMAND} test_elements.info test_elements_filtered.info WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${LCOV_COMMAND} --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_filtered.info + COMMAND ${LCOV_COMMAND} --add-tracefile test_elements_filtered.info --output-file test_elements_filtered.info WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_coverage.info + COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_elements_filtered.info --output-file test_elements_coverage.info WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${GENHTML_COMMAND} test_bitcoin_coverage.info --output-directory test_bitcoin.coverage + COMMAND ${GENHTML_COMMAND} test_elements_coverage.info --output-directory test_elements.coverage WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) @@ -75,7 +75,7 @@ execute_process( COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --add-tracefile functional_test_filtered.info --output-file total_coverage.info + COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_elements_filtered.info --add-tracefile functional_test_filtered.info --output-file total_coverage.info COMMAND ${GREP_EXECUTABLE} "%" COMMAND ${AWK_EXECUTABLE} "{ print substr($3,2,50) \"/\" $5 }" OUTPUT_FILE coverage_percent.txt diff --git a/contrib/devtools/test_deterministic_coverage.sh b/contrib/devtools/test_deterministic_coverage.sh index 885396bb259..988db90fd29 100755 --- a/contrib/devtools/test_deterministic_coverage.sh +++ b/contrib/devtools/test_deterministic_coverage.sh @@ -34,7 +34,7 @@ NON_DETERMINISTIC_TESTS=( "wallet_tests/wallet_disableprivkeys" # validation.cpp: if (signals.CallbacksPending() > 10) ) -TEST_BITCOIN_BINARY="src/test/test_bitcoin" +TEST_BITCOIN_BINARY="src/test/test_elements" print_usage() { echo "Usage: $0 [custom test filter (default: all but known non-deterministic tests)] [number of test runs (default: 2)]" diff --git a/contrib/valgrind.supp b/contrib/valgrind.supp index 9a9e640c615..87f3874ddbc 100644 --- a/contrib/valgrind.supp +++ b/contrib/valgrind.supp @@ -2,14 +2,14 @@ # dependencies that cannot be fixed in-tree. # # Example use: -# $ valgrind --suppressions=contrib/valgrind.supp build/bin/test_bitcoin +# $ valgrind --suppressions=contrib/valgrind.supp build/bin/test_elements # $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ -# --show-leak-kinds=all build/bin/test_bitcoin +# --show-leak-kinds=all build/bin/test_elements # # To create suppressions for found issues, use the --gen-suppressions=all option: # $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ # --show-leak-kinds=all --gen-suppressions=all --show-reachable=yes \ -# --error-limit=no build/bin/test_bitcoin +# --error-limit=no build/bin/test_elements # # Note that suppressions may depend on OS and/or library versions. # Tested on: diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index e33f133f7de..073bea63040 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -4,7 +4,7 @@ # Do not use generator expressions in test sources because the # SOURCES property is processed to gather test suite macros. -add_executable(test_bitcoin +add_executable(test_elements main.cpp addrman_tests.cpp allocator_tests.cpp @@ -130,7 +130,7 @@ add_executable(test_bitcoin ) include(TargetDataSources) -target_json_data_sources(test_bitcoin +target_json_data_sources(test_elements data/base58_encode_decode.json data/bip341_wallet_vectors.json data/blockfilters.json @@ -141,11 +141,11 @@ target_json_data_sources(test_bitcoin data/tx_invalid.json data/tx_valid.json ) -target_raw_data_sources(test_bitcoin NAMESPACE test::data +target_raw_data_sources(test_elements NAMESPACE test::data data/asmap.raw ) -target_link_libraries(test_bitcoin +target_link_libraries(test_elements core_interface test_util bitcoin_cli @@ -169,11 +169,11 @@ if(WITH_MULTIPROCESS) univalue ) - target_sources(test_bitcoin + target_sources(test_elements PRIVATE ipc_tests.cpp ) - target_link_libraries(test_bitcoin bitcoin_ipc_test bitcoin_ipc) + target_link_libraries(test_elements bitcoin_ipc_test bitcoin_ipc) endif() function(add_boost_test source_file) @@ -192,7 +192,7 @@ function(add_boost_test source_file) ) if(test_suite_name) add_test(NAME ${test_suite_name} - COMMAND test_bitcoin --run_test=${test_suite_name} --catch_system_error=no --log_level=test_suite -- DEBUG_LOG_OUT + COMMAND test_elements --run_test=${test_suite_name} --catch_system_error=no --log_level=test_suite -- DEBUG_LOG_OUT ) set_property(TEST ${test_suite_name} PROPERTY SKIP_REGULAR_EXPRESSION "no test cases matching filter" @@ -201,8 +201,8 @@ function(add_boost_test source_file) endfunction() function(add_all_test_targets) - get_target_property(test_source_dir test_bitcoin SOURCE_DIR) - get_target_property(test_sources test_bitcoin SOURCES) + get_target_property(test_source_dir test_elements SOURCE_DIR) + get_target_property(test_sources test_elements SOURCES) foreach(test_source ${test_sources}) cmake_path(IS_RELATIVE test_source result) if(result) @@ -214,4 +214,4 @@ endfunction() add_all_test_targets() -install_binary_component(test_bitcoin) +install_binary_component(test_elements) diff --git a/src/wallet/test/CMakeLists.txt b/src/wallet/test/CMakeLists.txt index f14a78ca1d2..2d66c6e3538 100644 --- a/src/wallet/test/CMakeLists.txt +++ b/src/wallet/test/CMakeLists.txt @@ -4,7 +4,7 @@ # Do not use generator expressions in test sources because the # SOURCES property is processed to gather test suite macros. -target_sources(test_bitcoin +target_sources(test_elements PRIVATE init_test_fixture.cpp wallet_test_fixture.cpp @@ -23,4 +23,4 @@ target_sources(test_bitcoin walletdb_tests.cpp walletload_tests.cpp ) -target_link_libraries(test_bitcoin bitcoin_wallet) +target_link_libraries(test_elements bitcoin_wallet) diff --git a/vcpkg.json b/vcpkg.json index d5dfb05ebe0..2e9d6e99566 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -35,7 +35,7 @@ ] }, "tests": { - "description": "Build test_bitcoin.exe executable", + "description": "Build test_elements.exe executable", "dependencies": [ "boost-test" ] From 4e3dd136b85a595e95c9a42a1cfd61e596ac8392 Mon Sep 17 00:00:00 2001 From: junbyjun1238 <251473466+junbyjun1238@users.noreply.github.com> Date: Thu, 14 May 2026 00:30:10 +0900 Subject: [PATCH 281/314] doc: mention -DWITH_ZMQ=ON in BSD build guides The FreeBSD, NetBSD, and OpenBSD build guides state that ZMQ support is compiled in when the package is installed. Since WITH_ZMQ defaults to OFF, update the wording to mention the required CMake option. Github-Pull: #35283 Rebased-From: ca93ab808c488324990eb91ed8297a37dd10d580 --- doc/build-freebsd.md | 2 +- doc/build-netbsd.md | 2 +- doc/build-openbsd.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index 549d189e7d1..63318840119 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -86,7 +86,7 @@ Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` #### Notifications ###### 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 pkg install libzmq4 ``` diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index 05b80eb7476..5b01d7b912c 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -86,7 +86,7 @@ Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` #### Notifications ###### 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 pkgin zeromq ``` diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index 7ab51054ad2..e2a15f67c86 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -80,7 +80,7 @@ Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` #### Notifications ###### 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 pkg_add zeromq ``` From cec3d1d6f67c678a03c0fccdf6492becc49da3a2 Mon Sep 17 00:00:00 2001 From: Tom Trevethan Date: Tue, 12 May 2026 01:32:04 +0100 Subject: [PATCH 282/314] gui: re-enable legacy wallet creation --- src/qt/bitcoingui.cpp | 27 +++++------ src/qt/bitcoingui.h | 2 - src/qt/createwalletdialog.cpp | 20 +++++++++ src/qt/createwalletdialog.h | 1 + src/qt/forms/createwalletdialog.ui | 72 +++++++----------------------- src/qt/walletcontroller.cpp | 5 ++- 6 files changed, 50 insertions(+), 77 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 0d121df73fd..defe6df810c 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -111,7 +111,10 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty { /** Create wallet frame and make it the central widget */ walletFrame = new WalletFrame(_platformStyle, this); - connect(walletFrame, &WalletFrame::createWalletButtonClicked, this, &BitcoinGUI::createWallet); + connect(walletFrame, &WalletFrame::createWalletButtonClicked, [this] { + auto activity = new CreateWalletActivity(getWalletController(), this); + activity->create(); + }); connect(walletFrame, &WalletFrame::message, [this](const QString& title, const QString& message, unsigned int style) { this->message(title, message, style); }); @@ -448,7 +451,12 @@ void BitcoinGUI::createActions() connect(m_close_wallet_action, &QAction::triggered, [this] { m_wallet_controller->closeWallet(walletFrame->currentWalletModel(), this); }); - connect(m_create_wallet_action, &QAction::triggered, this, &BitcoinGUI::createWallet); + connect(m_create_wallet_action, &QAction::triggered, [this] { + auto activity = new CreateWalletActivity(m_wallet_controller, this); + connect(activity, &CreateWalletActivity::created, this, &BitcoinGUI::setCurrentWallet); + connect(activity, &CreateWalletActivity::created, rpcConsole, &RPCConsole::setCurrentWallet); + activity->create(); + }); connect(m_close_all_wallets_action, &QAction::triggered, [this] { m_wallet_controller->closeAllWallets(this); }); @@ -1198,21 +1206,6 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer progressBar->setToolTip(tooltip); } -void BitcoinGUI::createWallet() -{ -#ifdef ENABLE_WALLET -#ifndef USE_SQLITE - // Compiled without sqlite support (required for descriptor wallets) - message(tr("Error creating wallet"), tr("Cannot create new wallet, the software was compiled without sqlite support (required for descriptor wallets)"), CClientUIInterface::MSG_ERROR); - return; -#endif // USE_SQLITE - auto activity = new CreateWalletActivity(getWalletController(), this); - connect(activity, &CreateWalletActivity::created, this, &BitcoinGUI::setCurrentWallet); - connect(activity, &CreateWalletActivity::created, rpcConsole, &RPCConsole::setCurrentWallet); - activity->create(); -#endif // ENABLE_WALLET -} - void BitcoinGUI::message(const QString& title, QString message, unsigned int style, bool* ret, const QString& detailed_message) { // Default title. On macOS, the window title is ignored (as required by the macOS Guidelines). diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 30b9210af0f..f82d8aa6fb1 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -227,8 +227,6 @@ public Q_SLOTS: void setNetworkActive(bool network_active); /** Set number of blocks and last block date shown in the UI */ void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state); - /** Launch the wallet creation modal (no-op if wallet is not compiled) **/ - void createWallet(); /** Notify the user of an event from the core network or transaction handling code. @param[in] title the message box / notification title diff --git a/src/qt/createwalletdialog.cpp b/src/qt/createwalletdialog.cpp index 2908043d28e..0ccf9a53336 100644 --- a/src/qt/createwalletdialog.cpp +++ b/src/qt/createwalletdialog.cpp @@ -48,10 +48,12 @@ CreateWalletDialog::CreateWalletDialog(QWidget* parent) : ui->encrypt_wallet_checkbox->setEnabled(!checked); ui->blank_wallet_checkbox->setEnabled(!checked); ui->disable_privkeys_checkbox->setEnabled(!checked); + ui->descriptor_checkbox->setEnabled(!checked); // The external signer checkbox is only enabled when a device is detected. // In that case it is checked by default. Toggling it restores the other // options to their default. + ui->descriptor_checkbox->setChecked(checked); ui->encrypt_wallet_checkbox->setChecked(false); ui->disable_privkeys_checkbox->setChecked(checked); ui->blank_wallet_checkbox->setChecked(false); @@ -83,6 +85,19 @@ CreateWalletDialog::CreateWalletDialog(QWidget* parent) : } }); +#ifndef USE_SQLITE + ui->descriptor_checkbox->setToolTip(tr("Compiled without sqlite support (required for descriptor wallets)")); + ui->descriptor_checkbox->setEnabled(false); + ui->descriptor_checkbox->setChecked(false); + ui->external_signer_checkbox->setEnabled(false); + ui->external_signer_checkbox->setChecked(false); +#endif + +#ifndef USE_BDB + ui->descriptor_checkbox->setEnabled(false); + ui->descriptor_checkbox->setChecked(true); +#endif + #ifndef ENABLE_EXTERNAL_SIGNER //: "External signing" means using devices such as hardware wallets. ui->external_signer_checkbox->setToolTip(tr("Compiled without external signing support (required for external signing)")); @@ -138,6 +153,11 @@ bool CreateWalletDialog::isMakeBlankWalletChecked() const return ui->blank_wallet_checkbox->isChecked(); } +bool CreateWalletDialog::isDescriptorWalletChecked() const +{ + return ui->descriptor_checkbox->isChecked(); +} + bool CreateWalletDialog::isExternalSignerChecked() const { return ui->external_signer_checkbox->isChecked(); diff --git a/src/qt/createwalletdialog.h b/src/qt/createwalletdialog.h index 24ee97385b0..939b82ff78c 100644 --- a/src/qt/createwalletdialog.h +++ b/src/qt/createwalletdialog.h @@ -35,6 +35,7 @@ class CreateWalletDialog : public QDialog bool isEncryptWalletChecked() const; bool isDisablePrivateKeysChecked() const; bool isMakeBlankWalletChecked() const; + bool isDescriptorWalletChecked() const; bool isExternalSignerChecked() const; private: diff --git a/src/qt/forms/createwalletdialog.ui b/src/qt/forms/createwalletdialog.ui index 1d6f0ed530a..56adbe17a5c 100644 --- a/src/qt/forms/createwalletdialog.ui +++ b/src/qt/forms/createwalletdialog.ui @@ -6,8 +6,8 @@ 0 0 - 371 - 298 + 364 + 249 @@ -17,48 +17,6 @@ true - - - - - 0 - 0 - - - - You are one step away from creating your new wallet! - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - false - - - - - - - Please provide a name and, if desired, enable any advanced options - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 3 - - - - @@ -117,19 +75,7 @@ Advanced Options - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - false - - - false - - - 9 - @@ -153,6 +99,19 @@ + + + + Use descriptors for scriptPubKey management + + + Descriptor Wallet + + + true + + + @@ -196,6 +155,7 @@ encrypt_wallet_checkbox disable_privkeys_checkbox blank_wallet_checkbox + descriptor_checkbox external_signer_checkbox diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index f0d72eaf73d..2bf9d7d958a 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -255,14 +255,15 @@ void CreateWalletActivity::createWallet() std::string name = m_create_wallet_dialog->walletName().toStdString(); uint64_t flags = 0; - // Enable descriptors by default. - flags |= WALLET_FLAG_DESCRIPTORS; if (m_create_wallet_dialog->isDisablePrivateKeysChecked()) { flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS; } if (m_create_wallet_dialog->isMakeBlankWalletChecked()) { flags |= WALLET_FLAG_BLANK_WALLET; } + if (m_create_wallet_dialog->isDescriptorWalletChecked()) { + flags |= WALLET_FLAG_DESCRIPTORS; + } if (m_create_wallet_dialog->isExternalSignerChecked()) { flags |= WALLET_FLAG_EXTERNAL_SIGNER; } From c4680ed0821fa520ed63fc6a7d5c9c8496115bb8 Mon Sep 17 00:00:00 2001 From: Tom Trevethan Date: Tue, 19 May 2026 14:17:41 +0100 Subject: [PATCH 283/314] re-enable add checks for CCheckQueueControl in connectblock --- src/validation.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index aead124a2e5..3fa097633d9 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3029,11 +3029,8 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state, tx_state.GetDebugMessage() + " in transaction " + tx.GetHash().ToString()); break; } - // control.Add(vChecks); - // - // if (!MoneyRange(fee_map)) { - // LogPrintf("ERROR: %s: accumulated fee in the block out of range.\n", __func__); - // return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-accumulated-fee-outofrange"); + control.Add(vChecks); + if (!MoneyRange(fee_map)) { state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-accumulated-fee-outofrange", "accumulated fee in the block out of range"); From 005738e3b846d1ba33f8d4a24f93c238fcf52f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Wed, 6 May 2026 14:27:13 +0200 Subject: [PATCH 284/314] wallet: use outpoint when estimating input size `CalculateMaximumSignedInputSize()` is passed the outpoint being sized, but that context was not used when estimating the signed input size. Pass the outpoint through so externally selected inputs are not underestimated. Co-authored-by: Antoine Poinsot Github-Pull: #35228 Rebased-From: cd8d3bd937b5515ea000408eb07d2ae3cd1aa417 --- src/wallet/spend.cpp | 2 +- src/wallet/test/spend_tests.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index f45db1c16f3..26924d63526 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -92,7 +92,7 @@ int CalculateMaximumSignedInputSize(const CTxOut& txout, const COutPoint outpoin if (!provider) return -1; 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(GetVirtualTransactionSize(*weight, 0, 0)); } } diff --git a/src/wallet/test/spend_tests.cpp b/src/wallet/test/spend_tests.cpp index 963c0f838b1..ac76fe4dda0 100644 --- a/src/wallet/test/spend_tests.cpp +++ b/src/wallet/test/spend_tests.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include #include