Skip to content

Latest commit

 

History

History
1094 lines (960 loc) · 38 KB

v24.0rc1-testing.md

File metadata and controls

1094 lines (960 loc) · 38 KB

General notes

Environment: Ubuntu 22.04 LTS, compiled from source

Configure command:

./configure --with-gui=yes --with-sqlite=yes BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include"

Can Add prune=550 to bitcoin.conf if disk space is low, but need to restart and reindex the node if doing this in the middle of a test scenario. So it may make sense to wipe the data directory and start over.

All tests are preformed on mainnet unless otherwise stated.

To recreate the data directory: rm -r $DATA_DIR && mkdir $DATA_DIR

Helpful links

Observing the new headers pre-synchronization phase during IBD

Test Results

Logs for headers pre-sync

✔️ Logs match what the testing guide expects

2022-09-28T15:57:43Z [net] Initial headers sync started with peer=0: height=0, max_commitments=4452548, min_work=00000000000000000000000000000000000000003404ba0801921119f903495e
2022-09-28T15:57:43Z [net] sending getheaders (101 bytes) peer=0
2022-09-28T15:57:43Z [net] more getheaders (from 00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a) to peer=0
2022-09-28T15:57:43Z Pre-synchronizing blockheaders, height: 2000 (~0.28%)
[...]
2022-09-28T15:58:50Z Pre-synchronizing blockheaders, height: 738000 (~97.62%)
[...]
2022-09-28T15:58:51Z [net] Initial headers sync transition with peer=8: reached sufficient work at height=752000, redownloading from height=0

Logs for headers sync

✔️ Logs match what the testing guide expects

2022-09-28T15:58:51Z [net] Initial headers sync transition with peer=8: reached sufficient work at height=752000, redownloading from height=0
2022-09-28T15:58:51Z [net] sending getheaders (101 bytes) peer=8
2022-09-28T15:58:51Z [net] more getheaders (from 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f) to peer=8
2022-09-28T15:58:51Z [net] received: headers (162003 bytes) peer=8
[...]
2022-09-28T15:58:51Z Synchronizing blockheaders, height: 4041 (~0.56%)
[...]
2022-09-28T15:59:05Z [net] Initial headers sync complete with peer=8: releasing all at height=752000 (redownload phase)
2022-09-28T15:59:05Z Synchronizing blockheaders, height: 752000 (~99.46%)

Watching the getpeerinfo output

✔️ As expected, the presynced_headers field is set for the peer currently involved in the presync/sync phase (instead of -1)

alt text

Observe Further: The peer I was syncing with did not disconnect, and no new blocks came in during headers pre-sync/sync. As a result, I did not observe any of the less common scenarios described in the guide.

Testing transient addresses for I2P outbound connections

Used official I2P router from https://geti2p.net/en/download

To run: ~/i2p/i2prouter start

Tip: to enable SAM, go to http://127.0.0.1:7657/configclients

Test Results

Accepting incoming connections

✔️ I2P address is the same for all outgoing connections

bitcoind -i2pacceptincoming=1

cli getpeerinfo | jq 'map(select(.network == "i2p" and .inbound == false)) | map({addrbind: .addrbind})'
[
  {
    "addrbind": "z4n5a4zqohzwqkakyt5j5c6znml7becr4t27cumo4symisgbhwwa.b32.i2p:0"
  },
  {
    "addrbind": "z4n5a4zqohzwqkakyt5j5c6znml7becr4t27cumo4symisgbhwwa.b32.i2p:0"
  },
  {
    "addrbind": "z4n5a4zqohzwqkakyt5j5c6znml7becr4t27cumo4symisgbhwwa.b32.i2p:0"
  },
  {
    "addrbind": "z4n5a4zqohzwqkakyt5j5c6znml7becr4t27cumo4symisgbhwwa.b32.i2p:0"
  },
  {
    "addrbind": "z4n5a4zqohzwqkakyt5j5c6znml7becr4t27cumo4symisgbhwwa.b32.i2p:0"
  },
  {
    "addrbind": "z4n5a4zqohzwqkakyt5j5c6znml7becr4t27cumo4symisgbhwwa.b32.i2p:0"
  },
  {
    "addrbind": "z4n5a4zqohzwqkakyt5j5c6znml7becr4t27cumo4symisgbhwwa.b32.i2p:0"
  },
  {
    "addrbind": "z4n5a4zqohzwqkakyt5j5c6znml7becr4t27cumo4symisgbhwwa.b32.i2p:0"
  }
]

Not accepting incoming connections

✔️ I2P address is different for each outgoing connection

bitcoind -i2pacceptincoming=0

cli getpeerinfo | jq 'map(select(.network == "i2p" and .inbound == false)) | map({addrbind: .addrbind})'
[
  {
    "addrbind": "qtmvnqodarfi5c4qlm2y2kga7aefz5y42k3svpbqnaclxyfaswqq.b32.i2p:0"
  },
  {
    "addrbind": "mgo3mkxa3dtgaaobn5vh6boqgwe6rpegrrsxqryxuhqcdg7yio2a.b32.i2p:0"
  },
  {
    "addrbind": "aeb43hzl6vrma5nu6obtanousnzirceva3b3w2xwuht7so7cfoza.b32.i2p:0"
  },
  {
    "addrbind": "2fpnc3wviya4cqxxs7egj5rvaepaloujitcod4qjtmueh5datrba.b32.i2p:0"
  },
  {
    "addrbind": "7kbarnrexsw7e7xzopye72fionp72fubhmhhkaurnjh5x5gpzlza.b32.i2p:0"
  },
  {
    "addrbind": "oriaauihkownt6rvprsvg56xwprdoky57rbyidqnkrd24qqbd6fq.b32.i2p:0"
  },
  {
    "addrbind": "r73a53fcfa7q5u2yrouy2pzonduxew2kesq2kgsppuggxijbdoha.b32.i2p:0"
  },
  {
    "addrbind": "vrtm43hleoh5uwesw4a4nakxqnjmdahqlnnwnrw4sn6ddtl7yhxq.b32.i2p:0"
  },
  {
    "addrbind": "rkteucyzgfnz73jc7jwflyujx5whgat4yc6p6y45yykcgy3334sq.b32.i2p:0"
  },
  {
    "addrbind": "mpd2uks4vtxlumecg4vrvam77wtf5gx34svgdmnru3u6bnwozntq.b32.i2p:0"
  }
]

Migrating legacy wallets to descriptor wallets

Note: The first time I tried to do these tests, I walked away from my computer for about 1.5 days after doing the wallet migration, but before verifying the new descriptors. During that time, my node stopped because my computer ran out of disk space. When I came back I had to reload the legacy wallet before I could view the descriptors. Because of this, I decided to run these tests twice.

solvable: anything we have (public) keys for and know how to spend

Test Results #1

Checking getaddressinfo before the migration:

wallet getaddressinfo $legacy
{
  "address": "1BZwUQ7zLZkfS8CPUWfM5UikL17cvksRRd",
  "scriptPubKey": "76a91473ec0a3557513562d0d03e6d5360a17c7992af2388ac",
  "ismine": true,
  "solvable": true,
  "desc": "pkh([232fe3d1/0'/0'/0']03edd5022971cc53f8c61b2a524a4562a89615c80422d9878218efd0d8772bab11)#kpradp2r",
  "iswatchonly": false,
  "isscript": false,
  "iswitness": false,
  "pubkey": "03edd5022971cc53f8c61b2a524a4562a89615c80422d9878218efd0d8772bab11",
  "iscompressed": true,
  "ischange": false,
  "timestamp": 1664415031,
  "hdkeypath": "m/0'/0'/0'",
  "hdseedid": "87abba25164f7bf0e8a99eb5f1513d69bfc3612c",
  "hdmasterfingerprint": "232fe3d1",
  "labels": [
    "my-P2PKH"
  ]
}

✔️ isMine = true, solvable = true, iswatchonly = false, labels = my-P2PKH

wallet getaddressinfo $p2sh_segwit
{
  "address": "3FQMBkphtNXt5FqnHePoPDm6tQtwkpfT3C",
  "scriptPubKey": "a914966ac4db30b5adf0520a09c5aab16d4dab48926f87",
  "ismine": true,
  "solvable": true,
  "desc": "sh(wpkh([232fe3d1/0'/0'/1']039b58a1c0020caed22a04aaaa7bd976830cf9746a3167eaa7786dc391731ebe1c))#gzpgpzpd",
  "iswatchonly": false,
  "isscript": true,
  "iswitness": false,
  "script": "witness_v0_keyhash",
  "hex": "00141f035de8556eeb2cbe05c70e036a944da6abe7fd",
  "pubkey": "039b58a1c0020caed22a04aaaa7bd976830cf9746a3167eaa7786dc391731ebe1c",
  "embedded": {
    "isscript": false,
    "iswitness": true,
    "witness_version": 0,
    "witness_program": "1f035de8556eeb2cbe05c70e036a944da6abe7fd",
    "pubkey": "039b58a1c0020caed22a04aaaa7bd976830cf9746a3167eaa7786dc391731ebe1c",
    "address": "bc1qrup4m6z4dm4je0s9cu8qx655fkn2helay2f7ag",
    "scriptPubKey": "00141f035de8556eeb2cbe05c70e036a944da6abe7fd"
  },
  "ischange": false,
  "timestamp": 1664415031,
  "hdkeypath": "m/0'/0'/1'",
  "hdseedid": "87abba25164f7bf0e8a99eb5f1513d69bfc3612c",
  "hdmasterfingerprint": "232fe3d1",
  "labels": [
    "my-P2SH(P2WPKH)"
  ]
}

✔️ isMine = true, solvable = true, iswatchonly = false, labels = my-P2SH(P2WPKH)

wallet getaddressinfo $bech32
{
  "address": "bc1qcx5udjh803fzm7jt5e3lj03qu9chzrrdxjq92k",
  "scriptPubKey": "0014c1a9c6cae77c522dfa4ba663f93e20e171710c6d",
  "ismine": true,
  "solvable": true,
  "desc": "wpkh([232fe3d1/0'/0'/2']0294b216f1a20fe6d3f50726efaf1bc57e144c710e88a06b988da435dc2dfabd69)#46774kk8",
  "iswatchonly": false,
  "isscript": false,
  "iswitness": true,
  "witness_version": 0,
  "witness_program": "c1a9c6cae77c522dfa4ba663f93e20e171710c6d",
  "pubkey": "0294b216f1a20fe6d3f50726efaf1bc57e144c710e88a06b988da435dc2dfabd69",
  "ischange": false,
  "timestamp": 1664415031,
  "hdkeypath": "m/0'/0'/2'",
  "hdseedid": "87abba25164f7bf0e8a99eb5f1513d69bfc3612c",
  "hdmasterfingerprint": "232fe3d1",
  "labels": [
    "my-P2WPKH"
  ]
}

✔️ isMine = true, solvable = true, iswatchonly = false, labels = my-P2WPKH

wallet getaddressinfo $non_HD_address
{
  "address": "bc1qthfgts22xtrdq3jxt3qklhuvn0ylururasqtl2",
  "scriptPubKey": "00145dd285c14a32c6d046465c416fdf8c9bc9fe0f83",
  "ismine": true,
  "solvable": true,
  "desc": "wpkh([5dd285c1]03b205877eb552f17aa9fcac57935ac258b6b5b69d401303618756dc8859c48d49)#62xwkvj0",
  "iswatchonly": false,
  "isscript": false,
  "iswitness": true,
  "witness_version": 0,
  "witness_program": "5dd285c14a32c6d046465c416fdf8c9bc9fe0f83",
  "pubkey": "03b205877eb552f17aa9fcac57935ac258b6b5b69d401303618756dc8859c48d49",
  "ischange": false,
  "timestamp": 1,
  "labels": [
    "non-HD"
  ]
}

✔️ isMine = true because the non_hd_key was imported into the wallet, solvable = true, iswatchonly = false, labels = non-HD

wallet getaddressinfo $watch_address
{
  "address": "bc1q5kynasa6xppczjp9y94gmwdtcse2u75zrzu8fe",
  "scriptPubKey": "0014a5893ec3ba3043814825216a8db9abc432ae7a82",
  "ismine": false,
  "solvable": false,
  "iswatchonly": true,
  "isscript": false,
  "iswitness": true,
  "witness_version": 0,
  "witness_program": "a5893ec3ba3043814825216a8db9abc432ae7a82",
  "ischange": false,
  "timestamp": 1,
  "labels": [
    "watch-me"
  ]
}

✔️ isMine = false, solvable = false because we don't have the key(s) for this imported watch address, iswatchonly = true, labels = watch-me

wallet getaddressinfo $multisig_address
{
  "address": "bc1q78zmnc4cgurv2vkmk8ea0rd4mpntj6kwmxgana0jaa7g9hvme40saqxm87",
  "scriptPubKey": "0020f1c5b9e2b84706c532dbb1f3d78db5d866b96aced991d9f5f2ef7c82dd9bcd5f",
  "ismine": false,
  "solvable": true,
  "desc": "wsh(multi(1,[232fe3d1/0'/0'/3']03295669b44d7b94f505237d6d82e0187a57c9a2f69a72eaf8a4329a9f1437b205,02f9703ff1c034ffd94be97dc6aa23bbda265ad7ddc5a068090bfe1f32bfcbe416))#x8v4az6a",
  "iswatchonly": false,
  "isscript": true,
  "iswitness": true,
  "witness_version": 0,
  "witness_program": "f1c5b9e2b84706c532dbb1f3d78db5d866b96aced991d9f5f2ef7c82dd9bcd5f",
  "script": "multisig",
  "hex": "512103295669b44d7b94f505237d6d82e0187a57c9a2f69a72eaf8a4329a9f1437b2052102f9703ff1c034ffd94be97dc6aa23bbda265ad7ddc5a068090bfe1f32bfcbe41652ae",
  "sigsrequired": 1,
  "pubkeys": [
    "03295669b44d7b94f505237d6d82e0187a57c9a2f69a72eaf8a4329a9f1437b205",
    "02f9703ff1c034ffd94be97dc6aa23bbda265ad7ddc5a068090bfe1f32bfcbe416"
  ],
  "ischange": false,
  "labels": [
    "multisig"
  ]
}

✔️ isMine = false, solvable = true, iswatchonly = false, labels = multisig

Migration

wallet migratewallet
{
  "wallet_name": "legacy",
  "watchonly_name": "legacy_watchonly",
  "solvables_name": "legacy_solvables",
  "backup_path": "/tmp/24-rc-test/legacy/legacy-1664417457.legacy.bak"
}

✔️ Migration had no errors and was a success

⚠️ This was when I stepped away from my computer for about a day and a half. When I got back, my node had shut down because my laptop was out of disk space. I restarted it in pruning mode. When I came back, I had to reload my legacy wallet before I could view the descriptors.

Verifying the new descriptors

cli -rpcwallet=legacy listdescriptors

{
  "wallet_name": "legacy",
  "descriptors": [
    {
      "desc": "combo([2c61c3bf]02380e1270bd89ceaffd929f37e5bb1ce26247997242d2b2c77f89dd2f88ffb9ea)#m9jxgph2",
      "timestamp": 1664415031,
      "active": false
    },
    {
      "desc": "combo([5dd285c1]03b205877eb552f17aa9fcac57935ac258b6b5b69d401303618756dc8859c48d49)#cd7kpxff",
      "timestamp": 1,
      "active": false
    },
    {
      "desc": "combo(xpub661MyMwAqRbcEi9K2dYF9BK9KyDVbV856n2k8izEzMxjeWKAwMywgwkedME6iHr7QjAQL6M5ugFhsGmETGrVbi7cNwdFUAC4MTCQ2rNTd6h/0'/0'/*')#qvnqd82f",
      "timestamp": 0,
      "active": false,
      "range": [
        0,
        1003
      ],
      "next": 0
    },
    {
      "desc": "combo(xpub661MyMwAqRbcEi9K2dYF9BK9KyDVbV856n2k8izEzMxjeWKAwMywgwkedME6iHr7QjAQL6M5ugFhsGmETGrVbi7cNwdFUAC4MTCQ2rNTd6h/0'/1'/*')#s2e3ahls",
      "timestamp": 0,
      "active": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "pkh([232fe3d1/44'/0'/0']xpub6CUaL1ESk2hCz3BZom717y3aA8CLNEoYA4vcToY6fJHkCDXLJzbJA5NwPZjCQEjL2g6jLKUJojKgtjpLhD6NqSFHnGJ5DdgMBMRf7TC2PaG/0/*)#2xyeklcl",
      "timestamp": 1664417581,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "pkh([232fe3d1/44'/0'/0']xpub6CUaL1ESk2hCz3BZom717y3aA8CLNEoYA4vcToY6fJHkCDXLJzbJA5NwPZjCQEjL2g6jLKUJojKgtjpLhD6NqSFHnGJ5DdgMBMRf7TC2PaG/1/*)#mjpct2g8",
      "timestamp": 1664417582,
      "active": true,
      "internal": true,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "sh(wpkh([232fe3d1/49'/0'/0']xpub6CohGCzo7oM9rbkCwWCZuTVsaYeBrQnU6z8WPvqF4Kuz948gwMgamNyAdK3RUhHSDMNYaac6unZuS4tB5LzecnYpYtrJTX7UxZ34sHagzAQ/0/*))#9998le9p",
      "timestamp": 1664417581,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "sh(wpkh([232fe3d1/49'/0'/0']xpub6CohGCzo7oM9rbkCwWCZuTVsaYeBrQnU6z8WPvqF4Kuz948gwMgamNyAdK3RUhHSDMNYaac6unZuS4tB5LzecnYpYtrJTX7UxZ34sHagzAQ/1/*))#syt38xs7",
      "timestamp": 1664417582,
      "active": true,
      "internal": true,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "tr([232fe3d1/86'/0'/0']xpub6DUwXqs7MQsBxcZ3974ZVT5YF64yQGqgs4ztVJKvce7T8GzkDBqULu2cqPkpRP1gNsitpyoFznXTQFz3oP4mjY4tMKmsYTaw7V2232qwPoQ/0/*)#n6r4q5pa",
      "timestamp": 1664417582,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "tr([232fe3d1/86'/0'/0']xpub6DUwXqs7MQsBxcZ3974ZVT5YF64yQGqgs4ztVJKvce7T8GzkDBqULu2cqPkpRP1gNsitpyoFznXTQFz3oP4mjY4tMKmsYTaw7V2232qwPoQ/1/*)#zwx5ap39",
      "timestamp": 1664417582,
      "active": true,
      "internal": true,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "wpkh([232fe3d1/84'/0'/0']xpub6BhhETR6yf7cmTBQXB29NeFsBEdTcVNeJSG4uDJoZD6i5G9MvxyF6Saq71Nr9FR5rcdmT3PHmWSn5DmGjJb6rYvmWDazK5YQ6xDYrBGfkmk/0/*)#us5qy5yp",
      "timestamp": 1664417581,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "wpkh([232fe3d1/84'/0'/0']xpub6BhhETR6yf7cmTBQXB29NeFsBEdTcVNeJSG4uDJoZD6i5G9MvxyF6Saq71Nr9FR5rcdmT3PHmWSn5DmGjJb6rYvmWDazK5YQ6xDYrBGfkmk/1/*)#dy3pep5e",
      "timestamp": 1664417582,
      "active": true,
      "internal": true,
      "range": [
        0,
        999
      ],
      "next": 0
    }
  ]
}

✔️ 2 descriptors per script type (pkh, sh(wpkh), tr, wpkh), accounting for 8 of the descriptors

✔️ 1 range combo descriptor for external addresses: combo(<xpub>/0'/0'/*')#qvnqd82f

✔️ 1 range combo descriptor for internal addresses: combo(<xpub>/0'/1'/*')#s2e3ahls

✔️ 1 combo descriptor for the HD seed

✔️ 1 combo descriptor for the non-HD seed (non_hd_key that was imported with wallet importprivkey $non_HD_key "non-HD")

cli -rpcwallet=legacy_watchonly listdescriptors
{
  "wallet_name": "legacy_watchonly",
  "descriptors": [
    {
      "desc": "addr(bc1q5kynasa6xppczjp9y94gmwdtcse2u75zrzu8fe)#auskal8c",
      "timestamp": 1,
      "active": false
    }
  ]
}

✔️ 1 descriptor for the legacy_watchonly wallet, confirmed that the watch_address belongs to this wallet

cli -rpcwallet=legacy_solvables listdescriptors
{
  "wallet_name": "legacy_solvables",
  "descriptors": [
    {
      "desc": "sh(multi(1,[232fe3d1/0'/0'/3']03295669b44d7b94f505237d6d82e0187a57c9a2f69a72eaf8a4329a9f1437b205,02f9703ff1c034ffd94be97dc6aa23bbda265ad7ddc5a068090bfe1f32bfcbe416))#5da89v03",
      "timestamp": 0,
      "active": false
    },
    {
      "desc": "sh(wsh(multi(1,[232fe3d1/0'/0'/3']03295669b44d7b94f505237d6d82e0187a57c9a2f69a72eaf8a4329a9f1437b205,02f9703ff1c034ffd94be97dc6aa23bbda265ad7ddc5a068090bfe1f32bfcbe416)))#vvp4seqa",
      "timestamp": 0,
      "active": false
    },
    {
      "desc": "wsh(multi(1,[232fe3d1/0'/0'/3']03295669b44d7b94f505237d6d82e0187a57c9a2f69a72eaf8a4329a9f1437b205,02f9703ff1c034ffd94be97dc6aa23bbda265ad7ddc5a068090bfe1f32bfcbe416))#x8v4az6a",
      "timestamp": 0,
      "active": false
    }
  ]
}

✔️ 3 descriptors for the legacy_solvables wallet, and can observe that the multisig_address belongs to this wallet (particularly since only one multisig address was created)

Test Results #2

Checking getaddressinfo before the migration:

wallet getaddressinfo $legacy
{
  "address": "1JAzueKR4QT1NT3Ty6ujFxdQebaTT6SgJu",
  "scriptPubKey": "76a914bc5e38897e19f550c4140c324de2e1bd24928eb088ac",
  "ismine": true,
  "solvable": true,
  "desc": "pkh([545678fa/0'/0'/0']02a1edc3697ecaac894d34cb3f57782e71891f1d3158b748aa8aab79b12f41fe11)#0kjh4feg",
  "iswatchonly": false,
  "isscript": false,
  "iswitness": false,
  "pubkey": "02a1edc3697ecaac894d34cb3f57782e71891f1d3158b748aa8aab79b12f41fe11",
  "iscompressed": true,
  "ischange": false,
  "timestamp": 1664553607,
  "hdkeypath": "m/0'/0'/0'",
  "hdseedid": "761c55cf5d365f4b8cd5ac672005ba4d8153b226",
  "hdmasterfingerprint": "545678fa",
  "labels": [
    "my-P2PKH"
  ]
}

✔️ isMine = true, solvable = true, iswatchonly = false, labels = my-P2PKH

wallet getaddressinfo $p2sh_segwit
{
  "address": "3LBSxyPKYggChXZ8SrTsGnSSuFQsdSSR3G",
  "scriptPubKey": "a914cad2d0a084de542bbca572801bb4d441380bdb1287",
  "ismine": true,
  "solvable": true,
  "desc": "sh(wpkh([545678fa/0'/0'/1']027be133bd319016c7b28f97cdf3f88a1317dd91110876b901319cebc4cc8fe7f9))#pc8s5ltu",
  "iswatchonly": false,
  "isscript": true,
  "iswitness": false,
  "script": "witness_v0_keyhash",
  "hex": "0014485b007d67f7a620669d00a439264ba3a4f1396b",
  "pubkey": "027be133bd319016c7b28f97cdf3f88a1317dd91110876b901319cebc4cc8fe7f9",
  "embedded": {
    "isscript": false,
    "iswitness": true,
    "witness_version": 0,
    "witness_program": "485b007d67f7a620669d00a439264ba3a4f1396b",
    "pubkey": "027be133bd319016c7b28f97cdf3f88a1317dd91110876b901319cebc4cc8fe7f9",
    "address": "bc1qfpdsqlt877nzqe5aqzjrjfjt5wj0zwttalkurw",
    "scriptPubKey": "0014485b007d67f7a620669d00a439264ba3a4f1396b"
  },
  "ischange": false,
  "timestamp": 1664553607,
  "hdkeypath": "m/0'/0'/1'",
  "hdseedid": "761c55cf5d365f4b8cd5ac672005ba4d8153b226",
  "hdmasterfingerprint": "545678fa",
  "labels": [
    "my-P2SH(P2WPKH)"
  ]
}

✔️ isMine = true, solvable = true, iswatchonly = false, labels = my-P2SH(P2WPKH)

wallet getaddressinfo $bech32
{
  "address": "bc1qg888qwp9l4n33a8nf8qa24ny28cnjvlk6ck5xp",
  "scriptPubKey": "001441ce703825fd6718f4f349c1d5566451f13933f6",
  "ismine": true,
  "solvable": true,
  "desc": "wpkh([545678fa/0'/0'/2']02d7d790612e9d07ded47dc5b76f2c588332c89051aeb263d2074e4eb240ced92e)#ysauz2mn",
  "iswatchonly": false,
  "isscript": false,
  "iswitness": true,
  "witness_version": 0,
  "witness_program": "41ce703825fd6718f4f349c1d5566451f13933f6",
  "pubkey": "02d7d790612e9d07ded47dc5b76f2c588332c89051aeb263d2074e4eb240ced92e",
  "ischange": false,
  "timestamp": 1664553607,
  "hdkeypath": "m/0'/0'/2'",
  "hdseedid": "761c55cf5d365f4b8cd5ac672005ba4d8153b226",
  "hdmasterfingerprint": "545678fa",
  "labels": [
    "my-P2WPKH"
  ]
}

✔️ isMine = true, solvable = true, iswatchonly = false, labels = my-P2WPKH

wallet getaddressinfo $non_HD_address
{
  "address": "bc1q7cxjsqm90k8yl7an7qnrp9wsq662hsuu3uc5f6",
  "scriptPubKey": "0014f60d2803657d8e4ffbb3f0263095d006b4abc39c",
  "ismine": true,
  "solvable": true,
  "desc": "wpkh([f60d2803]0394c4f0dfd1969a32a48341137e971cfe02ca24839ee41da77db6da86ee119567)#j256y6kx",
  "iswatchonly": false,
  "isscript": false,
  "iswitness": true,
  "witness_version": 0,
  "witness_program": "f60d2803657d8e4ffbb3f0263095d006b4abc39c",
  "pubkey": "0394c4f0dfd1969a32a48341137e971cfe02ca24839ee41da77db6da86ee119567",
  "ischange": false,
  "timestamp": 1,
  "labels": [
    "non-HD"
  ]
}

✔️ isMine = true because non_hd_key was imported into the wallet, solvable = true, iswatchonly = false, labels = non-HD

wallet getaddressinfo $watch_address
{
  "address": "bc1qmklnrfwq0l4wa2tz95hy5cp3vkuetuvv9zt2th",
  "scriptPubKey": "0014ddbf31a5c07feaeea9622d2e4a603165b995f18c",
  "ismine": false,
  "solvable": false,
  "iswatchonly": true,
  "isscript": false,
  "iswitness": true,
  "witness_version": 0,
  "witness_program": "ddbf31a5c07feaeea9622d2e4a603165b995f18c",
  "ischange": false,
  "timestamp": 1,
  "labels": [
    "watch-me"
  ]
}

✔️ isMine = false, solvable = false because we don't have the key(s) for this imported watch address, iswatchonly = true, labels = watch-me

wallet getaddressinfo $multisig_address
{
  "address": "bc1q4nqu6eyas99n5qrsgycd9h2xmm9ukn9pf76arr4xu5hv3n6tu7gqmr2c25",
  "scriptPubKey": "0020acc1cd649d814b3a00704130d2dd46decbcb4ca14fb5d18ea6e52ec8cf4be790",
  "ismine": false,
  "solvable": true,
  "desc": "wsh(multi(1,[545678fa/0'/0'/3']0233e5074525a884848a78ec777563f75c6d3c73f0de4700ef28a58130fa8717a0,02d2ab79584ab88de93e2dcd9e5df9e328a90d702a833c21fa6d00df6d60250b76))#0fqjv0ut",
  "iswatchonly": false,
  "isscript": true,
  "iswitness": true,
  "witness_version": 0,
  "witness_program": "acc1cd649d814b3a00704130d2dd46decbcb4ca14fb5d18ea6e52ec8cf4be790",
  "script": "multisig",
  "hex": "51210233e5074525a884848a78ec777563f75c6d3c73f0de4700ef28a58130fa8717a02102d2ab79584ab88de93e2dcd9e5df9e328a90d702a833c21fa6d00df6d60250b7652ae",
  "sigsrequired": 1,
  "pubkeys": [
    "0233e5074525a884848a78ec777563f75c6d3c73f0de4700ef28a58130fa8717a0",
    "02d2ab79584ab88de93e2dcd9e5df9e328a90d702a833c21fa6d00df6d60250b76"
  ],
  "ischange": false,
  "labels": [
    "multisig"
  ]
}

✔️ isMine = false, solvable = true, iswatchonly = false, labels = multisig

Migration

wallet migratewallet
{
  "wallet_name": "legacy",
  "watchonly_name": "legacy_watchonly",
  "solvables_name": "legacy_solvables",
  "backup_path": "/tmp/24-rc-test/legacy/legacy-1664554145.legacy.bak"
}

✔️ Migration had no errors and was a success

Verifying the new descriptors

cli -rpcwallet=legacy listdescriptors
{
  "wallet_name": "legacy",
  "descriptors": [
    {
      "desc": "combo([26b25381]0345ab28f3f1cae4b1e759d123b4280ef8892cb5f8c8fce55e2474712e67624677)#dp5tmf38",
      "timestamp": 1664553607,
      "active": false
    },
    {
      "desc": "combo([f60d2803]0394c4f0dfd1969a32a48341137e971cfe02ca24839ee41da77db6da86ee119567)#vqhrc52r",
      "timestamp": 1,
      "active": false
    },
    {
      "desc": "combo(xpub661MyMwAqRbcGpGEbbHPNRszUZ3CBSXA43y7awB8YmjjrxkMb8MyoNanQ4Ng7TT1P2KdfNFREzD6SgdTmMqig4oCQP78yxHQt6AjrNrCHSk/0'/0'/*')#urz4y4lm",
      "timestamp": 0,
      "active": false,
      "range": [
        0,
        1003
      ],
      "next": 0
    },
    {
      "desc": "combo(xpub661MyMwAqRbcGpGEbbHPNRszUZ3CBSXA43y7awB8YmjjrxkMb8MyoNanQ4Ng7TT1P2KdfNFREzD6SgdTmMqig4oCQP78yxHQt6AjrNrCHSk/0'/1'/*')#v9gy592z",
      "timestamp": 0,
      "active": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "pkh([545678fa/44'/0'/0']xpub6CqzPbe121RueGfiKQdmWuB4JevSodL9hAb1sUjTweQXh475R5u4zXPGBJDvG7ZWgf5aBFSZoxFgq3x2CmfNLM751MQpmFUHdy59zmUrsWE/0/*)#4zgx0yg6",
      "timestamp": 1664554248,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "pkh([545678fa/44'/0'/0']xpub6CqzPbe121RueGfiKQdmWuB4JevSodL9hAb1sUjTweQXh475R5u4zXPGBJDvG7ZWgf5aBFSZoxFgq3x2CmfNLM751MQpmFUHdy59zmUrsWE/1/*)#ykd8j3cz",
      "timestamp": 1664554248,
      "active": true,
      "internal": true,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "sh(wpkh([545678fa/49'/0'/0']xpub6CYRgHznr5UpX94vbCuJA82WvGu6CYAHxYcMMnQxPBWyt6cq89RSYjX6cm9ecfG2CYEu2UV47aqMWK2qK3LqKBZdtvaTqWBQuAuwafi7jk8/0/*))#c8jqdjjs",
      "timestamp": 1664554248,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "sh(wpkh([545678fa/49'/0'/0']xpub6CYRgHznr5UpX94vbCuJA82WvGu6CYAHxYcMMnQxPBWyt6cq89RSYjX6cm9ecfG2CYEu2UV47aqMWK2qK3LqKBZdtvaTqWBQuAuwafi7jk8/1/*))#dxuk4d80",
      "timestamp": 1664554248,
      "active": true,
      "internal": true,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "tr([545678fa/86'/0'/0']xpub6BjRKJByjsCP7AZPqRE1z5bG3EuUE6evxrX42rQeeDYLtzXo1tgckFSoyJXBN65axMEFNTz5mu2xwnPdaZD4PwmAd5S3zmez3BJrbrET7gJ/0/*)#aq7rh2cg",
      "timestamp": 1664554248,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "tr([545678fa/86'/0'/0']xpub6BjRKJByjsCP7AZPqRE1z5bG3EuUE6evxrX42rQeeDYLtzXo1tgckFSoyJXBN65axMEFNTz5mu2xwnPdaZD4PwmAd5S3zmez3BJrbrET7gJ/1/*)#v5mz2lgs",
      "timestamp": 1664554249,
      "active": true,
      "internal": true,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "wpkh([545678fa/84'/0'/0']xpub6CyWSPip8qgR255UdKjDshuBxxBxYpnohyPovmbg7cZ3P3tvRx1mMZ9Kes7fwr2T5nCSVsehiwzyhxWGEEktzQipfZ1LeA117vTRz1m9qVn/0/*)#j3pu3kge",
      "timestamp": 1664554248,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "wpkh([545678fa/84'/0'/0']xpub6CyWSPip8qgR255UdKjDshuBxxBxYpnohyPovmbg7cZ3P3tvRx1mMZ9Kes7fwr2T5nCSVsehiwzyhxWGEEktzQipfZ1LeA117vTRz1m9qVn/1/*)#r9yavrcp",
      "timestamp": 1664554248,
      "active": true,
      "internal": true,
      "range": [
        0,
        999
      ],
      "next": 0
    }
  ]
}

✔️ 2 descriptors per script type (pkh, sh(wpkh), tr, wpkh), accounting for 8 of the descriptors

✔️ range combo descriptor for external addresses: combo(<xpub>/0'/0'/*')#urz4y4lm

✔️ range combo descriptor for internal addresses: combo(<xpub>/0'/1'/*')#v9gy592z

✔️ 1 combo descriptor for the HD seed

✔️ 1 combo descriptor for the non-HD seed (non_hd_key that was imported with wallet importprivkey $non_HD_key "non-HD")

cli -rpcwallet=legacy_watchonly listdescriptors
{
  "wallet_name": "legacy_watchonly",
  "descriptors": [
    {
      "desc": "addr(bc1qmklnrfwq0l4wa2tz95hy5cp3vkuetuvv9zt2th)#v2et9v4g",
      "timestamp": 1,
      "active": false
    }
  ]
}

✔️ 1 descriptor for the legacy_watchonly wallet, confirmed that the watch_address belongs to this wallet

cli -rpcwallet=legacy_solvables listdescriptors
{
  "wallet_name": "legacy_solvables",
  "descriptors": [
    {
      "desc": "sh(multi(1,[545678fa/0'/0'/3']0233e5074525a884848a78ec777563f75c6d3c73f0de4700ef28a58130fa8717a0,02d2ab79584ab88de93e2dcd9e5df9e328a90d702a833c21fa6d00df6d60250b76))#ap4wadcm",
      "timestamp": 0,
      "active": false
    },
    {
      "desc": "sh(wsh(multi(1,[545678fa/0'/0'/3']0233e5074525a884848a78ec777563f75c6d3c73f0de4700ef28a58130fa8717a0,02d2ab79584ab88de93e2dcd9e5df9e328a90d702a833c21fa6d00df6d60250b76)))#6t2p4qpw",
      "timestamp": 0,
      "active": false
    },
    {
      "desc": "wsh(multi(1,[545678fa/0'/0'/3']0233e5074525a884848a78ec777563f75c6d3c73f0de4700ef28a58130fa8717a0,02d2ab79584ab88de93e2dcd9e5df9e328a90d702a833c21fa6d00df6d60250b76))#0fqjv0ut",
      "timestamp": 0,
      "active": false
    }
  ]
}

✔️ 3 descriptors for the legacy_solvables wallet, and can observe that the multisig_address belongs to this wallet (particularly since only one multisig address was created)

GUI: Testing the restore wallet option

Test Results
  1. Move the wallet backup created during the wallet migration to a different directory:
cp legacy-1664417457.legacy.bak ~/Desktop
mv ~/Desktop/legacy-1664417457.legacy.bak ~/Desktop/legacy-wallet-backup.dat
  1. Stop the node and recreate the data directory (cli stop and rm -r $DATA_DIR && mkdir $DATA_DIR)

  2. start qt (qt)

✔️ Wallet restotation in the GUI succeeds

✔️ Also tested not wiping $DATA_DIR before restortation. Restored the wallet as a different name, and this also succeeds.

⚠️ Note: earlier I had an issue where I restarted my node in pruned mode and that caused all kinds of problems, including wallet restoration crashing (even when I launched qt with -reindex). I think it's expected to have unstable behavior during the reindex, but I do plan to report this.

Testing the unification of settings between bitcoind and the GUI

Pruning settings test
  1. Create a bitcoin.conf file and add prune=550 (touch /tmp/24-rc-test/bitcoin.conf && echo "prune=550" > /tmp/24-rc-test/bitcoin.conf)
  2. Start bitcoind (bitcoind -daemon)
  3. Use cli getblockchaininfo to verify that pruning is turned on:
cli getblockchaininfo
{
  "chain": "main",
  "blocks": 0,
  "headers": 0,
  "bestblockhash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
  "difficulty": 1,
  "time": 1231006505,
  "mediantime": 1231006505,
  "verificationprogress": 1.3012604677626e-09,
  "initialblockdownload": true,
  "chainwork": "0000000000000000000000000000000000000000000000000000000100010001",
  "size_on_disk": 293,
  "pruned": true,
  "pruneheight": 0,
  "automatic_pruning": true,
  "prune_target_size": 576716800,
  "warnings": ""
}
  1. Stop (cli stop) and start qt (qt)
  2. Use the GUI to disable pruning (Settings > Options > Uncheck "Prune block storage to")
  3. Close the GUI, restart bitcoind (bitcoind -daemon)
  4. Use cli getblockchaininfo to check that pruning is no longer turned on:
cli getblockchaininfo
{
  "chain": "main",
  "blocks": 0,
  "headers": 348041,
  "bestblockhash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
  "difficulty": 1,
  "time": 1231006505,
  "mediantime": 1231006505,
  "verificationprogress": 1.301259541327865e-09,
  "initialblockdownload": true,
  "chainwork": "0000000000000000000000000000000000000000000000000000000100010001",
  "size_on_disk": 293,
  "pruned": false,
  "warnings": ""
}
  1. Spot check settings.json
cat /tmp/24-rc-test/settings.json 
{
  "prune": "0"
}

cat /tmp/24-rc-test/bitcoin.conf 
prune=550

✔️

Spending of unconfirmed change test

Network: signet (bitcoind -daemon -testnet)

  1. Start the GUI in signet mode (qt -signet)

  2. In the settings menu, disable spending unconfirmed change, enable coin control. Restart the client to apply the changes.

  3. Create a wallet and receive some funds from a signet faucet

  4. Create another receive address (can label it something like "send to myself"). Copy it.

  5. Once the transaction confirms and the node is synced, create a transaction and select the newly received coin as input. Send it to the receive address created in the previous step. Make sure the send amount is smaller than the input so that some change is created.

  6. Observe that the transaction is pending and that the balance is pending:

alt text alt text

  1. Try to spend the unconfirmed change output and observe that it's not available for selection:

alt text

  1. Verify that unconfirmed change is also unspendable with bitcoind:
cli -signet stop
bitcoind -signet -daemon
cli -signet getbalance
0.00000000
  1. Use the GUI to re-enable spending unconfirmed change. Verify that the balance now reflects the unconfirmed change:
cli -signet stop
qt -signet

alt text

  1. Check bitcoind to make sure that the setting change persisted and that the balance now reflects the unconfirmed change:
bitcoind -signet -daemon

cli -signet getbalance
0.00009859

✔️

Testing watch-only support for miniscript descriptors

Test Results

Network: signet (bitcoind -daemon -signet)

  1. Create descriptor wallet with private keys disabled:
cli -signet -named createwallet wallet_name=miniscript_wo disable_private_keys=true
{
  "name": "miniscript_wo",
  "warning": ""
}
  1. Create the descriptor in miniscript.fun and assign it to the 'descriptor' variable: descriptor="wsh(and_v(v:multi(2,[67e54752]tpubD6NzVbkrYhZ4YRJ9MTbmErYTvHdyph7n12fQvuBTozwGQC2LtT8aKbLGMs2jWC11Uj7dXsScu6bDyLdNPLFumAENDNDnaXA3p679HVimacv/0/*,[a9e03770]tpubD6NzVbkrYhZ4Ygoy6im7VLabzegPPSHVD4bY2q3jNkZumP48sK6EZoWuSwAEh4AsimdSXrrjxpuEWSD3k5P4WPcBVWJEVBuuCmMckhd5MbH/0/*,[c893176c]tpubD6NzVbkrYhZ4X1sRGHagnTgQxogHZciMGpPNYnpsdjTzGsMNx58nahwuQ3X2BhUAg4qkZjGDzm5vmXTKu27M7qp2imhxGh337y7BgpLyagM/0/*),after(21)))#pwx7gafs"

  2. Import the miniscript descriptor:

cli -signet importdescriptors '''[{"desc": "'$descriptor'", "active": true, "timestamp": "now"}]'''
[
  {
    "success": true,
    "warnings": [
      "Range not given, using default keypool range"
    ]
  }
]
  1. Derive a new address now that the descriptor has been imported to the wallet: watch_address=$(cli -signet getnewaddress)

  2. Use the signet faucet to send coins to the watch_address.

  3. Verify the wallet detected the transaction:

 cli -signet listtransactions
[
  {
    "address": "tb1qvrjw2xx8a8f3e5wtwl0nd50z60wlrta0wrghy8cu9f8d3f6cws2s605y82",
    "parent_descs": [
      "wsh(and_v(v:multi(2,[67e54752]tpubD6NzVbkrYhZ4YRJ9MTbmErYTvHdyph7n12fQvuBTozwGQC2LtT8aKbLGMs2jWC11Uj7dXsScu6bDyLdNPLFumAENDNDnaXA3p679HVimacv/0/*,[a9e03770]tpubD6NzVbkrYhZ4Ygoy6im7VLabzegPPSHVD4bY2q3jNkZumP48sK6EZoWuSwAEh4AsimdSXrrjxpuEWSD3k5P4WPcBVWJEVBuuCmMckhd5MbH/0/*,[c893176c]tpubD6NzVbkrYhZ4X1sRGHagnTgQxogHZciMGpPNYnpsdjTzGsMNx58nahwuQ3X2BhUAg4qkZjGDzm5vmXTKu27M7qp2imhxGh337y7BgpLyagM/0/*),after(21)))#pwx7gafs"
    ],
    "category": "receive",
    "amount": 0.00010000,
    "label": "",
    "vout": 0,
    "confirmations": 0,
    "trusted": false,
    "txid": "2dd6e54aac74333e26f3156eaefd71b546fe29a31b6d5b2d23dd55b059d12876",
    "wtxid": "177bc01de68ba0aa636b58c97ef7ba8b12f45d6af1001cf3f2a4bb6d3861a940",
    "walletconflicts": [
    ],
    "time": 1664560777,
    "timereceived": 1664560777,
    "bip125-replaceable": "no"
  }
]

Also verified that the parent_descs matches the descriptor imported earlier.