{
 "number": 36342,
 "input_hash": "14a2bbfb43bda81c",
 "model": "ledger",
 "prompt_hash": null,
 "created": "2026-10-01T01:21:04+00:00",
 "result": {
  "summary": "Validates that each recipient amount and the running sum of recipient amounts satisfy MoneyRange in CreateTransactionInternal before coin selection starts. Removes the separate non-negative check in CreateTransaction, which is now subsumed by the MoneyRange check.",
  "problem": "CreateTransaction only checked that recipient amounts were not negative, omitting upper-bound checks against MAX_MONEY for both individual amounts and their sum. When funding transactions with large amounts (via fundrawtransaction, walletcreatefundedpsbt, or sendmany), recipients_sum could overflow int64, triggering UBSan errors, an assertion failure crash in RecalculateWaste, or wrapping around to a small positive sum and incorrectly funding outputs exceeding 21 million BTC.",
  "card": "Validates that each recipient amount and their running sum fall within MoneyRange in CreateTransactionInternal before coin selection. Without this check, transactions with large outputs passed through RPCs like fundrawtransaction can overflow the int64 recipients sum, causing node crashes via assertion failures in coin selection or wrapping to fund transactions exceeding MAX_MONEY. Functional tests are added to verify rejection of oversized outputs, cumulative overflow, and negative amounts.",
  "evidence": [
   "Author description demonstrates a reproducible node crash on master with fundrawtransaction: 'Assertion failed: (!m_selected_inputs.empty()), function RecalculateWaste, file coinselection.cpp, line 904.'",
   "Author notes that with other wrapped sums, 'fundrawtransaction returns success for a tx with outputs of 46116860184 BTC each.'"
  ],
  "scope_notes": "",
  "changed_since_previous": "No functional changes; the commit was rebased or re-formatted.",
  "thread": {
   "last_event_at": "2026-09-29T14:17:25Z",
   "events": 9,
   "head_sha": "bab579e56aa8b80a6f2923285e55cbcb2a7730b8",
   "schema_floor": 2,
   "schema": 2
  },
  "waiting_on": [
   {
    "at": "2026-09-29",
    "id": "c:5892125804",
    "on": "reviewer",
    "url": "https://github.com/bitcoin/bitcoin/pull/36342#issuecomment-5892125804",
    "what": "re-review after author incorporated loop refactoring suggestions and squashed"
   },
   {
    "at": "2026-09-28",
    "id": "c:5872415752",
    "on": "author",
    "url": "https://github.com/bitcoin/bitcoin/pull/36342#issuecomment-5872415752",
    "what": "reply to pinheadmz's suggestion to close other PRs"
   }
  ],
  "risk": {
   "level": "medium",
   "touches": [
    "wallet"
   ],
   "why": "A flaw in recipient amount validation during transaction creation could reject legitimate payments or disrupt wallet funding operations."
  },
  "discussion": {
   "author_status": "last statement processed 2026-09-29",
   "open_concerns": [
    "pinheadmz: Suggests closing 6 of the author's 7 open PRs to focus on one and avoid flooding the repository with AI-assisted submissions."
   ],
   "resolved_concerns": [
    "pinheadmz: Asks whether the submission conforms to the AI policy and whether the author understands the choices made and is solving real problems. (answered by Bruce039 2026-09-26)",
    "furszy: Move the check into the existing recipients loop and merge the negative amount check there too. (fixed by Bruce039 2026-09-29)",
    "maflcko: Combine the check into a single loop and simplify the error message to 'Transaction output amount must be valid' to avoid two loops. (fixed by Bruce039 2026-09-29)"
   ]
  },
  "reviewability": {
   "state": "Ready",
   "label": "Ready",
   "reason": "Nothing known that would invalidate a review now."
  },
  "agreement": {
   "state": "Strong",
   "summary": "Strong: substantive support, no open objection (maflcko)",
   "reason": "Added furszy's suggestion to move the MoneyRange check into the existing recipients loop, which the author implemented and squashed in c:5892125804, also resolving maflcko's suggestion rc:4131313711. maflcko's squash request rc:4134252001 is a process comment.",
   "evidence": [
    "pinheadmz (suggestion, approach, must be answered, open): Suggests closing 6 of the author's 7 open PRs to focus on one and avoid flooding the repository with AI-assisted submissions.",
    "maflcko: ACK \u2014 Seems fine as a low-prio sanity check and for nicer sanitizer use"
   ],
   "objections": [
    {
     "reviewer": "pinheadmz",
     "association": "MEMBER",
     "type": "question",
     "kind": "approach",
     "harm": "",
     "request": "",
     "question": "Asks whether the submission conforms to the AI policy and whether the author understands the choices made and is solving real problems.",
     "text": "Asks whether the submission conforms to the AI policy and whether the author understands the choices made and is solving real problems.",
     "clears_with": "answer",
     "blocking": false,
     "status": "answered",
     "status_note": "author confirmed reading the policy, clarified AI was only used for description and tests, and explained submitting multiple PRs at once",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [
      "c:5846124971"
     ],
     "evidence": "2026-09-26: 'Do all three of these conform to our AI Policy? Before we spend any precious human resources reading through your submissions can you please assure us that you understand all the choices you've made'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36342#issuecomment-5845964081",
     "id": "c:5845964081",
     "at": "2026-09-26",
     "status_at": "2026-09-26",
     "status_by": "Bruce039",
     "resolution_evidence": "2026-09-26: Bruce039: 'Yes, I've read the AI policy and I accept it. And yes, I used AI, but only for the PR description and the tests.'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "pinheadmz",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "approach",
     "harm": "",
     "request": "Suggests closing 6 of the author's 7 open PRs to focus on one and avoid flooding the repository with AI-assisted submissions.",
     "question": "",
     "text": "Suggests closing 6 of the author's 7 open PRs to focus on one and avoid flooding the repository with AI-assisted submissions.",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-09-28: 'If you really want to support the project I suggest closing 6 of them. Pick one that really means a lot to you, that you think is the most important for the most bitcoin users, and really commit to it'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36342#issuecomment-5872415752",
     "id": "c:5872415752",
     "at": "2026-09-28",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "furszy",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "approach",
     "harm": "",
     "request": "Move the check into the existing recipients loop and merge the negative amount check there too.",
     "question": "",
     "text": "Move the check into the existing recipients loop and merge the negative amount check there too.",
     "clears_with": "answer",
     "blocking": false,
     "status": "fixed",
     "status_note": "author moved the check into the existing recipients loop and removed the separate check",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": true,
     "replies": [
      "c:5892125804"
     ],
     "evidence": "2026-09-29: 'Can move the check below the existing loop: ... and could also merge the negative amount checks there too. So it is just one loop.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36342#pullrequestreview-5353722707",
     "id": "r:5353722707",
     "at": "2026-09-29",
     "status_at": "2026-09-29",
     "status_by": "Bruce039",
     "resolution_evidence": "2026-09-29: Bruce039: 'Following furszy, the MoneyRange check now sits in the existing recipients loop in `CreateTransactionInternal`, and it also covers the negative-amount case'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "maflcko",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "approach",
     "harm": "",
     "request": "Combine the check into a single loop and simplify the error message to 'Transaction output amount must be valid' to avoid two loops.",
     "question": "",
     "text": "Combine the check into a single loop and simplify the error message to 'Transaction output amount must be valid' to avoid two loops.",
     "clears_with": "answer",
     "blocking": false,
     "status": "fixed",
     "status_note": "author folded negative check into MoneyRange loop and squashed commits",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": true,
     "replies": [
      "rc:4134197408",
      "c:5892125804"
     ],
     "evidence": "2026-09-29: 'I think you can combine this check/loop  and have the error message just be \"Transaction output amount must be valid\". this avoids two loops and overly strict hand holding'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36342#discussion_r4131313711",
     "id": "rc:4131313711",
     "at": "2026-09-29",
     "status_at": "2026-09-29",
     "status_by": "Bruce039",
     "resolution_evidence": "2026-09-29: Bruce039: 'Following furszy, the MoneyRange check now sits in the existing recipients loop in `CreateTransactionInternal`, and it also covers the negative-amount case'",
     "pin": null,
     "from_schema": 2
    }
   ],
   "support": [
    {
     "reviewer": "maflcko",
     "reason": "Seems fine as a low-prio sanity check and for nicer sanitizer use",
     "substantive": true,
     "verdict": "ACK",
     "id": "c:5873589058",
     "url": "https://github.com/bitcoin/bitcoin/pull/36342#issuecomment-5873589058",
     "at": "2026-09-28",
     "association": "MEMBER",
     "evidence": "read",
     "areas": []
    }
   ],
   "participants": [
    {
     "login": "pinheadmz",
     "stance": "question",
     "note": "asked about AI policy compliance and suggested closing other PRs to focus on one",
     "association": "MEMBER",
     "comments": 2,
     "first": "2026-09-26",
     "last": "2026-09-28"
    },
    {
     "login": "maflcko",
     "stance": "support",
     "note": "ACKed as a sanity check and suggested combining the validation loop",
     "association": "MEMBER",
     "comments": 3,
     "first": "2026-09-28",
     "last": "2026-09-29"
    },
    {
     "login": "furszy",
     "stance": "neutral",
     "note": "suggested merging the check into the existing recipients loop",
     "association": "MEMBER",
     "comments": 1,
     "first": "2026-09-29",
     "last": "2026-09-29"
    }
   ],
   "derivation": "substantive support, no open objection (maflcko)",
   "model_state": null,
   "corrections": [],
   "notes": "Added furszy's suggestion to move the MoneyRange check into the existing recipients loop, which the author implemented and squashed in c:5892125804, also resolving maflcko's suggestion rc:4131313711. maflcko's squash request rc:4134252001 is a process comment."
  },
  "dependencies": {
   "depends_on": [],
   "enables": []
  },
  "categories": [
   {
    "name": "wallet",
    "member": true,
    "evidence": "Matches Wallet label and modifies wallet spend logic in src/wallet/spend.cpp to validate recipient amounts.",
    "band": "P3",
    "reason_tag": "bug fix",
    "score": 0.4,
    "factors": {
     "bug_severity": 2,
     "leverage": 0,
     "performance": 0,
     "security_stability": 1,
     "user_value": 1
    },
    "rationale": "Prevents integer overflow and an assertion crash in RecalculateWaste when wallet transaction creation RPCs receive amounts exceeding MAX_MONEY. The problem is a real correctness and crash bug, but requires authenticated RPC calls with out-of-range amounts and is reasonably deferrable."
   }
  ],
  "confidence": "high",
  "uncertainties": [],
  "needs": []
 },
 "cost_usd": 0.0,
 "source": {
  "record": "2026-10-01T01:21:04+00:00",
  "code": "2026-10-01T01:29:29+00:00",
  "judgments": 1
 }
}