Browse Source

allow non-fast sync in recovery in Qt

master
Adam Gibson 8 years ago
parent
commit
b01c6979f1
No known key found for this signature in database
GPG Key ID: B3AE09F1E9A3197A
  1. 42
      jmclient/jmclient/blockchaininterface.py
  2. 29
      scripts/joinmarket-qt.py

42
jmclient/jmclient/blockchaininterface.py

@ -45,8 +45,8 @@ class BlockchainInterface(object):
def __init__(self):
pass
def sync_wallet(self, wallet):
self.sync_addresses(wallet)
def sync_wallet(self, wallet, restart_cb=None):
self.sync_addresses(wallet, restart_cb)
self.sync_unspent(wallet)
@abc.abstractmethod
@ -234,7 +234,7 @@ class BitcoinCoreInterface(BlockchainInterface):
for addr in addr_list:
self.rpc('importaddress', [addr, wallet_name, False])
def add_watchonly_addresses(self, addr_list, wallet_name):
def add_watchonly_addresses(self, addr_list, wallet_name, restart_cb=None):
"""For backwards compatibility, this fn name is preserved
as the case where we quit the program if a rescan is required;
but in some cases a rescan is not required (if the address is known
@ -244,19 +244,23 @@ class BitcoinCoreInterface(BlockchainInterface):
if jm_single().config.get("BLOCKCHAIN",
"blockchain_source") != 'regtest': #pragma: no cover
#Exit conditions cannot be included in tests
print('restart Bitcoin Core with -rescan if you\'re '
'recovering an existing wallet from backup seed')
print(' otherwise just restart this joinmarket script')
sys.exit(0)
restart_msg = ("restart Bitcoin Core with -rescan if you're "
"recovering an existing wallet from backup seed\n"
"Otherwise just restart this joinmarket application.")
if restart_cb:
restart_cb(restart_msg)
else:
print(restart_msg)
sys.exit(0)
def sync_wallet(self, wallet, fast=False):
def sync_wallet(self, wallet, fast=False, restart_cb=None):
#trigger fast sync if the index_cache is available
#(and not specifically disabled).
if fast:
self.sync_wallet_fast(wallet)
self.fast_sync_called = True
return
super(BitcoinCoreInterface, self).sync_wallet(wallet)
super(BitcoinCoreInterface, self).sync_wallet(wallet, restart_cb=restart_cb)
self.fast_sync_called = False
def sync_wallet_fast(self, wallet):
@ -290,7 +294,19 @@ class BitcoinCoreInterface(BlockchainInterface):
if len(addr_info) < 3 or addr_info[2] != wallet_name:
continue
used_address_dict[addr_info[0]] = (addr_info[1], addr_info[2])
#for a first run, import first chunk
if len(used_address_dict.keys()) == 0:
log.info("Detected new wallet, performing initial import")
for i in range(wallet.max_mix_depth):
for j in [0, 1]:
addrs_to_import = []
for k in range(wallet.gaplimit + 10): # a few more for safety
addrs_to_import.append(wallet.get_addr(i, j, k))
self.import_addresses(addrs_to_import, wallet_name)
wallet.index[i][j] = 0
self.wallet_synced = True
return
#Wallet has been used; scan forwards.
log.debug("Fast sync in progress. Got this many used addresses: " + str(
len(used_address_dict)))
#Need to have wallet.index point to the last used address
@ -353,7 +369,7 @@ class BitcoinCoreInterface(BlockchainInterface):
self.wallet_synced = True
def sync_addresses(self, wallet):
def sync_addresses(self, wallet, restart_cb=None):
from jmclient.wallet import BitcoinCoreWallet
if isinstance(wallet, BitcoinCoreWallet):
@ -401,7 +417,7 @@ class BitcoinCoreInterface(BlockchainInterface):
wallet_addr_list.append(imported_addr)
imported_addr_list = self.rpc('getaddressesbyaccount', [wallet_name])
if not set(wallet_addr_list).issubset(set(imported_addr_list)):
self.add_watchonly_addresses(wallet_addr_list, wallet_name)
self.add_watchonly_addresses(wallet_addr_list, wallet_name, restart_cb)
return
buf = self.rpc('listtransactions', [wallet_name, 1000, 0, True])
@ -478,7 +494,7 @@ class BitcoinCoreInterface(BlockchainInterface):
for _ in range(addr_req_count * 3)
]
self.add_watchonly_addresses(wallet_addr_list, wallet_name)
self.add_watchonly_addresses(wallet_addr_list, wallet_name, restart_cb)
return
self.wallet_synced = True

29
scripts/joinmarket-qt.py

@ -1298,6 +1298,11 @@ class JMMainWindow(QMainWindow):
return None
return str(message_e.toPlainText())
def restartForScan(self, msg):
JMQtMessageBox(self, msg, mbtype='info',
title="Restart")
self.close()
def recoverWallet(self):
success = wallet_generate_recover_bip39("recover", "wallets",
"wallet.json",
@ -1312,9 +1317,9 @@ class JMMainWindow(QMainWindow):
return
JMQtMessageBox(self, 'Wallet saved to ' + self.walletname,
title="Wallet created")
self.initWallet(seed=self.walletname)
self.initWallet(seed=self.walletname, restart_cb=self.restartForScan)
def selectWallet(self, testnet_seed=None):
def selectWallet(self, testnet_seed=None, restart_cb=None):
if jm_single().config.get("BLOCKCHAIN", "blockchain_source") != "regtest":
current_path = os.path.dirname(os.path.realpath(__file__))
if os.path.isdir(os.path.join(current_path, 'wallets')):
@ -1335,7 +1340,7 @@ class JMMainWindow(QMainWindow):
if not ok:
return
pwd = str(text).strip()
decrypted = self.loadWalletFromBlockchain(firstarg, pwd)
decrypted = self.loadWalletFromBlockchain(firstarg, pwd, restart_cb)
else:
if not testnet_seed:
testnet_seed, ok = QInputDialog.getText(self,
@ -1347,9 +1352,9 @@ class JMMainWindow(QMainWindow):
firstarg = str(testnet_seed)
pwd = None
#ignore return value as there is no decryption failure possible
self.loadWalletFromBlockchain(firstarg, pwd)
self.loadWalletFromBlockchain(firstarg, pwd, restart_cb)
def loadWalletFromBlockchain(self, firstarg=None, pwd=None):
def loadWalletFromBlockchain(self, firstarg=None, pwd=None, restart_cb=None):
if (firstarg and pwd) or (firstarg and get_network() == 'testnet'):
try:
self.wallet = SegwitWallet(
@ -1367,12 +1372,15 @@ class JMMainWindow(QMainWindow):
if 'listunspent_args' not in jm_single().config.options('POLICY'):
jm_single().config.set('POLICY', 'listunspent_args', '[0]')
assert self.wallet, "No wallet loaded"
reactor.callLater(0, self.syncWalletUpdate, True)
reactor.callLater(0, self.syncWalletUpdate, True, restart_cb)
self.statusBar().showMessage("Reading wallet from blockchain ...")
return True
def syncWalletUpdate(self, fast):
sync_wallet(self.wallet, fast=fast)
def syncWalletUpdate(self, fast, restart_cb=None):
if restart_cb:
fast=False
jm_single().bc_interface.sync_wallet(self.wallet, fast=fast,
restart_cb=restart_cb)
self.updateWalletInfo()
def updateWalletInfo(self):
@ -1452,7 +1460,7 @@ class JMMainWindow(QMainWindow):
mb.setStandardButtons(QMessageBox.Ok)
ret = mb.exec_()
def initWallet(self, seed=None):
def initWallet(self, seed=None, restart_cb=None):
'''Creates a new wallet if seed not provided.
Initializes by syncing.
'''
@ -1470,7 +1478,8 @@ class JMMainWindow(QMainWindow):
return
JMQtMessageBox(self, 'Wallet saved to ' + self.walletname,
title="Wallet created")
self.loadWalletFromBlockchain(self.walletname, pwd=self.textpassword)
self.loadWalletFromBlockchain(self.walletname, pwd=self.textpassword,
restart_cb=restart_cb)
def get_wallet_printout(wallet):
"""Given a joinmarket wallet, retrieve the list of

Loading…
Cancel
Save