{
 "number": 36525,
 "input_hash": "df1f7122cce5ecca",
 "model": "ledger",
 "prompt_hash": null,
 "created": "2026-10-30T01:14:19+00:00",
 "result": {
  "summary": "Protects block template access in the mining interface implementation with a mutex to serialize concurrent IPC worker thread operations. Adds an `m_total_fees` field to `CBlockTemplate` along with a corresponding `getTotalFees()` getter exposed over IPC. Modifies `WaitAndCreateNewBlock` to accept the previous block hash and fee values by value rather than inspecting the template pointer directly, allowing callers to release the template lock before waiting.",
  "problem": "Concurrent IPC worker threads can trigger data races when one thread modifies an active `CBlockTemplate` during `submitSolution()` while another thread reads from it. Furthermore, external IPC mining clients requiring total fee figures have to repeatedly retrieve and sum individual transaction fees across the IPC boundary.",
  "card": "This PR resolves a multithreading data race in the mining IPC interface where concurrent worker threads access m_block_template simultaneously, such as when submitSolution modifies a template while another call reads it. It guards template accesses inside BlockTemplateImpl with a mutex and updates WaitAndCreateNewBlock so the template lock can be released before entering the wait loop. In addition, it caches total fees on CBlockTemplate and introduces a getTotalFees() IPC method so clients do not have to aggregate per-transaction fees. The primary motivation is fixing issue #36515.",
  "evidence": [
   "Commit 4774cf1de6 and PR description state that IPC calls on different worker threads can race when submitSolution modifies a template while another call reads it, fixing issue #36515."
  ],
  "scope_notes": "",
  "changed_since_previous": "Added a Python functional test (run_concurrent_template_access_test in interface_ipc_mining.py) that exercises concurrent reads and submitSolution operations across separate Cap'n Proto worker threads.",
  "thread": {
   "last_event_at": "2026-10-29T09:19:02Z",
   "events": 22,
   "head_sha": "cbadeff334f182086538d7483dc1146c559859e6",
   "schema_floor": 2,
   "schema": 2
  },
  "waiting_on": [
   {
    "at": "2026-10-29",
    "id": "c:6491583234",
    "on": "reviewer",
    "url": "https://github.com/bitcoin/bitcoin/pull/36525#issuecomment-6491583234",
    "what": "sedited to respond to benchmark results and proposed deferral of making template const"
   }
  ],
  "risk": {
   "level": "medium",
   "touches": [
    "other"
   ],
   "why": "Mistakes in mutex scoping or lock inversion in BlockTemplateImpl could deadlock IPC mining worker threads or cause mining block submissions to stall."
  },
  "discussion": {
   "author_status": "last statement processed 2026-10-29",
   "open_concerns": [],
   "resolved_concerns": [
    "ismaelsadeeq: Is returning a vector of individual fees redundant now that total fees can be returned directly? (answered by Sjors 2026-10-15)",
    "ismaelsadeeq: Add a concurrent template access functional test to exercise the data race under TSAN (accepted by ismaelsadeeq 2026-10-16)",
    "enirox001: include the concurrent template access test as it consistently caught the regression under TSAN (accepted by enirox001 2026-10-16)",
    "sedited: Make m_block_template non-mutating/const instead of protecting it with a mutex (answered by Sjors 2026-10-29)",
    "ismaelsadeeq: Return the block copy after applying the solution (answered by Sjors 2026-10-25)"
   ]
  },
  "reviewability": {
   "state": "Ready",
   "label": "Ready",
   "reason": "Nothing known that would invalidate a review now."
  },
  "agreement": {
   "state": "Strong",
   "summary": "Strong: substantive support, no open objection (ismaelsadeeq, enirox001)",
   "reason": "Sjors benchmarked making the block template immutable and returning the full block in submitSolution(), identifying an IPC single-thread latency penalty in sv2-tp and recommending deferring immutability until IPC improvements land.",
   "evidence": [
    "w0xlt: Concept ACK \u2014 Concept ACK",
    "ismaelsadeeq: ACK \u2014 ACK 4774cf1de6a4670323686bf93beb93035b3f6dad",
    "enirox001: ACK \u2014 Fixes a data race between IPC calls modifying and reading a template, adds getTotalFees IPC method, tested with TSAN",
    "ismaelsadeeq: ACK \u2014 reACK cbadeff334f182086538d7483dc1146c559859e6",
    "enirox001: ACK \u2014 reACK https://github.com/bitcoin/bitcoin/pull/36525/changes/cbadeff334f182086538d7483dc1146c559859e6",
    "w0xlt: ACK \u2014 ACK cbadeff334"
   ],
   "objections": [
    {
     "reviewer": "ismaelsadeeq",
     "association": "MEMBER",
     "type": "question",
     "kind": "interface",
     "harm": "",
     "request": "",
     "question": "Is returning a vector of individual fees redundant now that total fees can be returned directly?",
     "text": "Is returning a vector of individual fees redundant now that total fees can be returned directly?",
     "clears_with": "answer",
     "blocking": false,
     "status": "answered",
     "status_note": "Sjors explained the vector is kept for compatibility with getblocktemplate and possible miner dashboard use cases",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [
      "c:6185087776"
     ],
     "evidence": "2026-10-15: 'It makes sense to return it so they don't have to sum them, so the vector one is now redundant?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#pullrequestreview-5528160495",
     "id": "r:5528160495",
     "at": "2026-10-15",
     "status_at": "2026-10-15",
     "status_by": "Sjors",
     "resolution_evidence": "2026-10-15: Sjors: 'Providing the total and individual via IPC is trivial, so I think we should keep it.'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "ismaelsadeeq",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "safety",
     "harm": "",
     "request": "Add a concurrent template access functional test to exercise the data race under TSAN",
     "question": "",
     "text": "Add a concurrent template access functional test to exercise the data race under TSAN",
     "clears_with": "answer",
     "blocking": false,
     "status": "accepted",
     "status_note": "author added test in c:6205291499 and reviewer reACKed",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": true,
     "replies": [
      "c:6185555791",
      "c:6205291499"
     ],
     "evidence": "2026-10-15: 'See minimal test that fails on our tsan functional tests.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#pullrequestreview-5528160495",
     "id": "r:5528160495#2",
     "at": "2026-10-15",
     "status_at": "2026-10-16",
     "status_by": "ismaelsadeeq",
     "resolution_evidence": "2026-10-16: ismaelsadeeq: 'reACK cbadeff334f182086538d7483dc1146c559859e6'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "enirox001",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "correctness",
     "harm": "",
     "request": "include the concurrent template access test as it consistently caught the regression under TSAN",
     "question": "",
     "text": "include the concurrent template access test as it consistently caught the regression under TSAN",
     "clears_with": "answer",
     "blocking": false,
     "status": "accepted",
     "status_note": "author added test in c:6205291499 and reviewer reACKed",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": true,
     "replies": [
      "c:6205291499"
     ],
     "evidence": "2026-10-15: 'I think the test is worth including. even though reproduction depends on scheduling, it consistently caught the regression on my machine'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#pullrequestreview-5530690658",
     "id": "r:5530690658",
     "at": "2026-10-15",
     "status_at": "2026-10-16",
     "status_by": "enirox001",
     "resolution_evidence": "2026-10-16: enirox001: 'reACK https://github.com/bitcoin/bitcoin/pull/36525/changes/cbadeff334f182086538d7483dc1146c559859e6'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "sedited",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "approach",
     "harm": "",
     "request": "Make m_block_template non-mutating/const instead of protecting it with a mutex",
     "question": "",
     "text": "Make m_block_template non-mutating/const instead of protecting it with a mutex",
     "clears_with": "answer",
     "blocking": false,
     "status": "answered",
     "status_note": "author benchmarked the immutable approach, found sv2-tp latency regressions due to IPC bottlenecks, and suggested deferring",
     "cleared": true,
     "author_replied": true,
     "others_replied": true,
     "fix_pushed": false,
     "replies": [
      "c:6380417140",
      "c:6408317995",
      "c:6491583234",
      "c:6492816419",
      "c:6313711072",
      "c:6321446193"
     ],
     "evidence": "2026-10-21: 'Might it be preferable to make m_block_template non-mutating? Do users of the interface even need the mutated template after submitting?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#issuecomment-6313228827",
     "id": "c:6313228827",
     "at": "2026-10-21",
     "status_at": "2026-10-29",
     "status_by": "Sjors",
     "resolution_evidence": "2026-10-29: Sjors: 'So my preference would be to defer making CBlockTemplate const until after these improvements land.'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "ismaelsadeeq",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "interface",
     "harm": "",
     "request": "Return the block copy after applying the solution",
     "question": "",
     "text": "Return the block copy after applying the solution",
     "clears_with": "answer",
     "blocking": false,
     "status": "answered",
     "status_note": "author explained clients intentionally wait 1 second before requesting it so as not to distract the node",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [
      "c:6396275706",
      "c:6491583234"
     ],
     "evidence": "2026-10-25: 'Could we just return the block copy after applying the solution?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#issuecomment-6394296261",
     "id": "c:6394296261",
     "at": "2026-10-25",
     "status_at": "2026-10-25",
     "status_by": "Sjors",
     "resolution_evidence": "2026-10-25: Sjors: 'in theory yes, but clients intentionally wait 1 second before requesting it.'",
     "pin": null,
     "from_schema": 2
    }
   ],
   "support": [
    {
     "reviewer": "w0xlt",
     "reason": "Concept ACK",
     "substantive": false,
     "verdict": "Concept ACK",
     "id": "c:6185669122",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#issuecomment-6185669122",
     "at": "2026-10-15",
     "association": "CONTRIBUTOR",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "ismaelsadeeq",
     "reason": "ACK 4774cf1de6a4670323686bf93beb93035b3f6dad",
     "substantive": true,
     "verdict": "ACK",
     "id": "r:5528160495",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#pullrequestreview-5528160495",
     "at": "2026-10-15",
     "association": "MEMBER",
     "evidence": "read",
     "areas": []
    },
    {
     "reviewer": "enirox001",
     "reason": "Fixes a data race between IPC calls modifying and reading a template, adds getTotalFees IPC method, tested with TSAN",
     "substantive": true,
     "verdict": "ACK",
     "id": "r:5530690658",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#pullrequestreview-5530690658",
     "at": "2026-10-15",
     "association": "CONTRIBUTOR",
     "evidence": "tested",
     "areas": []
    },
    {
     "reviewer": "ismaelsadeeq",
     "reason": "reACK cbadeff334f182086538d7483dc1146c559859e6",
     "substantive": false,
     "verdict": "ACK",
     "id": "r:5543130614",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#pullrequestreview-5543130614",
     "at": "2026-10-16",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "enirox001",
     "reason": "reACK https://github.com/bitcoin/bitcoin/pull/36525/changes/cbadeff334f182086538d7483dc1146c559859e6",
     "substantive": false,
     "verdict": "ACK",
     "id": "r:5545791068",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#pullrequestreview-5545791068",
     "at": "2026-10-16",
     "association": "CONTRIBUTOR",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "w0xlt",
     "reason": "ACK cbadeff334",
     "substantive": false,
     "verdict": "ACK",
     "id": "r:5592756558",
     "url": "https://github.com/bitcoin/bitcoin/pull/36525#pullrequestreview-5592756558",
     "at": "2026-10-20",
     "association": "CONTRIBUTOR",
     "evidence": "none",
     "areas": []
    }
   ],
   "participants": [
    {
     "login": "enirox001",
     "stance": "support",
     "note": "ACKed with TSAN testing, supported including the test, and reACKed after the test was added",
     "association": "CONTRIBUTOR",
     "comments": 2,
     "first": "2026-10-15",
     "last": "2026-10-16"
    },
    {
     "login": "ismaelsadeeq",
     "stance": "support",
     "note": "ACKed, proposed a functional test, reACKed once the test was included, and suggested returning the block copy after applying the solution",
     "association": "MEMBER",
     "comments": 5,
     "first": "2026-10-15",
     "last": "2026-10-25"
    },
    {
     "login": "w0xlt",
     "stance": "support",
     "note": "ACKed with doc nits, and supported the suggestion to make m_block_template non-mutating",
     "association": "CONTRIBUTOR",
     "comments": 3,
     "first": "2026-10-15",
     "last": "2026-10-21"
    },
    {
     "login": "sedited",
     "stance": "question",
     "note": "suggested making m_block_template non-mutating instead of adding mutex protection, and pushed back on whether block copying distraction is a valid concern",
     "association": "MEMBER",
     "comments": 3,
     "first": "2026-10-21",
     "last": "2026-10-28"
    }
   ],
   "derivation": "substantive support, no open objection (ismaelsadeeq, enirox001)",
   "model_state": null,
   "corrections": [],
   "notes": "Sjors benchmarked making the block template immutable and returning the full block in submitSolution(), identifying an IPC single-thread latency penalty in sv2-tp and recommending deferring immutability until IPC improvements land."
  },
  "dependencies": {
   "depends_on": [],
   "enables": []
  },
  "categories": [
   {
    "name": "ipc",
    "member": false,
    "evidence": "Changes what the mining interface exposes and how block templates are synchronized rather than IPC infrastructure itself, which the category explicitly excludes.",
    "band": "Unranked",
    "reason_tag": "cleanup",
    "score": 0.0,
    "factors": {
     "bug_severity": 2,
     "leverage": 0,
     "performance": 1,
     "security_stability": 2,
     "user_value": 1
    },
    "rationale": "Not an IPC PR because the changes concern mining interface methods and block template synchronization rather than serialization, connection handling, or capnp machinery."
   },
   {
    "name": "mining",
    "member": true,
    "evidence": "Has the Mining label and modifies `src/interfaces/mining.h`, `src/node/block_template_manager.*`, and `src/ipc/capnp/mining.capnp`.",
    "band": "P2",
    "reason_tag": "bug fix",
    "score": 0.7,
    "factors": {
     "bug_severity": 2,
     "leverage": 0,
     "performance": 1,
     "security_stability": 2,
     "user_value": 1
    },
    "rationale": "Resolves a data race where concurrent IPC worker threads access `CBlockTemplate` during `submitSolution()` while another thread reads from it. Ensuring thread-safe template access and exposing `getTotalFees()` directly improves the stability and completeness of the mining interface external Stratum v2 mining consumers rely on."
   }
  ],
  "confidence": "high",
  "uncertainties": [],
  "needs": []
 },
 "cost_usd": 0.0,
 "source": {
  "record": "2026-10-30T01:14:19+00:00",
  "code": "2026-10-16T01:19:08+00:00",
  "judgments": 2
 }
}