diff --git a/configure.ac b/configure.ac
index ce1508787a291..59359ca18f6b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,9 +1,9 @@
AC_PREREQ([2.69])
-define(_CLIENT_VERSION_MAJOR, 27)
-define(_CLIENT_VERSION_MINOR, 99)
+define(_CLIENT_VERSION_MAJOR, 28)
+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, 2024)
define(_COPYRIGHT_HOLDERS,[The %s developers])
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Groestlcoin Core]])
diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py
index 5d074c1b20019..47a76a06e9014 100644
--- a/contrib/seeds/makeseeds.py
+++ b/contrib/seeds/makeseeds.py
@@ -229,12 +229,12 @@ def main():
# Require service bit 1.
ips = [ip for ip in ips if (ip['service'] & 1) == 1]
print(f'{ip_stats(ips):s} Require service bit 1', file=sys.stderr)
- # Require at least 50% 30-day uptime for clearnet, 10% for onion and i2p.
+ # Require at least 50% 30-day uptime for clearnet, onion and i2p; 10% for cjdns
req_uptime = {
'ipv4': 50,
'ipv6': 50,
- 'onion': 10,
- 'i2p' : 10,
+ 'onion': 50,
+ 'i2p': 50,
'cjdns': 10,
}
ips = [ip for ip in ips if ip['uptime'] > req_uptime[ip['net']]]
diff --git a/contrib/seeds/nodes_main_manual.txt b/contrib/seeds/nodes_main_manual.txt
deleted file mode 100644
index 9694cc0d5e31b..0000000000000
--- a/contrib/seeds/nodes_main_manual.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-
-# manually added 2021-04 for minimal torv3 bootstrap support
-wd6qntxyftioxzwlelevsdrieh7ruxzsju2qna42culnqkbv32yhetad.onion:1331
-vsc6kyudmzcndtnbgthmk6u45ewqoe2xkxkpfplcsmnmsq3hl7im2uyd.onion:1331
-7uofqbelwzflqsbiz6nm5saatbemxieg4ogb2perqyollfn37g5wkead.onion:1331
-qswleezl4pxt7glm5udyouzxaywdtjwj3u4vmw7spkmqgewycsrzwaqd.onion:1331
-w4wm4fefr7zhpntpbse252ugcralqfrux67cr6ef2onj6su752oqmdyd.onion:1331
-mrock7dleasqpfco4luf7diff3jg7czeq5e5ituazloyx3rorii5acqd.onion:1331
-nnm6svqbssjom3tiilqfwmz4eorywam3eknskepdrnxrag6lj3lek3ad.onion:1331
-jarisfs2albw76o2ikqlqeyutcnzlnddloe3axydimbxy2tzugyanyyd.onion:1331
-3rciesai2s4y3v74hkn5zbrcr6qpe3i57cbgvhjzxjlnh74bfxjcldid.onion:1331
-7novt2eddbgn7hcanbtxpru6urekvukss7svctkxjqn2bsdqglipagad.onion:1331
-6ludsaxp3d27cg6qdm3chtghzhy2rgw225qwmw67seibsvpd7amc3uqd.onion:1331
-2fukjulc4qe26en2mmc6d7th57fjyuj4uwuqzt5aadt6svad27cwedid.onion:1331
-w5xqnhc3jsnwrbhae2yav7cgbkubjqtoxjgtgoixacialjol6f5zupyd.onion:1331
-eiuphbiwodt7x745amvkwirv627b2p2min4xlipy5vrrmfrmvybsimqd.onion:1331
-rh3wyzfinbck2jlmmoywwlmhd7y2rjzc5rtd2i72dxdbpmq5inxieuad.onion:1331
-zl4bwbro76njwpjefjlzq6i3bfwvtg3vhwe6bzstozbna4ktz3xmxvid.onion:1331
-w53z24mxzoqztr2jbc3hybrzqnjipcttsd4rojv6co6swxuso6ktuqid.onion:1331
-waxyj3athqufqepqeo6wjef4mefnvgh32dr2i6fg4fwhedyhtdg4l6ad.onion:1331
-udgejw5fd36dmlpnnqzeycdksgtanow42sfgrl53objpzah2vwushxyd.onion:1331
-dqipifdnfupokfatw3riuajq4o3bt52gljmgpgp3ppjh3f2d5hvyuuqd.onion:1331
-fcpeybgcvdhlqiszsk4cu6yhxznigc2ghw2z2cx4i2nz7fbruaz3mlyd.onion:1331
-yz5czem3bjbvpyvn2bfso67zfmq5jnut6ekv5zfxgh6aykzidtl5f4yd.onion:1331
-5hbdbpf52dhsqceawwl32v4fg44f3gerbyfiiswzo6tqgfjy26ztqpyd.onion:1331
-5ke7lbx3rslrpqg3xldkynn65xlbdb6xzvqrta32qs4sjvhsvtahzzid.onion:1331
-hape2nnawke2xqgm43h2jzg2qwlr3yx3ipdriuxx7ceiwvi6md7w3fqd.onion:1331
-2vu7mu6wuwgf6b3flgvruwf3yujnhjrmxibc64o3qg424c2cjlvg6mid.onion:1331
-gkhqstbxvs6yii6pcsvrc2iw2ior4mg3o2ypqx2g2sxuelfwd5iqfqqd.onion:1331
-bc7ollwpcw4w33ridg4jnunqmtj5fifa6srywk47yr3gzynv5xyassid.onion:1331
-7jym5jdpgzngfoeckrkn7fhqnijl6zute54delnytiuomky3i3inpbid.onion:1331
-5ynwxnhbaalflwqksqardusqdvbycpl2nmvfc7oxetoh52fi4fpgw7yd.onion:1331
-uxm36kwdspg5s4mlenq5olrm7svpp2thsd64j5nn3zo6pn6k5f7uk7ad.onion:1331
-xrkvshs6sa4eoc2dhhwnfescysidgcybmg5yp2cnimd6isgrtbo6tkad.onion:1331
-g6hlxkv4gj3x3qvw5c5nmbfpakahp6lfh4czpppakkzlkvp36uo4rrqd.onion:1331
-ig6f3mf3fjgca6wktmghzwjpahiarymubb2r2yncalypsxaj23vy3oyd.onion:1331
-67ib2ufjlsh6vlxi52kmucccmoyhjwaaph7pnrsph7kgw7iblufqtsad.onion:1331
-qn5wyqfu4l4fxqwxweqo5e37khwcvyz2m76wwn5ss7ojn4pnlnekfwid.onion:1331
-4ttdbxr22fsk6olaeecyqhonvhuhs5skanrikk5k3zjfoo2usagqnuad.onion:1331
-euwwgfucb3uinxqnc4np2owc2244xiicymnu5acq255thhki564f4oid.onion:1331
-s7yiejfewyxcxoudj7tawo4selwtuby27rsxdh6xwzg53c64k64ilmid.onion:1331
-62okwqe4s23i3d2yaaoujkz3g6sofivgadmcyaxrzbv4fcaw3aukp4qd.onion:1331
-cvumqkt676gwpjtiozutewsak55sndgzzu4joficwijawnn4fijo7gqd.onion:1331
diff --git a/doc/bips.md b/doc/bips.md
index 9bec671a7a289..c5951cb3d21ab 100644
--- a/doc/bips.md
+++ b/doc/bips.md
@@ -62,6 +62,7 @@ BIPs that are implemented by Groestlcoin Core:
[PR 21686](https://github.com/bitcoin/bitcoin/pull/21686)).
* [`BIP 350`](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki): Addresses for native v1+ segregated Witness outputs use Bech32m instead of Bech32 as of **v22.0** ([PR 20861](https://github.com/bitcoin/bitcoin/pull/20861)).
* [`BIP 371`](https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki): Taproot fields for PSBT as of **v24.0** ([PR 22558](https://github.com/bitcoin/bitcoin/pull/22558)).
+* [`BIP 379`](https://github.com/bitcoin/bips/blob/master/bip-0379.md): Miniscript was partially implemented in **v24.0** ([PR 24148](https://github.com/bitcoin/bitcoin/pull/24148)), and fully implemented as of **v26.0** ([PR 27255](https://github.com/bitcoin/bitcoin/pull/27255)).
* [`BIP 380`](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki)
[`381`](https://github.com/bitcoin/bips/blob/master/bip-0381.mediawiki)
[`382`](https://github.com/bitcoin/bips/blob/master/bip-0382.mediawiki)
@@ -70,4 +71,5 @@ BIPs that are implemented by Groestlcoin Core:
[`385`](https://github.com/bitcoin/bips/blob/master/bip-0385.mediawiki):
Output Script Descriptors, and most of Script Expressions are implemented as of **v0.17.0** ([PR 13697](https://github.com/bitcoin/bitcoin/pull/13697)).
* [`BIP 386`](https://github.com/bitcoin/bips/blob/master/bip-0386.mediawiki): tr() Output Script Descriptors are implemented as of **v22.0** ([PR 22051](https://github.com/bitcoin/bitcoin/pull/22051)).
+* [`BIP 387`](https://github.com/bitcoin/bips/blob/master/bip-0387.mediawiki): Tapscript Multisig Output Script Descriptors are implemented as of **v24.0** ([PR 24043](https://github.com/bitcoin/bitcoin/pull/24043)).
* [`BIP 431`](https://github.com/bitcoin/bips/blob/master/bip-0431.mediawiki): transactions with nVersion=3 are standard and treated as Topologically Restricted Until Confirmation as of **v28.0** ([PR 29496](https://github.com/bitcoin/bitcoin/pull/29496)).
diff --git a/doc/man/groestlcoin-cli.1 b/doc/man/groestlcoin-cli.1
index 5f60302353eb3..f6cbc43b92ba5 100644
--- a/doc/man/groestlcoin-cli.1
+++ b/doc/man/groestlcoin-cli.1
@@ -2,4 +2,12 @@
.SH NAME
groestlcoin-cli \- manual page for groestlcoin-cli
-This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release.
+Please contribute if you find Bitcoin Core useful. Visit
+ for further information about the software.
+The source code is available from .
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or
+.SH "SEE ALSO"
+bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1)
diff --git a/doc/man/groestlcoin-qt.1 b/doc/man/groestlcoin-qt.1
index cd8cbf4238514..0cbc9aedcb155 100644
--- a/doc/man/groestlcoin-qt.1
+++ b/doc/man/groestlcoin-qt.1
@@ -2,4 +2,12 @@
.SH NAME
groestlcoin-qt \- manual page for groestlcoin-qt
-This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release.
+Please contribute if you find Bitcoin Core useful. Visit
+ for further information about the software.
+The source code is available from .
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or
+.SH "SEE ALSO"
+bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1)
diff --git a/doc/man/groestlcoin-tx.1 b/doc/man/groestlcoin-tx.1
index dd878f10e4e66..db708b736d5e5 100644
--- a/doc/man/groestlcoin-tx.1
+++ b/doc/man/groestlcoin-tx.1
@@ -2,4 +2,12 @@
.SH NAME
groestlcoin-tx \- manual page for groestlcoin-tx
-This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release.
+Please contribute if you find Bitcoin Core useful. Visit
+ for further information about the software.
+The source code is available from .
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or
+.SH "SEE ALSO"
+bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1)
diff --git a/doc/man/groestlcoind.1 b/doc/man/groestlcoind.1
index 1024071149bd0..e37e1c6d6288f 100644
--- a/doc/man/groestlcoind.1
+++ b/doc/man/groestlcoind.1
@@ -2,4 +2,12 @@
.SH NAME
groestlcoind \- manual page for groestlcoind
-This is a placeholder file. Please follow the instructions in \fIcontrib/devtools/README.md\fR to generate the manual pages after a release.
+Please contribute if you find Bitcoin Core useful. Visit
+ for further information about the software.
+The source code is available from .
+
+This is experimental software.
+Distributed under the MIT software license, see the accompanying file COPYING
+or
+.SH "SEE ALSO"
+bitcoind(1), bitcoin-cli(1), bitcoin-tx(1), bitcoin-wallet(1), bitcoin-util(1), bitcoin-qt(1)
diff --git a/doc/release-28984.md b/doc/release-28984.md
deleted file mode 100644
index 3da64f6578682..0000000000000
--- a/doc/release-28984.md
+++ /dev/null
@@ -1,6 +0,0 @@
-P2P and network changes
------------------------
-
-- Limited package RBF is now enabled, where the proposed conflicting package would result in
- a connected component, aka cluster, of size 2 in the mempool. All clusters being conflicted
- against must be of size 2 or lower.
diff --git a/doc/release-notes-22729.md b/doc/release-notes-22729.md
deleted file mode 100644
index 7b836c2701a4a..0000000000000
--- a/doc/release-notes-22729.md
+++ /dev/null
@@ -1,21 +0,0 @@
-Notable changes
-===============
-
-P2P and network changes
------------------------
-
-- Previously if Bitcoin Core was listening for P2P connections, either using
- default settings or via `bind=addr:port` it would always also bind to
- `127.0.0.1:8334` to listen for Tor connections. It was not possible to switch
- this off, even if the node didn't use Tor. This has been changed and now
- `bind=addr:port` results in binding on `addr:port` only. The default behavior
- of binding to `0.0.0.0:8333` and `127.0.0.1:8334` has not been changed.
-
- If you are using a `bind=...` configuration without `bind=...=onion` and rely
- on the previous implied behavior to accept incoming Tor connections at
- `127.0.0.1:8334`, you need to now make this explicit by using
- `bind=... bind=127.0.0.1:8334=onion`. (#22729)
-
-- Bitcoin Core will now fail to start up if any of its P2P binds fail, rather
- than the previous behaviour where it would only abort startup if all P2P
- binds had failed. (#22729)
diff --git a/doc/release-notes-27101.md b/doc/release-notes-27101.md
deleted file mode 100644
index 7ce1e9a8c103f..0000000000000
--- a/doc/release-notes-27101.md
+++ /dev/null
@@ -1,6 +0,0 @@
-JSON-RPC
---------
-
-The JSON-RPC server now recognizes JSON-RPC 2.0 requests and responds with
-strict adherence to the [specification](https://www.jsonrpc.org/specification).
-See [JSON-RPC-interface.md](/doc/JSON-RPC-interface.md#json-rpc-11-vs-20) for details.
\ No newline at end of file
diff --git a/doc/release-notes-27114.md b/doc/release-notes-27114.md
deleted file mode 100644
index 980ffd78a44f2..0000000000000
--- a/doc/release-notes-27114.md
+++ /dev/null
@@ -1,2 +0,0 @@
-- Additional flags "in" and "out" have been added to `-whitelist` to control whether
- permissions apply to incoming connections and/or manual (default: incoming only).
\ No newline at end of file
diff --git a/doc/release-notes-27307.md b/doc/release-notes-27307.md
deleted file mode 100644
index 58fc7098b581a..0000000000000
--- a/doc/release-notes-27307.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Wallet
----
-
-The wallet now detects when wallet transactions conflict with the mempool. Mempool
-conflicting transactions can be seen in the `"mempoolconflicts"` field of
-`gettransaction`. The inputs of mempool conflicted transactions can now be respent
-without manually abandoning the transactions when the parent transaction is dropped
-from the mempool, which can cause wallet balances to appear higher.
diff --git a/doc/release-notes-27375.md b/doc/release-notes-27375.md
deleted file mode 100644
index e3f4ebdf7767e..0000000000000
--- a/doc/release-notes-27375.md
+++ /dev/null
@@ -1,6 +0,0 @@
-P2P
----
-
-UNIX domain sockets can now be used for proxy connections. Set `-onion` or `-proxy`
-to the local socket path with the prefix `unix:` (e.g. `-onion=unix:/home/me/torsocket`).
-(#27375)
\ No newline at end of file
diff --git a/doc/release-notes-27679.md b/doc/release-notes-27679.md
deleted file mode 100644
index dbbb30428caa3..0000000000000
--- a/doc/release-notes-27679.md
+++ /dev/null
@@ -1,2 +0,0 @@
-- unix socket paths are now accepted for `-zmqpubrawblock` and `-zmqpubrawtx` with
-the format `-zmqpubrawtx=unix:/path/to/file`
\ No newline at end of file
diff --git a/doc/release-notes-28052.md b/doc/release-notes-28052.md
deleted file mode 100644
index 386f0cee5f0b1..0000000000000
--- a/doc/release-notes-28052.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Blockstorage
-============
-
-Block files are now XOR'd by default with a key stored in the blocksdir.
-Previous releases of Bitcoin Core or previous external software will not be able to read the blocksdir with a non-zero XOR-key.
-Refer to the `-blocksxor` help for more details.
diff --git a/doc/release-notes-29091-29165.md b/doc/release-notes-29091-29165.md
deleted file mode 100644
index e13d29adc6c5c..0000000000000
--- a/doc/release-notes-29091-29165.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Build
------
-
-GCC 11.1 or later, or Clang 16.0 or later,
-are now required to compile Bitcoin Core.
diff --git a/doc/release-notes-29496.md b/doc/release-notes-29496.md
deleted file mode 100644
index 799b2ca01d5b0..0000000000000
--- a/doc/release-notes-29496.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Mempool Policy Changes
-----------------------
-
-- Transactions with version number set to 3 are now treated as standard on all networks (#29496),
- subject to Opt-in Topologically Restricted Until Confirmation (TRUC) Transactions policy as
- described in [BIP 431](https://github.com/bitcoin/bips/blob/master/bip-0431.mediawiki). The
- policy includes limits on spending unconfirmed outputs (#28948), eviction of a previous descendant
- if a more incentive-compatible one is submitted (#29306), and a maximum transaction size of 10,000vB
- (#29873). These restrictions simplify the assessment of incentive compatibility of accepting or
- replacing TRUC transactions, thus ensuring any replacements are more profitable for the node and
- making fee-bumping more reliable.
diff --git a/doc/release-notes-29612.md b/doc/release-notes-29612.md
deleted file mode 100644
index 31af3cab09ca9..0000000000000
--- a/doc/release-notes-29612.md
+++ /dev/null
@@ -1,8 +0,0 @@
-RPC
----
-
-- The `dumptxoutset` RPC now returns the UTXO set dump in a new and
- improved format. At the same time the `loadtxoutset` RPC now
- expects this new format in dumps it tries to load. Dumps with the
- old format are no longer supported and need to be recreated using
- the new format in order to be usable.
diff --git a/doc/release-notes-29775.md b/doc/release-notes-29775.md
deleted file mode 100644
index 6cb3ed3e8d1ac..0000000000000
--- a/doc/release-notes-29775.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Testnet4/BIP94 support
------
-
-Support for Testnet4 as specified in [BIP94](https://github.com/bitcoin/bips/blob/master/bip-0094.mediawiki)
-has been added. The network can be selected with the `-testnet4` option and
-the section header is also named `[testnet4]`.
-
-While the intention is to phase out support for Testnet3 in an upcoming
-version, support for it is still available via the known options in this
-release.
diff --git a/doc/release-notes-29845.md b/doc/release-notes-29845.md
deleted file mode 100644
index 4994d0a34dfe5..0000000000000
--- a/doc/release-notes-29845.md
+++ /dev/null
@@ -1,8 +0,0 @@
-RPC
----
-
-- the `warnings` field in `getblockchaininfo`, `getmininginfo` and
- `getnetworkinfo` now returns all the active node warnings as an array
- of strings, instead of just a single warning. The current behaviour
- can temporarily be restored by running bitcoind with configuration
- option `-deprecatedrpc=warnings`.
\ No newline at end of file
diff --git a/doc/release-notes-29987.md b/doc/release-notes-29987.md
deleted file mode 100644
index 4d4c2358d114c..0000000000000
--- a/doc/release-notes-29987.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Compatibility
-=============
-
-The minimum required glibc to run Bitcoin Core is now
-2.31. This means that RHEL 8 and Ubuntu 18.04 (Bionic)
-are no-longer supported. (#29987)
\ No newline at end of file
diff --git a/doc/release-notes-30058.md b/doc/release-notes-30058.md
deleted file mode 100644
index 47e7ae704e21a..0000000000000
--- a/doc/release-notes-30058.md
+++ /dev/null
@@ -1,7 +0,0 @@
-- When running with -alertnotify, an alert can now be raised multiple
-times instead of just once. Previously, it was only raised when unknown
-new consensus rules were activated, whereas the scope has now been
-increased to include all kernel warnings. Specifically, alerts will now
-also be raised when an invalid chain with a large amount of work has
-been detected. Additional warnings may be added in the future.
-(#30058)
diff --git a/doc/release-notes-30192.md b/doc/release-notes-30192.md
deleted file mode 100644
index 2a6c17d455c8d..0000000000000
--- a/doc/release-notes-30192.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Build
------
-
-`--enable-lcov-branch-coverage` has been removed, given
-incompatibilities between lcov version 1 & 2. `LCOV_OPTS`
-should be used to set any options instead.
diff --git a/doc/release-notes-30212.md b/doc/release-notes-30212.md
deleted file mode 100644
index cc4ea59b7f88a..0000000000000
--- a/doc/release-notes-30212.md
+++ /dev/null
@@ -1,8 +0,0 @@
-RPC
----
-
-- Previously when using the `sendrawtransaction` rpc and specifying outputs
- that are already in the UXTO set an RPC error code `-27` with RPC error
- text "Transaction already in block chain" was returned in response.
- The help text has been updated to "Transaction outputs already in utxo set"
- to more accurately describe the source of the issue.
diff --git a/doc/release-notes-30275.md b/doc/release-notes-30275.md
deleted file mode 100644
index 2fcaef17c8a3a..0000000000000
--- a/doc/release-notes-30275.md
+++ /dev/null
@@ -1,7 +0,0 @@
-RPC
----
-
-- The default mode for the `estimatesmartfee` RPC has been updated from `conservative` to `economical`.
- which is expected to reduce overestimation for many users, particularly if Replace-by-Fee is an option.
- For users that require high confidence in their fee estimates at the cost of potentially overestimating,
- the `conservative` mode remains available.
diff --git a/doc/release-notes-30352.md b/doc/release-notes-30352.md
deleted file mode 100644
index b67577a466752..0000000000000
--- a/doc/release-notes-30352.md
+++ /dev/null
@@ -1,10 +0,0 @@
-P2P and network changes
------------------------
-
-- Pay To Anchor(P2A) is a new standard witness output type for spending,
- a newly recognised output template. This allows for key-less anchor
- outputs, with compact spending conditions for additional efficiencies on
- top of an equivalent `sh(OP_TRUE)` output, in addition to the txid stability
- of the spending transaction.
- N.B. propagation of this output spending on the network will be limited
- until a sufficient number of nodes on the network adopt this upgrade.
diff --git a/doc/release-notes-30482.md b/doc/release-notes-30482.md
deleted file mode 100644
index fb625c2fa9889..0000000000000
--- a/doc/release-notes-30482.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Updated REST APIs
------------------
-- Parameter validation for `/rest/getutxos` has been improved by rejecting
- truncated or overly large txids and malformed outpoint indices by raising an
- HTTP_BAD_REQUEST "Parse error". Previously, these malformed requests would be
- silently handled. (#30482, #30444)
diff --git a/doc/release-notes-30493.md b/doc/release-notes-30493.md
deleted file mode 100644
index 98afbcc7d1334..0000000000000
--- a/doc/release-notes-30493.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Full Replace-By-Fee
-===================
-
-`mempoolfullrbf=1` is now set by default.
diff --git a/doc/release-notes-30647.md b/doc/release-notes-30647.md
deleted file mode 100644
index ca91f0aaeb648..0000000000000
--- a/doc/release-notes-30647.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Tests
------
-
-- The BIP94 timewarp attack mitigation is now active on the `regtest` network
diff --git a/doc/release-notes-empty-template.md b/doc/release-notes-empty-template.md
deleted file mode 100644
index 0c70d084e6675..0000000000000
--- a/doc/release-notes-empty-template.md
+++ /dev/null
@@ -1,95 +0,0 @@
-*The release notes draft is a temporary file that can be added to by anyone. See
-[/doc/developer-notes.md#release-notes](/doc/developer-notes.md#release-notes)
-for the process.*
-
-*version* Release Notes Draft
-===============================
-
-Groestlcoin Core version *version* is now available from:
-
-
-
-This release includes new features, various bug fixes and performance
-improvements, as well as updated translations.
-
-Please report bugs using the issue tracker at GitHub:
-
-
-
-How to Upgrade
-==============
-
-If you are running an older version, shut it down. Wait until it has completely
-shut down (which might take a few minutes in some cases), then run the
-installer (on Windows) or just copy over `/Applications/Groestlcoin-Qt` (on macOS)
-or `groestlcoind`/`groestlcoin-qt` (on Linux).
-
-Upgrading directly from a version of Groestlcoin Core that has reached its EOL is
-possible, but it might take some time if the data directory needs to be migrated. Old
-wallet versions of Groestlcoin Core are generally supported.
-
-Compatibility
-==============
-
-Groestlcoin Core is supported and extensively tested on operating systems
-using the Linux Kernel 3.17+, macOS 11.0+, and Windows 7 and newer. Groestlcoin
-Core should also work on most other Unix-like systems but is not as
-frequently tested on them. It is not recommended to use Groestlcoin Core on
-unsupported systems.
-
-Notable changes
-===============
-
-P2P and network changes
------------------------
-
-Updated RPCs
-------------
-
-
-Changes to wallet related RPCs can be found in the Wallet section below.
-
-New RPCs
---------
-
-Build System
-------------
-
-Updated settings
-----------------
-
-
-Changes to GUI or wallet related settings can be found in the GUI or Wallet section below.
-
-New settings
-------------
-
-Tools and Utilities
--------------------
-
-Wallet
-------
-
-GUI changes
------------
-
-Low-level changes
-=================
-
-RPC
----
-
-Tests
------
-
-*version* change log
-====================
-
-Credits
-=======
-
-Thanks to everyone who directly contributed to this release:
-
-
-As well as to everyone that helped with translations on
-[Transifex](https://www.transifex.com/bitcoin/bitcoin/).
diff --git a/doc/release-notes.md b/doc/release-notes.md
new file mode 100644
index 0000000000000..7a587cfec90b9
--- /dev/null
+++ b/doc/release-notes.md
@@ -0,0 +1 @@
+See https://github.com/bitcoin-core/bitcoin-devwiki/wiki/28.0-Release-Notes-Draft
diff --git a/doc/release-notes/release-notes-27064.md b/doc/release-notes/release-notes-27064.md
deleted file mode 100644
index be3ecee1b8e9c..0000000000000
--- a/doc/release-notes/release-notes-27064.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Files
------
-
-The default data directory on Windows has been moved from `C:\Users\Username\AppData\Roaming\Bitcoin`
-to `C:\Users\Username\AppData\Local\Bitcoin`. Bitcoin Core will check the existence
-of the old directory first and continue to use that directory for backwards
-compatibility if it is present.
\ No newline at end of file
diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h
index af45f81f95e45..be596b17657cb 100644
--- a/src/interfaces/chain.h
+++ b/src/interfaces/chain.h
@@ -96,6 +96,17 @@ struct BlockInfo {
BlockInfo(const uint256& hash LIFETIMEBOUND) : hash(hash) {}
};
+//! The action to be taken after updating a settings value.
+//! WRITE indicates that the updated value must be written to disk,
+//! while SKIP_WRITE indicates that the change will be kept in memory-only
+//! without persisting it.
+enum class SettingsAction {
+ WRITE,
+ SKIP_WRITE
+};
+
+using SettingsUpdate = std::function(common::SettingsValue&)>;
+
//! Interface giving clients (wallet processes, maybe other analysis tools in
//! the future) ability to access to the chain state, receive notifications,
//! estimate fees, and submit transactions.
@@ -344,9 +355,16 @@ class Chain
//! Return /settings.json setting value.
virtual common::SettingsValue getRwSetting(const std::string& name) = 0;
- //! Write a setting to /settings.json. Optionally just update the
- //! setting in memory and do not write the file.
- virtual bool updateRwSetting(const std::string& name, const common::SettingsValue& value, bool write=true) = 0;
+ //! Updates a setting in /settings.json.
+ //! Depending on the action returned by the update function, this will either
+ //! update the setting in memory or write the updated settings to disk.
+ virtual bool updateRwSetting(const std::string& name, const SettingsUpdate& update_function) = 0;
+
+ //! Replace a setting in /settings.json with a new value.
+ virtual bool overwriteRwSetting(const std::string& name, common::SettingsValue& value, bool write = true) = 0;
+
+ //! Delete a given setting in /settings.json.
+ virtual bool deleteRwSettings(const std::string& name, bool write = true) = 0;
//! Synchronously send transactionAddedToMempool notifications about all
//! current mempool transactions to the specified handler and return after
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 9fe08eb3dd3d4..54b986c926afd 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -814,14 +814,32 @@ class ChainImpl : public Chain
});
return result;
}
- bool updateRwSetting(const std::string& name, const common::SettingsValue& value, bool write) override
+ bool updateRwSetting(const std::string& name,
+ const interfaces::SettingsUpdate& update_settings_func) override
{
+ std::optional action;
args().LockSettings([&](common::Settings& settings) {
- if (value.isNull()) {
- settings.rw_settings.erase(name);
- } else {
- settings.rw_settings[name] = value;
- }
+ auto* ptr_value = common::FindKey(settings.rw_settings, name);
+ // Create value if it doesn't exist
+ auto& value = ptr_value ? *ptr_value : settings.rw_settings[name];
+ action = update_settings_func(value);
+ });
+ if (!action) return false;
+ // Now dump value to disk if requested
+ return *action == interfaces::SettingsAction::SKIP_WRITE || args().WriteSettingsFile();
+ }
+ bool overwriteRwSetting(const std::string& name, common::SettingsValue& value, bool write) override
+ {
+ if (value.isNull()) return deleteRwSettings(name, write);
+ return updateRwSetting(name, [&](common::SettingsValue& settings) {
+ settings = std::move(value);
+ return write ? interfaces::SettingsAction::WRITE : interfaces::SettingsAction::SKIP_WRITE;
+ });
+ }
+ bool deleteRwSettings(const std::string& name, bool write) override
+ {
+ args().LockSettings([&](common::Settings& settings) {
+ settings.rw_settings.erase(name);
});
return !write || args().WriteSettingsFile();
}
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index e26347d437af3..129b5c7c2a0a7 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -69,7 +69,7 @@ bool VerifyWallets(WalletContext& context)
// Pass write=false because no need to write file and probably
// better not to. If unnamed wallet needs to be added next startup
// and the setting is empty, this code will just run again.
- chain.updateRwSetting("wallet", wallets, /* write= */ false);
+ chain.overwriteRwSetting("wallet", wallets, /*write=*/false);
}
}
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 86d852ce5090c..c48ae8b0f3d53 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -329,6 +329,40 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
}
}
+// This test verifies that wallet settings can be added and removed
+// concurrently, ensuring no race conditions occur during either process.
+BOOST_FIXTURE_TEST_CASE(write_wallet_settings_concurrently, TestingSetup)
+{
+ WalletContext context;
+ context.chain = m_node.chain.get();
+ const auto NUM_WALLETS{5};
+
+ // Since we're counting the number of wallets, ensure we start without any.
+ BOOST_REQUIRE(context.chain->getRwSetting("wallet").isNull());
+
+ const auto& check_concurrent_wallet = [&](const auto& settings_function, int num_expected_wallets) {
+ std::vector threads;
+ threads.reserve(NUM_WALLETS);
+ for (auto i{0}; i < NUM_WALLETS; ++i) threads.emplace_back(settings_function, i);
+ for (auto& t : threads) t.join();
+
+ auto wallets = context.chain->getRwSetting("wallet");
+ BOOST_CHECK_EQUAL(wallets.getValues().size(), num_expected_wallets);
+ };
+
+ // Add NUM_WALLETS wallets concurrently, ensure we end up with NUM_WALLETS stored.
+ check_concurrent_wallet([&context](int i) {
+ Assert(AddWalletSetting(*context.chain, strprintf("wallet_%d", i)));
+ },
+ /*num_expected_wallets=*/NUM_WALLETS);
+
+ // Remove NUM_WALLETS wallets concurrently, ensure we end up with 0 wallets.
+ check_concurrent_wallet([&context](int i) {
+ Assert(RemoveWalletSetting(*context.chain, strprintf("wallet_%d", i)));
+ },
+ /*num_expected_wallets=*/0);
+}
+
// Check that GetImmatureCredit() returns a newly calculated value instead of
// the cached value after a MarkDirty() call.
//
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index f627bafcb94d8..404bb47d443c8 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -93,25 +93,30 @@ namespace wallet {
bool AddWalletSetting(interfaces::Chain& chain, const std::string& wallet_name)
{
- common::SettingsValue setting_value = chain.getRwSetting("wallet");
- if (!setting_value.isArray()) setting_value.setArray();
- for (const common::SettingsValue& value : setting_value.getValues()) {
- if (value.isStr() && value.get_str() == wallet_name) return true;
- }
- setting_value.push_back(wallet_name);
- return chain.updateRwSetting("wallet", setting_value);
+ const auto update_function = [&wallet_name](common::SettingsValue& setting_value) {
+ if (!setting_value.isArray()) setting_value.setArray();
+ for (const auto& value : setting_value.getValues()) {
+ if (value.isStr() && value.get_str() == wallet_name) return interfaces::SettingsAction::SKIP_WRITE;
+ }
+ setting_value.push_back(wallet_name);
+ return interfaces::SettingsAction::WRITE;
+ };
+ return chain.updateRwSetting("wallet", update_function);
}
bool RemoveWalletSetting(interfaces::Chain& chain, const std::string& wallet_name)
{
- common::SettingsValue setting_value = chain.getRwSetting("wallet");
- if (!setting_value.isArray()) return true;
- common::SettingsValue new_value(common::SettingsValue::VARR);
- for (const common::SettingsValue& value : setting_value.getValues()) {
- if (!value.isStr() || value.get_str() != wallet_name) new_value.push_back(value);
- }
- if (new_value.size() == setting_value.size()) return true;
- return chain.updateRwSetting("wallet", new_value);
+ const auto update_function = [&wallet_name](common::SettingsValue& setting_value) {
+ if (!setting_value.isArray()) return interfaces::SettingsAction::SKIP_WRITE;
+ common::SettingsValue new_value(common::SettingsValue::VARR);
+ for (const auto& value : setting_value.getValues()) {
+ if (!value.isStr() || value.get_str() != wallet_name) new_value.push_back(value);
+ }
+ if (new_value.size() == setting_value.size()) return interfaces::SettingsAction::SKIP_WRITE;
+ setting_value = std::move(new_value);
+ return interfaces::SettingsAction::WRITE;
+ };
+ return chain.updateRwSetting("wallet", update_function);
}
static void UpdateWalletSetting(interfaces::Chain& chain,