{
 "number": 35731,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/35731",
 "title": "Indexes: Harden the flush-error notification invariant",
 "author": "arejula27",
 "author_association": "CONTRIBUTOR",
 "created_at": "2026-07-15T17:35:12Z",
 "updated_at": "2026-09-16T20:57:37Z",
 "age_days": 63,
 "draft": true,
 "labels": [
  "UTXO Db and Indexes",
  "CI failed"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "a4c7bf0fbfd1f472d9d68a2dd8be2c45fde41611",
 "head_ref": "flush-notify-invariant",
 "head_repo": "arejula27/bitcoin",
 "head_history": [],
 "additions": 121,
 "deletions": 10,
 "changed_files": 5,
 "commit_count": 4,
 "size_bucket": "M",
 "mergeable_state": "unstable",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {},
   "conflicts": [
    {
     "number": 35714,
     "title": "validation: stop writes after flush failure",
     "author": "l0rinc"
    },
    {
     "number": 35307,
     "title": "blockstorage: keep snapshot base in normal blockfile range",
     "author": "shuv-amp"
    },
    {
     "number": 35003,
     "title": "validation: improve block data I/O error handling in P2P paths",
     "author": "furszy"
    },
    {
     "number": 29700,
     "title": "kernel, refactor: return error status on all fatal errors",
     "author": "ryanofsky"
    }
   ]
  }
 },
 "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": []
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": true,
  "mergeable_state": "unstable",
  "last_author_activity": "2026-07-15T17:33:18Z",
  "last_reviewer_activity": null,
  "last_reviewer": null,
  "author_silent_days": 63,
  "waiting_on_author_days": 0,
  "days_since_update": 0
 },
 "refs": {
  "mentioned": [
   35714
  ],
  "depends_on": [
   35714
  ],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 35714,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "validation: stop writes after flush failure"
   }
  ],
  "conflicts": [
   35714,
   35307,
   35003,
   29700
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [],
 "body": "This is a follow-up to #35714 as it has the two commits of that PR, do not merge or review before that PR\n\n#35714 makes `FlushStateToDisk()` return `state.Error(...)` when `FlushChainstateBlockFile()` fails, relying on the comment `// FlushChainstateBlockFile() already emitted the flush-error notification.`\n\nThat invariant holds today, but it is not guaranteed by construction: it depends on every `success = false` branch inside `FlushBlockFile`/`FlushUndoFile` emitting the notification on its own. A future flush source (a new file type, a new error branch) that sets `success = false` **without** notifying would make `FlushStateToDisk()` return an error without `AbortNode()`.\n\nThis PR makes sure that **whenever a flush reports failure, the flush-error notification has been emitted**:\n\n- **test: cover FlushBlockFile flush-error notifications**: lower-level `BlockManager` tests (as suggested in the #35714 review) that inject a failure on the block file and on the undo file separately and assert each failure emits `flushError`.\n- **blockstorage: encapsulate flush+notify in FlushFile**:  a single `FlushFile()` helper couples the flush and the notification; `FlushBlockFile`/`FlushUndoFile` delegate to it. Behaviour is unchanged.",
 "commits": [
  {
   "sha": "0f04fbee2f123c37c4b6fbff7dc10f61dd0b5924",
   "date": "2026-07-13T18:51:05Z",
   "message": "test: characterize writes after flush failure"
  },
  {
   "sha": "e1a337ee961db4308697de7cddcf4aad9684c7f1",
   "date": "2026-07-13T19:30:52Z",
   "message": "validation: stop writes after flush failure\n\nWhen a block-file or undo-file flush fails, shutdown is requested, but `FlushStateToDisk()` still writes block-index metadata and coins data, then advances `m_last_flushed_block`.\nReturn the error before those writes, keeping `m_last_flushed_block` at the last successful flush."
  },
  {
   "sha": "42ea4bcccbe77666d995ff6b770e1feed6fb16d9",
   "date": "2026-07-15T17:33:18Z",
   "message": "test: cover FlushBlockFile flush-error notifications"
  },
  {
   "sha": "a4c7bf0fbfd1f472d9d68a2dd8be2c45fde41611",
   "date": "2026-07-15T17:33:18Z",
   "message": "blockstorage: encapsulate flush+notify in FlushFile"
  }
 ],
 "timeline": [],
 "labels_log": [
  {
   "t": "2026-07-15T17:35:16Z",
   "action": "labeled",
   "label": "UTXO Db and Indexes",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-20T11:17:55Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  }
 ],
 "state_log": [],
 "text_chars": 1771,
 "text_tokens_estimate": 442,
 "changed_paths": [
  "src/node/blockstorage.cpp",
  "src/node/blockstorage.h",
  "src/test/blockmanager_tests.cpp",
  "src/test/chainstate_write_tests.cpp",
  "src/validation.cpp"
 ],
 "files": [
  {
   "path": "src/node/blockstorage.cpp",
   "add": 11,
   "del": 7
  },
  {
   "path": "src/node/blockstorage.h",
   "add": 5,
   "del": 0
  },
  {
   "path": "src/test/blockmanager_tests.cpp",
   "add": 79,
   "del": 0
  },
  {
   "path": "src/test/chainstate_write_tests.cpp",
   "add": 24,
   "del": 0
  },
  {
   "path": "src/validation.cpp",
   "add": 2,
   "del": 3
  }
 ],
 "test_lines": 103,
 "git": {
  "head": "a4c7bf0fbfd1f472d9d68a2dd8be2c45fde41611",
  "head_matches_backup": true,
  "base": "d18fec892e22530c79bbba0080af288a61512c9a",
  "commits": [
   {
    "sha": "0f04fbee2f",
    "subject": "test: characterize writes after flush failure",
    "files": 1,
    "add": 24,
    "del": 0
   },
   {
    "sha": "e1a337ee96",
    "subject": "validation: stop writes after flush failure",
    "files": 2,
    "add": 4,
    "del": 5
   },
   {
    "sha": "42ea4bcccb",
    "subject": "test: cover FlushBlockFile flush-error notifications",
    "files": 2,
    "add": 80,
    "del": 0
   },
   {
    "sha": "a4c7bf0fbf",
    "subject": "blockstorage: encapsulate flush+notify in FlushFile",
    "files": 2,
    "add": 15,
    "del": 7
   }
  ],
  "patch_truncated": false
 },
 "input_hash": "4c8fc6ce4efebbd5",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}