{
 "number": 35321,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/35321",
 "title": "p2p: Misbehave on invalid compact block in optimistic reconstruction",
 "author": "ViniciusCestarii",
 "author_association": "CONTRIBUTOR",
 "created_at": "2026-05-19T13:36:15Z",
 "updated_at": "2026-09-04T07:57:23Z",
 "age_days": 121,
 "draft": false,
 "labels": [
  "P2P"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "0fc9dc02763e44f693920f02a21ed025aebc89a1",
 "head_ref": "p2p-misbehave-invalid-cmpctblock-optimistic",
 "head_repo": "ViniciusCestarii/bitcoin",
 "head_history": [
  {
   "t": "2026-05-28T01:37:03Z",
   "sha": "0fc9dc02763e44f693920f02a21ed025aebc89a1"
  }
 ],
 "additions": 41,
 "deletions": 1,
 "changed_files": 2,
 "commit_count": 2,
 "size_bucket": "S",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_ack": [
     {
      "login": "sedited",
      "url": "https://github.com/bitcoin/bitcoin/pull/35321#issuecomment-5537496400"
     }
    ],
    "stale_ack": [
     {
      "login": "davidgumberg",
      "url": "https://github.com/bitcoin/bitcoin/pull/35321#issuecomment-4550701587"
     },
     {
      "login": "w0xlt",
      "url": "https://github.com/bitcoin/bitcoin/pull/35321#pullrequestreview-4370701324"
     }
    ]
   },
   "conflicts": []
  }
 },
 "acks_parsed": {
  "davidgumberg": {
   "kind": "ack",
   "hash": null,
   "t": "2026-05-27T02:25:00Z",
   "stale": true
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 1,
  "concept_ack": 0,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "davidgumberg",
   "sedited",
   "w0xlt"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-05-29T14:29:08Z",
  "last_reviewer_activity": "2026-09-04T07:57:20Z",
  "last_reviewer": "sedited",
  "author_silent_days": 111,
  "waiting_on_author_days": 13,
  "days_since_update": 13
 },
 "refs": {
  "mentioned": [
   32606
  ],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 32606,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-07-06",
    "title": "p2p: Drop unsolicited CMPCTBLOCK from non-HB peer and when blocksonly"
   }
  ],
  "conflicts": []
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "src/net_processing.cpp",
  "test/functional/p2p_compactblocks.py"
 ],
 "body": "When InitData returns READ_STATUS_INVALID (the peer sent malformed data) during optimistic compact block reconstruction. Call Misbehaving instead of silently ignoring it, consistent with the primary compact block handling path.\n\nRemoves the TODO added in 7017298eb2.",
 "commits": [
  {
   "sha": "4fe4b2a5fbf09ff4b3dbe622674ddbde6e4a8cfc",
   "date": "2026-05-28T01:33:30Z",
   "message": "p2p: misbehave on invalid compact block in optimistic reconstruction path"
  },
  {
   "sha": "0fc9dc02763e44f693920f02a21ed025aebc89a1",
   "date": "2026-05-28T01:34:03Z",
   "message": "test: disconnect receiving invalid cmpctblock on optmistic path"
  }
 ],
 "timeline": [
  {
   "t": "2026-05-27T00:38:34Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "Concept ACK This is consistent with how the happy path invalid compact blocks are treated, and consistent with how `Misbehaving()` is used in general, although for me it does open the question of what the rationale for `Misbehaving()` is and how and where it should be used, I asked this question on IRC: https://bitcoin-irc.chaincode.com/bitcoin-core-dev/2026-05-23#1779494915-1779495170; I don't think that question is blocking with this PR.\n\nNote, there is a silent merge conflict with  this PR and #32606."
  },
  {
   "t": "2026-05-27T00:46:03Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "test/functional/p2p_compactblocks.py",
   "commit": "0fc9dc02763e44f693920f02a21ed025aebc89a1",
   "in_reply_to": null,
   "text": "I think it would be better if all of the peers were ephemeral p2p conns like `stall1`, but this requires a little bit of refactoring which has been done in #32606, but isn't available yet, see e.g.:\n\nhttps://github.com/bitcoin/bitcoin/pull/32606/changes/856deb0d431d98253ca9ad968aa808b86061838e\n\nI think this is fine as-is, but if #32606 is merged first, this should incorporate similar changes:\n\n- `make_hb_to_candidate()` `stall1`, `stall2`, and `badpeer`\n- `stall3` does a solicited announcement, stall1 and 2 then do an unsolicited announcement\n- `badpeer` does its thing"
  },
  {
   "t": "2026-05-27T02:25:00Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "crACK https://github.com/bitcoin/bitcoin/pull/35321/commits/ce74a84ec73bae0b6d25f505745e28b38ee666d2"
  },
  {
   "t": "2026-05-27T08:25:28Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "src/net_processing.cpp",
   "commit": "0fc9dc02763e44f693920f02a21ed025aebc89a1",
   "in_reply_to": null,
   "text": "nit: comment could be added clarifying that only malformed compact blocks are considered misbehavior.\n\n```diff\n+ // Malformed compact blocks are peer misbehavior; reconstruction failures are not.\n  if (status == READ_STATUS_INVALID) Misbehaving(peer, \"invalid compact block\");\n```"
  },
  {
   "t": "2026-05-27T08:29:18Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "test/functional/p2p_compactblocks.py",
   "commit": "f24db575d33cdd6ebaac8cd02233bf9d266b7d42",
   "in_reply_to": null,
   "text": "nit: `valid_cmpct` can be renamed to `inflight_cmpct` to describe its role better.\n\n```diff\n-        valid_cmpct = HeaderAndShortIDs()\n-        valid_cmpct.header = CBlockHeader(block2)\n-        valid_cmpct.nonce = 0\n-        [k0, k1] = valid_cmpct.get_siphash_keys()\n-        valid_cmpct.shortids = [calculate_shortid(k0, k1, block2.vtx[0].wtxid_int)]\n+        inflight_cmpct = HeaderAndShortIDs()\n+        inflight_cmpct.header = CBlockHeader(block2)\n+        inflight_cmpct.nonce = 0\n+        [k0, k1] = inflight_cmpct.get_siphash_keys()\n+        inflight_cmpct.shortids = [calculate_shortid(k0, k1, block2.vtx[0].wtxid_int)]\n```"
  },
  {
   "t": "2026-05-27T08:34:54Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "test/functional/p2p_compactblocks.py",
   "commit": "0fc9dc02763e44f693920f02a21ed025aebc89a1",
   "in_reply_to": null,
   "text": "nit: comment could be added explaining why `PrefilledTransaction(1, block2.vtx[0])` is invalid.\n\n```diff\n+ # This prefilled transaction index is too high for a compact block with no shortids.\n  invalid_cmpct.prefilled_txn = [PrefilledTransaction(1, block2.vtx[0])]\n```"
  },
  {
   "t": "2026-05-27T08:37:04Z",
   "kind": "review",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "f24db575d33cdd6ebaac8cd02233bf9d266b7d42",
   "text": "Good catch ! ACK f24db575d33cdd6ebaac8cd02233bf9d266b7d42 with some non-blocking nits."
  },
  {
   "t": "2026-05-28T00:56:42Z",
   "kind": "review_comment",
   "who": "ViniciusCestarii",
   "assoc": "CONTRIBUTOR",
   "path": "test/functional/p2p_compactblocks.py",
   "commit": "0fc9dc02763e44f693920f02a21ed025aebc89a1",
   "in_reply_to": 3307751026,
   "text": "I agree, it's kinda awkward to read this way but at the same time I didn't want to refact it just to add this new test to cover this specific case. I'd happily update with your new changes in case your PR is merged first :)"
  },
  {
   "t": "2026-05-28T01:37:03Z",
   "kind": "force_push",
   "who": "ViniciusCestarii",
   "commit": "0fc9dc02763e44f693920f02a21ed025aebc89a1"
  },
  {
   "t": "2026-05-28T01:41:19Z",
   "kind": "review_comment",
   "who": "ViniciusCestarii",
   "assoc": "CONTRIBUTOR",
   "path": "src/net_processing.cpp",
   "commit": "0fc9dc02763e44f693920f02a21ed025aebc89a1",
   "in_reply_to": 3309502958,
   "text": "I agree, this makes the reconstruction failures case clearer. Done 4fe4b2a5fbf09ff4b3dbe622674ddbde6e4a8cfc"
  },
  {
   "t": "2026-05-28T01:42:43Z",
   "kind": "review_comment",
   "who": "ViniciusCestarii",
   "assoc": "CONTRIBUTOR",
   "path": "test/functional/p2p_compactblocks.py",
   "commit": "f24db575d33cdd6ebaac8cd02233bf9d266b7d42",
   "in_reply_to": 3309524017,
   "text": "I agree, this matches the MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK constant name. Done 0fc9dc02763e44f693920f02a21ed025aebc89a1"
  },
  {
   "t": "2026-05-28T01:45:31Z",
   "kind": "review_comment",
   "who": "ViniciusCestarii",
   "assoc": "CONTRIBUTOR",
   "path": "test/functional/p2p_compactblocks.py",
   "commit": "0fc9dc02763e44f693920f02a21ed025aebc89a1",
   "in_reply_to": 3309558187,
   "text": "I agree that a comment is welcome here. I added just `# This index will be too high` to match the previous comment on the same function. Done 0fc9dc02763e44f693920f02a21ed025aebc89a1"
  },
  {
   "t": "2026-05-28T01:56:48Z",
   "kind": "comment",
   "who": "ViniciusCestarii",
   "assoc": "CONTRIBUTOR",
   "text": "Looking back at the code I just noticed:\n\n```\n/** Maximum number of outstanding CMPCTBLOCK requests for the same block. */\nstatic const unsigned int MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK = 3;\n```\n\nThis seems imprecise:\n\nThe comment states \"outstanding CMPCTBLOCK requests for the same block\" but the context where MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK is used the CMPCTBLOCK is a message peers send to us (inbound),  not something we request. What we actually request are the missing transactions (via GETBLOCKTXN).\n\nMAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK is how many peers we're simultaneously doing compact block reconstruction with for the same block, but the name implies CMPCTBLOCKS inflight requests which is not what's happening.\n\nBut this is out of scope of this PR, just making an observation"
  },
  {
   "t": "2026-05-28T13:32:34Z",
   "kind": "comment",
   "who": "ViniciusCestarii",
   "assoc": "CONTRIBUTOR",
   "text": "[quoted text omitted]\n\nIt's a good question. It does seem to only punish software that is buggy / not strictly protocol conforming that are not causing harm. I thought about it and a reason could be to not waste connections on non protocol conforming peers, but still seems that Misbehave on first non comforming message may be too harsh."
  },
  {
   "t": "2026-05-29T14:29:08Z",
   "kind": "comment",
   "who": "ViniciusCestarii",
   "assoc": "CONTRIBUTOR",
   "text": "Forced push 0fc9dc0. Addressed @w0xlt feedback (forgot to explain the force-push earlier)"
  },
  {
   "t": "2026-07-24T07:31:01Z",
   "kind": "comment",
   "who": "sedited",
   "assoc": "MEMBER",
   "text": "@davidgumberg can you take another look here?"
  },
  {
   "t": "2026-09-04T07:57:20Z",
   "kind": "comment",
   "who": "sedited",
   "assoc": "MEMBER",
   "text": "Ping @w0xlt, you have a stale ACK here and the only change since last time seems to be reacting to your review."
  }
 ],
 "labels_log": [
  {
   "t": "2026-05-19T13:36:19Z",
   "action": "labeled",
   "label": "P2P",
   "who": "DrahtBot"
  },
  {
   "t": "2026-05-28T02:25:12Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-05-28T09:07:54Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-05-19T15:20:17Z",
   "kind": "closed",
   "who": "ViniciusCestarii"
  },
  {
   "t": "2026-05-19T15:20:33Z",
   "kind": "reopened",
   "who": "ViniciusCestarii"
  },
  {
   "t": "2026-05-19T15:21:23Z",
   "kind": "convert_to_draft",
   "who": "ViniciusCestarii"
  },
  {
   "t": "2026-05-20T13:09:17Z",
   "kind": "ready_for_review",
   "who": "ViniciusCestarii"
  }
 ],
 "text_chars": 4946,
 "text_tokens_estimate": 1236,
 "changed_paths": [
  "src/net_processing.cpp",
  "test/functional/p2p_compactblocks.py"
 ],
 "files": [
  {
   "path": "src/net_processing.cpp",
   "add": 2,
   "del": 1
  },
  {
   "path": "test/functional/p2p_compactblocks.py",
   "add": 39,
   "del": 0
  }
 ],
 "test_lines": 39,
 "git": {
  "head": "0fc9dc02763e44f693920f02a21ed025aebc89a1",
  "head_matches_backup": true,
  "base": "ed15e14b636bf741a7b48fd6804c94dce135ecac",
  "commits": [
   {
    "sha": "4fe4b2a5fb",
    "subject": "p2p: misbehave on invalid compact block in optimistic reconstruction path",
    "files": 1,
    "add": 2,
    "del": 1
   },
   {
    "sha": "0fc9dc0276",
    "subject": "test: disconnect receiving invalid cmpctblock on optmistic path",
    "files": 1,
    "add": 39,
    "del": 0
   }
  ],
  "patch_truncated": false
 },
 "input_hash": "67c3185db4783208",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}