{"action":"created","comment":{"url":"https://api.github.com/repos/ethereum/py-evm/pulls/comments/190152981","pull_request_review_id":122468590,"id":190152981,"diff_hunk":"@@ -865,6 +878,82 @@ def get_nodes_to_connect(self) -> Generator[Node, None, None]:\n             yield node\n \n \n+class PreferredNodePeerPool(PeerPool):\n+    \"\"\"\n+    A PeerPool which has a list of preferred nodes which it will prioritize\n+    using before going to the discovery protocol to find nodes.  Each preferred\n+    node can only be used once every preferred_node_recycle_time seconds.\n+    \"\"\"\n+    preferred_nodes: Sequence[Node] = None\n+    preferred_node_recycle_time: int = 300\n+    _preferred_node_tracker: Dict[Node, float] = None\n+\n+    def __init__(self,\n+                 peer_class: Type[BasePeer],\n+                 headerdb: 'BaseAsyncHeaderDB',\n+                 network_id: int,\n+                 privkey: datatypes.PrivateKey,\n+                 discovery: DiscoveryProtocol,\n+                 min_peers: int = DEFAULT_MIN_PEERS,\n+                 preferred_nodes: Sequence[Node] = None,\n+                 ) -> None:\n+        super().__init__(peer_class, headerdb, network_id, privkey, discovery, min_peers)\n+\n+        if preferred_nodes is not None:\n+            self.preferred_nodes = preferred_nodes\n+        elif network_id in DEFAULT_PREFERRED_NODES:\n+            self.preferred_nodes = DEFAULT_PREFERRED_NODES[network_id]\n+        else:\n+            self.logger.debug('PreferredNodePeerPool operating with no preferred nodes')\n+            self.preferred_nodes = tuple()\n+\n+        self._preferred_node_tracker = collections.defaultdict(lambda: 0)\n+\n+    @to_tuple\n+    def _get_eligible_preferred_nodes(self) -> Generator[Node, None, None]:\n+        \"\"\"\n+        Returns nodes from the preferred_nodes which have not been used within","path":"p2p/peer.py","position":210,"original_position":210,"commit_id":"60d9c3161103f2840ce097f56ca4c481f0fc75f5","original_commit_id":"60d9c3161103f2840ce097f56ca4c481f0fc75f5","user":{"login":"cburgdorf","id":521109,"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":"nitpick: Style guide prefers imperative, present tense.\r\n\r\n>Return nodes from the preferred_nodes which have not been used within the last preferred_node_recycle_time","created_at":"2018-05-23T07:54:12Z","updated_at":"2018-05-23T07:54:13Z","html_url":"https://github.com/ethereum/py-evm/pull/744#discussion_r190152981","pull_request_url":"https://api.github.com/repos/ethereum/py-evm/pulls/744","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/comments/190152981"},"html":{"href":"https://github.com/ethereum/py-evm/pull/744#discussion_r190152981"},"pull_request":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/744"}}},"pull_request":{"url":"https://api.github.com/repos/ethereum/py-evm/pulls/744","id":189510429,"html_url":"https://github.com/ethereum/py-evm/pull/744","diff_url":"https://github.com/ethereum/py-evm/pull/744.diff","patch_url":"https://github.com/ethereum/py-evm/pull/744.patch","issue_url":"https://api.github.com/repos/ethereum/py-evm/issues/744","number":744,"state":"open","locked":false,"title":"Add PreferredNodePeerPool","user":{"login":"pipermerriam","id":824194,"avatar_url":"https://avatars3.githubusercontent.com/u/824194?v=4","gravatar_id":"","url":"https://api.github.com/users/pipermerriam","html_url":"https://github.com/pipermerriam","followers_url":"https://api.github.com/users/pipermerriam/followers","following_url":"https://api.github.com/users/pipermerriam/following{/other_user}","gists_url":"https://api.github.com/users/pipermerriam/gists{/gist_id}","starred_url":"https://api.github.com/users/pipermerriam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pipermerriam/subscriptions","organizations_url":"https://api.github.com/users/pipermerriam/orgs","repos_url":"https://api.github.com/users/pipermerriam/repos","events_url":"https://api.github.com/users/pipermerriam/events{/privacy}","received_events_url":"https://api.github.com/users/pipermerriam/received_events","type":"User","site_admin":false},"body":"link: https://github.com/ethereum/py-evm/issues/741\r\n\r\n### What was wrong?\r\n\r\n- Running `trinity --light` with a niave peer pool and discovery will rarely find an LES peer to connect to.\r\n- Using `HardCodedNodesPeerPool` eliminates discovery, but also locks Trinity into only being able to connect to a few nodes.\r\n- We will be implementing APIs for Trinity to support reserving slots for certain nodes and trusted nodes.\r\n\r\n### How was it fixed?\r\n\r\nImplement a new `PeerPool` class which implements list of *preferred* nodes.  \r\n\r\n- Anytime the peer pool is looking for a new node to connect to it will try to use one of the preferred nodes.  \r\n- Each preferred node may only be used once every 300 seconds.\r\n- If there are no preferred nodes which have not been used recently then it falls back to use the discovery protocol\r\n\r\n#### Cute Animal Picture\r\n\r\n![86037878e80b3023632ab6b9907a750b](https://user-images.githubusercontent.com/824194/40387450-08a7bd44-5dca-11e8-941d-906f994c9fd5.jpg)\r\n\r\n","created_at":"2018-05-21T23:10:23Z","updated_at":"2018-05-23T07:54:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"325d832e578f14f3d7a33b2ae104888556c39d65","assignee":null,"assignees":[],"requested_reviewers":[{"login":"gsalgado","id":412274,"avatar_url":"https://avatars2.githubusercontent.com/u/412274?v=4","gravatar_id":"","url":"https://api.github.com/users/gsalgado","html_url":"https://github.com/gsalgado","followers_url":"https://api.github.com/users/gsalgado/followers","following_url":"https://api.github.com/users/gsalgado/following{/other_user}","gists_url":"https://api.github.com/users/gsalgado/gists{/gist_id}","starred_url":"https://api.github.com/users/gsalgado/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsalgado/subscriptions","organizations_url":"https://api.github.com/users/gsalgado/orgs","repos_url":"https://api.github.com/users/gsalgado/repos","events_url":"https://api.github.com/users/gsalgado/events{/privacy}","received_events_url":"https://api.github.com/users/gsalgado/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":630872074,"url":"https://api.github.com/repos/ethereum/py-evm/labels/Needs%20Review","name":"Needs Review","color":"0052cc","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/ethereum/py-evm/pulls/744/commits","review_comments_url":"https://api.github.com/repos/ethereum/py-evm/pulls/744/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/744/comments","statuses_url":"https://api.github.com/repos/ethereum/py-evm/statuses/60d9c3161103f2840ce097f56ca4c481f0fc75f5","head":{"label":"pipermerriam:piper/extend-HardCodedNodePeerPool-to-use-discovery","ref":"piper/extend-HardCodedNodePeerPool-to-use-discovery","sha":"60d9c3161103f2840ce097f56ca4c481f0fc75f5","user":{"login":"pipermerriam","id":824194,"avatar_url":"https://avatars3.githubusercontent.com/u/824194?v=4","gravatar_id":"","url":"https://api.github.com/users/pipermerriam","html_url":"https://github.com/pipermerriam","followers_url":"https://api.github.com/users/pipermerriam/followers","following_url":"https://api.github.com/users/pipermerriam/following{/other_user}","gists_url":"https://api.github.com/users/pipermerriam/gists{/gist_id}","starred_url":"https://api.github.com/users/pipermerriam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pipermerriam/subscriptions","organizations_url":"https://api.github.com/users/pipermerriam/orgs","repos_url":"https://api.github.com/users/pipermerriam/repos","events_url":"https://api.github.com/users/pipermerriam/events{/privacy}","received_events_url":"https://api.github.com/users/pipermerriam/received_events","type":"User","site_admin":false},"repo":{"id":112370752,"name":"py-evm","full_name":"pipermerriam/py-evm","owner":{"login":"pipermerriam","id":824194,"avatar_url":"https://avatars3.githubusercontent.com/u/824194?v=4","gravatar_id":"","url":"https://api.github.com/users/pipermerriam","html_url":"https://github.com/pipermerriam","followers_url":"https://api.github.com/users/pipermerriam/followers","following_url":"https://api.github.com/users/pipermerriam/following{/other_user}","gists_url":"https://api.github.com/users/pipermerriam/gists{/gist_id}","starred_url":"https://api.github.com/users/pipermerriam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pipermerriam/subscriptions","organizations_url":"https://api.github.com/users/pipermerriam/orgs","repos_url":"https://api.github.com/users/pipermerriam/repos","events_url":"https://api.github.com/users/pipermerriam/events{/privacy}","received_events_url":"https://api.github.com/users/pipermerriam/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/pipermerriam/py-evm","description":"A Python implementation of the Ethereum Virtual Machine","fork":true,"url":"https://api.github.com/repos/pipermerriam/py-evm","forks_url":"https://api.github.com/repos/pipermerriam/py-evm/forks","keys_url":"https://api.github.com/repos/pipermerriam/py-evm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pipermerriam/py-evm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pipermerriam/py-evm/teams","hooks_url":"https://api.github.com/repos/pipermerriam/py-evm/hooks","issue_events_url":"https://api.github.com/repos/pipermerriam/py-evm/issues/events{/number}","events_url":"https://api.github.com/repos/pipermerriam/py-evm/events","assignees_url":"https://api.github.com/repos/pipermerriam/py-evm/assignees{/user}","branches_url":"https://api.github.com/repos/pipermerriam/py-evm/branches{/branch}","tags_url":"https://api.github.com/repos/pipermerriam/py-evm/tags","blobs_url":"https://api.github.com/repos/pipermerriam/py-evm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pipermerriam/py-evm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pipermerriam/py-evm/git/refs{/sha}","trees_url":"https://api.github.com/repos/pipermerriam/py-evm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pipermerriam/py-evm/statuses/{sha}","languages_url":"https://api.github.com/repos/pipermerriam/py-evm/languages","stargazers_url":"https://api.github.com/repos/pipermerriam/py-evm/stargazers","contributors_url":"https://api.github.com/repos/pipermerriam/py-evm/contributors","subscribers_url":"https://api.github.com/repos/pipermerriam/py-evm/subscribers","subscription_url":"https://api.github.com/repos/pipermerriam/py-evm/subscription","commits_url":"https://api.github.com/repos/pipermerriam/py-evm/commits{/sha}","git_commits_url":"https://api.github.com/repos/pipermerriam/py-evm/git/commits{/sha}","comments_url":"https://api.github.com/repos/pipermerriam/py-evm/comments{/number}","issue_comment_url":"https://api.github.com/repos/pipermerriam/py-evm/issues/comments{/number}","contents_url":"https://api.github.com/repos/pipermerriam/py-evm/contents/{+path}","compare_url":"https://api.github.com/repos/pipermerriam/py-evm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pipermerriam/py-evm/merges","archive_url":"https://api.github.com/repos/pipermerriam/py-evm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pipermerriam/py-evm/downloads","issues_url":"https://api.github.com/repos/pipermerriam/py-evm/issues{/number}","pulls_url":"https://api.github.com/repos/pipermerriam/py-evm/pulls{/number}","milestones_url":"https://api.github.com/repos/pipermerriam/py-evm/milestones{/number}","notifications_url":"https://api.github.com/repos/pipermerriam/py-evm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pipermerriam/py-evm/labels{/name}","releases_url":"https://api.github.com/repos/pipermerriam/py-evm/releases{/id}","deployments_url":"https://api.github.com/repos/pipermerriam/py-evm/deployments","created_at":"2017-11-28T18:07:13Z","updated_at":"2018-05-23T00:29:11Z","pushed_at":"2018-05-23T03:05:22Z","git_url":"git://github.com/pipermerriam/py-evm.git","ssh_url":"git@github.com:pipermerriam/py-evm.git","clone_url":"https://github.com/pipermerriam/py-evm.git","svn_url":"https://github.com/pipermerriam/py-evm","homepage":"","size":3291,"stargazers_count":20,"watchers_count":20,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":3,"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"},"forks":3,"open_issues":0,"watchers":20,"default_branch":"master"}},"base":{"label":"ethereum:master","ref":"master","sha":"b29e3c728244934abadf5ad8d4ef19e7b9513eab","user":{"login":"ethereum","id":6250754,"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,"name":"py-evm","full_name":"ethereum/py-evm","owner":{"login":"ethereum","id":6250754,"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-05-23T01:56:23Z","pushed_at":"2018-05-23T03:05:24Z","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":3340,"stargazers_count":458,"watchers_count":458,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":187,"mirror_url":null,"archived":false,"open_issues_count":101,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":187,"open_issues":101,"watchers":458,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/744"},"html":{"href":"https://github.com/ethereum/py-evm/pull/744"},"issue":{"href":"https://api.github.com/repos/ethereum/py-evm/issues/744"},"comments":{"href":"https://api.github.com/repos/ethereum/py-evm/issues/744/comments"},"review_comments":{"href":"https://api.github.com/repos/ethereum/py-evm/pulls/744/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/744/commits"},"statuses":{"href":"https://api.github.com/repos/ethereum/py-evm/statuses/60d9c3161103f2840ce097f56ca4c481f0fc75f5"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"cburgdorf"}}