|
8 | 8 | from itertools import product
|
9 | 9 |
|
10 | 10 | from test_framework.authproxy import JSONRPCException
|
| 11 | +from test_framework.descriptors import descsum_create |
11 | 12 | from test_framework.test_framework import BitcoinTestFramework
|
12 | 13 | from test_framework.util import (
|
13 | 14 | assert_equal,
|
@@ -168,49 +169,91 @@ def run_test(self):
|
168 | 169 | self.nodes[1].createwallet(wallet_name="w1")
|
169 | 170 | w1 = self.nodes[1].get_wallet_rpc("w1")
|
170 | 171 | # w2 contains the private keys for w3
|
171 |
| - self.nodes[1].createwallet(wallet_name="w2") |
| 172 | + self.nodes[1].createwallet(wallet_name="w2", blank=True) |
172 | 173 | w2 = self.nodes[1].get_wallet_rpc("w2")
|
| 174 | + xpriv = "tprv8ZgxMBicQKsPfHCsTwkiM1KT56RXbGGTqvc2hgqzycpwbHqqpcajQeMRZoBD35kW4RtyCemu6j34Ku5DEspmgjKdt2qe4SvRch5Kk8B8A2v" |
| 175 | + xpub = "tpubD6NzVbkrYhZ4YkEfMbRJkQyZe7wTkbTNRECozCtJPtdLRn6cT1QKb8yHjwAPcAr26eHBFYs5iLiFFnCbwPRsncCKUKCfubHDMGKzMVcN1Jg" |
| 176 | + if self.options.descriptors: |
| 177 | + w2.importdescriptors([{ |
| 178 | + "desc": descsum_create("wpkh(" + xpriv + "/0/0/*)"), |
| 179 | + "timestamp": "now", |
| 180 | + "range": [0, 100], |
| 181 | + "active": True |
| 182 | + },{ |
| 183 | + "desc": descsum_create("wpkh(" + xpriv + "/0/1/*)"), |
| 184 | + "timestamp": "now", |
| 185 | + "range": [0, 100], |
| 186 | + "active": True, |
| 187 | + "internal": True |
| 188 | + }]) |
| 189 | + else: |
| 190 | + w2.sethdseed(True) |
| 191 | + |
173 | 192 | # w3 is a watch-only wallet, based on w2
|
174 | 193 | self.nodes[1].createwallet(wallet_name="w3", disable_private_keys=True)
|
175 | 194 | w3 = self.nodes[1].get_wallet_rpc("w3")
|
176 |
| - for _ in range(3): |
177 |
| - a2_receive = w2.getnewaddress() |
178 |
| - a2_change = w2.getrawchangeaddress() # doesn't actually use change derivation |
179 |
| - res = w3.importmulti([{ |
180 |
| - "desc": w2.getaddressinfo(a2_receive)["desc"], |
| 195 | + if self.options.descriptors: |
| 196 | + # Match the privkeys in w2 for descriptors |
| 197 | + res = w3.importdescriptors([{ |
| 198 | + "desc": descsum_create("wpkh(" + xpub + "/0/0/*)"), |
181 | 199 | "timestamp": "now",
|
| 200 | + "range": [0, 100], |
182 | 201 | "keypool": True,
|
| 202 | + "active": True, |
183 | 203 | "watchonly": True
|
184 | 204 | },{
|
185 |
| - "desc": w2.getaddressinfo(a2_change)["desc"], |
| 205 | + "desc": descsum_create("wpkh(" + xpub + "/0/1/*)"), |
186 | 206 | "timestamp": "now",
|
| 207 | + "range": [0, 100], |
187 | 208 | "keypool": True,
|
| 209 | + "active": True, |
188 | 210 | "internal": True,
|
189 | 211 | "watchonly": True
|
190 | 212 | }])
|
191 | 213 | assert_equal(res, [{"success": True}, {"success": True}])
|
192 | 214 |
|
193 |
| - w0.sendtoaddress(a2_receive, 10) # fund w3 |
194 |
| - self.nodes[0].generate(1) |
195 |
| - self.sync_blocks() |
196 |
| - |
197 |
| - # w4 has private keys enabled, but only contains watch-only keys (from w2) |
198 |
| - self.nodes[1].createwallet(wallet_name="w4", disable_private_keys=False) |
199 |
| - w4 = self.nodes[1].get_wallet_rpc("w4") |
200 | 215 | for _ in range(3):
|
201 | 216 | a2_receive = w2.getnewaddress()
|
202 |
| - res = w4.importmulti([{ |
203 |
| - "desc": w2.getaddressinfo(a2_receive)["desc"], |
204 |
| - "timestamp": "now", |
205 |
| - "keypool": False, |
206 |
| - "watchonly": True |
207 |
| - }]) |
208 |
| - assert_equal(res, [{"success": True}]) |
| 217 | + if not self.options.descriptors: |
| 218 | + # Because legacy wallets use exclusively hardened derivation, we can't do a ranged import like we do for descriptors |
| 219 | + a2_change = w2.getrawchangeaddress() # doesn't actually use change derivation |
| 220 | + res = w3.importmulti([{ |
| 221 | + "desc": w2.getaddressinfo(a2_receive)["desc"], |
| 222 | + "timestamp": "now", |
| 223 | + "keypool": True, |
| 224 | + "watchonly": True |
| 225 | + },{ |
| 226 | + "desc": w2.getaddressinfo(a2_change)["desc"], |
| 227 | + "timestamp": "now", |
| 228 | + "keypool": True, |
| 229 | + "internal": True, |
| 230 | + "watchonly": True |
| 231 | + }]) |
| 232 | + assert_equal(res, [{"success": True}, {"success": True}]) |
209 | 233 |
|
210 |
| - w0.sendtoaddress(a2_receive, 10) # fund w4 |
| 234 | + w0.sendtoaddress(a2_receive, 10) # fund w3 |
211 | 235 | self.nodes[0].generate(1)
|
212 | 236 | self.sync_blocks()
|
213 | 237 |
|
| 238 | + if not self.options.descriptors: |
| 239 | + # w4 has private keys enabled, but only contains watch-only keys (from w2) |
| 240 | + # This is legacy wallet behavior only as descriptor wallets don't allow watchonly and non-watchonly things in the same wallet. |
| 241 | + self.nodes[1].createwallet(wallet_name="w4", disable_private_keys=False) |
| 242 | + w4 = self.nodes[1].get_wallet_rpc("w4") |
| 243 | + for _ in range(3): |
| 244 | + a2_receive = w2.getnewaddress() |
| 245 | + res = w4.importmulti([{ |
| 246 | + "desc": w2.getaddressinfo(a2_receive)["desc"], |
| 247 | + "timestamp": "now", |
| 248 | + "keypool": False, |
| 249 | + "watchonly": True |
| 250 | + }]) |
| 251 | + assert_equal(res, [{"success": True}]) |
| 252 | + |
| 253 | + w0.sendtoaddress(a2_receive, 10) # fund w4 |
| 254 | + self.nodes[0].generate(1) |
| 255 | + self.sync_blocks() |
| 256 | + |
214 | 257 | self.log.info("Send to address...")
|
215 | 258 | self.test_send(from_wallet=w0, to_wallet=w1, amount=1)
|
216 | 259 | self.test_send(from_wallet=w0, to_wallet=w1, amount=1, add_to_wallet=True)
|
@@ -241,11 +284,15 @@ def run_test(self):
|
241 | 284 | res = w2.walletprocesspsbt(res["psbt"])
|
242 | 285 | assert res["complete"]
|
243 | 286 |
|
244 |
| - self.log.info("Create PSBT from wallet w4 with watch-only keys, sign with w2...") |
245 |
| - self.test_send(from_wallet=w4, to_wallet=w1, amount=1, expect_error=(-4, "Insufficient funds")) |
246 |
| - res = self.test_send(from_wallet=w4, to_wallet=w1, amount=1, include_watching=True, add_to_wallet=False) |
247 |
| - res = w2.walletprocesspsbt(res["psbt"]) |
248 |
| - assert res["complete"] |
| 287 | + if not self.options.descriptors: |
| 288 | + # Descriptor wallets do not allow mixed watch-only and non-watch-only things in the same wallet. |
| 289 | + # This is specifically testing that w4 ignores its own private keys and creates a psbt with send |
| 290 | + # which is not something that needs to be tested in descriptor wallets. |
| 291 | + self.log.info("Create PSBT from wallet w4 with watch-only keys, sign with w2...") |
| 292 | + self.test_send(from_wallet=w4, to_wallet=w1, amount=1, expect_error=(-4, "Insufficient funds")) |
| 293 | + res = self.test_send(from_wallet=w4, to_wallet=w1, amount=1, include_watching=True, add_to_wallet=False) |
| 294 | + res = w2.walletprocesspsbt(res["psbt"]) |
| 295 | + assert res["complete"] |
249 | 296 |
|
250 | 297 | self.log.info("Create OP_RETURN...")
|
251 | 298 | self.test_send(from_wallet=w0, to_wallet=w1, amount=1)
|
|
0 commit comments