{"action":"closed","number":1755,"pull_request":{"url":"https://api.github.com/repos/hyperledger/fabric/pulls/1755","id":73087853,"html_url":"https://github.com/hyperledger/fabric/pull/1755","diff_url":"https://github.com/hyperledger/fabric/pull/1755.diff","patch_url":"https://github.com/hyperledger/fabric/pull/1755.patch","issue_url":"https://api.github.com/repos/hyperledger/fabric/issues/1755","number":1755,"state":"closed","locked":false,"title":"Statetransfer full state block hole fix","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":"<!--- Provide a general summary of your changes in the Title above -->\r\n\r\n## Description\r\nThis PR builds on top of PR #1749 so please consider only the latest commit for code review.\r\n\r\nThis changeset causes state transfer to check for missing blocks after state transfer skips to a point in time via a state snapshot.\r\n\r\n## Motivation and Context\r\nVia #1091, the ledger reported `null` blocks on occasion.  After investigation, these seems to occur when there is a missing block in the ledger (this should be handled more cleanly by the REST API, but that is a separate issue).  These 'missing blocks' turn out to be caused by state transfer falling sufficiently behind, that is moves to a point in time in the future.  When this completes, state transfer was not filling in the missing blocks in the background (despite its design to do so).\r\n\r\nThis was caused by a relatively simple bug, where `break` was used inside a select statement, when it was intended to break from the enclosing for loop.  This bug has been fixed.\r\n\r\nAdditionally, there was some small logical inefficiencies which are addressed in this changeset.  Rather than retrieve blocks, then see if there are sufficient deltas to recover, this change now checks before the block retrieval.  Similarly the state is detected as invalid when comparing against the known state hash from a valid block, rather than explicitly invalidating it (as the update does).\r\n\r\nDoes not fix, but is relevant to #1091 \r\n\r\n## How Has This Been Tested?\r\nAn existing test case has been enhanced to fail under the old behavior, and verifies that the entire chain is recovered after one of these 'skip' operations.\r\n\r\n## Checklist:\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: Jason Yellick <jyellick@us.ibm.com>","created_at":"2016-06-08T17:30:02Z","updated_at":"2016-06-09T21:57:12Z","closed_at":"2016-06-09T21:57:12Z","merged_at":"2016-06-09T21:57:12Z","merge_commit_sha":"15e748559d2c5fce90d88b60cf12d7ea571feb0f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/hyperledger/fabric/pulls/1755/commits","review_comments_url":"https://api.github.com/repos/hyperledger/fabric/pulls/1755/comments","review_comment_url":"https://api.github.com/repos/hyperledger/fabric/pulls/comments{/number}","comments_url":"https://api.github.com/repos/hyperledger/fabric/issues/1755/comments","statuses_url":"https://api.github.com/repos/hyperledger/fabric/statuses/bd5d50b3ad81f898859e09d2d25b99dc1dae496b","head":{"label":"jyellick:statetransfer-full-state-block-hole-fix","ref":"statetransfer-full-state-block-hole-fix","sha":"bd5d50b3ad81f898859e09d2d25b99dc1dae496b","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},"repo":{"id":55510365,"name":"fabric","full_name":"jyellick/fabric","owner":{"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},"private":false,"html_url":"https://github.com/jyellick/fabric","description":"Blockchain fabric incubator code","fork":true,"url":"https://api.github.com/repos/jyellick/fabric","forks_url":"https://api.github.com/repos/jyellick/fabric/forks","keys_url":"https://api.github.com/repos/jyellick/fabric/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jyellick/fabric/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jyellick/fabric/teams","hooks_url":"https://api.github.com/repos/jyellick/fabric/hooks","issue_events_url":"https://api.github.com/repos/jyellick/fabric/issues/events{/number}","events_url":"https://api.github.com/repos/jyellick/fabric/events","assignees_url":"https://api.github.com/repos/jyellick/fabric/assignees{/user}","branches_url":"https://api.github.com/repos/jyellick/fabric/branches{/branch}","tags_url":"https://api.github.com/repos/jyellick/fabric/tags","blobs_url":"https://api.github.com/repos/jyellick/fabric/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jyellick/fabric/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jyellick/fabric/git/refs{/sha}","trees_url":"https://api.github.com/repos/jyellick/fabric/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jyellick/fabric/statuses/{sha}","languages_url":"https://api.github.com/repos/jyellick/fabric/languages","stargazers_url":"https://api.github.com/repos/jyellick/fabric/stargazers","contributors_url":"https://api.github.com/repos/jyellick/fabric/contributors","subscribers_url":"https://api.github.com/repos/jyellick/fabric/subscribers","subscription_url":"https://api.github.com/repos/jyellick/fabric/subscription","commits_url":"https://api.github.com/repos/jyellick/fabric/commits{/sha}","git_commits_url":"https://api.github.com/repos/jyellick/fabric/git/commits{/sha}","comments_url":"https://api.github.com/repos/jyellick/fabric/comments{/number}","issue_comment_url":"https://api.github.com/repos/jyellick/fabric/issues/comments{/number}","contents_url":"https://api.github.com/repos/jyellick/fabric/contents/{+path}","compare_url":"https://api.github.com/repos/jyellick/fabric/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jyellick/fabric/merges","archive_url":"https://api.github.com/repos/jyellick/fabric/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jyellick/fabric/downloads","issues_url":"https://api.github.com/repos/jyellick/fabric/issues{/number}","pulls_url":"https://api.github.com/repos/jyellick/fabric/pulls{/number}","milestones_url":"https://api.github.com/repos/jyellick/fabric/milestones{/number}","notifications_url":"https://api.github.com/repos/jyellick/fabric/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jyellick/fabric/labels{/name}","releases_url":"https://api.github.com/repos/jyellick/fabric/releases{/id}","deployments_url":"https://api.github.com/repos/jyellick/fabric/deployments","created_at":"2016-04-05T13:31:56Z","updated_at":"2016-04-05T13:31:58Z","pushed_at":"2016-06-09T13:28:15Z","git_url":"git://github.com/jyellick/fabric.git","ssh_url":"git@github.com:jyellick/fabric.git","clone_url":"https://github.com/jyellick/fabric.git","svn_url":"https://github.com/jyellick/fabric","homepage":"","size":43022,"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":"2d43be93477d3f105ea19969f84b23f0dc25d565","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-09T21:34:11Z","pushed_at":"2016-06-09T21:57:12Z","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":77436,"stargazers_count":755,"watchers_count":755,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":669,"mirror_url":null,"open_issues_count":338,"forks":669,"open_issues":338,"watchers":755,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/1755"},"html":{"href":"https://github.com/hyperledger/fabric/pull/1755"},"issue":{"href":"https://api.github.com/repos/hyperledger/fabric/issues/1755"},"comments":{"href":"https://api.github.com/repos/hyperledger/fabric/issues/1755/comments"},"review_comments":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/1755/comments"},"review_comment":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/hyperledger/fabric/pulls/1755/commits"},"statuses":{"href":"https://api.github.com/repos/hyperledger/fabric/statuses/bd5d50b3ad81f898859e09d2d25b99dc1dae496b"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"binhn","id":3342057,"avatar_url":"https://avatars.githubusercontent.com/u/3342057?v=3","gravatar_id":"","url":"https://api.github.com/users/binhn","html_url":"https://github.com/binhn","followers_url":"https://api.github.com/users/binhn/followers","following_url":"https://api.github.com/users/binhn/following{/other_user}","gists_url":"https://api.github.com/users/binhn/gists{/gist_id}","starred_url":"https://api.github.com/users/binhn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/binhn/subscriptions","organizations_url":"https://api.github.com/users/binhn/orgs","repos_url":"https://api.github.com/users/binhn/repos","events_url":"https://api.github.com/users/binhn/events{/privacy}","received_events_url":"https://api.github.com/users/binhn/received_events","type":"User","site_admin":false},"comments":3,"review_comments":0,"commits":2,"additions":132,"deletions":11,"changed_files":7}}
{"actor":{"display_login":"binhn"}}