Beispiel #1
0
    def test_sc_build(self):
        warnings.filterwarnings(
            'ignore',
            category=ResourceWarning)  # filters warnings about unclosed files
        # test no input
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['build']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please specify the required parameter",
                          mock_print.getvalue())

        # test bad path
        args = ['build', 'SampleSC.py']
        res = CommandSC().execute(args)
        self.assertFalse(res)

        # test successful compilation
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['build', 'neo/Prompt/Commands/tests/SampleSC.py']
            res = CommandSC().execute(args)
            self.assertTrue(res)
            self.assertIn(
                "Saved output to neo/Prompt/Commands/tests/SampleSC.avm",
                mock_print.getvalue())
    def test_sc_debugstorage(self):
        # test with insufficient parameters
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['debugstorage']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please specify the required parameter", mock_print.getvalue())

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

        # test with reset parameter
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['debugstorage', 'reset']
            res = CommandSC().execute(args)
            self.assertTrue(res)
            self.assertIn("Reset debug storage", mock_print.getvalue())

        # test turning on
        args = ['debugstorage', 'on']
        res = CommandSC().execute(args)
        self.assertTrue(res)
        self.assertTrue(settings.USE_DEBUG_STORAGE)

        # test turning off
        args = ['debugstorage', 'off']
        res = CommandSC().execute(args)
        self.assertTrue(res)
        self.assertFalse(settings.USE_DEBUG_STORAGE)
    def test_sc(self):
        # with no subcommand
        with patch('sys.stdout', new=StringIO()) as mock_print:
            res = CommandSC().execute(None)
            self.assertFalse(res)
            self.assertIn("run `sc help` to see supported queries", mock_print.getvalue())

        # with invalid command
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['badcommand']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("badcommand is an invalid parameter", mock_print.getvalue())
    def test_sc_loadrun(self):
        warnings.filterwarnings('ignore', category=ResourceWarning)  # filters warnings about unclosed files
        # test no input
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['load_run']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please specify the required parameters", mock_print.getvalue())

        # test bad path
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['load_run', 'neo/Prompt/Commands/tests/SampleSC.py', 'True', 'False', 'False', '070502', '02', '--i']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("run `sc load_run help` to see supported queries", mock_print.getvalue())

        # build the .avm file
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['build', 'neo/Prompt/Commands/tests/SampleSC.py']
            res = CommandSC().execute(args)
            self.assertTrue(res)
            self.assertIn("Saved output to neo/Prompt/Commands/tests/SampleSC.avm", mock_print.getvalue())

        # test no open wallet
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['load_run', 'neo/Prompt/Commands/tests/SampleSC.avm', 'True', 'False', 'False', '070502', '02',
                    'add' 'AG4GfwjnvydAZodm4xEDivguCtjCFzLcJy' '3']
            tx, result, total_ops, engine = CommandSC().execute(args)
            self.assertEqual(tx, None)
            self.assertEqual(result, None)
            self.assertEqual(total_ops, None)
            self.assertEqual(engine, None)
            self.assertIn("Please open a wallet to test build contract", mock_print.getvalue())

        # test bad args
        PromptData.Wallet = self.GetWallet1(recreate=True)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['load_run', 'neo/Prompt/Commands/tests/SampleSC.avm', 'True', 'False', '070502', '02', 'balance', 'AG4GfwjnvydAZodm4xEDivguCtjCFzLcJy',
                    '0']  # missing payable flag
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("run `sc load_run help` to see supported queries", mock_print.getvalue())

        # test successful load and run with from-addr
        PromptData.Wallet = self.GetWallet1(recreate=True)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['load_run', 'neo/Prompt/Commands/tests/SampleSC.avm', 'True', 'False', 'False', '070502', '02', 'balance',
                    'AG4GfwjnvydAZodm4xEDivguCtjCFzLcJy', '0', '--from-addr=' + self.wallet_1_addr]
            tx, result, total_ops, engine = CommandSC().execute(args)
            self.assertTrue(tx)
            self.assertIn("Test deploy invoke successful", mock_print.getvalue())
    def test_sc_invoke(self):
        token_hash_str = '31730cc9a1844891a3bafd1aa929a4142860d8d3'

        # test no open wallet
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['invoke', token_hash_str, 'symbol', '[]']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please open a wallet", mock_print.getvalue())

        PromptData.Wallet = self.GetWallet3(recreate=True)

        # test invalid contract script hash
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['invoke', 'invalid_hash', 'invalid_params']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Invalid script hash", mock_print.getvalue())

        # test invalid parameter count (missing required `contract`)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['invoke', '--from-addr=bla']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please specify the required parameters", mock_print.getvalue())

        # test with an script_hash that cannot be found
        with patch('sys.stdout', new=StringIO()) as mock_print:
            bad_contract = 'a' * 40  # passes basic script_hash length check, but won't find actual contract
            args = ['invoke', bad_contract, 'name', '[]']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Error testing contract invoke", mock_print.getvalue())

        # test ok, but bad passw to send to network
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt', side_effect=["blah"]):
                args = ['invoke', token_hash_str, 'symbol', '[]']
                res = CommandSC().execute(args)
                self.assertFalse(res)
                self.assertIn("Incorrect password", mock_print.getvalue())

        # test ok
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt', side_effect=[self.wallet_3_pass()]):
                args = ['invoke', token_hash_str, 'symbol', '[]']
                res = CommandSC().execute(args)
                # not the best check, but will do for now
                self.assertTrue(res)
    def test_sc_buildrun(self):
        warnings.filterwarnings('ignore', category=ResourceWarning)  # filters warnings about unclosed files
        # test no input
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['build_run']
            tx, result, total_ops, engine = CommandSC().execute(args)
            self.assertFalse(tx)
            self.assertIn("Please specify the required parameters", mock_print.getvalue())

        # test bad path
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['build_run', 'SampleSC.py', 'True', 'False', 'False', '070502', '02', '--i']
            tx, result, total_ops, engine = CommandSC().execute(args)
            self.assertEqual(tx, None)
            self.assertEqual(result, None)
            self.assertEqual(total_ops, None)
            self.assertEqual(engine, None)
            self.assertIn("Please check the path to your Python (.py) file to compile", mock_print.getvalue())

        # test no open wallet
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['build_run', 'neo/Prompt/Commands/tests/SampleSC.py', 'True', 'False', 'False', '070502', '02',
                    'add' 'AG4GfwjnvydAZodm4xEDivguCtjCFzLcJy' '3']
            tx, result, total_ops, engine = CommandSC().execute(args)
            self.assertEqual(tx, None)
            self.assertEqual(result, None)
            self.assertEqual(total_ops, None)
            self.assertEqual(engine, None)
            self.assertIn("Please open a wallet to test build contract", mock_print.getvalue())

        # test bad args
        PromptData.Wallet = self.GetWallet1(recreate=True)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['build_run', 'neo/Prompt/Commands/tests/SampleSC.py', 'True', 'False', '070502', '02', 'add', 'AG4GfwjnvydAZodm4xEDivguCtjCFzLcJy',
                    '3']  # missing payable flag
            tx, result, total_ops, engine = CommandSC().execute(args)
            self.assertFalse(tx)
            self.assertIn("run `sc build_run help` to see supported queries", mock_print.getvalue())

        # test successful build and run
        PromptData.Wallet = self.GetWallet1(recreate=True)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['build_run', 'neo/Prompt/Commands/tests/SampleSC.py', 'True', 'False', 'False', '070502', '02', 'add', 'AG4GfwjnvydAZodm4xEDivguCtjCFzLcJy',
                    '3']
            tx, result, total_ops, engine = CommandSC().execute(args)
            self.assertTrue(tx)
            self.assertEqual(str(result[0]), '3')
            self.assertIn("Test deploy invoke successful", mock_print.getvalue())

        # test successful build and run with prompted input
        # PromptData.Wallet = self.GetWallet1(recreate=True)
        # with patch('sys.stdout', new=StringIO()) as mock_print:
        #     with patch('neo.Prompt.Utils.PromptSession.prompt', side_effect=['remove', 'AG4GfwjnvydAZodm4xEDivguCtjCFzLcJy', '3']):
        #         args = ['build_run', 'neo/Prompt/Commands/tests/SampleSC.py', 'True', 'False', 'False', '070502', '02', '--i']
        #         tx, result, total_ops, engine = CommandSC().execute(args)
        #         self.assertTrue(tx)
        #         self.assertEqual(str(result[0]), '0')
        #         self.assertIn("Test deploy invoke successful", mock_print.getvalue())

        # test invoke failure (SampleSC requires three inputs)
        PromptData.Wallet = self.GetWallet1(recreate=True)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['build_run', 'neo/Prompt/Commands/tests/SampleSC.py', 'True', 'False', 'False', '0705', '02', 'balance',
                    'AG4GfwjnvydAZodm4xEDivguCtjCFzLcJy']
            tx, result, total_ops, engine = CommandSC().execute(args)
            self.assertIsNone(tx)
            self.assertIn("Test invoke failed", mock_print.getvalue())
    def test_sc_deploy(self):
        # test no wallet
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please open a wallet", mock_print.getvalue())

        PromptData.Wallet = self.GetWallet1(recreate=True)

        # test no input
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please specify the required parameters", mock_print.getvalue())

        # test bad path (.py instead of .avm)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy', 'neo/Prompt/Commands/tests/SampleSC.py', 'False', 'False', 'False', '070502', '02']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please load a compiled .avm file", mock_print.getvalue())

        # test with invalid boolean option(s) for contract
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy', path_dir + 'SampleSC.avm', 'Blah', 'False', 'False', '070502', '02']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Invalid boolean option", mock_print.getvalue())

        # test with invalid input parameter type (void)
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '0705ff', '02']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Void is not a valid input parameter type", mock_print.getvalue())

        # with failing to gather contract details
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.GatherContractDetails', side_effect=[(None)]):
                args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02']
                res = CommandSC().execute(args)
                self.assertFalse(res)
                self.assertIn("Failed to generate deploy script", mock_print.getvalue())

        # test ok contract parameter gathering, but bad passw
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)

        prompt_entries = ['test_name', 'test_version', 'test_author', 'test_email', 'test_description', 'False', 'False', 'False', 'bad_pw']
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.prompt', side_effect=['bad_passw']):
                    args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02']
                    res = CommandSC().execute(args)
                    self.assertFalse(res)
                    self.assertTrue(mock_print.getvalue().endswith('Incorrect password\n'))

        # test ok contract parameter gathering, but test_invoke failure
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)

        prompt_entries = ['test_name', 'test_version', 'test_author', 'test_email', 'test_description', 'False', 'False', 'False', 'bad_pw']
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.test_invoke', side_effect=[(None, None, None, None, None)]):
                    args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02']
                    res = CommandSC().execute(args)
                    self.assertFalse(res)
                    self.assertIn("Test invoke failed", mock_print.getvalue())

        # test with ok contract parameter gathering, but bad fee
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.prompt', side_effect=[self.wallet_1_pass()]):
                    args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02', '--fee=0.001!']
                    res = CommandSC().execute(args)
                    self.assertFalse(res)
                    self.assertIn("invalid amount format", mock_print.getvalue())

        # test with ok contract parameter gathering, but negative fee
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.prompt', side_effect=[self.wallet_1_pass()]):
                    args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02', '--fee=-0.001']
                    res = CommandSC().execute(args)
                    self.assertFalse(res)
                    self.assertIn("invalid amount format", mock_print.getvalue())

        # test with ok contract parameter gathering, ok passw, and priority fee (just insufficient funds to deploy)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.prompt', side_effect=[self.wallet_1_pass()]):
                    args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02', '--fee=0.001']
                    res = CommandSC().execute(args)
                    self.assertFalse(res)
                    self.assertIn("Priority Fee (0.001) + Deploy Invoke TX Fee (0.0) = 0.001", mock_print.getvalue())
                    self.assertTrue(mock_print.getvalue().endswith('Insufficient funds\n'))

        # test with ok contract parameter gathering, and tx is too large for low priority (e.g. >1024), just insufficient funds to deploy
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.prompt', side_effect=[self.wallet_1_pass()]):
                    with patch('neo.Core.TX.InvocationTransaction.InvocationTransaction.Size', return_value=1026):  # returns a size of 1026
                        args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02']
                        res = CommandSC().execute(args)
                        self.assertFalse(res)
                        self.assertIn("Deploy Invoke TX Fee: 0.001", mock_print.getvalue())  # notice the required fee is equal to the low priority threshold
                        self.assertTrue(mock_print.getvalue().endswith('Insufficient funds\n'))

        # test with ok contract parameter gathering, but tx size exceeds the size covered by the high priority fee (e.g. >1124), just insufficient funds to deploy
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.prompt', side_effect=[self.wallet_1_pass()]):
                    with patch('neo.Core.TX.InvocationTransaction.InvocationTransaction.Size', return_value=1411):  # returns a size of 1411
                        args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02']
                        res = CommandSC().execute(args)
                        self.assertFalse(res)
                        self.assertIn("Deploy Invoke TX Fee: 0.00387", mock_print.getvalue())  # notice the required fee is now greater than the low priority threshold
                        self.assertTrue(mock_print.getvalue().endswith('Insufficient funds\n'))
Beispiel #8
0
    def test_sc_invoke(self):
        token_hash_str = '31730cc9a1844891a3bafd1aa929a4142860d8d3'

        # test no open wallet
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['invoke', token_hash_str, 'symbol', '[]']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please open a wallet", mock_print.getvalue())

        PromptData.Wallet = self.GetWallet3(recreate=True)

        # test invalid contract script hash
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['invoke', 'invalid_hash', 'invalid_params']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Invalid script hash", mock_print.getvalue())

        # test invalid parameter count (missing required `contract`)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['invoke', '--from-addr=bla']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please specify the required parameters",
                          mock_print.getvalue())

        # test with an script_hash that cannot be found
        with patch('sys.stdout', new=StringIO()) as mock_print:
            bad_contract = 'a' * 40  # passes basic script_hash length check, but won't find actual contract
            args = ['invoke', bad_contract, 'name', '[]']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Error testing contract invoke",
                          mock_print.getvalue())

        # test with keyboard interrupt
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt',
                       side_effect=[KeyboardInterrupt]):
                args = ['invoke', token_hash_str, 'symbol', '[]']
                res = CommandSC().execute(args)
                self.assertFalse(res)
                self.assertIn("Invocation cancelled", mock_print.getvalue())

        # test with negative fee
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt',
                       side_effect=[self.wallet_3_pass()]):
                args = [
                    'invoke', token_hash_str, 'symbol', '[]', '--fee=-0.001'
                ]
                res = CommandSC().execute(args)
                self.assertFalse(res)
                self.assertIn("invalid amount format", mock_print.getvalue())

        # test with weird fee
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt',
                       side_effect=[self.wallet_3_pass()]):
                args = [
                    'invoke', token_hash_str, 'symbol', '[]', '--fee=0.0abc'
                ]
                res = CommandSC().execute(args)
                self.assertFalse(res)
                self.assertIn("invalid amount format", mock_print.getvalue())

        # test ok, but bad passw to send to network
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt', side_effect=["blah"]):
                args = ['invoke', token_hash_str, 'symbol', '[]']
                res = CommandSC().execute(args)
                self.assertFalse(res)
                self.assertIn("Incorrect password", mock_print.getvalue())

        # test with no return-type override
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt',
                       side_effect=[KeyboardInterrupt]):
                args = ['invoke', token_hash_str, 'totalSupply', '[]', '']
                res = CommandSC().execute(args)
                a = mock_print.getvalue()
                self.assertIn("ByteArray", mock_print.getvalue())

        # test with bad return-type override
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt',
                       side_effect=[KeyboardInterrupt]):
                args = [
                    'invoke', token_hash_str, 'totalSupply', '[]',
                    '--return-type=99'
                ]
                res = CommandSC().execute(args)
                self.assertFalse(res)

        # test with hex return-type override
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt',
                       side_effect=[KeyboardInterrupt]):
                args = [
                    'invoke', token_hash_str, 'totalSupply', '[]',
                    '--return-type=02'
                ]
                res = CommandSC().execute(args)
                self.assertIn("Integer", mock_print.getvalue())

        # test with named return-type override
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt',
                       side_effect=[KeyboardInterrupt]):
                args = [
                    'invoke', token_hash_str, 'totalSupply', '[]',
                    '--return-type=Integer'
                ]
                res = CommandSC().execute(args)
                self.assertIn("Integer", mock_print.getvalue())

        # test ok
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.prompt',
                       side_effect=[self.wallet_3_pass()]):
                args = [
                    'invoke', token_hash_str, 'symbol', '[]', '--fee=0.001'
                ]
                res = CommandSC().execute(args)
                # not the best check, but will do for now
                self.assertTrue(res)
                self.assertIn(
                    "Priority Fee (0.001) + Invoke TX Fee (0.0001) = 0.0011",
                    mock_print.getvalue())
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()
    def test_sc_deploy(self):
        # test no wallet
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please open a wallet", mock_print.getvalue())

        PromptData.Wallet = self.GetWallet1(recreate=True)

        # test no input
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please specify the required parameters", mock_print.getvalue())

        # test bad path (.py instead of .avm)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy', 'neo/Prompt/Commands/tests/SampleSC.py', 'False', 'False', 'False', '070502', '02']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Please load a compiled .avm file", mock_print.getvalue())

        # test with invalid boolean option(s) for contract
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy', path_dir + 'SampleSC.avm', 'Blah', 'False', 'False', '070502', '02']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Invalid boolean option", mock_print.getvalue())

        # test with invalid input parameter type (void)
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '0705ff', '02']
            res = CommandSC().execute(args)
            self.assertFalse(res)
            self.assertIn("Void is not a valid input parameter type", mock_print.getvalue())

        # with failing to gather contract details
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.SC.GatherContractDetails', side_effect=[(None)]):
                args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02']
                res = CommandSC().execute(args)
                self.assertFalse(res)
                self.assertIn("Failed to generate deploy script", mock_print.getvalue())

        # test ok contract parameter gathering, but bad passw
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)

        prompt_entries = ['test_name', 'test_version', 'test_author', 'test_email', 'test_description', 'False', 'False', 'False', 'bad_pw']
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.prompt', side_effect=['bad_passw']):
                    args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02']
                    res = CommandSC().execute(args)
                    self.assertFalse(res)
                    self.assertTrue(mock_print.getvalue().endswith('Incorrect password\n'))

        # test ok contract parameter gathering, but test_invoke failure
        path_dir = 'neo/Prompt/Commands/tests/'
        Compiler.instance().load_and_save(path_dir + 'SampleSC.py', use_nep8=False)

        prompt_entries = ['test_name', 'test_version', 'test_author', 'test_email', 'test_description', 'False', 'False', 'False', 'bad_pw']
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.test_invoke', side_effect=[(None, None, None, None, None)]):
                    args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02']
                    res = CommandSC().execute(args)
                    self.assertFalse(res)
                    self.assertIn("Test invoke failed", mock_print.getvalue())

        # test with ok contract parameter gathering and ok passw (just insufficient funds to deploy)
        with patch('sys.stdout', new=StringIO()) as mock_print:
            with patch('neo.Prompt.Commands.LoadSmartContract.prompt', side_effect=prompt_entries):
                with patch('neo.Prompt.Commands.SC.prompt', side_effect=[self.wallet_1_pass()]):
                    args = ['deploy', path_dir + 'SampleSC.avm', 'True', 'False', 'False', '070502', '02']
                    res = CommandSC().execute(args)
                    self.assertFalse(res)
                    self.assertTrue(mock_print.getvalue().endswith('Insufficient funds\n'))
Beispiel #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

    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()