{
 "number": 36353,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/36353",
 "title": "kernel: document that blocks cache their check results",
 "author": "FlashWayne",
 "author_association": "CONTRIBUTOR",
 "created_at": "2026-09-26T22:36:41Z",
 "updated_at": "2026-10-10T16:01:35Z",
 "description_hash": "748635fc0ff20093",
 "age_days": 36,
 "draft": false,
 "labels": [
  "Validation"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "3add4efcd2af064e59678aa41748868c748f2731",
 "head_ref": "fix-kernel-block-check-cache",
 "head_repo": "FlashWayne/bitcoin",
 "head_history": [
  {
   "t": "2026-09-30T07:37:06Z",
   "sha": "ac8a65d9390a820d4b28947a02ed20f5016faae7"
  },
  {
   "t": "2026-10-08T17:25:53Z",
   "sha": "54b363a291b275b7cbc727a0683608d28ef0b2dc"
  }
 ],
 "additions": 11,
 "deletions": 0,
 "changed_files": 1,
 "commit_count": 3,
 "size_bucket": "S",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_ack": [
     {
      "login": "l0rinc",
      "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-5938501653"
     }
    ],
    "approach_nack": [
     {
      "login": "sedited",
      "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-6064504067"
     }
    ],
    "stale_ack": [
     {
      "login": "yuvicc",
      "url": "https://github.com/bitcoin/bitcoin/pull/36353#pullrequestreview-5362379358"
     },
     {
      "login": "jcastros",
      "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-5971806968"
     }
    ]
   },
   "conflicts": []
  }
 },
 "acks_parsed": {
  "yuvicc": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-09-30T05:54:16Z",
   "stale": false
  },
  "l0rinc": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-10-01T19:02:21Z",
   "stale": false
  },
  "sedited": {
   "kind": "approach_nack",
   "hash": null,
   "t": "2026-10-08T16:34:42Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 2,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 1
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "alexanderwiederin",
   "jcastros",
   "l0rinc",
   "sedited",
   "yuvicc"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-10-09T15:51:53Z",
  "last_reviewer_activity": "2026-10-09T15:33:09Z",
  "last_reviewer": "alexanderwiederin",
  "author_silent_days": 23,
  "waiting_on_author_days": 0,
  "days_since_update": 22
 },
 "refs": {
  "mentioned": [],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [],
  "conflicts": []
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "src/kernel/bitcoinkernel.cpp",
  "src/kernel/bitcoinkernel.h",
  "src/test/kernel/test_kernel.cpp"
 ],
 "body": "`CheckBlock` returns true right away when `block.fChecked` is set. In the kernel API a `btck_Block` wraps a shared `CBlock`, and `btck_block_copy` only adds a reference, so once a block passed `btck_block_check` or `btck_chainstate_manager_process_block`, later calls on it (or on a copy) skip the checks, whatever consensus params or flags are passed. For example a regtest block that has passed once with regtest params also returns 1 from `btck_block_check` with mainnet params.\n\nbitcoind isn't affected, since it only has one chainstate manager and one set of params. `btck_block_check` and custom signet params are new in 32.0, and the header docs don't mention this.\n\nFollowing sedited's review, this no longer copies the block on every call. It only documents on `btck_block_check` and `btck_chainstate_manager_process_block` that a block caches its check results and should only be used with one set of consensus parameters.",
 "commits": [
  {
   "sha": "54b363a291b275b7cbc727a0683608d28ef0b2dc",
   "date": "2026-10-08T17:25:49Z",
   "message": "kernel: document that blocks cache their check results\n\nA btck_Block caches the result of its context-free checks, and copies\nmade with btck_block_copy share that cache. Once a block passed\nbtck_block_check or btck_chainstate_manager_process_block, later calls\nwith other consensus parameters or flags are not checked again.\n\nDocument that a block should only be used with a single set of\nconsensus parameters, instead of paying for a copy on every call."
  },
  {
   "sha": "47cb9a682be8a4f5f75b4bad1aa8aba99c9bd8fd",
   "date": "2026-10-09T12:37:44Z",
   "message": "kernel: limit cache docs to blocks checked for POW and merkle root\n\nThe cache is only set if both the proof of work and the merkle root\nwere checked."
  },
  {
   "sha": "3add4efcd2af064e59678aa41748868c748f2731",
   "date": "2026-10-09T15:49:22Z",
   "message": "kernel: drop POW/merkle clause from process_block docs\n\nbtck_chainstate_manager_process_block always checks the proof of work\nand the merkle root, so the clause is only needed for btck_block_check."
  }
 ],
 "timeline": [
  {
   "t": "2026-09-30T05:54:16Z",
   "kind": "comment",
   "who": "yuvicc",
   "assoc": "CONTRIBUTOR",
   "text": "Concept ACK! Good observation.",
   "id": "c:5905037578",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-5905037578",
   "hash": "d13da53440d3bde0",
   "edited": null
  },
  {
   "t": "2026-09-30T06:38:26Z",
   "kind": "review_comment",
   "who": "yuvicc",
   "assoc": "CONTRIBUTOR",
   "path": "src/test/kernel/test_kernel.cpp",
   "commit": "ac8a65d9390a820d4b28947a02ed20f5016faae7",
   "in_reply_to": null,
   "text": "could also assert the reason for rejection:\n```cpp\nBOOST_CHECK(state.GetBlockValidationResult() == BlockValidationResult::CONSENSUS);\n```",
   "id": "rc:4141526992",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#discussion_r4141526992",
   "hash": "9900ca7b3a3f098b",
   "edited": "2026-09-30T07:08:54Z"
  },
  {
   "t": "2026-09-30T07:06:30Z",
   "kind": "review_comment",
   "who": "yuvicc",
   "assoc": "CONTRIBUTOR",
   "path": "src/kernel/bitcoinkernel.cpp",
   "commit": "9d735dae130dff17153c0aa5678b5cfb1999f00d",
   "in_reply_to": null,
   "text": "documenting would be useful `src/kernel/bitcoinkernel.h`, in the docs of both `btck_block_check` and `btck_chainstate_manager_process_block`:\n\n```c\n * The block is not modified, and earlier checks of it (e.g. under other\n * consensus params) do not affect the result.\n```",
   "id": "rc:4141764396",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#discussion_r4141764396",
   "hash": "bffa2604f7c2bcae",
   "edited": "2026-09-30T07:08:54Z"
  },
  {
   "t": "2026-09-30T07:08:54Z",
   "kind": "review",
   "who": "yuvicc",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "9d735dae130dff17153c0aa5678b5cfb1999f00d",
   "text": "cr-ACK 9d735dae130dff17153c0aa5678b5cfb1999f00d\n\nThe only overhead is that a block passed in a second time re-runs the context-free checks instead of returning early; for a duplicate `process_block` call, `AcceptBlock` still returns early on `fAlreadyHave`, so nothing is re-stored or re-connected.\n\nLeft some nits.",
   "id": "r:5362379358",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#pullrequestreview-5362379358",
   "hash": "2bb71944c9b5fcb8",
   "edited": null
  },
  {
   "t": "2026-09-30T07:37:06Z",
   "kind": "force_push",
   "who": "FlashWayne",
   "commit": "ac8a65d9390a820d4b28947a02ed20f5016faae7",
   "id": "push:ac8a65d9390a820d4b28947a02ed20f5016faae7"
  },
  {
   "t": "2026-09-30T07:39:13Z",
   "kind": "comment",
   "who": "FlashWayne",
   "assoc": "CONTRIBUTOR",
   "text": "Thanks for the review! Took both suggestions in ac8a65d939: the signet test now also asserts BlockValidationResult::CONSENSUS, and the note is added to the docs of btck_block_check and btck_chainstate_manager_process_block in bitcoinkernel.h.",
   "id": "c:5906509613",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-5906509613",
   "hash": "68d6bdf930d489f9",
   "edited": null
  },
  {
   "t": "2026-10-01T19:02:21Z",
   "kind": "comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "text": "Concept ACK",
   "id": "c:5938501653",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-5938501653",
   "hash": "e8334cc43879b73c",
   "edited": null
  },
  {
   "t": "2026-10-03T17:46:45Z",
   "kind": "comment",
   "who": "jcastros",
   "assoc": "CONTRIBUTOR",
   "text": "I tested ac8a65d939 with -DBUILD_KERNEL_LIB=ON. I ran the new tests with bitcoinkernel.cpp from the parent, ed7dd7cf4e, and test_kernel failed. When I put this commit's file back, it passed.\n\nThe description says 4 failures, and I saw 5. The extra check is the CONSENSUS result at test_kernel.cpp:1118, which wasn't in 9d735dae.\n\nShould this be backported to 32.x? btck_block_check is new in that release.\n\nACK ac8a65d939",
   "id": "c:5971806968",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-5971806968",
   "hash": "cc343ddb385236b5",
   "edited": null
  },
  {
   "t": "2026-10-03T18:23:58Z",
   "kind": "comment",
   "who": "FlashWayne",
   "assoc": "CONTRIBUTOR",
   "text": "Thanks for testing! You're right, the fifth one is the `CONSENSUS` assertion I added after yuvicc's review; I updated the description.\n\nOn backporting: `btck_block_check`, `btck_chainstate_manager_process_block` and `btck_chain_parameters_create_signet` are all in 32.x, so the issue is present in the 32.0 release and I think a backport makes sense. Happy to open one if maintainers want it.",
   "id": "c:5972142046",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-5972142046",
   "hash": "4debfe97dc53158c",
   "edited": null
  },
  {
   "t": "2026-10-08T16:34:42Z",
   "kind": "comment",
   "who": "sedited",
   "assoc": "MEMBER",
   "text": "Approach NACK\n\nI don't think this is a worthwhile fix. The same problem exists in the normal unit tests as well, and shouldn't be fixed there with this approach either in my opinion. Paying a copy for every check call to protect against a scenario that should never happen, does not seem worthwhile to me.",
   "id": "c:6064504067",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-6064504067",
   "hash": "2c180a27c3f8c5a3",
   "edited": null
  },
  {
   "t": "2026-10-08T17:25:53Z",
   "kind": "force_push",
   "who": "FlashWayne",
   "commit": "54b363a291b275b7cbc727a0683608d28ef0b2dc",
   "id": "push:54b363a291b275b7cbc727a0683608d28ef0b2dc"
  },
  {
   "t": "2026-10-08T17:26:03Z",
   "kind": "comment",
   "who": "FlashWayne",
   "assoc": "CONTRIBUTOR",
   "text": "Thanks for the review, sedited. You're right: a copy on every call isn't worth it for a case that shouldn't happen, and the unit tests have the same property.\n\nI dropped the copy and the tests. The PR is now a single docs commit (54b363a291, rebased on current master, which also clears the conflict). It states on `btck_block_check` and `btck_chainstate_manager_process_block` that a `btck_Block` caches its check results, that copies from `btck_block_copy` share the cache, and that a block should only be used with one set of consensus parameters.\n\nI changed the title and description to match. If you'd rather not have the note either, I'm happy to close this.",
   "id": "c:6065383919",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-6065383919",
   "hash": "8c0f54df7fe43885",
   "edited": null
  },
  {
   "t": "2026-10-09T12:03:56Z",
   "kind": "review_comment",
   "who": "alexanderwiederin",
   "assoc": "MEMBER",
   "path": "src/kernel/bitcoinkernel.h",
   "commit": "3add4efcd2af064e59678aa41748868c748f2731",
   "in_reply_to": null,
   "text": "I think the description is too broad. The cache only takes effect when POW and the Merkle root are checked.\n\nhttps://github.com/bitcoin/bitcoin/blob/4bacf21a13c2ed25ef9362ca38f26bf0a67d22c9/src/validation.cpp#L3987-L3988",
   "id": "rc:4229887144",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#discussion_r4229887144",
   "hash": "99e75b20ae226969",
   "edited": null
  },
  {
   "t": "2026-10-09T12:37:50Z",
   "kind": "comment",
   "who": "FlashWayne",
   "assoc": "CONTRIBUTOR",
   "text": "Thanks @alexanderwiederin, you're right. The cache is only set when both the proof of work and the merkle root were checked. I narrowed both doc comments accordingly in 47cb9a682b. Happy to squash if preferred.",
   "id": "c:6081039205",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#issuecomment-6081039205",
   "hash": "06607b08f0f9cc19",
   "edited": null
  },
  {
   "t": "2026-10-09T15:33:09Z",
   "kind": "review_comment",
   "who": "alexanderwiederin",
   "assoc": "MEMBER",
   "path": "src/kernel/bitcoinkernel.h",
   "commit": "47cb9a682be8a4f5f75b4bad1aa8aba99c9bd8fd",
   "in_reply_to": null,
   "text": "You don't have to add the clause here. `ProcessNewBlock` calls `CheckBlock` with `fCheckPOW` and `fCheckMerkleRoot` set to their default `true`.",
   "id": "rc:4231810698",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#discussion_r4231810698",
   "hash": "540111db84b1dd1d",
   "edited": null
  },
  {
   "t": "2026-10-09T15:51:53Z",
   "kind": "review_comment",
   "who": "FlashWayne",
   "assoc": "CONTRIBUTOR",
   "path": "src/kernel/bitcoinkernel.h",
   "commit": "47cb9a682be8a4f5f75b4bad1aa8aba99c9bd8fd",
   "in_reply_to": 4231810698,
   "text": "Thanks, dropped the clause from the `process_block` docs in 3add4efcd2af (kept it only for `btck_block_check`, and fixed the `@param` alignment).",
   "id": "rc:4231979389",
   "url": "https://github.com/bitcoin/bitcoin/pull/36353#discussion_r4231979389",
   "hash": "ff7503b165d020ed",
   "edited": "2026-10-09T15:51:54Z"
  }
 ],
 "labels_log": [
  {
   "t": "2026-09-26T22:36:44Z",
   "action": "labeled",
   "label": "Validation",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-28T12:04:18Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-29T19:17:17Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-08T16:11:35Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-08T18:41:53Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-10-08T17:26:01Z",
   "kind": "renamed",
   "who": "FlashWayne",
   "from": "kernel: don't reuse cached CheckBlock results across params",
   "to": "kernel: document that blocks cache their check results"
  }
 ],
 "text_chars": 5312,
 "text_tokens_estimate": 1328,
 "changed_paths": [
  "src/kernel/bitcoinkernel.h"
 ],
 "files": [
  {
   "path": "src/kernel/bitcoinkernel.h",
   "add": 11,
   "del": 0
  }
 ],
 "test_lines": 0,
 "git": {
  "head": "3add4efcd2af064e59678aa41748868c748f2731",
  "head_matches_backup": true,
  "base": "f739c7876b81304bdc72e7eaa307702da269ac31",
  "patch_id": "a3e45a0cfafb0b1b",
  "commits": [
   {
    "sha": "54b363a291",
    "subject": "kernel: document that blocks cache their check results",
    "files": 1,
    "add": 10,
    "del": 0
   },
   {
    "sha": "47cb9a682b",
    "subject": "kernel: limit cache docs to blocks checked for POW and merkle root",
    "files": 1,
    "add": 9,
    "del": 7
   },
   {
    "sha": "3add4efcd2",
    "subject": "kernel: drop POW/merkle clause from process_block docs",
    "files": 1,
    "add": 4,
    "del": 5
   }
  ],
  "patch_truncated": false
 },
 "patch_id": "a3e45a0cfafb0b1b",
 "input_hash": "30832a8151b4722f",
 "extracted_at": "2026-11-02T01:09:49+00:00"
}