Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
gruve-p committed Aug 25, 2023
2 parents 1deb59e + 6a9e532 commit d66a6a3
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 34 deletions.
17 changes: 14 additions & 3 deletions electrum_grs/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ def __init__(
if 'wallet_path' in config.cmdline_options:
self.logger.warning("Ignoring parameter 'wallet_path' for daemon. "
"Use the load_wallet command instead.")
self._plugins = None # type: Optional[Plugins]
self.asyncio_loop = util.get_asyncio_loop()
if not self.config.NETWORK_OFFLINE:
self.network = Network(config, daemon=self)
Expand Down Expand Up @@ -560,6 +561,9 @@ async def _stop_wallet(self, path: str) -> bool:
return True

def run_daemon(self):
# init plugins
self._plugins = Plugins(self.config, 'cmdline')
# block until we are stopping
try:
self._stopping_soon_or_errored.wait()
except KeyboardInterrupt:
Expand Down Expand Up @@ -590,25 +594,32 @@ async def stop(self):
if self.network:
await group.spawn(self.network.stop(full_shutdown=True))
await group.spawn(self.taskgroup.cancel_remaining())
if self._plugins:
self.logger.info("stopping plugins")
self._plugins.stop()
async with ignore_after(1):
await self._plugins.stopped_event_async.wait()
finally:
if self.listen_jsonrpc:
self.logger.info("removing lockfile")
remove_lockfile(get_lockfile(self.config))
self.logger.info("stopped")
self._stopped_event.set()

def run_gui(self, config: 'SimpleConfig', plugins: 'Plugins'):
def run_gui(self) -> None:
assert self.config
threading.current_thread().name = 'GUI'
gui_name = config.GUI_NAME
gui_name = self.config.GUI_NAME
if gui_name in ['lite', 'classic']:
gui_name = 'qt'
self._plugins = Plugins(self.config, gui_name) # init plugins
self.logger.info(f'launching GUI: {gui_name}')
try:
try:
gui = __import__('electrum_grs.gui.' + gui_name, fromlist=['electrum_grs'])
except GuiImportError as e:
sys.exit(str(e))
self.gui_object = gui.ElectrumGui(config=config, daemon=self, plugins=plugins)
self.gui_object = gui.ElectrumGui(config=self.config, daemon=self, plugins=self._plugins)
if not self._stop_entered:
self.gui_object.main()
else:
Expand Down
2 changes: 1 addition & 1 deletion electrum_grs/gui/qml/qewizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def createStorage(self, js_data, single_password_enabled, single_password):

self.createSuccess.emit()
except Exception as e:
self._logger.error(f"createStorage errored: {e!r}")
self._logger.exception(f"createStorage errored: {e!r}")
self.createError.emit(str(e))


Expand Down
2 changes: 1 addition & 1 deletion electrum_grs/gui/qt/installwizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ def run_upgrades(self, storage: WalletStorage, db: 'WalletDB') -> None:
self.run(action)
for k, v in self.data.items():
db.put(k, v)
db.write(storage)
db.write()
return

if db.requires_upgrade():
Expand Down
1 change: 1 addition & 0 deletions electrum_grs/gui/qt/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,7 @@ def update_console(self):
'util': util,
'bitcoin': bitcoin,
'lnutil': lnutil,
'channels': list(self.wallet.lnworker.channels.values()) if self.wallet.lnworker else []
})

c = commands.Commands(
Expand Down
4 changes: 2 additions & 2 deletions electrum_grs/gui/qt/send_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,13 +511,13 @@ def get_amount(self) -> int:
# must not be None
return self.amount_e.get_amount() or 0

def on_finalize_done(self, pi):
def on_finalize_done(self, pi: PaymentIdentifier):
self.showSpinner(False)
self.update_fields()
if pi.error:
self.show_error(pi.error)
return
invoice = pi.get_invoice(self.get_amount(), self.get_message())
invoice = pi.bolt11
self.pending_invoice = invoice
self.logger.debug(f'after finalize invoice: {invoice!r}')
self.do_pay_invoice(invoice)
Expand Down
4 changes: 2 additions & 2 deletions electrum_grs/payment_identifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def __init__(self, wallet: Optional['Abstract_Wallet'], text: str):
# more than one of those may be set
self.multiline_outputs = None
self._is_max = False
self.bolt11 = None
self.bolt11 = None # type: Optional[Invoice]
self.bip21 = None
self.spk = None
#
Expand Down Expand Up @@ -406,7 +406,7 @@ async def _do_finalize(
if invoice.get_amount_sat() != amount_sat:
raise Exception("lnurl returned invoice with wrong amount")
# this will change what is returned by get_fields_for_GUI
self.bolt11 = bolt11_invoice
self.bolt11 = invoice
self.set_state(PaymentIdentifierState.AVAILABLE)
except Exception as e:
self.error = str(e)
Expand Down
2 changes: 1 addition & 1 deletion electrum_grs/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ def get_plugin(self, name: str) -> 'BasePlugin':

def run(self):
while self.is_running():
time.sleep(0.1)
self.wake_up_event.wait(0.1) # time.sleep(0.1) OR event
self.run_jobs()
self.on_stop()

Expand Down
2 changes: 1 addition & 1 deletion electrum_grs/plugins/trustedcoin/trustedcoin.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ def add_new_billing_address(self, billing_index: int, address: str, addr_type: s
self.db.put('trustedcoin_billing_addresses', self._billing_addresses['legacy'])
self.db.put('trustedcoin_billing_addresses_segwit', self._billing_addresses['segwit'])
# FIXME this often runs in a daemon thread, where storage.write will fail
self.db.write(self.storage)
self.db.write()

def is_billing_address(self, addr: str) -> bool:
return addr in self._billing_addresses_set
Expand Down
30 changes: 13 additions & 17 deletions electrum_grs/tests/test_storage_upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from electrum_grs.wallet import Wallet
from electrum_grs import constants
from electrum_grs import util
from electrum_grs.plugin import Plugins
from electrum_grs.simple_config import SimpleConfig

from . import as_testnet
from .test_wallet import WalletTestCase
Expand Down Expand Up @@ -297,25 +299,19 @@ async def test_upgrade_from_client_3_3_8_xpub_with_realistic_history(self):

plugins: 'electrum_grs.plugin.Plugins'

@classmethod
def setUpClass(cls):
super().setUpClass()
from electrum_grs.plugin import Plugins
from electrum_grs.simple_config import SimpleConfig

cls.__electrum_path = tempfile.mkdtemp()
config = SimpleConfig({'electrum_path': cls.__electrum_path})

def setUp(self):
super().setUp()
self.__electrum_path = tempfile.mkdtemp()
config = SimpleConfig({'electrum_path': self.__electrum_path})
gui_name = 'cmdline'
# TODO it's probably wasteful to load all plugins... only need Trezor
cls.plugins = Plugins(config, gui_name)

@classmethod
def tearDownClass(cls):
super().tearDownClass()
shutil.rmtree(cls.__electrum_path)
cls.plugins.stop()
cls.plugins.stopped_event.wait()
self.plugins = Plugins(config, gui_name)

def tearDown(self):
super().tearDown()
shutil.rmtree(self.__electrum_path)
self.plugins.stop()
self.plugins.stopped_event.wait()

async def _upgrade_storage(self, wallet_json, accounts=1) -> Optional[WalletDB]:
if accounts == 1:
Expand Down
8 changes: 7 additions & 1 deletion electrum_grs/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,9 @@ def __init__(self):
self.running_lock = threading.Lock()
self.job_lock = threading.Lock()
self.jobs = []
self.stopped_event = threading.Event() # set when fully stopped
self.stopped_event = threading.Event() # set when fully stopped
self.stopped_event_async = asyncio.Event() # set when fully stopped
self.wake_up_event = threading.Event() # for perf optimisation of polling in run()

def add_jobs(self, jobs):
with self.job_lock:
Expand Down Expand Up @@ -404,6 +406,8 @@ def is_running(self):
def stop(self):
with self.running_lock:
self.running = False
self.wake_up_event.set()
self.wake_up_event.clear()

def on_stop(self):
if 'ANDROID_DATA' in os.environ:
Expand All @@ -412,6 +416,8 @@ def on_stop(self):
self.logger.info("jnius detach")
self.logger.info("stopped")
self.stopped_event.set()
loop = get_asyncio_loop()
loop.call_soon_threadsafe(self.stopped_event_async.set)


def print_stderr(*args):
Expand Down
2 changes: 1 addition & 1 deletion electrum_grs/wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ def create_storage(self, path, data):
db.put('lightning_xprv', k.get_lightning_xprv(data['password'] if data['encrypt'] else None))

db.load_plugins()
db.write(storage)
db.write()

class ServerConnectWizard(AbstractWizard):

Expand Down
10 changes: 6 additions & 4 deletions run_electrum_grs
Original file line number Diff line number Diff line change
Expand Up @@ -451,10 +451,9 @@ def handle_cmd(*, cmdname: str, config: 'SimpleConfig', config_options: dict):
configure_logging(config)
fd = daemon.get_file_descriptor(config)
if fd is not None:
plugins = init_plugins(config, config.GUI_NAME)
d = daemon.Daemon(config, fd, start_network=False)
try:
d.run_gui(config, plugins)
d.run_gui()
except BaseException as e:
_logger.exception('daemon.run_gui errored')
sys_exit(1)
Expand All @@ -469,7 +468,6 @@ def handle_cmd(*, cmdname: str, config: 'SimpleConfig', config_options: dict):
fd = daemon.get_file_descriptor(config)
if fd is not None:
# run daemon
init_plugins(config, 'cmdline')
d = daemon.Daemon(config, fd)
d.run_daemon()
sys_exit(0)
Expand Down Expand Up @@ -515,7 +513,11 @@ def handle_cmd(*, cmdname: str, config: 'SimpleConfig', config_options: dict):
coro = run_offline_command(config, config_options, plugins)
fut = asyncio.run_coroutine_threadsafe(coro, loop)
try:
result = fut.result()
try:
result = fut.result()
finally:
plugins.stop()
plugins.stopped_event.wait(1)
except Exception as e:
print_stderr(str(e) or repr(e))
sys_exit(1)
Expand Down

0 comments on commit d66a6a3

Please sign in to comment.