{
 "number": 35994,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/35994",
 "title": "Primitives: Combine assignments",
 "author": "purpleKarrot",
 "author_association": "CONTRIBUTOR",
 "created_at": "2026-08-17T13:22:18Z",
 "updated_at": "2026-08-24T09:18:57Z",
 "age_days": 31,
 "draft": true,
 "labels": [
  "Needs rebase",
  "CI failed"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "95ea8fca11e459354b99d90d83280eefd5621c86",
 "head_ref": "combine-assignments",
 "head_repo": "purpleKarrot/bitcoin",
 "head_history": [
  {
   "t": "2026-08-17T13:39:58Z",
   "sha": "cbb9fefb9cf444179b1d9b3eceedfe68249d8d01"
  },
  {
   "t": "2026-08-17T18:55:47Z",
   "sha": "58e4280d9fa948ca688b5f1dcc3368f281bbd6f7"
  },
  {
   "t": "2026-08-17T19:29:07Z",
   "sha": "da83f7092f5a37ee2b5e60d6dfa0dc42cd2de09a"
  },
  {
   "t": "2026-08-21T09:21:47Z",
   "sha": "95ea8fca11e459354b99d90d83280eefd5621c86"
  }
 ],
 "additions": 394,
 "deletions": 366,
 "changed_files": 42,
 "commit_count": 8,
 "size_bucket": "L",
 "mergeable_state": "unknown",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_ack": [
     {
      "login": "l0rinc",
      "url": "https://github.com/bitcoin/bitcoin/pull/35994#issuecomment-5319813498"
     },
     {
      "login": "josibake",
      "url": "https://github.com/bitcoin/bitcoin/pull/35994#issuecomment-5332099006"
     },
     {
      "login": "alexanderwiederin",
      "url": "https://github.com/bitcoin/bitcoin/pull/35994#pullrequestreview-4965218337"
     }
    ]
   },
   "conflicts": [
    {
     "number": 35733,
     "title": "sign: Remove FillableSigningProvider",
     "author": "achow101"
    },
    {
     "number": 35580,
     "title": "bugfix:  compare non-adjusted chunk weight against block weight limit",
     "author": "ismaelsadeeq"
    },
    {
     "number": 35569,
     "title": "Encapsulation for CTransaction",
     "author": "purpleKarrot"
    },
    {
     "number": 35477,
     "title": "test: exercise Schnorr signature cache in txvalidationcache_tests.cpp",
     "author": "theStack"
    },
    {
     "number": 34360,
     "title": "bench: add WalletBalanceManySpent for high-history wallet scenario",
     "author": "w0xlt"
    }
   ]
  }
 },
 "acks_parsed": {
  "josibake": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-08-18T18:01:39Z",
   "stale": false
  },
  "alexanderwiederin": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-08-18T20:16:42Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 2,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "alexanderwiederin",
   "janb84",
   "josibake",
   "l0rinc",
   "maflcko"
  ]
 },
 "signals": {
  "needs_rebase": true,
  "ci_failed": true,
  "mergeable_state": "unknown",
  "last_author_activity": "2026-08-21T09:21:47Z",
  "last_reviewer_activity": "2026-08-24T08:50:20Z",
  "last_reviewer": "maflcko",
  "author_silent_days": 27,
  "waiting_on_author_days": 24,
  "days_since_update": 24
 },
 "refs": {
  "mentioned": [
   35569,
   35904
  ],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 35904,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "Factoring out a stateless, side-effect free validation library"
   },
   {
    "number": 35569,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "Encapsulation for CTransaction"
   }
  ],
  "conflicts": [
   35733,
   35580,
   35569,
   35477,
   34360
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp",
  "src/bench/ccoins_caching.cpp",
  "src/bench/duplicate_inputs.cpp",
  "src/primitives/transaction.h",
  "src/test/util/transaction_utils.cpp"
 ],
 "body": "#35904 mentions that validation code does not require the data members of `COutPoint`, `CTxOut`, and `CTxIn` to be individually mutable. This requirement instead comes from test code being written in a procedural rather than declarative style.\n\nThis PR presents a `bitcoin-tidy` check that identifies consecutive assignments to annotated data members of the same object and suggests rewriting them with a constructor invocation. This allows a mechanical refactoring of the majority of mutations and it paves the road for making the types fully immutable.",
 "commits": [
  {
   "sha": "8bd308042107943902d59035d47ad217f89d7dde",
   "date": "2026-08-21T09:21:24Z",
   "message": "bitcoin-tidy: Add combine-assignments check\n\nAdd a check to bitcoin-tidy that detects multiple consecutive assignments\nto data members of the same base and suggests a constructor call as a\nreplacement."
  },
  {
   "sha": "db610323e322b2fba105c627c6b2a1f0e301ed3d",
   "date": "2026-08-21T09:21:25Z",
   "message": "attributes: Add CONSTRUCTOR_ARGUMENT annotation helper"
  },
  {
   "sha": "752c8629547546768c6524bc3f249a44f7d83fcf",
   "date": "2026-08-21T09:21:27Z",
   "message": "COutPoint: Add CONSTRUCTOR_ARGUMENT annotation"
  },
  {
   "sha": "3c3432a1270b8a7aa1b76d97fd2954f3969875de",
   "date": "2026-08-21T09:21:28Z",
   "message": "COutPoint: Apply combine-assignments fixup"
  },
  {
   "sha": "46cd7ed0014af673e2460aff43f3f89f7c1ef213",
   "date": "2026-08-21T09:21:29Z",
   "message": "CTxOut: Add CONSTRUCTOR_ARGUMENT annotation"
  },
  {
   "sha": "039a7c14d76bf6eeafb7706361c84a1682a2fc8e",
   "date": "2026-08-21T09:21:30Z",
   "message": "CTxOut: Apply combine-assignments fixup"
  },
  {
   "sha": "61ca1dc254ae39968f0d58349bf90fb755ffaa8a",
   "date": "2026-08-21T09:21:32Z",
   "message": "CTxIn: Add CONSTRUCTOR_ARGUMENT annotation"
  },
  {
   "sha": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "date": "2026-08-21T09:21:33Z",
   "message": "CTxIn: Apply combine-assignments fixup"
  }
 ],
 "timeline": [
  {
   "t": "2026-08-17T13:39:58Z",
   "kind": "force_push",
   "who": "purpleKarrot",
   "commit": "cbb9fefb9cf444179b1d9b3eceedfe68249d8d01"
  },
  {
   "t": "2026-08-17T18:55:47Z",
   "kind": "force_push",
   "who": "purpleKarrot",
   "commit": "58e4280d9fa948ca688b5f1dcc3368f281bbd6f7"
  },
  {
   "t": "2026-08-17T19:29:07Z",
   "kind": "force_push",
   "who": "purpleKarrot",
   "commit": "da83f7092f5a37ee2b5e60d6dfa0dc42cd2de09a"
  },
  {
   "t": "2026-08-17T20:22:20Z",
   "kind": "comment",
   "who": "l0rinc",
   "assoc": "CONTRIBUTOR",
   "text": "I understand that it's not always trivial to run every check locally, but we're getting notifications about every push and it doesn't really increase the confidence in changes like this if they don't even pass CI.\nI usually push these to my own fork first to make sure the change makes sense before pushing here.\nAlso, the `Primitives: Combine assignments` give no clue about what this PR is about, but reading the code seems to make sense, concept ACK."
  },
  {
   "t": "2026-08-18T05:35:09Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/primitives/transaction.h",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": null,
   "text": "Is the annotation really required? I'd guess that clang-tidy should be able to iterator over all ctors with args itself and then derive this itself?\n\nThe benefit would be that there is only a single source of truth and this won't go stale. Also, manual marking wouldn't be needed. (If you want to limit this to a selected set of classes, it would be better to pass the list as an option to clang-tidy?)"
  },
  {
   "t": "2026-08-18T05:36:59Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/bench/ccoins_caching.cpp",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": null,
   "text": "Is there a reason to not use the C++11 narrowing checks for new code? Other places use a `static_cast<uint32_t>()` for the second arg, and I think this is useful to know about and be explicit.\n\n```suggestion\n    t1.vin[2].prevout = COutPoint{dummyTransactions[1].GetHash(), 1};\n```"
  },
  {
   "t": "2026-08-18T05:39:44Z",
   "kind": "review",
   "who": "maflcko",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "da83f7092f5a37ee2b5e60d6dfa0dc42cd2de09a",
   "text": "Looks like this is mostly a test-only cleanup (modulo ~6 instances in real code).\n\nSeems fine, as this should reduce test issues due to re-using dirty state accidentally (c.f. https://github.com/bitcoin/bitcoin/pull/35863 et al)"
  },
  {
   "t": "2026-08-18T05:40:55Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": null,
   "text": "```suggestion\n        CheckFactories.registerCheck<CombineAssignments>(\"bitcoin-prefer-ctor\");\n```\n\nGiven that the was confusion about the name, maybe name it differently?"
  },
  {
   "t": "2026-08-18T07:29:40Z",
   "kind": "comment",
   "who": "purpleKarrot",
   "assoc": "CONTRIBUTOR",
   "text": "I pushed this both to back the claim that most mutations appear in test code, but also as a base for discussion about the approach.\n\nOne approach would be to submit this PR as is.\n\nAn alternative approach would be to focus on one class at a time, like \"COutPoint: Make type immutable\". Such a PR would then apply `bitcoin-prefer-ctor` as introduced here, `bitcoin-use-observers` from #35569, some manual fixes, plus the change to make the data members private. In this approach, https://github.com/bitcoin/bitcoin/pull/35994#discussion_r3801299334 would be less of an issue, because the annotations would be temporary anyway.\n\nYet another approach would be to just use this PR as a backlog to identify \"places of interest\" and then rewrite the code manually, one file at a time, in a declarative style. For example, this code:\n\nhttps://github.com/bitcoin/bitcoin/blob/6751a323c0130310880c84e03f7104f6bb86385d/src/bench/ccoins_caching.cpp#L35-L51\n\ncould be rewritten (assuming the necessary constructors are made available) as:\n\n```cpp\nconst CTransaction tx_1{\n    std::vector{\n        CTxIn{COutPoint{dummyTransactions[0].GetHash(), 1}, CScript{} << std::vector<unsigned char>(65, 0)},\n        CTxIn{COutPoint{dummyTransactions[1].GetHash(), 0}, CScript{} << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4)},\n        CTxIn{COutPoint{dummyTransactions[1].GetHash(), 1}, CScript{} << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4)},\n    },\n    std::vector{\n        CTxOut{90 * COIN, CScript{} << OP_1},\n        CTxOut{},\n    },\n};\n```\n\nIn this approach, https://github.com/bitcoin/bitcoin/pull/35994#discussion_r3801307204 can be applied directly, with explicit conversions where necessary."
  },
  {
   "t": "2026-08-18T07:35:17Z",
   "kind": "review_comment",
   "who": "purpleKarrot",
   "assoc": "CONTRIBUTOR",
   "path": "src/bench/ccoins_caching.cpp",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": 3801307204,
   "text": "Yes, there are a few places where aggregate initialization would not compile, unfortunately."
  },
  {
   "t": "2026-08-18T07:46:32Z",
   "kind": "review_comment",
   "who": "purpleKarrot",
   "assoc": "CONTRIBUTOR",
   "path": "src/primitives/transaction.h",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": 3801299334,
   "text": "I don't want to build too many heuristics into the clang-tidy check. But depending on how we approach the change, it may be less of an issue or not be needed at all (see https://github.com/bitcoin/bitcoin/pull/35994#issuecomment-5325013842)."
  },
  {
   "t": "2026-08-18T10:45:21Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/bench/ccoins_caching.cpp",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": 3801307204,
   "text": "Ok, I see. I wonder if it is worth it to update them manually (either by adding a static_cast, or by updating the outer type to `unsigned`, or so)?\n\nGiven that such a patch should be easy to review and test-only, with other benefits, it seems fine to submit it and I'd be happy to review it, but no strong opinion."
  },
  {
   "t": "2026-08-18T11:56:27Z",
   "kind": "comment",
   "who": "janb84",
   "assoc": "CONTRIBUTOR",
   "text": "If i'm not mistaken, I read 3 options from the [comment of purpleKarrot:](https://github.com/bitcoin/bitcoin/pull/35994#issuecomment-5325013842)\n\n**A. Merge this PR as is.** The tooling lands in this PR but needs annotations to work. The drawback is that the `CONSTRUCTOR_ARGUMENT` annotations stay in `primitives/transaction.h` with no guarantee that a follow-up removes them, and reviewers approve a large mechanical diff with the justification in a future PR.\n\n**B. One class at a time, ending in \"immutability\".** For example \"COutPoint: Make type immutable\": annotate, run the check, run use-observers from #35569, fix the rest by hand, make the members private, and delete the annotations in the same PR. Each PR is self contained and  can be judged as a whole if the change is worth the churn.\n\n**C. Use the check as a backlog only.** Never merge the annotations. Run the check locally to find candidate files and rewrite them by hand in declarative style.\n\n--\n\nPersonally I would opt for option B, where a tracking issue can be used to identify and coordinate the effort, keep this  bitcoin-tidy code etc. If i'm not mistaken (or mis-understood the comment) this will result in PR's that are self contained with no, or little, follow ups so that the benefits, churn and results are clearly visible in one PR."
  },
  {
   "t": "2026-08-18T12:28:13Z",
   "kind": "comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "text": "I am not sure about throwing this in the same bucket as https://github.com/bitcoin/bitcoin/pull/35569. I think it is pretty clear that a CTransaction should not be mutable (otherwise there wouldn't be a MutableTransaction).\n\nHowever, for other structs, is there much value/benefit? https://github.com/bitcoin/bitcoin/pull/35569 seems a bit controversial, so expanding it to stuff that has even less benefit may not be the best approach?\n\nI'd leave this a mostly test-only cleanup (plus maybe https://github.com/bitcoin/bitcoin/pull/35994#discussion_r3803317221), but no strong opinion."
  },
  {
   "t": "2026-08-18T18:01:39Z",
   "kind": "comment",
   "who": "josibake",
   "assoc": "MEMBER",
   "text": "Concept ACK\n\n[quoted text omitted]\nCleaning up the tests is a convention. It does nothing to stop the same buggy behaviour being repeated in the future. Can you explain what benefit you see to keeping the structs in this PR mutable?"
  },
  {
   "t": "2026-08-18T19:55:10Z",
   "kind": "review_comment",
   "who": "alexanderwiederin",
   "assoc": "CONTRIBUTOR",
   "path": "src/bench/ccoins_caching.cpp",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": 3801307204,
   "text": "I tried switching the fix-it to emit {}. From what I can tell everything that then fails to compile is in test/bench."
  },
  {
   "t": "2026-08-18T19:57:43Z",
   "kind": "review_comment",
   "who": "alexanderwiederin",
   "assoc": "CONTRIBUTOR",
   "path": "src/test/util/transaction_utils.cpp",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": null,
   "text": "Does this drop the witness?"
  },
  {
   "t": "2026-08-18T20:16:42Z",
   "kind": "review",
   "who": "alexanderwiederin",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "da83f7092f5a37ee2b5e60d6dfa0dc42cd2de09a",
   "text": "Concept ACK\n\nDo the checks here need to be run to a fixed point or is a single pass sufficient? Might be worth adding the invocation in the commit messages, so the mechanical changes can be verified."
  },
  {
   "t": "2026-08-18T20:22:28Z",
   "kind": "review_comment",
   "who": "purpleKarrot",
   "assoc": "CONTRIBUTOR",
   "path": "src/test/util/transaction_utils.cpp",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": 3807467505,
   "text": "Indeed."
  },
  {
   "t": "2026-08-18T20:38:13Z",
   "kind": "comment",
   "who": "purpleKarrot",
   "assoc": "CONTRIBUTOR",
   "text": "[quoted text omitted]\n\nThey do belong into the same bucket. As I wrote in https://github.com/bitcoin/bitcoin/pull/35569#issuecomment-5281383955:\n\n[quoted text omitted]\nThose types should be made immutable, with no associated builder (no `CMutableTransaction`), and code that \"builds\" those types in procedural code should be rewritten in a declarative style (this mostly affects test code).\n\nWhich is exactly the claim that I wanted to back with this draft.\n\nConcerning the approach, I actually lean towards **C**."
  },
  {
   "t": "2026-08-19T08:02:50Z",
   "kind": "comment",
   "who": "alexanderwiederin",
   "assoc": "CONTRIBUTOR",
   "text": "[quoted text omitted]\n\nThat sounds reasonable to me. It means the surrounding context gets read, the narrowing conversions get made explicit and comments in the affected blocks survive.\n\nI've started on a couple of these in `/bench`. Happy to keep going if that's useful."
  },
  {
   "t": "2026-08-21T09:21:47Z",
   "kind": "force_push",
   "who": "purpleKarrot",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86"
  },
  {
   "t": "2026-08-24T08:50:20Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/bench/duplicate_inputs.cpp",
   "commit": "95ea8fca11e459354b99d90d83280eefd5621c86",
   "in_reply_to": null,
   "text": "should probably use init-list, like https://github.com/bitcoin/bitcoin/pull/36019#discussion_r3811388178"
  }
 ],
 "labels_log": [
  {
   "t": "2026-08-17T19:29:55Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-17T21:07:26Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-21T08:16:39Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-21T10:48:09Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-21T10:53:18Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-24T09:18:56Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  }
 ],
 "state_log": [],
 "text_chars": 8410,
 "text_tokens_estimate": 2102,
 "changed_paths": [
  "contrib/devtools/bitcoin-tidy/CMakeLists.txt",
  "contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp",
  "contrib/devtools/bitcoin-tidy/combine-assignments.cpp",
  "contrib/devtools/bitcoin-tidy/combine-assignments.h",
  "src/attributes.h",
  "src/bench/ccoins_caching.cpp",
  "src/bench/duplicate_inputs.cpp",
  "src/bench/mempool_eviction.cpp",
  "src/bench/mempool_stress.cpp",
  "src/bench/rpc_mempool.cpp",
  "src/bench/wallet_create_tx.cpp",
  "src/bitcoin-tx.cpp",
  "src/kernel/chainparams.cpp",
  "src/primitives/transaction.h",
  "src/psbt.cpp",
  "src/rpc/rawtransaction_util.cpp",
  "src/test/blockencodings_tests.cpp",
  "src/test/fuzz/cmpctblock.cpp",
  "src/test/fuzz/coinscache_sim.cpp",
  "src/test/fuzz/package_eval.cpp",
  "src/test/fuzz/tx_pool.cpp",
  "src/test/fuzz/util.cpp",
  "src/test/mempool_tests.cpp",
  "src/test/miner_tests.cpp",
  "src/test/miniminer_tests.cpp",
  "src/test/multisig_tests.cpp",
  "src/test/orphanage_tests.cpp",
  "src/test/rbf_tests.cpp",
  "src/test/script_p2sh_tests.cpp",
  "src/test/sighash_tests.cpp",
  "src/test/sigopcount_tests.cpp",
  "src/test/transaction_tests.cpp",
  "src/test/txospenderindex_tests.cpp",
  "src/test/txpackage_tests.cpp",
  "src/test/txvalidation_tests.cpp",
  "src/test/txvalidationcache_tests.cpp",
  "src/test/util/mining.cpp",
  "src/test/util/transaction_utils.cpp",
  "src/test/validation_block_tests.cpp",
  "src/validation.cpp",
  "src/wallet/test/fuzz/spend.cpp",
  "src/wallet/test/group_outputs_tests.cpp"
 ],
 "files": [
  {
   "path": "contrib/devtools/bitcoin-tidy/CMakeLists.txt",
   "add": 7,
   "del": 1
  },
  {
   "path": "contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp",
   "add": 2,
   "del": 0
  },
  {
   "path": "contrib/devtools/bitcoin-tidy/combine-assignments.cpp",
   "add": 183,
   "del": 0
  },
  {
   "path": "contrib/devtools/bitcoin-tidy/combine-assignments.h",
   "add": 12,
   "del": 0
  },
  {
   "path": "src/attributes.h",
   "add": 9,
   "del": 0
  },
  {
   "path": "src/bench/ccoins_caching.cpp",
   "add": 3,
   "del": 6
  },
  {
   "path": "src/bench/duplicate_inputs.cpp",
   "add": 2,
   "del": 4
  },
  {
   "path": "src/bench/mempool_eviction.cpp",
   "add": 11,
   "del": 22
  },
  {
   "path": "src/bench/mempool_stress.cpp",
   "add": 2,
   "del": 4
  },
  {
   "path": "src/bench/rpc_mempool.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/bench/wallet_create_tx.cpp",
   "add": 2,
   "del": 4
  },
  {
   "path": "src/bitcoin-tx.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/kernel/chainparams.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/primitives/transaction.h",
   "add": 7,
   "del": 7
  },
  {
   "path": "src/psbt.cpp",
   "add": 2,
   "del": 4
  },
  {
   "path": "src/rpc/rawtransaction_util.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/test/blockencodings_tests.cpp",
   "add": 3,
   "del": 6
  },
  {
   "path": "src/test/fuzz/cmpctblock.cpp",
   "add": 2,
   "del": 5
  },
  {
   "path": "src/test/fuzz/coinscache_sim.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/test/fuzz/package_eval.cpp",
   "add": 1,
   "del": 3
  },
  {
   "path": "src/test/fuzz/tx_pool.cpp",
   "add": 1,
   "del": 3
  },
  {
   "path": "src/test/fuzz/util.cpp",
   "add": 1,
   "del": 3
  },
  {
   "path": "src/test/mempool_tests.cpp",
   "add": 19,
   "del": 38
  },
  {
   "path": "src/test/miner_tests.cpp",
   "add": 13,
   "del": 28
  },
  {
   "path": "src/test/miniminer_tests.cpp",
   "add": 1,
   "del": 4
  },
  {
   "path": "src/test/multisig_tests.cpp",
   "add": 2,
   "del": 4
  },
  {
   "path": "src/test/orphanage_tests.cpp",
   "add": 8,
   "del": 16
  },
  {
   "path": "src/test/rbf_tests.cpp",
   "add": 2,
   "del": 4
  },
  {
   "path": "src/test/script_p2sh_tests.cpp",
   "add": 30,
   "del": 60
  },
  {
   "path": "src/test/sighash_tests.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/test/sigopcount_tests.cpp",
   "add": 3,
   "del": 6
  },
  {
   "path": "src/test/transaction_tests.cpp",
   "add": 20,
   "del": 40
  },
  {
   "path": "src/test/txospenderindex_tests.cpp",
   "add": 2,
   "del": 4
  },
  {
   "path": "src/test/txpackage_tests.cpp",
   "add": 6,
   "del": 12
  },
  {
   "path": "src/test/txvalidation_tests.cpp",
   "add": 4,
   "del": 8
  },
  {
   "path": "src/test/txvalidationcache_tests.cpp",
   "add": 18,
   "del": 36
  },
  {
   "path": "src/test/util/mining.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/test/util/transaction_utils.cpp",
   "add": 5,
   "del": 12
  },
  {
   "path": "src/test/validation_block_tests.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/validation.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/wallet/test/fuzz/spend.cpp",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/wallet/test/group_outputs_tests.cpp",
   "add": 1,
   "del": 2
  }
 ],
 "test_lines": 719,
 "git": {
  "head": "95ea8fca11e459354b99d90d83280eefd5621c86",
  "head_matches_backup": true,
  "base": "f5e91c6fbae7dc0377dd382814ace063f50e2741",
  "commits": [
   {
    "sha": "8bd3080421",
    "subject": "bitcoin-tidy: Add combine-assignments check",
    "files": 4,
    "add": 204,
    "del": 1
   },
   {
    "sha": "db610323e3",
    "subject": "attributes: Add CONSTRUCTOR_ARGUMENT annotation helper",
    "files": 1,
    "add": 9,
    "del": 0
   },
   {
    "sha": "752c862954",
    "subject": "COutPoint: Add CONSTRUCTOR_ARGUMENT annotation",
    "files": 1,
    "add": 2,
    "del": 2
   },
   {
    "sha": "3c3432a127",
    "subject": "COutPoint: Apply combine-assignments fixup",
    "files": 18,
    "add": 57,
    "del": 114
   },
   {
    "sha": "46cd7ed001",
    "subject": "CTxOut: Add CONSTRUCTOR_ARGUMENT annotation",
    "files": 1,
    "add": 2,
    "del": 2
   },
   {
    "sha": "039a7c14d7",
    "subject": "CTxOut: Apply combine-assignments fixup",
    "files": 27,
    "add": 113,
    "del": 228
   },
   {
    "sha": "61ca1dc254",
    "subject": "CTxIn: Add CONSTRUCTOR_ARGUMENT annotation",
    "files": 1,
    "add": 3,
    "del": 3
   },
   {
    "sha": "95ea8fca11",
    "subject": "CTxIn: Apply combine-assignments fixup",
    "files": 6,
    "add": 6,
    "del": 18
   }
  ],
  "patch_truncated": true
 },
 "input_hash": "a1b95fb71e515457",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}