diff --git a/jmclient/jmclient/blockchaininterface.py b/jmclient/jmclient/blockchaininterface.py index 39412c7b1..6af425fc1 100644 --- a/jmclient/jmclient/blockchaininterface.py +++ b/jmclient/jmclient/blockchaininterface.py @@ -504,10 +504,20 @@ def get_address_usages(self, wallet): # overall performance gain is probably negligible used_indices = self._get_used_indices(wallet, used_addresses) self._rewind_wallet_indices(wallet, used_indices, saved_indices) + # Now that we have finalized the wallet indices, update: + wallet.save() self.wallet_synced = True def sync_addresses(self, wallet, restart_cb=None): + # This more detailed version of wallet syncing must cover situations + # where the user has used the wallet on other Bitcoin Core instances + # and therefore the wallet label either does not have addresses + # imported, and/or, after the addresses are imported, they may not + # have the full history, since a rescan is required to discover + # the history of addresses before they were imported. + log.debug("requesting detailed wallet history") + wallet_name = self.get_wallet_name(wallet) addresses, saved_indices = self._collect_addresses_init(wallet) @@ -529,7 +539,6 @@ def sync_addresses(self, wallet, restart_cb=None): used_addresses_gen = (tx['address'] for tx in self._yield_transactions(wallet_name) if tx['category'] == 'receive') - used_indices = self._get_used_indices(wallet, used_addresses_gen) log.debug("got used indices: {}".format(used_indices)) gap_limit_used = not self._check_gap_indices(wallet, used_indices) @@ -547,6 +556,8 @@ def sync_addresses(self, wallet, restart_cb=None): else: log.debug("Wallet successfully synced") self._rewind_wallet_indices(wallet, used_indices, saved_indices) + # Now that we have finalized the wallet indices, update: + wallet.save() self.wallet_synced = True @staticmethod diff --git a/jmclient/jmclient/wallet.py b/jmclient/jmclient/wallet.py index d6dddbc3e..7d35621ec 100644 --- a/jmclient/jmclient/wallet.py +++ b/jmclient/jmclient/wallet.py @@ -426,12 +426,20 @@ def get_key_from_addr(self, addr): privkey = self._get_priv_from_path(path)[0] return hexlify(privkey).decode('ascii') - def _get_addr_int_ext(self, get_script_func, mixdepth, bci=None): - script = get_script_func(mixdepth) + def _get_addr_int_ext(self, internal, mixdepth, bci=None): + script = self.get_internal_script(mixdepth) if internal else \ + self.get_external_script(mixdepth) addr = self.script_to_addr(script) if bci is not None and hasattr(bci, 'import_addresses'): assert hasattr(bci, 'get_wallet_name') - bci.import_addresses([addr], bci.get_wallet_name(self)) + # we aggressively import ahead of our index, so that when + # detailed sync is needed in future, it will not find + # imports missing (and this operation costs nothing). + addrs_to_import = list(bci._collect_addresses_gap( + self, self.gaplimit)) + print("after adding gap, addrs to import is: ") + print(addrs_to_import) + bci.import_addresses(addrs_to_import, bci.get_wallet_name(self)) return addr def get_external_addr(self, mixdepth, bci=None): @@ -443,8 +451,7 @@ def get_external_addr(self, mixdepth, bci=None): address into this blockchaininterface instance (based on Bitcoin Core's model). """ - return self._get_addr_int_ext(self.get_external_script, mixdepth, - bci=bci) + return self._get_addr_int_ext(False, mixdepth, bci=bci) def get_internal_addr(self, mixdepth, bci=None): """ @@ -454,8 +461,7 @@ def get_internal_addr(self, mixdepth, bci=None): address into this blockchaininterface instance (based on Bitcoin Core's model). """ - return self._get_addr_int_ext(self.get_internal_script, mixdepth, - bci=bci) + return self._get_addr_int_ext(True, mixdepth, bci=bci) def get_external_script(self, mixdepth): return self.get_new_script(mixdepth, False)