aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac8
-rwxr-xr-xcontrib/devtools/symbol-check.py6
-rw-r--r--doc/bips.md2
-rw-r--r--doc/man/bitcoin-cli.1182
-rw-r--r--doc/man/bitcoin-qt.1819
-rw-r--r--doc/man/bitcoin-tx.1146
-rw-r--r--doc/man/bitcoin-util.166
-rw-r--r--doc/man/bitcoin-wallet.1122
-rw-r--r--doc/man/bitcoind.1797
-rw-r--r--share/examples/bitcoin.conf686
-rw-r--r--src/Makefile.am2
-rw-r--r--src/script/miniscript.h282
-rw-r--r--src/test/miniscript_tests.cpp3
-rw-r--r--src/wallet/interfaces.cpp24
-rw-r--r--src/wallet/wallet.cpp34
-rw-r--r--src/zmq/zmqnotificationinterface.cpp2
-rw-r--r--src/zmq/zmqpublishnotifier.cpp1
17 files changed, 3038 insertions, 144 deletions
diff --git a/configure.ac b/configure.ac
index 12f8f2dcc6..e60ae73c01 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,9 +1,9 @@
AC_PREREQ([2.69])
-define(_CLIENT_VERSION_MAJOR, 23)
-define(_CLIENT_VERSION_MINOR, 99)
+define(_CLIENT_VERSION_MAJOR, 24)
+define(_CLIENT_VERSION_MINOR, 0)
define(_CLIENT_VERSION_BUILD, 0)
-define(_CLIENT_VERSION_RC, 0)
-define(_CLIENT_VERSION_IS_RELEASE, false)
+define(_CLIENT_VERSION_RC, 1)
+define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2022)
define(_COPYRIGHT_HOLDERS,[The %s developers])
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin Core]])
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index 23d29af3f1..4b1cceb57c 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -35,7 +35,6 @@ import lief #type:ignore
MAX_VERSIONS = {
'GCC': (4,8,0),
'GLIBC': {
- lief.ELF.ARCH.i386: (2,18),
lief.ELF.ARCH.x86_64: (2,18),
lief.ELF.ARCH.ARM: (2,18),
lief.ELF.ARCH.AARCH64:(2,18),
@@ -45,8 +44,6 @@ MAX_VERSIONS = {
'LIBATOMIC': (1,0),
'V': (0,5,0), # xkb (bitcoin-qt only)
}
-# See here for a description of _IO_stdin_used:
-# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109
# Ignore symbols that are exported as part of every executable
IGNORE_EXPORTS = {
@@ -57,9 +54,6 @@ IGNORE_EXPORTS = {
# Expected linker-loader names can be found here:
# https://sourceware.org/glibc/wiki/ABIList?action=recall&rev=16
ELF_INTERPRETER_NAMES: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, str]] = {
- lief.ELF.ARCH.i386: {
- lief.ENDIANNESS.LITTLE: "/lib/ld-linux.so.2",
- },
lief.ELF.ARCH.x86_64: {
lief.ENDIANNESS.LITTLE: "/lib64/ld-linux-x86-64.so.2",
},
diff --git a/doc/bips.md b/doc/bips.md
index 0f3f61daf1..4119d86aaa 100644
--- a/doc/bips.md
+++ b/doc/bips.md
@@ -1,4 +1,4 @@
-BIPs that are implemented by Bitcoin Core (up-to-date up to **v23.0**):
+BIPs that are implemented by Bitcoin Core (up-to-date up to **v24.0**):
* [`BIP 9`](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki): The changes allowing multiple soft-forks to be deployed in parallel have been implemented since **v0.12.1** ([PR #7575](https://github.com/bitcoin/bitcoin/pull/7575))
* [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
diff --git a/doc/man/bitcoin-cli.1 b/doc/man/bitcoin-cli.1
index 6bcad7006b..926bd3be83 100644
--- a/doc/man/bitcoin-cli.1
+++ b/doc/man/bitcoin-cli.1
@@ -1,5 +1,181 @@
-.TH BITCOIN-CLI "1"
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
+.TH BITCOIN-CLI "1" "September 2022" "bitcoin-cli v24.0.0rc1" "User Commands"
.SH NAME
-bitcoin-cli \- manual page for bitcoin-cli
+bitcoin-cli \- manual page for bitcoin-cli v24.0.0rc1
+.SH SYNOPSIS
+.B bitcoin-cli
+[\fI\,options\/\fR] \fI\,<command> \/\fR[\fI\,params\/\fR] \fI\,Send command to Bitcoin Core\/\fR
+.br
+.B bitcoin-cli
+[\fI\,options\/\fR] \fI\,-named <command> \/\fR[\fI\,name=value\/\fR]... \fI\,Send command to Bitcoin Core (with named arguments)\/\fR
+.br
+.B bitcoin-cli
+[\fI\,options\/\fR] \fI\,help List commands\/\fR
+.br
+.B bitcoin-cli
+[\fI\,options\/\fR] \fI\,help <command> Get help for a command\/\fR
+.SH DESCRIPTION
+Bitcoin Core RPC client version v24.0.0rc1
+.SH OPTIONS
+.HP
+\-?
+.IP
+Print this help message and exit
+.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\-color=\fR<when>
+.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.
+.HP
+\fB\-conf=\fR<file>
+.IP
+Specify configuration file. Relative paths will be prefixed by datadir
+location. (default: bitcoin.conf)
+.HP
+\fB\-datadir=\fR<dir>
+.IP
+Specify data directory
+.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 results of \fB\-getinfo\fR is the result of
+multiple non\-atomic requests. Some entries in the result may
+represent results from different states (e.g. wallet balance may
+be as of a different block from the chain state reported)
+.HP
+\fB\-named\fR
+.IP
+Pass named instead of positional arguments (default: false)
+.HP
+\fB\-netinfo\fR
+.IP
+Get network peer connection information from the remote server. An
+optional integer argument from 0 to 4 can be passed for different
+peers listings (default: 0). Pass "help" for detailed help
+documentation.
+.HP
+\fB\-rpcclienttimeout=\fR<n>
+.IP
+Timeout in seconds during HTTP requests, or 0 for no timeout. (default:
+900)
+.HP
+\fB\-rpcconnect=\fR<ip>
+.IP
+Send commands to node running on <ip> (default: 127.0.0.1)
+.HP
+\fB\-rpccookiefile=\fR<loc>
+.IP
+Location of the auth cookie. Relative paths will be prefixed by a
+net\-specific datadir location. (default: data dir)
+.HP
+\fB\-rpcpassword=\fR<pw>
+.IP
+Password for JSON\-RPC connections
+.HP
+\fB\-rpcport=\fR<port>
+.IP
+Connect to JSON\-RPC on <port> (default: 8332, testnet: 18332, signet:
+38332, regtest: 18443)
+.HP
+\fB\-rpcuser=\fR<user>
+.IP
+Username for JSON\-RPC connections
+.HP
+\fB\-rpcwait\fR
+.IP
+Wait for RPC server to start
+.HP
+\fB\-rpcwaittimeout=\fR<n>
+.IP
+Timeout in seconds to wait for the RPC server to start, or 0 for no
+timeout. (default: 0)
+.HP
+\fB\-rpcwallet=\fR<walletname>
+.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/<walletname>
+.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<chain>
+.IP
+Use the chain <chain> (default: main). Allowed values: main, test,
+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 test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR.
+.SH COPYRIGHT
+Copyright (C) 2009-2022 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
+<https://bitcoincore.org/> for further information about the software.
+The source code is available from <https://github.com/bitcoin/bitcoin>.
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or <https://opensource.org/licenses/MIT> \ No newline at end of file
diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1
index ff4d1d2c7a..90e707b6f0 100644
--- a/doc/man/bitcoin-qt.1
+++ b/doc/man/bitcoin-qt.1
@@ -1,5 +1,818 @@
-.TH BITCOIN-QT "1"
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
+.TH BITCOIN-QT "1" "September 2022" "bitcoin-qt v24.0.0rc1" "User Commands"
.SH NAME
-bitcoin-qt \- manual page for bitcoin-qt
+bitcoin-qt \- manual page for bitcoin-qt v24.0.0rc1
+.SH SYNOPSIS
+.B bitcoin-qt
+[\fI\,command-line options\/\fR]
+.SH DESCRIPTION
+Bitcoin Core version v24.0.0rc1
+.SH OPTIONS
+.HP
+\-?
+.IP
+Print this help message and exit
+.HP
+\fB\-alertnotify=\fR<cmd>
+.IP
+Execute command when an alert is raised (%s in cmd is replaced by
+message)
+.HP
+\fB\-assumevalid=\fR<hex>
+.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:
+00000000000000000009c97098b5295f7e5f183ac811fb5d1534040adb93cabd,
+testnet:
+0000000000000004877fa2d36316398528de4f347df2f8a96f76613a298ce060,
+signet:
+000000d1a0e224fa4679d2fb2187ba55431c284fa1b74cbc8cfda866fd4d2c09)
+.HP
+\fB\-blockfilterindex=\fR<type>
+.IP
+Maintain an index of compact filters by block (default: 0, values:
+basic). If <type> is not supplied or if <type> = 1, indexes for
+all known types are enabled.
+.HP
+\fB\-blocknotify=\fR<cmd>
+.IP
+Execute command when the best block changes (%s in cmd is replaced by
+block hash)
+.HP
+\fB\-blockreconstructionextratxn=\fR<n>
+.IP
+Extra transactions to keep in memory for compact block reconstructions
+(default: 100)
+.HP
+\fB\-blocksdir=\fR<dir>
+.IP
+Specify directory to hold blocks subdirectory for *.dat files (default:
+<datadir>)
+.HP
+\fB\-blocksonly\fR
+.IP
+Whether to reject transactions from network peers. Automatic broadcast
+and rebroadcast of any transactions from inbound peers is
+disabled, unless the peer has the 'forcerelay' permission. RPC
+transactions are not affected. (default: 0)
+.HP
+\fB\-coinstatsindex\fR
+.IP
+Maintain coinstats index used by the gettxoutsetinfo RPC (default: 0)
+.HP
+\fB\-conf=\fR<file>
+.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<dir>
+.IP
+Specify data directory
+.HP
+\fB\-dbcache=\fR<n>
+.IP
+Maximum database cache size <n> MiB (4 to 16384, default: 450). In
+addition, unused mempool memory is shared for this cache (see
+\fB\-maxmempool\fR).
+.HP
+\fB\-debuglogfile=\fR<file>
+.IP
+Specify location of debug log file. Relative paths will be prefixed by a
+net\-specific datadir location. (\fB\-nodebuglogfile\fR to disable;
+default: debug.log)
+.HP
+\fB\-includeconf=\fR<file>
+.IP
+Specify additional configuration file, relative to the \fB\-datadir\fR path
+(only useable from configuration file, not command line)
+.HP
+\fB\-loadblock=\fR<file>
+.IP
+Imports blocks from external file on startup
+.HP
+\fB\-maxmempool=\fR<n>
+.IP
+Keep the transaction memory pool below <n> megabytes (default: 300)
+.HP
+\fB\-maxorphantx=\fR<n>
+.IP
+Keep at most <n> unconnectable transactions in memory (default: 100)
+.HP
+\fB\-mempoolexpiry=\fR<n>
+.IP
+Do not keep transactions in the mempool longer than <n> hours (default:
+336)
+.HP
+\fB\-par=\fR<n>
+.IP
+Set the number of script verification threads (\fB\-10\fR to 15, 0 = auto, <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\-pid=\fR<file>
+.IP
+Specify pid file. Relative paths will be prefixed by a net\-specific
+datadir location. (default: bitcoind.pid)
+.HP
+\fB\-prune=\fR<n>
+.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
+Rebuild chain state and block index from the blk*.dat files on disk.
+This will also rebuild active optional indexes.
+.HP
+\fB\-reindex\-chainstate\fR
+.IP
+Rebuild chain state from the currently indexed blocks. When in pruning
+mode or if blocks on disk might be corrupted, use full \fB\-reindex\fR
+instead. Deactivate all optional indexes before running this.
+.HP
+\fB\-sandbox=\fR<mode>
+.IP
+Use the experimental syscall sandbox in the specified mode
+(\fB\-sandbox\fR=\fI\,log\-and\-abort\/\fR or \fB\-sandbox\fR=\fI\,abort\/\fR). Allow only expected
+syscalls to be used by bitcoind. Note that this is an
+experimental new feature that may cause bitcoind to exit or crash
+unexpectedly: use with caution. In the "log\-and\-abort" mode the
+invocation of an unexpected syscall results in a debug handler
+being invoked which will log the incident and terminate the
+program (without executing the unexpected syscall). In the
+"abort" mode the invocation of an unexpected syscall results in
+the entire process being killed immediately by the kernel without
+executing the unexpected syscall.
+.HP
+\fB\-settings=\fR<file>
+.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\-startupnotify=\fR<cmd>
+.IP
+Execute command on startup.
+.HP
+\fB\-sysperms\fR
+.IP
+Create new files with system default permissions, instead of umask 077
+(only effective with disabled wallet functionality)
+.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>
+.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<file>
+.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<n>
+.IP
+Default duration (in seconds) of manually configured bans (default:
+86400)
+.HP
+\fB\-bind=\fR<addr>[:<port>][=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, testnet: 127.0.0.1:18334=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>
+.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)
+.HP
+\fB\-externalip=\fR<ip>
+.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
+If set and \fB\-i2psam\fR is also set then incoming I2P connections are
+accepted via the SAM proxy. If this is not set but \fB\-i2psam\fR is set
+then only outgoing connections will be made to the I2P network.
+Ignored if \fB\-i2psam\fR is not set. Listening for incoming I2P
+connections is done through the SAM proxy, not by binding to a
+local address and port (default: 1)
+.HP
+\fB\-i2psam=\fR<ip:port>
+.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 or \fB\-connect\fR)
+.HP
+\fB\-listenonion\fR
+.IP
+Automatically create Tor onion service (default: 1)
+.HP
+\fB\-maxconnections=\fR<n>
+.IP
+Maintain at most <n> 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<n>
+.IP
+Maximum per\-connection receive buffer, <n>*1000 bytes (default: 5000)
+.HP
+\fB\-maxsendbuffer=\fR<n>
+.IP
+Maximum per\-connection send buffer, <n>*1000 bytes (default: 1000)
+.HP
+\fB\-maxtimeadjustment\fR
+.IP
+Maximum allowed median peer time offset adjustment. Local perspective of
+time may be influenced by outbound peers forward or backward by
+this amount (default: 4200 seconds).
+.HP
+\fB\-maxuploadtarget=\fR<n>
+.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 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:port>
+.IP
+Use separate SOCKS5 proxy to reach peers via Tor onion services, set
+\fB\-noonion\fR to disable (default: \fB\-proxy\fR)
+.HP
+\fB\-onlynet=\fR<net>
+.IP
+Make automatic outbound connections only to network <net> (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\-permitbaremultisig\fR
+.IP
+Relay non\-P2SH multisig (default: 1)
+.HP
+\fB\-port=\fR<port>
+.IP
+Listen for connections on <port>. Nodes not using the default ports
+(default: 8333, testnet: 18333, signet: 38333, regtest: 18444)
+are unlikely to get incoming connections. Not relevant for I2P
+(see doc/i2p.md).
+.HP
+\fB\-proxy=\fR<ip:port>
+.IP
+Connect through SOCKS5 proxy, set \fB\-noproxy\fR to disable (default:
+disabled)
+.HP
+\fB\-proxyrandomize\fR
+.IP
+Randomize credentials for every proxy connection. This enables Tor
+stream isolation (default: 1)
+.HP
+\fB\-seednode=\fR<ip>
+.IP
+Connect to a node to retrieve peer addresses, and disconnect. This
+option can be specified multiple times to connect to multiple
+nodes.
+.HP
+\fB\-timeout=\fR<n>
+.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>:<port>
+.IP
+Tor control port to use if onion listening enabled (default:
+127.0.0.1:9051)
+.HP
+\fB\-torpassword=\fR<pass>
+.IP
+Tor control port password (default: empty)
+.HP
+\fB\-upnp\fR
+.IP
+Use UPnP to map the listening port (default: 0)
+.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 connecting from 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. 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<amt>
+.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<amt>
+.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<amt>
+.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<n>
+.IP
+Set key pool size to <n> (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<n>
+.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<amt>
+.IP
+Fee rates (in BTC/kvB) smaller than this are considered zero fee for
+transaction creation (default: 0.00001)
+.HP
+\fB\-paytxfee=\fR<amt>
+.IP
+Fee rate (in BTC/kvB) to add to transactions you send (default: 0.00)
+.HP
+\fB\-signer=\fR<cmd>
+.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<n>
+.IP
+If paytxfee is not set, include enough fee so transactions begin
+confirmation on average within n blocks (default: 6)
+.HP
+\fB\-wallet=\fR<path>
+.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 <walletdir>. 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
+<walletdir>.
+.HP
+\fB\-walletbroadcast\fR
+.IP
+Make the wallet broadcast transactions (default: 1)
+.HP
+\fB\-walletdir=\fR<dir>
+.IP
+Specify directory to hold wallets (default: <datadir>/wallets if it
+exists, otherwise <datadir>)
+.HP
+\fB\-walletnotify=\fR<cmd>
+.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<address>
+.IP
+Enable publish hash block in <address>
+.HP
+\fB\-zmqpubhashblockhwm=\fR<n>
+.IP
+Set publish hash block outbound message high water mark (default: 1000)
+.HP
+\fB\-zmqpubhashtx=\fR<address>
+.IP
+Enable publish hash transaction in <address>
+.HP
+\fB\-zmqpubhashtxhwm=\fR<n>
+.IP
+Set publish hash transaction outbound message high water mark (default:
+1000)
+.HP
+\fB\-zmqpubrawblock=\fR<address>
+.IP
+Enable publish raw block in <address>
+.HP
+\fB\-zmqpubrawblockhwm=\fR<n>
+.IP
+Set publish raw block outbound message high water mark (default: 1000)
+.HP
+\fB\-zmqpubrawtx=\fR<address>
+.IP
+Enable publish raw transaction in <address>
+.HP
+\fB\-zmqpubrawtxhwm=\fR<n>
+.IP
+Set publish raw transaction outbound message high water mark (default:
+1000)
+.HP
+\fB\-zmqpubsequence=\fR<address>
+.IP
+Enable publish hash block and tx sequence in <address>
+.HP
+\fB\-zmqpubsequencehwm=\fR<n>
+.IP
+Set publish hash sequence message high water mark (default: 1000)
+.PP
+Debugging/Testing options:
+.HP
+\fB\-debug=\fR<category>
+.IP
+Output debug and trace logging (default: \fB\-nodebug\fR, supplying <category>
+is optional). If <category> is not supplied or if <category> = 1,
+output all debug and trace logging. <category> can be: addrman,
+bench, blockstorage, cmpctblock, coindb, estimatefee, http, i2p,
+ipc, leveldb, libevent, mempool, mempoolrej, net, proxy, prune,
+qt, rand, reindex, rpc, selectcoins, tor, util, validation,
+walletdb, zmq. This option can be specified multiple times to
+output multiple categories.
+.HP
+\fB\-debugexclude=\fR<category>
+.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.
+.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\-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 (only available
+on platforms supporting thread_local) (default: 0)
+.HP
+\fB\-logtimestamps\fR
+.IP
+Prepend debug output with timestamp (default: 1)
+.HP
+\fB\-maxtxfee=\fR<amt>
+.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<cmt>
+.IP
+Append comment to the user agent string
+.PP
+Chain selection options:
+.HP
+\fB\-chain=\fR<chain>
+.IP
+Use the chain <chain> (default: main). Allowed values: main, test,
+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 test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\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
+Maximum size of data in data carrier transactions we relay and mine
+(default: 83)
+.HP
+\fB\-mempoolfullrbf\fR
+.IP
+Accept transaction replace\-by\-fee without requiring replaceability
+signaling (default: 0)
+.HP
+\fB\-minrelaytxfee=\fR<amt>
+.IP
+Fees (in BTC/kvB) smaller than this are considered zero fee for
+relaying, mining and transaction creation (default: 0.00001)
+.HP
+\fB\-whitelistforcerelay\fR
+.IP
+Add 'forcerelay' permission to whitelisted inbound 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 inbound peers with default
+permissions. This will accept relayed transactions even when not
+relaying transactions (default: 1)
+.PP
+Block creation options:
+.HP
+\fB\-blockmaxweight=\fR<n>
+.IP
+Set maximum BIP141 block weight (default: 3996000)
+.HP
+\fB\-blockmintxfee=\fR<amt>
+.IP
+Set lowest fee rate (in BTC/kvB) for transactions to be included in
+block creation. (default: 0.00001)
+.PP
+RPC server options:
+.HP
+\fB\-rest\fR
+.IP
+Accept public REST requests (default: 0)
+.HP
+\fB\-rpcallowip=\fR<ip>
+.IP
+Allow JSON\-RPC connections from specified source. Valid for <ip> are a
+single IP (e.g. 1.2.3.4), a network/netmask (e.g.
+1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This
+option can be specified multiple times
+.HP
+\fB\-rpcauth=\fR<userpw>
+.IP
+Username and HMAC\-SHA\-256 hashed password for JSON\-RPC connections. The
+field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A
+canonical python script is included in share/rpcauth. The client
+then connects normally using the
+rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This
+option can be specified multiple times
+.HP
+\fB\-rpcbind=\fR<addr>[: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<loc>
+.IP
+Location of the auth cookie. Relative paths will be prefixed by a
+net\-specific datadir location. (default: data dir)
+.HP
+\fB\-rpcpassword=\fR<pw>
+.IP
+Password for JSON\-RPC connections
+.HP
+\fB\-rpcport=\fR<port>
+.IP
+Listen for JSON\-RPC connections on <port> (default: 8332, testnet:
+18332, signet: 38332, regtest: 18443)
+.HP
+\fB\-rpcserialversion\fR
+.IP
+Sets the serialization of raw transaction or block hex returned in
+non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1)
+.HP
+\fB\-rpcthreads=\fR<n>
+.IP
+Set the number of threads to service RPC calls (default: 4)
+.HP
+\fB\-rpcuser=\fR<user>
+.IP
+Username for JSON\-RPC connections
+.HP
+\fB\-rpcwhitelist=\fR<whitelist>
+.IP
+Set a whitelist to filter incoming RPC calls for a specific user. The
+field <whitelist> comes in the format: <USERNAME>:<rpc 1>,<rpc
+2>,...,<rpc n>. 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<lang>
+.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-2022 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
+<https://bitcoincore.org/> for further information about the software.
+The source code is available from <https://github.com/bitcoin/bitcoin>.
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or <https://opensource.org/licenses/MIT> \ No newline at end of file
diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1
index 776bb46234..0d21d63ff1 100644
--- a/doc/man/bitcoin-tx.1
+++ b/doc/man/bitcoin-tx.1
@@ -1,5 +1,145 @@
-.TH BITCOIN-TX "1"
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
+.TH BITCOIN-TX "1" "September 2022" "bitcoin-tx v24.0.0rc1" "User Commands"
.SH NAME
-bitcoin-tx \- manual page for bitcoin-tx
+bitcoin-tx \- manual page for bitcoin-tx v24.0.0rc1
+.SH SYNOPSIS
+.B bitcoin-tx
+[\fI\,options\/\fR] \fI\,<hex-tx> \/\fR[\fI\,commands\/\fR] \fI\,Update hex-encoded bitcoin transaction\/\fR
+.br
+.B bitcoin-tx
+[\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] \fI\,Create hex-encoded bitcoin transaction\/\fR
+.SH DESCRIPTION
+Bitcoin Core bitcoin\-tx utility version v24.0.0rc1
+.SH OPTIONS
+.HP
+\-?
+.IP
+Print this help message and exit
+.HP
+\fB\-create\fR
+.IP
+Create new, empty TX.
+.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<chain>
+.IP
+Use the chain <chain> (default: main). Allowed values: main, test,
+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 test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\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
+Set RBF opt\-in sequence number for input N (if not provided, opt\-in all
+available inputs)
+.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-2022 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
+<https://bitcoincore.org/> for further information about the software.
+The source code is available from <https://github.com/bitcoin/bitcoin>.
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or <https://opensource.org/licenses/MIT> \ No newline at end of file
diff --git a/doc/man/bitcoin-util.1 b/doc/man/bitcoin-util.1
index 5c733c6e21..07b1a37341 100644
--- a/doc/man/bitcoin-util.1
+++ b/doc/man/bitcoin-util.1
@@ -1,5 +1,65 @@
-.TH BITCOIN-UTIL "1"
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
+.TH BITCOIN-UTIL "1" "September 2022" "bitcoin-util v24.0.0rc1" "User Commands"
.SH NAME
-bitcoin-util \- manual page for bitcoin-util
+bitcoin-util \- manual page for bitcoin-util v24.0.0rc1
+.SH SYNOPSIS
+.B bitcoin-util
+[\fI\,options\/\fR] [\fI\,commands\/\fR] \fI\,Do stuff\/\fR
+.SH DESCRIPTION
+Bitcoin Core bitcoin\-util utility version v24.0.0rc1
+.SH OPTIONS
+.HP
+\-?
+.IP
+Print this help message and exit
+.HP
+\fB\-version\fR
+.IP
+Print version and exit
+.PP
+Debugging/Testing options:
+.PP
+Chain selection options:
+.HP
+\fB\-chain=\fR<chain>
+.IP
+Use the chain <chain> (default: main). Allowed values: main, test,
+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 test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\fR.
+.PP
+Commands:
+.IP
+grind
+.IP
+Perform proof of work on hex header string
+.SH COPYRIGHT
+Copyright (C) 2009-2022 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
+<https://bitcoincore.org/> for further information about the software.
+The source code is available from <https://github.com/bitcoin/bitcoin>.
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or <https://opensource.org/licenses/MIT> \ No newline at end of file
diff --git a/doc/man/bitcoin-wallet.1 b/doc/man/bitcoin-wallet.1
index 2da43dec66..ed1497dba1 100644
--- a/doc/man/bitcoin-wallet.1
+++ b/doc/man/bitcoin-wallet.1
@@ -1,5 +1,121 @@
-.TH BITCOIN-WALLET "1"
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
+.TH BITCOIN-WALLET "1" "September 2022" "bitcoin-wallet v24.0.0rc1" "User Commands"
.SH NAME
-bitcoin-wallet \- manual page for bitcoin-wallet
+bitcoin-wallet \- manual page for bitcoin-wallet v24.0.0rc1
+.SH DESCRIPTION
+Bitcoin Core bitcoin\-wallet version v24.0.0rc1
+.PP
+bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files.
+By default bitcoin\-wallet will act on wallets in the default mainnet wallet directory in the datadir.
+To change the target wallet, use the \fB\-datadir\fR, \fB\-wallet\fR and \fB\-regtest\fR/\-signet/\-testnet arguments.
+.SS "Usage:"
+.IP
+bitcoin\-wallet [options] <command>
+.SH OPTIONS
+.HP
+\-?
+.IP
+Print this help message and exit
+.HP
+\fB\-datadir=\fR<dir>
+.IP
+Specify data directory
+.HP
+\fB\-descriptors\fR
+.IP
+Create descriptors wallet. Only for 'create'
+.HP
+\fB\-dumpfile=\fR<file name>
+.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<format>
+.IP
+The format of the wallet file to create. Either "bdb" or "sqlite". Only
+used with 'createfromdump'
+.HP
+\fB\-legacy\fR
+.IP
+Create legacy wallet. Only for 'create'
+.HP
+\fB\-version\fR
+.IP
+Print version and exit
+.HP
+\fB\-wallet=\fR<wallet\-name>
+.IP
+Specify wallet name
+.PP
+Debugging/Testing options:
+.HP
+\fB\-debug=\fR<category>
+.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).
+.PP
+Chain selection options:
+.HP
+\fB\-chain=\fR<chain>
+.IP
+Use the chain <chain> (default: main). Allowed values: main, test,
+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 test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\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-2022 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
+<https://bitcoincore.org/> for further information about the software.
+The source code is available from <https://github.com/bitcoin/bitcoin>.
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or <https://opensource.org/licenses/MIT> \ No newline at end of file
diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1
index 2c88f74520..98c9aeecdd 100644
--- a/doc/man/bitcoind.1
+++ b/doc/man/bitcoind.1
@@ -1,5 +1,796 @@
-.TH BITCOIND "1"
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
+.TH BITCOIND "1" "September 2022" "bitcoind v24.0.0rc1" "User Commands"
.SH NAME
-bitcoind \- manual page for bitcoind
+bitcoind \- manual page for bitcoind v24.0.0rc1
+.SH SYNOPSIS
+.B bitcoind
+[\fI\,options\/\fR] \fI\,Start Bitcoin Core\/\fR
+.SH DESCRIPTION
+Bitcoin Core version v24.0.0rc1
+.SH OPTIONS
+.HP
+\-?
+.IP
+Print this help message and exit
+.HP
+\fB\-alertnotify=\fR<cmd>
+.IP
+Execute command when an alert is raised (%s in cmd is replaced by
+message)
+.HP
+\fB\-assumevalid=\fR<hex>
+.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:
+00000000000000000009c97098b5295f7e5f183ac811fb5d1534040adb93cabd,
+testnet:
+0000000000000004877fa2d36316398528de4f347df2f8a96f76613a298ce060,
+signet:
+000000d1a0e224fa4679d2fb2187ba55431c284fa1b74cbc8cfda866fd4d2c09)
+.HP
+\fB\-blockfilterindex=\fR<type>
+.IP
+Maintain an index of compact filters by block (default: 0, values:
+basic). If <type> is not supplied or if <type> = 1, indexes for
+all known types are enabled.
+.HP
+\fB\-blocknotify=\fR<cmd>
+.IP
+Execute command when the best block changes (%s in cmd is replaced by
+block hash)
+.HP
+\fB\-blockreconstructionextratxn=\fR<n>
+.IP
+Extra transactions to keep in memory for compact block reconstructions
+(default: 100)
+.HP
+\fB\-blocksdir=\fR<dir>
+.IP
+Specify directory to hold blocks subdirectory for *.dat files (default:
+<datadir>)
+.HP
+\fB\-blocksonly\fR
+.IP
+Whether to reject transactions from network peers. Automatic broadcast
+and rebroadcast of any transactions from inbound peers is
+disabled, unless the peer has the 'forcerelay' permission. RPC
+transactions are not affected. (default: 0)
+.HP
+\fB\-coinstatsindex\fR
+.IP
+Maintain coinstats index used by the gettxoutsetinfo RPC (default: 0)
+.HP
+\fB\-conf=\fR<file>
+.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<dir>
+.IP
+Specify data directory
+.HP
+\fB\-dbcache=\fR<n>
+.IP
+Maximum database cache size <n> MiB (4 to 16384, default: 450). In
+addition, unused mempool memory is shared for this cache (see
+\fB\-maxmempool\fR).
+.HP
+\fB\-debuglogfile=\fR<file>
+.IP
+Specify location of debug log file. Relative paths will be prefixed by a
+net\-specific datadir location. (\fB\-nodebuglogfile\fR to disable;
+default: debug.log)
+.HP
+\fB\-includeconf=\fR<file>
+.IP
+Specify additional configuration file, relative to the \fB\-datadir\fR path
+(only useable from configuration file, not command line)
+.HP
+\fB\-loadblock=\fR<file>
+.IP
+Imports blocks from external file on startup
+.HP
+\fB\-maxmempool=\fR<n>
+.IP
+Keep the transaction memory pool below <n> megabytes (default: 300)
+.HP
+\fB\-maxorphantx=\fR<n>
+.IP
+Keep at most <n> unconnectable transactions in memory (default: 100)
+.HP
+\fB\-mempoolexpiry=\fR<n>
+.IP
+Do not keep transactions in the mempool longer than <n> hours (default:
+336)
+.HP
+\fB\-par=\fR<n>
+.IP
+Set the number of script verification threads (\fB\-10\fR to 15, 0 = auto, <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\-pid=\fR<file>
+.IP
+Specify pid file. Relative paths will be prefixed by a net\-specific
+datadir location. (default: bitcoind.pid)
+.HP
+\fB\-prune=\fR<n>
+.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
+Rebuild chain state and block index from the blk*.dat files on disk.
+This will also rebuild active optional indexes.
+.HP
+\fB\-reindex\-chainstate\fR
+.IP
+Rebuild chain state from the currently indexed blocks. When in pruning
+mode or if blocks on disk might be corrupted, use full \fB\-reindex\fR
+instead. Deactivate all optional indexes before running this.
+.HP
+\fB\-sandbox=\fR<mode>
+.IP
+Use the experimental syscall sandbox in the specified mode
+(\fB\-sandbox\fR=\fI\,log\-and\-abort\/\fR or \fB\-sandbox\fR=\fI\,abort\/\fR). Allow only expected
+syscalls to be used by bitcoind. Note that this is an
+experimental new feature that may cause bitcoind to exit or crash
+unexpectedly: use with caution. In the "log\-and\-abort" mode the
+invocation of an unexpected syscall results in a debug handler
+being invoked which will log the incident and terminate the
+program (without executing the unexpected syscall). In the
+"abort" mode the invocation of an unexpected syscall results in
+the entire process being killed immediately by the kernel without
+executing the unexpected syscall.
+.HP
+\fB\-settings=\fR<file>
+.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\-startupnotify=\fR<cmd>
+.IP
+Execute command on startup.
+.HP
+\fB\-sysperms\fR
+.IP
+Create new files with system default permissions, instead of umask 077
+(only effective with disabled wallet functionality)
+.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>
+.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<file>
+.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<n>
+.IP
+Default duration (in seconds) of manually configured bans (default:
+86400)
+.HP
+\fB\-bind=\fR<addr>[:<port>][=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, testnet: 127.0.0.1:18334=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>
+.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)
+.HP
+\fB\-externalip=\fR<ip>
+.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
+If set and \fB\-i2psam\fR is also set then incoming I2P connections are
+accepted via the SAM proxy. If this is not set but \fB\-i2psam\fR is set
+then only outgoing connections will be made to the I2P network.
+Ignored if \fB\-i2psam\fR is not set. Listening for incoming I2P
+connections is done through the SAM proxy, not by binding to a
+local address and port (default: 1)
+.HP
+\fB\-i2psam=\fR<ip:port>
+.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 or \fB\-connect\fR)
+.HP
+\fB\-listenonion\fR
+.IP
+Automatically create Tor onion service (default: 1)
+.HP
+\fB\-maxconnections=\fR<n>
+.IP
+Maintain at most <n> 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<n>
+.IP
+Maximum per\-connection receive buffer, <n>*1000 bytes (default: 5000)
+.HP
+\fB\-maxsendbuffer=\fR<n>
+.IP
+Maximum per\-connection send buffer, <n>*1000 bytes (default: 1000)
+.HP
+\fB\-maxtimeadjustment\fR
+.IP
+Maximum allowed median peer time offset adjustment. Local perspective of
+time may be influenced by outbound peers forward or backward by
+this amount (default: 4200 seconds).
+.HP
+\fB\-maxuploadtarget=\fR<n>
+.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 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:port>
+.IP
+Use separate SOCKS5 proxy to reach peers via Tor onion services, set
+\fB\-noonion\fR to disable (default: \fB\-proxy\fR)
+.HP
+\fB\-onlynet=\fR<net>
+.IP
+Make automatic outbound connections only to network <net> (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\-permitbaremultisig\fR
+.IP
+Relay non\-P2SH multisig (default: 1)
+.HP
+\fB\-port=\fR<port>
+.IP
+Listen for connections on <port>. Nodes not using the default ports
+(default: 8333, testnet: 18333, signet: 38333, regtest: 18444)
+are unlikely to get incoming connections. Not relevant for I2P
+(see doc/i2p.md).
+.HP
+\fB\-proxy=\fR<ip:port>
+.IP
+Connect through SOCKS5 proxy, set \fB\-noproxy\fR to disable (default:
+disabled)
+.HP
+\fB\-proxyrandomize\fR
+.IP
+Randomize credentials for every proxy connection. This enables Tor
+stream isolation (default: 1)
+.HP
+\fB\-seednode=\fR<ip>
+.IP
+Connect to a node to retrieve peer addresses, and disconnect. This
+option can be specified multiple times to connect to multiple
+nodes.
+.HP
+\fB\-timeout=\fR<n>
+.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>:<port>
+.IP
+Tor control port to use if onion listening enabled (default:
+127.0.0.1:9051)
+.HP
+\fB\-torpassword=\fR<pass>
+.IP
+Tor control port password (default: empty)
+.HP
+\fB\-upnp\fR
+.IP
+Use UPnP to map the listening port (default: 0)
+.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 connecting from 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. 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<amt>
+.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<amt>
+.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<amt>
+.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<n>
+.IP
+Set key pool size to <n> (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<n>
+.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<amt>
+.IP
+Fee rates (in BTC/kvB) smaller than this are considered zero fee for
+transaction creation (default: 0.00001)
+.HP
+\fB\-paytxfee=\fR<amt>
+.IP
+Fee rate (in BTC/kvB) to add to transactions you send (default: 0.00)
+.HP
+\fB\-signer=\fR<cmd>
+.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<n>
+.IP
+If paytxfee is not set, include enough fee so transactions begin
+confirmation on average within n blocks (default: 6)
+.HP
+\fB\-wallet=\fR<path>
+.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 <walletdir>. 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
+<walletdir>.
+.HP
+\fB\-walletbroadcast\fR
+.IP
+Make the wallet broadcast transactions (default: 1)
+.HP
+\fB\-walletdir=\fR<dir>
+.IP
+Specify directory to hold wallets (default: <datadir>/wallets if it
+exists, otherwise <datadir>)
+.HP
+\fB\-walletnotify=\fR<cmd>
+.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<address>
+.IP
+Enable publish hash block in <address>
+.HP
+\fB\-zmqpubhashblockhwm=\fR<n>
+.IP
+Set publish hash block outbound message high water mark (default: 1000)
+.HP
+\fB\-zmqpubhashtx=\fR<address>
+.IP
+Enable publish hash transaction in <address>
+.HP
+\fB\-zmqpubhashtxhwm=\fR<n>
+.IP
+Set publish hash transaction outbound message high water mark (default:
+1000)
+.HP
+\fB\-zmqpubrawblock=\fR<address>
+.IP
+Enable publish raw block in <address>
+.HP
+\fB\-zmqpubrawblockhwm=\fR<n>
+.IP
+Set publish raw block outbound message high water mark (default: 1000)
+.HP
+\fB\-zmqpubrawtx=\fR<address>
+.IP
+Enable publish raw transaction in <address>
+.HP
+\fB\-zmqpubrawtxhwm=\fR<n>
+.IP
+Set publish raw transaction outbound message high water mark (default:
+1000)
+.HP
+\fB\-zmqpubsequence=\fR<address>
+.IP
+Enable publish hash block and tx sequence in <address>
+.HP
+\fB\-zmqpubsequencehwm=\fR<n>
+.IP
+Set publish hash sequence message high water mark (default: 1000)
+.PP
+Debugging/Testing options:
+.HP
+\fB\-debug=\fR<category>
+.IP
+Output debug and trace logging (default: \fB\-nodebug\fR, supplying <category>
+is optional). If <category> is not supplied or if <category> = 1,
+output all debug and trace logging. <category> can be: addrman,
+bench, blockstorage, cmpctblock, coindb, estimatefee, http, i2p,
+ipc, leveldb, libevent, mempool, mempoolrej, net, proxy, prune,
+qt, rand, reindex, rpc, selectcoins, tor, util, validation,
+walletdb, zmq. This option can be specified multiple times to
+output multiple categories.
+.HP
+\fB\-debugexclude=\fR<category>
+.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.
+.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\-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 (only available
+on platforms supporting thread_local) (default: 0)
+.HP
+\fB\-logtimestamps\fR
+.IP
+Prepend debug output with timestamp (default: 1)
+.HP
+\fB\-maxtxfee=\fR<amt>
+.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<cmt>
+.IP
+Append comment to the user agent string
+.PP
+Chain selection options:
+.HP
+\fB\-chain=\fR<chain>
+.IP
+Use the chain <chain> (default: main). Allowed values: main, test,
+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 test chain. Equivalent to \fB\-chain\fR=\fI\,test\/\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
+Maximum size of data in data carrier transactions we relay and mine
+(default: 83)
+.HP
+\fB\-mempoolfullrbf\fR
+.IP
+Accept transaction replace\-by\-fee without requiring replaceability
+signaling (default: 0)
+.HP
+\fB\-minrelaytxfee=\fR<amt>
+.IP
+Fees (in BTC/kvB) smaller than this are considered zero fee for
+relaying, mining and transaction creation (default: 0.00001)
+.HP
+\fB\-whitelistforcerelay\fR
+.IP
+Add 'forcerelay' permission to whitelisted inbound 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 inbound peers with default
+permissions. This will accept relayed transactions even when not
+relaying transactions (default: 1)
+.PP
+Block creation options:
+.HP
+\fB\-blockmaxweight=\fR<n>
+.IP
+Set maximum BIP141 block weight (default: 3996000)
+.HP
+\fB\-blockmintxfee=\fR<amt>
+.IP
+Set lowest fee rate (in BTC/kvB) for transactions to be included in
+block creation. (default: 0.00001)
+.PP
+RPC server options:
+.HP
+\fB\-rest\fR
+.IP
+Accept public REST requests (default: 0)
+.HP
+\fB\-rpcallowip=\fR<ip>
+.IP
+Allow JSON\-RPC connections from specified source. Valid for <ip> are a
+single IP (e.g. 1.2.3.4), a network/netmask (e.g.
+1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This
+option can be specified multiple times
+.HP
+\fB\-rpcauth=\fR<userpw>
+.IP
+Username and HMAC\-SHA\-256 hashed password for JSON\-RPC connections. The
+field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A
+canonical python script is included in share/rpcauth. The client
+then connects normally using the
+rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This
+option can be specified multiple times
+.HP
+\fB\-rpcbind=\fR<addr>[: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<loc>
+.IP
+Location of the auth cookie. Relative paths will be prefixed by a
+net\-specific datadir location. (default: data dir)
+.HP
+\fB\-rpcpassword=\fR<pw>
+.IP
+Password for JSON\-RPC connections
+.HP
+\fB\-rpcport=\fR<port>
+.IP
+Listen for JSON\-RPC connections on <port> (default: 8332, testnet:
+18332, signet: 38332, regtest: 18443)
+.HP
+\fB\-rpcserialversion\fR
+.IP
+Sets the serialization of raw transaction or block hex returned in
+non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1)
+.HP
+\fB\-rpcthreads=\fR<n>
+.IP
+Set the number of threads to service RPC calls (default: 4)
+.HP
+\fB\-rpcuser=\fR<user>
+.IP
+Username for JSON\-RPC connections
+.HP
+\fB\-rpcwhitelist=\fR<whitelist>
+.IP
+Set a whitelist to filter incoming RPC calls for a specific user. The
+field <whitelist> comes in the format: <USERNAME>:<rpc 1>,<rpc
+2>,...,<rpc n>. 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-2022 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
+<https://bitcoincore.org/> for further information about the software.
+The source code is available from <https://github.com/bitcoin/bitcoin>.
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or <https://opensource.org/licenses/MIT> \ No newline at end of file
diff --git a/share/examples/bitcoin.conf b/share/examples/bitcoin.conf
index 5bee4bf92e..ab94040283 100644
--- a/share/examples/bitcoin.conf
+++ b/share/examples/bitcoin.conf
@@ -1 +1,685 @@
-# 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
+
+
+# Execute command when an alert is raised (%s in cmd is replaced by
+# message)
+#alertnotify=<cmd>
+
+# 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:
+# 00000000000000000009c97098b5295f7e5f183ac811fb5d1534040adb93cabd,
+# testnet:
+# 0000000000000004877fa2d36316398528de4f347df2f8a96f76613a298ce060,
+# signet:
+# 000000d1a0e224fa4679d2fb2187ba55431c284fa1b74cbc8cfda866fd4d2c09)
+#assumevalid=<hex>
+
+# Maintain an index of compact filters by block (default: 0, values:
+# basic). If <type> is not supplied or if <type> = 1, indexes for
+# all known types are enabled.
+#blockfilterindex=<type>
+
+# Execute command when the best block changes (%s in cmd is replaced by
+# block hash)
+#blocknotify=<cmd>
+
+# Extra transactions to keep in memory for compact block reconstructions
+# (default: 100)
+#blockreconstructionextratxn=<n>
+
+# Specify directory to hold blocks subdirectory for *.dat files (default:
+# <datadir>)
+#blocksdir=<dir>
+
+# Whether to reject transactions from network peers. Automatic broadcast
+# and rebroadcast of any transactions from inbound peers is
+# disabled, unless the peer has the 'forcerelay' permission. RPC
+# transactions are not affected. (default: 0)
+#blocksonly=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=<file>
+
+# 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=<dir>
+
+# Maximum database cache size <n> MiB (4 to 16384, default: 450). In
+# addition, unused mempool memory is shared for this cache (see
+# -maxmempool).
+#dbcache=<n>
+
+# Specify location of debug log file. Relative paths will be prefixed by a
+# net-specific datadir location. (-nodebuglogfile to disable;
+# default: debug.log)
+#debuglogfile=<file>
+
+# Specify additional configuration file, relative to the -datadir path
+# (only useable from configuration file, not command line)
+#includeconf=<file>
+
+# Imports blocks from external file on startup
+#loadblock=<file>
+
+# Keep the transaction memory pool below <n> megabytes (default: 300)
+#maxmempool=<n>
+
+# Keep at most <n> unconnectable transactions in memory (default: 100)
+#maxorphantx=<n>
+
+# Do not keep transactions in the mempool longer than <n> hours (default:
+# 336)
+#mempoolexpiry=<n>
+
+# Set the number of script verification threads (-10 to 15, 0 = auto, <0 =
+# leave that many cores free, default: 0)
+#par=<n>
+
+# Whether to save the mempool on shutdown and load on restart (default: 1)
+#persistmempool=1
+
+# Specify pid file. Relative paths will be prefixed by a net-specific
+# datadir location. (default: bitcoind.pid)
+#pid=<file>
+
+# 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=<n>
+
+# Rebuild chain state and block index from the blk*.dat files on disk.
+# This will also rebuild active optional indexes.
+#reindex=1
+
+# Rebuild chain state from the currently indexed blocks. When in pruning
+# mode or if blocks on disk might be corrupted, use full -reindex
+# instead. Deactivate all optional indexes before running this.
+#reindex-chainstate=1
+
+# Use the experimental syscall sandbox in the specified mode
+# (-sandbox=log-and-abort or -sandbox=abort). Allow only expected
+# syscalls to be used by bitcoind. Note that this is an
+# experimental new feature that may cause bitcoind to exit or crash
+# unexpectedly: use with caution. In the "log-and-abort" mode the
+# invocation of an unexpected syscall results in a debug handler
+# being invoked which will log the incident and terminate the
+# program (without executing the unexpected syscall). In the
+# "abort" mode the invocation of an unexpected syscall results in
+# the entire process being killed immediately by the kernel without
+# executing the unexpected syscall.
+#sandbox=<mode>
+
+# 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=<file>
+
+# Execute command on startup.
+#startupnotify=<cmd>
+
+# Create new files with system default permissions, instead of umask 077
+# (only effective with disabled wallet functionality)
+#sysperms=1
+
+# 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=<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.
+#asmap=<file>
+
+# Default duration (in seconds) of manually configured bans (default:
+# 86400)
+#bantime=<n>
+
+# 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, testnet: 127.0.0.1:18334=onion,
+# signet: 127.0.0.1:38334=onion, regtest: 127.0.0.1:18445=onion)
+#bind=<addr>[:<port>][=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=<ip>
+
+# 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)
+#dnsseed=1
+
+# Specify your own public address
+#externalip=<ip>
+
+# 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
+
+# If set and -i2psam is also set then incoming I2P connections are
+# accepted via the SAM proxy. If this is not set but -i2psam is set
+# then only outgoing connections will be made to the I2P network.
+# Ignored if -i2psam is not set. Listening for incoming I2P
+# connections is done through the SAM proxy, not by binding to a
+# local address and port (default: 1)
+#i2pacceptincoming=1
+
+# I2P SAM proxy to reach I2P peers and accept I2P connections (default:
+# none)
+#i2psam=<ip:port>
+
+# Accept connections from outside (default: 1 if no -proxy or -connect)
+#listen=1
+
+# Automatically create Tor onion service (default: 1)
+#listenonion=1
+
+# Maintain at most <n> 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=<n>
+
+# Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)
+#maxreceivebuffer=<n>
+
+# Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)
+#maxsendbuffer=<n>
+
+# Maximum allowed median peer time offset adjustment. Local perspective of
+# time may be influenced by outbound peers forward or backward by
+# this amount (default: 4200 seconds).
+#maxtimeadjustment=1
+
+# 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=<n>
+
+# Use 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)
+#onion=<ip:port>
+
+# Make automatic outbound connections only to network <net> (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=<net>
+
+# 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
+
+# Relay non-P2SH multisig (default: 1)
+#permitbaremultisig=1
+
+# Listen for connections on <port>. Nodes not using the default ports
+# (default: 8333, testnet: 18333, signet: 38333, regtest: 18444)
+# are unlikely to get incoming connections. Not relevant for I2P
+# (see doc/i2p.md).
+#port=<port>
+
+# Connect through SOCKS5 proxy, set -noproxy to disable (default:
+# disabled)
+#proxy=<ip:port>
+
+# 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.
+#seednode=<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)
+#timeout=<n>
+
+# Tor control port to use if onion listening enabled (default:
+# 127.0.0.1:9051)
+#torcontrol=<ip>:<port>
+
+# Tor control port password (default: empty)
+#torpassword=<pass>
+
+# Use UPnP to map the listening port (default: 0)
+#upnp=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 connecting from 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. 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=<amt>
+
+# 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=<amt>
+
+# 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=<amt>
+
+# Set key pool size to <n> (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=<n>
+
+# Spend up to this amount in additional (absolute) fees (in BTC) if it
+# allows the use of partial spend avoidance (default: 0.00)
+#maxapsfee=<n>
+
+# Fee rates (in BTC/kvB) smaller than this are considered zero fee for
+# transaction creation (default: 0.00001)
+#mintxfee=<amt>
+
+# Fee rate (in BTC/kvB) to add to transactions you send (default: 0.00)
+#paytxfee=<amt>
+
+# External signing tool, see doc/external-signer.md
+#signer=<cmd>
+
+# 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=<n>
+
+# 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 <walletdir>. 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
+# <walletdir>.
+#wallet=<path>
+
+# Make the wallet broadcast transactions (default: 1)
+#walletbroadcast=1
+
+# Specify directory to hold wallets (default: <datadir>/wallets if it
+# exists, otherwise <datadir>)
+#walletdir=<dir>
+
+# 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=<cmd>
+
+# Send transactions with full-RBF opt-in enabled (RPC only, default: 1)
+#walletrbf=1
+
+
+### ZeroMQ notification options
+
+
+# Enable publish hash block in <address>
+#zmqpubhashblock=<address>
+
+# Set publish hash block outbound message high water mark (default: 1000)
+#zmqpubhashblockhwm=<n>
+
+# Enable publish hash transaction in <address>
+#zmqpubhashtx=<address>
+
+# Set publish hash transaction outbound message high water mark (default:
+# 1000)
+#zmqpubhashtxhwm=<n>
+
+# Enable publish raw block in <address>
+#zmqpubrawblock=<address>
+
+# Set publish raw block outbound message high water mark (default: 1000)
+#zmqpubrawblockhwm=<n>
+
+# Enable publish raw transaction in <address>
+#zmqpubrawtx=<address>
+
+# Set publish raw transaction outbound message high water mark (default:
+# 1000)
+#zmqpubrawtxhwm=<n>
+
+# Enable publish hash block and tx sequence in <address>
+#zmqpubsequence=<address>
+
+# Set publish hash sequence message high water mark (default: 1000)
+#zmqpubsequencehwm=<n>
+
+
+### Debugging/Testing options
+
+
+# Output debug and trace logging (default: -nodebug, supplying <category>
+# is optional). If <category> is not supplied or if <category> = 1,
+# output all debug and trace logging. <category> can be: addrman,
+# bench, blockstorage, cmpctblock, coindb, estimatefee, http, i2p,
+# ipc, leveldb, libevent, mempool, mempoolrej, net, proxy, prune,
+# qt, rand, reindex, rpc, selectcoins, tor, util, validation,
+# walletdb, zmq. This option can be specified multiple times to
+# output multiple categories.
+#debug=<category>
+
+# 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.
+#debugexclude=<category>
+
+# Print help message with debugging options and exit
+#help-debug=1
+
+# Include IP addresses in debug output (default: 0)
+#logips=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 (only available
+# on platforms supporting thread_local) (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=<amt>
+
+# 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=<cmt>
+
+
+### Chain selection options
+
+
+# Use the chain <chain> (default: main). Allowed values: main, test,
+# signet, regtest
+#chain=<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 test chain. Equivalent to -chain=test.
+#testnet=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
+
+# Maximum size of data in data carrier transactions we relay and mine
+# (default: 83)
+#datacarriersize=1
+
+# Accept transaction replace-by-fee without requiring replaceability
+# signaling (default: 0)
+#mempoolfullrbf=1
+
+# Fees (in BTC/kvB) smaller than this are considered zero fee for
+# relaying, mining and transaction creation (default: 0.00001)
+#minrelaytxfee=<amt>
+
+# Add 'forcerelay' permission to whitelisted inbound 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 inbound 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: 3996000)
+#blockmaxweight=<n>
+
+# Set lowest fee rate (in BTC/kvB) for transactions to be included in
+# block creation. (default: 0.00001)
+#blockmintxfee=<amt>
+
+
+### RPC server options
+
+
+# Accept public REST requests (default: 0)
+#rest=1
+
+# Allow JSON-RPC connections from specified source. Valid for <ip> are a
+# single IP (e.g. 1.2.3.4), a network/netmask (e.g.
+# 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This
+# option can be specified multiple times
+#rpcallowip=<ip>
+
+# Username and HMAC-SHA-256 hashed password for JSON-RPC connections. The
+# field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A
+# canonical python script is included in share/rpcauth. The client
+# then connects normally using the
+# rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This
+# option can be specified multiple times
+#rpcauth=<userpw>
+
+# 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=<addr>[:port]
+
+# Location of the auth cookie. Relative paths will be prefixed by a
+# net-specific datadir location. (default: data dir)
+#rpccookiefile=<loc>
+
+# Password for JSON-RPC connections
+#rpcpassword=<pw>
+
+# Listen for JSON-RPC connections on <port> (default: 8332, testnet:
+# 18332, signet: 38332, regtest: 18443)
+#rpcport=<port>
+
+# Sets the serialization of raw transaction or block hex returned in
+# non-verbose mode, non-segwit(0) or segwit(1) (default: 1)
+#rpcserialversion=1
+
+# Set the number of threads to service RPC calls (default: 4)
+#rpcthreads=<n>
+
+# Username for JSON-RPC connections
+#rpcuser=<user>
+
+# Set a whitelist to filter incoming RPC calls for a specific user. The
+# field <whitelist> comes in the format: <USERNAME>:<rpc 1>,<rpc
+# 2>,...,<rpc n>. If multiple whitelists are set for a given user,
+# they are set-intersected. See -rpcwhitelistdefault documentation
+# for information on default whitelist behavior.
+#rpcwhitelist=<whitelist>
+
+# 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 testnet
+[test]
+
+# Options for signet
+[signet]
+
+# Options for regtest
+[regtest]
diff --git a/src/Makefile.am b/src/Makefile.am
index 1bb887af20..6364e00d1e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -439,7 +439,7 @@ libbitcoin_node_a_SOURCES += dummywallet.cpp
endif
if ENABLE_ZMQ
-libbitcoin_zmq_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BOOST_CPPFLAGS) $(ZMQ_CFLAGS)
+libbitcoin_zmq_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_zmq_a_SOURCES = \
zmq/zmqabstractnotifier.cpp \
diff --git a/src/script/miniscript.h b/src/script/miniscript.h
index f783d1dafc..ab25fa67b7 100644
--- a/src/script/miniscript.h
+++ b/src/script/miniscript.h
@@ -276,6 +276,8 @@ struct StackSize {
StackSize(MaxInt<uint32_t> in_sat, MaxInt<uint32_t> in_dsat) : sat(in_sat), dsat(in_dsat) {};
};
+struct NoDupCheck {};
+
} // namespace internal
//! A node in a miniscript expression.
@@ -301,8 +303,13 @@ private:
const Type typ;
//! Cached script length (computed by CalcScriptLen).
const size_t scriptlen;
- //! Whether a public key appears more than once in this node.
- const bool duplicate_key;
+ //! Whether a public key appears more than once in this node. This value is initialized
+ //! by all constructors except the NoDupCheck ones. The NoDupCheck ones skip the
+ //! computation, requiring it to be done manually by invoking DuplicateKeyCheck().
+ //! DuplicateKeyCheck(), or a non-NoDupCheck constructor, will compute has_duplicate_keys
+ //! for all subnodes as well.
+ mutable std::optional<bool> has_duplicate_keys;
+
//! Compute the length of the script for this miniscript (including children).
size_t CalcScriptLen() const {
@@ -654,6 +661,7 @@ public:
return TreeEvalMaybe<std::string>(false, downfn, upfn);
}
+private:
internal::Ops CalcOps() const {
switch (fragment) {
case Fragment::JUST_1: return {0, 0, {}};
@@ -777,11 +785,14 @@ public:
assert(false);
}
- /** Check whether any key is repeated.
+public:
+ /** Update duplicate key information in this Node.
+ *
* This uses a custom key comparator provided by the context in order to still detect duplicates
* for more complicated types.
*/
- template<typename Ctx> bool ContainsDuplicateKey(const Ctx& ctx) const {
+ template<typename Ctx> void DuplicateKeyCheck(const Ctx& ctx) const
+ {
// We cannot use a lambda here, as lambdas are non assignable, and the set operations
// below require moving the comparators around.
struct Comp {
@@ -789,31 +800,55 @@ public:
Comp(const Ctx& ctx) : ctx_ptr(&ctx) {}
bool operator()(const Key& a, const Key& b) const { return ctx_ptr->KeyCompare(a, b); }
};
- using set = std::set<Key, Comp>;
- auto upfn = [this, &ctx](const Node& node, Span<set> subs) -> std::optional<set> {
- if (&node != this && node.duplicate_key) return {};
+ // state in the recursive computation:
+ // - std::nullopt means "this node has duplicates"
+ // - an std::set means "this node has no duplicate keys, and they are: ...".
+ using keyset = std::set<Key, Comp>;
+ using state = std::optional<keyset>;
+
+ auto upfn = [&ctx](const Node& node, Span<state> subs) -> state {
+ // If this node is already known to have duplicates, nothing left to do.
+ if (node.has_duplicate_keys.has_value() && *node.has_duplicate_keys) return {};
+
+ // Check if one of the children is already known to have duplicates.
+ for (auto& sub : subs) {
+ if (!sub.has_value()) {
+ node.has_duplicate_keys = true;
+ return {};
+ }
+ }
+ // Start building the set of keys involved in this node and children.
+ // Start by keys in this node directly.
size_t keys_count = node.keys.size();
- set key_set{node.keys.begin(), node.keys.end(), Comp(ctx)};
- if (key_set.size() != keys_count) return {};
+ keyset key_set{node.keys.begin(), node.keys.end(), Comp(ctx)};
+ if (key_set.size() != keys_count) {
+ // It already has duplicates; bail out.
+ node.has_duplicate_keys = true;
+ return {};
+ }
- for (auto& sub: subs) {
- keys_count += sub.size();
+ // Merge the keys from the children into this set.
+ for (auto& sub : subs) {
+ keys_count += sub->size();
// Small optimization: std::set::merge is linear in the size of the second arg but
// logarithmic in the size of the first.
- if (key_set.size() < sub.size()) std::swap(key_set, sub);
- key_set.merge(sub);
- if (key_set.size() != keys_count) return {};
+ if (key_set.size() < sub->size()) std::swap(key_set, *sub);
+ key_set.merge(*sub);
+ if (key_set.size() != keys_count) {
+ node.has_duplicate_keys = true;
+ return {};
+ }
}
+ node.has_duplicate_keys = false;
return key_set;
};
- return !TreeEvalMaybe<set>(upfn);
+ TreeEval<state>(upfn);
}
-public:
//! Return the size of the script for this expression (faster than ToScript().size()).
size_t ScriptSize() const { return scriptlen; }
@@ -858,7 +893,7 @@ public:
bool CheckTimeLocksMix() const { return GetType() << "k"_mst; }
//! Check whether there is no duplicate key across this fragment and all its sub-fragments.
- bool CheckDuplicateKey() const { return !duplicate_key; }
+ bool CheckDuplicateKey() const { return has_duplicate_keys && !*has_duplicate_keys; }
//! Whether successful non-malleable satisfactions are guaranteed to be valid.
bool ValidSatisfactions() const { return IsValid() && CheckOpsLimit() && CheckStackSize(); }
@@ -872,13 +907,21 @@ public:
//! Equality testing.
bool operator==(const Node<Key>& arg) const { return Compare(*this, arg) == 0; }
- // Constructors with various argument combinations.
- template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<NodeRef<Key>> sub, std::vector<unsigned char> arg, uint32_t val = 0) : fragment(nt), k(val), data(std::move(arg)), subs(std::move(sub)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()), duplicate_key(ContainsDuplicateKey(ctx)) {}
- template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<unsigned char> arg, uint32_t val = 0) : fragment(nt), k(val), data(std::move(arg)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()), duplicate_key(ContainsDuplicateKey(ctx)) {}
- template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<NodeRef<Key>> sub, std::vector<Key> key, uint32_t val = 0) : fragment(nt), k(val), keys(std::move(key)), subs(std::move(sub)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()), duplicate_key(ContainsDuplicateKey(ctx)) {}
- template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<Key> key, uint32_t val = 0) : fragment(nt), k(val), keys(std::move(key)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()), duplicate_key(ContainsDuplicateKey(ctx)) {}
- template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<NodeRef<Key>> sub, uint32_t val = 0) : fragment(nt), k(val), subs(std::move(sub)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()), duplicate_key(ContainsDuplicateKey(ctx)) {}
- template <typename Ctx> Node(const Ctx& ctx, Fragment nt, uint32_t val = 0) : fragment(nt), k(val), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()), duplicate_key(ContainsDuplicateKey(ctx)) {}
+ // Constructors with various argument combinations, which bypass the duplicate key check.
+ Node(internal::NoDupCheck, Fragment nt, std::vector<NodeRef<Key>> sub, std::vector<unsigned char> arg, uint32_t val = 0) : fragment(nt), k(val), data(std::move(arg)), subs(std::move(sub)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
+ Node(internal::NoDupCheck, Fragment nt, std::vector<unsigned char> arg, uint32_t val = 0) : fragment(nt), k(val), data(std::move(arg)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
+ Node(internal::NoDupCheck, Fragment nt, std::vector<NodeRef<Key>> sub, std::vector<Key> key, uint32_t val = 0) : fragment(nt), k(val), keys(std::move(key)), subs(std::move(sub)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
+ Node(internal::NoDupCheck, Fragment nt, std::vector<Key> key, uint32_t val = 0) : fragment(nt), k(val), keys(std::move(key)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
+ Node(internal::NoDupCheck, Fragment nt, std::vector<NodeRef<Key>> sub, uint32_t val = 0) : fragment(nt), k(val), subs(std::move(sub)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
+ Node(internal::NoDupCheck, Fragment nt, uint32_t val = 0) : fragment(nt), k(val), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
+
+ // Constructors with various argument combinations, which do perform the duplicate key check.
+ template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<NodeRef<Key>> sub, std::vector<unsigned char> arg, uint32_t val = 0) : Node(internal::NoDupCheck{}, nt, std::move(sub), std::move(arg), val) { DuplicateKeyCheck(ctx); }
+ template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<unsigned char> arg, uint32_t val = 0) : Node(internal::NoDupCheck{}, nt, std::move(arg), val) { DuplicateKeyCheck(ctx);}
+ template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<NodeRef<Key>> sub, std::vector<Key> key, uint32_t val = 0) : Node(internal::NoDupCheck{}, nt, std::move(sub), std::move(key), val) { DuplicateKeyCheck(ctx); }
+ template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<Key> key, uint32_t val = 0) : Node(internal::NoDupCheck{}, nt, std::move(key), val) { DuplicateKeyCheck(ctx); }
+ template <typename Ctx> Node(const Ctx& ctx, Fragment nt, std::vector<NodeRef<Key>> sub, uint32_t val = 0) : Node(internal::NoDupCheck{}, nt, std::move(sub), val) { DuplicateKeyCheck(ctx); }
+ template <typename Ctx> Node(const Ctx& ctx, Fragment nt, uint32_t val = 0) : Node(internal::NoDupCheck{}, nt, val) { DuplicateKeyCheck(ctx); }
};
namespace internal {
@@ -965,15 +1008,15 @@ std::optional<std::pair<std::vector<unsigned char>, int>> ParseHexStrEnd(Span<co
}
/** BuildBack pops the last two elements off `constructed` and wraps them in the specified Fragment */
-template<typename Key, typename Ctx>
-void BuildBack(const Ctx& ctx, Fragment nt, std::vector<NodeRef<Key>>& constructed, const bool reverse = false)
+template<typename Key>
+void BuildBack(Fragment nt, std::vector<NodeRef<Key>>& constructed, const bool reverse = false)
{
NodeRef<Key> child = std::move(constructed.back());
constructed.pop_back();
if (reverse) {
- constructed.back() = MakeNodeRef<Key>(ctx, nt, Vector(std::move(child), std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, nt, Vector(std::move(child), std::move(constructed.back())));
} else {
- constructed.back() = MakeNodeRef<Key>(ctx, nt, Vector(std::move(constructed.back()), std::move(child)));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, nt, Vector(std::move(constructed.back()), std::move(child)));
}
}
@@ -987,6 +1030,18 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
{
using namespace spanparsing;
+ // Account for the minimum script size for all parsed fragments so far. It "borrows" 1
+ // script byte from all leaf nodes, counting it instead whenever a space for a recursive
+ // expression is added (through andor, and_*, or_*, thresh). This guarantees that all fragments
+ // increment the script_size by at least one, except for:
+ // - "0", "1": these leafs are only a single byte, so their subtracted-from increment is 0.
+ // This is not an issue however, as "space" for them has to be created by combinators,
+ // which do increment script_size.
+ // - "v:": the v wrapper adds nothing as in some cases it results in no opcode being added
+ // (instead transforming another opcode into its VERIFY form). However, the v: wrapper has
+ // to be interleaved with other fragments to be valid, so this is not a concern.
+ size_t script_size{1};
+
// The two integers are used to hold state for thresh()
std::vector<std::tuple<ParseContext, int64_t, int64_t>> to_parse;
std::vector<NodeRef<Key>> constructed;
@@ -994,14 +1049,16 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
while (!to_parse.empty()) {
+ if (script_size > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {};
+
// Get the current context we are decoding within
auto [cur_context, n, k] = to_parse.back();
to_parse.pop_back();
switch (cur_context) {
case ParseContext::WRAPPED_EXPR: {
- int colon_index = -1;
- for (int i = 1; i < (int)in.size(); ++i) {
+ std::optional<size_t> colon_index{};
+ for (size_t i = 1; i < in.size(); ++i) {
if (in[i] == ':') {
colon_index = i;
break;
@@ -1009,106 +1066,131 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
if (in[i] < 'a' || in[i] > 'z') break;
}
// If there is no colon, this loop won't execute
- for (int j = 0; j < colon_index; ++j) {
+ bool last_was_v{false};
+ for (size_t j = 0; colon_index && j < *colon_index; ++j) {
+ if (script_size > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {};
if (in[j] == 'a') {
+ script_size += 2;
to_parse.emplace_back(ParseContext::ALT, -1, -1);
} else if (in[j] == 's') {
+ script_size += 1;
to_parse.emplace_back(ParseContext::SWAP, -1, -1);
} else if (in[j] == 'c') {
+ script_size += 1;
to_parse.emplace_back(ParseContext::CHECK, -1, -1);
} else if (in[j] == 'd') {
+ script_size += 3;
to_parse.emplace_back(ParseContext::DUP_IF, -1, -1);
} else if (in[j] == 'j') {
+ script_size += 4;
to_parse.emplace_back(ParseContext::NON_ZERO, -1, -1);
} else if (in[j] == 'n') {
+ script_size += 1;
to_parse.emplace_back(ParseContext::ZERO_NOTEQUAL, -1, -1);
} else if (in[j] == 'v') {
+ // do not permit "...vv...:"; it's not valid, and also doesn't trigger early
+ // failure as script_size isn't incremented.
+ if (last_was_v) return {};
to_parse.emplace_back(ParseContext::VERIFY, -1, -1);
} else if (in[j] == 'u') {
+ script_size += 4;
to_parse.emplace_back(ParseContext::WRAP_U, -1, -1);
} else if (in[j] == 't') {
+ script_size += 1;
to_parse.emplace_back(ParseContext::WRAP_T, -1, -1);
} else if (in[j] == 'l') {
// The l: wrapper is equivalent to or_i(0,X)
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::JUST_0));
+ script_size += 4;
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::JUST_0));
to_parse.emplace_back(ParseContext::OR_I, -1, -1);
} else {
return {};
}
+ last_was_v = (in[j] == 'v');
}
to_parse.emplace_back(ParseContext::EXPR, -1, -1);
- in = in.subspan(colon_index + 1);
+ if (colon_index) in = in.subspan(*colon_index + 1);
break;
}
case ParseContext::EXPR: {
if (Const("0", in)) {
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::JUST_0));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::JUST_0));
} else if (Const("1", in)) {
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::JUST_1));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::JUST_1));
} else if (Const("pk(", in)) {
auto res = ParseKeyEnd<Key, Ctx>(in, ctx);
if (!res) return {};
auto& [key, key_size] = *res;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::WRAP_C, Vector(MakeNodeRef<Key>(ctx, Fragment::PK_K, Vector(std::move(key))))));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_C, Vector(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::PK_K, Vector(std::move(key))))));
in = in.subspan(key_size + 1);
+ script_size += 34;
} else if (Const("pkh(", in)) {
auto res = ParseKeyEnd<Key>(in, ctx);
if (!res) return {};
auto& [key, key_size] = *res;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::WRAP_C, Vector(MakeNodeRef<Key>(ctx, Fragment::PK_H, Vector(std::move(key))))));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_C, Vector(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::PK_H, Vector(std::move(key))))));
in = in.subspan(key_size + 1);
+ script_size += 24;
} else if (Const("pk_k(", in)) {
auto res = ParseKeyEnd<Key>(in, ctx);
if (!res) return {};
auto& [key, key_size] = *res;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::PK_K, Vector(std::move(key))));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::PK_K, Vector(std::move(key))));
in = in.subspan(key_size + 1);
+ script_size += 33;
} else if (Const("pk_h(", in)) {
auto res = ParseKeyEnd<Key>(in, ctx);
if (!res) return {};
auto& [key, key_size] = *res;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::PK_H, Vector(std::move(key))));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::PK_H, Vector(std::move(key))));
in = in.subspan(key_size + 1);
+ script_size += 23;
} else if (Const("sha256(", in)) {
auto res = ParseHexStrEnd(in, 32, ctx);
if (!res) return {};
auto& [hash, hash_size] = *res;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::SHA256, std::move(hash)));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::SHA256, std::move(hash)));
in = in.subspan(hash_size + 1);
+ script_size += 38;
} else if (Const("ripemd160(", in)) {
auto res = ParseHexStrEnd(in, 20, ctx);
if (!res) return {};
auto& [hash, hash_size] = *res;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::RIPEMD160, std::move(hash)));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::RIPEMD160, std::move(hash)));
in = in.subspan(hash_size + 1);
+ script_size += 26;
} else if (Const("hash256(", in)) {
auto res = ParseHexStrEnd(in, 32, ctx);
if (!res) return {};
auto& [hash, hash_size] = *res;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::HASH256, std::move(hash)));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::HASH256, std::move(hash)));
in = in.subspan(hash_size + 1);
+ script_size += 38;
} else if (Const("hash160(", in)) {
auto res = ParseHexStrEnd(in, 20, ctx);
if (!res) return {};
auto& [hash, hash_size] = *res;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::HASH160, std::move(hash)));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::HASH160, std::move(hash)));
in = in.subspan(hash_size + 1);
+ script_size += 26;
} else if (Const("after(", in)) {
int arg_size = FindNextChar(in, ')');
if (arg_size < 1) return {};
int64_t num;
if (!ParseInt64(std::string(in.begin(), in.begin() + arg_size), &num)) return {};
if (num < 1 || num >= 0x80000000L) return {};
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::AFTER, num));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::AFTER, num));
in = in.subspan(arg_size + 1);
+ script_size += 1 + (num > 16) + (num > 0x7f) + (num > 0x7fff) + (num > 0x7fffff);
} else if (Const("older(", in)) {
int arg_size = FindNextChar(in, ')');
if (arg_size < 1) return {};
int64_t num;
if (!ParseInt64(std::string(in.begin(), in.begin() + arg_size), &num)) return {};
if (num < 1 || num >= 0x80000000L) return {};
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::OLDER, num));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::OLDER, num));
in = in.subspan(arg_size + 1);
+ script_size += 1 + (num > 16) + (num > 0x7f) + (num > 0x7fff) + (num > 0x7fffff);
} else if (Const("multi(", in)) {
// Get threshold
int next_comma = FindNextChar(in, ',');
@@ -1128,7 +1210,8 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
}
if (keys.size() < 1 || keys.size() > 20) return {};
if (k < 1 || k > (int64_t)keys.size()) return {};
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::MULTI, std::move(keys), k));
+ script_size += 2 + (keys.size() > 16) + (k > 16) + 34 * keys.size();
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::MULTI, std::move(keys), k));
} else if (Const("thresh(", in)) {
int next_comma = FindNextChar(in, ',');
if (next_comma < 1) return {};
@@ -1138,6 +1221,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
// n = 1 here because we read the first WRAPPED_EXPR before reaching THRESH
to_parse.emplace_back(ParseContext::THRESH, 1, k);
to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
+ script_size += 2 + (k > 16);
} else if (Const("andor(", in)) {
to_parse.emplace_back(ParseContext::ANDOR, -1, -1);
to_parse.emplace_back(ParseContext::CLOSE_BRACKET, -1, -1);
@@ -1146,21 +1230,29 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
to_parse.emplace_back(ParseContext::COMMA, -1, -1);
to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
+ script_size += 5;
} else {
if (Const("and_n(", in)) {
to_parse.emplace_back(ParseContext::AND_N, -1, -1);
+ script_size += 5;
} else if (Const("and_b(", in)) {
to_parse.emplace_back(ParseContext::AND_B, -1, -1);
+ script_size += 2;
} else if (Const("and_v(", in)) {
to_parse.emplace_back(ParseContext::AND_V, -1, -1);
+ script_size += 1;
} else if (Const("or_b(", in)) {
to_parse.emplace_back(ParseContext::OR_B, -1, -1);
+ script_size += 2;
} else if (Const("or_c(", in)) {
to_parse.emplace_back(ParseContext::OR_C, -1, -1);
+ script_size += 3;
} else if (Const("or_d(", in)) {
to_parse.emplace_back(ParseContext::OR_D, -1, -1);
+ script_size += 4;
} else if (Const("or_i(", in)) {
to_parse.emplace_back(ParseContext::OR_I, -1, -1);
+ script_size += 4;
} else {
return {};
}
@@ -1172,69 +1264,70 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
break;
}
case ParseContext::ALT: {
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_A, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_A, Vector(std::move(constructed.back())));
break;
}
case ParseContext::SWAP: {
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_S, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_S, Vector(std::move(constructed.back())));
break;
}
case ParseContext::CHECK: {
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_C, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_C, Vector(std::move(constructed.back())));
break;
}
case ParseContext::DUP_IF: {
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_D, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_D, Vector(std::move(constructed.back())));
break;
}
case ParseContext::NON_ZERO: {
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_J, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_J, Vector(std::move(constructed.back())));
break;
}
case ParseContext::ZERO_NOTEQUAL: {
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_N, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_N, Vector(std::move(constructed.back())));
break;
}
case ParseContext::VERIFY: {
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_V, Vector(std::move(constructed.back())));
+ script_size += (constructed.back()->GetType() << "x"_mst);
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_V, Vector(std::move(constructed.back())));
break;
}
case ParseContext::WRAP_U: {
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::OR_I, Vector(std::move(constructed.back()), MakeNodeRef<Key>(ctx, Fragment::JUST_0)));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::OR_I, Vector(std::move(constructed.back()), MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::JUST_0)));
break;
}
case ParseContext::WRAP_T: {
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::AND_V, Vector(std::move(constructed.back()), MakeNodeRef<Key>(ctx, Fragment::JUST_1)));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::AND_V, Vector(std::move(constructed.back()), MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::JUST_1)));
break;
}
case ParseContext::AND_B: {
- BuildBack(ctx, Fragment::AND_B, constructed);
+ BuildBack(Fragment::AND_B, constructed);
break;
}
case ParseContext::AND_N: {
auto mid = std::move(constructed.back());
constructed.pop_back();
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::ANDOR, Vector(std::move(constructed.back()), std::move(mid), MakeNodeRef<Key>(ctx, Fragment::JUST_0)));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::ANDOR, Vector(std::move(constructed.back()), std::move(mid), MakeNodeRef<Key>(ctx, Fragment::JUST_0)));
break;
}
case ParseContext::AND_V: {
- BuildBack(ctx, Fragment::AND_V, constructed);
+ BuildBack(Fragment::AND_V, constructed);
break;
}
case ParseContext::OR_B: {
- BuildBack(ctx, Fragment::OR_B, constructed);
+ BuildBack(Fragment::OR_B, constructed);
break;
}
case ParseContext::OR_C: {
- BuildBack(ctx, Fragment::OR_C, constructed);
+ BuildBack(Fragment::OR_C, constructed);
break;
}
case ParseContext::OR_D: {
- BuildBack(ctx, Fragment::OR_D, constructed);
+ BuildBack(Fragment::OR_D, constructed);
break;
}
case ParseContext::OR_I: {
- BuildBack(ctx, Fragment::OR_I, constructed);
+ BuildBack(Fragment::OR_I, constructed);
break;
}
case ParseContext::ANDOR: {
@@ -1242,7 +1335,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
constructed.pop_back();
auto mid = std::move(constructed.back());
constructed.pop_back();
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::ANDOR, Vector(std::move(constructed.back()), std::move(mid), std::move(right)));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::ANDOR, Vector(std::move(constructed.back()), std::move(mid), std::move(right)));
break;
}
case ParseContext::THRESH: {
@@ -1251,6 +1344,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
in = in.subspan(1);
to_parse.emplace_back(ParseContext::THRESH, n+1, k);
to_parse.emplace_back(ParseContext::WRAPPED_EXPR, -1, -1);
+ script_size += 2;
} else if (in[0] == ')') {
if (k > n) return {};
in = in.subspan(1);
@@ -1261,7 +1355,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
constructed.pop_back();
}
std::reverse(subs.begin(), subs.end());
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::THRESH, std::move(subs), k));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::THRESH, std::move(subs), k));
} else {
return {};
}
@@ -1282,8 +1376,11 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
// Sanity checks on the produced miniscript
assert(constructed.size() == 1);
+ assert(constructed[0]->ScriptSize() == script_size);
if (in.size() > 0) return {};
- return std::move(constructed.front());
+ const NodeRef<Key> tl_node = std::move(constructed.front());
+ tl_node->DuplicateKeyCheck(ctx);
+ return tl_node;
}
/** Decode a script into opcode/push pairs.
@@ -1394,12 +1491,12 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
// Constants
if (in[0].first == OP_1) {
++in;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::JUST_1));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::JUST_1));
break;
}
if (in[0].first == OP_0) {
++in;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::JUST_0));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::JUST_0));
break;
}
// Public keys
@@ -1407,14 +1504,14 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
auto key = ctx.FromPKBytes(in[0].second.begin(), in[0].second.end());
if (!key) return {};
++in;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::PK_K, Vector(std::move(*key))));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::PK_K, Vector(std::move(*key))));
break;
}
if (last - in >= 5 && in[0].first == OP_VERIFY && in[1].first == OP_EQUAL && in[3].first == OP_HASH160 && in[4].first == OP_DUP && in[2].second.size() == 20) {
auto key = ctx.FromPKHBytes(in[2].second.begin(), in[2].second.end());
if (!key) return {};
in += 5;
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::PK_H, Vector(std::move(*key))));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::PK_H, Vector(std::move(*key))));
break;
}
// Time locks
@@ -1422,31 +1519,31 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
if (last - in >= 2 && in[0].first == OP_CHECKSEQUENCEVERIFY && (num = ParseScriptNumber(in[1]))) {
in += 2;
if (*num < 1 || *num > 0x7FFFFFFFL) return {};
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::OLDER, *num));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::OLDER, *num));
break;
}
if (last - in >= 2 && in[0].first == OP_CHECKLOCKTIMEVERIFY && (num = ParseScriptNumber(in[1]))) {
in += 2;
if (num < 1 || num > 0x7FFFFFFFL) return {};
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::AFTER, *num));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::AFTER, *num));
break;
}
// Hashes
if (last - in >= 7 && in[0].first == OP_EQUAL && in[3].first == OP_VERIFY && in[4].first == OP_EQUAL && (num = ParseScriptNumber(in[5])) && num == 32 && in[6].first == OP_SIZE) {
if (in[2].first == OP_SHA256 && in[1].second.size() == 32) {
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::SHA256, in[1].second));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::SHA256, in[1].second));
in += 7;
break;
} else if (in[2].first == OP_RIPEMD160 && in[1].second.size() == 20) {
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::RIPEMD160, in[1].second));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::RIPEMD160, in[1].second));
in += 7;
break;
} else if (in[2].first == OP_HASH256 && in[1].second.size() == 32) {
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::HASH256, in[1].second));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::HASH256, in[1].second));
in += 7;
break;
} else if (in[2].first == OP_HASH160 && in[1].second.size() == 20) {
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::HASH160, in[1].second));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::HASH160, in[1].second));
in += 7;
break;
}
@@ -1467,7 +1564,7 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
if (!k || *k < 1 || *k > *n) return {};
in += 3 + *n;
std::reverse(keys.begin(), keys.end());
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::MULTI, std::move(keys), *k));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::MULTI, std::move(keys), *k));
break;
}
/** In the following wrappers, we only need to push SINGLE_BKV_EXPR rather
@@ -1562,63 +1659,63 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
case DecodeContext::SWAP: {
if (in >= last || in[0].first != OP_SWAP || constructed.empty()) return {};
++in;
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_S, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_S, Vector(std::move(constructed.back())));
break;
}
case DecodeContext::ALT: {
if (in >= last || in[0].first != OP_TOALTSTACK || constructed.empty()) return {};
++in;
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_A, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_A, Vector(std::move(constructed.back())));
break;
}
case DecodeContext::CHECK: {
if (constructed.empty()) return {};
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_C, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_C, Vector(std::move(constructed.back())));
break;
}
case DecodeContext::DUP_IF: {
if (constructed.empty()) return {};
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_D, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_D, Vector(std::move(constructed.back())));
break;
}
case DecodeContext::VERIFY: {
if (constructed.empty()) return {};
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_V, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_V, Vector(std::move(constructed.back())));
break;
}
case DecodeContext::NON_ZERO: {
if (constructed.empty()) return {};
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_J, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_J, Vector(std::move(constructed.back())));
break;
}
case DecodeContext::ZERO_NOTEQUAL: {
if (constructed.empty()) return {};
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::WRAP_N, Vector(std::move(constructed.back())));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::WRAP_N, Vector(std::move(constructed.back())));
break;
}
case DecodeContext::AND_V: {
if (constructed.size() < 2) return {};
- BuildBack(ctx, Fragment::AND_V, constructed, /*reverse=*/true);
+ BuildBack(Fragment::AND_V, constructed, /*reverse=*/true);
break;
}
case DecodeContext::AND_B: {
if (constructed.size() < 2) return {};
- BuildBack(ctx, Fragment::AND_B, constructed, /*reverse=*/true);
+ BuildBack(Fragment::AND_B, constructed, /*reverse=*/true);
break;
}
case DecodeContext::OR_B: {
if (constructed.size() < 2) return {};
- BuildBack(ctx, Fragment::OR_B, constructed, /*reverse=*/true);
+ BuildBack(Fragment::OR_B, constructed, /*reverse=*/true);
break;
}
case DecodeContext::OR_C: {
if (constructed.size() < 2) return {};
- BuildBack(ctx, Fragment::OR_C, constructed, /*reverse=*/true);
+ BuildBack(Fragment::OR_C, constructed, /*reverse=*/true);
break;
}
case DecodeContext::OR_D: {
if (constructed.size() < 2) return {};
- BuildBack(ctx, Fragment::OR_D, constructed, /*reverse=*/true);
+ BuildBack(Fragment::OR_D, constructed, /*reverse=*/true);
break;
}
case DecodeContext::ANDOR: {
@@ -1628,7 +1725,7 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
NodeRef<Key> right = std::move(constructed.back());
constructed.pop_back();
NodeRef<Key> mid = std::move(constructed.back());
- constructed.back() = MakeNodeRef<Key>(ctx, Fragment::ANDOR, Vector(std::move(left), std::move(mid), std::move(right)));
+ constructed.back() = MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::ANDOR, Vector(std::move(left), std::move(mid), std::move(right)));
break;
}
case DecodeContext::THRESH_W: {
@@ -1652,7 +1749,7 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
constructed.pop_back();
subs.push_back(std::move(sub));
}
- constructed.push_back(MakeNodeRef<Key>(ctx, Fragment::THRESH, std::move(subs), k));
+ constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, Fragment::THRESH, std::move(subs), k));
break;
}
case DecodeContext::ENDIF: {
@@ -1702,7 +1799,7 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
if (in >= last) return {};
if (in[0].first == OP_IF) {
++in;
- BuildBack(ctx, Fragment::OR_I, constructed, /*reverse=*/true);
+ BuildBack(Fragment::OR_I, constructed, /*reverse=*/true);
} else if (in[0].first == OP_NOTIF) {
++in;
to_parse.emplace_back(DecodeContext::ANDOR, -1, -1);
@@ -1717,6 +1814,7 @@ inline NodeRef<Key> DecodeScript(I& in, I last, const Ctx& ctx)
}
if (constructed.size() != 1) return {};
const NodeRef<Key> tl_node = std::move(constructed.front());
+ tl_node->DuplicateKeyCheck(ctx);
// Note that due to how ComputeType works (only assign the type to the node if the
// subs' types are valid) this would fail if any node of tree is badly typed.
if (!tl_node->IsValidTopLevel()) return {};
@@ -1733,6 +1831,8 @@ inline NodeRef<typename Ctx::Key> FromString(const std::string& str, const Ctx&
template<typename Ctx>
inline NodeRef<typename Ctx::Key> FromScript(const CScript& script, const Ctx& ctx) {
using namespace internal;
+ // A too large Script is necessarily invalid, don't bother parsing it.
+ if (script.size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE) return {};
auto decomposed = DecomposeScript(script);
if (!decomposed) return {};
auto it = decomposed->begin();
diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp
index 95e8476b77..9387c01e73 100644
--- a/src/test/miniscript_tests.cpp
+++ b/src/test/miniscript_tests.cpp
@@ -296,6 +296,9 @@ BOOST_AUTO_TEST_CASE(fixed_tests)
// Same when the duplicates are on different levels in the tree
const auto ms_dup4 = miniscript::FromString("thresh(2,pkh(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),s:pk(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556),a:and_b(dv:older(1),s:pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)))", CONVERTER);
BOOST_CHECK(ms_dup4 && !ms_dup4->IsSane() && !ms_dup4->CheckDuplicateKey());
+ // Sanity check the opposite is true, too. An otherwise sane Miniscript with no duplicate keys is sane.
+ const auto ms_nondup = miniscript::FromString("pk(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65)", CONVERTER);
+ BOOST_CHECK(ms_nondup && ms_nondup->CheckDuplicateKey() && ms_nondup->IsSane());
// Test we find the first insane sub closer to be a leaf node. This fragment is insane for two reasons:
// 1. It can be spent without a signature
// 2. It contains timelock mixes
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
index 98925e6b10..9cf2b677e6 100644
--- a/src/wallet/interfaces.cpp
+++ b/src/wallet/interfaces.cpp
@@ -560,8 +560,12 @@ public:
options.create_flags = wallet_creation_flags;
options.create_passphrase = passphrase;
bilingual_str error;
- util::Result<std::unique_ptr<Wallet>> wallet{MakeWallet(m_context, CreateWallet(m_context, name, /*load_on_start=*/true, options, status, error, warnings))};
- return wallet ? std::move(wallet) : util::Error{error};
+ std::unique_ptr<Wallet> wallet{MakeWallet(m_context, CreateWallet(m_context, name, /*load_on_start=*/true, options, status, error, warnings))};
+ if (wallet) {
+ return {std::move(wallet)};
+ } else {
+ return util::Error{error};
+ }
}
util::Result<std::unique_ptr<Wallet>> loadWallet(const std::string& name, std::vector<bilingual_str>& warnings) override
{
@@ -570,15 +574,23 @@ public:
ReadDatabaseArgs(*m_context.args, options);
options.require_existing = true;
bilingual_str error;
- util::Result<std::unique_ptr<Wallet>> wallet{MakeWallet(m_context, LoadWallet(m_context, name, /*load_on_start=*/true, options, status, error, warnings))};
- return wallet ? std::move(wallet) : util::Error{error};
+ std::unique_ptr<Wallet> wallet{MakeWallet(m_context, LoadWallet(m_context, name, /*load_on_start=*/true, options, status, error, warnings))};
+ if (wallet) {
+ return {std::move(wallet)};
+ } else {
+ return util::Error{error};
+ }
}
util::Result<std::unique_ptr<Wallet>> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, std::vector<bilingual_str>& warnings) override
{
DatabaseStatus status;
bilingual_str error;
- util::Result<std::unique_ptr<Wallet>> wallet{MakeWallet(m_context, RestoreWallet(m_context, backup_file, wallet_name, /*load_on_start=*/true, status, error, warnings))};
- return wallet ? std::move(wallet) : util::Error{error};
+ std::unique_ptr<Wallet> wallet{MakeWallet(m_context, RestoreWallet(m_context, backup_file, wallet_name, /*load_on_start=*/true, status, error, warnings))};
+ if (wallet) {
+ return {std::move(wallet)};
+ } else {
+ return util::Error{error};
+ }
}
std::string getWalletDir() override
{
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index c084ef10ec..e0f1655ab7 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -386,25 +386,31 @@ std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& b
ReadDatabaseArgs(*context.args, options);
options.require_existing = true;
- if (!fs::exists(backup_file)) {
- error = Untranslated("Backup file does not exist");
- status = DatabaseStatus::FAILED_INVALID_BACKUP_FILE;
- return nullptr;
- }
-
const fs::path wallet_path = fsbridge::AbsPathJoin(GetWalletDir(), fs::u8path(wallet_name));
+ auto wallet_file = wallet_path / "wallet.dat";
+ std::shared_ptr<CWallet> wallet;
- if (fs::exists(wallet_path) || !TryCreateDirectories(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;
- }
+ try {
+ if (!fs::exists(backup_file)) {
+ error = Untranslated("Backup file does not exist");
+ status = DatabaseStatus::FAILED_INVALID_BACKUP_FILE;
+ return nullptr;
+ }
- auto wallet_file = wallet_path / "wallet.dat";
- fs::copy_file(backup_file, wallet_file, fs::copy_options::none);
+ if (fs::exists(wallet_path) || !TryCreateDirectories(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;
+ }
- auto wallet = LoadWallet(context, wallet_name, load_on_start, options, status, error, warnings);
+ fs::copy_file(backup_file, wallet_file, fs::copy_options::none);
+ wallet = LoadWallet(context, wallet_name, load_on_start, options, status, error, warnings);
+ } catch (const std::exception& e) {
+ assert(!wallet);
+ if (!error.empty()) error += Untranslated("\n");
+ error += strprintf(Untranslated("Unexpected exception: %s"), e.what());
+ }
if (!wallet) {
fs::remove(wallet_file);
fs::remove(wallet_path);
diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp
index 26618735f6..b9b7019a3c 100644
--- a/src/zmq/zmqnotificationinterface.cpp
+++ b/src/zmq/zmqnotificationinterface.cpp
@@ -8,7 +8,7 @@
#include <zmq.h>
-#include <validation.h>
+#include <primitives/block.h>
#include <util/system.h>
CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(nullptr)
diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp
index 011336bf72..51c8ad515e 100644
--- a/src/zmq/zmqpublishnotifier.cpp
+++ b/src/zmq/zmqpublishnotifier.cpp
@@ -11,7 +11,6 @@
#include <rpc/server.h>
#include <streams.h>
#include <util/system.h>
-#include <validation.h> // For cs_main
#include <zmq/zmqutil.h>
#include <zmq.h>