Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251):252self.log.info(f"Importing private Miniscript descriptor '{desc}'")253is_taproot = desc.startswith("tr(")254desc = descsum_create(desc)255res = self.ms_sig_wallet.importdescriptors(256[257{258"desc": desc,259"active": True,260"range": 0,261"next_index": 0,262"timestamp": "now",263}264]265)266assert res[0]["success"], res268self.log.info("Generating an address for it and testing it detects funds")269addr_type = "bech32m" if is_taproot else "bech32"270addr = self.ms_sig_wallet.getnewaddress(address_type=addr_type)271txid = self.funder.sendtoaddress(addr, 0.01)272self.wait_until(lambda: txid in self.funder.getrawmempool())273self.funder.generatetoaddress(1, self.funder.getnewaddress())274utxo = self.ms_sig_wallet.listunspent(addresses=[addr])[0]275assert_equal(txid, utxo["txid"])276assert_equal(utxo["solvable"], True)278self.log.info("Creating a transaction spending these funds")279dest_addr = self.funder.getnewaddress()280seq = sequence if sequence is not None else 0xFFFFFFFF - 2281lt = locktime if locktime is not None else 0282psbt = self.ms_sig_wallet.createpsbt(283[284{285"txid": txid,286"vout": utxo["vout"],287"sequence": seq,288}289],290[{dest_addr: 0.009}],291lt,292)294self.log.info("Signing it and checking the satisfaction.")295if sha256_preimages is not None:296psbt = PSBT.from_base64(psbt)297for (h, preimage) in sha256_preimages.items():298k = PSBT_IN_SHA256.to_bytes(1, "big") + bytes.fromhex(h)299psbt.i[0].map[k] = bytes.fromhex(preimage)300psbt = psbt.to_base64()301res = self.ms_sig_wallet.walletprocesspsbt(psbt=psbt, finalize=False)302psbtin = self.nodes[0].decodepsbt(res["psbt"])["inputs"][0]303sigs_field_name = "taproot_script_path_sigs" if is_taproot else "partial_signatures"304assert_equal(len(psbtin[sigs_field_name]), sigs_count)305res = self.ms_sig_wallet.finalizepsbt(res["psbt"])306assert_equal(res["complete"], stack_size is not None)308if stack_size is not None:309txin = self.nodes[0].decoderawtransaction(res["hex"])["vin"][0]310assert len(txin["txinwitness"]) == stack_size, txin["txinwitness"]311self.log.info("Broadcasting the transaction.")312# If necessary, satisfy a relative timelock313if sequence is not None:314self.funder.generatetoaddress(sequence, self.funder.getnewaddress())315# If necessary, satisfy an absolute timelock316height = self.funder.getblockcount()317if locktime is not None and height < locktime:318self.funder.generatetoaddress(319locktime - height, self.funder.getnewaddress()320)321self.ms_sig_wallet.sendrawtransaction(res["hex"])323def run_test(self):324self.log.info("Making a descriptor wallet")325self.funder = self.nodes[0].get_wallet_rpc(self.default_wallet_name)326self.nodes[0].createwallet(327wallet_name="ms_wo", disable_private_keys=True328)329self.ms_wo_wallet = self.nodes[0].get_wallet_rpc("ms_wo")330self.nodes[0].createwallet(wallet_name="ms_sig")331self.ms_sig_wallet = self.nodes[0].get_wallet_rpc("ms_sig")333# Sanity check we wouldn't let an insane Miniscript descriptor in334res = self.ms_wo_wallet.importdescriptors(335[336{337"desc": descsum_create(338"wsh(and_b(ripemd160(1fd9b55a054a2b3f658d97e6b84cf3ee00be429a),a:1))"339),340"active": False,341"timestamp": "now",342}343]344)[0]345assert_equal(res["success"], False)346assert "is not sane: witnesses without signature exist" in res["error"]["message"]348# Sanity check we wouldn't let an unspendable Miniscript descriptor in349res = self.ms_wo_wallet.importdescriptors(350[351{352"desc": descsum_create("wsh(0)"),353"active": False,354"timestamp": "now",355}356]357)[0]358assert not res["success"] and "is not satisfiable" in res["error"]["message"]360# Test we can track any type of Miniscript361for desc in DESCS:362self.watchonly_test(desc)364# Test we can sign for any Miniscript.365for desc in DESCS_PRIV:366self.signing_test(367desc["desc"],368desc["sequence"],369desc["locktime"],370desc["sigs_count"],371desc["stack_size"],372desc.get("sha256_preimages"),373)375# Test we can sign for a max-size TapMiniscript. Recompute the maximum accepted size376# for a TapMiniscript (see cpp file for details). Then pad a simple pubkey check up377# to the maximum size. Make sure we can import and spend this script.378leeway_weight = (4 + 4 + 1 + 36 + 4 + 1 + 1 + 8 + 1 + 1 + 33) * 4 + 2379max_tapmini_size = 400_000 - 3 - (1 + 65) * 1_000 - 3 - (33 + 32 * 128) - leeway_weight - 5380padding = max_tapmini_size - 33 - 1381ms = f"pk({TPRVS[0]}/*)"382ms = "n" * padding + ":" + ms383desc = f"tr({PUBKEYS[0]},{ms})"384self.signing_test(desc, None, None, 1, 3, None)385# This was really the maximum size, one more byte and we can't import it.386ms = "n" + ms387desc = f"tr({PUBKEYS[0]},{ms})"388res = self.ms_wo_wallet.importdescriptors(389[390{391"desc": descsum_create(desc),392"active": False,393"timestamp": "now",394}395]396)[0]397assert_equal(res["success"], False)398assert "is not a valid descriptor function" in res["error"]["message"]401if __name__ == "__main__":402WalletMiniscriptTest(__file__).main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.