URI: 
       tcosigner pool: use single thread to send messages - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 7a6ec23b6ecfe48e28e16d2a9cd1bb255ead75c8
   DIR parent 1a9e6a434f9fb5277c0813e2438805e1f23397be
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Mon, 29 Jun 2020 02:19:03 +0200
       
       cosigner pool: use single thread to send messages
       
       ServerProxy does not seem to be thread-safe.
       For e.g. a 2of3 multisig wallet, which would send two messages,
       one msg would get sent but the other might error out. See trace:
       
       E | plugins.cosigner_pool.qt.Plugin | on_failure
       Traceback (most recent call last):
         File "...\electrum\electrum\gui\qt\util.py", line 832, in run
           result = task.task()
         File "...\electrum\electrum\plugins\cosigner_pool\qt.py", line 199, in <lambda>
           task = lambda: server.put(_hash, message)
         File "...\Python38\lib\xmlrpc\client.py", line 1109, in __call__
           return self.__send(self.__name, args)
         File "...\Python38\lib\xmlrpc\client.py", line 1450, in __request
           response = self.__transport.request(
         File "...\Python38\lib\xmlrpc\client.py", line 1153, in request
           return self.single_request(host, handler, request_body, verbose)
         File "...\Python38\lib\xmlrpc\client.py", line 1165, in single_request
           http_conn = self.send_request(host, handler, request_body, verbose)
         File "...\Python38\lib\xmlrpc\client.py", line 1271, in send_request
           connection.putrequest("POST", handler, skip_accept_encoding=True)
         File "...\Python38\lib\http\client.py", line 1088, in putrequest
           raise CannotSendRequest(self.__state)
       http.client.CannotSendRequest: Request-sent
       
       Diffstat:
         M electrum/plugins/cosigner_pool/qt.… |      20 +++++++++++++++-----
       
       1 file changed, 15 insertions(+), 5 deletions(-)
       ---
   DIR diff --git a/electrum/plugins/cosigner_pool/qt.py b/electrum/plugins/cosigner_pool/qt.py
       t@@ -188,17 +188,27 @@ class Plugin(BasePlugin):
                    except OSError: pass
                    window.show_error(_("Failed to send transaction to cosigning pool") + ':\n' + repr(e))
        
       +        buffer = []
       +        some_window = None
       +        # construct messages
                for window, xpub, K, _hash in self.cosigner_list:
                    if not self.cosigner_can_sign(tx, xpub):
                        continue
       -            # construct message
       +            some_window = window
                    raw_tx_bytes = tx.serialize_as_bytes()
                    public_key = ecc.ECPubkey(K)
                    message = public_key.encrypt_message(raw_tx_bytes).decode('ascii')
       -            # send message
       -            task = lambda: server.put(_hash, message)
       -            msg = _('Sending transaction to cosigning pool...')
       -            WaitingDialog(window, msg, task, on_success, on_failure)
       +            buffer.append((_hash, message))
       +        if not buffer:
       +            return
       +
       +        # send messages
       +        # note: we send all messages sequentially on the same thread
       +        def send_messages_task():
       +            for _hash, message in buffer:
       +                server.put(_hash, message)
       +        msg = _('Sending transaction to cosigning pool...')
       +        WaitingDialog(some_window, msg, send_messages_task, on_success, on_failure)
        
            def on_receive(self, keyhash, message):
                self.logger.info(f"signal arrived for {keyhash}")