# Buggy code
def start(self):
    """
    Start a Tribler session by initializing the LaunchManyCore class, opening the database and running the upgrader.
    Returns a deferred that fires when the Tribler session is ready for use.
    """
    # Start the REST API before the upgrader since we want to send interesting upgrader events over the socket
    if self.config.get_http_api_enabled():
        self.lm.api_manager = RESTManager(self)
        self.readable_status = STATE_START_API
        self.lm.api_manager.start()

    if self.upgrader_enabled:
        self.upgrader = TriblerUpgrader(self)
        self.readable_status = STATE_UPGRADING_READABLE
        upgrader_deferred = self.upgrader.run()
    else:
        upgrader_deferred = succeed(None)

    def after_upgrade(_):
        self.upgrader = None

    def log_upgrader_error(failure):
        self._logger.error("Error in Upgrader callback chain: %s", failure)

    def on_tribler_started(_):
        self.notifier.notify(NTFY_TRIBLER, NTFY_STARTED, None)

    startup_deferred = (
        upgrader_deferred.addCallbacks(
            lambda _: self.lm.register(self, self.session_lock), log_upgrader_error
        )
        .addCallbacks(after_upgrade, log_upgrader_error)
        .addCallback(on_tribler_started)
    )

    def load_checkpoint(_):
        if self.config.get_libtorrent_enabled():
            self.readable_status = STATE_LOAD_CHECKPOINTS
            self.load_checkpoint()
        self.readable_status = STATE_READABLE_STARTED

    def start_gigachannel_manager(_):
        # GigaChannel Manager should be started *after* resuming the downloads,
        # because it depends on the states of torrent downloads
        # TODO: move GigaChannel torrents into a separate session
        if self.lm.gigachannel_manager:
            self.lm.gigachannel_manager.start()

    def start_bootstrap_download(_):
        if not self.lm.bootstrap:
            self.lm.start_bootstrap_download()

    return (
        startup_deferred.addCallback(load_checkpoint)
        .addCallback(start_gigachannel_manager)
        .addCallback(start_bootstrap_download)
    )


# Traceback (ValueError)
ERROR   1576450617.34                 community:695  (TriblerTunnelCommunity)  Exception occurred while handling packet!
Traceback (most recent call last):
File "/home/tribler/tribler/Tribler/pyipv8/ipv8/messaging/anonymization/community.py", line 692, in on_packet_from_circuit
self.decode_map_private[msg_id](source_address, data, circuit_id)
File "/home/tribler/tribler/Tribler/pyipv8/ipv8/messaging/anonymization/community.py", line 76, in wrapper
return inner_wrapper(self, source_address, data)
File "/home/tribler/tribler/Tribler/pyipv8/ipv8/lazy_community.py", line 104, in wrapper
return func(self, source_address, *unpacked)
File "/home/tribler/tribler/Tribler/pyipv8/ipv8/messaging/anonymization/community.py", line 74, in inner_wrapper
return func(inner_self, inner_source_address, *combo)
File "/home/tribler/tribler/Tribler/pyipv8/ipv8/messaging/anonymization/community.py", line 774, in on_created
self._ours_on_created_extended(circuit, payload)
File "/home/tribler/tribler/Tribler/community/triblertunnel/community.py", line 447, in _ours_on_created_extended
super(TriblerTunnelCommunity, self)._ours_on_created_extended(circuit, payload)
File "/home/tribler/tribler/Tribler/pyipv8/ipv8/messaging/anonymization/community.py", line 551, in _ours_on_created_extended
payload.auth, hop.public_key.key.pk)
File "/home/tribler/tribler/Tribler/pyipv8/ipv8/messaging/anonymization/tunnelcrypto.py", line 51, in verify_and_generate_shared_secret
libnacl.crypto_auth_verify(auth, dh_received, shared_secret)
File "/home/tribler/.local/lib/python3.7/site-packages/libnacl/__init__.py", line 887, in crypto_auth_verify
raise ValueError('Invalid secret key')
ValueError: Invalid secret key

# Fixed code
def start(self):
    """
    Start a Tribler session by initializing the LaunchManyCore class, opening the database and running the upgrader.
    Returns a deferred that fires when the Tribler session is ready for use.
    """
    # Start the REST API before the upgrader since we want to send interesting upgrader events over the socket
    if self.config.get_http_api_enabled():
        self.lm.api_manager = RESTManager(self)
        self.readable_status = STATE_START_API
        self.lm.api_manager.start()

    if self.upgrader_enabled:
        self.upgrader = TriblerUpgrader(self)
        self.readable_status = STATE_UPGRADING_READABLE
        upgrader_deferred = self.upgrader.run()
    else:
        upgrader_deferred = succeed(None)

    def after_upgrade(_):
        self.upgrader = None

    def log_upgrader_error(failure):
        self._logger.error("Error in Upgrader callback chain: %s", failure)

    def on_tribler_started(_):
        self.notifier.notify(NTFY_TRIBLER, NTFY_STARTED, None)

    startup_deferred = (
        upgrader_deferred.addCallbacks(after_upgrade, log_upgrader_error)
        .addCallbacks(
            lambda _: self.lm.register(self, self.session_lock), log_upgrader_error
        )
        .addCallback(on_tribler_started)
    )

    def load_checkpoint(_):
        if self.config.get_libtorrent_enabled():
            self.readable_status = STATE_LOAD_CHECKPOINTS
            self.load_checkpoint()
        self.readable_status = STATE_READABLE_STARTED

    def start_gigachannel_manager(_):
        # GigaChannel Manager should be started *after* resuming the downloads,
        # because it depends on the states of torrent downloads
        # TODO: move GigaChannel torrents into a separate session
        if self.lm.gigachannel_manager:
            self.lm.gigachannel_manager.start()

    def start_bootstrap_download(_):
        if not self.lm.bootstrap:
            self.lm.start_bootstrap_download()

    return (
        startup_deferred.addCallback(load_checkpoint)
        .addCallback(start_gigachannel_manager)
        .addCallback(start_bootstrap_download)
    )