{"action":"created","comment":{"url":"https://api.github.com/repos/hyperledger/fabric/pulls/comments/66724571","id":66724571,"diff_hunk":"@@ -0,0 +1,147 @@\n+/*\n+Copyright IBM Corp. 2016 All Rights Reserved.\n+\n+Licensed under the Apache License, Version 2.0 (the \"License\");\n+you may not use this file except in compliance with the License.\n+You may obtain a copy of the License at\n+\n+\t\t http://www.apache.org/licenses/LICENSE-2.0\n+\n+Unless required by applicable law or agreed to in writing, software\n+distributed under the License is distributed on an \"AS IS\" BASIS,\n+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+See the License for the specific language governing permissions and\n+limitations under the License.\n+*/\n+\n+package obcpbft\n+\n+import (\n+\t\"fmt\"\n+\t\"sync\"\n+\t\"time\"\n+\n+\t\"github.com/hyperledger/fabric/consensus\"\n+\tpb \"github.com/hyperledger/fabric/protos\"\n+)\n+\n+type communicator interface {\n+\tconsensus.Communicator\n+\tconsensus.Inquirer\n+}\n+\n+type broadcaster struct {\n+\tcomm communicator\n+\n+\tf        int\n+\tmsgChans map[uint64]chan *pb.Message\n+\tclosed   sync.WaitGroup\n+\tclosedCh chan struct{}\n+}\n+\n+func newBroadcaster(self uint64, N int, f int, c communicator) *broadcaster {\n+\tqueueSize := 10 // XXX increase after testing\n+\n+\tchans := make(map[uint64]chan *pb.Message)\n+\tfor i := 0; i < N; i++ {\n+\t\tif uint64(i) == self {\n+\t\t\tcontinue\n+\t\t}\n+\t\tchans[uint64(i)] = make(chan *pb.Message, queueSize)\n+\t}\n+\tb := &broadcaster{\n+\t\tcomm:     c,\n+\t\tf:        f,\n+\t\tmsgChans: chans,\n+\t\tclosedCh: make(chan struct{}),\n+\t}\n+\tfor i := range b.msgChans {\n+\t\tb.closed.Add(1)\n+\t\tgo b.sendQueue(i)\n+\t}\n+\treturn b\n+}\n+\n+func (b *broadcaster) Close() {\n+\tclose(b.closedCh)\n+\tb.closed.Wait()\n+}\n+\n+func (b *broadcaster) unicastOne(msg *pb.Message, dest uint64, wait chan bool) {\n+\tdefer func() { wait <- true }()\n+\n+\tselect {\n+\tcase b.msgChans[dest] <- msg:\n+\t\treturn\n+\tcase <-time.After(1 * time.Second):\n+\t\treturn\n+\tcase <-b.closedCh:\n+\t\treturn\n+\t}\n+}\n+\n+func (b *broadcaster) send(msg *pb.Message, dest *uint64) error {\n+\tselect {\n+\tcase <-b.closedCh:\n+\t\treturn fmt.Errorf(\"broadcaster closed\")\n+\tdefault:\n+\t}\n+\n+\tvar destCount int\n+\tvar required int\n+\tif dest != nil {\n+\t\tdestCount = 1\n+\t\trequired = 1\n+\t} else {\n+\t\tdestCount = len(b.msgChans)\n+\t\trequired = destCount - b.f\n+\t}\n+\n+\twait := make(chan bool, destCount)","path":"consensus/obcpbft/broadcast.go","position":100,"original_position":100,"commit_id":"d73751ce98517fe401a3d590da18e0fff34b5d31","original_commit_id":"d73751ce98517fe401a3d590da18e0fff34b5d31","user":{"login":"jyellick","id":7431583,"avatar_url":"https://avatars.githubusercontent.com/u/7431583?v=3","gravatar_id":"","url":"https://api.github.com/users/jyellick","html_url":"https://github.com/jyellick","followers_url":"https://api.github.com/users/jyellick/followers","following_url":"https://api.github.com/users/jyellick/following{/other_user}","gists_url":"https://api.github.com/users/jyellick/gists{/gist_id}","starred_url":"https://api.github.com/users/jyellick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jyellick/subscriptions","organizations_url":"https://api.github.com/users/jyellick/orgs","repos_url":"https://api.github.com/users/jyellick/repos","events_url":"https://api.github.com/users/jyellick/events{/privacy}","received_events_url":"https://api.github.com/users/jyellick/received_events","type":"User","site_admin":false},"body":"Why is this a channel of `bool`s? It seems like the return value is not used so it should be of `struct{}`s.","created_at":"2016-06-12T17:42:22Z","updated_at":"2016-06-12T17:42:22Z","html_url":"https://github.com/hyperledger/fabric/pull/1793#discussion_r66724571","pull_request_url":"https://api.github.com/repos/hyperledger/fabric/pulls/1793","_links":{"self":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/comments/66724571"},"html":{"href":"https://github.com/hyperledger/fabric/pull/1793#discussion_r66724571"},"pull_request":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/1793"}}},"pull_request":{"url":"https://api.github.com/repos/hyperledger/fabric/pulls/1793","id":73427826,"html_url":"https://github.com/hyperledger/fabric/pull/1793","diff_url":"https://github.com/hyperledger/fabric/pull/1793.diff","patch_url":"https://github.com/hyperledger/fabric/pull/1793.patch","issue_url":"https://api.github.com/repos/hyperledger/fabric/issues/1793","number":1793,"state":"open","locked":false,"title":"consensus: non-blocking broadcast","user":{"login":"corecode","id":177979,"avatar_url":"https://avatars.githubusercontent.com/u/177979?v=3","gravatar_id":"","url":"https://api.github.com/users/corecode","html_url":"https://github.com/corecode","followers_url":"https://api.github.com/users/corecode/followers","following_url":"https://api.github.com/users/corecode/following{/other_user}","gists_url":"https://api.github.com/users/corecode/gists{/gist_id}","starred_url":"https://api.github.com/users/corecode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/corecode/subscriptions","organizations_url":"https://api.github.com/users/corecode/orgs","repos_url":"https://api.github.com/users/corecode/repos","events_url":"https://api.github.com/users/corecode/events{/privacy}","received_events_url":"https://api.github.com/users/corecode/received_events","type":"User","site_admin":false},"body":"<!--- Provide a general summary of your changes in the Title above -->\r\n\r\n## Description\r\n<!--- Describe your changes in detail. -->\r\nIntroduces a broadcaster service, which will block only for N-f replicas, so that a byzantine replica cannot halt the network.\r\n\r\n## Motivation and Context\r\n<!--- Why is this change required? What problem does it solve? -->\r\n<!--- If it fixes an open issue, please link to the issue here. -->\r\nFixes #1056 \r\n\r\n## How Has This Been Tested?\r\n<!--- Please describe in detail how you tested your changes. -->\r\n<!--- If this PR does not contain a new test case, explain why. -->\r\nnew unit tests, new bddtest\r\n\r\n## Checklist:\r\n<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->\r\n<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->\r\n- [x] I have added a [Signed-off-by](https://github.com/hyperledger/fabric/blob/master/CONTRIBUTING.md#legal-stuff)\r\n- [x] Either no new documentation is required by this change, OR I added new documentation\r\n- [x] Either no new tests are required by this change, OR I added new tests\r\n- [x] I have run [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/), and [golint](https://github.com/golang/lint). I have cleaned up all valid errors and warnings in code I have added or modified. These tools may generate false positives. Don't be worried about ignoring some errors or warnings. The goal is clean, consistent, and readable code.\r\n\r\nSigned-off-by:\r\nSimon Schubert <sis@zurich.ibm.com>","created_at":"2016-06-10T20:01:19Z","updated_at":"2016-06-12T17:42:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"78a2d05fb1f8906862fc5606d628e3891548662c","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/hyperledger/fabric/pulls/1793/commits","review_comments_url":"https://api.github.com/repos/hyperledger/fabric/pulls/1793/comments","review_comment_url":"https://api.github.com/repos/hyperledger/fabric/pulls/comments{/number}","comments_url":"https://api.github.com/repos/hyperledger/fabric/issues/1793/comments","statuses_url":"https://api.github.com/repos/hyperledger/fabric/statuses/d73751ce98517fe401a3d590da18e0fff34b5d31","head":{"label":"corecode:byz-broadcast","ref":"byz-broadcast","sha":"d73751ce98517fe401a3d590da18e0fff34b5d31","user":{"login":"corecode","id":177979,"avatar_url":"https://avatars.githubusercontent.com/u/177979?v=3","gravatar_id":"","url":"https://api.github.com/users/corecode","html_url":"https://github.com/corecode","followers_url":"https://api.github.com/users/corecode/followers","following_url":"https://api.github.com/users/corecode/following{/other_user}","gists_url":"https://api.github.com/users/corecode/gists{/gist_id}","starred_url":"https://api.github.com/users/corecode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/corecode/subscriptions","organizations_url":"https://api.github.com/users/corecode/orgs","repos_url":"https://api.github.com/users/corecode/repos","events_url":"https://api.github.com/users/corecode/events{/privacy}","received_events_url":"https://api.github.com/users/corecode/received_events","type":"User","site_admin":false},"repo":{"id":52092618,"name":"fabric","full_name":"corecode/fabric","owner":{"login":"corecode","id":177979,"avatar_url":"https://avatars.githubusercontent.com/u/177979?v=3","gravatar_id":"","url":"https://api.github.com/users/corecode","html_url":"https://github.com/corecode","followers_url":"https://api.github.com/users/corecode/followers","following_url":"https://api.github.com/users/corecode/following{/other_user}","gists_url":"https://api.github.com/users/corecode/gists{/gist_id}","starred_url":"https://api.github.com/users/corecode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/corecode/subscriptions","organizations_url":"https://api.github.com/users/corecode/orgs","repos_url":"https://api.github.com/users/corecode/repos","events_url":"https://api.github.com/users/corecode/events{/privacy}","received_events_url":"https://api.github.com/users/corecode/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/corecode/fabric","description":"Blockchain fabric code","fork":true,"url":"https://api.github.com/repos/corecode/fabric","forks_url":"https://api.github.com/repos/corecode/fabric/forks","keys_url":"https://api.github.com/repos/corecode/fabric/keys{/key_id}","collaborators_url":"https://api.github.com/repos/corecode/fabric/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/corecode/fabric/teams","hooks_url":"https://api.github.com/repos/corecode/fabric/hooks","issue_events_url":"https://api.github.com/repos/corecode/fabric/issues/events{/number}","events_url":"https://api.github.com/repos/corecode/fabric/events","assignees_url":"https://api.github.com/repos/corecode/fabric/assignees{/user}","branches_url":"https://api.github.com/repos/corecode/fabric/branches{/branch}","tags_url":"https://api.github.com/repos/corecode/fabric/tags","blobs_url":"https://api.github.com/repos/corecode/fabric/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/corecode/fabric/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/corecode/fabric/git/refs{/sha}","trees_url":"https://api.github.com/repos/corecode/fabric/git/trees{/sha}","statuses_url":"https://api.github.com/repos/corecode/fabric/statuses/{sha}","languages_url":"https://api.github.com/repos/corecode/fabric/languages","stargazers_url":"https://api.github.com/repos/corecode/fabric/stargazers","contributors_url":"https://api.github.com/repos/corecode/fabric/contributors","subscribers_url":"https://api.github.com/repos/corecode/fabric/subscribers","subscription_url":"https://api.github.com/repos/corecode/fabric/subscription","commits_url":"https://api.github.com/repos/corecode/fabric/commits{/sha}","git_commits_url":"https://api.github.com/repos/corecode/fabric/git/commits{/sha}","comments_url":"https://api.github.com/repos/corecode/fabric/comments{/number}","issue_comment_url":"https://api.github.com/repos/corecode/fabric/issues/comments{/number}","contents_url":"https://api.github.com/repos/corecode/fabric/contents/{+path}","compare_url":"https://api.github.com/repos/corecode/fabric/compare/{base}...{head}","merges_url":"https://api.github.com/repos/corecode/fabric/merges","archive_url":"https://api.github.com/repos/corecode/fabric/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/corecode/fabric/downloads","issues_url":"https://api.github.com/repos/corecode/fabric/issues{/number}","pulls_url":"https://api.github.com/repos/corecode/fabric/pulls{/number}","milestones_url":"https://api.github.com/repos/corecode/fabric/milestones{/number}","notifications_url":"https://api.github.com/repos/corecode/fabric/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/corecode/fabric/labels{/name}","releases_url":"https://api.github.com/repos/corecode/fabric/releases{/id}","deployments_url":"https://api.github.com/repos/corecode/fabric/deployments","created_at":"2016-02-19T14:20:57Z","updated_at":"2016-04-05T09:44:02Z","pushed_at":"2016-06-10T19:58:49Z","git_url":"git://github.com/corecode/fabric.git","ssh_url":"git@github.com:corecode/fabric.git","clone_url":"https://github.com/corecode/fabric.git","svn_url":"https://github.com/corecode/fabric","homepage":"","size":43570,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"hyperledger:master","ref":"master","sha":"bfc2b868e328d24cfe060d03f430d91269955937","user":{"login":"hyperledger","id":7657900,"avatar_url":"https://avatars.githubusercontent.com/u/7657900?v=3","gravatar_id":"","url":"https://api.github.com/users/hyperledger","html_url":"https://github.com/hyperledger","followers_url":"https://api.github.com/users/hyperledger/followers","following_url":"https://api.github.com/users/hyperledger/following{/other_user}","gists_url":"https://api.github.com/users/hyperledger/gists{/gist_id}","starred_url":"https://api.github.com/users/hyperledger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hyperledger/subscriptions","organizations_url":"https://api.github.com/users/hyperledger/orgs","repos_url":"https://api.github.com/users/hyperledger/repos","events_url":"https://api.github.com/users/hyperledger/events{/privacy}","received_events_url":"https://api.github.com/users/hyperledger/received_events","type":"Organization","site_admin":false},"repo":{"id":42975662,"name":"fabric","full_name":"hyperledger/fabric","owner":{"login":"hyperledger","id":7657900,"avatar_url":"https://avatars.githubusercontent.com/u/7657900?v=3","gravatar_id":"","url":"https://api.github.com/users/hyperledger","html_url":"https://github.com/hyperledger","followers_url":"https://api.github.com/users/hyperledger/followers","following_url":"https://api.github.com/users/hyperledger/following{/other_user}","gists_url":"https://api.github.com/users/hyperledger/gists{/gist_id}","starred_url":"https://api.github.com/users/hyperledger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hyperledger/subscriptions","organizations_url":"https://api.github.com/users/hyperledger/orgs","repos_url":"https://api.github.com/users/hyperledger/repos","events_url":"https://api.github.com/users/hyperledger/events{/privacy}","received_events_url":"https://api.github.com/users/hyperledger/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/hyperledger/fabric","description":"Fabric is a blockchain project in Incubation proposed to the community and documented at https://goo.gl/RYQZ5N.  Information on what Incubation entails can be found in the Hyperledger Project Lifecycle document (https://goo.gl/4edNRc)","fork":false,"url":"https://api.github.com/repos/hyperledger/fabric","forks_url":"https://api.github.com/repos/hyperledger/fabric/forks","keys_url":"https://api.github.com/repos/hyperledger/fabric/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hyperledger/fabric/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hyperledger/fabric/teams","hooks_url":"https://api.github.com/repos/hyperledger/fabric/hooks","issue_events_url":"https://api.github.com/repos/hyperledger/fabric/issues/events{/number}","events_url":"https://api.github.com/repos/hyperledger/fabric/events","assignees_url":"https://api.github.com/repos/hyperledger/fabric/assignees{/user}","branches_url":"https://api.github.com/repos/hyperledger/fabric/branches{/branch}","tags_url":"https://api.github.com/repos/hyperledger/fabric/tags","blobs_url":"https://api.github.com/repos/hyperledger/fabric/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hyperledger/fabric/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hyperledger/fabric/git/refs{/sha}","trees_url":"https://api.github.com/repos/hyperledger/fabric/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hyperledger/fabric/statuses/{sha}","languages_url":"https://api.github.com/repos/hyperledger/fabric/languages","stargazers_url":"https://api.github.com/repos/hyperledger/fabric/stargazers","contributors_url":"https://api.github.com/repos/hyperledger/fabric/contributors","subscribers_url":"https://api.github.com/repos/hyperledger/fabric/subscribers","subscription_url":"https://api.github.com/repos/hyperledger/fabric/subscription","commits_url":"https://api.github.com/repos/hyperledger/fabric/commits{/sha}","git_commits_url":"https://api.github.com/repos/hyperledger/fabric/git/commits{/sha}","comments_url":"https://api.github.com/repos/hyperledger/fabric/comments{/number}","issue_comment_url":"https://api.github.com/repos/hyperledger/fabric/issues/comments{/number}","contents_url":"https://api.github.com/repos/hyperledger/fabric/contents/{+path}","compare_url":"https://api.github.com/repos/hyperledger/fabric/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hyperledger/fabric/merges","archive_url":"https://api.github.com/repos/hyperledger/fabric/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hyperledger/fabric/downloads","issues_url":"https://api.github.com/repos/hyperledger/fabric/issues{/number}","pulls_url":"https://api.github.com/repos/hyperledger/fabric/pulls{/number}","milestones_url":"https://api.github.com/repos/hyperledger/fabric/milestones{/number}","notifications_url":"https://api.github.com/repos/hyperledger/fabric/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hyperledger/fabric/labels{/name}","releases_url":"https://api.github.com/repos/hyperledger/fabric/releases{/id}","deployments_url":"https://api.github.com/repos/hyperledger/fabric/deployments","created_at":"2015-09-23T03:17:14Z","updated_at":"2016-06-12T10:00:16Z","pushed_at":"2016-06-12T17:25:59Z","git_url":"git://github.com/hyperledger/fabric.git","ssh_url":"git@github.com:hyperledger/fabric.git","clone_url":"https://github.com/hyperledger/fabric.git","svn_url":"https://github.com/hyperledger/fabric","homepage":"","size":77556,"stargazers_count":765,"watchers_count":765,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":679,"mirror_url":null,"open_issues_count":359,"forks":679,"open_issues":359,"watchers":765,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/1793"},"html":{"href":"https://github.com/hyperledger/fabric/pull/1793"},"issue":{"href":"https://api.github.com/repos/hyperledger/fabric/issues/1793"},"comments":{"href":"https://api.github.com/repos/hyperledger/fabric/issues/1793/comments"},"review_comments":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/1793/comments"},"review_comment":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/1793/commits"},"statuses":{"href":"https://api.github.com/repos/hyperledger/fabric/statuses/d73751ce98517fe401a3d590da18e0fff34b5d31"}}}}
{"actor":{"display_login":"jyellick"}}