Track util::Expected compatibility refactors for future std::expected migration #35332

issue kevkevinpal opened this issue on May 20, 2026
  1. kevkevinpal commented at 2:14 PM on May 20, 2026: contributor

    Summary

    In C++23 std::expected is introduced. Currently, we support C++20 and above because of this we use util::Expected.

    I've opened a few PR's, making changes to use util::Expected now, and expect that there are more that I missed. I want to use this issue to consolidate everywhere we might need to refactor to use util::Expected instead.

    PRs refactoring to use util::Expected

    Found these instances where util::Expected is already used

    grep -nri "util::Expected" ./src/
    ./src/index/txospenderindex.cpp:141:util::Expected<TxoSpender, std::string> TxoSpenderIndex::ReadTransaction(const CDiskTxPos& tx_pos) const
    ./src/index/txospenderindex.cpp:160:util::Expected<std::optional<TxoSpender>, std::string> TxoSpenderIndex::FindSpender(const COutPoint& txo) const
    ./src/index/txospenderindex.cpp:180:    return util::Expected<std::optional<TxoSpender>, std::string>(std::nullopt);
    ./src/index/txospenderindex.h:44:    util::Expected<TxoSpender, std::string> ReadTransaction(const CDiskTxPos& pos) const;
    ./src/index/txospenderindex.h:68:    util::Expected<std::optional<TxoSpender>, std::string> FindSpender(const COutPoint& txo) const;
    ./src/node/blockstorage.h:319:    using ReadRawBlockResult = util::Expected<std::vector<std::byte>, ReadRawError>;
    ./src/net_processing.cpp:534:    util::Expected<void, std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override
    ./src/net_processing.cpp:1961:util::Expected<void, std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBlockIndex& block_index)
    ./src/net_processing.h:110:    virtual util::Expected<void, std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) = 0;
    ./src/util/threadpool.h:184:    [[nodiscard]] util::Expected<Future<F>, SubmitError> Submit(F&& fn) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
    ./src/util/threadpool.h:220:    [[nodiscard]] util::Expected<std::vector<RangeFuture<R>>, SubmitError> Submit(R&& fns) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
    

    Also, when Bitcoin Core upgrades to C++23, then we should ideally move to using std:expected instead

  2. fanquake commented at 2:07 PM on June 1, 2026: member

    Is there a particular motivation to do this (now), before migrating to C++23, and do we need a tracking issue for this?

  3. kevkevinpal commented at 2:34 PM on June 1, 2026: contributor

    Is there a particular motivation to do this (now), before migrating to C++23, and do we need a tracking issue for this?

    A few reasons,

    • Better Semantics: Having an OK variant inside an error enum is confusing. I initially opened #32958 just to remove OK, but it touched a massive number of files. util::Expected is a much cleaner way to handle this.
    • Simplified Logic: Moving to using the util::Expected simplified the logic quite a bit
    • Smoother Migration: Since util::Expected mirrors C++23, doing this refactor improves the codebase today and will make the eventual std::expected migration simply updating from using util::Expected to std::expected.

    As for the tracking issue, I opened it mainly to consolidate the scattered places where this refactor makes sense, rather than having isolated PRs pop up randomly. Let me know if the tracking issue is overkill, and we can close this and have the individual stand-alone PRs instead.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-06-13 21:30 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me