{
 "number": 36619,
 "input_hash": "3d0332bc0f424ac2",
 "model": "ledger",
 "prompt_hash": null,
 "created": "2026-10-29T01:22:06+00:00",
 "result": {
  "summary": "Check block undo data availability before attempting to read undo data in the `/rest/spenttxouts/<hash>` REST endpoint. If `BLOCK_HAVE_UNDO` is not set on the block index, the endpoint returns an HTTP 404 immediately without calling `ReadBlockUndo()`. A functional test verifies that querying a side-branch block returns a 404 without writing undo failure errors to `debug.log`.",
  "problem": "When `/rest/spenttxouts/<hash>` is requested for a block that lacks undo data\u2014such as pruned blocks or disconnected side branches\u2014`ReadBlockUndo()` fails and logs an `[error] OpenUndoFile failed for FlatFilePos(nFile=-1, nPos=0)` to `debug.log`. Although the REST endpoint correctly returns a 404 response, unauthenticated requests can spam the log with false error messages that mimic disk corruption.",
  "card": "Suppresses spurious disk-corruption error logs when querying `/rest/spenttxouts/<hash>` for blocks without undo data. Today, unauthenticated requests for pruned blocks or disconnected side branches cause OpenUndoFile to fail and log an error to debug.log before returning an HTTP 404. This PR verifies that BLOCK_HAVE_UNDO is set before attempting to read undo files, keeping the HTTP 404 response unchanged while preventing debug.log spam.",
  "evidence": [
   "Commit and PR description: \"For a block that was stored but never connected (a side branch) or whose undo data was pruned, GetUndoPos() is null, so OpenUndoFile() fails and ReadBlockUndo() writes 'OpenUndoFile failed for FlatFilePos(nFile=-1, nPos=0)' to debug.log with LogError.\"",
   "PR description notes the test fails on master: \"The new check at the end of interface_rest.py requests a stale block and fails on master because of the logged error.\""
  ],
  "scope_notes": "",
  "changed_since_previous": "The implementation directly checks `nStatus & BLOCK_HAVE_UNDO` under `cs_main` instead of using a helper function.",
  "thread": {
   "last_event_at": "2026-10-27T15:00:37Z",
   "events": 13,
   "head_sha": "eebc145847b4f05da61e95fcae1b420a6ce3ea0f",
   "schema_floor": 2,
   "schema": 2
  },
  "waiting_on": [
   {
    "at": null,
    "id": "",
    "on": "nothing",
    "url": null,
    "what": "all comments addressed and both reviewers re-ACKed the latest push"
   }
  ],
  "risk": {
   "level": "medium",
   "touches": [
    "rpc_api"
   ],
   "why": "A mistake in inspecting block status flags or locking cs_main could return false 404s for valid undo data or trigger lock contention on REST requests."
  },
  "discussion": {
   "author_status": "last statement processed 2026-10-27",
   "open_concerns": [],
   "resolved_concerns": [
    "stickies-v: Remove the redundant IsBlockPruned check (fixed by kriss39 2026-10-23)",
    "maflcko: Use CheckBlockDataAvailability to avoid duplicating implementation (fixed by maflcko 2026-10-23)",
    "stickies-v: Consider a direct bitwise check on nStatus instead of CheckBlockDataAvailability (fixed by stickies-v 2026-10-27)",
    "maflcko: Address the nit to switch to a direct nStatus & BLOCK_HAVE_UNDO check (fixed by maflcko 2026-10-27)"
   ]
  },
  "reviewability": {
   "state": "Ready",
   "label": "Ready",
   "reason": "Nothing known that would invalidate a review now."
  },
  "agreement": {
   "state": "Positive",
   "summary": "Positive: support without stated reasons, no open objection (stickies-v, stickies-v, maflcko, maflcko, stickies-v)",
   "reason": "maflcko asked the author to adopt the direct bitwise check suggested earlier by stickies-v. The author updated the PR to use nStatus & BLOCK_HAVE_UNDO, and both reviewers re-ACKed.",
   "evidence": [
    "stickies-v: ACK \u2014 ACK e8af2c7488925e35ffeaf64e523cef48b70280eb",
    "stickies-v: Approach ACK",
    "maflcko: ACK \u2014 lgtm ACK e8af2c7488925e35ffeaf64e523cef48b70280eb",
    "maflcko: ACK \u2014 review ACK eebc145847b4f05da61e95fcae1b420a6ce3ea0f \ud83d\udee0",
    "stickies-v: ACK \u2014 re-ACK eebc145847b4f05da61e95fcae1b420a6ce3ea0f"
   ],
   "objections": [
    {
     "reviewer": "stickies-v",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "maintenance",
     "harm": "",
     "request": "Remove the redundant IsBlockPruned check",
     "question": "",
     "text": "Remove the redundant IsBlockPruned check",
     "clears_with": "answer",
     "blocking": false,
     "status": "fixed",
     "status_note": "author confirmed IsBlockPruned is redundant because BLOCK_HAVE_UNDO is cleared on prune, and removed it in push",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": true,
     "replies": [
      "rc:4358800508"
     ],
     "evidence": "2026-10-23: 'I think the `&& !chainman->m_blockman.IsBlockPruned(*pblockindex)` check here is redundant?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36619#discussion_r4358444111",
     "id": "rc:4358444111",
     "at": "2026-10-23",
     "status_at": "2026-10-23",
     "status_by": "kriss39",
     "resolution_evidence": "2026-10-23: kriss39: 'PruneOneBlockFile() clears BLOCK_HAVE_UNDO, so the IsBlockPruned() check added nothing.'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "maflcko",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "maintenance",
     "harm": "",
     "request": "Use CheckBlockDataAvailability to avoid duplicating implementation",
     "question": "",
     "text": "Use CheckBlockDataAvailability to avoid duplicating implementation",
     "clears_with": "answer",
     "blocking": false,
     "status": "fixed",
     "status_note": "switched to CheckBlockDataAvailability in e8af2c7488925e35ffeaf64e523cef48b70280eb and accepted",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": true,
     "replies": [
      "rc:4358800508"
     ],
     "evidence": "2026-10-23: 'Can this use `CheckBlockDataAvailability` to avoid duplicating the impl?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36619#discussion_r4358648834",
     "id": "rc:4358648834",
     "at": "2026-10-23",
     "status_at": "2026-10-23",
     "status_by": "maflcko",
     "resolution_evidence": "2026-10-23: maflcko: 'lgtm ACK e8af2c7488925e35ffeaf64e523cef48b70280eb'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "stickies-v",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "maintenance",
     "harm": "",
     "request": "Consider a direct bitwise check on nStatus instead of CheckBlockDataAvailability",
     "question": "",
     "text": "Consider a direct bitwise check on nStatus instead of CheckBlockDataAvailability",
     "clears_with": "answer",
     "blocking": false,
     "status": "fixed",
     "status_note": "author implemented the plain nStatus check in eebc145847b4f05da61e95fcae1b420a6ce3ea0f and reviewer re-ACKed",
     "cleared": true,
     "author_replied": true,
     "others_replied": true,
     "fix_pushed": true,
     "replies": [
      "rc:4388601219",
      "rc:4360912651",
      "rc:4388370425"
     ],
     "evidence": "2026-10-23: 'I think a simple `pblockindex->nStatus & BLOCK_HAVE_UNDO` is more straightforward tbh but either way works.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36619#discussion_r4359063293",
     "id": "rc:4359063293",
     "at": "2026-10-23",
     "status_at": "2026-10-27",
     "status_by": "stickies-v",
     "resolution_evidence": "2026-10-27: stickies-v: 're-ACK eebc145847b4f05da61e95fcae1b420a6ce3ea0f'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "maflcko",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "maintenance",
     "harm": "",
     "request": "Address the nit to switch to a direct nStatus & BLOCK_HAVE_UNDO check",
     "question": "",
     "text": "Address the nit to switch to a direct nStatus & BLOCK_HAVE_UNDO check",
     "clears_with": "answer",
     "blocking": false,
     "status": "fixed",
     "status_note": "author switched to plain nStatus & BLOCK_HAVE_UNDO in eebc145847b4f05da61e95fcae1b420a6ce3ea0f",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": true,
     "replies": [
      "rc:4388601219"
     ],
     "evidence": "2026-10-27: 'Can you address the nit? I think both reviewers would be happy to re-ack a `nStatus & BLOCK_HAVE_UNDO`'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36619#discussion_r4388370425",
     "id": "rc:4388370425",
     "at": "2026-10-27",
     "status_at": "2026-10-27",
     "status_by": "maflcko",
     "resolution_evidence": "2026-10-27: maflcko: 'review ACK eebc145847b4f05da61e95fcae1b420a6ce3ea0f \ud83d\udee0'",
     "pin": null,
     "from_schema": 2
    }
   ],
   "support": [
    {
     "reviewer": "stickies-v",
     "reason": "ACK e8af2c7488925e35ffeaf64e523cef48b70280eb",
     "substantive": false,
     "verdict": "ACK",
     "id": "c:6363921935",
     "url": "https://github.com/bitcoin/bitcoin/pull/36619#issuecomment-6363921935",
     "at": "2026-10-23",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "stickies-v",
     "reason": "",
     "substantive": false,
     "verdict": "Approach ACK",
     "id": "r:5626851079",
     "url": "https://github.com/bitcoin/bitcoin/pull/36619#pullrequestreview-5626851079",
     "at": "2026-10-23",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "maflcko",
     "reason": "lgtm ACK e8af2c7488925e35ffeaf64e523cef48b70280eb",
     "substantive": false,
     "verdict": "ACK",
     "id": "r:5627442260",
     "url": "https://github.com/bitcoin/bitcoin/pull/36619#pullrequestreview-5627442260",
     "at": "2026-10-23",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "maflcko",
     "reason": "review ACK eebc145847b4f05da61e95fcae1b420a6ce3ea0f \ud83d\udee0",
     "substantive": false,
     "verdict": "ACK",
     "id": "c:6443682061",
     "url": "https://github.com/bitcoin/bitcoin/pull/36619#issuecomment-6443682061",
     "at": "2026-10-27",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "stickies-v",
     "reason": "re-ACK eebc145847b4f05da61e95fcae1b420a6ce3ea0f",
     "substantive": false,
     "verdict": "ACK",
     "id": "c:6445394644",
     "url": "https://github.com/bitcoin/bitcoin/pull/36619#issuecomment-6445394644",
     "at": "2026-10-27",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    }
   ],
   "participants": [
    {
     "login": "maflcko",
     "stance": "support",
     "note": "suggested CheckBlockDataAvailability then asked to switch to nStatus check, re-ACKed update",
     "association": "MEMBER",
     "comments": 6,
     "first": "2026-10-23",
     "last": "2026-10-27"
    },
    {
     "login": "stickies-v",
     "stance": "support",
     "note": "reviewed redundancy of prune check, suggested direct bitwise check, Approach ACKed and re-ACKed updates",
     "association": "MEMBER",
     "comments": 5,
     "first": "2026-10-23",
     "last": "2026-10-27"
    }
   ],
   "derivation": "support without stated reasons, no open objection (stickies-v, stickies-v, maflcko, maflcko, stickies-v)",
   "model_state": null,
   "corrections": [],
   "notes": "maflcko asked the author to adopt the direct bitwise check suggested earlier by stickies-v. The author updated the PR to use nStatus & BLOCK_HAVE_UNDO, and both reviewers re-ACKed."
  },
  "dependencies": {
   "depends_on": [],
   "enables": []
  },
  "categories": [
   {
    "name": "rpc",
    "member": true,
    "evidence": "Matches RPC/REST/ZMQ label and modifies REST endpoint handler in src/rest.cpp.",
    "band": "P3",
    "reason_tag": "bug fix",
    "score": 0.35,
    "factors": {
     "bug_severity": 1,
     "leverage": 0,
     "performance": 0,
     "security_stability": 1,
     "user_value": 1
    },
    "rationale": "Prevents spurious `[error]` log entries that mimic disk corruption when requesting spent TXOs for pruned or side-branch blocks. An unauthenticated endpoint was invoking `ReadBlockUndo()` on blocks without undo data, spamming `debug.log` despite properly returning a 404."
   }
  ],
  "confidence": "high",
  "uncertainties": [],
  "needs": []
 },
 "cost_usd": 0.0,
 "source": {
  "record": "2026-10-29T01:22:06+00:00",
  "code": "2026-10-29T01:26:02+00:00",
  "judgments": 1
 }
}