{
 "number": 36501,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/36501",
 "title": "refactor : Reorder CBlockIndex members to save 8 bytes",
 "author": "bartoli",
 "author_association": "FIRST_TIME_CONTRIBUTOR",
 "created_at": "2026-10-11T16:07:36Z",
 "updated_at": "2026-10-27T10:07:43Z",
 "description_hash": "4af8d7ee03bc9877",
 "age_days": 21,
 "draft": false,
 "labels": [],
 "milestone": null,
 "base": "master",
 "head_sha": "d9387c41c1c2076ce035aeb6a3daf7bfd83f7c32",
 "head_ref": "CBlockIndexPacking",
 "head_repo": "bartoli/bitcoin",
 "head_history": [],
 "additions": 5,
 "deletions": 5,
 "changed_files": 1,
 "commit_count": 1,
 "size_bucket": "S",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "ack": [
     {
      "login": "l0rinc",
      "url": "https://github.com/bitcoin/bitcoin/pull/36501#issuecomment-6114950728"
     },
     {
      "login": "maflcko",
      "url": "https://github.com/bitcoin/bitcoin/pull/36501#issuecomment-6122975411"
     }
    ]
   },
   "conflicts": []
  }
 },
 "acks_parsed": {},
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 0,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "l0rinc",
   "maflcko",
   "stickies-v"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-10-13T14:14:37Z",
  "last_reviewer_activity": "2026-10-27T10:07:43Z",
  "last_reviewer": "maflcko",
  "author_silent_days": 19,
  "waiting_on_author_days": 5,
  "days_since_update": 5
 },
 "refs": {
  "mentioned": [],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [],
  "conflicts": []
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [],
 "body": "It seems we can save 8 bytes per CBlockIndex instance by reordering one class member. Moving one 8-byte field seems to avoid losing 2x 4 bytes to structure padding on a 64-bit build (on a 32-bit build, there is no gain).\n\nI could not exactly measure the runtime gain from just this (smaller than RAM usage variation between 2 launches), but I confirmed there was about as many instances of CBlockIndex as blocks in the chain (increasing CBlockIndex size by 320 bytes increases RAM usage by ~300MB), so saving 8 bytes per instance should save about 8MB of RAM at current block height.\n\nThe gain is small, but it seems like it has no cost/risk, since that structure is not used for serialization, and just reordering here should have no side effects.\n\nI saw a few other types that could gain a few bytes in size by doing something similar (for example, CTxIn), but they have far fewer instances in memory to make the change worth it.",
 "commits": [
  {
   "sha": "d9387c41c1c2076ce035aeb6a3daf7bfd83f7c32",
   "date": "2026-10-11T15:00:06Z",
   "message": "Reorder CBlockIndex members to save 8 bytes\n\nOn a windows x64 build, CBlockIndex size is 152 bytes. Moving one field\nsomewhere else makes the class lose less bytes due to padding to respect\nthe 8-byte alignment\n\nFor a ~1M block height, this saves about 8M of Ram without doing\nanything else."
  }
 ],
 "timeline": [
  {
   "t": "2026-10-11T23:10:50Z",
   "kind": "comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "text": "[Godbolt](https://godbolt.org/z/3ba8Ers5q) indicates 152 -> 144 bytes on 64-bit (with no change on 32-bit, as mentioned in the PR description).\nI wouldn't claim a total RAM saving though, as it seems allocator-dependent: glibc gives the map nodes 200 bytes in both cases.\nBut I don't see a downside to the swap, since the fields initialize independently and serialization is unchanged.\n\nACK d9387c41c1c2076ce035aeb6a3daf7bfd83f7c32",
   "id": "c:6114950728",
   "url": "https://github.com/bitcoin/bitcoin/pull/36501#issuecomment-6114950728",
   "hash": "81d3637c4ef4511b",
   "edited": null
  },
  {
   "t": "2026-10-12T11:03:25Z",
   "kind": "comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "text": "lgtm ACK d9387c41c1c2076ce035aeb6a3daf7bfd83f7c32",
   "id": "c:6122975411",
   "url": "https://github.com/bitcoin/bitcoin/pull/36501#issuecomment-6122975411",
   "hash": "b5c77eb17865fde5",
   "edited": null
  },
  {
   "t": "2026-10-13T09:59:31Z",
   "kind": "comment",
   "who": "stickies-v",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nI disagree with the risk assessment. Also, `CDiskBlockIndex` derives from `CBlockIndex` and is serialized. The change is safe because serialization is field by name, not because it does not happen.\n\n`CBlockIndex` is used everywhere, any reliance on its memory layout can yield a bug, possibly a consensus one. Especially for a refactor change like this, I think the onus is on the PR author to exhaustively list why this change is safe, and how reviewers can verify that. For example, some ways the reorder can cause bugs:\n\n- positional / aggregate init\n- initializer-order dependencies\n- defaulted comparison operators\n- serialization\n- byte-level access: `memcpy`, `reinterpret_cast`, etc\n\nI checked these myself, including clang-query over all translation units for casts, `mem*` calls and `sizeof`/`offsetof` on the type, and found only pointer printing and allocator internals. So it looks safe to me. But the PR should let reviewers falsify its assumptions rather than assert \"no side effects\".",
   "id": "c:6143054112",
   "url": "https://github.com/bitcoin/bitcoin/pull/36501#issuecomment-6143054112",
   "hash": "9f624603810b7119",
   "edited": null
  },
  {
   "t": "2026-10-13T14:14:37Z",
   "kind": "comment",
   "who": "bartoli",
   "assoc": "NONE",
   "text": "[quoted text omitted]\n\nMy rationale was that the type is not serialized directly, and it also changes size between built platforms, so type serialization to bytes in memory has little chance to cause issues outside of that binary if they don't already do.\nBut you are definately right about more needed checks on accesses inside the node process.",
   "id": "c:6147567773",
   "url": "https://github.com/bitcoin/bitcoin/pull/36501#issuecomment-6147567773",
   "hash": "2e3dbfd2207d96f9",
   "edited": null
  },
  {
   "t": "2026-10-27T10:07:43Z",
   "kind": "comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "text": "Yeah, if there was some byte-level access, or order dependent serialization, that would seem like a pre-existing bug that would already have been hit. Also, with C++20 \"Prohibiting Aggregates with User-Declared Constructors P1008\", the init issue is rejected at compile-time. So I still think this is fine.",
   "id": "c:6439038733",
   "url": "https://github.com/bitcoin/bitcoin/pull/36501#issuecomment-6439038733",
   "hash": "76d3ad3838a7ec9a",
   "edited": null
  }
 ],
 "labels_log": [],
 "state_log": [],
 "text_chars": 3437,
 "text_tokens_estimate": 859,
 "changed_paths": [
  "src/chain.h"
 ],
 "files": [
  {
   "path": "src/chain.h",
   "add": 5,
   "del": 5
  }
 ],
 "test_lines": 0,
 "git": {
  "head": "d9387c41c1c2076ce035aeb6a3daf7bfd83f7c32",
  "head_matches_backup": true,
  "base": "9dfde64cc3262329051fd05fffe40eecc786a99f",
  "patch_id": "e40b68bc3bd27c13",
  "commits": [
   {
    "sha": "d9387c41c1",
    "subject": "Reorder CBlockIndex members to save 8 bytes",
    "files": 1,
    "add": 5,
    "del": 5
   }
  ],
  "patch_truncated": false
 },
 "patch_id": "e40b68bc3bd27c13",
 "input_hash": "cf636e6ced14e836",
 "extracted_at": "2026-11-02T01:09:49+00:00"
}