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
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)
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.
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"
}
]
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
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)
Test Results
- 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
-
Stop the node and recreate the data directory (
cli stop
andrm -r $DATA_DIR && mkdir $DATA_DIR
) -
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.
-reindex
). I think it's expected to have unstable behavior during the reindex, but I do plan to report this.
Pruning settings test
- 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
) - Start bitcoind (
bitcoind -daemon
) - 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": ""
}
- Stop (
cli stop
) and start qt (qt
) - Use the GUI to disable pruning (Settings > Options > Uncheck "Prune block storage to")
- Close the GUI, restart bitcoind (
bitcoind -daemon
) - 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": ""
}
- 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
)
-
Start the GUI in signet mode (
qt -signet
) -
In the settings menu, disable spending unconfirmed change, enable coin control. Restart the client to apply the changes.
-
Create a wallet and receive some funds from a signet faucet
-
Create another receive address (can label it something like "send to myself"). Copy it.
-
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.
-
Observe that the transaction is pending and that the balance is pending:
- Try to spend the unconfirmed change output and observe that it's not available for selection:
- Verify that unconfirmed change is also unspendable with bitcoind:
cli -signet stop
bitcoind -signet -daemon
cli -signet getbalance
0.00000000
- Use the GUI to re-enable spending unconfirmed change. Verify that the balance now reflects the unconfirmed change:
cli -signet stop
qt -signet
- 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
✔️
Test Results
Network: signet (bitcoind -daemon -signet
)
- Create descriptor wallet with private keys disabled:
cli -signet -named createwallet wallet_name=miniscript_wo disable_private_keys=true
{
"name": "miniscript_wo",
"warning": ""
}
-
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"
-
Import the miniscript descriptor:
cli -signet importdescriptors '''[{"desc": "'$descriptor'", "active": true, "timestamp": "now"}]'''
[
{
"success": true,
"warnings": [
"Range not given, using default keypool range"
]
}
]
-
Derive a new address now that the descriptor has been imported to the wallet:
watch_address=$(cli -signet getnewaddress)
-
Use the signet faucet to send coins to the watch_address.
-
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.