Skip to content

Commit

Permalink
Ensure all displayed addresses are imported
Browse files Browse the repository at this point in the history
Fixes #1143 (and possibly others). Before this commit,
(index plus gap limit) addresses are imported on sync,
and addresses used by maker/taker in coinjoin are imported,
but when a deposit occurred, bumping the index, further
addresses were not imported. The effect was that it was
possible, if doing a series of deposits to multiple
external addresses in a Qt session, to end up depositing
to an address that was not yet imported. And this results
in the user needing to rescan for Core+JM to recognize the
coins.
After this commit, we ensure all 'gap limit forwards'
addresses, which are displayed as potential deposit addresses
in Joinmarket-Qt, are imported before the display.
  • Loading branch information
AdamISZ committed Jan 14, 2022
1 parent 8b3d21f commit ac8b173
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
16 changes: 8 additions & 8 deletions jmclient/jmclient/wallet_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -887,11 +887,13 @@ def get_balance_by_mixdepth(self, verbose=True,
include_disabled=include_disabled,
maxheight=maxheight)

def get_internal_addr(self, mixdepth):
def import_addr(self, addr):
if self.bci is not None and hasattr(self.bci, 'import_addresses'):
addr = self.wallet.get_internal_addr(mixdepth)
self.bci.import_addresses([addr],
self.wallet.get_wallet_name())
self.bci.import_addresses([addr], self.wallet.get_wallet_name())

def get_internal_addr(self, mixdepth):
addr = self.wallet.get_internal_addr(mixdepth)
self.import_addr(addr)
return addr

def collect_addresses_init(self):
Expand Down Expand Up @@ -944,10 +946,8 @@ def collect_addresses_gap(self, gap_limit=None):
return addresses

def get_external_addr(self, mixdepth):
if self.bci is not None and hasattr(self.bci, 'import_addresses'):
addr = self.wallet.get_external_addr(mixdepth)
self.bci.import_addresses([addr],
self.wallet.get_wallet_name())
addr = self.wallet.get_external_addr(mixdepth)
self.import_addr(addr)
return addr

def __getattr__(self, attr):
Expand Down
12 changes: 12 additions & 0 deletions jmclient/jmclient/wallet_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,9 +494,12 @@ def get_addr_status(addr_path, utxos, is_new, is_internal):
xpub_key = ""

unused_index = wallet_service.get_next_unused_index(m, address_type)
gap_addrs = []
for k in range(unused_index + wallet_service.gap_limit):
path = wallet_service.get_path(m, address_type, k)
addr = wallet_service.get_address_from_path(path)
if k >= unused_index:
gap_addrs.append(addr)
label = wallet_service.get_address_label(addr)
balance, status = get_addr_status(
path, utxos[m], k >= unused_index, address_type)
Expand All @@ -509,6 +512,15 @@ def get_addr_status(addr_path, utxos, is_new, is_internal):
entrylist.append(WalletViewEntry(
wallet_service.get_path_repr(path), m, address_type, k, addr,
[balance, balance], priv=privkey, status=status, label=label))
# ensure that we never display un-imported addresses (this will generally duplicate
# the import of each new address gap limit times, but one importmulti call
# per mixdepth is cheap enough.
# This only applies to the external branch, because it only applies to addresses
# displayed for user deposit.
# It also does not apply to fidelity bond addresses which are created manually.
if address_type == BaseWallet.ADDRESS_TYPE_EXTERNAL:
wallet_service.bci.import_addresses(gap_addrs,
wallet_service.get_wallet_name())
wallet_service.set_next_index(m, address_type, unused_index)
path = wallet_service.get_path_repr(wallet_service.get_path(m, address_type))
branchlist.append(WalletViewBranch(path, m, address_type, entrylist,
Expand Down
2 changes: 1 addition & 1 deletion test/ygrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def get_addr_and_fund(yg):
return
if yg.wallet_service.timelock_funded:
return
addr = wallet_gettimelockaddress(yg.wallet_service.wallet, "2021-11")
addr = wallet_gettimelockaddress(yg.wallet_service.wallet, "2023-11")
print("Got timelockaddress: {}".format(addr))

# pay into it; amount is randomized for now.
Expand Down

0 comments on commit ac8b173

Please sign in to comment.