Launch `WatchtowerPlugin.watchtower.start_watching()` through
asyncio.run_coroutine_threadsafe instead of ensure_future to prevent the
following exception from happening when running python with
`PYTHONASYNCIODEBUG=1`.
```
20251103T165007.087746Z | ERROR | plugin.Plugins | cannot initialize plugin watchtower: Error loading watchtower plugin: RuntimeError('Non-thread-safe operation invoked on an event loop other than the current one')
Traceback (most recent call last):
File "/home/user/code/electrum-fork/electrum/plugin.py", line 629, in load_plugin_by_name
plugin = module.Plugin(self, self.config, name)
File "/home/user/code/electrum-fork/electrum/plugins/watchtower/watchtower.py", line 59, in __init__
asyncio.ensure_future(self.watchtower.start_watching())
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.14/asyncio/tasks.py", line 732, in ensure_future
return loop.create_task(coro_or_future)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.14/asyncio/base_events.py", line 468, in create_task
return self._task_factory(self, coro, **kwargs)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/code/electrum-fork/electrum/util.py", line 1773, in factory
task = asyncio.Task(coro, loop=loop_, **kwargs)
File "/usr/lib64/python3.14/asyncio/base_events.py", line 829, in call_soon
self._check_thread()
~~~~~~~~~~~~~~~~~~^^
File "/usr/lib64/python3.14/asyncio/base_events.py", line 866, in _check_thread
raise RuntimeError(
"Non-thread-safe operation invoked on an event loop other "
"than the current one")
RuntimeError: Non-thread-safe operation invoked on an event loop other than the current one
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/user/code/electrum-fork/electrum/plugin.py", line 184, in load_plugins
self.load_plugin_by_name(name)
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/home/user/code/electrum-fork/electrum/plugin.py", line 631, in load_plugin_by_name
raise Exception(f"Error loading {name} plugin: {repr(e)}") from e
Exception: Error loading watchtower plugin: RuntimeError('Non-thread-safe operation invoked on an event loop other than the current one')
```
Plugin rules: * The plugin system of Electrum is designed to allow the development of new features without increasing the core code of Electrum. * Electrum is written in pure python. if you want to add a feature that requires non-python libraries, then it must be submitted as a plugin. If the feature you want to add requires communication with a remote server (not an Electrum server), then it should be a plugin as well. If the feature you want to add introduces new dependencies in the code, then it should probably be a plugin. * We expect plugin developers to maintain their plugin code. However, once a plugin is merged in Electrum, we will have to maintain it too, because changes in the Electrum code often require updates in the plugin code. Therefore, plugins have to be easy to maintain. If we believe that a plugin will create too much maintenance work in the future, it will be rejected. * Plugins should be compatible with Electrum's conventions. If your plugin does not fit with Electrum's architecture, or if we believe that it will create too much maintenance work, it will not be accepted. In particular, do not duplicate existing Electrum code in your plugin. * We may decide to remove a plugin after it has been merged in Electrum. For this reason, a plugin must be easily removable, without putting at risk the user's bitcoins. If we feel that a plugin cannot be removed without threatening users who rely on it, we will not merge it.