rpc, logging: add backgroundvalidation to getblockchaininfo #33259

pull polespinasa wants to merge 3 commits into bitcoin:master from polespinasa:2025-08-26-getblockchaininfo-backgroundvalidation changing 5 files +74 −7
  1. polespinasa commented at 11:02 pm on August 26, 2025: member

    getblockchaininfo returns verificationprogress=1 and initialblockdownload=false even if there’s background validation. This PR adds information about background validation to rpc getblockchaininfo in a similar way to validationprogress does.

    If assume utxo was used the output of a “sync” node performing background validation:

     0$ ./build/bin/bitcoin-cli getblockchaininfo
     1...
     2  "mediantime": 1756933740,
     3  "verificationprogress": 1,
     4  "initialblockdownload": false,
     5  "backgroundvalidation": true,
     6  "background": {
     7    "snapshotheight": 880000,
     8    "blocks": 527589,
     9    "bestblockhash": "0000000000000000002326308420fa5ccd28a9155217f4d1896ab443d84148fa",
    10    "mediantime": 1529076654,
    11    "chainwork": "0000000000000000000000000000000000000000020c92fab9e5e1d8ed2d8dbc",
    12    "verificationprogress": 0.2815790617966284
    13  },
    14  "chainwork": "0000000000000000000000000000000000000000df97866c410b0302954919d2",
    15  "size_on_disk": 61198817285,
    16
    17...
    

    If assume utxo was not used the progress is hidden and background validation is set to false:

    0$ ./build/bin/bitcoin-cli getblockchaininfo
    1...
    2  "mediantime": 1756245700,
    3  "verificationprogress": 1,
    4  "initialblockdownload": false,
    5  "backgroundvalidation": false,
    6  "chainwork": "00000000000000000000000000000000000000000000000000000656d6bb052b",
    7  "size_on_disk": 3964972194,
    8...
    

    The PR also updates the way we estimate the verification progress returning a 100% on the snapshot block and not on the tip as we will stop doing background validation when reaching it.

  2. DrahtBot commented at 11:02 pm on August 26, 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/33259.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    Concept ACK yuvicc, luke-jr, danielabrozzoni

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

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #30214 (refactor: Improve assumeutxo state representation by ryanofsky)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  3. yuvicc commented at 5:23 am on August 27, 2025: contributor
    Concept ACK
  4. luke-jr commented at 10:50 pm on August 27, 2025: member
    Concept ACK. Would be nice to test the active state.
  5. polespinasa commented at 11:12 pm on August 27, 2025: member

    Would be nice to test the active state. @luke-jr what do you mean by active state?

  6. bitcoin deleted a comment on Aug 27, 2025
  7. luke-jr commented at 11:43 pm on August 27, 2025: member
    When there is a background sync, not just false
  8. luke-jr referenced this in commit 732ba0e131 on Aug 28, 2025
  9. ajtowns commented at 0:56 am on August 28, 2025: contributor

    Would it be better to return an object, eg:

    0{
    1    "background": {
    2        "blocks": 100000,
    3        "bestblockhash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",
    4        "mediantime": 1293622620,
    5        "chainwork": "0000000000000000000000000000000000000000000000000644cb7f5234089e"
    6        "verificationprogress": 0.001,
    7    }
    8    ...
    9}
    
  10. polespinasa force-pushed on Aug 28, 2025
  11. polespinasa force-pushed on Aug 28, 2025
  12. polespinasa commented at 2:32 am on August 28, 2025: member
    @ajtowns sgtm, done. Not sure about the order thought… I’m open to suggestions.
  13. in src/rpc/blockchain.cpp:1339 in 8efdfa9035 outdated
    1335@@ -1336,6 +1336,15 @@ RPCHelpMan getblockchaininfo()
    1336                 {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
    1337                 {RPCResult::Type::NUM, "verificationprogress", "estimate of verification progress [0..1]"},
    1338                 {RPCResult::Type::BOOL, "initialblockdownload", "(debug information) estimate of whether this node is in Initial Block Download mode"},
    1339+                {RPCResult::Type::BOOL, "backgroundvalidation", "(debug information) estimate of whether this node is doing background validation"},
    


    ajtowns commented at 5:04 am on August 28, 2025:

    Can just drop this field, and use the presence/absence of the object to indicate where background validation is occurring?

    If not, “estimate of” isn’t accurate here – the node knows whether it’s doing background validation or not.


    polespinasa commented at 6:30 pm on August 28, 2025:
    I like to see false if it’s not in b validation. Fixed the “estimate of”
  14. in src/rpc/blockchain.cpp:1344 in 8efdfa9035 outdated
    1335@@ -1336,6 +1336,15 @@ RPCHelpMan getblockchaininfo()
    1336                 {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
    1337                 {RPCResult::Type::NUM, "verificationprogress", "estimate of verification progress [0..1]"},
    1338                 {RPCResult::Type::BOOL, "initialblockdownload", "(debug information) estimate of whether this node is in Initial Block Download mode"},
    1339+                {RPCResult::Type::BOOL, "backgroundvalidation", "(debug information) estimate of whether this node is doing background validation"},
    1340+                {RPCResult::Type::OBJ, "background", /*optional=*/true, "state info regarding background validation process",
    1341+                {
    1342+                    {RPCResult::Type::NUM, "blocks", /*optional=*/true, "the height of the most-work fully-background validated chain. The genesis block has height 0"},
    1343+                    {RPCResult::Type::STR, "bestblockhash", /*optional=*/true, "the hash of the currently best block validated in background"},
    1344+                    {RPCResult::Type::NUM_TIME, "mediantime", /*optional=*/true, "The median block time expressed in " + UNIX_EPOCH_TIME},
    


    ajtowns commented at 5:11 am on August 28, 2025:

    Could make it the instead of The for consistency with other options. Could consider doing the same for the main mediantime help text that this was copied from too.

    As far as ordering goes, probably copy the ordering of the fields in getblockchaininfo?


    polespinasa commented at 6:29 pm on August 28, 2025:
    done
  15. in src/rpc/blockchain.cpp:1397 in 8efdfa9035 outdated
    1392+        const CBlockIndex& btip{*CHECK_NONFATAL(chainman.GetBackgroundSyncTip())};
    1393+        bValidation.pushKV("blocks",btip.nHeight);
    1394+        bValidation.pushKV("bestblockhash", btip.GetBlockHash().GetHex());
    1395+        bValidation.pushKV("mediantime", btip.GetMedianTimePast());
    1396+        bValidation.pushKV("chainwork", btip.nChainWork.GetHex());
    1397+        bValidation.pushKV("verificationprogress", chainman.GuessVerificationProgress(&btip));
    


    ajtowns commented at 5:24 am on August 28, 2025:

    This is telling you how far the background has progressed if it were going to go all the way to the current tip; but it will actually stop when it hits the snapshot block. So I think this should be calling a new method chainman.GetBackgroundVerificationProgress(btip), something like:

    0double ChainstateManager::GetBackgroundVerificationProgress(const CBlockIndex* tip)
    1{
    2    if (tip == nullptr) return 0.0;
    3    auto base = GetSnapshotBaseBlock();
    4    if (base == nullptr || base->m_chain_tx_count == 0) return 0.0;
    5    return tip->m_chain_tx_count / base->m_chain_tc_count;
    6}
    

    polespinasa commented at 6:48 pm on August 28, 2025:

    That’s a good point, but that’s actually what we are showing in the logs. Do we want to keep consistency between both? Update maybe also the logging?

    [background validation] UpdateTip: new best=00000000000000000007b796179f5abb7eed59f736e3418eb8381c29eb78527a height=744000 version=0x20400004 log2_work=93.616004 tx=747106639 date='2022-07-07T14:47:25Z' progress=0.605933 cache=358.0MiB(2606151txo)

    In validation.cpp

    0constexpr int BACKGROUND_LOG_INTERVAL = 2000;
    1        if (pindexNew->nHeight % BACKGROUND_LOG_INTERVAL == 0) {
    2            UpdateTipLog(m_chainman, coins_tip, pindexNew, __func__, "[background validation] ", "");
    3        }
    
    0static void UpdateTipLog( ... const CBlockIndex* tip,...)
    1{
    2
    3   ...
    4                   FormatISO8601DateTime(tip->GetBlockTime()),
    5                   chainman.GuessVerificationProgress(tip),
    6   ...
    7}
    

    polespinasa commented at 10:07 pm on September 3, 2025:
    Implemented the new method and used it also in the logs
  16. in test/functional/rpc_blockchain.py:176 in 8efdfa9035 outdated
    170@@ -170,6 +171,10 @@ def _test_getblockchaininfo(self):
    171         assert res['pruned']
    172         assert not res['automatic_pruning']
    173 
    174+        # check background validation
    175+        assert not res['backgroundvalidation']
    176+        assert "background" not in res.keys()
    


    ajtowns commented at 5:29 am on August 28, 2025:
    Should be able to test the field-exists case via feature_assumeutxo.py probably just prior to the invocation of n1.submitblock(snapshot_block)

    polespinasa commented at 9:19 pm on August 28, 2025:
    do we want to test that in feature_assumeutxo.py or in rpc_blockchain.py

    polespinasa commented at 10:36 pm on September 3, 2025:
    done in a48d92a5fb4c443dbf615715c8f25d1de9cabc9e
  17. polespinasa force-pushed on Aug 28, 2025
  18. polespinasa force-pushed on Aug 28, 2025
  19. polespinasa force-pushed on Aug 28, 2025
  20. polespinasa commented at 9:00 pm on August 28, 2025: member

    2d48902999a7ad1fcf19a8e630c69d6228dbd373 added snapshot height

    83a1721817fda4db88ba12e0395ed63ba064c41b modify the way verification progress is calculated for background validation -> context: #33259 (review)

  21. polespinasa force-pushed on Aug 28, 2025
  22. polespinasa force-pushed on Aug 28, 2025
  23. in src/rpc/blockchain.cpp:1342 in 2d48902999 outdated
    1340                 {RPCResult::Type::NUM, "verificationprogress", "estimate of verification progress [0..1]"},
    1341                 {RPCResult::Type::BOOL, "initialblockdownload", "(debug information) estimate of whether this node is in Initial Block Download mode"},
    1342+                {RPCResult::Type::BOOL, "backgroundvalidation", "(debug information) whether this node is doing background validation"},
    1343+                {RPCResult::Type::OBJ, "background", /*optional=*/true, "state info regarding background validation process",
    1344+                {
    1345+                    {RPCResult::Type::NUM, "snapshotheight", /*optional=*/true, "the heigh of the snapshot block"},
    


    maflcko commented at 10:56 am on August 29, 2025:
    "the heigh of the snapshot block" -> "the height of the snapshot block" [spelling error: "heigh" should be "height"]
    
  24. in src/validation.h:1167 in 2d48902999 outdated
    1162@@ -1163,6 +1163,9 @@ class ChainstateManager
    1163     /** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */
    1164     double GuessVerificationProgress(const CBlockIndex* pindex) const EXCLUSIVE_LOCKS_REQUIRED(GetMutex());
    1165 
    1166+    /** Guess background verification progress in case assume utxo was used (as a fraction between 0.0=genesis and 1.0=snapshot blocks). */
    1167+    double GetBackgroundVerificationProgress(const CBlockIndex* pindex) const EXCLUSIVE_LOCKS_REQUIRED(GetMutex());
    


    maflcko commented at 10:59 am on August 29, 2025:
    0    /** Guess background verification progress in case assume-utxo was used (as a fraction between 0.0=genesis and 1.0=snapshot blocks). */
    1    double GetBackgroundVerificationProgress(const CBlockIndex& block) const EXCLUSIVE_LOCKS_REQUIRED(GetMutex());
    

    can remove the unused nullptr handling here, as all call-sites already dereferenced the pointer


    polespinasa commented at 7:49 pm on August 29, 2025:
    Done
  25. log: update progress calculations for background validation
    updates estimations to the block snapshot instead of the main chain tip as it will stop validation after reaching that height
    471092ca98
  26. rpc, log: add backgroundvalidation to getblockchaininfo 01860ea0e5
  27. polespinasa force-pushed on Aug 29, 2025
  28. danielabrozzoni commented at 2:35 pm on September 2, 2025: member

    Concept ACK

    I did a very rough first pass and the code looks good to me. As others have said, I would like to see a functional test testing the newly introduced fields when the background validation is in progress

  29. polespinasa force-pushed on Sep 3, 2025
  30. polespinasa commented at 10:08 pm on September 3, 2025: member

    @danielabrozzoni @ajtowns @luke-jr

    Tests implemented, not the cleanest way for sure, but I couldn’t figure out anything simpler. Open to suggestions :)

  31. polespinasa requested review from danielabrozzoni on Sep 3, 2025
  32. polespinasa requested review from ajtowns on Sep 3, 2025
  33. polespinasa requested review from luke-jr on Sep 3, 2025
  34. in test/functional/feature_assumeutxo.py:522 in a48d92a5fb outdated
    518@@ -518,6 +519,28 @@ def check_dump_output(output):
    519         assert_equal(utxo_info['height'], SNAPSHOT_BASE_HEIGHT)
    520         assert_equal(utxo_info['bestblock'], snapshot_hash)
    521 
    522+        self.log.info("Check that getblockchaininfo returns information about the background validaiton process")
    


    BinaryIgor commented at 5:17 pm on September 9, 2025:
    nit: typo, should be “validation”

    polespinasa commented at 5:22 pm on September 15, 2025:
    thanks 👍
  35. in test/functional/feature_assumeutxo.py:532 in a48d92a5fb outdated
    527+            "mediantime",
    528+            "chainwork",
    529+            "verificationprogress"
    530+        ]
    531+        res = n1.getblockchaininfo()
    532+        assert "background" in res.keys()
    


    BinaryIgor commented at 5:24 pm on September 9, 2025:
    As this already is a rather too long test, it would be nice to move these assertions into a separate method, similarly as it done with check_tx_counts

    polespinasa commented at 5:23 pm on September 15, 2025:
    I don’t think that’s useful. The test is not much longer than others and check_tx_counts is separated in a function because it’s called multiple times with different values of final. In this case there’s no duplicated code.
  36. test: add background validation test for getblockchaininfo 21fb4c949c
  37. polespinasa force-pushed on Sep 15, 2025
  38. polespinasa commented at 5:23 pm on September 15, 2025: member
    21fb4c949cebf3510dad3dc3827ccb9451e4828d correct typos
  39. DrahtBot added the label Needs rebase on Dec 16, 2025
  40. DrahtBot commented at 3:33 pm on December 16, 2025: contributor
    🐙 This pull request conflicts with the target branch and needs rebase.

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-12-21 12:12 UTC

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