Skip to content

Commit bfb01a0

Browse files
committed
Merge #1775: Support Bitcoin Core descriptor wallets (quick and dirty way)
f3630dc Support Bitcoin Core descriptor wallets (quick and dirty way) (Kristaps Kaupe) Pull request description: Basically same as #1064, using `address()` descriptors and importing each watchable address separately, like with legacy wallets. There have been a lot of discussions about better proper implementation, but that requires more changes and nobody has written the code. IMHO this is better than nothing, more and more people are complaining about JoinMarket not working with newer Bitcoin Core versions (as it requires manual changes in `bitcoin.conf`). Note that I haven't re-tested this right now. Resolves #1571. ACKs for top commit: laanwj: Tested ACK f3630dc. With this, i was able to recover an existing jm wallet into a new bitcoin core descriptor wallet, and get the same balances. Sending and receiving was also successful. Tree-SHA512: 8bbce9637bdc0fa73956131f739424ee1247a659048807775d21e5f06da6053b7e93bcc4ee9a5c0dab2518ac4e5bd2bdfe0d789540d1d2c8879ab69dffe43c4c
2 parents dcb0054 + f3630dc commit bfb01a0

File tree

2 files changed

+25
-27
lines changed

2 files changed

+25
-27
lines changed

docs/USAGE.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,19 +121,11 @@ Make sure to follow the following step.
121121
With `bitcoind` running, do:
122122

123123
```
124-
bitcoin-cli -named createwallet wallet_name=jm_wallet descriptors=false
124+
bitcoin-cli -named createwallet wallet_name=jm_wallet disable_private_keys=true
125125
```
126126

127-
If this command fails with error `Unknown named parameter descriptors`, it means you run Bitcoin Core version older than v0.21. In that case do the following instead (but it's recommended to upgrade Bitcoin Core to more recent version):
128-
```
129-
bitcoin-cli createwallet "jm_wallet"
130-
```
131-
132-
If this command fails with error `BDB wallet creation is deprecated and will be removed in a future release. In this release it can be re-enabled temporarily with the -deprecatedrpc=create_bdb setting.`, it means you run Bitcoin Core version v26 or newer. In that case you must add `deprecatedrpc=create_bdb` setting to your `bitcoin.conf`, restart Bitcoin Core and try again.
133-
134127
The "jm_wallet" name is just an example. You can set any name. Alternative to this `bitcoin-cli` command: you can set a line with `wallet=..` in your
135-
`bitcoin.conf` before starting Core (see the Bitcoin Core documentation for details). At the moment, only legacy wallets (`descriptors=false`)
136-
work with Joinmarket. This means that Bitcoin Core needs to have been built with legacy wallet (Berkeley DB) support.
128+
`bitcoin.conf` before starting Core (see the Bitcoin Core documentation for details).
137129

138130
After you create the wallet in the Bitcoin Core, you should set it in the `joinmarket.cfg`:
139131

src/jmclient/blockchaininterface.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -356,14 +356,11 @@ def __init__(self, jsonRpc: JsonRpc, network: str, wallet_name: str) -> None:
356356
log.info("Loading Bitcoin RPC wallet " + wallet_name + "...")
357357
self._rpc("loadwallet", [wallet_name])
358358
log.info("Done.")
359-
# We only support legacy wallets currently
359+
# We need to know is this legacy or descriptors wallet because there
360+
# will be different RPC calls needed for address import.
360361
wallet_info = self._getwalletinfo()
361-
if "descriptors" in wallet_info and wallet_info["descriptors"]:
362-
raise Exception(
363-
"JoinMarket currently does not support Bitcoin Core "
364-
"descriptor wallets, use legacy wallet (rpc_wallet_file "
365-
"setting in joinmarket.cfg) instead. See docs/USAGE.md "
366-
"for details.")
362+
self.descriptors = ("descriptors" in wallet_info and
363+
wallet_info["descriptors"])
367364

368365
def is_address_imported(self, addr: str) -> bool:
369366
return len(self._rpc('getaddressinfo', [addr])['labels']) > 0
@@ -429,7 +426,8 @@ def _rpc(self, method: str, args: Union[dict, list] = []) -> Any:
429426
if method not in ['importaddress', 'walletpassphrase', 'getaccount',
430427
'gettransaction', 'getrawtransaction', 'gettxout',
431428
'importmulti', 'listtransactions', 'getblockcount',
432-
'scantxoutset', 'getblock', 'getblockhash']:
429+
'scantxoutset', 'getblock', 'getblockhash',
430+
'importdescriptors']:
433431
log.debug('rpc: ' + method + " " + str(args))
434432
try:
435433
res = self.jsonRpc.call(method, args)
@@ -457,15 +455,23 @@ def is_address_labeled(self, utxo: dict, walletname: str) -> bool:
457455
def import_addresses(self, addr_list: Iterable[str], wallet_name: str,
458456
restart_cb: Callable[[str], None] = None) -> None:
459457
requests = []
460-
for addr in addr_list:
461-
requests.append({
462-
"scriptPubKey": {"address": addr},
463-
"timestamp": 0,
464-
"label": wallet_name,
465-
"watchonly": True
466-
})
467-
468-
result = self._rpc('importmulti', [requests, {"rescan": False}])
458+
if self.descriptors:
459+
for addr in addr_list:
460+
requests.append({
461+
"desc": btc.get_address_descriptor(addr),
462+
"timestamp": "now",
463+
"label": wallet_name
464+
})
465+
result = self._rpc('importdescriptors', [requests])
466+
else:
467+
for addr in addr_list:
468+
requests.append({
469+
"scriptPubKey": {"address": addr},
470+
"timestamp": 0,
471+
"label": wallet_name,
472+
"watchonly": True
473+
})
474+
result = self._rpc('importmulti', [requests, {"rescan": False}])
469475

470476
num_failed = 0
471477
for row in result:

0 commit comments

Comments
 (0)