Skip to content

Commit

Permalink
Properly manage addresses caching using Core native descriptor wallets (
Browse files Browse the repository at this point in the history
cryptoadvance#1193)

* Properly manage addresses caching using Core native descriptor wallets

* Move comment
  • Loading branch information
ben-kaufman authored and stepansnigirev committed May 28, 2021
1 parent 6efdde3 commit 9f1f1d9
Showing 1 changed file with 39 additions and 43 deletions.
82 changes: 39 additions & 43 deletions src/cryptoadvance/specter/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@


class Wallet:
# if the wallet is old we import 300 addresses
IMPORT_KEYPOOL = 300
# a gap of 20 addresses is what many wallets do (not used with descriptor wallets)
GAP_LIMIT = 20
# minimal fee rate is slightly above 1 sat/vbyte
Expand Down Expand Up @@ -1133,12 +1131,6 @@ def get_balance(self):
return self.balance

def keypoolrefill(self, start, end=None, change=False):
# Descriptor wallets were introduced in v0.21.0, but upgraded nodes may
# still have legacy wallets. Use getwalletinfo to check the wallet type.
# The "keypool" for descriptor wallets is automatically refilled
if self.use_descriptors and start > 0:
return

if end is None:
# end is ignored for descriptor wallets
end = start + self.GAP_LIMIT
Expand Down Expand Up @@ -1168,43 +1160,47 @@ def keypoolrefill(self, start, end=None, change=False):
]
self._addresses.add(addresses, check_rpc=False)

if not self.is_multisig:
if self.use_descriptors:
r = self.rpc.importdescriptors(args)
else:
r = self.rpc.importmulti(args, {"rescan": False})
# bip67 requires sorted public keys for multisig addresses
else:
if self.use_descriptors:
self.rpc.importdescriptors(args)
# Descriptor wallets were introduced in v0.21.0, but upgraded nodes may
# still have legacy wallets. Use getwalletinfo to check the wallet type.
# The "keypool" for descriptor wallets is automatically refilled
if not self.use_descriptors or start > 0:
if not self.is_multisig:
if self.use_descriptors:
r = self.rpc.importdescriptors(args)
else:
r = self.rpc.importmulti(args, {"rescan": False})
# bip67 requires sorted public keys for multisig addresses
else:
# try if sortedmulti is supported
r = self.rpc.importmulti(args, {"rescan": False})
# doesn't raise, but instead returns "success": False
if not r[0]["success"]:
# first import normal multi
# remove checksum
desc = desc.split("#")[0]
# switch to multi
desc = desc.replace("sortedmulti", "multi")
# add checksum
desc = AddChecksum(desc)
# update descriptor
args[0]["desc"] = desc
if self.use_descriptors:
self.rpc.importdescriptors(args)
else:
# try if sortedmulti is supported
r = self.rpc.importmulti(args, {"rescan": False})
# make a batch of single addresses to import
arg = args[0]
# remove range key
arg.pop("range")
batch = []
for i in range(start, end):
sorted_desc = sort_descriptor(desc, index=i)
# create fresh object
obj = {}
obj.update(arg)
obj.update({"desc": sorted_desc})
batch.append(obj)
r = self.rpc.importmulti(batch, {"rescan": False})
# doesn't raise, but instead returns "success": False
if not r[0]["success"]:
# first import normal multi
# remove checksum
desc = desc.split("#")[0]
# switch to multi
desc = desc.replace("sortedmulti", "multi")
# add checksum
desc = AddChecksum(desc)
# update descriptor
args[0]["desc"] = desc
r = self.rpc.importmulti(args, {"rescan": False})
# make a batch of single addresses to import
arg = args[0]
# remove range key
arg.pop("range")
batch = []
for i in range(start, end):
sorted_desc = sort_descriptor(desc, index=i)
# create fresh object
obj = {}
obj.update(arg)
obj.update({"desc": sorted_desc})
batch.append(obj)
r = self.rpc.importmulti(batch, {"rescan": False})
if change:
self.change_keypool = end
else:
Expand Down

0 comments on commit 9f1f1d9

Please sign in to comment.