{
 "number": 34502,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/34502",
 "title": "wallet: remove most asserts of `WALLET_FLAG_DESCRIPTORS` flag",
 "author": "rkrux",
 "author_association": "CONTRIBUTOR",
 "created_at": "2026-02-04T10:42:07Z",
 "updated_at": "2026-08-15T02:49:41Z",
 "age_days": 225,
 "draft": true,
 "labels": [
  "Wallet",
  "Needs rebase"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "77778e255925368b80a09d8bb3543dfc69b21c94",
 "head_ref": "descriptors-assertion",
 "head_repo": "rkrux/bitcoin",
 "head_history": [
  {
   "t": "2026-02-04T15:08:47Z",
   "sha": "77778e255925368b80a09d8bb3543dfc69b21c94"
  }
 ],
 "additions": 8,
 "deletions": 17,
 "changed_files": 2,
 "commit_count": 2,
 "size_bucket": "S",
 "mergeable_state": "dirty",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {},
   "conflicts": [
    {
     "number": 32895,
     "title": "wallet: Prepare for future upgrades by recording versions of last client to open and decrypt",
     "author": "achow101"
    },
    {
     "number": 32784,
     "title": "wallet: derivehdkey RPC to get xpub at arbitrary path",
     "author": "Sjors"
    },
    {
     "number": 30343,
     "title": "wallet, logging: Replace WalletLogPrintf() with LogInfo()",
     "author": "ryanofsky"
    }
   ]
  }
 },
 "acks_parsed": {},
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 0,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "b-l-u-e",
   "frankomosh"
  ]
 },
 "signals": {
  "needs_rebase": true,
  "ci_failed": false,
  "mergeable_state": "dirty",
  "last_author_activity": "2026-02-04T15:08:47Z",
  "last_reviewer_activity": "2026-02-18T13:50:44Z",
  "last_reviewer": "b-l-u-e",
  "author_silent_days": 225,
  "waiting_on_author_days": 211,
  "days_since_update": 33
 },
 "refs": {
  "mentioned": [],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [],
  "conflicts": [
   32895,
   32784,
   30343
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [],
 "body": "Reasons:\n1. Few of the wallet methods are descriptors specific as suggested\nby their names, these assertions seems redundant within them.\n2. Since the legacy wallet can't be loaded anymore, few of these\nassertions are outdated now.\n3. Seeing too many of these assertions in the `CWallet` class while\nreading the code is cognitively loaded, and after a while becomes\nannoying for the reader.\n\nNote: Such assertions in the migration specific functions have been\nleft untouched because they seem necessary there.",
 "commits": [
  {
   "sha": "a3ff41a5a89a3fdc9e47ae2036f7562029ae20cb",
   "date": "2026-02-04T14:53:06Z",
   "message": "wallet: remove few asserts of `WALLET_FLAG_DESCRIPTORS` flag\n\nReasons:\n1. Few of the wallet methods are descriptors specific as suggested\nby their names, these assertions seems redundant within them.\n2. Since the legacy wallet can't be loaded anymore, few of these\nassertions are outdated now.\n3. Seeing too many of these assertions in the `CWallet` class while\nreading the code is cognitively loaded, and after a while becomes\nannoying for the reader.\n\nNote: Such assertions in the migration specific functions have been\nleft untouched because they seem necessary there."
  },
  {
   "sha": "77778e255925368b80a09d8bb3543dfc69b21c94",
   "date": "2026-02-04T15:06:29Z",
   "message": "wallet: move out `UpgradeDescriptorCache()` wallet flag check to the callers\n\nThe `UpgradeDescriptorCache` method ends up being called via the\n`CWallet::Unlock` and `WalletBatch::LoadWallet` methods, both of\nwhich can be called for the legacy wallets within the context of\nwallet migration. For the former caller, it is evident in the\n`test_encrypted` test of `wallet_migration` suite.\n\nThe previous code where there is no explicit check in the callers\nmakes the reader believe that the callers end up being called only\nfor descriptor wallets, which is misleading. This move out of the\ncheck makes it explicit for the reader that this is not the only\nflow for these callers."
  }
 ],
 "timeline": [
  {
   "t": "2026-02-04T11:49:21Z",
   "kind": "comment",
   "who": "rkrux",
   "assoc": "CONTRIBUTOR",
   "text": "I had incorrectly run the functional tests in a different directory in local that led to all the functional tests pass. I can reproduce the test failure locally now, putting the PR in draft for now."
  },
  {
   "t": "2026-02-04T15:08:47Z",
   "kind": "force_push",
   "who": "rkrux",
   "commit": "77778e255925368b80a09d8bb3543dfc69b21c94"
  },
  {
   "t": "2026-02-09T11:29:34Z",
   "kind": "review",
   "who": "frankomosh",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "77778e255925368b80a09d8bb3543dfc69b21c94",
   "text": "Few questions from my code review;\n\nWhy remove the assertion from `EncryptWallet()`? I think it also does descriptor-specific work (iterates `m_spk_managers`, calls `SetupDescriptorScriptPubKeyMans()`).\n\nYou said in the other commit that `Unlock()` and `LoadWallet()` can be called during migration for legacy wallets. I wonder if `EncryptWallet()` can face a similar situation."
  },
  {
   "t": "2026-02-18T12:38:07Z",
   "kind": "comment",
   "who": "b-l-u-e",
   "assoc": "CONTRIBUTOR",
   "text": "[quoted text omitted]\n\ni tried testing with and without assertion seems with removing assertion leds to errors failing later\nadded some tests in src/wallet/test/wallet_tests.cpp to  see\n```diff\n--- a/src/wallet/test/wallet_tests.cpp\n+++ b/src/wallet/test/wallet_tests.cpp\n@@ -722,5 +722,32 @@ BOOST_FIXTURE_TEST_CASE(RemoveTxs, TestChain100Setup)\n     TestUnloadWallet(std::move(wallet));\n }\n\n+BOOST_FIXTURE_TEST_CASE(encryptwallet_requires_descriptor_wallet, BasicTestingSetup)\n+{\n+    WalletContext context;\n+    context.args = &m_args;\n+    auto wallet = TestLoadWallet(context);\n+    BOOST_REQUIRE(wallet);\n+    BOOST_CHECK(wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));\n+    bool ok = wallet->EncryptWallet(\"test\");\n+    (void)ok;\n+    WaitForDeleteWallet(std::move(wallet));\n+}\n+\n+BOOST_FIXTURE_TEST_CASE(encryptwallet_on_non_descriptor_wrong_behavior, WalletTestingSetup)\n+{\n+    BOOST_REQUIRE(!m_wallet.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));\n+    BOOST_REQUIRE(m_wallet.GetAllScriptPubKeyMans().empty());\n+\n+    bool ok = m_wallet.EncryptWallet(\"test\");\n+\n+    if (ok) {\n+        BOOST_CHECK_MESSAGE(!m_wallet.GetAllScriptPubKeyMans().empty(),\n+            \"EncryptWallet added descriptor SPKMs via SetupDescriptorScriptPubKeyMans()\");\n+        BOOST_CHECK_MESSAGE(!m_wallet.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS),\n+            \"Wrong behavior: wallet has descriptor SPKMs but WALLET_FLAG_DESCRIPTORS was never set inconsistent state\");\n+    }\n+}\n```\n\nso tests fails inside descriptor code scriptpubkeyman this is without assert\n```\nwallet/test/wallet_tests.cpp(737): Entering test case \"encryptwallet_on_non_descriptor_wrong_behavior\"\nwallet/test/wallet_tests.cpp(739): info: check !m_wallet.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) has passed\nwallet/test/wallet_tests.cpp(740): info: check m_wallet.GetAllScriptPubKeyMans().empty() has passed\ntest_bitcoin: wallet/scriptpubkeyman.cpp:1138: bool wallet::DescriptorScriptPubKeyMan::SetupDescriptorGeneration(WalletBatch &, const CExtKey &, OutputType, bool): Assertion `m_storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)' failed.\nunknown location(0): fatal error: in \"wallet_tests/encryptwallet_on_non_descriptor_wrong_behavior\": signal: SIGABRT (application abort requested)\nwallet/test/wallet_tests.cpp(740): last checkpoint\nwallet/test/wallet_tests.cpp(737): Leaving test case \"encryptwallet_on_non_descriptor_wrong_behavior\"; testing time: 340947us\nwallet/test/wallet_tests.cpp(45): Leaving test suite \"wallet_tests\"; testing time: 340982us\nwallet/test/wallet_transaction_tests.cpp(12): Test suite \"wallet_transaction_tests\" is skipped because disabled\nwallet/test/walletdb_tests.cpp(15): Test suite \"walletdb_tests\" is skipped because disabled\nwallet/test/walletload_tests.cpp(14): Test suite \"walletload_tests\" is skipped because disabled\nipc/test/ipc_tests.cpp(11): Test suite \"ipc_tests\" is skipped because disabled\nLeaving test module \"Bitcoin Core Test Suite\"; testing time: 341332us\n\n*** 1 failure is detected in the test module \"Bitcoin Core Test Suite\"\n```\n\nand then with assert it fails at the boundary Encryptwallet\n```\nwallet/test/wallet_tests.cpp(739): info: check !m_wallet.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) has passed\nwallet/test/wallet_tests.cpp(740): info: check m_wallet.GetAllScriptPubKeyMans().empty() has passed\nwallet/wallet.cpp:812 bool wallet::CWallet::EncryptWallet(const SecureString &): Assertion `IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)' failed.\nunknown location(0): fatal error: in \"wallet_tests/encryptwallet_on_non_descriptor_wrong_behavior\": signal: SIGABRT (application abort requested)\nwallet/test/wallet_tests.cpp(740): last checkpoint\nwallet/test/wallet_tests.cpp(737): Leaving test case \"encryptwallet_on_non_descriptor_wrong_behavior\"; testing time: 13719us\nwallet/test/wallet_tests.cpp(45): Leaving test suite \"wallet_tests\"; testing time: 13750us\nwallet/test/wallet_transaction_tests.cpp(12): Test suite \"wallet_transaction_tests\" is skipped because disabled\nwallet/test/walletdb_tests.cpp(15): Test suite \"walletdb_tests\" is skipped because disabled\nwallet/test/walletload_tests.cpp(14): Test suite \"walletload_tests\" is skipped because disabled\nipc/test/ipc_tests.cpp(11): Test suite \"ipc_tests\" is skipped because disabled\nLeaving test module \"Bitcoin Core Test Suite\"; testing time: 14055us\n\n*** 1 failure is detected in the test module \"Bitcoin Core Test Suite\"\n```"
  },
  {
   "t": "2026-02-18T13:50:44Z",
   "kind": "comment",
   "who": "b-l-u-e",
   "assoc": "CONTRIBUTOR",
   "text": "i think here states that its descriptor-specific\n\n```\ngit show a3ff41a5a8:src/wallet/wallet.cpp | sed -n '865,868p'\n        if (!IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET)) {\n            SetupDescriptorScriptPubKeyMans();\n        }\n        Lock();\n```"
  }
 ],
 "labels_log": [
  {
   "t": "2026-02-04T10:42:28Z",
   "action": "labeled",
   "label": "Wallet",
   "who": "DrahtBot"
  },
  {
   "t": "2026-02-04T12:05:38Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-02-04T16:13:02Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-15T02:49:40Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-02-04T11:49:31Z",
   "kind": "convert_to_draft",
   "who": "rkrux"
  },
  {
   "t": "2026-02-04T15:10:28Z",
   "kind": "renamed",
   "who": "rkrux",
   "from": "wallet: remove few asserts of `WALLET_FLAG_DESCRIPTORS` flag",
   "to": "wallet: remove most asserts of `WALLET_FLAG_DESCRIPTORS` flag"
  },
  {
   "t": "2026-02-05T07:40:58Z",
   "kind": "ready_for_review",
   "who": "rkrux"
  },
  {
   "t": "2026-03-05T08:46:41Z",
   "kind": "convert_to_draft",
   "who": "rkrux"
  }
 ],
 "text_chars": 7038,
 "text_tokens_estimate": 1759,
 "changed_paths": [],
 "files": [],
 "test_lines": null,
 "git": null,
 "input_hash": "968075286ee095f1",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}