{"action":"created","comment":{"url":"https://api.github.com/repos/ethereum/py-evm/pulls/comments/201791576","pull_request_review_id":136343679,"id":201791576,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwMTc5MTU3Ng==","diff_hunk":"@@ -0,0 +1,91 @@\n+from argparse import (\n+    Action,\n+    ArgumentParser,\n+)\n+import sys\n+\n+from trinity.config import (\n+    ChainConfig\n+)\n+from trinity.extensibility import (\n+    BaseEvent,\n+    BasePlugin,\n+    PluginContext,\n+    PluginProcess,\n+)\n+from trinity.extensibility.events import (\n+    NetworkProcessReadyEvent,\n+    TrinityStartupEvent,\n+)\n+\n+from trinity.plugins.builtin.console.console import (\n+    console\n+)\n+\n+\n+class ConsolePlugin(BasePlugin):\n+\n+    def __init__(self) -> None:\n+        self.is_attach = False\n+        self.is_console = False\n+        self.is_vanilla = False\n+        self.network_process_ready = False\n+        self.chain_config: ChainConfig = None\n+\n+    @property\n+    def name(self) -> str:\n+        return \"Console\"\n+\n+    @property\n+    def process(self) -> PluginProcess:\n+        return PluginProcess.MAIN\n+\n+    def configure_parser(self, arg_parser: ArgumentParser, sub_parser: Action) -> None:\n+        console_parser = sub_parser.add_parser(\n+            'console', help='run the chain and start the trinity REPL')\n+        console_parser.add_argument(\n+            '--vanilla-shell',\n+            action='store_true',\n+            default=False,\n+            help='start a native Python shell'\n+        )\n+\n+        attach_parser = sub_parser.add_parser(\n+            'attach',\n+            help='open an REPL attached to a currently running chain',\n+        )\n+        attach_parser.add_argument(\n+            '--vanilla-shell',\n+            action='store_true',\n+            default=False,\n+            help='start a native Python shell'\n+        )\n+\n+    def handle_event(self, event: BaseEvent) -> None:\n+        if isinstance(event, NetworkProcessReadyEvent):\n+            self.network_process_ready = True\n+\n+        if isinstance(event, TrinityStartupEvent):\n+            self.is_console = event.args.subcommand == 'console'\n+            self.is_attach = event.args.subcommand == 'attach'\n+            self.is_vanilla = (hasattr(event.args, \"vanilla_shell\") and\n+                               event.args.vanilla_shell)\n+            self.chain_config = event.chain_config\n+\n+    def should_start(self):\n+        return (self.is_console and self.network_process_ready) or self.is_attach\n+\n+    def start(self, context: PluginContext) -> None:\n+        self.run_console(self.chain_config, not self.is_vanilla)\n+\n+        # If we run `attach` the console will block the node from booting and we want\n+        # to shut it down to not continue booting when the user leaves the console\n+        if self.is_attach:\n+            sys.exit(0)","path":"trinity/plugins/builtin/console/plugin.py","position":84,"original_position":84,"commit_id":"cfce7bd9dee5a5beca63ef16bc1b3d7aa598b8e8","original_commit_id":"cfce7bd9dee5a5beca63ef16bc1b3d7aa598b8e8","user":{"login":"carver","id":205327,"node_id":"MDQ6VXNlcjIwNTMyNw==","avatar_url":"https://avatars0.githubusercontent.com/u/205327?v=4","gravatar_id":"","url":"https://api.github.com/users/carver","html_url":"https://github.com/carver","followers_url":"https://api.github.com/users/carver/followers","following_url":"https://api.github.com/users/carver/following{/other_user}","gists_url":"https://api.github.com/users/carver/gists{/gist_id}","starred_url":"https://api.github.com/users/carver/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/carver/subscriptions","organizations_url":"https://api.github.com/users/carver/orgs","repos_url":"https://api.github.com/users/carver/repos","events_url":"https://api.github.com/users/carver/events{/privacy}","received_events_url":"https://api.github.com/users/carver/received_events","type":"User","site_admin":false},"body":"It makes sense how we got here. But I'm worried that a pattern where a plugin takes over execution and then exits is a pretty special case. Maybe such a special case that it's not even really a plugin anymore, but a completely different app that's running.\r\n\r\nI don't really have a suggestion here other than to maybe add a comment that it's unusual and should be discouraged for plugins to block indefinitely on `start()`, and also discouraged to `exit()`. If two plugins tried to do that at the same time, they would be racing to go first.","created_at":"2018-07-11T18:14:08Z","updated_at":"2018-07-11T18:16:53Z","html_url":"https://github.com/ethereum/py-evm/pull/1000#discussion_r201791576","pull_request_url":"https://api.github.com/repos/ethereum/py-evm/pulls/1000","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/comments/201791576"},"html":{"href":"https://github.com/ethereum/py-evm/pull/1000#discussion_r201791576"},"pull_request":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/1000"}}},"pull_request":{"url":"https://api.github.com/repos/ethereum/py-evm/pulls/1000","id":200122638,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAwMTIyNjM4","html_url":"https://github.com/ethereum/py-evm/pull/1000","diff_url":"https://github.com/ethereum/py-evm/pull/1000.diff","patch_url":"https://github.com/ethereum/py-evm/pull/1000.patch","issue_url":"https://api.github.com/repos/ethereum/py-evm/issues/1000","number":1000,"state":"open","locked":false,"title":"Make trinity console / attach a plugin","user":{"login":"cburgdorf","id":521109,"node_id":"MDQ6VXNlcjUyMTEwOQ==","avatar_url":"https://avatars2.githubusercontent.com/u/521109?v=4","gravatar_id":"","url":"https://api.github.com/users/cburgdorf","html_url":"https://github.com/cburgdorf","followers_url":"https://api.github.com/users/cburgdorf/followers","following_url":"https://api.github.com/users/cburgdorf/following{/other_user}","gists_url":"https://api.github.com/users/cburgdorf/gists{/gist_id}","starred_url":"https://api.github.com/users/cburgdorf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cburgdorf/subscriptions","organizations_url":"https://api.github.com/users/cburgdorf/orgs","repos_url":"https://api.github.com/users/cburgdorf/repos","events_url":"https://api.github.com/users/cburgdorf/events{/privacy}","received_events_url":"https://api.github.com/users/cburgdorf/received_events","type":"User","site_admin":false},"body":"### What was wrong?\r\n\r\nThis builds on top of #996 and makes the `trinity console` as well as the `trinity attach` command a plugin. Both commands don't need to be in the core and in fact help to make the main file less verbose.\r\n\r\n### How was it fixed?\r\n\r\n- made plugins and plugin manager aware of the process that they are operating in\r\n- Created a new `NetworkProcessReadyActivationEvent` to give plugins more fine grained control\r\n- changed the `BasePlugin` to be able to amend sub command configs\r\n- moved exist console logic into plugin space and wrapped it as `ConsolePlugin`\r\n\r\n### A word about processes\r\n\r\nIn our multi process architecture, there's are some aspects of plugins that cause actions on the main process (e.g. configuring the arg parser) whereas others may fall into another process (e.g. tx pool wants to run in the networking process for now).\r\n\r\nIn the future we may have a dedicated plugin process and plugins may have the ability to decide if they want to run in that shared process or in their own process. However, for now, the *networking process* **is considered** the shared plugin process. I think we can operate under that assumption and slice the nodes into more fine grained plugins until we hit the need to have a plugin that really needs to operate in its own process.\r\n\r\nHowever, what's important for now is that this causes us to have two instances of `PluginManager` today. One that lives in the main process, and allows all plugins to configure the argparser as well as *run* the plugins that do want to run in the main process (hint: console / attach, needs to run their) and another one that runs in the networking process.\r\n\r\nWhile all plugins need to be able to configure the arg parser, we only want those that are intended to run in the main process to receive events from the main process and only want those that are intended to run in the shared process to receive events from that process.\r\n\r\nTo make that possible the `BasePlugin` defines a property `process` of type `PluginProcess` (an enum) that defaults to `PluginProcess.SHARED` but can easily be overwritten to `PluginProcess.MAIN`. Similarly, when we create a `PluginManager` we pass the `PluginProcess` to set the process scope for that manager. \r\n\r\n#### Cute Animal Picture\r\n\r\n![put a cute animal picture link inside the parentheses](https://static.panoramio.com.storage.googleapis.com/photos/large/67607536.jpg)\r\n","created_at":"2018-07-09T14:43:57Z","updated_at":"2018-07-11T18:16:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d8790348f9f79a18c15b8b2822ca5af782b8d876","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/ethereum/py-evm/pulls/1000/commits","review_comments_url":"https://api.github.com/repos/ethereum/py-evm/pulls/1000/comments","review_comment_url":"https://api.github.com/repos/ethereum/py-evm/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ethereum/py-evm/issues/1000/comments","statuses_url":"https://api.github.com/repos/ethereum/py-evm/statuses/cfce7bd9dee5a5beca63ef16bc1b3d7aa598b8e8","head":{"label":"cburgdorf:christoph/feat/console-plugin","ref":"christoph/feat/console-plugin","sha":"cfce7bd9dee5a5beca63ef16bc1b3d7aa598b8e8","user":{"login":"cburgdorf","id":521109,"node_id":"MDQ6VXNlcjUyMTEwOQ==","avatar_url":"https://avatars2.githubusercontent.com/u/521109?v=4","gravatar_id":"","url":"https://api.github.com/users/cburgdorf","html_url":"https://github.com/cburgdorf","followers_url":"https://api.github.com/users/cburgdorf/followers","following_url":"https://api.github.com/users/cburgdorf/following{/other_user}","gists_url":"https://api.github.com/users/cburgdorf/gists{/gist_id}","starred_url":"https://api.github.com/users/cburgdorf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cburgdorf/subscriptions","organizations_url":"https://api.github.com/users/cburgdorf/orgs","repos_url":"https://api.github.com/users/cburgdorf/repos","events_url":"https://api.github.com/users/cburgdorf/events{/privacy}","received_events_url":"https://api.github.com/users/cburgdorf/received_events","type":"User","site_admin":false},"repo":{"id":122467896,"node_id":"MDEwOlJlcG9zaXRvcnkxMjI0Njc4OTY=","name":"py-evm","full_name":"cburgdorf/py-evm","owner":{"login":"cburgdorf","id":521109,"node_id":"MDQ6VXNlcjUyMTEwOQ==","avatar_url":"https://avatars2.githubusercontent.com/u/521109?v=4","gravatar_id":"","url":"https://api.github.com/users/cburgdorf","html_url":"https://github.com/cburgdorf","followers_url":"https://api.github.com/users/cburgdorf/followers","following_url":"https://api.github.com/users/cburgdorf/following{/other_user}","gists_url":"https://api.github.com/users/cburgdorf/gists{/gist_id}","starred_url":"https://api.github.com/users/cburgdorf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cburgdorf/subscriptions","organizations_url":"https://api.github.com/users/cburgdorf/orgs","repos_url":"https://api.github.com/users/cburgdorf/repos","events_url":"https://api.github.com/users/cburgdorf/events{/privacy}","received_events_url":"https://api.github.com/users/cburgdorf/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/cburgdorf/py-evm","description":"A Python implementation of the Ethereum Virtual Machine","fork":true,"url":"https://api.github.com/repos/cburgdorf/py-evm","forks_url":"https://api.github.com/repos/cburgdorf/py-evm/forks","keys_url":"https://api.github.com/repos/cburgdorf/py-evm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cburgdorf/py-evm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cburgdorf/py-evm/teams","hooks_url":"https://api.github.com/repos/cburgdorf/py-evm/hooks","issue_events_url":"https://api.github.com/repos/cburgdorf/py-evm/issues/events{/number}","events_url":"https://api.github.com/repos/cburgdorf/py-evm/events","assignees_url":"https://api.github.com/repos/cburgdorf/py-evm/assignees{/user}","branches_url":"https://api.github.com/repos/cburgdorf/py-evm/branches{/branch}","tags_url":"https://api.github.com/repos/cburgdorf/py-evm/tags","blobs_url":"https://api.github.com/repos/cburgdorf/py-evm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cburgdorf/py-evm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cburgdorf/py-evm/git/refs{/sha}","trees_url":"https://api.github.com/repos/cburgdorf/py-evm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cburgdorf/py-evm/statuses/{sha}","languages_url":"https://api.github.com/repos/cburgdorf/py-evm/languages","stargazers_url":"https://api.github.com/repos/cburgdorf/py-evm/stargazers","contributors_url":"https://api.github.com/repos/cburgdorf/py-evm/contributors","subscribers_url":"https://api.github.com/repos/cburgdorf/py-evm/subscribers","subscription_url":"https://api.github.com/repos/cburgdorf/py-evm/subscription","commits_url":"https://api.github.com/repos/cburgdorf/py-evm/commits{/sha}","git_commits_url":"https://api.github.com/repos/cburgdorf/py-evm/git/commits{/sha}","comments_url":"https://api.github.com/repos/cburgdorf/py-evm/comments{/number}","issue_comment_url":"https://api.github.com/repos/cburgdorf/py-evm/issues/comments{/number}","contents_url":"https://api.github.com/repos/cburgdorf/py-evm/contents/{+path}","compare_url":"https://api.github.com/repos/cburgdorf/py-evm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cburgdorf/py-evm/merges","archive_url":"https://api.github.com/repos/cburgdorf/py-evm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cburgdorf/py-evm/downloads","issues_url":"https://api.github.com/repos/cburgdorf/py-evm/issues{/number}","pulls_url":"https://api.github.com/repos/cburgdorf/py-evm/pulls{/number}","milestones_url":"https://api.github.com/repos/cburgdorf/py-evm/milestones{/number}","notifications_url":"https://api.github.com/repos/cburgdorf/py-evm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cburgdorf/py-evm/labels{/name}","releases_url":"https://api.github.com/repos/cburgdorf/py-evm/releases{/id}","deployments_url":"https://api.github.com/repos/cburgdorf/py-evm/deployments","created_at":"2018-02-22T11:07:50Z","updated_at":"2018-03-28T15:01:32Z","pushed_at":"2018-07-11T11:01:34Z","git_url":"git://github.com/cburgdorf/py-evm.git","ssh_url":"git@github.com:cburgdorf/py-evm.git","clone_url":"https://github.com/cburgdorf/py-evm.git","svn_url":"https://github.com/cburgdorf/py-evm","homepage":"http://py-evm.readthedocs.io/en/latest/","size":4553,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"ethereum:master","ref":"master","sha":"35d57d7831d5e18c59a85975500296082624d8ee","user":{"login":"ethereum","id":6250754,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYyNTA3NTQ=","avatar_url":"https://avatars3.githubusercontent.com/u/6250754?v=4","gravatar_id":"","url":"https://api.github.com/users/ethereum","html_url":"https://github.com/ethereum","followers_url":"https://api.github.com/users/ethereum/followers","following_url":"https://api.github.com/users/ethereum/following{/other_user}","gists_url":"https://api.github.com/users/ethereum/gists{/gist_id}","starred_url":"https://api.github.com/users/ethereum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ethereum/subscriptions","organizations_url":"https://api.github.com/users/ethereum/orgs","repos_url":"https://api.github.com/users/ethereum/repos","events_url":"https://api.github.com/users/ethereum/events{/privacy}","received_events_url":"https://api.github.com/users/ethereum/received_events","type":"Organization","site_admin":false},"repo":{"id":77478378,"node_id":"MDEwOlJlcG9zaXRvcnk3NzQ3ODM3OA==","name":"py-evm","full_name":"ethereum/py-evm","owner":{"login":"ethereum","id":6250754,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYyNTA3NTQ=","avatar_url":"https://avatars3.githubusercontent.com/u/6250754?v=4","gravatar_id":"","url":"https://api.github.com/users/ethereum","html_url":"https://github.com/ethereum","followers_url":"https://api.github.com/users/ethereum/followers","following_url":"https://api.github.com/users/ethereum/following{/other_user}","gists_url":"https://api.github.com/users/ethereum/gists{/gist_id}","starred_url":"https://api.github.com/users/ethereum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ethereum/subscriptions","organizations_url":"https://api.github.com/users/ethereum/orgs","repos_url":"https://api.github.com/users/ethereum/repos","events_url":"https://api.github.com/users/ethereum/events{/privacy}","received_events_url":"https://api.github.com/users/ethereum/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ethereum/py-evm","description":"A Python implementation of the Ethereum Virtual Machine","fork":false,"url":"https://api.github.com/repos/ethereum/py-evm","forks_url":"https://api.github.com/repos/ethereum/py-evm/forks","keys_url":"https://api.github.com/repos/ethereum/py-evm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ethereum/py-evm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ethereum/py-evm/teams","hooks_url":"https://api.github.com/repos/ethereum/py-evm/hooks","issue_events_url":"https://api.github.com/repos/ethereum/py-evm/issues/events{/number}","events_url":"https://api.github.com/repos/ethereum/py-evm/events","assignees_url":"https://api.github.com/repos/ethereum/py-evm/assignees{/user}","branches_url":"https://api.github.com/repos/ethereum/py-evm/branches{/branch}","tags_url":"https://api.github.com/repos/ethereum/py-evm/tags","blobs_url":"https://api.github.com/repos/ethereum/py-evm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ethereum/py-evm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ethereum/py-evm/git/refs{/sha}","trees_url":"https://api.github.com/repos/ethereum/py-evm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ethereum/py-evm/statuses/{sha}","languages_url":"https://api.github.com/repos/ethereum/py-evm/languages","stargazers_url":"https://api.github.com/repos/ethereum/py-evm/stargazers","contributors_url":"https://api.github.com/repos/ethereum/py-evm/contributors","subscribers_url":"https://api.github.com/repos/ethereum/py-evm/subscribers","subscription_url":"https://api.github.com/repos/ethereum/py-evm/subscription","commits_url":"https://api.github.com/repos/ethereum/py-evm/commits{/sha}","git_commits_url":"https://api.github.com/repos/ethereum/py-evm/git/commits{/sha}","comments_url":"https://api.github.com/repos/ethereum/py-evm/comments{/number}","issue_comment_url":"https://api.github.com/repos/ethereum/py-evm/issues/comments{/number}","contents_url":"https://api.github.com/repos/ethereum/py-evm/contents/{+path}","compare_url":"https://api.github.com/repos/ethereum/py-evm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ethereum/py-evm/merges","archive_url":"https://api.github.com/repos/ethereum/py-evm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ethereum/py-evm/downloads","issues_url":"https://api.github.com/repos/ethereum/py-evm/issues{/number}","pulls_url":"https://api.github.com/repos/ethereum/py-evm/pulls{/number}","milestones_url":"https://api.github.com/repos/ethereum/py-evm/milestones{/number}","notifications_url":"https://api.github.com/repos/ethereum/py-evm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ethereum/py-evm/labels{/name}","releases_url":"https://api.github.com/repos/ethereum/py-evm/releases{/id}","deployments_url":"https://api.github.com/repos/ethereum/py-evm/deployments","created_at":"2016-12-27T19:36:00Z","updated_at":"2018-07-11T16:14:14Z","pushed_at":"2018-07-11T16:14:11Z","git_url":"git://github.com/ethereum/py-evm.git","ssh_url":"git@github.com:ethereum/py-evm.git","clone_url":"https://github.com/ethereum/py-evm.git","svn_url":"https://github.com/ethereum/py-evm","homepage":"http://py-evm.readthedocs.io/en/latest/","size":4141,"stargazers_count":537,"watchers_count":537,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":232,"mirror_url":null,"archived":false,"open_issues_count":115,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":232,"open_issues":115,"watchers":537,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/1000"},"html":{"href":"https://github.com/ethereum/py-evm/pull/1000"},"issue":{"href":"https://api.github.com/repos/ethereum/py-evm/issues/1000"},"comments":{"href":"https://api.github.com/repos/ethereum/py-evm/issues/1000/comments"},"review_comments":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/1000/comments"},"review_comment":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/1000/commits"},"statuses":{"href":"https://api.github.com/repos/ethereum/py-evm/statuses/cfce7bd9dee5a5beca63ef16bc1b3d7aa598b8e8"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"carver"}}