{"action":"created","comment":{"url":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/comments/191147577","pull_request_review_id":123665048,"id":191147577,"diff_hunk":"@@ -9,122 +9,122 @@ export default class Block {\n     this.parent = parent;\n     this.height = height;\n     this.txList = [];\n+    this.txHashList = [];\n   }\n \n   addTx(tx) {\n-    if (this.txList.findIndex(compHash(tx.hash())) > -1) {\n+    if (this.txHashList.indexOf(tx.hash()) > -1) {\n       throw Error('tx already contained');\n     }\n     this.txList.push(tx);\n+    this.txHashList.push(tx.hash());\n+    // invalidate existing tree\n+    // todo: optimize not to recalculate the whole tree on every tx added\n+    this.merkleTree = null;\n     return this;\n   }\n \n-  hashTree(list) {\n-    if (list.length % 2 !== 0) {\n-      throw Error('uneven number of tx');\n-    }\n-    let payload;\n-    const rv = [];\n-    for (let i = 0; i < list.length; i += 2) {\n-      payload = Buffer.alloc(64);\n-      list[i].copy(payload, 0);\n-      list[i + 1].copy(payload, 32);\n-      rv.push(ethUtil.sha3(payload));\n+  getMerkleTree() {\n+    if (!this.merkleTree) {\n+      const hashBufs = this.txList.map(tx => tx.toRaw());\n+      this.merkleTree = new MerkleTree(hashBufs);\n     }\n-    if (rv.length === 1) {\n-      return `0x${rv[0].toString('hex')}`;\n-    }\n-    return this.hashTree(rv);\n+    return this.merkleTree;\n   }\n \n   merkleRoot() {\n-    const hashBufs = [];\n-    for (let i = 0; i < this.txList.length; i += 1) {\n-      hashBufs.push(this.txList[i].hashBuf());\n-    }\n-    if (hashBufs.length % 2 !== 0) {\n-      hashBufs.push(Buffer.alloc(32, 0));\n-    }\n-    return this.hashTree(hashBufs);\n+    return this.getMerkleTree().getHexRoot();\n   }\n \n-  unsigedHeader(payload) {\n+  unsignedHeader(payload) {\n     payload.write(this.parent.replace('0x', ''), 0, 'hex');\n-    const big = ~~(this.height / MAX_UINT32);  // eslint-disable-line no-bitwise\n-    payload.writeUInt32BE(big, 32);\n-    const low = (this.height % MAX_UINT32) - big;\n-    payload.writeUInt32BE(low, 36);\n+    writeUint64(payload, this.height, 32);\n     payload.write(this.merkleRoot().replace('0x', ''), 40, 'hex');\n     return payload;\n   }\n \n   sigHash() {\n-    return ethUtil.sha3(this.unsigedHeader(Buffer.alloc(72, 0)));\n+    return ethUtil.sha3(this.unsignedHeader(Buffer.alloc(72, 0)));\n   }\n \n   sign(privKey) {\n-    const privBuf = new Buffer(privKey.replace('0x', ''), 'hex');\n+    const privBuf = toBuffer(privKey);\n     const sig = ethUtil.ecsign(this.sigHash(), privBuf);\n     this.v = sig.v;\n     this.r = sig.r;\n     this.s = sig.s;\n-    return [sig.v, `0x${sig.r.toString('hex')}`, `0x${sig.s.toString('hex')}`];\n+    return [sig.v, bufferToHex(sig.r), bufferToHex(sig.s)];\n   }\n \n   hash() {\n     if (!this.v || !this.r || !this.s) {\n       throw new Error('not signed yet');\n     }\n-    const payload = this.unsigedHeader(Buffer.alloc(137, 0));\n+    const payload = this.unsignedHeader(Buffer.alloc(137, 0));\n \n     payload.writeUInt8(this.v, 72);\n     this.r.copy(payload, 73);\n     this.s.copy(payload, 105);\n     return ethUtil.bufferToHex(ethUtil.sha3(payload));\n   }\n \n-  //  _txData = [ 32b blockHash, 32b r, 32b s, (4b offset, 8b pos, 1b v, ..00.., 1b txData),\n-  // 32b txData, 32b proof, 32b proof ]\n-  proof(txData, pos, proof) {\n+  // Returns merkle proof for given tx\n+  // [\n+  // 32b - blockHash\n+  // 32b - r\n+  // 32b - s,\n+  // 32b - (4b tx length, 4b pos, 1b v, ..00.., Xb txData),\n+  // 32b - txData,\n+  // ... <more 32b tx data if needed>\n+  // 32b - proof,\n+  // ... <more 32b proofs if needed>\n+  // ]\n+  proof(tx) {\n+    const txData = tx.toRaw();\n+    const pos = this.txHashList.indexOf(tx.hash());\n+    if (pos < 0) {\n+      throw Error('tx not in the block');\n+    }\n     const slices = [];\n     slices.push(this.hash());\n-    slices.push(`0x${this.r.toString('hex')}`);\n-    slices.push(`0x${this.s.toString('hex')}`);\n-\n-    const sliceCount = Math.floor(txData.length / 32) + 1;\n-\n-    let payload = Buffer.alloc(32);\n+    slices.push(bufferToHex(this.r));\n+    slices.push(bufferToHex(this.s));\n+\n+    // Slices with tx metadata, v-sig and tx data\n+    // metadata size: 4 bytes tx length + 4 bytes tx index + 1 byte v-sig = 9 bytes\n+    const metadataAndTxLength = 9 + txData.length;\n+    // align to 32 bytes, so that e.g. 38 bytes will be stored in 64 bytes buffer\n+    const doubleWordAlignedLength = metadataAndTxLength + (32 - (metadataAndTxLength % 32));\n+    const txPayload = Buffer.alloc(doubleWordAlignedLength);\n     // tx length\n-    payload.writeUInt32BE(txData.length, 0);\n-    // offset\n-    let offset = ((txData.length % 32) <= 19) ? 32 - (txData.length % 32) : (32 - (txData.length % 32)) + 32;\n-    offset += 96;\n-    payload.writeUInt8(offset, 0);","path":"lib/block.js","position":148,"original_position":148,"commit_id":"29ca4587e77203ddcd6727a88ef43c3c76a42ae7","original_commit_id":"29ca4587e77203ddcd6727a88ef43c3c76a42ae7","user":{"login":"johannbarbie","id":659301,"avatar_url":"https://avatars1.githubusercontent.com/u/659301?v=4","gravatar_id":"","url":"https://api.github.com/users/johannbarbie","html_url":"https://github.com/johannbarbie","followers_url":"https://api.github.com/users/johannbarbie/followers","following_url":"https://api.github.com/users/johannbarbie/following{/other_user}","gists_url":"https://api.github.com/users/johannbarbie/gists{/gist_id}","starred_url":"https://api.github.com/users/johannbarbie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johannbarbie/subscriptions","organizations_url":"https://api.github.com/users/johannbarbie/orgs","repos_url":"https://api.github.com/users/johannbarbie/repos","events_url":"https://api.github.com/users/johannbarbie/events{/privacy}","received_events_url":"https://api.github.com/users/johannbarbie/received_events","type":"User","site_admin":false},"body":"we use only 2 bytes of the length, so we can overwrite the first 2 bytes.","created_at":"2018-05-28T08:44:11Z","updated_at":"2018-05-28T08:44:11Z","html_url":"https://github.com/parsec-labs/parsec-lib/pull/3#discussion_r191147577","pull_request_url":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/3","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/comments/191147577"},"html":{"href":"https://github.com/parsec-labs/parsec-lib/pull/3#discussion_r191147577"},"pull_request":{"href":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/3"}},"in_reply_to_id":191145980},"pull_request":{"url":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/3","id":189186570,"html_url":"https://github.com/parsec-labs/parsec-lib/pull/3","diff_url":"https://github.com/parsec-labs/parsec-lib/pull/3.diff","patch_url":"https://github.com/parsec-labs/parsec-lib/pull/3.patch","issue_url":"https://api.github.com/repos/parsec-labs/parsec-lib/issues/3","number":3,"state":"open","locked":false,"title":"Complete Primitive Data Structures","user":{"login":"troggy","id":163447,"avatar_url":"https://avatars1.githubusercontent.com/u/163447?v=4","gravatar_id":"","url":"https://api.github.com/users/troggy","html_url":"https://github.com/troggy","followers_url":"https://api.github.com/users/troggy/followers","following_url":"https://api.github.com/users/troggy/following{/other_user}","gists_url":"https://api.github.com/users/troggy/gists{/gist_id}","starred_url":"https://api.github.com/users/troggy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/troggy/subscriptions","organizations_url":"https://api.github.com/users/troggy/orgs","repos_url":"https://api.github.com/users/troggy/repos","events_url":"https://api.github.com/users/troggy/events{/privacy}","received_events_url":"https://api.github.com/users/troggy/received_events","type":"User","site_admin":false},"body":"- [x] make transaction a proper object holding Inputs and Outputs\r\n- [x] serialize on request with `.toRaw()`\r\n- [x] got rid of `Signer` object\r\n\r\nResolves:\r\n- https://github.com/parsec-labs/PIPs/wiki/Bounty_007\r\n- #1 \r\n- #2","created_at":"2018-05-19T12:43:37Z","updated_at":"2018-05-28T08:44:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"54bf9e7c63098d3025fa793b6a9c4ad825e3fb94","assignee":null,"assignees":[],"requested_reviewers":[{"login":"sunify","id":1477583,"avatar_url":"https://avatars3.githubusercontent.com/u/1477583?v=4","gravatar_id":"","url":"https://api.github.com/users/sunify","html_url":"https://github.com/sunify","followers_url":"https://api.github.com/users/sunify/followers","following_url":"https://api.github.com/users/sunify/following{/other_user}","gists_url":"https://api.github.com/users/sunify/gists{/gist_id}","starred_url":"https://api.github.com/users/sunify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sunify/subscriptions","organizations_url":"https://api.github.com/users/sunify/orgs","repos_url":"https://api.github.com/users/sunify/repos","events_url":"https://api.github.com/users/sunify/events{/privacy}","received_events_url":"https://api.github.com/users/sunify/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/3/commits","review_comments_url":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/3/comments","review_comment_url":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/comments{/number}","comments_url":"https://api.github.com/repos/parsec-labs/parsec-lib/issues/3/comments","statuses_url":"https://api.github.com/repos/parsec-labs/parsec-lib/statuses/29ca4587e77203ddcd6727a88ef43c3c76a42ae7","head":{"label":"parsec-labs:rich-transaction","ref":"rich-transaction","sha":"29ca4587e77203ddcd6727a88ef43c3c76a42ae7","user":{"login":"parsec-labs","id":24871304,"avatar_url":"https://avatars3.githubusercontent.com/u/24871304?v=4","gravatar_id":"","url":"https://api.github.com/users/parsec-labs","html_url":"https://github.com/parsec-labs","followers_url":"https://api.github.com/users/parsec-labs/followers","following_url":"https://api.github.com/users/parsec-labs/following{/other_user}","gists_url":"https://api.github.com/users/parsec-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/parsec-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parsec-labs/subscriptions","organizations_url":"https://api.github.com/users/parsec-labs/orgs","repos_url":"https://api.github.com/users/parsec-labs/repos","events_url":"https://api.github.com/users/parsec-labs/events{/privacy}","received_events_url":"https://api.github.com/users/parsec-labs/received_events","type":"Organization","site_admin":false},"repo":{"id":129519955,"name":"parsec-lib","full_name":"parsec-labs/parsec-lib","owner":{"login":"parsec-labs","id":24871304,"avatar_url":"https://avatars3.githubusercontent.com/u/24871304?v=4","gravatar_id":"","url":"https://api.github.com/users/parsec-labs","html_url":"https://github.com/parsec-labs","followers_url":"https://api.github.com/users/parsec-labs/followers","following_url":"https://api.github.com/users/parsec-labs/following{/other_user}","gists_url":"https://api.github.com/users/parsec-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/parsec-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parsec-labs/subscriptions","organizations_url":"https://api.github.com/users/parsec-labs/orgs","repos_url":"https://api.github.com/users/parsec-labs/repos","events_url":"https://api.github.com/users/parsec-labs/events{/privacy}","received_events_url":"https://api.github.com/users/parsec-labs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/parsec-labs/parsec-lib","description":"library for tx and block signing","fork":false,"url":"https://api.github.com/repos/parsec-labs/parsec-lib","forks_url":"https://api.github.com/repos/parsec-labs/parsec-lib/forks","keys_url":"https://api.github.com/repos/parsec-labs/parsec-lib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/parsec-labs/parsec-lib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/parsec-labs/parsec-lib/teams","hooks_url":"https://api.github.com/repos/parsec-labs/parsec-lib/hooks","issue_events_url":"https://api.github.com/repos/parsec-labs/parsec-lib/issues/events{/number}","events_url":"https://api.github.com/repos/parsec-labs/parsec-lib/events","assignees_url":"https://api.github.com/repos/parsec-labs/parsec-lib/assignees{/user}","branches_url":"https://api.github.com/repos/parsec-labs/parsec-lib/branches{/branch}","tags_url":"https://api.github.com/repos/parsec-labs/parsec-lib/tags","blobs_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/refs{/sha}","trees_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/parsec-labs/parsec-lib/statuses/{sha}","languages_url":"https://api.github.com/repos/parsec-labs/parsec-lib/languages","stargazers_url":"https://api.github.com/repos/parsec-labs/parsec-lib/stargazers","contributors_url":"https://api.github.com/repos/parsec-labs/parsec-lib/contributors","subscribers_url":"https://api.github.com/repos/parsec-labs/parsec-lib/subscribers","subscription_url":"https://api.github.com/repos/parsec-labs/parsec-lib/subscription","commits_url":"https://api.github.com/repos/parsec-labs/parsec-lib/commits{/sha}","git_commits_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/commits{/sha}","comments_url":"https://api.github.com/repos/parsec-labs/parsec-lib/comments{/number}","issue_comment_url":"https://api.github.com/repos/parsec-labs/parsec-lib/issues/comments{/number}","contents_url":"https://api.github.com/repos/parsec-labs/parsec-lib/contents/{+path}","compare_url":"https://api.github.com/repos/parsec-labs/parsec-lib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/parsec-labs/parsec-lib/merges","archive_url":"https://api.github.com/repos/parsec-labs/parsec-lib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/parsec-labs/parsec-lib/downloads","issues_url":"https://api.github.com/repos/parsec-labs/parsec-lib/issues{/number}","pulls_url":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls{/number}","milestones_url":"https://api.github.com/repos/parsec-labs/parsec-lib/milestones{/number}","notifications_url":"https://api.github.com/repos/parsec-labs/parsec-lib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/parsec-labs/parsec-lib/labels{/name}","releases_url":"https://api.github.com/repos/parsec-labs/parsec-lib/releases{/id}","deployments_url":"https://api.github.com/repos/parsec-labs/parsec-lib/deployments","created_at":"2018-04-14T13:34:31Z","updated_at":"2018-05-23T09:37:11Z","pushed_at":"2018-05-28T07:02:51Z","git_url":"git://github.com/parsec-labs/parsec-lib.git","ssh_url":"git@github.com:parsec-labs/parsec-lib.git","clone_url":"https://github.com/parsec-labs/parsec-lib.git","svn_url":"https://github.com/parsec-labs/parsec-lib","homepage":null,"size":71,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":3,"license":null,"forks":0,"open_issues":3,"watchers":1,"default_branch":"master"}},"base":{"label":"parsec-labs:master","ref":"master","sha":"1955f64862915a088a416d1313b996c8a9eb3ccc","user":{"login":"parsec-labs","id":24871304,"avatar_url":"https://avatars3.githubusercontent.com/u/24871304?v=4","gravatar_id":"","url":"https://api.github.com/users/parsec-labs","html_url":"https://github.com/parsec-labs","followers_url":"https://api.github.com/users/parsec-labs/followers","following_url":"https://api.github.com/users/parsec-labs/following{/other_user}","gists_url":"https://api.github.com/users/parsec-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/parsec-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parsec-labs/subscriptions","organizations_url":"https://api.github.com/users/parsec-labs/orgs","repos_url":"https://api.github.com/users/parsec-labs/repos","events_url":"https://api.github.com/users/parsec-labs/events{/privacy}","received_events_url":"https://api.github.com/users/parsec-labs/received_events","type":"Organization","site_admin":false},"repo":{"id":129519955,"name":"parsec-lib","full_name":"parsec-labs/parsec-lib","owner":{"login":"parsec-labs","id":24871304,"avatar_url":"https://avatars3.githubusercontent.com/u/24871304?v=4","gravatar_id":"","url":"https://api.github.com/users/parsec-labs","html_url":"https://github.com/parsec-labs","followers_url":"https://api.github.com/users/parsec-labs/followers","following_url":"https://api.github.com/users/parsec-labs/following{/other_user}","gists_url":"https://api.github.com/users/parsec-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/parsec-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parsec-labs/subscriptions","organizations_url":"https://api.github.com/users/parsec-labs/orgs","repos_url":"https://api.github.com/users/parsec-labs/repos","events_url":"https://api.github.com/users/parsec-labs/events{/privacy}","received_events_url":"https://api.github.com/users/parsec-labs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/parsec-labs/parsec-lib","description":"library for tx and block signing","fork":false,"url":"https://api.github.com/repos/parsec-labs/parsec-lib","forks_url":"https://api.github.com/repos/parsec-labs/parsec-lib/forks","keys_url":"https://api.github.com/repos/parsec-labs/parsec-lib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/parsec-labs/parsec-lib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/parsec-labs/parsec-lib/teams","hooks_url":"https://api.github.com/repos/parsec-labs/parsec-lib/hooks","issue_events_url":"https://api.github.com/repos/parsec-labs/parsec-lib/issues/events{/number}","events_url":"https://api.github.com/repos/parsec-labs/parsec-lib/events","assignees_url":"https://api.github.com/repos/parsec-labs/parsec-lib/assignees{/user}","branches_url":"https://api.github.com/repos/parsec-labs/parsec-lib/branches{/branch}","tags_url":"https://api.github.com/repos/parsec-labs/parsec-lib/tags","blobs_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/refs{/sha}","trees_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/parsec-labs/parsec-lib/statuses/{sha}","languages_url":"https://api.github.com/repos/parsec-labs/parsec-lib/languages","stargazers_url":"https://api.github.com/repos/parsec-labs/parsec-lib/stargazers","contributors_url":"https://api.github.com/repos/parsec-labs/parsec-lib/contributors","subscribers_url":"https://api.github.com/repos/parsec-labs/parsec-lib/subscribers","subscription_url":"https://api.github.com/repos/parsec-labs/parsec-lib/subscription","commits_url":"https://api.github.com/repos/parsec-labs/parsec-lib/commits{/sha}","git_commits_url":"https://api.github.com/repos/parsec-labs/parsec-lib/git/commits{/sha}","comments_url":"https://api.github.com/repos/parsec-labs/parsec-lib/comments{/number}","issue_comment_url":"https://api.github.com/repos/parsec-labs/parsec-lib/issues/comments{/number}","contents_url":"https://api.github.com/repos/parsec-labs/parsec-lib/contents/{+path}","compare_url":"https://api.github.com/repos/parsec-labs/parsec-lib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/parsec-labs/parsec-lib/merges","archive_url":"https://api.github.com/repos/parsec-labs/parsec-lib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/parsec-labs/parsec-lib/downloads","issues_url":"https://api.github.com/repos/parsec-labs/parsec-lib/issues{/number}","pulls_url":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls{/number}","milestones_url":"https://api.github.com/repos/parsec-labs/parsec-lib/milestones{/number}","notifications_url":"https://api.github.com/repos/parsec-labs/parsec-lib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/parsec-labs/parsec-lib/labels{/name}","releases_url":"https://api.github.com/repos/parsec-labs/parsec-lib/releases{/id}","deployments_url":"https://api.github.com/repos/parsec-labs/parsec-lib/deployments","created_at":"2018-04-14T13:34:31Z","updated_at":"2018-05-23T09:37:11Z","pushed_at":"2018-05-28T07:02:51Z","git_url":"git://github.com/parsec-labs/parsec-lib.git","ssh_url":"git@github.com:parsec-labs/parsec-lib.git","clone_url":"https://github.com/parsec-labs/parsec-lib.git","svn_url":"https://github.com/parsec-labs/parsec-lib","homepage":null,"size":71,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":3,"license":null,"forks":0,"open_issues":3,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/3"},"html":{"href":"https://github.com/parsec-labs/parsec-lib/pull/3"},"issue":{"href":"https://api.github.com/repos/parsec-labs/parsec-lib/issues/3"},"comments":{"href":"https://api.github.com/repos/parsec-labs/parsec-lib/issues/3/comments"},"review_comments":{"href":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/3/comments"},"review_comment":{"href":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/parsec-labs/parsec-lib/pulls/3/commits"},"statuses":{"href":"https://api.github.com/repos/parsec-labs/parsec-lib/statuses/29ca4587e77203ddcd6727a88ef43c3c76a42ae7"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"johannbarbie"}}