26.0 Release Candidate Testing Guide - bitcoin-core/bitcoin-devwiki GitHub Wiki

Testing Guide: Bitcoin Core 26.0 Release Candidate

For feedback on this guide, please visit #28866

This document outlines some of the upcoming Bitcoin Core 26.0 release changes and provides steps to help test them. This guide is meant to be the starting point for experimentation and further testing, but is in no way comprehensive! After running through the steps in this guide, you are encouraged to do your own testing.

This can be as simple as testing the same features in this guide but trying it a different way. Even better, think of features you use regularly and test that they still work as expected in the release candidate. You can also read the release notes to find something not covered in this guide. This is a great way to be involved with Bitcoin's development and helps keep Bitcoin running smoothly and bug-free! Your help in this endeavour is greatly appreciated.

Overview

Changes covered in this testing guide include:


For a comprehensive list of changes in Bitcoin Core 26.0, check out the release notes.

Preparation

1. Grab Latest Release Candidate

Current Release Candidate: Bitcoin Core 26.0rc2 (release-notes)

There are two ways to grab the latest release candidate: pre-compiled binary or source code. The source code for the latest release can be grabbed from here: latest release source code

If you want to use a binary, make sure to grab the correct one for your system.

2. Compile Release Candidate

If you grabbed a binary, skip this step

Before compiling, make sure that your system has all the right dependencies installed and that you have checked out the correct tag:

git checkout -b v26.0rc3 tags/v26.0rc3

For more information on compiling from source, here are some guides to compile Bitcoin Core for UNIX/Linux, macOS, Windows, FreeBSD, NetBSD, and OpenBSD.

3. Setting up command line environment

First, create a temporary data directory

export DATA_DIR=/tmp/26-rc-test
mkdir $DATA_DIR

Next, specify the following paths. For source compiled, start from the root of your release candidate directory and run:

export BINARY_PATH=$(pwd)/src

For the downloaded binary, start from the root of the downloaded release candidate (cd ~/bitcoin-26.0rc2, for example) and run:

export BINARY_PATH=$(pwd)/bin

To avoid specifying the data directory (-datadir=$DATA_DIR) on each command, below are a few extra variables to set.

alias bitcoind-test="$(echo $BINARY_PATH)/bitcoind -datadir=$DATA_DIR"
alias bcli="$(echo $BINARY_PATH)/bitcoin-cli -datadir=$DATA_DIR"

The commands throughout the rest of the guide will look like:

bcli [cli args]

Start node

echo "regtest=1" > $DATA_DIR/bitcoin.conf
bitcoind-test
2023-11-05T13:42:54Z Bitcoin Core version v26.0rc2 (release build)
2023-11-05T13:42:54Z Using the 'x86_shani(1way,2way)' SHA256 implementation
2023-11-05T13:42:54Z Using RdSeed as an additional entropy source
2023-11-05T13:42:54Z Using RdRand as an additional entropy source
2023-11-05T13:42:54Z Default data directory /home/max/.bitcoin
2023-11-05T13:42:54Z Using data directory /tmp/26-rc-test/regtest
2023-11-05T13:42:54Z Config file: /tmp/26-rc-test/bitcoin.conf (not found, skipping)

Stop bitcoind

Ctrl + C

Look at the logs and ensure you are running the correct version.

For the rest of the guide we will be starting bitcoind in daemon mode (-daemon) and as such CTRL + C will not stop the process. Instead we will be using bcli stop.

4. Reset testing environment

Between sections in this guide, it's recommended to stop your node and wipe the data directory. You can use the commands provided below.

Stop node

bcli stop

Wipe and recreate the directory

rm -r $DATA_DIR
mkdir $DATA_DIR

RPC: add getprioritisedtransactions

The RPC prioritisetransaction allows miners to "prioritise" a transaction in their mempool for block assembly by treating it as if it had a higher fee than it actually does. This new RPC fetches prioritised transactions from the node's mempool.

Before beginning make sure you have already stopped your node and cleaned the datadir.

We can test this RPC on regtest:

echo "regtest=1" > $DATA_DIR/bitcoin.conf
bitcoind-test -daemon

Let's create a wallet

bcli createwallet test-wallet
{
  "name": "test-wallet"
}

And generate some blocks so that we have some funds

bcli -rpcwallet=test-wallet -generate 101

Get an address

export ADDRESS=$(bcli -rpcwallet=test-wallet getnewaddress)

Send a transaction to yourself with a 10 sat per vbyte fee

bcli -rpcwallet=test-wallet -named send outputs="{\"$ADDRESS\": 1}" fee_rate=10
{
  "txid": "2f22473070db30ab29b16a17f31d1fedd07c018639752430c2f265641c277149",
  "complete": true
}

Let's prioritise this transaction and give it a boost of another 10 sats per vbyte

bcli prioritisetransaction <txid from tx above> 0 10

And finally call the getprioritisedtransactions RPC to see that it's prioritised, what the fee delta is and if it's in the mempool.

bcli getprioritisedtransactions
{
  "2f22473070db30ab29b16a17f31d1fedd07c018639752430c2f265641c277149": {
    "fee_delta": 10,
    "in_mempool": true
  }
}

Once the test is successful, don't forget to stop your node and clean the datadir.


RPC: Importmempool

A new RPC is available to import a mempool.dat file without having to restart the node.

Before beginning make sure you have already stopped your node and cleaned the datadir.

This change allows for import of a mempool.dat file using an RPC which previously had to be put in a specific directory when starting bitcoind. To test this on regtest we will put a transaction in the mempool and then shutdown bitcoind, rename the mempool.dat file, start bitcoind and then import the mempool.

Those with a synced mainnet node should do a slightly different test of shutting down their node, renaming the mempool.dat file and then restarting the node but with connect=0 in the conf file to prevent the node from getting mempool transactions from peers and finally importing the renamed mempool file.

Regtest Test

(Please jump to Mainnet Test if you have a synced node on mainnet

Run on regtest

echo "regtest=1" > $DATA_DIR/bitcoin.conf

Start bitcoind

bitcoind-test -daemon

Create a wallet

bcli createwallet test-wallet
{
  "name": "test-wallet"
}

Generate some blocks

bcli -rpcwallet=test-wallet -generate 101

Get an address from the test wallet

export ADDRESS=$(bcli -rpcwallet=test-wallet getnewaddress)

Send a transaction to yourself, leave it as unconfirmed

bcli -rpcwallet=test-wallet -named send outputs="{\"$ADDRESS\": 1}" fee_rate=10

Check mempool, we should see one transaction. The other values in the output may vary for you.

bcli getmempoolinfo
{
  "loaded": true,
  "size": 1,
  "bytes": 141,
  "usage": 1136,
  "total_fee": 0.00001410,
  "maxmempool": 300000000,
  "mempoolminfee": 0.00001000,
  "minrelaytxfee": 0.00001000,
  "incrementalrelayfee": 0.00001000,
  "unbroadcastcount": 1,
  "fullrbf": false
}

Shutdown bitcoind

bcli stop

Rename the mempool file

mv $DATA_DIR/regtest/mempool.dat $DATA_DIR/regtest/mempool.dat.old

Start bitcoind

bitcoind-test -daemon

Check the mempool, it should be empty

bcli getmempoolinfo
{
  "loaded": true,
  "size": 0,
  "bytes": 0,
  "usage": 0,
  "total_fee": 0.00000000,
  "maxmempool": 300000000,
  "mempoolminfee": 0.00001000,
  "minrelaytxfee": 0.00001000,
  "incrementalrelayfee": 0.00001000,
  "unbroadcastcount": 0,
  "fullrbf": false
}

Import the mempool

bcli importmempool $DATA_DIR/regtest/mempool.dat.old

Now we should see that the mempool has one transaction in it again

bcli getmempoolinfo
{
  "loaded": true,
  "size": 1,
  "bytes": 141,
  "usage": 1136,
  "total_fee": 0.00001410,
  "maxmempool": 300000000,
  "mempoolminfee": 0.00001000,
  "minrelaytxfee": 0.00001000,
  "incrementalrelayfee": 0.00001000,
  "unbroadcastcount": 0,
  "fullrbf": false
}

Once the test is successful, don't forget to stop your node and clean the datadir.

Mainnet Test

(Skip if you do not have a mainnet synced node and have completed the regtest test above)

Start mainnet bitcoind if it's not already running and wait for it to get fully synced

bitcoind-test -daemon

Check we are fully synced

bcli -getinfo

Check mempool, we should see transactions

bcli getmempoolinfo
{
  "loaded": true,
  "size": 3017,
  "bytes": 7963335,
  "usage": 23787680,
  "total_fee": 0.89191778,
  "maxmempool": 300000000,
  "mempoolminfee": 0.00001000,
  "minrelaytxfee": 0.00001000,
  "incrementalrelayfee": 0.00001000,
  "unbroadcastcount": 0,
  "fullrbf": false
}

Shutdown bitcoind

bcli stop

Rename the mempool file

mv $DATA_DIR/mempool.dat $DATA_DIR/mempool.dat.old

Prevent bitcoind from connecting to peers

echo "connect=0" >> $DATA_DIR/bitcoin.conf

Start bitcoind

bitcoind-test -daemon

Check the mempool, it should be empty

bcli getmempoolinfo
{
  "loaded": true,
  "size": 0,
  "bytes": 0,
  "usage": 0,
  "total_fee": 0.00000000,
  "maxmempool": 300000000,
  "mempoolminfee": 0.00001000,
  "minrelaytxfee": 0.00001000,
  "incrementalrelayfee": 0.00001000,
  "unbroadcastcount": 0,
  "fullrbf": false
}

Import the mempool

bcli importmempool $DATA_DIR/mempool.dat.old

Now we should see that the mempool has all the transactions in it again

bcli getmempoolinfo
{
  "loaded": true,
  "size": 3017,
  "bytes": 7963335,
  "usage": 23787680,
  "total_fee": 0.89191778,
  "maxmempool": 300000000,
  "mempoolminfee": 0.00001000,
  "minrelaytxfee": 0.00001000,
  "incrementalrelayfee": 0.00001000,
  "unbroadcastcount": 0,
  "fullrbf": false
}

Once the test is successful, don't forget to stop your node and clean the datadir.


V2 Transport - BIP 324

V2 transport if supported by both sides of a connection encrypts peer traffic. In this guide, we will test this on signet by connecting to nodes that are known to support V2 transport but please feel free to run this on a different network.

Before beginning make sure you have already stopped your node and cleaned the datadir.

Add signet=1 and v2transport=1 in the bitcoin.conf to use the signet network for testing.

{
echo "signet=1"
echo "v2transport=1"
} > $DATA_DIR/bitcoin.conf
bitcoind-test -daemon

Connect to a signet node supporting V2. Two nodes on signet that should support V2 Transport are:

  • bitcoin.achow101.com:38333
  • 175.45.182.145:38333.
bcli addnode <node ip or hostname>:38333 add true

The true at end of the previous command instructs the addnode RPC to use V2 transport.

Check that you have successfully connected using V2 Transport:

bcli getpeerinfo
[
  ...
  {
    "id": 15,
    "addr": "bitcoin.achow101.com:38333",
    ...
    "connection_type": "manual",
    "transport_protocol_type": "v2",
    "session_id": "7c081213779063150191fe0295da0dd18d95c9b4dc67809cc4ed9fb9e112ca71"
  }
]

This successfully tested manual v2 connections. To see more logging consider enabling net logging with:

bcli logging "[\"net\"]"

To view anything related to V2 Transport the logs:

cat $DATA_DIR/signet/debug.log | grep v2

Please check to see if you have also connected to an automatic v2 peer which is one that you didn't explicitly try to connect but your node would have become aware of via gossip.

Once the test is successful, don't forget to stop your node and clean the datadir.


TapMiniscript

Miniscript is now supported inside a taproot descriptor. To test, we will use a simple miniscript using fragment or_b which allows one of two keys to be used to spend.

Before beginning make sure you have already stopped your node and cleaned the datadir.

We can run this test on regtest:

echo "regtest=1" > $DATA_DIR/bitcoin.conf
bitcoind-test -daemon

Create two wallets

bcli -named createwallet wallet_name=taproot-wallet blank=true descriptors=true
bcli createwallet legacy-wallet

To use this feature we will use a taproot + miniscript descriptor:

tr(<Taproot Internal Key>,or_b(pk(<key A>/*),s:pk(<key B>/*)))

Breaking down this descriptor we can see that it uses tr() to denote it's taproot, it has one script leaf which uses the miniscript fragment or_b which means one of two keys will be provided.

Take a look at https://bitcoin.sipa.be/miniscript/ to learn about other valid miniscript fragments and scripts.

If we use the following keys:

  • Internal Key: tprv8ZgxMBicQKsPerQj6m35no46amfKQdjY7AhLnmatHYXs8S4MTgeZYkWAn4edSGwwL3vkSiiGqSZQrmy5D3P5gBoqgvYP2fCUpBwbKTMTAkL
  • Key A: tprv8ZgxMBicQKsPd3cbrKjE5GKKJLDEidhtzSSmPVtSPyoHQGL2LZw49yt9foZsN9BeiC5VqRaESUSDV2PS9w7zAVBSK6EQH3CZW9sMKxSKDwD
  • Key B: tprv8iF7W37EHnVEtDr9EFeyFjQJFL6SfGby2AnZ2vQARxTQHQXy9tdzZvBBVp8a19e5vXhskczLkJ1AZjqgScqWL4FpmXVp8LLjiorcrFK63Sr

The full descriptor becomes:

tr(tprv8ZgxMBicQKsPerQj6m35no46amfKQdjY7AhLnmatHYXs8S4MTgeZYkWAn4edSGwwL3vkSiiGqSZQrmy5D3P5gBoqgvYP2fCUpBwbKTMTAkL,or_b(pk(tprv8ZgxMBicQKsPd3cbrKjE5GKKJLDEidhtzSSmPVtSPyoHQGL2LZw49yt9foZsN9BeiC5VqRaESUSDV2PS9w7zAVBSK6EQH3CZW9sMKxSKDwD/*),s:pk(tprv8iF7W37EHnVEtDr9EFeyFjQJFL6SfGby2AnZ2vQARxTQHQXy9tdzZvBBVp8a19e5vXhskczLkJ1AZjqgScqWL4FpmXVp8LLjiorcrFK63Sr/*)))

Lets work out the checksum for this descriptor:

bcli getdescriptorinfo "tr(tprv8ZgxMBicQKsPerQj6m35no46amfKQdjY7AhLnmatHYXs8S4MTgeZYkWAn4edSGwwL3vkSiiGqSZQrmy5D3P5gBoqgvYP2fCUpBwbKTMTAkL,or_b(pk(tprv8ZgxMBicQKsPd3cbrKjE5GKKJLDEidhtzSSmPVtSPyoHQGL2LZw49yt9foZsN9BeiC5VqRaESUSDV2PS9w7zAVBSK6EQH3CZW9sMKxSKDwD/*),s:pk(tprv8iF7W37EHnVEtDr9EFeyFjQJFL6SfGby2AnZ2vQARxTQHQXy9tdzZvBBVp8a19e5vXhskczLkJ1AZjqgScqWL4FpmXVp8LLjiorcrFK63Sr/*)))"
{
  "descriptor": "tr(tpubD6NzVbkrYhZ4YKSWzQhgCCiD9oBFZxvSgUJ85HdBhpLFxvK865U9jF82xCoBAn9nwNZ4uwX7ZKhZbh2iZRPa5s3UHXg3v7d1srFY44SFJVt,or_b(pk(tpubD6NzVbkrYhZ4WWePjyPpUfyRsMjAsxtoZk3Yg1vjpFbgEkanxxkeLUW1qw7Q8k1n9asHy7yC9fJtQmYhAZLFvFr2iYUa2Lv8YWgtcPahTow/*),s:pk(tpubDEw9eT9USAAumgsw7uKZf94QpMcNpbnsbUPLKSSTrEFo7tnjnHTakQo3fxhoD41o5Lq25J64D4DYjPQZMPmVa5xvNX8qP1z19uMPRaGd9Uc/*)))#a78h9fyu",
  "checksum": "sek2wh9v",
  "isrange": true,
  "issolvable": true,
  "hasprivatekeys": true
}

And import the descriptor into our wallet named taproot-wallet

bcli -rpcwallet=taproot-wallet importdescriptors '[{"desc": "tr(tprv8ZgxMBicQKsPerQj6m35no46amfKQdjY7AhLnmatHYXs8S4MTgeZYkWAn4edSGwwL3vkSiiGqSZQrmy5D3P5gBoqgvYP2fCUpBwbKTMTAkL,or_b(pk(tprv8ZgxMBicQKsPd3cbrKjE5GKKJLDEidhtzSSmPVtSPyoHQGL2LZw49yt9foZsN9BeiC5VqRaESUSDV2PS9w7zAVBSK6EQH3CZW9sMKxSKDwD/*),s:pk(tprv8iF7W37EHnVEtDr9EFeyFjQJFL6SfGby2AnZ2vQARxTQHQXy9tdzZvBBVp8a19e5vXhskczLkJ1AZjqgScqWL4FpmXVp8LLjiorcrFK63Sr/*)))#sek2wh9v","timestamp": "now","active":true,"internal": true, "next": 0}]'

Next we can give this wallet some funds by generating blocks and then try and spend back to our wallet named legacy-wallet.

Get an address:

bcli deriveaddresses "tr(tprv8ZgxMBicQKsPerQj6m35no46amfKQdjY7AhLnmatHYXs8S4MTgeZYkWAn4edSGwwL3vkSiiGqSZQrmy5D3P5gBoqgvYP2fCUpBwbKTMTAkL,or_b(pk(tprv8ZgxMBicQKsPd3cbrKjE5GKKJLDEidhtzSSmPVtSPyoHQGL2LZw49yt9foZsN9BeiC5VqRaESUSDV2PS9w7zAVBSK6EQH3CZW9sMKxSKDwD/*),s:pk(tprv8iF7W37EHnVEtDr9EFeyFjQJFL6SfGby2AnZ2vQARxTQHQXy9tdzZvBBVp8a19e5vXhskczLkJ1AZjqgScqWL4FpmXVp8LLjiorcrFK63Sr/*)))#sek2wh9v" "[0,0]"

Generate a block to this address:

bcli generatetoaddress 1 <address from last command>

Then generate 100 other blocks:

bcli -rpcwallet=legacy-wallet -generate 100

Now we should be able to see that our taproot wallet has a UTXO ready to be spent:

bcli -rpcwallet=taproot-wallet listunspent
[
  {
    "txid": "92d4cdf376db2a3b1315d7e9b39700b6ad43b731014b2e0fcea342d7f6e07be3",
    "vout": 0,
    "address": "bcrt1pysnlw6me7prca487trt305dzymxzhkknj834j320cq2krrzl4g8se36kq5",
    "scriptPubKey": "51202427f76b79f0478ed4fe58d717d1a226cc2bdad391e359454fc015618c5faa0f",
    "amount": 50.00000000,
    "confirmations": 101,
    "spendable": true,
    "solvable": true,
    "desc": "tr([00a8d74e]dfb6959ac8931e834c89d8acba84f96e6b1b0034f9ec618d1dffb0f30d579956,or_b(pk([b1841e27/0]02688b79e683b532b1a02ed023c3610bbefb959654bc5069b5e44875712aa0fdf2),s:pk(02ead2ef0977391544379ac093f29675fc2607e7648519d586c7d6f32b7c10985f)))#zss56xjz",
    "parent_descs": [
      "tr(tpubD6NzVbkrYhZ4YKSWzQhgCCiD9oBFZxvSgUJ85HdBhpLFxvK865U9jF82xCoBAn9nwNZ4uwX7ZKhZbh2iZRPa5s3UHXg3v7d1srFY44SFJVt,or_b(pk(tpubD6NzVbkrYhZ4WWePjyPpUfyRsMjAsxtoZk3Yg1vjpFbgEkanxxkeLUW1qw7Q8k1n9asHy7yC9fJtQmYhAZLFvFr2iYUa2Lv8YWgtcPahTow/*),s:pk(tpubDEw9eT9USAAumgsw7uKZf94QpMcNpbnsbUPLKSSTrEFo7tnjnHTakQo3fxhoD41o5Lq25J64D4DYjPQZMPmVa5xvNX8qP1z19uMPRaGd9Uc/*)))#a78h9fyu"
    ],
    "safe": true
  }
]

To spend this, lets construct a payment using that output to a new address.

First get a new address to send funds to:

export ADDRESS=$(bcli -rpcwallet=legacy-wallet getnewaddress)

Send 49.9BTC to this address

bcli -rpcwallet=taproot-wallet -named send outputs="{\"$ADDRESS\": 49.9}" fee_rate=1.1
{
  "txid": "385504b1379770e6b3b8da1e07faf81cd36cd066f84fac33f14b61367608cd2e",
  "complete": true
}

Mine a block

bcli -rpcwallet=legacy-wallet -generate 1
{
  "address": "bcrt1qygad7v49uql5kgqpp6navxxj2g2pw34w0g6n0d",
  "blocks": [
    "15bf3c15480ed033c993c9dda85c9fdc84e4cec0ca9cc1bd191c9fa112a1332a"
  ]
}

Check our transaction id returned from the send command is in the block:

bcli getblock <block from above command>

And check our unspent outputs for the taproot wallet:

bcli -rpcwallet=taproot-wallet listunspent
[
  {
    "txid": "385504b1379770e6b3b8da1e07faf81cd36cd066f84fac33f14b61367608cd2e",
    "vout": 0,
    "address": "bcrt1pv3r0mpgnsufprtdh9yyag9rqh3k4ysd0fcn48vwslyfamhfd2l4qckam67",
    "scriptPubKey": "51206446fd8513871211adb72909d41460bc6d5241af4e2753b1d0f913dddd2d57ea",
    "amount": 0.09999842,
    "confirmations": 1,
    "spendable": true,
    "solvable": true,
    "desc": "tr([00a8d74e]dfb6959ac8931e834c89d8acba84f96e6b1b0034f9ec618d1dffb0f30d579956,or_b(pk(02cf390b69d48bdf855eca713527f1665ac4bf746d5dfaf579321e6fe0c2819084),s:pk([341b3bbc/1]02a110286ad8c309b8376c68dc9c0036d7de3d02a4de426abff7a818790ab1fc4f)))#fnfrp4ax",
    "parent_descs": [
      "tr(tpubD6NzVbkrYhZ4YKSWzQhgCCiD9oBFZxvSgUJ85HdBhpLFxvK865U9jF82xCoBAn9nwNZ4uwX7ZKhZbh2iZRPa5s3UHXg3v7d1srFY44SFJVt,or_b(pk(tpubD6NzVbkrYhZ4WWePjyPpUfyRsMjAsxtoZk3Yg1vjpFbgEkanxxkeLUW1qw7Q8k1n9asHy7yC9fJtQmYhAZLFvFr2iYUa2Lv8YWgtcPahTow/*),s:pk(tpubDEw9eT9USAAumgsw7uKZf94QpMcNpbnsbUPLKSSTrEFo7tnjnHTakQo3fxhoD41o5Lq25J64D4DYjPQZMPmVa5xvNX8qP1z19uMPRaGd9Uc/*)))#a78h9fyu"
    ],
    "safe": true
  }
]

The tooling around TapMiniScript is a little limited at the moment but some ideas on how to take this further could be:

  1. Try more complex miniscript scripts
  2. Implement a 2of2 between a Coldcard and a Ledger which decays into a 1 of 2 after -say- 6 blocks (be cautious with real funds)

Once the test is successful, don't forget to stop your node and clean the datadir.


MacOs zip packaging

With this release packaging has changed for MacOS. If you are following this guide from start to finish then you will have already completed the following steps. This section is just people skimming the document to bring their attention to the fact that the packaging has changed for MacOS and how to check that it's working for them.

To test:

Either:

  1. Compile from source on a mac

Or

  1. Download MacOs Zip from bitcoincore.org

It should be possible to extract the Bitcoin application, drag it to the Applications directory and run it. For the first run you may need to right click the application and click run to give MacOS permissions to run the downloaded app.

Remember to shut bitcoin down as it will start running the initial block download on mainnet if you haven't configured a config file instructing it to do otherwise.


Ancestor Aware Funding

Transactions that use unconfirmed UTXOs as their input will now calculate the effective fee for all the transactions together and increase the fee on the child transaction to hit the desired fee.

Before beginning make sure you have already stopped your node and cleaned the datadir.

Run on regtest:

echo "regtest=1" > $DATA_DIR/bitcoin.conf
bitcoind-test -daemon

Create a wallet

bcli createwallet test-wallet
{
  "name": "test-wallet"
}

Mine yourself some block rewards

bcli -rpcwallet=test-wallet -generate 1

Make another wallet to mine to to get previous transaction confirmed

bcli createwallet another-wallet
{
  "name": "another-wallet"
}
bcli -rpcwallet=another-wallet -generate 100

Create an address with test wallet

export ADDRESS=$(bcli -rpcwallet=test-wallet getnewaddress)

Send a 1BTC, 10 sat per vbyte transaction to yourself using your 50btc block reward

bcli -rpcwallet=test-wallet -named send outputs="{\"$ADDRESS\": 1}" fee_rate=10

This transaction will remain unconfirmed unless we mine a block (which we wont)

Get another address:

export ADDRESS=$(bcli -rpcwallet=test-wallet getnewaddress)

Now send a 2BTC, 20 sat per vbyte transaction to yourself

bcli -rpcwallet=test-wallet -named send outputs="{\"$ADDRESS\": 2}" fee_rate=20

As this second transaction will use the original 1BTC, 10 sat per vbyte transaction's output it would require both transactions to be included in a block. The PR tries to ensure that this child transaction is aware of that ancestor and sets it's fee sufficiently high so that when you average both transactions' fees out they hit your new target (20 sats per vbyte in this case).

Let's look at the transactions on this test wallet and their fees:

bcli -rpcwallet=test-wallet listtransactions
[
  {
    ...
    "category": "generate",
    "amount": 50.00000000,
    "label": "",
    "vout": 0,
    "abandoned": false,
    "confirmations": 101,
    "generated": true,
    ...
  },
  ...
  {
    "address": "bcrt1qwqnjhrp535gxul8rry2jg4xv4rq26ptlg9xqkg",
    "category": "send",
    "amount": -1.00000000,
    "label": "",
    "vout": 1,
    "fee": -0.00001410,
    "confirmations": 0,
    "trusted": true,
    "txid": "3c6f4e09becd0ba3c586535b6e3abdafd766c0e2fc1df5f24c162c60a88dc3e9",
    "wtxid": "de4b240151e07120cae459e40e24b6b2d71d11bd769e6a698741c1b23ce9cf96",
    ...
  },
  ...
  {
    "address": "bcrt1qzwd6gz6dvu6yeh9cl6vdky4a2qszrmlymkugp5",
    "category": "send",
    "amount": -2.00000000,
    "label": "",
    "vout": 0,
    "fee": -0.00004230,
    "confirmations": 0,
    "trusted": true,
    "txid": "3b22b7c7e78f4369177109437bbafe0be47393a12b637c1ac506fa9283fd774e",
    "wtxid": "050e8332d302578cf0c3f3019454d4ab921aeed36ff6ba498b52ad6b2c60b7eb",
    ...
  }
]

Pay attention to the fees paid. The fee on the first transaction was 1410 sats and the fee on the second was 4230. If we add these two fees together we get 5640 sats but that's obviously paying for two transactions. So if we assume equal weight and divide by two we get an average of 2820 paid per tx. This is double the 1410 sats we paid when we asked for 10 sats a vbyte. So the average across both appears to be 20 sats per vbyte as requested by our second transaction.

This test only used one ancestor but automatic bumping should affect all ancestor transactions. Try to make one or two more transactions at a different feerate and consider which transactions were bumped or not bumped.

Once the test is successful, don't forget to stop your node and clean the datadir.


Outbound connection management

The motivation behind this PR is to try to maintain at least one connection per network type (IPV4/6, tor, I2P, CJDNS).

Before beginning make sure you have already stopped your node and cleaned the datadir.

How to test this improvement:

  1. Run on mainnet
  2. Configure multiple networks (IP4/6, tor, I2P, CJDNS)
  3. Observe that node connects to at least one peer in all of these networks
  4. As you are on mainnet remember to shutdown bitcoind when you are finished

If you are running the GUI (bitcoin-qt) it is possible to see the connections using the Peers tab on the Node window (main menu->Window->Peers).

The problem with the above test is that it is entirely possible you would have had connections to all of those networks by chance. We can't prove the PR helped in this regard. It is beyond the scope of this testing document but one idea for how we could try to have more confidence that the PR is working is to setup a contrived network, perhaps using the Warnet tool.

Alternative testing idea using warnet

  1. Run warnet with hundreds of IPV4 nodes and a handful of tor/i2p/cjdns nodes
  2. Observe that the multi network nodes all find and connect with each other

The idea is that before the PR a multi network node would be happy just connecting to the plentiful IPV4 nodes.

Once the test is successful, don't forget to stop your node and clean the datadir.


Add pool based memory resource

This release includes a strategy for allocating memory that is optimised for node-based containers. The goal is to be able to cache more coins with the same memory usage. We should be able to see performance improvements when reindexing the chainstate.

Before beginning make sure you have already stopped your node and cleaned the datadir.

If possible, run this test on mainnet with a synced node.

Run a re-index up to block 690000. Warning: depending on hardware this will take a long time, probably hours.

bitcoind-test -dbcache=5000 -assumevalid=00000000000000000002a23d6df20eecec15b21d32c75833cce28f113de888b7 -reindex-chainstate -stopatheight=690000

That's the test complete. To see the performance improvements, compare the runtime against bitcoin 25.

If you are impatient you can see the performance improvements by just reindexing up to block 300000 which should only take a matter of minutes.

bitcoind-test -dbcache=5000 -assumevalid=000000000000000082ccf8f1557c5d40b21edabb18d2d691cfbf87118bac7254 -reindex-chainstate -stopatheight=300000

Kudos if you make it this far 👏🎉

Thanks for your contribution and for taking the time to make Bitcoin awesome. For feedback on this guide, please visit #28866


Many thanks to stickies-v, Pieter Wuille, murchandamus, Antoine Poinsot and Abubakar Sadiq Ismail for their input and review on this document.

⚠️ **GitHub.com Fallback** ⚠️