def test_show_contract(self): # test no contract entered args = ['contract'] res = CommandShow().execute(args) self.assertFalse(res) # show all contracts args = ['contract', 'all'] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(len(res), 6) self.assertEqual(res[0]["test NEX Template V4"], '0x31730cc9a1844891a3bafd1aa929a4142860d8d3') # query with contract scripthash args = ['contract', '31730cc9a1844891a3bafd1aa929a4142860d8d3'] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(res['name'], "test NEX Template V4") self.assertEqual(res['token']['name'], "NEX Template V4") self.assertEqual(res['token']['symbol'], "NXT4") # query with a contract scripthash not on the blockchain args = ['contract', '3a4acd3647086e7c44398aac0349802e6a171129'] # NEX token hash res = CommandShow().execute(args) self.assertFalse(res) # query bad input args = ['contract', 'blah'] res = CommandShow().execute(args) self.assertFalse(res)
def test_show_header(self): # test no header input args = ['header'] res = CommandShow().execute(args) self.assertFalse(res) # show good header by index args = ['header', '9'] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(res['index'], 9) self.assertNotIn('tx', res) # show good header by hash args = [ 'header', "0x7c5b4c8a70336bf68e8679be7c9a2a15f85c0f6d0e14389019dcc3edfab2bb4b" ] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(res['index'], 9) self.assertNotIn('tx', res) # request bad header args = ['header', 'blah'] res = CommandShow().execute(args) self.assertFalse(res)
def test_show_tx(self): # test no tx input args = ['tx'] res = CommandShow().execute(args) self.assertFalse(res) # show good tx txid = '0x83df8bd085fcb60b2789f7d0a9f876e5f3908567f7877fcba835e899b9dea0b5' args = ['tx', txid] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(res['txid'], txid) self.assertIn('height', res) self.assertIn('unspents', res) # query a bad tx args = [ 'tx', '0x83df8bd085fcb60b2789f7d0a9f876e5f3908567f7877fcba835e899b9dea0b6' ] res = CommandShow().execute(args) self.assertFalse(res) # query with bad args args = ['tx', 'blah'] res = CommandShow().execute(args) self.assertFalse(res)
def test_show_block(self): # test no block input args = ['block'] res = CommandShow().execute(args) self.assertFalse(res) # show good block by index args = ['block', '9'] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(res['index'], 9) self.assertIn('tx', res) # show good block by hash args = [ 'block', "0x7c5b4c8a70336bf68e8679be7c9a2a15f85c0f6d0e14389019dcc3edfab2bb4b" ] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(res['index'], 9) self.assertIn('tx', res) # show the block's transactions only args = ['block', '9', "tx"] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(len(res), 2) self.assertEqual(res[0]['type'], "MinerTransaction") self.assertEqual(res[1]['type'], "ContractTransaction") # request bad block args = ['block', 'blah'] res = CommandShow().execute(args) self.assertFalse(res)
def test_show_account(self): # setup wallet_1_addr = 'AJQ6FoaSXDFzA6wLnyZ1nFN7SGSN2oNTc3' # test no account address entered args = ['account'] res = CommandShow().execute(args) self.assertFalse(res) # test good account args = ['account', wallet_1_addr] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(res['address'], wallet_1_addr) self.assertIn('balances', res) # test empty account with patch('neo.Prompt.PromptData.PromptData.Prompt'): with patch('neo.Prompt.Commands.Wallet.prompt', side_effect=["testpassword", "testpassword"]): with patch('neo.Prompt.Commands.Wallet.asyncio'): with patch('neo.Wallets.Wallet.Wallet.sync_wallet'): args = ['create', 'testwallet.wallet'] res = CommandWallet().execute(args) self.assertTrue(res) self.assertIsInstance(res, UserWallet) addr = res.Addresses[0] args = ['account', addr] res = CommandShow().execute(args) self.assertFalse(res) # remove test wallet os.remove("testwallet.wallet")
def test_show(self): # with no subcommand res = CommandShow().execute(None) self.assertFalse(res) # with invalid command args = ['badcommand'] res = CommandShow().execute(args) self.assertFalse(res)
def test_show_state(self): # setup PromptInterface() args = ['state'] res = CommandShow().execute(args) self.assertTrue(res)
def test_show_state(self, mock_SyncManager): # setup class mock_SM(Singleton): def init(self): self.block_cache = [1, 2, 3, 4, 5] # simulate blocks in the block_cache mock_SyncManager.return_value = mock_SM() PromptInterface() with patch('sys.stdout', new=StringIO()) as mock_print: args = ['state'] res = CommandShow().execute(args) self.assertTrue(res) self.assertIn("Block-cache length 5", mock_print.getvalue())
def test_show_nodes(self): # query nodes with no NodeLeader.Instance() with patch('neo.Network.NodeLeader.NodeLeader.Instance'): args = ['nodes'] res = CommandShow().execute(args) self.assertFalse(res) # query nodes with connected peers # 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") leader.Peers = [test_node] # now show nodes with patch('neo.Network.NeoNode.NeoNode.Name', return_value="test name"): args = ['nodes'] res = CommandShow().execute(args) self.assertTrue(res) self.assertIn('Total Connected: 1', res) self.assertIn('Peer 0', res) # now use "node" args = ['node'] res = CommandShow().execute(args) self.assertTrue(res) self.assertIn('Total Connected: 1', res) self.assertIn('Peer 0', res)
def test_show_asset(self): # test no asset entered args = ['asset'] res = CommandShow().execute(args) self.assertFalse(res) # show all assets args = ['asset', 'all'] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(len(res), 2) self.assertEqual( res[1]['NEO'], "0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b" ) self.assertEqual( res[0]['NEOGas'], "0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7" ) # query with "neo" args = ['asset', 'neo'] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual( res['assetId'], "0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b" ) self.assertEqual(res['name'], "NEO") # query with "gas" args = ['asset', 'gas'] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual( res['assetId'], "0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7" ) self.assertEqual(res['name'], "NEOGas") # query with scripthash args = [ 'asset', 'c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b' ] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual( res['assetId'], "0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b" ) self.assertEqual(res['name'], "NEO") # query with bad asset args = [ 'asset', 'c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9e' ] res = CommandShow().execute(args) self.assertFalse(res) # query with bad input args = ['asset', 'blah'] res = CommandShow().execute(args) self.assertFalse(res)
def test_show_notifications(self): # setup wallet_1_addr = 'AJQ6FoaSXDFzA6wLnyZ1nFN7SGSN2oNTc3' # test with no NotificationDB with patch( 'neo.Implementations.Notifications.NotificationDB.NotificationDB.instance', return_value=None): args = ['notifications', wallet_1_addr] res = CommandShow().execute(args) self.assertFalse(res) # test with no input args = ['notifications'] res = CommandShow().execute(args) self.assertFalse(res) # good test with address args = ['notifications', wallet_1_addr] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(len(res), 1) jsn = res[0].ToJson() self.assertEqual(jsn['notify_type'], 'transfer') self.assertEqual(jsn['addr_from'], wallet_1_addr) # test an address with no notifications args = ['notifications', 'AZiE7xfyJALW7KmADWtCJXGGcnduYhGiCX'] res = CommandShow().execute(args) self.assertFalse(res) # good test with contract contract_hash = "31730cc9a1844891a3bafd1aa929a4142860d8d3" args = ['notifications', contract_hash] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(len(res), 1) jsn = res[0].ToJson() self.assertEqual(jsn['notify_type'], 'transfer') self.assertIn(contract_hash, jsn['contract']) # good test with contract 0x hash contract_hash = "0x31730cc9a1844891a3bafd1aa929a4142860d8d3" args = ['notifications', contract_hash] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(len(res), 1) jsn = res[0].ToJson() self.assertEqual(jsn['notify_type'], 'transfer') self.assertEqual(contract_hash, jsn['contract']) # test contract not on the blockchain contract_hash = "3a4acd3647086e7c44398aac0349802e6a171129" # NEX token hash args = ['notifications', contract_hash] res = CommandShow().execute(args) self.assertFalse(res) # good test with block index args = ['notifications', "12337"] res = CommandShow().execute(args) self.assertTrue(res) self.assertEqual(len(res), 1) jsn = res[0].ToJson() self.assertEqual(jsn['notify_type'], 'transfer') self.assertEqual(jsn['block'], 12337) # test block with no notifications args = ['notifications', "1"] res = CommandShow().execute(args) self.assertFalse(res) # test bad block index = Blockchain.Default().Height + 1 args = ['notifications', str(index)] res = CommandShow().execute(args) self.assertFalse(res) # test invalid input args = ['notifications', "blah"] res = CommandShow().execute(args) self.assertFalse(res)
def test_show_nodes(self): nodemgr = NodeManager() nodemgr.reset_for_test() # test "nodes" with no nodes connected args = ['nodes'] with patch('sys.stdout', new=StringIO()) as mock_print: res = CommandShow().execute(args) self.assertFalse(res) self.assertIn('No nodes connected yet', mock_print.getvalue()) # test "nodes verbose" with no nodes connected args = ['nodes', 'verbose'] res = CommandShow().execute(args) self.assertIn('Addresses in queue: 0', res) self.assertIn('Known addresses: 0', res) self.assertIn('Bad addresses: 0', res) # test "nodes queued" with no nodes connected args = ['nodes', 'queued'] res = CommandShow().execute(args) self.assertIn('No queued addresses', res) # test "nodes known" with no nodes connected args = ['nodes', 'known'] res = CommandShow().execute(args) self.assertIn('No known addresses other than connect peers', res) # test "nodes bad" with no nodes connected args = ['nodes', 'bad'] res = CommandShow().execute(args) self.assertIn('No bad addresses', res) # query nodes with connected peers # 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" node1.best_height = 1025 node2.best_height = 1026 node1.version = MagicMock() node2.version = MagicMock() node1.version.user_agent = "test_user_agent" node2.version.user_agent = "test_user_agent" nodemgr.nodes = [node1, node2] queued_address = "127.0.0.1:20335" known_address = "127.0.0.1:20336" bad_address = "127.0.0.1:20337" nodemgr.queued_addresses.append(queued_address) nodemgr.known_addresses.append(known_address) nodemgr.bad_addresses.append(bad_address) # now use "node" args = ['node'] res = CommandShow().execute(args) self.assertIn("Connected: 2", res) self.assertIn("Peer 1", res) self.assertIn("1025", res) # test "nodes verbose" with queued, known, and bad addresses args = ['nodes', 'verbose'] res = CommandShow().execute(args) self.assertIn("Addresses in queue: 1", res) self.assertIn("Known addresses: 1", res) self.assertIn("Bad addresses: 1", res) # test "nodes queued" with queued, known, and bad addresses args = ['nodes', 'queued'] res = CommandShow().execute(args) self.assertIn("Queued addresses:", res) self.assertIn(queued_address, res) # test "nodes known" with queued, known, and bad addresses args = ['nodes', 'known'] res = CommandShow().execute(args) self.assertIn("Known addresses:", res) self.assertIn(known_address, res) # test "nodes bad" with queued, known, and bad addresses args = ['nodes', 'bad'] res = CommandShow().execute(args) self.assertIn("Bad addresses:", res) self.assertIn(bad_address, res) nodemgr.reset_for_test()
def test_show_mem(self): args = ['mem'] res = CommandShow().execute(args) self.assertTrue(res)
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()
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()