{
 "number": 36621,
 "input_hash": "ef193e9dd0d8a38e",
 "model": "ledger",
 "prompt_hash": null,
 "created": "2026-10-25T01:14:05+00:00",
 "result": {
  "summary": "Replaces `PruneOneBlockFile` with `PruneBlockFiles(const std::set<int>&)` in `BlockManager`, batching block file pruning into a single pass over `m_block_index` using a dynamic bitfield. In `FindFilesToPrune` and `FindFilesToPruneManual`, calls are consolidated so the block index is traversed once across all candidate files rather than once per file. It also skips block index entries that have neither block data nor undo data, avoiding redundant checks and preventing header-only entries from being marked dirty when file 0 is pruned.",
  "problem": "Switching an existing node with full history to pruned mode (or manually pruning many block files) iterated over the entire `m_block_index` separately for every block file pruned. On a full chain (~5,770 files and ~972k blocks), this O(M * N) operation performed billions of iterations while holding `cs_main`, freezing the node for up to ten minutes on startup.",
  "card": "Batches block file pruning into a single pass over the block index rather than traversing the full index once per pruned file. When starting a node with -prune on an existing full-chain datadir or pruning thousands of files at once, the previous O(M * N) approach executed billions of iterations while holding cs_main, freezing the node for tens of seconds on desktop hardware and up to 10 minutes on a Raspberry Pi 5. Benchmarks report reducing pruning time on 5,770 files from 606s to 26ms on ARM64 and 75s to 15ms on x86_64.",
  "evidence": [
   "Commit description: 'When pruning a full chain (~5,770 files and ~972k blocks), this triggered ~5.6 billion iterations and froze the node running on a Pi 5 for ~10 minutes on startup while holding cs_main.'",
   "Author benchmarks: x86_64 (i7-8665U) dropped from 75.1s to 14.7ms (~5,100x speedup); ARM64 (Raspberry Pi 5) dropped from 606.0s to 26.3ms (>3,500x speedup)."
  ],
  "scope_notes": "",
  "changed_since_previous": "Diff inspected (previously nopatch); implementation confirms the bitfield batching, the dataless/header-only skip, and new unit tests in blockmanager_tests.",
  "thread": {
   "last_event_at": null,
   "events": 0,
   "head_sha": "b96e669c607c18c97533f59e70aef44b7c1e613a",
   "schema_floor": 2,
   "schema": 2
  },
  "waiting_on": [],
  "risk": {
   "level": "medium",
   "touches": [
    "validation"
   ],
   "why": "A bug in updating block index records or dirty flags during pruning could corrupt block index metadata or incorrectly report block availability."
  },
  "discussion": {
   "author_status": "no discussion",
   "open_concerns": [],
   "resolved_concerns": []
  },
  "reviewability": {
   "state": "Ready",
   "label": "Ready",
   "reason": "Nothing known that would invalidate a review now."
  },
  "agreement": {
   "state": "Crickets",
   "summary": "Crickets: no substantive comment either way",
   "reason": "Derived from the claims and support below; every entry links to the statement it came from.",
   "evidence": [],
   "objections": [],
   "support": [],
   "participants": [],
   "derivation": "no substantive comment either way",
   "model_state": null,
   "corrections": [],
   "notes": null
  },
  "dependencies": {
   "depends_on": [],
   "enables": []
  },
  "categories": [
   {
    "name": "utils",
    "member": false,
    "evidence": "Matches the 'lock' keyword only via holding cs_main; it changes block storage and block index traversal rather than utility infrastructure or synchronization primitives.",
    "band": "Unranked",
    "reason_tag": "cleanup",
    "score": 0.0,
    "factors": {
     "bug_severity": 1,
     "leverage": 0,
     "performance": 2,
     "security_stability": 1,
     "user_value": 2
    },
    "rationale": "Does not alter utility primitives or shared helper libraries."
   },
   {
    "name": "validation",
    "member": true,
    "evidence": "Changes block storage and block index pruning logic in `src/node/blockstorage.cpp` and `src/node/blockstorage.h`.",
    "band": "P2",
    "reason_tag": "speedup",
    "score": 0.7,
    "factors": {
     "bug_severity": 2,
     "leverage": 0,
     "performance": 3,
     "security_stability": 1,
     "user_value": 1
    },
    "rationale": "Consolidating block index traversals eliminates an O(M * N) loop holding `cs_main` that froze nodes for up to 10 minutes on startup when switching an existing chain to pruned mode. Author benchmarks show pruning time dropping from 606s to 26ms on a Raspberry Pi 5 and 75s to 15ms on x86 (>3,500x speedup)."
   },
   {
    "name": "wallet",
    "member": false,
    "evidence": "Touches `src/wallet/test/rescan_tests.cpp` with a minor 4-line mechanical update to match the block storage method signature.",
    "band": "Unranked",
    "reason_tag": "cleanup",
    "score": 0.0,
    "factors": {
     "bug_severity": 2,
     "leverage": 0,
     "performance": 3,
     "security_stability": 1,
     "user_value": 1
    },
    "rationale": "Does not alter wallet behavior or interfaces; the test edit merely adapts to the blockstorage change."
   }
  ],
  "confidence": "high",
  "uncertainties": [],
  "needs": []
 },
 "cost_usd": 0.0,
 "source": {
  "record": "2026-10-25T01:14:05+00:00",
  "code": "2026-10-25T01:16:13+00:00",
  "judgments": 3
 }
}