Browse Source

Merge #589: Allow accessing basic wallet info without blockchain source

f26186d1bd Allow accessing basic wallet info without blockchain source (Kristaps Kaupe)

Pull request description:

  In both GUI and `wallet-tool.py`. Useful to, for example, extract recovery seed from a .jmdat wallet file without blockchain source. Resolves #545.

Top commit has no ACKs.

Tree-SHA512: c9c2d3b8601eac5dd55a05694c3fbd0873007abc666170e43cf26d745602db84200f5000355e4cc1c3be8085c78764f7d1d6cec87552d4e5775d47aa3d835208
master
Kristaps Kaupe 6 years ago
parent
commit
ebd4a82403
No known key found for this signature in database
GPG Key ID: D47B1B4232B55437
  1. 3
      jmclient/jmclient/wallet.py
  2. 5
      jmclient/jmclient/wallet_service.py
  3. 2
      jmclient/jmclient/wallet_utils.py
  4. 7
      jmclient/jmclient/yieldgenerator.py
  5. 40
      scripts/joinmarket-qt.py
  6. 4
      scripts/tumbler.py

3
jmclient/jmclient/wallet.py

@ -74,6 +74,9 @@ def estimate_tx_fee(ins, outs, txtype='p2pkh', extra_bytes=0):
for a transaction with the given number of inputs and outputs,
based on information from the blockchain interface.
'''
if jm_single().bc_interface is None:
raise RuntimeError("Cannot estimate transaction fee " +
"without blockchain source.")
fee_per_kb = jm_single().bc_interface.estimate_fee_per_kb(
jm_single().config.getint("POLICY","tx_fees"))
absurd_fee = jm_single().config.getint("POLICY", "absurd_fee_per_kb")

5
jmclient/jmclient/wallet_service.py

@ -42,7 +42,11 @@ class WalletService(Service):
self.bci = jm_single().bc_interface
# keep track of the quasi-real-time blockheight
# (updated in main monitor loop)
if self.bci is not None:
self.update_blockheight()
else:
jlog.warning("No blockchain source available, " +
"wallet tools will not show correct balances.")
self.wallet = wallet
self.synced = False
@ -111,6 +115,7 @@ class WalletService(Service):
""" Ensures wallet sync is complete
before the main event loop starts.
"""
if self.bci is not None:
d = task.deferLater(reactor, 0.0, self.sync_wallet)
d.addCallback(self.start_wallet_monitoring)

2
jmclient/jmclient/wallet_utils.py

@ -1410,7 +1410,7 @@ def wallet_tool_main(wallet_root_path):
# the service will not be started since this is a synchronous script:
wallet_service = WalletService(wallet)
if method not in noscan_methods:
if method not in noscan_methods and jm_single().bc_interface is not None:
# if nothing was configured, we override bitcoind's options so that
# unconfirmed balance is included in the wallet display by default
if 'listunspent_args' not in jm_single().config.options('POLICY'):

7
jmclient/jmclient/yieldgenerator.py

@ -12,7 +12,7 @@ from jmclient import Maker, jm_single, load_program_config, \
JMClientProtocolFactory, start_reactor, calc_cj_fee, \
WalletService, add_base_options
from .wallet_utils import open_test_wallet_maybe, get_wallet_path
from jmbase.support import EXIT_ARGERROR
from jmbase.support import EXIT_ARGERROR, EXIT_FAILURE
jlog = get_log()
@ -239,6 +239,11 @@ def ygmain(ygclass, txfee=1000, cjfee_a=200, cjfee_r=0.002, ordertype='swreloffe
load_program_config(config_path=options.datadir)
if jm_single().bc_interface is None:
jlog.error("Running yield generator requires configured " +
"blockchain source.")
sys.exit(EXIT_FAILURE)
wallet_path = get_wallet_path(wallet_name, None)
wallet = open_test_wallet_maybe(
wallet_path, wallet_name, options.mixdepth,

40
scripts/joinmarket-qt.py

@ -580,6 +580,9 @@ class SpendTab(QWidget):
self.startJoin()
def startMultiple(self):
if jm_single().bc_interface is None:
log.info("Cannot start join, blockchain source not available.")
return
if not self.spendstate.runstate == 'ready':
log.info("Cannot start join, already running.")
return
@ -659,7 +662,7 @@ class SpendTab(QWidget):
try:
amount = btc.amount_to_sat(self.amountInput.text())
except ValueError as e:
JMQtMessageBox(parent, e.args[0], title="Error", mbtype="warn")
JMQtMessageBox(self, e.args[0], title="Error", mbtype="warn")
return
makercount = int(self.numCPInput.text())
mixdepth = int(self.mixdepthInput.text())
@ -995,6 +998,12 @@ class SpendTab(QWidget):
self.tumbler_destaddrs = None
def validateSettings(self):
if jm_single().bc_interface is None:
JMQtMessageBox(
self,
"Sending coins not possible without blockchain source.",
mbtype='warn', title="Error")
return False
valid, errmsg = validate_address(
str(self.addressInput.text().strip()))
if not valid:
@ -1318,11 +1327,17 @@ class JMWalletTab(QWidget):
self.wallet_name = os.path.basename(
mainWindow.wallet_service.get_storage_location())
if total_bal is None:
if jm_single().bc_interface is not None:
total_bal = " (syncing..)"
else:
total_bal = " (unknown, no blockchain source available)"
self.label1.setText("CURRENT WALLET: " + self.wallet_name +
', total balance: ' + total_bal)
l.show()
if jm_single().bc_interface is None and self.wallet_name != 'NONE':
return
for i in range(nm):
if walletinfo:
mdbalance = mbalances[i]
@ -1728,6 +1743,12 @@ class JMMainWindow(QMainWindow):
self.walletRefresh.stop()
self.wallet_service = WalletService(wallet)
if jm_single().bc_interface is None:
self.centralWidget().widget(0).updateWalletInfo(
get_wallet_printout(self.wallet_service))
return True
# add information callbacks:
self.wallet_service.add_restart_callback(self.restartWithMsg)
self.wallet_service.autofreeze_warning_cb = self.autofreeze_warning_cb
@ -1936,15 +1957,16 @@ except Exception as e:
])
JMQtMessageBox(None, config_load_error, mbtype='crit', title='failed to load')
sys.exit(EXIT_FAILURE)
# Qt does not currently support any functioning without a Core interface:
# Only partial functionality (see wallet info, change config) is possible
# without a blockchain interface.
if jm_single().bc_interface is None:
blockchain_error = ''.join(["Joinmarket-Qt requires Bitcoin Core as a blockchain ",
"interface; change the setting of 'blockchain_source' ",
"in the joinmarket.cfg file to a value not equal to ",
"'no-blockchain'; see comments for details."])
JMQtMessageBox(None, blockchain_error, mbtype='crit',
title='Invalid blockchain source')
sys.exit(EXIT_FAILURE)
blockchain_warning = ''.join([
"No blockchain source currently configured. ",
"You will be able to see wallet information and change configuration ",
"but other functionality will be limited. ",
"Go to the 'Settings' tab and configure blockchain settings there."])
JMQtMessageBox(None, blockchain_warning, mbtype='warn',
title='No blockchain source')
#refuse to load non-segwit wallet (needs extra work in wallet-utils).
if not jm_single().config.get("POLICY", "segwit") == "true":
wallet_load_error = ''.join(["Joinmarket-Qt only supports segwit based wallets, ",

4
scripts/tumbler.py

@ -31,6 +31,10 @@ def main():
sys.exit(EXIT_ARGERROR)
load_program_config(config_path=options['datadir'])
if jm_single().bc_interface is None:
jmprint('Error: Needs a blockchain source', "error")
sys.exit(EXIT_FAILURE)
check_regtest()
#Load the wallet

Loading…
Cancel
Save