# Buggy code
def start(  # type: ignore
    self,
    raiden_service: "RaidenService",
    whitelist: List[Address],
    prev_auth_data: Optional[str],
) -> None:
    if not self._stop_event.ready():
        raise RuntimeError(f"{self!r} already started")
    self.log.debug("Matrix starting")
    self._stop_event.clear()
    self._starting = True
    self._raiden_service = raiden_service

    self._address_mgr.start()

    try:
        login(
            client=self._client,
            signer=self._raiden_service.signer,
            prev_auth_data=prev_auth_data,
        )
    except ValueError:
        # `ValueError` may be raised if `get_user` provides invalid data to
        # the `User` constructor. This is either a bug in the login, that
        # tries to get the user after a failed login, or a bug in the
        # Matrix SDK.
        raise RaidenUnrecoverableError("Matrix SDK failed to properly set the userid")
    except MatrixHttpLibError:
        raise RaidenUnrecoverableError("The Matrix homeserver seems to be unavailable.")

    self.log = log.bind(
        current_user=self._user_id,
        node=to_checksum_address(self._raiden_service.address),
        transport_uuid=str(self._uuid),
    )

    self._initialize_first_sync()
    self._initialize_broadcast_rooms()
    self._initialize_inventory_rooms()

    def on_success(greenlet: gevent.Greenlet) -> None:
        if greenlet in self.greenlets:
            self.greenlets.remove(greenlet)

    self._client.start_listener_thread()
    assert isinstance(self._client.sync_thread, gevent.Greenlet)
    self._client.sync_thread.link_exception(self.on_error)
    self._client.sync_thread.link_value(on_success)
    self.greenlets = [self._client.sync_thread]

    self._client.set_presence_state(UserPresence.ONLINE.value)

    # (re)start any _RetryQueue which was initialized before start
    for retrier in self._address_to_retrier.values():
        if not retrier:
            self.log.debug("Starting retrier", retrier=retrier)
            retrier.start()

    super().start()  # start greenlet
    self._starting = False
    self._started = True

    pool = Pool(size=10)
    greenlets = set(
        pool.apply_async(self.whitelist, [address]) for address in whitelist
    )
    gevent.joinall(greenlets, raise_error=True)

    self.log.debug("Matrix started", config=self._config)

    # Handle any delayed invites in the future
    self._schedule_new_greenlet(self._process_queued_invites, in_seconds_from_now=1)


# Traceback (nurllib3.exceptions.ProtocolError)
{
"task": "<TransferTask: {'from': 0, 'to': 1, 'amount': 500000000000000000, 'expected_http_status': 200}>",
"event": "Task errored",
"logger": "scenario_player.tasks.base",
"level": "error",
"timestamp": "2019-11-12 01:58:24.322286",
"exception": "Traceback (most recent call last):\n  File \"/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py\", line 603, in urlopen\n    chunked=chunked)\n  File \"/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py\", line 387, in _make_request\n    six.raise_from(e, None)\n  File \"<string>\", line 2, in raise_from\n  File \"/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py\", line 383, in _make_request\n    httplib_response = conn.getresponse()\n  File \"/usr/local/lib/python3.7/http/client.py\", line 1321, in getresponse\n    response.begin()\n  File \"/usr/local/lib/python3.7/http/client.py\", line 296, in begin\n    version, status, reason = self._read_status()\n  File \"/usr/local/lib/python3.7/http/client.py\", line 265, in _read_status\n    raise RemoteDisconnected(\"Remote end closed connection without\"\nhttp.client.RemoteDisconnected: Remote end closed connection without response\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/usr/local/lib/python3.7/site-packages/requests/adapters.py\", line 449, in send\n    timeout=timeout\n  File \"/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py\", line 641, in urlopen\n    _stacktrace=sys.exc_info()[2])\n  File \"/usr/local/lib/python3.7/site-packages/urllib3/util/retry.py\", line 368, in increment\n    raise six.reraise(type(error), error, _stacktrace)\n  File \"/usr/local/lib/python3.7/site-packages/urllib3/packages/six.py\", line 685, in reraise\n    raise value.with_traceback(tb)\n  File \"/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py\", line 603, in urlopen\n    chunked=chunked)\n  File \"/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py\", line 387, in _make_request\n    six.raise_from(e, None)\n  File \"<string>\", line 2, in raise_from\n  File \"/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py\", line 383, in _make_request\n    httplib_response = conn.getresponse()\n  File \"/usr/local/lib/python3.7/http/client.py\", line 1321, in getresponse\n    response.begin()\n  File \"/usr/local/lib/python3.7/http/client.py\", line 296, in begin\n    version, status, reason = self._read_status()\n  File \"/usr/local/lib/python3.7/http/client.py\", line 265, in _read_status\n    raise RemoteDisconnected(\"Remote end closed connection without\"\nurllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/usr/local/lib/python3.7/site-packages/scenario_player/tasks/api_base.py\", line 51, in _run\n    method=self._method, url=url, json=self._request_params, timeout=self._timeout\n  File \"/usr/local/lib/python3.7/site-packages/requests/sessions.py\", line 533, in request\n    resp = self.send(prep, **send_kwargs)\n  File \"/usr/local/lib/python3.7/site-packages/requests/sessions.py\", line 646, in send\n    r = adapter.send(request, **kwargs)\n  File \"/usr/local/lib/python3.7/site-packages/requests/adapters.py\", line 498, in send\n    raise ConnectionError(err, request=request)\nrequests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n  File \"/usr/local/lib/python3.7/site-packages/scenario_player/tasks/base.py\", line 74, in __call__\n    return self._run(*args, **kwargs)\n  File \"/usr/local/lib/python3.7/site-packages/scenario_player/tasks/api_base.py\", line 56, in _run\n    raise RESTAPIError(f\"Error performing REST-API call: {self._name}\") from ex\nscenario_player.exceptions.legacy.RESTAPIError: Error performing REST-API call: transfer"
}

# Fixed code
def start(  # type: ignore
    self,
    raiden_service: "RaidenService",
    whitelist: List[Address],
    prev_auth_data: Optional[str],
) -> None:
    if not self._stop_event.ready():
        raise RuntimeError(f"{self!r} already started")
    self.log.debug("Matrix starting")
    self._stop_event.clear()
    self._starting = True
    self._raiden_service = raiden_service

    self._address_mgr.start()

    try:
        login(
            client=self._client,
            signer=self._raiden_service.signer,
            prev_auth_data=prev_auth_data,
        )
    except ValueError:
        # `ValueError` may be raised if `get_user` provides invalid data to
        # the `User` constructor. This is either a bug in the login, that
        # tries to get the user after a failed login, or a bug in the
        # Matrix SDK.
        raise RaidenUnrecoverableError("Matrix SDK failed to properly set the userid")
    except MatrixHttpLibError:
        raise RaidenUnrecoverableError("The Matrix homeserver seems to be unavailable.")

    self.log = log.bind(
        current_user=self._user_id,
        node=to_checksum_address(self._raiden_service.address),
        transport_uuid=str(self._uuid),
    )

    self._initialize_first_sync()
    self._initialize_broadcast_rooms()
    self._initialize_room_inventory()

    def on_success(greenlet: gevent.Greenlet) -> None:
        if greenlet in self.greenlets:
            self.greenlets.remove(greenlet)

    self._client.start_listener_thread()
    assert isinstance(self._client.sync_thread, gevent.Greenlet)
    self._client.sync_thread.link_exception(self.on_error)
    self._client.sync_thread.link_value(on_success)
    self.greenlets = [self._client.sync_thread]

    self._client.set_presence_state(UserPresence.ONLINE.value)

    # (re)start any _RetryQueue which was initialized before start
    for retrier in self._address_to_retrier.values():
        if not retrier:
            self.log.debug("Starting retrier", retrier=retrier)
            retrier.start()

    super().start()  # start greenlet
    self._starting = False
    self._started = True

    pool = Pool(size=10)
    greenlets = set(
        pool.apply_async(self.whitelist, [address]) for address in whitelist
    )
    gevent.joinall(greenlets, raise_error=True)

    self.log.debug("Matrix started", config=self._config)

    # Handle any delayed invites in the future
    self._schedule_new_greenlet(self._process_queued_invites, in_seconds_from_now=1)