{
 "number": 36266,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/36266",
 "title": "rpc: Let dumptxoutset fail early on stale targets and concurrent runs",
 "author": "fjahr",
 "author_association": "MEMBER",
 "created_at": "2026-09-16T07:25:34Z",
 "updated_at": "2026-09-16T07:25:55Z",
 "age_days": 1,
 "draft": false,
 "labels": [
  "RPC/REST/ZMQ"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "31000db0ea566f800679323894063b2941bae0cc",
 "head_ref": "2026-09-dump-fail-early",
 "head_repo": "fjahr/bitcoin",
 "head_history": [],
 "additions": 57,
 "deletions": 12,
 "changed_files": 2,
 "commit_count": 2,
 "size_bucket": "S",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {},
   "conflicts": []
  }
 },
 "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": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-09-15T22:09:18Z",
  "last_reviewer_activity": null,
  "last_reviewer": null,
  "author_silent_days": 1,
  "waiting_on_author_days": 0,
  "days_since_update": 1
 },
 "refs": {
  "mentioned": [],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [],
  "conflicts": []
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [],
 "body": "This improves handling of two edge cases where `dumptxoutset` currently only fails after doing unnecessary and possibly incorrect work:\n\nStale rollback target (first commit): `ParseHashOrHeight` accepts any known block hash, and the rollback path never checks the target is on the active chain. The full UTXO set is copied and blocks are disconnected back from the tip only to fail when the target block height is reached. This is now rejected before all that as an invalid param, matching the check in `getchaintxstats` and `scanblocks`. This is a pretty unlikely scenario but the fix is also very small.\n\nConcurrent calls (second commit): Nothing prevented triggering two runs at once and since this is a relatively long running operation I don't think it is that unlikely that this might happen by accident or that users think this might actually be a possible thing to do if you want two different dumps. On master currently both runs would write to `<path>.incomplete`, so the second dump to the same path corrupts the file the first one reports as successfully written. And also the prune lock has a fixed name, so the second run overwrites the first's height and the first to finish deletes the others lock mid-rollback. A second call now fails immediately with \"dumptxoutset is already running\". `TemporaryPruneLock` is extended and renamed to `DumptxoutsetGuard` and handles both the general running of multiple instances and the lock management. The alternative to this approach would be to allow for concurrent runs and fix that behavior but it seemed to me like that would be overengineering considering that the audience for this functionality should be very small.",
 "commits": [
  {
   "sha": "35a9b9193fa1d647c2733f60231a28dacca785f1",
   "date": "2026-09-15T14:07:03Z",
   "message": "rpc: Exit dumptxoutset early if target is stale"
  },
  {
   "sha": "31000db0ea566f800679323894063b2941bae0cc",
   "date": "2026-09-15T22:09:18Z",
   "message": "rpc: Reject concurrent dumptxoutset calls"
  }
 ],
 "timeline": [],
 "labels_log": [
  {
   "t": "2026-09-16T07:25:38Z",
   "action": "labeled",
   "label": "RPC/REST/ZMQ",
   "who": "DrahtBot"
  }
 ],
 "state_log": [],
 "text_chars": 1837,
 "text_tokens_estimate": 459,
 "changed_paths": [
  "src/rpc/blockchain.cpp",
  "test/functional/rpc_dumptxoutset.py"
 ],
 "files": [
  {
   "path": "src/rpc/blockchain.cpp",
   "add": 24,
   "del": 11
  },
  {
   "path": "test/functional/rpc_dumptxoutset.py",
   "add": 33,
   "del": 1
  }
 ],
 "test_lines": 34,
 "git": {
  "head": "31000db0ea566f800679323894063b2941bae0cc",
  "head_matches_backup": true,
  "base": "dadca55f60ad1e756bd9ad88351729f0e6af2181",
  "commits": [
   {
    "sha": "35a9b9193f",
    "subject": "rpc: Exit dumptxoutset early if target is stale",
    "files": 2,
    "add": 9,
    "del": 1
   },
   {
    "sha": "31000db0ea",
    "subject": "rpc: Reject concurrent dumptxoutset calls",
    "files": 2,
    "add": 48,
    "del": 11
   }
  ],
  "patch_truncated": false
 },
 "input_hash": "e40d8bbd64600c8e",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}