This repository was archived by the owner on Nov 15, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 187
[refactor prompt] Add support for show method group (pt 1) #738
Merged
ixje
merged 18 commits into
CityOfZion:refactor-prompt
from
jseagrave21:refactor-CommandShow-pt1
Dec 6, 2018
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
dbe5074
Merge pull request #78 from CityOfZion/refactor-prompt
jseagrave21 681b063
Update prompt.py
jseagrave21 5b8c226
Update prompt.py
jseagrave21 6b31e9e
Update prompt.py
jseagrave21 2c2fce7
Create Show.py
jseagrave21 ea08db1
Create test_show_commands.py
jseagrave21 1ddacb0
Update prompt.py
jseagrave21 02b0f69
Update Show.py
jseagrave21 d10cc2d
Update test_show_commands.py
jseagrave21 202f64d
Update Wallet.py
jseagrave21 31eb699
Update prompt.py
jseagrave21 89c8d39
Merge pull request #79 from CityOfZion/refactor-prompt
jseagrave21 8771766
Update prompt.py
jseagrave21 3edaff0
Update Search.py
jseagrave21 474caa1
Update Show.py
jseagrave21 b6074e1
Update Show.py
jseagrave21 a57ab9f
Update test_show_commands.py
jseagrave21 18eb438
Update Show.py
jseagrave21 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| import os | ||
| import psutil | ||
| import datetime | ||
| from neo.Prompt.CommandBase import CommandBase, CommandDesc, ParameterDesc | ||
| from neo.Prompt.PromptData import PromptData | ||
| from neo.Prompt.Utils import get_arg | ||
| from neo.Core.Blockchain import Blockchain | ||
| from neocore.UInt256 import UInt256 | ||
| from neo.IO.MemoryStream import StreamManager | ||
| from neo.Network.NodeLeader import NodeLeader | ||
| from neo.Implementations.Notifications.LevelDB.NotificationDB import NotificationDB | ||
| from neo.logging import log_manager | ||
| import json | ||
|
|
||
|
|
||
| logger = log_manager.getLogger() | ||
|
|
||
|
|
||
| class CommandShow(CommandBase): | ||
| def __init__(self): | ||
| super().__init__() | ||
|
|
||
| self.register_sub_command(CommandShowBlock()) | ||
| self.register_sub_command(CommandShowHeader()) | ||
| self.register_sub_command(CommandShowTx()) | ||
| self.register_sub_command(CommandShowMem()) | ||
| self.register_sub_command(CommandShowNodes(), ['node']) | ||
|
|
||
| def command_desc(self): | ||
| return CommandDesc('show', 'show useful data') | ||
|
|
||
| def execute(self, arguments): | ||
| item = get_arg(arguments) | ||
|
|
||
| if not item: | ||
| print("run `%s help` to see supported queries" % self.command_desc().command) | ||
| return | ||
|
|
||
| try: | ||
| return self.execute_sub_command(item, arguments[1:]) | ||
| except KeyError: | ||
| print(f"{item} is an invalid parameter") | ||
| return | ||
|
|
||
|
|
||
| class CommandShowBlock(CommandBase): | ||
| def __init__(self): | ||
| super().__init__() | ||
|
|
||
| def execute(self, arguments): | ||
| item = get_arg(arguments) | ||
| txarg = get_arg(arguments, 1) | ||
| if item is not None: | ||
| block = Blockchain.Default().GetBlock(item) | ||
|
|
||
| if block is not None: | ||
| block.LoadTransactions() | ||
|
|
||
| if txarg and 'tx' in txarg: | ||
| txs = [] | ||
| for tx in block.FullTransactions: | ||
| print(json.dumps(tx.ToJson(), indent=4)) | ||
| txs.append(tx.ToJson()) | ||
| return txs | ||
|
|
||
| print(json.dumps(block.ToJson(), indent=4)) | ||
| return block.ToJson() | ||
|
|
||
| else: | ||
| print("Could not locate block %s" % item) | ||
| return | ||
| else: | ||
| print("please specify a block") | ||
| return | ||
|
|
||
| def command_desc(self): | ||
| p1 = ParameterDesc('index/hash', 'the index or scripthash of the block') | ||
| p2 = ParameterDesc('tx', 'arg to only show block transactions', optional=True) | ||
| return CommandDesc('block', 'show a specified block', [p1, p2]) | ||
|
|
||
|
|
||
| class CommandShowHeader(CommandBase): | ||
| def __init__(self): | ||
| super().__init__() | ||
|
|
||
| def execute(self, arguments): | ||
| item = get_arg(arguments) | ||
| if item is not None: | ||
| header = Blockchain.Default().GetHeaderBy(item) | ||
| if header is not None: | ||
| print(json.dumps(header.ToJson(), indent=4)) | ||
| return header.ToJson() | ||
| else: | ||
| print("Could not locate header %s\n" % item) | ||
| return | ||
| else: | ||
| print("Please specify a header") | ||
| return | ||
|
|
||
| def command_desc(self): | ||
| p1 = ParameterDesc('index/hash', 'the index or scripthash of the block header') | ||
| return CommandDesc('header', 'show the header of a specified block', [p1]) | ||
|
|
||
|
|
||
| class CommandShowTx(CommandBase): | ||
| def __init__(self): | ||
| super().__init__() | ||
|
|
||
| def execute(self, arguments): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. show tx with an invalid argument gives a not user friendly error
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about now? (I just removed the exception) |
||
| if len(arguments): | ||
| try: | ||
| txid = UInt256.ParseString(get_arg(arguments)) | ||
| tx, height = Blockchain.Default().GetTransaction(txid) | ||
| if height > -1: | ||
| jsn = tx.ToJson() | ||
| jsn['height'] = height | ||
| jsn['unspents'] = [uns.ToJson(tx.outputs.index(uns)) for uns in | ||
| Blockchain.Default().GetAllUnspent(txid)] | ||
| print(json.dumps(jsn, indent=4)) | ||
| return jsn | ||
| else: | ||
| print(f"Could not find transaction for hash {txid}") | ||
| return | ||
| except Exception: | ||
| print("Could not find transaction from args: %s" % arguments) | ||
| return | ||
| else: | ||
| print("Please specify a TX hash") | ||
| return | ||
|
|
||
| def command_desc(self): | ||
| p1 = ParameterDesc('hash', 'the scripthash of the transaction') | ||
| return CommandDesc('tx', 'show a specified transaction', [p1]) | ||
jseagrave21 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| class CommandShowMem(CommandBase): | ||
| def __init__(self): | ||
| super().__init__() | ||
|
|
||
| def execute(self, arguments=None): | ||
| process = psutil.Process(os.getpid()) | ||
| total = process.memory_info().rss | ||
| totalmb = total / (1024 * 1024) | ||
| out = "Total: %s MB\n" % totalmb | ||
| out += "Total buffers: %s\n" % StreamManager.TotalBuffers() | ||
| print(out) | ||
| return out | ||
|
|
||
| def command_desc(self): | ||
| return CommandDesc('mem', 'show memory in use and number of buffers') | ||
|
|
||
|
|
||
| class CommandShowNodes(CommandBase): | ||
| def __init__(self): | ||
| super().__init__() | ||
|
|
||
| def execute(self, arguments=None): | ||
| if len(NodeLeader.Instance().Peers) > 0: | ||
| out = "Total Connected: %s\n" % len(NodeLeader.Instance().Peers) | ||
| for peer in NodeLeader.Instance().Peers: | ||
| out += "Peer %s - IO: %s\n" % (peer.Name(), peer.IOStats()) | ||
| print(out) | ||
| return out | ||
| else: | ||
| print("Not connected yet\n") | ||
| return | ||
|
|
||
| def command_desc(self): | ||
| return CommandDesc('nodes', 'show connected peers') | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| import os | ||
| from neo.Settings import settings | ||
| from neo.Utils.BlockchainFixtureTestCase import BlockchainFixtureTestCase | ||
| from neo.Prompt.Commands.Show import CommandShow | ||
| from neo.Prompt.Commands.Wallet import CommandWallet | ||
| from neo.Prompt.PromptData import PromptData | ||
| from neo.bin.prompt import PromptInterface | ||
| from copy import deepcopy | ||
| from neo.Network.NodeLeader import NodeLeader, NeoNode | ||
| from neo.Core.Blockchain import Blockchain | ||
| from neo.Implementations.Wallets.peewee.UserWallet import UserWallet | ||
| from mock import patch | ||
|
|
||
|
|
||
| class CommandShowTestCase(BlockchainFixtureTestCase): | ||
|
|
||
| @classmethod | ||
| def leveldb_testpath(self): | ||
| return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain') | ||
|
|
||
| @classmethod | ||
| def tearDown(cls): | ||
| PromptData.Prompt = None | ||
| PromptData.Wallet = None | ||
|
|
||
| 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_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_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_mem(self): | ||
| args = ['mem'] | ||
| res = CommandShow().execute(args) | ||
| self.assertTrue(res) | ||
|
|
||
| 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 | ||
| leader = NodeLeader.Instance() | ||
| old_leader = deepcopy(leader) | ||
| leader.ADDRS = ["127.0.0.1:20333", "127.0.0.2:20334"] | ||
| leader.DEAD_ADDRS = ["127.0.0.1:20335"] | ||
| test_node = NeoNode() | ||
| test_node.host = "127.0.0.1" | ||
| test_node.port = 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 test name - IO: 0.0 MB in / 0.0 MB out', res) | ||
|
|
||
| # now use "node" | ||
| args = ['node'] | ||
| res = CommandShow().execute(args) | ||
| self.assertTrue(res) | ||
| self.assertIn('Total Connected: 1', res) | ||
| self.assertIn('Peer test name - IO: 0.0 MB in / 0.0 MB out', res) | ||
|
|
||
| # restore whatever state the instance was in | ||
| NodeLeader._LEAD = old_leader |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
show blockandshow headerswithout an argument throws an exception. Exampleshow txwithout arguments throws a different exceptionThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed all those user friendly messages because I thought @LysanderGG 's change to CommandBase here #733 (review) was going to be merged. Oops 😊
I will add all the original messages back in