コード例 #1
0
    def test_config_output(self):
        # importing because it sets up `peewee` logging, which is checked at the test below
        from neo.Implementations.Wallets.peewee.UserWallet import UserWallet

        args = ['output']
        with patch(
                'neo.Prompt.Commands.Config.prompt',
                side_effect=[1, 1, 1, "a", "\n", "\n"]
        ):  # tests changing the level and keeping the current level. Entering "a" has no effect.
            res = CommandConfig().execute(args)
            self.assertTrue(res)
            self.assertEqual(res['generic'], "DEBUG")
            self.assertEqual(res['vm'], "DEBUG")
            self.assertEqual(res['db'], "DEBUG")
            self.assertEqual(res['peewee'], "ERROR")
            self.assertEqual(res['network'], "INFO")
            self.assertEqual(res['network.verbose'], "INFO")

        # test with keyboard interrupt
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.Config.prompt',
                       side_effect=[KeyboardInterrupt]):
                res = CommandConfig().execute(args)
                self.assertFalse(res)
                self.assertIn("Output configuration cancelled",
                              mock_print.getvalue())
コード例 #2
0
    def test_config(self):
        # with no subcommand
        res = CommandConfig().execute(None)
        self.assertFalse(res)

        # with invalid command
        args = ['badcommand']
        res = CommandConfig().execute(args)
        self.assertFalse(res)
コード例 #3
0
    def test_config_node_requests(self):
        # test no input
        args = ['node-requests']
        res = CommandConfig().execute(args)
        self.assertFalse(res)

        # test updating block request size
        # first make sure we have a predictable state
        NodeLeader.Instance().Reset()
        leader = NodeLeader.Instance()
        leader.ADDRS = ["127.0.0.1:20333", "127.0.0.2:20334"]
        leader.DEAD_ADDRS = ["127.0.0.1:20335"]

        # test slow setting
        args = ['node-requests', 'slow']
        res = CommandConfig().execute(args)
        self.assertTrue(res)

        # test normal setting
        args = ['node-requests', 'normal']
        res = CommandConfig().execute(args)
        self.assertTrue(res)

        # test fast setting
        args = ['node-requests', 'fast']
        res = CommandConfig().execute(args)
        self.assertTrue(res)

        # test bad setting
        args = ['node-requests', 'blah']
        res = CommandConfig().execute(args)
        self.assertFalse(res)

        # test custom setting
        args = ['node-requests', '20', '6000']
        res = CommandConfig().execute(args)
        self.assertTrue(res)

        # test bad custom input
        args = ['node-requests', '20', 'blah']
        res = CommandConfig().execute(args)
        self.assertFalse(res)

        # test bad custom setting: breqmax should be greater than breqpart
        args = ['node-requests', '20', '10']
        res = CommandConfig().execute(args)
        self.assertFalse(res)

        # test another bad custom setting: breqpart should not exceed 500
        args = ['node-requests', '600', '5000']
        res = CommandConfig().execute(args)
        self.assertFalse(res)
コード例 #4
0
    def test_config_minpeers(self):
        # test no input and verify output confirming current minpeers
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['minpeers']
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn(
                f"Maintaining minpeers at {settings.CONNECTED_PEER_MIN}",
                mock_print.getvalue())

        # test changing the number of minpeers
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['minpeers', "6"]
            res = CommandConfig().execute(args)
            self.assertTrue(res)
            self.assertEqual(int(res), settings.CONNECTED_PEER_MIN)
            self.assertIn(f"Minpeers set to {settings.CONNECTED_PEER_MIN}",
                          mock_print.getvalue())

        # test bad input
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['minpeers', "blah"]
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn("Please supply a positive integer for minpeers",
                          mock_print.getvalue())

        # test negative number
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['minpeers', "-1"]
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn("Please supply a positive integer for minpeers",
                          mock_print.getvalue())

        # test minpeers greater than maxpeers
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['minpeers', f"{settings.CONNECTED_PEER_MAX + 1}"]
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn(
                "minpeers setting cannot be bigger than maxpeers setting",
                mock_print.getvalue())
コード例 #5
0
    def test_config_vm_log(self):
        # test no input
        args = ['vm-log']
        res = CommandConfig().execute(args)
        self.assertFalse(res)

        # test turning them on
        args = ['vm-log', 'on']
        res = CommandConfig().execute(args)
        self.assertTrue(res)
        self.assertTrue(settings.log_vm_instructions)

        # test turning them off
        args = ['vm-log', '0']
        res = CommandConfig().execute(args)
        self.assertTrue(res)
        self.assertFalse(settings.log_vm_instructions)

        # test bad input
        args = ['vm-log', 'blah']
        res = CommandConfig().execute(args)
        self.assertFalse(res)
コード例 #6
0
    def test_config_debug_notify(self):
        # test no input
        args = ['sc-debug-notify']
        res = CommandConfig().execute(args)
        self.assertFalse(res)

        # test turning them on
        args = ['sc-debug-notify', 'on']
        res = CommandConfig().execute(args)
        self.assertTrue(res)
        self.assertTrue(settings.emit_notify_events_on_sc_execution_error)

        # test turning them off
        args = ['sc-debug-notify', '0']
        res = CommandConfig().execute(args)
        self.assertTrue(res)
        self.assertFalse(settings.emit_notify_events_on_sc_execution_error)

        # test bad input
        args = ['sc-debug-notify', 'blah']
        res = CommandConfig().execute(args)
        self.assertFalse(res)
コード例 #7
0
    def test_config_sc_events(self):
        # test no input
        args = ['sc-events']
        res = CommandConfig().execute(args)
        self.assertFalse(res)

        # test turning them on
        args = ['sc-events', 'on']
        res = CommandConfig().execute(args)
        self.assertTrue(res)
        self.assertTrue(settings.log_smart_contract_events)

        # test turning them off
        args = ['sc-events', '0']
        res = CommandConfig().execute(args)
        self.assertTrue(res)
        self.assertFalse(settings.log_smart_contract_events)

        # test bad input
        args = ['sc-events', 'blah']
        res = CommandConfig().execute(args)
        self.assertFalse(res)
コード例 #8
0
    def test_config_output(self):
        # importing because it sets up `peewee` logging, which is checked at the test below
        from neo.Implementations.Wallets.peewee.UserWallet import UserWallet

        args = ['output']
        with patch('neo.Prompt.Commands.Config.prompt', side_effect=[1, 1, 1, "\n", "\n", "\n"]):  # tests changing the level and keeping the current level
            res = CommandConfig().execute(args)
            self.assertTrue(res)
            self.assertEqual(res['generic'], "DEBUG")
            self.assertEqual(res['vm'], "DEBUG")
            self.assertEqual(res['db'], "DEBUG")
            self.assertEqual(res['peewee'], "ERROR")
            self.assertEqual(res['network'], "INFO")
            self.assertEqual(res['network.verbose'], "INFO")
コード例 #9
0
    def test_config_maxpeers(self):
        # test no input and verify output confirming current maxpeers
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers']
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn(f"Maintaining maxpeers at {settings.CONNECTED_PEER_MAX}", mock_print.getvalue())

        # test changing the number of maxpeers
        args = ['maxpeers', "6"]
        res = CommandConfig().execute(args)
        self.assertTrue(res)
        self.assertEqual(int(res), settings.CONNECTED_PEER_MAX)

        # test bad input
        args = ['maxpeers', "blah"]
        res = CommandConfig().execute(args)
        self.assertFalse(res)

        # test negative number
        args = ['maxpeers', "-1"]
        res = CommandConfig().execute(args)
        self.assertFalse(res)
コード例 #10
0
    def test_config_nep8(self):
        # test with missing flag argument
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['nep8']
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn("Please specify the required parameter",
                          mock_print.getvalue())

        # test with invalid option
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['nep8', 'blah']
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn("Invalid option", mock_print.getvalue())

        # ideally for the next tests we should compile some SC and validate if NEP-8 instructions are used or not
        # for now the effort required to do so does not seem justified and we'll just rely on applying the setting

        # test turning on - 1
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['nep8', 'on']
            res = CommandConfig().execute(args)
            self.assertTrue(res)
            self.assertIn("NEP-8 compiler instruction usage is ON",
                          mock_print.getvalue())

        # test turning on - 2
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['nep8', '1']
            res = CommandConfig().execute(args)
            self.assertTrue(res)
            self.assertIn("NEP-8 compiler instruction usage is ON",
                          mock_print.getvalue())

        # test turning off - 1
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['nep8', 'off']
            res = CommandConfig().execute(args)
            self.assertTrue(res)
            self.assertIn("NEP-8 compiler instruction usage is OFF",
                          mock_print.getvalue())

        # test turning off - 2
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['nep8', '0']
            res = CommandConfig().execute(args)
            self.assertTrue(res)
            self.assertIn("NEP-8 compiler instruction usage is OFF",
                          mock_print.getvalue())
コード例 #11
0
class PromptInterface:
    prompt_completer = None
    history = None

    go_on = True

    wallet_loop_deferred = None

    Wallet = None

    _known_things = []

    _commands = [
        CommandWallet(),
        CommandShow(),
        CommandSearch(),
        CommandConfig(),
        CommandSC()
    ]

    _command_descs = [
        desc for c in _commands
        for desc in c.command_descs_with_sub_commands()
    ]

    commands = {
        command.command_desc().command: command
        for command in _commands
    }

    start_height = None
    start_dt = None

    def __init__(self, history_filename=None):
        PromptData.Prompt = self
        if history_filename:
            PromptInterface.history = PromptFileHistory(history_filename)

        self.input_parser = InputParser()
        self.start_height = Blockchain.Default().Height
        self.start_dt = datetime.datetime.utcnow()

    def get_bottom_toolbar(self, cli=None):
        out = []
        try:
            return "[%s] Progress: %s/%s" % (
                settings.net_name, str(Blockchain.Default().Height),
                str(Blockchain.Default().HeaderHeight))
        except Exception as e:
            pass

        return out

    def get_completer(self):
        standard_completions = list({
            word
            for d in self._command_descs for word in d.command.split()
        })  # Use a set to ensure unicity of words
        standard_completions += ['quit', 'help', 'exit']

        if PromptData.Wallet:
            for addr in PromptData.Wallet.Addresses:
                if addr not in self._known_things:
                    self._known_things.append(addr)
            for alias in PromptData.Wallet.NamedAddr:
                if alias.Title not in self._known_things:
                    self._known_things.append(alias.Title)
            for tkn in PromptData.Wallet.GetTokens().values():
                if tkn.symbol not in self._known_things:
                    self._known_things.append(tkn.symbol)

        all_completions = standard_completions + self._known_things

        PromptInterface.prompt_completer = WordCompleter(all_completions)

        return PromptInterface.prompt_completer

    def quit(self):
        print('Shutting down. This may take a bit...')
        self.go_on = False
        PromptData.close_wallet()
        Blockchain.Default().Dispose()
        NodeLeader.Instance().Shutdown()
        reactor.stop()

    def help(self):
        prompt_print(f"\nCommands:")
        for command_group in sorted(self.commands.keys()):
            command = self.commands[command_group]
            prompt_print(
                f"   {command_group:<15} - {command.command_desc().short_help}"
            )
        prompt_print(
            f"\nRun 'COMMAND help' for more information on a command.")

    def start_wallet_loop(self):
        if self.wallet_loop_deferred:
            self.stop_wallet_loop()
        self.walletdb_loop = task.LoopingCall(PromptData.Wallet.ProcessBlocks)
        self.wallet_loop_deferred = self.walletdb_loop.start(1)
        self.wallet_loop_deferred.addErrback(self.on_looperror)

    def stop_wallet_loop(self):
        self.wallet_loop_deferred.cancel()
        self.wallet_loop_deferred = None
        if self.walletdb_loop and self.walletdb_loop.running:
            self.walletdb_loop.stop()

    def on_looperror(self, err):
        logger.debug("On DB loop error! %s " % err)

    def run(self):
        dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
        dbloop_deferred = dbloop.start(.1)
        dbloop_deferred.addErrback(self.on_looperror)

        tokens = [("class:neo", 'NEO'), ("class:default", ' cli. Type '),
                  ("class:command", '\'help\' '),
                  ("class:default", 'to get started')]

        print_formatted_text(FormattedText(tokens), style=token_style)

        print('\n')

        while self.go_on:

            session = PromptSession(
                "neo> ",
                completer=self.get_completer(),
                history=self.history,
                bottom_toolbar=self.get_bottom_toolbar,
                style=token_style,
                refresh_interval=3,
            )

            try:
                result = session.prompt()
            except EOFError:
                # Control-D pressed: quit
                return self.quit()
            except KeyboardInterrupt:
                # Control-C pressed: do nothing
                continue
            except Exception as e:
                logger.error("Exception handling input: %s " % e)

            try:
                command, arguments = self.input_parser.parse_input(result)

                if command is not None and len(command) > 0:
                    command = command.lower()

                    if command in self.commands:
                        cmd = self.commands[command]

                        if len(arguments) > 0 and arguments[-1] == 'help':
                            cmd.handle_help(arguments)
                        else:
                            cmd.execute(arguments)
                    else:
                        if command == 'quit' or command == 'exit':
                            self.quit()
                        elif command == 'help':
                            self.help()
                        elif command is None:
                            print("Please specify a command")
                        else:
                            print("Command '%s' not found" % command)

            except Exception as e:

                print("Could not execute command: %s" % e)
                traceback.print_stack()
                traceback.print_exc()
コード例 #12
0
    def test_config_maxpeers(self):
        # test no input and verify output confirming current maxpeers
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers']
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn(
                f"Maintaining maxpeers at {settings.CONNECTED_PEER_MAX}",
                mock_print.getvalue())

        # test changing the number of maxpeers
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers', "6"]
            res = CommandConfig().execute(args)
            self.assertTrue(res)
            self.assertEqual(int(res), settings.CONNECTED_PEER_MAX)
            self.assertIn(f"Maxpeers set to {settings.CONNECTED_PEER_MAX}",
                          mock_print.getvalue())

        # test bad input
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers', "blah"]
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn("Please supply a positive integer for maxpeers",
                          mock_print.getvalue())

        # test negative number
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers', "-1"]
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn("Please supply a positive integer for maxpeers",
                          mock_print.getvalue())

        # test if the new maxpeers < settings.CONNECTED_PEER_MAX
        # first make sure we have a predictable state
        NodeLeader.Instance().Reset()
        leader = NodeLeader.Instance()
        addr1 = Address("127.0.0.1:20333")
        addr2 = Address("127.0.0.1:20334")
        leader.ADDRS = [addr1, addr2]
        leader.DEAD_ADDRS = [Address("127.0.0.1:20335")]
        test_node = NeoNode()
        test_node.host = "127.0.0.1"
        test_node.port = 20333
        test_node.address = Address("127.0.0.1:20333")
        test_node2 = NeoNode()
        test_node2.host = "127.0.0.1"
        test_node2.port = 20333
        test_node2.address = Address("127.0.0.1:20334")
        leader.Peers = [test_node, test_node2]

        with patch(
                "neo.Network.NeoNode.NeoNode.Disconnect") as mock_disconnect:
            # first test if the number of connected peers !< new maxpeers
            with patch('sys.stdout', new=StringIO()) as mock_print:
                args = ['maxpeers', "4"]
                res = CommandConfig().execute(args)
                self.assertTrue(res)
                self.assertEqual(len(leader.Peers), 2)
                self.assertFalse(mock_disconnect.called)
                self.assertIn(f"Maxpeers set to {settings.CONNECTED_PEER_MAX}",
                              mock_print.getvalue())

            # now test if the number of connected peers < new maxpeers
            with patch('sys.stdout', new=StringIO()) as mock_print:
                args = ['maxpeers', "1"]
                res = CommandConfig().execute(args)
                self.assertTrue(res)
                self.assertEqual(len(leader.Peers), 1)
                self.assertEqual(leader.Peers[0].address, test_node.address)
                self.assertTrue(mock_disconnect.called)
                self.assertIn(f"Maxpeers set to {settings.CONNECTED_PEER_MAX}",
                              mock_print.getvalue())
コード例 #13
0
    def test_config_maxpeers(self):
        nodemgr = NodeManager()
        nodemgr.reset_for_test()

        # test no input and verify output confirming current maxpeers
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers']
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertEqual(settings.CONNECTED_PEER_MAX, 10)
            self.assertIn(
                f"Maintaining maxpeers at {settings.CONNECTED_PEER_MAX}",
                mock_print.getvalue())

        # test changing the number of maxpeers
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers', "6"]
            res = CommandConfig().execute(args)
            self.assertTrue(res)
            self.assertEqual(settings.CONNECTED_PEER_MAX, 6)
            self.assertEqual(int(res), settings.CONNECTED_PEER_MAX)
            self.assertIn(f"Maxpeers set to {settings.CONNECTED_PEER_MAX}",
                          mock_print.getvalue())

        # test trying to set maxpeers > 10
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers', "12"]
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn("Max peers is limited to 10", mock_print.getvalue())

        # test bad input
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers', "blah"]
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn("Invalid argument", mock_print.getvalue())

        # test negative number
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['maxpeers', "-1"]
            res = CommandConfig().execute(args)
            self.assertFalse(res)
            self.assertIn("Please supply a positive integer for maxpeers",
                          mock_print.getvalue())

        # test if the new maxpeers < settings.CONNECTED_PEER_MAX
        # first make sure we have a predictable state
        node1 = NeoNode(object, object)
        node2 = NeoNode(object, object)
        node1.address = "127.0.0.1:20333"
        node2.address = "127.0.0.1:20334"

        nodemgr.nodes = [node1, node2]
        nodemgr.loop = object

        with patch("neo.Network.node.NeoNode.disconnect") as mock_disconnect:
            # first test if the number of connected peers !< new maxpeers
            self.assertEqual(nodemgr.max_clients,
                             6)  # verifying the current number of maxpeers
            with patch('sys.stdout', new=StringIO()) as mock_print:
                args = ['maxpeers', "4"]
                res = CommandConfig().execute(args)
                self.assertTrue(res)
                self.assertEqual(nodemgr.max_clients, 4)
                self.assertFalse(mock_disconnect.called)
                self.assertEqual(settings.CONNECTED_PEER_MAX, 4)
                self.assertIn(f"Maxpeers set to {settings.CONNECTED_PEER_MAX}",
                              mock_print.getvalue())

            # now test if the number of connected peers < new maxpeers and < current minpeers
            self.assertEqual(settings.CONNECTED_PEER_MIN,
                             4)  # verifying the current minpeers value
            with patch('sys.stdout', new=StringIO()) as mock_print:
                with patch('neo.Prompt.Commands.Config.wait_for'):
                    args = ['maxpeers', "1"]
                    res = CommandConfig().execute(args)
                    self.assertTrue(res)
                    self.assertEqual(nodemgr.max_clients, 1)
                    self.assertTrue(mock_disconnect.called)
                    self.assertEqual(settings.CONNECTED_PEER_MAX, 1)
                    self.assertIn(
                        f"Maxpeers set to {settings.CONNECTED_PEER_MAX}",
                        mock_print.getvalue())

                    self.assertEqual(settings.CONNECTED_PEER_MIN, 1)
                    self.assertIn(
                        f"Minpeers set to {settings.CONNECTED_PEER_MIN}",
                        mock_print.getvalue())

        # reset for future tests
        nodemgr.reset_for_test()
        nodemgr.loop = None
        settings.set_max_peers(10)
コード例 #14
0
class PromptInterface:
    prompt_completer = None
    history = None

    go_on = True

    wallet_loop_deferred = None

    Wallet = None

    _known_things = []

    _commands = [
        CommandWallet(),
        CommandShow(),
        CommandSearch(),
        CommandConfig(),
        CommandSC()
    ]

    _command_descs = [
        desc for c in _commands
        for desc in c.command_descs_with_sub_commands()
    ]

    commands = {
        command.command_desc().command: command
        for command in _commands
    }

    start_height = None
    start_dt = None

    prompt_session = None

    def __init__(self, history_filename=None):
        PromptData.Prompt = self
        if history_filename:
            PromptInterface.history = PromptFileHistory(history_filename)

        self.input_parser = InputParser()
        self.start_height = Blockchain.Default().Height
        self.start_dt = datetime.datetime.utcnow()

    def get_bottom_toolbar(self, cli=None):
        out = []
        try:
            if PromptData.Wallet is None:
                return "[%s] Progress: 0/%s/%s" % (
                    settings.net_name, str(Blockchain.Default().Height),
                    str(Blockchain.Default().HeaderHeight))
            else:
                return "[%s] Progress: %s/%s/%s" % (
                    settings.net_name, str(PromptData.Wallet._current_height),
                    str(Blockchain.Default().Height),
                    str(Blockchain.Default().HeaderHeight))
        except Exception as e:
            pass

        return out

    def get_completer(self):
        standard_completions = list({
            word
            for d in self._command_descs for word in d.command.split()
        })  # Use a set to ensure unicity of words
        standard_completions += ['quit', 'help', 'exit']

        if PromptData.Wallet:
            for addr in PromptData.Wallet.Addresses:
                if addr not in self._known_things:
                    self._known_things.append(addr)
            for alias in PromptData.Wallet.NamedAddr:
                if alias.Title not in self._known_things:
                    self._known_things.append(alias.Title)
            for tkn in PromptData.Wallet.GetTokens().values():
                if tkn.symbol not in self._known_things:
                    self._known_things.append(tkn.symbol)

        all_completions = standard_completions + self._known_things

        PromptInterface.prompt_completer = WordCompleter(all_completions)

        return PromptInterface.prompt_completer

    def quit(self):
        print('Shutting down. This may take a bit...')
        self.go_on = False
        PromptData.close_wallet()
        raise SystemExit

    def help(self):
        prompt_print(f"\nCommands:")
        for command_group in sorted(self.commands.keys()):
            command = self.commands[command_group]
            prompt_print(
                f"   {command_group:<15} - {command.command_desc().short_help}"
            )
        prompt_print(
            f"\nRun 'COMMAND help' for more information on a command.")

    def on_looperror(self, err):
        logger.debug("On DB loop error! %s " % err)

    async def run(self):
        nodemgr = NodeManager()
        while not nodemgr.running:
            await asyncio.sleep(0.1)

        tokens = [("class:neo", 'NEO'), ("class:default", ' cli. Type '),
                  ("class:command", '\'help\' '),
                  ("class:default", 'to get started')]

        print_formatted_text(FormattedText(tokens), style=token_style)

        print('\n')

        session = PromptSession(
            "neo> ",
            completer=self.get_completer(),
            history=self.history,
            bottom_toolbar=self.get_bottom_toolbar,
            style=token_style,
            refresh_interval=3,
        )
        self.prompt_session = session
        result = ""

        while self.go_on:
            # with patch_stdout():
            try:
                result = await session.prompt(async_=True)
            except EOFError:
                # Control-D pressed: quit
                return self.quit()
            except KeyboardInterrupt:
                # Control-C pressed: pause for user input

                # temporarily mute stdout during user input
                # components like `network` set at DEBUG level will spam through the console
                # making it impractical to input user data
                log_manager.mute_stdio()

                print('Logging output muted during user input...')
                try:
                    result = await session.prompt(async_=True)
                except Exception as e:
                    logger.error("Exception handling input: %s " % e)

                # and re-enable stdio
                log_manager.unmute_stdio()
            except Exception as e:
                logger.error("Exception handling input: %s " % e)

            try:
                command, arguments = self.input_parser.parse_input(result)

                if command is not None and len(command) > 0:
                    command = command.lower()

                    if command in self.commands:
                        cmd = self.commands[command]

                        if len(arguments) > 0 and arguments[-1] == 'help':
                            cmd.handle_help(arguments)
                        else:
                            cmd.execute(arguments)
                    else:
                        if command == 'quit' or command == 'exit':
                            self.quit()
                        elif command == 'help':
                            self.help()
                        elif command is None:
                            print("Please specify a command")
                        else:
                            print("Command '%s' not found" % command)

            except Exception as e:

                print("Could not execute command: %s" % e)
                traceback.print_stack()
                traceback.print_exc()