{
 "number": 34729,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/34729",
 "title": "Reduce log noise",
 "author": "ajtowns",
 "author_association": "MEMBER",
 "created_at": "2026-03-04T11:56:05Z",
 "updated_at": "2026-09-17T04:45:50Z",
 "age_days": 197,
 "draft": false,
 "labels": [],
 "milestone": null,
 "base": "master",
 "head_sha": "91f8b365e7e7887e59240651c2c76b1a64071233",
 "head_ref": "202603-logerror",
 "head_repo": "ajtowns/bitcoin",
 "head_history": [
  {
   "t": "2026-04-22T12:16:49Z",
   "sha": "ac131ef122f057b4905f5aa1b7b237a6a2e3e707"
  },
  {
   "t": "2026-04-23T15:24:00Z",
   "sha": "5359a99eb9b5bd442daee6c35d133ee5ea9f6583"
  },
  {
   "t": "2026-05-28T08:44:42Z",
   "sha": "7bf185f483836db91c1fcccbbd01957ac397ead2"
  },
  {
   "t": "2026-05-28T08:50:26Z",
   "sha": "8d60c1428507921d9dd70c9840c41e447649268f"
  },
  {
   "t": "2026-08-15T19:38:10Z",
   "sha": "d21e76d3d095cde6808fbffff35e584ba04b7cf0"
  },
  {
   "t": "2026-08-15T20:29:46Z",
   "sha": "03a1e6949c180209e2a5327d3b0883fb701f4d11"
  },
  {
   "t": "2026-08-15T21:11:23Z",
   "sha": "91f8b365e7e7887e59240651c2c76b1a64071233"
  }
 ],
 "additions": 85,
 "deletions": 54,
 "changed_files": 13,
 "commit_count": 7,
 "size_bucket": "M",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "stale_ack": [
     {
      "login": "kevkevinpal",
      "url": "https://github.com/bitcoin/bitcoin/pull/34729#pullrequestreview-3889901411"
     },
     {
      "login": "sedited",
      "url": "https://github.com/bitcoin/bitcoin/pull/34729#pullrequestreview-4565520869"
     },
     {
      "login": "l0rinc",
      "url": "https://github.com/bitcoin/bitcoin/pull/34729#pullrequestreview-4566335613"
     },
     {
      "login": "ryanofsky",
      "url": "https://github.com/bitcoin/bitcoin/pull/34729#pullrequestreview-4699929573"
     }
    ]
   },
   "conflicts": [
    {
     "number": 36002,
     "title": "txindex: allow running in pruned mode",
     "author": "andrewtoth"
    },
    {
     "number": 35733,
     "title": "sign: Remove FillableSigningProvider",
     "author": "achow101"
    },
    {
     "number": 35646,
     "title": "RFC: Separate out runtime errors from BlockValidationState using `util::Expected`",
     "author": "yuvicc"
    },
    {
     "number": 34520,
     "title": "refactor: Add [[nodiscard]] to functions returning bool+mutable ref",
     "author": "maflcko"
    },
    {
     "number": 29700,
     "title": "kernel, refactor: return error status on all fatal errors",
     "author": "ryanofsky"
    }
   ]
  }
 },
 "acks_parsed": {
  "kevkevinpal": {
   "kind": "ack",
   "hash": "c665935d02b633032147e58436e3a1c6511d64f3",
   "t": "2026-03-04T15:00:53Z",
   "stale": true
  },
  "ryanofsky": {
   "kind": "ack",
   "hash": "8d60c1428507921d9dd70c9840c41e447649268f",
   "t": "2026-07-15T01:01:29Z",
   "stale": true
  },
  "sedited": {
   "kind": "ack",
   "hash": "8d60c1428507921d9dd70c9840c41e447649268f",
   "t": "2026-06-24T20:05:05Z",
   "stale": true
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 3,
  "concept_ack": 0,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 6,
  "changes_requested": 0,
  "distinct_reviewers": [
   "achow101",
   "kevkevinpal",
   "l0rinc",
   "ryanofsky",
   "sedited"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-08-15T21:11:23Z",
  "last_reviewer_activity": "2026-07-15T01:01:29Z",
  "last_reviewer": "ryanofsky",
  "author_silent_days": 32,
  "waiting_on_author_days": 0,
  "days_since_update": 0
 },
 "refs": {
  "mentioned": [
   29236,
   30348,
   34549,
   34730
  ],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 29236,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2024-03-12",
    "title": "log: Nuke error(...)"
   },
   {
    "number": 34549,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-02-20",
    "title": "net: reduce log level for PCP/NAT-PMP NOT_AUTHORIZED failures"
   },
   {
    "number": 30348,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "RFC: Misused LogError and LogWarning macros"
   },
   {
    "number": 34730,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "util/log: Combine the warning/error log levels into a single alert level"
   }
  ],
  "conflicts": [
   36002,
   35733,
   35646,
   34520,
   29700
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "doc/developer-notes.md",
  "src/bitcoin-tx.cpp",
  "src/index/txindex.cpp",
  "src/kernel/coinstats.cpp",
  "src/netbase.cpp",
  "src/script/signingprovider.cpp",
  "src/util/log.h",
  "src/validation.cpp",
  "src/wallet/test/wallet_tests.cpp"
 ],
 "body": "This set of changes reduces some of the exaggerated logging that was introduced in #29236 when \"error()\" logging was upgraded from `LogPrintf` (aka `LogInfo`) to `LogError`. It also introduces `LogWarnThenDebug()` which duplicates the behaviour of #34549 which issues a warning the first time the log line is hit, but downgrades that to categorized debug messages afterwards. This function is used for failures that are likely caused by system configuration problems (so likely degrade the node's functionality and warrant admin attention) but are triggered by remote activity and thus could occur frequently.",
 "commits": [
  {
   "sha": "ec627b3f3b82929bf517fd5d00d0ea54f4fcc187",
   "date": "2026-08-15T21:08:59Z",
   "message": "util/log: Add LogWarnThenDebug() helper\n\nThis generalises the functionality introduced for PCP/NAT-PMP logging\nin #34549."
  },
  {
   "sha": "4f42b76ca76b54de5b4794e2402aaa5ea2925862",
   "date": "2026-08-15T21:09:00Z",
   "message": "netbase: Reduce levels of socks5 error logging"
  },
  {
   "sha": "7902a8ee83fc1b81e29710b0b00b2316b42cacef",
   "date": "2026-08-15T21:09:00Z",
   "message": "netbase: Tidy up logging levels\n\nThis mostly reduces log noise by using BCLog::NET debug logging where\npossible (with `LogWarnThenDebug()` used to ensure the first log message\nstill appears for things that may be due to system misconfiguration).\nAlso drops some unnecessary trailing newlines."
  },
  {
   "sha": "3c4336631e3d05705521cc5c1001b73bc5a6cd1d",
   "date": "2026-08-15T21:09:00Z",
   "message": "script: Lower level of oversized redeemScript log, push errors to callers"
  },
  {
   "sha": "93b9613b764a046148b426abf63d1a1f5058f019",
   "date": "2026-08-15T21:09:00Z",
   "message": "kernel/coinstats: Downgrade ComputeUTXOStats log level"
  },
  {
   "sha": "788242d6d009e57cdf9f132bea1a6aee1c23c6f5",
   "date": "2026-08-15T21:09:00Z",
   "message": "txindex: Downgrade log messages and include index name"
  },
  {
   "sha": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "date": "2026-08-15T21:09:00Z",
   "message": "validation: Upgrade log levels for possible block corruption warnings"
  }
 ],
 "timeline": [
  {
   "t": "2026-03-04T11:59:31Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "See #30348 for further background; I think the changes here should be able to stand on their own merits. I haven't addressed cases where there's ambiguity between LogWarning and LogError here, but if there are other current cases where things are at Warning/Error and should be Info, or at Warning/Error/Info and should be Debug, happy to add them to this PR."
  },
  {
   "t": "2026-03-04T14:48:02Z",
   "kind": "review_comment",
   "who": "kevkevinpal",
   "assoc": "CONTRIBUTOR",
   "path": "src/validation.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "```suggestion\n            LogWarning(BCLog::VALIDATION, %s: Missing input %d in transaction \\'%s\\'\", __func__, i, tx.GetHash().GetHex());\n```"
  },
  {
   "t": "2026-03-04T14:48:20Z",
   "kind": "review_comment",
   "who": "kevkevinpal",
   "assoc": "CONTRIBUTOR",
   "path": "src/validation.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "```suggestion\n        LogWarning(BCLog::VALIDATION, \"Block validation error: %s\", state.ToString());\n```"
  },
  {
   "t": "2026-03-04T15:00:53Z",
   "kind": "review",
   "who": "kevkevinpal",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "c665935d02b633032147e58436e3a1c6511d64f3",
   "text": "ACK c665935d02b633032147e58436e3a1c6511d64f3\n\nThis is a good improvement on the amount of functional code dedicated to logging. Also, the `LogWarnThenDebug` log will be useful in future cases to help avoid log noise\n\nAdded two comments about potentially adding `BCLog::VALIDATION` to the two validation logs touched"
  },
  {
   "t": "2026-03-05T03:12:16Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/validation.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2884217388,
   "text": "LogWarning doesn't accept a filter category because it isn't filterable."
  },
  {
   "t": "2026-03-05T03:12:34Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/validation.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2884218959,
   "text": "LogWarning doesn't accept a filter category because it isn't filterable."
  },
  {
   "t": "2026-03-06T02:41:12Z",
   "kind": "review_comment",
   "who": "kevkevinpal",
   "assoc": "CONTRIBUTOR",
   "path": "src/validation.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2884218959,
   "text": "Ahh ya my bad. Also, it makes sense to have only debug logs to be filterable since warnings and errors should always be seen."
  },
  {
   "t": "2026-03-06T17:17:32Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "In commit \"netbase: Tidy up logging levels\" (436bc942d362aefbf7315c73f74d032dcb75f435)\n\nMaybe prefix this with `Error:` to indicate a problem has occurred and distinguish this from informational debug messages\n\nWould suggest the same for other some messages below that aren't clearly labeled as error or failures."
  },
  {
   "t": "2026-03-06T17:30:43Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "In commit \"netbase: Reduce levels of socks5 error logging\" (75674718fd35102be0db288802c7dc3af57ca986)\n\nIf this is an error communicating with the proxy server (as opposed to an error with the proxy server making a remote connection), it would seem potentially important for the user to know about so they can fix the problem with the server. Hiding this could make problems harder to diagnose, and it might be better to keep the previous level"
  },
  {
   "t": "2026-03-06T17:38:03Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "In commit \"netbase: Tidy up logging levels\" (436bc942d362aefbf7315c73f74d032dcb75f435)\n\nThis change seems ok, but if the goal in the commit message is to use higher levels for errors \"that may be due to system misconfiguration\" I don't know why this socket error would be more likely to be the result of misconfiguration than SO_NOSIGPIPE above, or if something else account for the difference like this error being considered more severe?"
  },
  {
   "t": "2026-03-06T17:48:59Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/bitcoin-tx.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "In commit \"script: Lower level of oversized redeemScript log, push errors to callers\" (c02d58966796c80a37d745957e37d5134d0c093d)\n\nIt seems good to throw an error here though text of this message doesn't seem ideal. Redeemscript blob is potentially large and earler logged message seems more helpful (though I'm not sure if logs are shown in bitcoin-tx so it might also be useless). Might want to add another TODO comment here to improve"
  },
  {
   "t": "2026-03-06T19:07:01Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "In commit \"netbase: Reduce levels of socks5 error logging\" (75674718fd35102be0db288802c7dc3af57ca986)\n\nI\u2019m not sure `LogWarnThenDebug()` is the best fit here. Compared to the earlier uses in this commit and the previous one, this seems less like a persistent configuration problem and more like something that could be intermittent, e.g. due to hitting resource limits.\n\nIn that case, warning exactly once and never again may hide recurring failures. It would seem better to have a rate limit and show the error once per hour or once per day while it is still occurring, not to just show it once and never again for the lifetime of the process. Absent that, keeping this at info/warning/error level might be safer."
  },
  {
   "t": "2026-03-06T20:28:26Z",
   "kind": "review",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "state": "APPROVED",
   "commit": "c665935d02b633032147e58436e3a1c6511d64f3",
   "text": "Code review ACK c665935d02b633032147e58436e3a1c6511d64f3, Concept -0. Changes here seem logical overall, and I left comments the few places where I had concerns. The `LogWarnThenDebug` macro also seems cool and potentially useful more places.\n\nThe thing I don\u2019t like about this change is that it makes it harder to see if messages are errors or warnings or normal notifications. Being able to see `[error]` and `[warning]` tags is a nice feature that is unfortunate to lose. [^1]\n\nIn an ideal world I would use `LogWarning` and `LogError` macros **more** places rather than fewer. I would also make `LogWarning` and `LogError` messages configurable and not always shown, and add a `LogCritical` level for truly critical messages that should always be shown even when debug logging is off.\n\nThat said, this PR seems fine overall: some positives, some negatives, and the code changes look ok.\n\n[^1]: Note that a message\u2019s error/warning/info status is orthogonal to its priority. A message could describe a normal condition (info), an unexpected condition (warning), or a failure condition (error), and any of these messages could have high or low priority depending how important the information is, whether the condition is temporary or permanent, what side effects it could lead to, and whether it might require manual intervention."
  },
  {
   "t": "2026-03-09T13:27:48Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2897019626,
   "text": "The `SO_NOSIGPIPE` error is marked as \"continuing anyway\", rather than immediately failing the connection, which seems fairly straightforwardly less severe."
  },
  {
   "t": "2026-03-11T13:21:21Z",
   "kind": "review_comment",
   "who": "sedited",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "In commit 436bc942d362aefbf7315c73f74d032dcb75f435\n\nI'm a bit confused when you are choosing Debug and when WarnThenDebug in this commit. What is the difference between these cases?"
  },
  {
   "t": "2026-03-11T21:21:38Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2918334248,
   "text": "`Proxy::Connect` failing means you can't connect to the proxy you've configured, which seems likely to be a fairly serious problem for your node, and that error is likely the thing you need to see; `ConnectDirectly` failing might also be a severe problem, but it might also just be that you're trying to connect over ipv6 because your node says \"why not?\" but your OS says \"no way\", which is not really problematic at all. Note that `CreateSock` is `CreateSockOS` which mostly has `LogWarnThenDebug` before it returns nullptr as well.\n\nNot particularly wedded to any particular choices here, these were just my best guesses."
  },
  {
   "t": "2026-03-13T10:13:40Z",
   "kind": "review_comment",
   "who": "sedited",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2918334248,
   "text": "Thanks for elaborating. Makes sense to me."
  },
  {
   "t": "2026-04-22T12:16:49Z",
   "kind": "force_push",
   "who": "ajtowns",
   "commit": "ac131ef122f057b4905f5aa1b7b237a6a2e3e707"
  },
  {
   "t": "2026-04-23T15:24:00Z",
   "kind": "force_push",
   "who": "ajtowns",
   "commit": "5359a99eb9b5bd442daee6c35d133ee5ea9f6583"
  },
  {
   "t": "2026-05-10T11:26:41Z",
   "kind": "review",
   "who": "sedited",
   "assoc": "MEMBER",
   "state": "APPROVED",
   "commit": "5359a99eb9b5bd442daee6c35d133ee5ea9f6583",
   "text": "ACK 5359a99eb9b5bd442daee6c35d133ee5ea9f6583"
  },
  {
   "t": "2026-05-12T11:12:40Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nGiven that the original authors thought these should be errors, we could add short commit message explanations to clarify why these (expected?) conditions are no longer treated as serious errors. Obviously, no need to overdo it, but maybe add a short summary of your GitHub comments about the categories and constraints you've considered."
  },
  {
   "t": "2026-05-12T11:14:35Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2896931967,
   "text": "Not sure about this. Wouldn't that just blur the line between what's an error, what's a warning, and what's info and debug? Wouldn't `LogWarnThenDebug` suffice for that case?"
  },
  {
   "t": "2026-05-12T11:22:10Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "doc/developer-notes.md",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nNit: the `Log` prefix is kinda redundant, but it *is* consistent with the existing functions, so in this PR it makes sense to keep it (maybe in a follow-up we could remove it)."
  },
  {
   "t": "2026-05-12T11:46:25Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nSince we're already modifying it, maybe we could make it consistent with other similar calls and log the error:\n```suggestion\n    if (sock.GetSockName(sa, &len) != 0) {\n        LogWarning(\"GetSockName failed: %s\", NetworkErrorString(WSAGetLastError()));\n    } else {\n        addr_bind.SetSockAddr(sa, len);\n    }\n```"
  },
  {
   "t": "2026-05-12T11:54:31Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/kernel/coinstats.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nIt seems to me that every single caller checks the result, usually returning an `Error` or throwing, so demoting this makes sense. Maybe we could extend the commit message with this info.\n\nFor consistency with other similar \"unable to read\" messages, and to continue our `__func__` removals, maybe we could adjust this to something like:\n```suggestion\n            LogDebug(BCLog::COINDB, \"ComputeUTXOStats: unable to read value for key %s\", key.ToString());\n```"
  },
  {
   "t": "2026-05-12T12:01:39Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/kernel/coinstats.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nCommit message nit: `ComputeUTXOStates` -> `ComputeUTXOStats`"
  },
  {
   "t": "2026-05-12T12:08:51Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nCould we test the behavior of this newly added logger with a simple unit test, something like:\n```C++\nnamespace {\nvoid LogWarnThenDebugFromSameLocation(std::string_view message)\n{\n    LogWarnThenDebug(BCLog::NET, \"warn_then_debug: %s\", message);\n}\n} // namespace\nBOOST_FIXTURE_TEST_CASE(logging_LogWarnThenDebug, LogSetup)\n{\n    LogWarnThenDebugFromSameLocation(\"first\");\n    LogWarnThenDebugFromSameLocation(\"suppressed\");\n\n    LogInstance().EnableCategory(BCLog::NET);\n    LogWarnThenDebugFromSameLocation(\"debug\");\n\n    std::vector log_lines{ReadDebugLogLines()};\n    std::vector<std::string> expected = {\n        \"[warning] warn_then_debug: first\",\n        \"[net] warn_then_debug: debug\",\n    };\n    BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), expected.begin(), expected.end());\n}\n```"
  },
  {
   "t": "2026-05-12T12:19:56Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "e054403acc07b3b2f24e0e8f7fc89456e2f51b23",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nnit: The current `_warned` flag names the second state, so the first branch has to be expressed as a negation.\nCould this instead track whether the call site should still warn? That keeps the first-warning branch first and makes the condition read directly:\n```suggestion\n    do { \\\n        static std::atomic_bool _should_warn{true}; \\\n        if (_should_warn.exchange(false)) { \\\n            LogWarning(__VA_ARGS__); \\\n        } else { \\\n            LogDebug(category, __VA_ARGS__); \\\n        } \\\n    } while (0)\n```\n\nnit1: The formatting seems a bit off compared to `detail_LogIfCategoryAndLevelEnabled`, by one space per indentation level.\nnit2: We could use `static std::atomic_bool _warned{false}` here instead and add `#include <atomic>`.\nnit3: `while` is not a function, so I added a space after it."
  },
  {
   "t": "2026-05-12T12:23:56Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/bitcoin-tx.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2897063742,
   "text": "yeah, maybe something like:\n```suggestion\n                    throw std::runtime_error(strprintf(\"invalid redeemScript: exceeds maximum size of %d bytes\", MAX_SCRIPT_ELEMENT_SIZE));\n```"
  },
  {
   "t": "2026-05-12T12:27:55Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/index/txindex.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nWe've added the index names, maybe we could add a bit more info:\n```suggestion\n        LogWarning(\"%s: failed to open block file for tx %s at %s\",\n                   GetName(), tx_hash.ToString(), postx.ToString());\n```\nand the later ones:\n```C++\n        LogWarning(\"%s: failed to read tx %s at %s offset %s: %s\",\n                   GetName(), tx_hash.ToString(), postx.ToString(), postx.nTxOffset, e.what());\n```\nand\n```C++\n        LogWarning(\"%s: txid mismatch for tx %s at %s offset %s (read %s)\",\n                   GetName(), tx_hash.ToString(), postx.ToString(), postx.nTxOffset, tx->GetHash().ToString());\n```"
  },
  {
   "t": "2026-05-12T12:32:15Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nSlightly unrelated, but some connection-management diagnostics outside `netbase` may still be repeated in logs for ordinary retries, e.g. https://github.com/bitcoin/bitcoin/blob/10ca73c02cbff59f2134c0c7da3b8d0a7e727475/src/net.cpp#L394\nMaybe we could also change this one to something like:\n```C++\nLogDebug(BCLog::NET, \"Failed to open new connection to %s, already connected\", addrConnect.ToStringAddrPort());\n```"
  },
  {
   "t": "2026-05-12T12:40:19Z",
   "kind": "review",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "state": "APPROVED",
   "commit": "5359a99eb9b5bd442daee6c35d133ee5ea9f6583",
   "text": "The changes make sense to me, Concept ACK.\nI would also be fine merging as-is, but please consider the few remaining comments."
  },
  {
   "t": "2026-05-12T13:38:55Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 3225891191,
   "text": "The original authors tagged them with \"ERROR:\" via the `error()` helper, which was accurate -- they're not things that are expected to happen in normal usage, and `error()` just added some log text and an early exit. That was changed to invoke `LogError` in #29236 which was not correct per the definition of that function in the docs, and this PR just corrects that."
  },
  {
   "t": "2026-05-18T17:21:31Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2896931967,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/34729#discussion_r3225902706\n\n[quoted text omitted]\nI just think we should make it easy to distinguish failure messages from status messages. So I'd agree `LogWarnThenDebug` would be an improvement because it would provide a clearer indication that something is wrong.\n\nBut I think you should be allowed to use the word \"Error\" even if you are not literally calling the `LogError` macro. I've said elsewhere the `LogError` macro is poorly named for what it's it's currently intended to be used for (severe errors causing the node to not function), and think a name like `LogCritical` would be better."
  },
  {
   "t": "2026-05-18T17:30:34Z",
   "kind": "review",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "5359a99eb9b5bd442daee6c35d133ee5ea9f6583",
   "text": "Code review ACK 5359a99eb9b5bd442daee6c35d133ee5ea9f6583. Concept -0 as explained in [previous review](https://github.com/bitcoin/bitcoin/pull/34729#pullrequestreview-3904982911) (because this makes it harder to tell when errors are happening). No changes since previous review other than rebase."
  },
  {
   "t": "2026-05-20T23:09:12Z",
   "kind": "comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "text": "@ajtowns do you want to address the remaining comments here?"
  },
  {
   "t": "2026-05-28T07:42:33Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "e054403acc07b3b2f24e0e8f7fc89456e2f51b23",
   "in_reply_to": 3226304121,
   "text": "I think it's clearer as is -- the condition is that if we haven't already warned, we warn, and if we have we do a debug log. The warn goes in the first branch because it's the first thing we do, and the condition is negated, because of the \"not\" in \"haven't already warned\"."
  },
  {
   "t": "2026-05-28T07:51:38Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 3226233911,
   "text": "Taken."
  },
  {
   "t": "2026-05-28T07:58:12Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2896931967,
   "text": "We already had #29236 being overzealous in equating \"error\" with `LogError`, so I don't think it would be smart to set things up for that to happen again. Combining and renaming LogError/LogWarning to LogAlert/LogCritical/LogKablooie/whatever (eg #34730) might make the distinction clearer and reduce the risk of confusion though."
  },
  {
   "t": "2026-05-28T08:08:50Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/bitcoin-tx.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 2897063742,
   "text": "As far as I can see, you'll only get an this error in bitcoin-tx if you deliberately feed it an overly large redeemscript via the `set` register command, so if you get ~14 lines of error message because you deliberately fed it ~14 lines of redeemscript, that doesn't seem very problematic.\n\nbitcoin-tx doesn't show log lines (it doesn't call `StartLogging`)."
  },
  {
   "t": "2026-05-28T08:44:42Z",
   "kind": "force_push",
   "who": "ajtowns",
   "commit": "7bf185f483836db91c1fcccbbd01957ac397ead2"
  },
  {
   "t": "2026-05-28T08:50:26Z",
   "kind": "force_push",
   "who": "ajtowns",
   "commit": "8d60c1428507921d9dd70c9840c41e447649268f"
  },
  {
   "t": "2026-05-28T08:51:39Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "Rebased, addressed some feedback (LogWarnThenDebug test particularly). I think non-trivial improvements to the wording/information provided in these (and related) log messages are better left for a separate PR."
  },
  {
   "t": "2026-06-24T20:05:05Z",
   "kind": "review",
   "who": "sedited",
   "assoc": "MEMBER",
   "state": "APPROVED",
   "commit": "8d60c1428507921d9dd70c9840c41e447649268f",
   "text": "Re-ACK 8d60c1428507921d9dd70c9840c41e447649268f"
  },
  {
   "t": "2026-06-24T22:09:15Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "e054403acc07b3b2f24e0e8f7fc89456e2f51b23",
   "in_reply_to": 3226304121,
   "text": "[quoted text omitted]\n\nYes, my point was avoiding double negation:\n```patch\n-if (!_warned.exchange(true)) { \\\n+if (_should_warn.exchange(false)) {\n```"
  },
  {
   "t": "2026-06-26T18:42:23Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/script/signingprovider.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "nit: `redeemScripts` -> `redeemScript`\nnit2: would probably be interesting to show the invalid size\n\n```suggestion\n        LogInfo(\"FillableSigningProvider::AddCScript(): redeemScript exceeds size limit: %d > %d\", redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE); // TODO: remove, ...\n```"
  },
  {
   "t": "2026-06-26T18:57:11Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/wallet/test/wallet_tests.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nHmmm, something's off here.\nFirst, change doesn't seem like \"log noise reduction\" - but that could be fine if it's setting up a follow up -, but the test is actually passing with:\n```C++\nbool FillableSigningProvider::AddCScript(const CScript& redeemScript) { return false; }\n```\ni.e. without the call:\n```patch\ndiff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp\n--- a/src/wallet/test/wallet_tests.cpp\t(revision a0a29a62d47a6211c41ac6ad4dbabe8cf91ba9f3)\n+++ b/src/wallet/test/wallet_tests.cpp\t(revision 8515753627e2db958cd3a455248ad6d09e1571c2)\n@@ -516,9 +516,8 @@\n     uint160 script_id(Hash160(inner_script));\n     CScript script_pubkey = CScript() << OP_HASH160 << std::vector<unsigned char>(script_id.begin(), script_id.end()) << OP_EQUAL;\n\n-    // Add inner-script to key store and key to watchonly\n+    // Add key to key store; related scripts are learned implicitly.\n     FillableSigningProvider keystore;\n-    BOOST_CHECK(keystore.AddCScript(inner_script));\n     keystore.AddKeyPubKey(key, pubkey);\n\n     // Fill in dummy signatures for fee calculation.\n```\n\nThe reason is that `keystore.AddKeyPubKey` calls `ImplicitlyLearnRelatedKeyScripts` which just overrides (or populates if the above patch is taken) `mapScripts` with the script.\nIt seems to me removing the line is a simpler fix that addin a check.\n(cc: @instagibbs)"
  },
  {
   "t": "2026-06-26T19:00:26Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nSeems to me `#include <atomic>` is missing here"
  },
  {
   "t": "2026-06-26T19:46:50Z",
   "kind": "review",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "state": "APPROVED",
   "commit": "8d60c1428507921d9dd70c9840c41e447649268f",
   "text": "lightly tested ACK 8d60c1428507921d9dd70c9840c41e447649268f\n\nNot all of the comments have been replied to, but I assumed the change is ready for re-review anyway.\nI have slightly different takes on a few decisions here, but no strong opinion either way. I focused mostly on correctness, style, utility, and consistency - the world is a slightly better place after this change.\nI'm personally fine with merging as-is, but would be interested in @ryanofsky's opinion here, given how many PRs are in conflict with this one."
  },
  {
   "t": "2026-07-15T01:01:29Z",
   "kind": "review",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "state": "APPROVED",
   "commit": "8d60c1428507921d9dd70c9840c41e447649268f",
   "text": "Code review ACK 8d60c1428507921d9dd70c9840c41e447649268f. Approach -0 because this drops `[error]` and `[warning]` tags so now the log messages are harder to interpret. IMO, a better approach would keep `[error]` and `[warning]` levels but make them conditional, using a `[critical]` level for actually critical messages.\n\nSince previous review, only changes are rebasing and adding test. I think the PR may be RFM if review comments are replied to and there aren't other objections."
  },
  {
   "t": "2026-08-15T19:38:10Z",
   "kind": "force_push",
   "who": "ajtowns",
   "commit": "d21e76d3d095cde6808fbffff35e584ba04b7cf0"
  },
  {
   "t": "2026-08-15T19:48:51Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/wallet/test/wallet_tests.cpp",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233",
   "in_reply_to": 3483506582,
   "text": "The change is just to ensure that the return value isn't discarded (due to the `nodiscard` addition), and because the inner_script is known and doesn't exceed the limit, we can rely on the return value being true and use `BOOST_CHECK` rather than `(void)`.\n\nThe primary change here is reducing `LogError` for something that isn't going to abort a node or subsystem to `LogInfo`, but even that is overkill, so the `[[nodiscard]]` and comment set things up so the log message could be removed entirely in the future."
  },
  {
   "t": "2026-08-15T20:29:46Z",
   "kind": "force_push",
   "who": "ajtowns",
   "commit": "03a1e6949c180209e2a5327d3b0883fb701f4d11"
  },
  {
   "t": "2026-08-15T21:11:23Z",
   "kind": "force_push",
   "who": "ajtowns",
   "commit": "91f8b365e7e7887e59240651c2c76b1a64071233"
  }
 ],
 "labels_log": [
  {
   "t": "2026-04-20T11:58:29Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-22T18:09:36Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-23T06:08:38Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-23T07:55:53Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-23T12:40:40Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-23T16:14:11Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-23T17:07:57Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-23T21:08:17Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-05-22T10:45:33Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-05-28T08:51:03Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-05-28T10:56:56Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-05-29T16:03:18Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-15T15:41:17Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-15T19:56:28Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-15T20:30:12Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-15T22:39:14Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  }
 ],
 "state_log": [],
 "text_chars": 17996,
 "text_tokens_estimate": 4499,
 "changed_paths": [
  "doc/developer-notes.md",
  "src/bitcoin-tx.cpp",
  "src/common/pcp.cpp",
  "src/index/txindex.cpp",
  "src/kernel/coinstats.cpp",
  "src/netbase.cpp",
  "src/script/signingprovider.cpp",
  "src/script/signingprovider.h",
  "src/test/logging_tests.cpp",
  "src/util/log.h",
  "src/validation.cpp",
  "src/wallet/scriptpubkeyman.h",
  "src/wallet/test/wallet_tests.cpp"
 ],
 "files": [
  {
   "path": "doc/developer-notes.md",
   "add": 5,
   "del": 0
  },
  {
   "path": "src/bitcoin-tx.cpp",
   "add": 3,
   "del": 1
  },
  {
   "path": "src/common/pcp.cpp",
   "add": 4,
   "del": 15
  },
  {
   "path": "src/index/txindex.cpp",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/kernel/coinstats.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/netbase.cpp",
   "add": 28,
   "del": 28
  },
  {
   "path": "src/script/signingprovider.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/script/signingprovider.h",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/logging_tests.cpp",
   "add": 23,
   "del": 0
  },
  {
   "path": "src/util/log.h",
   "add": 12,
   "del": 0
  },
  {
   "path": "src/validation.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/wallet/scriptpubkeyman.h",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/wallet_tests.cpp",
   "add": 1,
   "del": 1
  }
 ],
 "test_lines": 25,
 "git": {
  "head": "91f8b365e7e7887e59240651c2c76b1a64071233",
  "head_matches_backup": true,
  "base": "c90c23d388f66b7eef67f4c6f69184c088727d6a",
  "commits": [
   {
    "sha": "ec627b3f3b",
    "subject": "util/log: Add LogWarnThenDebug() helper",
    "files": 4,
    "add": 44,
    "del": 15
   },
   {
    "sha": "4f42b76ca7",
    "subject": "netbase: Reduce levels of socks5 error logging",
    "files": 1,
    "add": 18,
    "del": 18
   },
   {
    "sha": "7902a8ee83",
    "subject": "netbase: Tidy up logging levels",
    "files": 1,
    "add": 10,
    "del": 10
   },
   {
    "sha": "3c4336631e",
    "subject": "script: Lower level of oversized redeemScript log, push errors to callers",
    "files": 5,
    "add": 7,
    "del": 5
   },
   {
    "sha": "93b9613b76",
    "subject": "kernel/coinstats: Downgrade ComputeUTXOStats log level",
    "files": 1,
    "add": 1,
    "del": 1
   },
   {
    "sha": "788242d6d0",
    "subject": "txindex: Downgrade log messages and include index name",
    "files": 1,
    "add": 3,
    "del": 3
   },
   {
    "sha": "91f8b365e7",
    "subject": "validation: Upgrade log levels for possible block corruption warnings",
    "files": 1,
    "add": 2,
    "del": 2
   }
  ],
  "patch_truncated": false
 },
 "input_hash": "bed054cfc4b5db5d",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}