index: remove unnecessary locator cleaning in BaseIndex::Init() #32882

pull HowHsu wants to merge 1 commits into bitcoin:master from HowHsu:read-best-block changing 2 files +8 −7
  1. HowHsu commented at 4:13 pm on July 5, 2025: none
    Leverage locator.IsNull() to simplify ReadBestBlock() and remove unnecessary SetNull().
  2. DrahtBot added the label UTXO Db and Indexes on Jul 5, 2025
  3. DrahtBot commented at 4:13 pm on July 5, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32882.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK l0rinc, furszy

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

  4. in src/index/base.h:59 in 1f678d832b outdated
    55@@ -56,7 +56,7 @@ class BaseIndex : public CValidationInterface
    56            bool f_memory = false, bool f_wipe = false, bool f_obfuscate = false);
    57 
    58         /// Read block locator of the chain that the index is in sync with.
    59-        bool ReadBestBlock(CBlockLocator& locator) const;
    60+        void ReadBestBlock(CBlockLocator& locator) const;
    


    luke-jr commented at 9:03 pm on July 7, 2025:
    No harm in returning success, even if ignored currently.

    HowHsu commented at 2:19 am on July 8, 2025:
    I tend to favor the principle of adding things only when they’re actually needed.
  5. l0rinc approved
  6. l0rinc commented at 11:52 pm on August 4, 2025: contributor

    ACK 1f678d832b1196ca7d7c2ff7e70d2172ae8c90b6

    Recreated and retested it locally. It’s a similar change to #33042, we have a few more places which should be cleanup up like this.

    I think this already makes the code slightly simpler, but alternatively, you could return an optional and not rely output params and nullness

     0diff --git a/src/index/base.cpp b/src/index/base.cpp
     1index fdd0e0d8af..0408021fd5 100644
     2--- a/src/index/base.cpp
     3+++ b/src/index/base.cpp
     4@@ -59,13 +59,10 @@ BaseIndex::DB::DB(const fs::path& path, size_t n_cache_size, bool f_memory, bool
     5         .options = [] { DBOptions options; node::ReadDatabaseArgs(gArgs, options); return options; }()}}
     6 {}
     7 
     8-bool BaseIndex::DB::ReadBestBlock(CBlockLocator& locator) const
     9+std::optional<CBlockLocator> BaseIndex::DB::ReadBestBlock() const
    10 {
    11-    bool success = Read(DB_BEST_BLOCK, locator);
    12-    if (!success) {
    13-        locator.SetNull();
    14-    }
    15-    return success;
    16+    if (CBlockLocator locator; Read(DB_BEST_BLOCK, locator)) return locator;
    17+    return {};
    18 }
    19 
    20 void BaseIndex::DB::WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator)
    21@@ -97,20 +94,17 @@ bool BaseIndex::Init()
    22     // callbacks are not missed once m_synced is true.
    23     m_chain->context()->validation_signals->RegisterValidationInterface(this);
    24 
    25-    CBlockLocator locator;
    26-    if (!GetDB().ReadBestBlock(locator)) {
    27-        locator.SetNull();
    28-    }
    29+    const auto locator{GetDB().ReadBestBlock()};
    30 
    31     LOCK(cs_main);
    32     CChain& index_chain = m_chainstate->m_chain;
    33 
    34-    if (locator.IsNull()) {
    35+    if (!locator) {
    36         SetBestBlockIndex(nullptr);
    37     } else {
    38         // Setting the best block to the locator's top block. If it is not part of the
    39         // best chain, we will rewind to the fork point during index sync
    40-        const CBlockIndex* locator_index{m_chainstate->m_blockman.LookupBlockIndex(locator.vHave.at(0))};
    41+        const CBlockIndex* locator_index{m_chainstate->m_blockman.LookupBlockIndex(locator->vHave.at(0))};
    42         if (!locator_index) {
    43             return InitError(Untranslated(strprintf("best block of %s not found. Please rebuild the index.", GetName())));
    44         }
    45diff --git a/src/index/base.h b/src/index/base.h
    46index 4131b06cad..c1971cae3f 100644
    47--- a/src/index/base.h
    48+++ b/src/index/base.h
    49@@ -56,7 +56,7 @@ protected:
    50            bool f_memory = false, bool f_wipe = false, bool f_obfuscate = false);
    51 
    52         /// Read block locator of the chain that the index is in sync with.
    53-        bool ReadBestBlock(CBlockLocator& locator) const;
    54+        std::optional<CBlockLocator> ReadBestBlock() const;
    55 
    56         /// Write block locator of the chain that the index is in sync with.
    57         void WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator);
    
  7. HowHsu force-pushed on Aug 5, 2025
  8. HowHsu commented at 5:28 am on August 5, 2025: none

    ACK 1f678d8

    Recreated and retested it locally. It’s a similar change to #33042, we have a few more places which should be cleanup up like this.

    I think this already makes the code slightly simpler, but alternatively, you could return an optional and not rely output params and nullness

    Details

    Thanks, l0rinc. I’ve updated the code as what you suggested

  9. l0rinc commented at 5:32 am on August 5, 2025: contributor
    The commit message and PR description needs to be updated now. Also consider adding co-authors when someone else also contributed.
  10. HowHsu force-pushed on Aug 5, 2025
  11. HowHsu commented at 5:54 am on August 5, 2025: none

    The commit message and PR description needs to be updated now. Also consider adding co-authors when someone else also contributed.

    True. Done.

  12. l0rinc commented at 5:55 am on August 5, 2025: contributor
    There’s still a typo in the title
  13. l0rinc approved
  14. l0rinc commented at 6:00 am on August 5, 2025: contributor

    ACK ce7323ec635c389732e142c043f83868ddcefdb3

    The commit message still sounds a bit unnatural and has a few typos, consider something like:

    index: remove unnecessary locator cleaning in BaseIndex::Init()

    Refactor BaseIndex::DB::ReadBestBlock() to return an optional value so that callers don’t need to rely on the locator itself to check if the call is successful or not. This simplifies the code.

    or just simply:

    refactor: remove redundant locator cleanup in BaseIndex::Init()

    Return optional value in ReadBestBlock() to eliminate manual SetNull() calls.

  15. HowHsu force-pushed on Aug 5, 2025
  16. l0rinc commented at 5:34 pm on August 5, 2025: contributor

    ACK 04044e554e6982977f9d82f9bb60659315a45f92

    PR title still has the typo

  17. in src/index/base.cpp:65 in 04044e554e outdated
    66-    if (!success) {
    67-        locator.SetNull();
    68-    }
    69-    return success;
    70+    if (CBlockLocator locator; Read(DB_BEST_BLOCK, locator)) return locator;
    71+    return {};
    


    furszy commented at 5:52 pm on August 5, 2025:
    Better to return std::nullopt.

    l0rinc commented at 6:55 pm on August 5, 2025:

    Isn’t that what we’re doing already? I tried making it explicit in:

    0if (CBlockLocator locator; false) return locator;
    1return {};
    

    which successfully enters:

    0if (!locator) {
    1    SetBestBlockIndex(nullptr);
    

    since locator.has_value() == false when running txindex_tests/txindex_initial_sync.

    Or do you mean just that it’s more aesthetic that way?


    furszy commented at 7:12 pm on August 5, 2025:

    I think the fact that you had to run the txindex_tests/txindex_initial_sync test to assert the return value is kind of self-explanatory.

    Using the standard std::nullopt is better in terms of style and clarity. It’s explicit and self-documenting. In contrast, return {}; is more ambiguous. One need to check the function’s signature. Is it returning an empty CBlockLocator? a null optional?

  18. HowHsu force-pushed on Aug 6, 2025
  19. l0rinc commented at 3:11 am on August 6, 2025: contributor

    ACK c83741e4033824b4c798fc3e9cdc33cb30bbaf32

    please fix the typo in the PR subject: locater -> locator

  20. HowHsu renamed this:
    index: remove unnecessary locater cleaning in BaseIndex::Init()
    index: remove unnecessary locator cleaning in BaseIndex::Init()
    on Aug 6, 2025
  21. in src/index/base.cpp:102 in c83741e403 outdated
    102 
    103     LOCK(cs_main);
    104     CChain& index_chain = m_chainstate->m_chain;
    105 
    106-    if (locator.IsNull()) {
    107+    if (!locator) {
    


    furszy commented at 10:27 pm on August 16, 2025:

    Might be good to do if (!locator || locator->IsNull()) { just in case we ever stored an empty locator on disk (probably we never have, but.. we’ve had issues in this area before #24117, so better to be a bit conservative here).

    That said, given this finding, I feel we should just use CBlockLocator directly, without the optional type. This would simplify the code and minimize the changes in the PR. You’d just need to make the function return a locator instead of a bool (because the locator is created within the Read function, you would never need to call SetNull on the locator), and extend the method’s doc to note that the returned locator will be empty if no record exists too.


    l0rinc commented at 11:20 pm on August 16, 2025:
    Since there’s already a null locator, you’re right, we don’t need an optional
  22. HowHsu force-pushed on Sep 17, 2025
  23. refactor: remove redundant locator cleanup in BaseIndex::Init()
    Leverage locator.IsNull() to simplify ReadBestBlock() and remove
    unnecessary SetNull().
    
    Co-authored-by: furszy <matiasfurszyfer@protonmail.com>
    Co-authored-by: l0rinc <pap.lorinc@gmail.com>
    Signed-off-by: Hao Xu <hao.xu@linux.dev>
    facd01e6ff
  24. HowHsu force-pushed on Sep 17, 2025
  25. l0rinc commented at 9:11 pm on September 17, 2025: contributor

    ACK facd01e6ffbbd019312f370a3807de0b95bbd745

    Note that we don’t usually add the Signed off by to the commit message, it just seems like noise to me. You can still sign your commits if you want, but I’m no sure what this line adds that isn’t already obvious.

    Also, not sure why refactor: remove redundant locator cleanup in BaseIndex::Init() is repeated (slightly differently) in the PR description.

  26. HowHsu commented at 3:02 am on September 18, 2025: none

    ACK facd01e

    Note that we don’t usually add the Signed off by to the commit message, it just seems like noise to me. You can still sign your commits if you want, but I’m no sure what this line adds that isn’t already obvious.

    Added by my git config automatically, that is a kind of DCO for GPLv2, I’ll remove it in later PRs since Bitcoin Core is MIT, so yes, it is not necessary to Sign.

    Also, not sure why refactor: remove redundant locator cleanup in BaseIndex::Init() is repeated (slightly differently) in the PR description.

    I’ll remove it.

  27. furszy commented at 7:38 pm on September 18, 2025: member

    utACK facd01e6ffbbd019312f370a3807de0b95bbd745

    At least for me, there’s no need to add me as a co-author when the code or suggestion is simple. Generally, only add people when they contribute a substantial change. Just a small thought.


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: 2025-10-10 15:13 UTC

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