{
 "number": 35713,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/35713",
 "title": "Remove boost as a unit test runner",
 "author": "rustaceanrob",
 "author_association": "MEMBER",
 "created_at": "2026-07-13T14:23:22Z",
 "updated_at": "2026-09-16T21:19:39Z",
 "age_days": 66,
 "draft": false,
 "labels": [],
 "milestone": null,
 "base": "master",
 "head_sha": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7",
 "head_ref": "remove-boost-test",
 "head_repo": "rustaceanrob/bitcoin",
 "head_history": [
  {
   "t": "2026-07-14T11:49:45Z",
   "sha": "00f8712a95e8dca5cec4ded90b407bb00c0151b3"
  },
  {
   "t": "2026-07-14T11:53:18Z",
   "sha": "16926e7daed10ad09dc36332e4f7f4feab5e6b8f"
  },
  {
   "t": "2026-07-15T11:16:52Z",
   "sha": "f812859086c8ea24434d403139df550b5a4c8bc3"
  },
  {
   "t": "2026-07-15T12:03:01Z",
   "sha": "19e79835f9d7259661b0e98e71162cddd09aabc2"
  },
  {
   "t": "2026-07-20T10:09:23Z",
   "sha": "bedcd2ed6fe6218324f8f872a281409b98769968"
  },
  {
   "t": "2026-07-20T10:53:22Z",
   "sha": "261ac7eeffca40bca34ff8cc8fbef950e313134f"
  },
  {
   "t": "2026-07-20T15:06:39Z",
   "sha": "697eff8a7c97ed2f07abd11279e8e2e24ce84575"
  },
  {
   "t": "2026-07-22T12:42:05Z",
   "sha": "5723fc8db37c18c120ac4e70cae3b41eccb2b984"
  },
  {
   "t": "2026-07-22T14:23:32Z",
   "sha": "3eed6264ade0345d641230ddcc42d367331f3da0"
  },
  {
   "t": "2026-07-24T17:24:38Z",
   "sha": "4f23505c60eb1fbf8939cd97cafc19e229486c26"
  },
  {
   "t": "2026-07-26T10:54:24Z",
   "sha": "08fcf67faae4b57c07372edc83bbbc2361b00df1"
  },
  {
   "t": "2026-07-26T14:20:55Z",
   "sha": "d6b35d5d203836def74150c8cd87e40e994af867"
  },
  {
   "t": "2026-07-28T08:53:31Z",
   "sha": "5a02f5fb594dc91a7e60aa719161607b2167445a"
  },
  {
   "t": "2026-07-29T09:29:34Z",
   "sha": "0049e447210cc40a39928a0ca4bd2d23ad0f641e"
  },
  {
   "t": "2026-07-30T09:35:14Z",
   "sha": "9e409ccd073301e43be2d112b7b6abb778e4890c"
  },
  {
   "t": "2026-08-01T13:16:38Z",
   "sha": "fff8bc3a7a240069d65c2c3ac5a9a26c98dd889d"
  },
  {
   "t": "2026-08-04T13:49:13Z",
   "sha": "6b6a6cf40957649109664d7814f118ee019e3366"
  },
  {
   "t": "2026-08-11T17:30:29Z",
   "sha": "62103dacc518b7118699caab52ea6f5b2afa7cb3"
  },
  {
   "t": "2026-08-12T13:06:11Z",
   "sha": "54e14787e30306c7ab1633de9732f876dfe5b794"
  },
  {
   "t": "2026-08-12T13:38:29Z",
   "sha": "e50e95e3b0005db4e7537fb98f350fa3cbab2046"
  },
  {
   "t": "2026-08-20T14:03:41Z",
   "sha": "56cd20f712eed53d5cd347c99e8e9f37c9023b02"
  },
  {
   "t": "2026-08-23T15:51:47Z",
   "sha": "8cc86b5332648154d84745d1b27c6d6da1d92a8f"
  },
  {
   "t": "2026-08-24T15:25:26Z",
   "sha": "8be2320bfe7930038915785f9b9ebf106d63e068"
  },
  {
   "t": "2026-09-03T14:10:54Z",
   "sha": "c7677eae8592ec9f9db39615d66fb117038e75f5"
  },
  {
   "t": "2026-09-10T11:30:19Z",
   "sha": "9ead8ded9839c99a0c58ba89cbbe7e75ca858695"
  },
  {
   "t": "2026-09-10T11:44:37Z",
   "sha": "81077740a9fef4af671fb3981d259e350c8fa6fc"
  },
  {
   "t": "2026-09-14T10:51:15Z",
   "sha": "b33574d00b87c74ca8b1dd8054902b3f4e46a1c0"
  },
  {
   "t": "2026-09-16T18:02:20Z",
   "sha": "15b17fe9730e073458222d30d7c9b41b4163a6e3"
  },
  {
   "t": "2026-09-16T18:24:12Z",
   "sha": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7"
  }
 ],
 "additions": 1696,
 "deletions": 264,
 "changed_files": 163,
 "commit_count": 12,
 "size_bucket": "XL",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_ack": [
     {
      "login": "josibake",
      "url": "https://github.com/bitcoin/bitcoin/pull/35713#issuecomment-4959035820"
     },
     {
      "login": "jeanpablojp",
      "url": "https://github.com/bitcoin/bitcoin/pull/35713#pullrequestreview-5061768134"
     }
    ]
   },
   "conflicts": [
    {
     "number": 36182,
     "title": "fees: return `block_policy` fee rate estimate when `mempool_policy` is not ready",
     "author": "ismaelsadeeq"
    },
    {
     "number": 36159,
     "title": "http: Improve HTTPRemoteClient::MaybeDisconnect()",
     "author": "hodlinator"
    },
    {
     "number": 36091,
     "title": "test: Add debug output to common tested types",
     "author": "rustaceanrob"
    },
    {
     "number": 36013,
     "title": "test: Descriptor roundtrip and raw()/ addr() coverage",
     "author": "pablomartin4btc"
    },
    {
     "number": 35855,
     "title": "guix: update time-machine",
     "author": "fanquake"
    },
    {
     "number": 35744,
     "title": "coins: prevent DB resize from invalidating cursors",
     "author": "l0rinc"
    },
    {
     "number": 35662,
     "title": "script: prevent stale sighash caches across transactions",
     "author": "l0rinc"
    },
    {
     "number": 35581,
     "title": "node: add block template manager and track waitNext fee inflow",
     "author": "ismaelsadeeq"
    },
    {
     "number": 35569,
     "title": "Encapsulation for CTransaction",
     "author": "purpleKarrot"
    },
    {
     "number": 35511,
     "title": "RFC: consensus: Make `CAmount` a class",
     "author": "hodlinator"
    },
    {
     "number": 35139,
     "title": "test: Add thread-safe fast-failing test macros",
     "author": "maflcko"
    },
    {
     "number": 35003,
     "title": "validation: improve block data I/O error handling in P2P paths",
     "author": "furszy"
    },
    {
     "number": 29700,
     "title": "kernel, refactor: return error status on all fatal errors",
     "author": "ryanofsky"
    },
    {
     "number": 29278,
     "title": "Wallet:  Add `maxfeerate` wallet startup option",
     "author": "ismaelsadeeq"
    },
    {
     "number": 26022,
     "title": "Add util::ResultPtr class",
     "author": "ryanofsky"
    },
    {
     "number": 25665,
     "title": "refactor: Add util::Result failure types and ability to merge result values",
     "author": "ryanofsky"
    }
   ]
  }
 },
 "acks_parsed": {
  "jeanpablojp": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-08-30T20:02:10Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 1,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "fanquake",
   "jeanpablojp",
   "josibake",
   "maflcko"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-09-16T18:24:12Z",
  "last_reviewer_activity": "2026-08-30T20:02:10Z",
  "last_reviewer": "jeanpablojp",
  "author_silent_days": 0,
  "waiting_on_author_days": 0,
  "days_since_update": 0
 },
 "refs": {
  "mentioned": [
   8670,
   24301,
   34666,
   35587,
   35729,
   36045,
   36091
  ],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 35587,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "Remove boost as a unit test runner"
   },
   {
    "number": 34666,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "[rfc] Replacing Boost Unit Test Framework?"
   },
   {
    "number": 8670,
    "type": "issue",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "Replacing Boost Test Framework"
   },
   {
    "number": 36045,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-08-21",
    "title": "test: avoid undersized Boost.Test signal stacks"
   },
   {
    "number": 24301,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2022-02-14",
    "title": "build: header-only Boost"
   },
   {
    "number": 35729,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-08-11",
    "title": "refactor: test: Unroll `&&` conditions in macros"
   },
   {
    "number": 36091,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "test: Add debug output to common tested types"
   }
  ],
  "conflicts": [
   36182,
   36159,
   36091,
   36013,
   35855,
   35744,
   35662,
   35581,
   35569,
   35511,
   35139,
   35003,
   29700,
   29278,
   26022,
   25665
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "contrib/guix/libexec/build_linux.sh",
  "src/test/dbwrapper_tests.cpp",
  "src/test/util/framework.h",
  "src/test/validation_chainstatemanager_tests.cpp",
  "src/wallet/test/wallet_transaction_tests.cpp"
 ],
 "body": "Continued from #35587. tl;dr: Make an equivalent test runner to boost with simpler macros and tighter coupling to bitcoin-specific code.\n### Motivation\nThere are a number of problems with using dependencies in general. Bugs must either be promptly upstreamed or patched, projects may be abandoned, and they are not tailored to a particular use case. This PR removes boost for writing and running unit tests. In the case of Boost.Test, there are a number of issues which are listed below.\n\n### My problems with Boost.Test\n\n#### Macros\nWhen using boost, there are 3 ways of writing the same thing, each with different outcomes\n- `BOOST_CHECK(expr1 == expr2)`: failures show the expression, but no values for `expr1` and `expr2`\n- `BOOST_CHECK_EQUAL(expr1, expr2)`: failures show the expression and values, but requires developers remember `CHECK_EQUAL` and does not use usual operands\n- `BOOST_TEST(expr1 == expr2)`: failures show the expression and values, and developers may use familiar operands (`==`, `!=`)\n\nAll three are preserved to maintain backwards compatibility - presumably, but this results in all 3 being used throughout the repository. As a bonus there is a 4th way, with added context\n- `BOOST_CHECK_MESSAGE(expr1 == expr2, \"the context\")`:  failures show the expression and message, but no values for `expr1` and `expr2`\n\nTo make debugging and review easier, all of these should be unified to a single macro. Test sites use operands, print helpful messages - values are always included, and do not vary in approach (deciding between `BOOST_TEST`, `CHECK`, and `BOOST_CHECK_EQUAL` is unintuitive)\n\nExample boost outputs\n\n```cpp\nBOOST_AUTO_TEST_CASE(mustfail)\n{\n    auto a{1};\n    auto b{2};\n    BOOST_CHECK(a == b);\n    BOOST_CHECK_EQUAL(a, b);\n    BOOST_TEST(a == b);\n    COutPoint outpoint_1{Txid{\"0000000000000000000000000000000000000000000000000000000000000100\"}, 0};\n    COutPoint outpoint_2{Txid{\"0000000000000000000000000000000000000000000000000000000000000100\"}, 1};\n    BOOST_CHECK(outpoint_1 == outpoint_2);\n    // Doesn't even compile\n    // BOOST_TEST(outpoint_1 == outpoint_2);\n    // BOOST_CHECK_EQUAL(outpoint_1, outpoint_2);\n}\n```\n\n```\nRunning 1 test case...\ntest/argsman_tests.cpp(31): error: in \"argsman_tests/mustfail\": check a == b has failed\ntest/argsman_tests.cpp(32): error: in \"argsman_tests/mustfail\": check a == b has failed [1 != 2]\ntest/argsman_tests.cpp(33): error: in \"argsman_tests/mustfail\": check a == b has failed [1 != 2]\ntest/argsman_tests.cpp(36): error: in \"argsman_tests/mustfail\": check outpoint_1 == outpoint_2 has failed\n```\n\nNew outputs\n\n```cpp\nTEST_CASE(mustfail)\n{\n    auto a{1};\n    auto b{2};\n    CHECK(a == b);\n    COutPoint outpoint_1{Txid{\"0000000000000000000000000000000000000000000000000000000000000100\"}, 0};\n    COutPoint outpoint_2{Txid{\"0000000000000000000000000000000000000000000000000000000000000100\"}, 1};\n    CHECK(outpoint_1 == outpoint_2);\n}\n```\n\n```\nRunning 1 test cases...\n[FAIL]: test/argsman_tests.cpp:30: CHECK(a == b)\n1 == 2\n\n[FAIL]: test/argsman_tests.cpp:33: CHECK(outpoint_1 == outpoint_2)\nCOutPoint(0000000000, 0) == COutPoint(0000000000, 1)\n\n[FAIL] mustfail (2/2 checks failed)\n```\n\n#### In the depends system\n\nWe can simplify `depends` and a workaround in the guix build\n\n#### No repository context\n\nA custom framework allows for complete control of debug output, console output, CLI arguments, etc.\n\n#### Other issues\n\nIssues are mentioned in #34666, #8670, #36045. Using a test runner within the source also makes IWYU easier to work with.\n\n### High level changes\n\nFor those running tests, not a tremendous amount has changed in this PR. For instance, the [doc page](https://github.com/bitcoin/bitcoin/tree/master/src/test) remains valid. Changes to the runner options include anything that is not `help, run_test, log_level, list_content`. This includes `catch_system_errors` which is always no. The `log_levels` have been reduced to 5 levels.\n\nFor an explanation of all the internal details, I have written a detailed [personal blog](https://rustaceanrob.com/unit-test-cpp/)\n\n### Changes in writing tests\n\nNote that no changes `BOOST_*` macros are changed in this PR. Macro shims are added so developers may continue using the usual `BOOST_*` macros. Future changes to writing tests would include:\n- `CHECK` to compare two values with any `==`, `!=`, `>`, etc\n- `CHECK(a == b, \"my message\")` to append a message\n- `REQUIRE`, same as `CHECK`, but will fail the test immediately\n- `TEST_CASE(name)` to add a test\n- `FIXTURE_TEST_CASE(name, Fixture)` to add a test with a fixture\n- `TEST_SUITE_BEGIN/END` to declare a suite, optionally with fixture for each test in the suite\n\n### Migration\n\n`Boost.Test` is removed in this PR, but the macros are aliased by `BOOST_*` counterparts so there are no merge conflicts. The idea would be to migrate test files to the new macros when there are no/low number of conflicts on that file.\n\nCommits\n\n**The addition of the framework:**\n- test: Add header-only framework to util\n\n**Migration script (majority of the file changes):**\n- scripted-diff: Migrate tests to header-only framework\n\n**Low usage count macro removals:**\n- test: Remove low usage `BOOST` macros\n\n**Required for expression decomposition:**\n- test: Wrap `||` expressions in macros\n- test: Wrap bitwise `&` expressions in macros\n\n**To pass CI**\n- test: Inline CRecipient to avoid gcc12 uninitialized warning\n\n**Build and config**\n- depends: drop test from Boost libraries\n- cmake: drop vcpkg Boost Test check\n- vcpkg: drop boost-test dependency\n- guix: Drop Boost.Test unused workaround",
 "commits": [
  {
   "sha": "aa3b60c048b58dfc59ecc0478a6b8a5f1473e0ef",
   "date": "2026-09-16T18:11:59Z",
   "message": "test: Add display `operator<<` overloads to `common.{h,cpp}`\n\nIf the `<<` operator exists, boost can use this as a debug output when a\ncheck fails (besides `BOOST_CHECK`). This adds `<<` for types commonly\nused across the unit tests that do not yet have a display output."
  },
  {
   "sha": "f3758b351f6c575fe71563ed75be4da79bf0bcf2",
   "date": "2026-09-16T18:12:02Z",
   "message": "test: Remove low usage `BOOST` macros\n\n`BOOST_FAIL`: This check may be simplified by using the timeout as the\ncondition for a `BOOST_REQUIRE`\n\n`BOOST_TEST_INFO`: In the case of `descriptor_tests.cpp`, the info is only used to get the\ndiagonsics of `BOOST_CHECK_EQUAL` along with the human readable form of\nthe descriptor. This is irrelevant if the test framework implements\nexpression decomposition, which will print the string representation on\nfailure (e.g. `BOOST_TEST`)."
  },
  {
   "sha": "04a8028ce764b992d334297cc3e8937099134eaf",
   "date": "2026-09-16T18:12:03Z",
   "message": "test: Inline `CRecipient` construction to avoid gcc12 uninitialized warning\n\ngcc12 warns with uninitialized when boost is not used for this test.\nUnfortunately, I think this is a false positive, as `CRecipient` seems\nobivously initialized?\n\nref: https://github.com/boostorg/variant2/issues/55\n\nerror:\n```\n[quoted text omitted]\n\n367 | _M_impl._M_end_of_storage - _M_impl._M_start);\n\n| ~~~~~~~~^~~~~~~~~~~~~~~~~\n\n/home/runner/work/_temp/src/wallet/test/spend_tests.cpp: In lambda function:\n\n/home/runner/work/_temp/src/wallet/test/spend_tests.cpp:47:20: note: \u2018recipient\u2019 declared here\n\n47 | CRecipient recipient{PubKeyDestination({}), 50 * COIN - leftover_input_amount, /*subtract_fee=*/true};\n\n| ^~~~~~~~~\n\ncc1plus: all warnings being treated as errors\n\ngmake[2]: *** [src/test/CMakeFiles/test_bitcoin.dir/build.make:2142: src/test/CMakeFiles/test_bitcoin.dir/__/wallet/test/spend_tests.cpp.o] Error 1\n\ngmake[1]: *** [CMakeFiles/Makefile2:2621: src/test/CMakeFiles/test_bitcoin.dir/all] Error 2\n\ngmake: *** [Makefile:146: all] Error 2\n\nCommand '['docker', 'exec', '--env', 'DANGER_RUN_CI_ON_HOST=1', 'e5149787b8a1739029b127ba5d3b9cf034d955ca907ea03ab0cfe5de2af9e8d9', '/home/runner/work/_temp/ci/test/03_test_script.sh']' returned non-zero exit status 2.\n```"
  },
  {
   "sha": "5b8c34777ec1aaae48243938bc3b6e6487f930d9",
   "date": "2026-09-16T18:12:04Z",
   "message": "test: Wrap bitwise `&` expressions in macros\n\nLogical operators are not usable with test frameworks that decompose\nexpressions, as introduced in a later commit.\n\nref: https://catch2-temp.readthedocs.io/en/latest/assertions.html#other-limitations\nref: https://fekir.info/post/decomposing-an-expression/"
  },
  {
   "sha": "e3cd8423ff2483898f95ec446a7057a083abb00b",
   "date": "2026-09-16T18:12:05Z",
   "message": "test: Wrap `||`, `&&` expressions in macros\n\nThe `||` and `&&` re not usable with `BOOST_TEST` and other modern test\nframeworks like Catch2. This is due to operator precedence used in such\nmacros. Here is an additional opinion from Catch2:\n\n[quoted text omitted]\nthat if you have || in your test expression, you should rethink your tests.\n\nref: https://catch2-temp.readthedocs.io/en/latest/assertions.html#other-limitations\nref: https://fekir.info/post/decomposing-an-expression/"
  },
  {
   "sha": "5b7017760beae1762fd7a06bddc0a9a235c0b959",
   "date": "2026-09-16T18:12:06Z",
   "message": "test: Add header-only framework to util\n\nThis commit introduces a new test runner as well as the associated\nmacros. The runner takes inspiration from boost, catch2, and doctest.\nNotably, expressions are \"decomposed\" by taking each value and recording\na debug string in the case of an invalid expression. It does so by\noverriding an operator (<=) before other comparison operations are\nevaluated. Each test initializes a `TestContext` that manages the test\nstate and scoped logs.\n\nCompatiblity with boost is maintained for environment variables and CLI\narguments that are used in CI and docs.\n\nODR violation lint suppression: https://clang.llvm.org/extra/clang-tidy/checks/misc/definitions-in-headers.html\nref: https://fekir.info/post/decomposing-an-expression/"
  },
  {
   "sha": "c541190f42178d4959461f2d5c47178338a6e0ef",
   "date": "2026-09-16T18:18:34Z",
   "message": "scripted-diff: Migrate tests to header-only framework\n\nThis migrates the test runner, boost header imports, and linter.\n`include <memory>` line is to fix an IWYU.\n\n-BEGIN VERIFY SCRIPT-\nmv src/test/new_main.cpp src/test/main.cpp\ngit grep -l '<boost/test/unit_test.hpp>' | xargs sed -i 's|<boost/test/unit_test.hpp>|<test/util/framework.h>|'\nsed -i 's|BOOST_TEST_MODULE Bitcoin Kernel Test Suite|BITCOIN_TEST_MAIN|; s|<boost/test/included/unit_test.hpp>|<test/util/framework.h>|' src/test/kernel/test_kernel.cpp\nsed -i 's|boost::unit_test::framework::master_test_suite().argv\\[0\\]|framework::executable_path()|' src/test/system_tests.cpp\nsed -i '/boost\\/test\\/\\(included\\/\\)\\?unit_test.hpp/d' test/lint/lint-includes.py\nsed -i 's|#include <test/util/framework.h>|&\\n\\n#include <memory>|' src/test/result_tests.cpp\n-END VERIFY SCRIPT-"
  },
  {
   "sha": "e0be64bfc55b019f39ec50ba8f1d662a2a002e9b",
   "date": "2026-09-16T18:22:31Z",
   "message": "test: Require `stringify` implementation or explicit omission\n\nIf there is no meaningful string representation for a type being\nchecked, this fails with a `static_assert`. If the test writer does not\nwant to add a string representation, there is a `CHECK_NO_DISPLAY` macro\nfor explicit opt-out."
  },
  {
   "sha": "bac9d2c6c2ac61181bfc03035193430cc75113bf",
   "date": "2026-09-16T18:22:32Z",
   "message": "depends: drop test from Boost libraries"
  },
  {
   "sha": "19bb8c8dd86e4deb407cb41844859e15091bcff2",
   "date": "2026-09-16T18:22:32Z",
   "message": "cmake: drop vcpkg Boost Test check"
  },
  {
   "sha": "da4147020bd088c2c1fe928c54e4f2f4b1fec8a8",
   "date": "2026-09-16T18:22:33Z",
   "message": "vcpkg: drop boost-test dependency"
  },
  {
   "sha": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7",
   "date": "2026-09-16T18:22:34Z",
   "message": "guix: Drop `Boost.Test` unused workaround"
  }
 ],
 "timeline": [
  {
   "t": "2026-07-13T14:28:04Z",
   "kind": "comment",
   "who": "josibake",
   "assoc": "MEMBER",
   "text": "Moving over my original ACK from the previous PR: https://github.com/bitcoin/bitcoin/pull/35587#issuecomment-4779166872\n\n---\nStrong Concept ACK!\n\nLove to see it. While I broadly agree with the author's reasons stated in the PR, the ones I'll highlight specifically are:\n\n* No repository context\n* Not extensible\n\nHaving our own simple, in house test framework gives us the ability to customise it for exactly our needs. I believe we should do everything in our power to make testing an easy, intuitive, and feature rich experience as this helps to remove barriers to people writing and interpreting tests.\n\nIn particular, as a longer term project I am looking at ways to improve concurrency in our testing to help speed up CI. As @purpleKarrot points out:\n\n[quoted text omitted]"
  },
  {
   "t": "2026-07-13T14:41:18Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": null,
   "text": "As explained in https://github.com/bitcoin/bitcoin/pull/35625#issuecomment-4845221857, I still don't think this makes sense. The only change is that some compile-time type name may be printed  for both sides.\n\nThis should remain a compile failure, like it is on current master."
  },
  {
   "t": "2026-07-14T08:39:42Z",
   "kind": "review_comment",
   "who": "fanquake",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": null,
   "text": "In 6eaefedb79598eedf00b24e4e480a7e005440e40:\n[quoted text omitted]\n\nWe don't use any Boost libraries (header-only since #24301), so not sure how the library missing instrumentation could be the cause of issues here?"
  },
  {
   "t": "2026-07-14T09:02:22Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "Maybe this is just one of the GCC false positive bugs about -w-uninit? Though, hard to tell without seeing the exact compiler/sanitizer output in the commit message.\n\nMaybe the commit messages could be expanded with the exact output?"
  },
  {
   "t": "2026-07-14T09:06:02Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "I'm running the CI on a different branch to see if this still fails. If so, I'll paste some output."
  },
  {
   "t": "2026-07-14T09:16:38Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "00f8712a95e8dca5cec4ded90b407bb00c0151b3",
   "in_reply_to": null,
   "text": "llm-nit: (Also looks like the LLM broke down):\n\nPossible typos and grammar issues:\n\n* `/** Path that the test binary */ -> /** Path to the test binary */` [the original comment is grammatically incomplete and \u0905\u0938\u094d\u092a\u0937\u094d\u091f]"
  },
  {
   "t": "2026-07-14T09:38:15Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "Agree this should be a static assert but I haven't gotten to this yet because `BOOST_CHECK` doesn't require a meaningful string representation. There are many types that would then require a `ToString` or similar for `stringify` to work properly. I have a couple ideas of how to do this."
  },
  {
   "t": "2026-07-14T09:38:29Z",
   "kind": "comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "text": "Draft while I work on https://github.com/bitcoin/bitcoin/pull/35713#discussion_r3571556207"
  },
  {
   "t": "2026-07-14T09:54:36Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "Why not just keep the pre-existing approach of using the helpers from `src/test/util/common.h` (`std::ostream& operator<<`)?"
  },
  {
   "t": "2026-07-14T10:20:02Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "Those don't cover most of the types. For instance, a few random ones, `ByRatio<FeeFrac>` and `Coin` do not have a `ToString` or `<<`."
  },
  {
   "t": "2026-07-14T11:14:39Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "Ok, I see. It could make sense to split this fix up into its own pull request? Otherwise, it looks like it is hidden in a single line in a ~1500line pull request.\n\nTo explain the background:\n\n* No code today (in master) exists that compares `Coin` in the test framework with pretty debug output.\n* If someone were to trigger pretty output, e.g. by using `BOOST_CHECK_EQUAL`, then the compilation would fail:\n\n```diff\ndiff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp\nindex 6ae5f2b7cb..9ba2e67e30 100644\n--- a/src/test/coins_tests.cpp\n+++ b/src/test/coins_tests.cpp\n@@ -168,3 +168,3 @@ void SimulationTest(CCoinsView* base, bool fake_best_block)\n                 AccessByTxid(*stack.back(), txid) : stack.back()->AccessCoin(COutPoint(txid, 0));\n-            BOOST_CHECK(coin == entry);\n+            BOOST_CHECK_EQUAL(coin,entry);\n\n```\n\nTo fix this, I think it would be fine to provide a `ToString` or `operator<<`, maybe in a separate pull request? However, I haven't checked how many classes are affected in total.\n\nMaybe there is a better solution available (we don't have C++26, heh), but I think whatever the solution is, should (and can) be a separate pull request. Also, seems fine to keep it here, but I think this pull request should try to preserve the behavior, or at least list all behavior changes and why they are done."
  },
  {
   "t": "2026-07-14T11:49:45Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "00f8712a95e8dca5cec4ded90b407bb00c0151b3"
  },
  {
   "t": "2026-07-14T11:49:55Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "Looks like an older state of the framwork or commit history was causing this, dropped the commit."
  },
  {
   "t": "2026-07-14T11:53:18Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "16926e7daed10ad09dc36332e4f7f4feab5e6b8f"
  },
  {
   "t": "2026-07-14T12:08:27Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "Could still make sense to expand the other commit with the exact failure reason.\n\nStuff like 9e1247067dbf51fab4a532a8ffda707361886021 looks like bugs in the bitcoin core code itself. About 17b37d2fdded4cb02203a07e27408f4001abe894 I wonder what the error was."
  },
  {
   "t": "2026-07-14T13:52:03Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "I think some have a natural fix, like if `HexStr(v)` works than it is probably a good representation. Also, if an type implements a `v.Serialize` then we can also pass that as a hex string, which should be suitable for debugging (maybe the typeid as a prefix to the hex string). Also `std::vector<Foo>` for `Foo` with a stringifyable can just print the list of `Foo`. Same goes for `std::pair` and some others.\n\nFor the rest of the cases, I was thinking it could be possible to add a macro `BOOST_NO_DISPLAY_CHECK`. All of these callsites can be fixed by adding a `ToString` or `<<` as that file is migrated to new macros."
  },
  {
   "t": "2026-07-14T13:57:30Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "Ah nice. Hex could work here.\n\nThough, for a vector I am not sure if it makes sense to dump the full list. See `check_eq_collections` in https://github.com/bitcoin/bitcoin/pull/35139/changes, which only prints the failing index. IIRC this is also what boost does."
  },
  {
   "t": "2026-07-14T14:10:29Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "For the `constexpr` commits, it is a linker error, which I will add to the commit messages:\n\n```\nundefined reference to `LockedPool::ARENA_SIZE'\nclang++: error: linker command failed with exit code 1 (use -v to see invocation)\nninja: build stopped: subcommand failed.\n```\n\nAFICT there are no downsides to `const -> constexpr`, so it feels like these commits should belong in a broader sweep, but then again I don't see much of a motivation to do so outside of this PR. Would there be any benefit?"
  },
  {
   "t": "2026-07-14T14:53:26Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "Ah, it is a linker error due to the missing `inline` via `constexpr`. Thanks for explaining.\n\nFor reference, the compile failure for the other commit would be something like:\n\n```\nerror: invalid operands to binary expression ('const AddressPosition' and 'const AddressPosition')\n  851 |                     (void)(ref==ref);\n      |                            ~~~^ ~~~\nsrc/addrman.h:76:10: note: candidate function not viable: 'this' argument has type 'const AddressPosition', but method is not marked const\n   76 |     bool operator==(AddressPosition other) {\n      |          ^\n```"
  },
  {
   "t": "2026-07-15T11:16:52Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "f812859086c8ea24434d403139df550b5a4c8bc3"
  },
  {
   "t": "2026-07-15T12:03:01Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2"
  },
  {
   "t": "2026-07-15T15:39:01Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "I think the fallback `return typeid(T).name();` still exists in the latest push and is still wrong.\n\nThe correct lowest fallback is still a compilation-failure, just like the prior behavior with boost."
  },
  {
   "t": "2026-07-15T15:56:17Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "Yeah, agree, however there are around 80 callsites that still do not have a string representation. Some of which appear to be the wrong check, like using `BOOST_CHECK` on two ranges instead of `BOOST_CHECK_EQUAL_RANGES`. Others would need a custom `ToString` or `<<`.\n\nFor the time being, in a separate commit after the scripted diff, I was going to introduce the static assert and a macro `CHECK_NO_DISPLAY` that omits the stringify for those sites. I am also open to other approaches."
  },
  {
   "t": "2026-07-16T12:22:00Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "Yeah, seems fine to have way to skip having to provide a stringifier. One hacky way would be to just use double-braces: `CHECK((a==b))`, but that may be a bit ugly and unintuitive. `CHECK_NO_DISPLAY` sounds fine.\n\nThe benefit of the static assert is that it can print the problem and solution at compile time, instead of silently running into issues without any suggestion on how to fix them. E.g. something like:\n\n```\n        static_assert(requires(std::ostream& os) { os << value; }, \"Please provide an operator<<(std::ostream&, const T&) for formatting. Otherwise, a test failure will not be able to display the differing objects. Alternatively, use CHECK_NO_DISPLAY to disable display of the objects completely.\");"
  },
  {
   "t": "2026-07-20T10:09:23Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "bedcd2ed6fe6218324f8f872a281409b98769968"
  },
  {
   "t": "2026-07-20T10:53:22Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "261ac7eeffca40bca34ff8cc8fbef950e313134f"
  },
  {
   "t": "2026-07-20T12:32:51Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "19e79835f9d7259661b0e98e71162cddd09aabc2",
   "in_reply_to": 3571556207,
   "text": "01be0daef8f8e003d4cda75cf5b226fa0eff0696 and efa00a2cded95fb39ca820a2eae4da527da6e89a updates stringify overloads and 05397f7c0881265f1b108e8e2544c889d7c8b830 moves to a `static_assert`. In doing this exercise I saw a lot of `BOOST_CHECK(r1 == r2)` that compares two ranges, where almost certainly it would be better to use `BOOST_CHECK_EQUAL_COLLECTIONS`. I think it would be a nice property to allow devs to use `CHECK(r1 == r2)`, so I added a concept that checks if a developer is trying to compare two ranges and that type does not already have a `ToString` or `<<`. This allowed me two remove the `CHECK_EQUAL_COLLECTIONS` macro entirely, which I prefer.\n\nUnfortunately, two iterators are compared quite a few times in the tests, however it is difficult to make a meaningful `stringify` for these cases. I am hoping to leave those conversions to `CHECK_NO_DISPLAY` as followup, so as to not completely bloat this PR."
  },
  {
   "t": "2026-07-20T15:06:39Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "697eff8a7c97ed2f07abd11279e8e2e24ce84575"
  },
  {
   "t": "2026-07-22T12:42:05Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "5723fc8db37c18c120ac4e70cae3b41eccb2b984"
  },
  {
   "t": "2026-07-22T12:47:04Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "683a06f0869e471239a75f672eb1f8841c424c26 circumvents the linker issue by just removing the use of `const T&` for the `static const` class member variables. I looked at the number of `static const` member variables in `src` and there were quite a few, so I would rather not convert all of these to `constexpr` at the moment."
  },
  {
   "t": "2026-07-22T13:27:55Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "I mean it looks like ODR violations that just happen to get optimized away by the compiler, but I guess there is no tool to find/fix all of them?"
  },
  {
   "t": "2026-07-22T14:23:32Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "3eed6264ade0345d641230ddcc42d367331f3da0"
  },
  {
   "t": "2026-07-22T15:47:07Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "I think https://github.com/llvm/llvm-project/pull/162741 would do it but looks a bit stalled"
  },
  {
   "t": "2026-07-22T16:06:25Z",
   "kind": "review_comment",
   "who": "fanquake",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "I think it'd be fine to open a PR that just changes all class usage of `static const` to `static constexpr`? That seems straightforward, and correct (happy to do). Somewhat related, I had been looking at debug symbols (from the 31.1 release), to check where symbols were being duplicated across TUs, rather than squashed to a single definition by the linker; `MAX_SCRIPT_ELEMENT_SIZE` is one of a few. Fixing these is basically just changing `static const` -> `inline constexpr`, which also seems worthwhile, and if anything, shrinks our release binary."
  },
  {
   "t": "2026-07-24T17:24:38Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "4f23505c60eb1fbf8939cd97cafc19e229486c26"
  },
  {
   "t": "2026-07-26T10:54:24Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "08fcf67faae4b57c07372edc83bbbc2361b00df1"
  },
  {
   "t": "2026-07-26T14:20:55Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "d6b35d5d203836def74150c8cd87e40e994af867"
  },
  {
   "t": "2026-07-28T08:53:31Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "5a02f5fb594dc91a7e60aa719161607b2167445a"
  },
  {
   "t": "2026-07-29T09:29:34Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "0049e447210cc40a39928a0ca4bd2d23ad0f641e"
  },
  {
   "t": "2026-07-30T08:09:35Z",
   "kind": "comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "text": "Could rebase and drop the unused boost workaround in guix?\n\n```sh\n+# Use LINK_WARNING_AS_ERROR when using CMake 4.x\n+case \"$HOST\" in\n+    riscv64-linux-gnu) ;; # https://github.com/boostorg/test/issues/345\n+    *) HOST_LDFLAGS=\"${HOST_LDFLAGS} -Wl,--fatal-warnings\" ;;\n+esac\n+"
  },
  {
   "t": "2026-07-30T09:35:14Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "9e409ccd073301e43be2d112b7b6abb778e4890c"
  },
  {
   "t": "2026-07-30T09:40:59Z",
   "kind": "comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "text": "Given the response to #35729, which I was surprised to see pushback on, I found a solution to preserve `&&` and `||` at the cost of the debug output. By implementing `operator bool` we can chain operations within the macros to preserve the perceived expressiveness of writing two conditions in one check. In the current state, this makes the loss of debug output implicit, but the PR becomes a lot more concise. We can revisit if we should `delete` the `&&` and `||` at a later point, or perhaps fix these as files are migrated."
  },
  {
   "t": "2026-07-30T12:37:26Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "Everything in this thread is resolved and it can be closed?"
  },
  {
   "t": "2026-07-30T12:42:33Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "[quoted text omitted]\n\nPerhaps this can be made an issue if there are other associated changes or this impact on the binary size is noticeable."
  },
  {
   "t": "2026-07-30T18:14:56Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/dbwrapper_tests.cpp",
   "commit": "421271dbcc85f99e5f770bef1628bb82a713674e",
   "in_reply_to": 3577321667,
   "text": "Did some `inline constexpr` scripted diff in https://github.com/bitcoin/bitcoin/pull/35852. Let's see what reviewers think."
  },
  {
   "t": "2026-08-01T13:16:38Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "fff8bc3a7a240069d65c2c3ac5a9a26c98dd889d"
  },
  {
   "t": "2026-08-03T10:20:31Z",
   "kind": "comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "text": "I walked back the comment above on the basis that the test framework should not hide debug behavior implicitly. `&&` and `||` are `delete` in the latest push, which also includes the changes from #35729 once more."
  },
  {
   "t": "2026-08-04T13:49:13Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "6b6a6cf40957649109664d7814f118ee019e3366"
  },
  {
   "t": "2026-08-11T17:30:29Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "62103dacc518b7118699caab52ea6f5b2afa7cb3"
  },
  {
   "t": "2026-08-12T13:06:11Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "54e14787e30306c7ab1633de9732f876dfe5b794"
  },
  {
   "t": "2026-08-12T13:38:29Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "e50e95e3b0005db4e7537fb98f350fa3cbab2046"
  },
  {
   "t": "2026-08-19T08:44:39Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/wallet/test/wallet_transaction_tests.cpp",
   "commit": "312b1ec3b1d1c3b59dd686c94460406247020ef4",
   "in_reply_to": null,
   "text": "This points at a larger problem of all the verbose, brittle and confusing manual exception checks. I'd say all of those should be removed. Done in https://github.com/bitcoin/bitcoin/pull/36018"
  },
  {
   "t": "2026-08-20T14:03:41Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "56cd20f712eed53d5cd347c99e8e9f37c9023b02"
  },
  {
   "t": "2026-08-20T14:28:48Z",
   "kind": "review_comment",
   "who": "maflcko",
   "assoc": "MEMBER",
   "path": "src/test/validation_chainstatemanager_tests.cpp",
   "commit": "6a4ae21f18cfe13cbf622691aa659a7423721f09",
   "in_reply_to": null,
   "text": "nit: Use clang-tidy named-args here for the third arg, to avoid confusion with fraction vs pct https://stackoverflow.com/questions/1093453/difference-between-boost-check-close-and-boost-check-close-fraction?\n\n```cpp\n    BOOST_CHECK(close_to(double{c1.m_coinstip_cache_size_bytes}, max_cache * 0.05, /*tol_pct=*/1));"
  },
  {
   "t": "2026-08-23T15:51:47Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "8cc86b5332648154d84745d1b27c6d6da1d92a8f"
  },
  {
   "t": "2026-08-24T15:25:26Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "8be2320bfe7930038915785f9b9ebf106d63e068"
  },
  {
   "t": "2026-08-30T20:02:10Z",
   "kind": "review",
   "who": "jeanpablojp",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "8be2320bfe7930038915785f9b9ebf106d63e068",
   "text": "Concept ACK\n\nThe whole suite passes here and the scripted-diff reproduces.\n\n`BOOST_TEST_RUN_FILTERS` is no longer read, so `deterministic-unittest-coverage` runs the whole binary instead of the suite it was given.\n\n`bitcoin_core_ci.sh` in the libmultiprocess subtree still passes three Boost.Test flags, and any one of them now makes it exit with code 2 without running anything. It doesn't run in CI here, but it checks out Core master, so it breaks as soon as this lands.\n\nOne question on scope. That's 1096 new lines in `framework.h` and I couldn't find anything covering their failure paths. `util_check_tests` covers both paths for `Assert`. Would something similar work here, or is it worth a follow-up? Happy to help if useful."
  },
  {
   "t": "2026-08-30T20:02:10Z",
   "kind": "review_comment",
   "who": "jeanpablojp",
   "assoc": "CONTRIBUTOR",
   "path": "src/test/util/framework.h",
   "commit": "c7677eae8592ec9f9db39615d66fb117038e75f5",
   "in_reply_to": null,
   "text": "Comparing contents here is right, `BOOST_CHECK_EQUAL` already did that. What comes with it is that there's no null check, and `is_cstring` matches after decay, so literals land here too. With either side null this segfaults instead of reporting the failure. On master two nulls pass and one null reports a failure.\n\nToday the branch is only reached from `NullOverride` in `settings_tests`, where neither side can be null, so nothing breaks yet."
  },
  {
   "t": "2026-08-30T20:02:10Z",
   "kind": "review_comment",
   "who": "jeanpablojp",
   "assoc": "CONTRIBUTOR",
   "path": "src/test/util/framework.h",
   "commit": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7",
   "in_reply_to": null,
   "text": "This never flushes. With a crash inside a test case and output redirected, master keeps the preceding lines and here the file comes back empty. Boost catches the signal and names the case that died, while the PR description explicitly calls out disabling `catch_system_errors`. I didn't see the flush mentioned, and it's what makes a crash leave no trace at all.\n\nUnder CTest the loss is partial, because the node log with `-printtoconsole=1` flushes stdout per line and carries the framework's lines along with it.\n\nThe same buffer causes a second, smaller thing. `test_LockDirectory` forks and the child exits with `exit(0)`, reprinting what it inherited, so the output comes out duplicated."
  },
  {
   "t": "2026-08-30T20:02:10Z",
   "kind": "review_comment",
   "who": "jeanpablojp",
   "assoc": "CONTRIBUTOR",
   "path": "contrib/guix/libexec/build_linux.sh",
   "commit": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7",
   "in_reply_to": null,
   "text": "I saw the request to drop the workaround. Looking at `b12a70f330`, the workaround looks to me like the `riscv64-linux-gnu` arm of the `case` rather than the flag, since the exception was there because of the linker warnings from `execution_monitor.ipp`, which this PR removes. Dropping the whole block means no Linux host links with `-Wl,--fatal-warnings` any more, while `build_win.sh` and `build_win_gui.sh` keep it. CMake's `working_linker_werror_flag` doesn't cover this. Would it make sense to keep the flag for every host now that riscv64 is clean?"
  },
  {
   "t": "2026-08-30T20:02:10Z",
   "kind": "review_comment",
   "who": "jeanpablojp",
   "assoc": "CONTRIBUTOR",
   "path": "src/test/util/framework.h",
   "commit": "c7677eae8592ec9f9db39615d66fb117038e75f5",
   "in_reply_to": null,
   "text": "Here the value is only checked for presence, never read, so `0` and an empty string both turn shuffling on and a fixed seed no longer reproduces. With `BOOST_TEST_RANDOM=5` master repeats the order across runs and this doesn't. Boost also prints the seed it used, which here doesn't come out at any level, so there's no way to reproduce an order-dependent failure. `00_setup_env.sh` already uses `${BOOST_TEST_RANDOM:-1}`."
  },
  {
   "t": "2026-08-30T20:02:10Z",
   "kind": "review_comment",
   "who": "jeanpablojp",
   "assoc": "CONTRIBUTOR",
   "path": "src/test/util/framework.h",
   "commit": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7",
   "in_reply_to": null,
   "text": "This overload wins over the primary by partial ordering, so the `static_assert` never reaches `std::optional`. With `BOOST_CHECK_EQUAL` and a `T` that has no `operator<<`, comparing two `optional<T>` compiles here and prints the same type-only text on both sides, whereas the merge base refuses to compile.\n\nMaking it recurse into `stringify(*v)` does reach the assert, and then three existing sites stop building: the `optional<CCoinsStats>` in `coinstatsindex_tests`, the `optional<FeeRateEstimate>` in `mempool_fee_estimator_tests`, and the `optional<Node<CPubKey>>` in `miniscript_tests`. This looks like the same case as the iterators, so is this one for the `CHECK_NO_DISPLAY` follow-up too?"
  },
  {
   "t": "2026-08-30T20:02:10Z",
   "kind": "review_comment",
   "who": "jeanpablojp",
   "assoc": "CONTRIBUTOR",
   "path": "src/test/util/framework.h",
   "commit": "c7677eae8592ec9f9db39615d66fb117038e75f5",
   "in_reply_to": null,
   "text": "`TEST_SUITE_BEGIN(suite, Fixture)` sets `btc_suite_fixture`, but `TEST_CASE` registers a plain function and never uses it. With a fixture whose constructor bumps a counter, a `TEST_CASE` in that suite sees 0 while a `BOOST_AUTO_TEST_CASE` in an otherwise identical suite sees 1. The description says the suite fixture applies to each test, and the comment above `TEST_CASE` says it's the no-fixture case. Should `TEST_CASE` delegate to `FIXTURE_TEST_CASE(name, btc_suite_fixture)`?"
  },
  {
   "t": "2026-09-03T14:10:54Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "c7677eae8592ec9f9db39615d66fb117038e75f5"
  },
  {
   "t": "2026-09-03T14:12:00Z",
   "kind": "comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "text": "Rebased with changes from #36091. Thanks for the review @jeanpablojp will address it soon"
  },
  {
   "t": "2026-09-10T11:30:19Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "9ead8ded9839c99a0c58ba89cbbe7e75ca858695"
  },
  {
   "t": "2026-09-10T11:31:05Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "contrib/guix/libexec/build_linux.sh",
   "commit": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7",
   "in_reply_to": 3890390078,
   "text": "Added `Wl, --fatal-warnings` on head commit, lmk if thats what you mean"
  },
  {
   "t": "2026-09-10T11:32:26Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "c7677eae8592ec9f9db39615d66fb117038e75f5",
   "in_reply_to": 3890390082,
   "text": "Fixed by using a random seed and printing it if equal to 1, and setting the seed directly if > 1. 0 and null do nothing, thanks. Although I wonder if tests can fail because of a particular ordering, are they actually \"unit\" tests."
  },
  {
   "t": "2026-09-10T11:33:26Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "c7677eae8592ec9f9db39615d66fb117038e75f5",
   "in_reply_to": 3890390092,
   "text": "Seems fine. I would think it very strange to update a global as part of a test fixture, but this is a code reduction and should hopefully simplify review."
  },
  {
   "t": "2026-09-10T11:33:53Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7",
   "in_reply_to": 3890390077,
   "text": "I think a cout flush should solve these. Updated in latest push."
  },
  {
   "t": "2026-09-10T11:34:45Z",
   "kind": "review_comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "path": "src/test/util/framework.h",
   "commit": "c7677eae8592ec9f9db39615d66fb117038e75f5",
   "in_reply_to": 3890390075,
   "text": "Added a check if either side is null so it does not go through strcmp"
  },
  {
   "t": "2026-09-10T11:44:37Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "81077740a9fef4af671fb3981d259e350c8fa6fc"
  },
  {
   "t": "2026-09-10T12:18:05Z",
   "kind": "comment",
   "who": "rustaceanrob",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nFixed\n\n[quoted text omitted]\n~I'll push a fix in a bit. I suppose log/run report should be separate concepts like with boost.~\n\nI added a `catch_system_error` flag for compatibility as well as a separation between the summary and log level. `./build/bin/test_bitcoin --report_level=yes -l nothing` now prints the run summary but no logs."
  },
  {
   "t": "2026-09-14T10:51:15Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "b33574d00b87c74ca8b1dd8054902b3f4e46a1c0"
  },
  {
   "t": "2026-09-16T18:02:20Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "15b17fe9730e073458222d30d7c9b41b4163a6e3"
  },
  {
   "t": "2026-09-16T18:24:12Z",
   "kind": "force_push",
   "who": "rustaceanrob",
   "commit": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7"
  }
 ],
 "labels_log": [
  {
   "t": "2026-07-14T11:54:13Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-14T13:22:08Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-15T12:03:47Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-15T13:27:19Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-20T10:54:07Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-20T12:16:15Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-22T14:12:03Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-22T15:36:51Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-29T09:03:22Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-29T11:27:07Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-11T16:18:17Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-11T18:47:44Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-11T19:03:15Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-12T15:02:58Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-14T15:41:23Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-20T14:45:30Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-21T08:23:28Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-23T16:16:18Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-10T11:45:42Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-10T13:07:30Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-16T18:25:20Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-16T19:54:58Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-07-14T09:38:33Z",
   "kind": "convert_to_draft",
   "who": "rustaceanrob"
  },
  {
   "t": "2026-07-15T12:37:42Z",
   "kind": "ready_for_review",
   "who": "rustaceanrob"
  },
  {
   "t": "2026-07-15T16:03:49Z",
   "kind": "convert_to_draft",
   "who": "rustaceanrob"
  },
  {
   "t": "2026-07-20T15:11:46Z",
   "kind": "ready_for_review",
   "who": "rustaceanrob"
  }
 ],
 "text_chars": 26985,
 "text_tokens_estimate": 6746,
 "changed_paths": [
  "cmake/module/AddBoostIfNeeded.cmake",
  "contrib/guix/libexec/build_linux.sh",
  "depends/packages/boost.mk",
  "src/ipc/test/ipc_tests.cpp",
  "src/test/addrman_tests.cpp",
  "src/test/allocator_tests.cpp",
  "src/test/amount_tests.cpp",
  "src/test/argsman_tests.cpp",
  "src/test/arith_uint256_tests.cpp",
  "src/test/banman_tests.cpp",
  "src/test/base32_tests.cpp",
  "src/test/base58_tests.cpp",
  "src/test/base64_tests.cpp",
  "src/test/baseindex_tests.cpp",
  "src/test/bech32_tests.cpp",
  "src/test/bip324_tests.cpp",
  "src/test/bip328_tests.cpp",
  "src/test/bip32_tests.cpp",
  "src/test/blockchain_tests.cpp",
  "src/test/blockencodings_tests.cpp",
  "src/test/blockfilter_index_tests.cpp",
  "src/test/blockfilter_tests.cpp",
  "src/test/blockmanager_tests.cpp",
  "src/test/blockpolicyestimator_tests.cpp",
  "src/test/bloom_tests.cpp",
  "src/test/bswap_tests.cpp",
  "src/test/btcsignals_tests.cpp",
  "src/test/caches_tests.cpp",
  "src/test/chain_tests.cpp",
  "src/test/chainstate_write_tests.cpp",
  "src/test/checkqueue_tests.cpp",
  "src/test/cluster_linearize_tests.cpp",
  "src/test/coins_tests.cpp",
  "src/test/coinscachepair_tests.cpp",
  "src/test/coinstatsindex_tests.cpp",
  "src/test/coinsviewoverlay_tests.cpp",
  "src/test/common_url_tests.cpp",
  "src/test/compress_tests.cpp",
  "src/test/crypto_tests.cpp",
  "src/test/cuckoocache_tests.cpp",
  "src/test/dbwrapper_tests.cpp",
  "src/test/denialofservice_tests.cpp",
  "src/test/descriptor_tests.cpp",
  "src/test/disconnected_transactions.cpp",
  "src/test/feefrac_tests.cpp",
  "src/test/feerounder_tests.cpp",
  "src/test/fees_util_tests.cpp",
  "src/test/flatfile_tests.cpp",
  "src/test/fs_tests.cpp",
  "src/test/getarg_tests.cpp",
  "src/test/hash_tests.cpp",
  "src/test/headers_sync_chainwork_tests.cpp",
  "src/test/httpserver_tests.cpp",
  "src/test/i2p_tests.cpp",
  "src/test/interfaces_tests.cpp",
  "src/test/kernel/test_kernel.cpp",
  "src/test/key_io_tests.cpp",
  "src/test/key_tests.cpp",
  "src/test/logging_tests.cpp",
  "src/test/main.cpp",
  "src/test/mempool_fee_estimator_tests.cpp",
  "src/test/mempool_tests.cpp",
  "src/test/merkle_tests.cpp",
  "src/test/merkleblock_tests.cpp",
  "src/test/miner_tests.cpp",
  "src/test/miniminer_tests.cpp",
  "src/test/miniscript_tests.cpp",
  "src/test/minisketch_tests.cpp",
  "src/test/multisig_tests.cpp",
  "src/test/net_peer_connection_tests.cpp",
  "src/test/net_peer_eviction_tests.cpp",
  "src/test/net_tests.cpp",
  "src/test/netbase_tests.cpp",
  "src/test/node_init_tests.cpp",
  "src/test/node_warnings_tests.cpp",
  "src/test/orphanage_tests.cpp",
  "src/test/pcp_tests.cpp",
  "src/test/peerman_tests.cpp",
  "src/test/pmt_tests.cpp",
  "src/test/pool_tests.cpp",
  "src/test/pow_tests.cpp",
  "src/test/prevector_tests.cpp",
  "src/test/private_broadcast_tests.cpp",
  "src/test/psbt_tests.cpp",
  "src/test/random_tests.cpp",
  "src/test/rbf_tests.cpp",
  "src/test/rest_tests.cpp",
  "src/test/result_tests.cpp",
  "src/test/reverselock_tests.cpp",
  "src/test/rpc_tests.cpp",
  "src/test/sanity_tests.cpp",
  "src/test/scheduler_tests.cpp",
  "src/test/script_assets_tests.cpp",
  "src/test/script_p2sh_tests.cpp",
  "src/test/script_parse_tests.cpp",
  "src/test/script_segwit_tests.cpp",
  "src/test/script_standard_tests.cpp",
  "src/test/script_tests.cpp",
  "src/test/scriptnum_tests.cpp",
  "src/test/serfloat_tests.cpp",
  "src/test/serialize_tests.cpp",
  "src/test/settings_tests.cpp",
  "src/test/sighash_tests.cpp",
  "src/test/sigopcount_tests.cpp",
  "src/test/skiplist_tests.cpp",
  "src/test/sock_tests.cpp",
  "src/test/span_tests.cpp",
  "src/test/streams_tests.cpp",
  "src/test/sync_tests.cpp",
  "src/test/system_ram_tests.cpp",
  "src/test/system_tests.cpp",
  "src/test/testnet4_miner_tests.cpp",
  "src/test/threadpool_tests.cpp",
  "src/test/timeoffsets_tests.cpp",
  "src/test/torcontrol_tests.cpp",
  "src/test/transaction_tests.cpp",
  "src/test/translation_tests.cpp",
  "src/test/txdownload_tests.cpp",
  "src/test/txgraph_tests.cpp",
  "src/test/txindex_tests.cpp",
  "src/test/txospenderindex_tests.cpp",
  "src/test/txpackage_tests.cpp",
  "src/test/txreconciliation_tests.cpp",
  "src/test/txrequest_tests.cpp",
  "src/test/txvalidation_tests.cpp",
  "src/test/txvalidationcache_tests.cpp",
  "src/test/uint256_tests.cpp",
  "src/test/util/CMakeLists.txt",
  "src/test/util/common.cpp",
  "src/test/util/common.h",
  "src/test/util/framework.h",
  "src/test/util_check_tests.cpp",
  "src/test/util_expected_tests.cpp",
  "src/test/util_string_tests.cpp",
  "src/test/util_tests.cpp",
  "src/test/util_threadnames_tests.cpp",
  "src/test/util_trace_tests.cpp",
  "src/test/validation_block_tests.cpp",
  "src/test/validation_chainstate_tests.cpp",
  "src/test/validation_chainstatemanager_tests.cpp",
  "src/test/validation_flush_tests.cpp",
  "src/test/validation_tests.cpp",
  "src/test/validationinterface_tests.cpp",
  "src/test/versionbits_tests.cpp",
  "src/wallet/test/coinselection_tests.cpp",
  "src/wallet/test/coinselector_tests.cpp",
  "src/wallet/test/db_tests.cpp",
  "src/wallet/test/feebumper_tests.cpp",
  "src/wallet/test/group_outputs_tests.cpp",
  "src/wallet/test/init_tests.cpp",
  "src/wallet/test/ismine_tests.cpp",
  "src/wallet/test/psbt_wallet_tests.cpp",
  "src/wallet/test/scriptpubkeyman_tests.cpp",
  "src/wallet/test/spend_tests.cpp",
  "src/wallet/test/wallet_crypto_tests.cpp",
  "src/wallet/test/wallet_interfaces_tests.cpp",
  "src/wallet/test/wallet_rpc_tests.cpp",
  "src/wallet/test/wallet_tests.cpp",
  "src/wallet/test/wallet_transaction_tests.cpp",
  "src/wallet/test/walletdb_tests.cpp",
  "src/wallet/test/walletload_tests.cpp",
  "test/lint/lint-includes.py",
  "vcpkg.json"
 ],
 "files": [
  {
   "path": "cmake/module/AddBoostIfNeeded.cmake",
   "add": 0,
   "del": 12
  },
  {
   "path": "contrib/guix/libexec/build_linux.sh",
   "add": 1,
   "del": 7
  },
  {
   "path": "depends/packages/boost.mk",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/ipc/test/ipc_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/addrman_tests.cpp",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/test/allocator_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/amount_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/argsman_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/test/arith_uint256_tests.cpp",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/test/banman_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/base32_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/base58_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/base64_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/baseindex_tests.cpp",
   "add": 5,
   "del": 5
  },
  {
   "path": "src/test/bech32_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/bip324_tests.cpp",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/test/bip328_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/bip32_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/blockchain_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/blockencodings_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/blockfilter_index_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/blockfilter_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/blockmanager_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/blockpolicyestimator_tests.cpp",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/test/bloom_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/bswap_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/btcsignals_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/caches_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/chain_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/chainstate_write_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/checkqueue_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/cluster_linearize_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/test/coins_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/coinscachepair_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/coinstatsindex_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/coinsviewoverlay_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/common_url_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/compress_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/crypto_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/cuckoocache_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/dbwrapper_tests.cpp",
   "add": 11,
   "del": 1
  },
  {
   "path": "src/test/denialofservice_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/descriptor_tests.cpp",
   "add": 5,
   "del": 7
  },
  {
   "path": "src/test/disconnected_transactions.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/feefrac_tests.cpp",
   "add": 4,
   "del": 4
  },
  {
   "path": "src/test/feerounder_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/fees_util_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/flatfile_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/fs_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/getarg_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/hash_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/headers_sync_chainwork_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/httpserver_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/i2p_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/interfaces_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/kernel/test_kernel.cpp",
   "add": 36,
   "del": 2
  },
  {
   "path": "src/test/key_io_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/key_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/logging_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/main.cpp",
   "add": 10,
   "del": 17
  },
  {
   "path": "src/test/mempool_fee_estimator_tests.cpp",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/test/mempool_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/merkle_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/merkleblock_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/miner_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/miniminer_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/miniscript_tests.cpp",
   "add": 5,
   "del": 5
  },
  {
   "path": "src/test/minisketch_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/multisig_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/net_peer_connection_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/net_peer_eviction_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/net_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/netbase_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/node_init_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/node_warnings_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/orphanage_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/pcp_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/peerman_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/pmt_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/pool_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/pow_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/prevector_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/private_broadcast_tests.cpp",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/test/psbt_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/random_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/rbf_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/rest_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/result_tests.cpp",
   "add": 3,
   "del": 1
  },
  {
   "path": "src/test/reverselock_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/rpc_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/sanity_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/scheduler_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/script_assets_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/script_p2sh_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/script_parse_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/script_segwit_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/script_standard_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/script_tests.cpp",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/test/scriptnum_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/serfloat_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/serialize_tests.cpp",
   "add": 6,
   "del": 6
  },
  {
   "path": "src/test/settings_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/sighash_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/test/sigopcount_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/skiplist_tests.cpp",
   "add": 5,
   "del": 5
  },
  {
   "path": "src/test/sock_tests.cpp",
   "add": 5,
   "del": 5
  },
  {
   "path": "src/test/span_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/streams_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/sync_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/system_ram_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/system_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/test/testnet4_miner_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/threadpool_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/timeoffsets_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/torcontrol_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/transaction_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/test/translation_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/txdownload_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/test/txgraph_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/test/txindex_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/txospenderindex_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/txpackage_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/txreconciliation_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/txrequest_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/txvalidation_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/txvalidationcache_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/test/uint256_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/util/CMakeLists.txt",
   "add": 1,
   "del": 0
  },
  {
   "path": "src/test/util/common.cpp",
   "add": 146,
   "del": 0
  },
  {
   "path": "src/test/util/common.h",
   "add": 55,
   "del": 0
  },
  {
   "path": "src/test/util/framework.h",
   "add": 1209,
   "del": 0
  },
  {
   "path": "src/test/util_check_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/util_expected_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/util_string_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/util_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/util_threadnames_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/util_trace_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/validation_block_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/validation_chainstate_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/validation_chainstatemanager_tests.cpp",
   "add": 11,
   "del": 11
  },
  {
   "path": "src/test/validation_flush_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/validation_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/validationinterface_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/versionbits_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/wallet/test/coinselection_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/coinselector_tests.cpp",
   "add": 2,
   "del": 2
  },
  {
   "path": "src/wallet/test/db_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/feebumper_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/group_outputs_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/init_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/ismine_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/psbt_wallet_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/scriptpubkeyman_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/spend_tests.cpp",
   "add": 6,
   "del": 4
  },
  {
   "path": "src/wallet/test/wallet_crypto_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/wallet_interfaces_tests.cpp",
   "add": 6,
   "del": 1
  },
  {
   "path": "src/wallet/test/wallet_rpc_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/wallet_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/wallet_transaction_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/walletdb_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/wallet/test/walletload_tests.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "test/lint/lint-includes.py",
   "add": 0,
   "del": 2
  },
  {
   "path": "vcpkg.json",
   "add": 1,
   "del": 4
  }
 ],
 "test_lines": 1939,
 "git": {
  "head": "53c89d1f17e0eca6f61fc9a3496a7ddae0e9f4c7",
  "head_matches_backup": true,
  "base": "b8215855437288cac95c7fd5d41104c73c0f3495",
  "commits": [
   {
    "sha": "aa3b60c048",
    "subject": "test: Add display `operator<<` overloads to `common.{h,cpp}`",
    "files": 3,
    "add": 202,
    "del": 0
   },
   {
    "sha": "f3758b351f",
    "subject": "test: Remove low usage `BOOST` macros",
    "files": 2,
    "add": 6,
    "del": 8
   },
   {
    "sha": "04a8028ce7",
    "subject": "test: Inline `CRecipient` construction to avoid gcc12 uninitialized warning",
    "files": 1,
    "add": 5,
    "del": 3
   },
   {
    "sha": "5b8c34777e",
    "subject": "test: Wrap bitwise `&` expressions in macros",
    "files": 1,
    "add": 10,
    "del": 10
   },
   {
    "sha": "e3cd8423ff",
    "subject": "test: Wrap `||`, `&&` expressions in macros",
    "files": 15,
    "add": 27,
    "del": 27
   },
   {
    "sha": "5b7017760b",
    "subject": "test: Add header-only framework to util",
    "files": 2,
    "add": 1240,
    "del": 0
   },
   {
    "sha": "c541190f42",
    "subject": "scripted-diff: Migrate tests to header-only framework",
    "files": 156,
    "add": 167,
    "del": 205
   },
   {
    "sha": "e0be64bfc5",
    "subject": "test: Require `stringify` implementation or explicit omission",
    "files": 11,
    "add": 68,
    "del": 19
   },
   {
    "sha": "bac9d2c6c2",
    "subject": "depends: drop test from Boost libraries",
    "files": 1,
    "add": 1,
    "del": 1
   },
   {
    "sha": "19bb8c8dd8",
    "subject": "cmake: drop vcpkg Boost Test check",
    "files": 1,
    "add": 0,
    "del": 12
   },
   {
    "sha": "da4147020b",
    "subject": "vcpkg: drop boost-test dependency",
    "files": 1,
    "add": 1,
    "del": 4
   },
   {
    "sha": "53c89d1f17",
    "subject": "guix: Drop `Boost.Test` unused workaround",
    "files": 1,
    "add": 1,
    "del": 7
   }
  ],
  "patch_truncated": true
 },
 "input_hash": "74417967b23ef8df",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}