{
 "number": 36520,
 "input_hash": "0ced3e16e3d77384",
 "model": "ledger",
 "prompt_hash": null,
 "created": "2026-10-31T01:17:30+00:00",
 "result": {
  "summary": "Hardens node implementations of interfaces::Chain against crashes caused by invalid arguments or IPC notification failures. Replaces asserts and null dereferences in getBlockHash, broadcastTransaction, and checkChainLimits with bounds checks and error returns. Wraps validation notification forwarding in NotificationsProxy to catch ipc::Exception and avoid crashing the validation scheduler thread, and fixes findAncestorByHash returning true when the descendant block hash is unknown.",
  "problem": "interfaces::Chain methods were designed for well-behaved in-process callers like the internal wallet and assert or dereference null on invalid inputs. When exposed across IPC to out-of-process clients, omitted parameters or invalid inputs crash bitcoin-node, and errors returned by client notification handlers terminate the validation interface scheduler thread. Additionally, findAncestorByHash falsely reports success when the descendant block is missing.",
  "card": "This PR hardens Bitcoin Core's Chain interface implementations against crashes from invalid arguments and IPC client errors. Currently, Chain methods assume well-behaved in-process callers, asserting or dereferencing null pointers on invalid inputs and permitting client exceptions on the validation scheduler thread to terminate the node. It also fixes a logic bug where findAncestorByHash reports success for unknown descendant blocks (issue 36472). While standalone, these changes primarily safeguard the node before exposing the Chain interface over multiprocess IPC in PR 29409.",
  "evidence": [
   "Fixes #36472 ('interfaces: findAncestorByHash returns true for an unknown descendant')",
   "Author notes: 'The problems were reported by zaidmstrr, willcl-ark and xyzconstant while reviewing #29409, and by enirox001 in #36472.'",
   "Commit message notes that notifications run on the validation interface scheduler thread, where uncaught exceptions from disconnected or failing IPC clients terminate the node process."
  ],
  "scope_notes": "",
  "changed_since_previous": "",
  "thread": {
   "last_event_at": "2026-10-30T15:24:50Z",
   "events": 7,
   "head_sha": "b67d871f95fa1b9c47fc2f8d08d80e27f0a81e16",
   "schema_floor": 2,
   "schema": 2
  },
  "waiting_on": [
   {
    "at": "2026-10-30",
    "id": "rc:4424094065",
    "on": "author",
    "url": "https://github.com/bitcoin/bitcoin/pull/36520#discussion_r4424094065",
    "what": "author reply to test cleanup suggestion and questions regarding scope and exception types"
   }
  ],
  "risk": {
   "level": "low",
   "touches": [
    "validation",
    "other"
   ],
   "why": "Mistakes would at most cause valid interface calls to return unexpected errors or fail to notify an attached IPC client."
  },
  "discussion": {
   "author_status": "last statement processed 2026-10-30",
   "open_concerns": [
    "cyb3ralbert: cover hasBlocks() crash on negative max_height here or in a follow-up",
    "cyb3ralbert: whether throwing std::out_of_range in getBlockHash was intended over a std::runtime_error-derived type given wallet catch blocks",
    "cyb3ralbert: expand unit tests to cover all six Notifications methods throwing ipc::Exception",
    "xyzconstant: cover the hasBlocks() negative max_height crash in this PR",
    "enirox001: remove redundant queue synchronization in throwingNotifications since CreateAndProcessBlock already synchronizes notifications by default"
   ],
   "resolved_concerns": []
  },
  "reviewability": {
   "state": "Ready",
   "label": "Ready",
   "reason": "Nothing known that would invalidate a review now."
  },
  "agreement": {
   "state": "Strong",
   "summary": "Strong: substantive support, no open objection (enirox001, xyzconstant, enirox001)",
   "reason": "Added enirox001's Tested ACK and inline suggestion regarding redundant queue synchronization in unit tests. Their comment about shared input validation across the interface was noted as a followup question and not recorded as a claim holding this PR.",
   "evidence": [
    "cyb3ralbert (suggestion, scope, must be answered, open): cover hasBlocks() crash on negative max_height here or in a follow-up",
    "cyb3ralbert (question, interface, must be answered, open): whether throwing std::out_of_range in getBlockHash was intended over a std::runtime_error-derived type given wallet catch blocks",
    "cyb3ralbert (suggestion, safety, must be answered, open): expand unit tests to cover all six Notifications methods throwing ipc::Exception",
    "xyzconstant (suggestion, scope, must be answered, open): cover the hasBlocks() negative max_height crash in this PR",
    "enirox001 (suggestion, maintenance, must be answered, open): remove redundant queue synchronization in throwingNotifications since CreateAndProcessBlock already synchronizes notifications by default",
    "enirox001: Concept ACK \u2014 makes the chain interface more defensive against invalid inputs when exposed over IPC instead of crashing the node",
    "xyzconstant: ACK \u2014 fixes issues reported by IPC consumers testing the Chain interface; current fixes are clean and can be merged as is",
    "enirox001: Tested ACK \u2014 fixes resolve problems reported in #36472 and during review of #29409; confirmed resolved in a functional test"
   ],
   "objections": [
    {
     "reviewer": "cyb3ralbert",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "scope",
     "harm": "",
     "request": "cover hasBlocks() crash on negative max_height here or in a follow-up",
     "question": "",
     "text": "cover hasBlocks() crash on negative max_height here or in a follow-up",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-22: 'Could hasBlocks() be covered here, or should it be a follow-up?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36520#issuecomment-6337747539",
     "id": "c:6337747539",
     "at": "2026-10-22",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "cyb3ralbert",
     "association": "CONTRIBUTOR",
     "type": "question",
     "kind": "interface",
     "harm": "",
     "request": "",
     "question": "whether throwing std::out_of_range in getBlockHash was intended over a std::runtime_error-derived type given wallet catch blocks",
     "text": "whether throwing std::out_of_range in getBlockHash was intended over a std::runtime_error-derived type given wallet catch blocks",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-22: 'Is out_of_range intended over a runtime_error-derived type?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36520#issuecomment-6337747539",
     "id": "c:6337747539#2",
     "at": "2026-10-22",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "cyb3ralbert",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "safety",
     "harm": "",
     "request": "expand unit tests to cover all six Notifications methods throwing ipc::Exception",
     "question": "",
     "text": "expand unit tests to cover all six Notifications methods throwing ipc::Exception",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-22: 'Coverage nit: the PR's tests make only blockConnected and updatedBlockTip throw.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36520#issuecomment-6337747539",
     "id": "c:6337747539#3",
     "at": "2026-10-22",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "xyzconstant",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "scope",
     "harm": "",
     "request": "cover the hasBlocks() negative max_height crash in this PR",
     "question": "",
     "text": "cover the hasBlocks() negative max_height crash in this PR",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-22: 'I think this issue should also be covered in this PR. Nonetheless, the current fixes here are clean and can be merged as is.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36520#pullrequestreview-5621447619",
     "id": "r:5621447619",
     "at": "2026-10-22",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "enirox001",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "maintenance",
     "harm": "",
     "request": "remove redundant queue synchronization in throwingNotifications since CreateAndProcessBlock already synchronizes notifications by default",
     "question": "",
     "text": "remove redundant queue synchronization in throwingNotifications since CreateAndProcessBlock already synchronizes notifications by default",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-30: 'We can remove the redundant queue synchronization in throwingNotifications as `CreateAndProcessBlock` already synchronizes notifications by default'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36520#discussion_r4424094065",
     "id": "rc:4424094065",
     "at": "2026-10-30",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    }
   ],
   "support": [
    {
     "reviewer": "enirox001",
     "reason": "makes the chain interface more defensive against invalid inputs when exposed over IPC instead of crashing the node",
     "substantive": true,
     "verdict": "Concept ACK",
     "id": "r:5516680185",
     "url": "https://github.com/bitcoin/bitcoin/pull/36520#pullrequestreview-5516680185",
     "at": "2026-10-14",
     "association": "CONTRIBUTOR",
     "evidence": "read",
     "areas": []
    },
    {
     "reviewer": "xyzconstant",
     "reason": "fixes issues reported by IPC consumers testing the Chain interface; current fixes are clean and can be merged as is",
     "substantive": true,
     "verdict": "ACK",
     "id": "r:5621447619",
     "url": "https://github.com/bitcoin/bitcoin/pull/36520#pullrequestreview-5621447619",
     "at": "2026-10-22",
     "association": "CONTRIBUTOR",
     "evidence": "read",
     "areas": []
    },
    {
     "reviewer": "enirox001",
     "reason": "fixes resolve problems reported in #36472 and during review of #29409; confirmed resolved in a functional test",
     "substantive": true,
     "verdict": "Tested ACK",
     "id": "r:5712899549",
     "url": "https://github.com/bitcoin/bitcoin/pull/36520#pullrequestreview-5712899549",
     "at": "2026-10-30",
     "association": "CONTRIBUTOR",
     "evidence": "both",
     "areas": []
    }
   ],
   "participants": [
    {
     "login": "enirox001",
     "stance": "support",
     "note": "supports defensively handling IPC calls; tested fix for #36472 and suggested removing redundant test sync",
     "association": "CONTRIBUTOR",
     "comments": 3,
     "first": "2026-10-14",
     "last": "2026-10-30"
    },
    {
     "login": "cyb3ralbert",
     "stance": "question",
     "note": "tested extensively; asked whether hasBlocks() should be covered and questioned throwing std::out_of_range",
     "association": "CONTRIBUTOR",
     "comments": 1,
     "first": "2026-10-22",
     "last": "2026-10-22"
    },
    {
     "login": "xyzconstant",
     "stance": "support",
     "note": "ACK b67d871f95; suggested also covering hasBlocks() negative max_height crash",
     "association": "CONTRIBUTOR",
     "comments": 3,
     "first": "2026-10-22",
     "last": "2026-10-22"
    }
   ],
   "derivation": "substantive support, no open objection (enirox001, xyzconstant, enirox001)",
   "model_state": null,
   "corrections": [],
   "notes": "Added enirox001's Tested ACK and inline suggestion regarding redundant queue synchronization in unit tests. Their comment about shared input validation across the interface was noted as a followup question and not recorded as a claim holding this PR."
  },
  "dependencies": {
   "depends_on": [],
   "enables": [
    "#29409"
   ]
  },
  "categories": [
   {
    "name": "ipc",
    "member": true,
    "evidence": "Carries the IPC label and modifies src/node/interfaces.cpp and src/interfaces/chain.h to harden interfaces::Chain against invalid cross-process calls and IPC notification exceptions.",
    "band": "P1",
    "reason_tag": "bug fix",
    "score": 0.8,
    "factors": {
     "bug_severity": 2,
     "leverage": 1,
     "performance": 0,
     "security_stability": 2,
     "user_value": 0
    },
    "rationale": "Prevents bitcoin-node crashes and scheduler thread termination caused by invalid IPC arguments or failed client notification handlers. In the IPC category, crash and disconnect handling across the process boundary is a core reliability requirement."
   }
  ],
  "confidence": "high",
  "uncertainties": [],
  "needs": []
 },
 "cost_usd": 0.0,
 "source": {
  "record": "2026-10-31T01:17:30+00:00",
  "code": "2026-10-16T01:19:07+00:00",
  "judgments": 1
 }
}