Add warning on first startup if free disk space is less than necessary #25315

pull Empact wants to merge 1 commits into bitcoin:master from Empact:disk-space-check changing 3 files +22 −6
  1. Empact commented at 9:08 PM on June 8, 2022: member

    This reworks/revives #15848 to add a check for low disk space on first startup and issue a warning if disk space is below the expected space required to accommodate the blocks.

    This PR was fashioned by a team of developers at the bitcoin++ conference workshop: "Let's contribute to Bitcoin Core"

    Fixes #15813

  2. Empact force-pushed on Jun 8, 2022
  3. Empact force-pushed on Jun 8, 2022
  4. Empact force-pushed on Jun 8, 2022
  5. litch commented at 11:44 AM on June 9, 2022: contributor

    Confirmed this in an underpowered VM. I know it was discussed to use a warning instead of an error. I think that a warning, however, should probably not terminate the process. So perhaps it would be better to change this function to return true after emitting the warning.

    2022-06-09T11:42:03Z init message: Verifying blocks…
    2022-06-09T11:42:03Z  block index             463ms
    2022-06-09T11:42:03Z Warning: Disk space for "/home/litch/.bitcoin/blocks" may not accommodate the block files
    Warning: Disk space for "/home/litch/.bitcoin/blocks" may not accommodate the block files
    2022-06-09T11:42:03Z Shutdown: In progress...
    2022-06-09T11:42:03Z scheduler thread exit
    2022-06-09T11:42:03Z Shutdown: done
    litch@bitcoind-test:~/bitcoin$
    
  6. Empact force-pushed on Jun 9, 2022
  7. Empact commented at 1:58 PM on June 9, 2022: member

    So perhaps it would be better to change this function to return true after emitting the warning.

    Well thanks for testing - in this case we don't need to return at all, as the intention is to note the issue and carry on. Removed the return statement.

  8. Empact force-pushed on Jun 9, 2022
  9. in src/init.cpp:1643 in 5fa1f763f8 outdated
    1645 | +              : chainparams.AssumedBlockchainSize() * GIB_BYTES;
    1646 | +        }
    1647 | +    }
    1648 | +    if (!CheckDiskSpace(gArgs.GetBlocksDirPath(), additional_bytes_needed)) {
    1649 | +        InitWarning(strprintf(_("Disk space for %s may not accommodate the block files"),
    1650 | +          fs::quoted(fs::PathToString(gArgs.GetBlocksDirPath())))
    


    maflcko commented at 2:20 PM on June 9, 2022:

    would be nice to use args (the local reference) over gArgs (the global) for new code


    Empact commented at 2:50 PM on June 9, 2022:

    👍

  10. Empact force-pushed on Jun 9, 2022
  11. Empact force-pushed on Jun 9, 2022
  12. Empact force-pushed on Jun 9, 2022
  13. Empact force-pushed on Jun 9, 2022
  14. litch commented at 3:48 PM on June 9, 2022: contributor
    ...
    2022-06-09T15:43:48Z Initializing databases...
    2022-06-09T15:43:48Z Opening LevelDB in /home/litch/.bitcoin/chainstate
    2022-06-09T15:43:49Z Opened LevelDB successfully
    2022-06-09T15:43:49Z Wrote new obfuscate key for /home/litch/.bitcoin/chainstate: 5da37d724c848cd8
    2022-06-09T15:43:49Z Using obfuscation key for /home/litch/.bitcoin/chainstate: 5da37d724c848cd8
    2022-06-09T15:43:49Z init message: Verifying blocks…
    2022-06-09T15:43:49Z  block index            1014ms
    2022-06-09T15:43:49Z Warning: Disk space for "/home/litch/.bitcoin/blocks" may not accommodate the block files. Approximately 460 GB of data will be stored in this directory.
    Warning: Disk space for "/home/litch/.bitcoin/blocks" may not accommodate the block files. Approximately 460 GB of data will be stored in this directory.
    2022-06-09T15:43:49Z loadblk thread start
    2022-06-09T15:43:49Z UpdateTip: new best=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f height=0 version=0x00000001 log2_work=32.000022 tx=1 date='2009-01-03T18:15:05Z' progr
    ess=0.000000 cache=0.0MiB(0txo)
    2022-06-09T15:43:49Z Failed to open mempool file from disk. Continuing anyway.
    2022-06-09T15:43:49Z loadblk thread exit
    2022-06-09T15:43:49Z block tree size = 1
    ...
    

    When running on a VM with a small HDD, this prints the warning as expected.

    After downloading a number of blocks, then re-starting bitcoind, the warning is not re-emitted.

  15. in src/init.cpp:1637 in 82533930cc outdated
    1632 | @@ -1633,6 +1633,25 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
    1633 |          return false;
    1634 |      }
    1635 |  
    1636 | +    uint64_t additional_bytes_needed = 0;
    1637 | +    if (!fReindex) {
    


    mzumsande commented at 3:57 PM on June 9, 2022:

    I think the reason for this is that fReindex sets back the height to 0 without deleting blocks (to rebuild the chain later in init), so that it would be wrong to give a warning that doesn't account for the already downloaded blocks. But in that case, I think that this should also be skipped for fReindexChainState, for the same reason.


    Empact commented at 5:44 AM on June 16, 2022:

    While I'm not able to confirm your point, disabling the check in that case seems prudent as this check is intended for the common case.

  16. Empact force-pushed on Jun 16, 2022
  17. Empact force-pushed on Jun 16, 2022
  18. Empact commented at 5:46 AM on June 16, 2022: member

    Disabled the warning on fReindexChainState, and reworked it to avoid duplicative check in the cases where additional_bytes_needed would be 0.

  19. Empact force-pushed on Jun 16, 2022
  20. Empact force-pushed on Jun 16, 2022
  21. Empact commented at 6:00 AM on June 16, 2022: member

    Moved the check further down initialization, to the point where chain_active_height was already being read, so we don't need to do any new locking - a question to test is: will the height be the appropriate value at this time in the startup?

  22. Empact force-pushed on Jun 16, 2022
  23. luke-jr commented at 5:37 PM on June 18, 2022: member

    Concept ACK (as a warning only).

  24. achow101 commented at 8:52 PM on June 20, 2022: member

    I don't think the current location in initialization is correct. ~50 lines above, we start the thread for importing blocks from an external file. This thread will be copying the blocks from the external file to our datadir and then put them all into the block index. It additionally does not do ActivateBestChain until after all of the blocks have been loaded, so we could end up in a similar scenario as a reindex - all the blocks are written but the height still remains 0.

    We need to be checking the disk space before -loadblk is handled so that we can know whether we have enough disk space before we begin loading blocks from the external file(s).

  25. DrahtBot commented at 12:54 AM on June 21, 2022: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK achow101, aureleoules, willcl-ark
    Concept ACK hernanmarino, luke-jr, pablomartin4btc

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    No conflicts as of last run.

  26. hernanmarino commented at 5:24 PM on August 5, 2022: contributor

    I agree with @achow101 I believe this should be done earlier.

  27. pablomartin4btc commented at 5:30 PM on August 5, 2022: member

    As @hernanmarino and @achow101, perhaps we could move that validation after the other 2 that also check disk space? (around line 1635)

  28. Empact force-pushed on Aug 8, 2022
  29. Empact commented at 5:32 AM on August 8, 2022: member

    As suggested, moved the check back to being alongside the other disk space checks.

  30. hernanmarino approved
  31. hernanmarino commented at 2:58 PM on August 8, 2022: contributor

    Code review ACK bba667e

  32. Empact commented at 3:56 PM on August 8, 2022: member

    Will need some accommodation for the tests - ignoring the message perhaps?:

    test 2022-08-08T06:47:18.274000Z TestFramework (ERROR): Assertion failed Traceback (most recent call last): File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/test_framework.py", line 133, in main self.run_test() File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/wallet_crosschain.py", line 53, in run_test self.stop_nodes() File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/test_framework.py", line 567, in stop_nodes node.stop_node(wait=wait, wait_until_stopped=False) File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/test_node.py", line 350, in stop_node raise AssertionError("Unexpected stderr {} != {}".format(stderr, expected_stderr)) AssertionError: Unexpected stderr Warning: Disk space for "/tmp/cirrus-ci-build/ci/scratch/test_runner/test_runner_₿_🏃_20220808_063508/wallet_crosschain_80/node1/testnet3/blocks" may not accommodate the block files. Approximately 40 GB of data will be stored in this directory. !=

    https://cirrus-ci.com/task/5510419358941184?logs=ci#L4359

  33. pablomartin4btc approved
  34. pablomartin4btc commented at 7:18 PM on August 8, 2022: member

    Core review ACK.

    And it works as expected, only displaying the warning the first time before we start loading blocks.

    2022-08-08T19:01:43Z Opening LevelDB in /tmp/btc/chainstate
    2022-08-08T19:01:43Z Opened LevelDB successfully
    2022-08-08T19:01:43Z Wrote new obfuscate key for /tmp/btc/chainstate: f4392c646d173853
    2022-08-08T19:01:43Z Using obfuscation key for /tmp/btc/chainstate: f4392c646d173853
    2022-08-08T19:01:43Z init message: Verifying blocks…
    2022-08-08T19:01:43Z  block index              82ms
    2022-08-08T19:01:43Z Warning: Disk space for "/tmp/btc/blocks" may not accommodate the block files. Approximately 460 GB of data will be stored in this directory.
    2022-08-08T19:02:24Z loadblk thread start
    2022-08-08T19:02:24Z UpdateTip: new best=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f height=0 version=0x00000001 log2_work=32.000022 tx=1 date='2009-01-03T18:15:05Z' progress=0.000000 cache=0.0MiB(0txo)
    2022-08-08T19:02:24Z block tree size = 1
    2022-08-08T19:02:24Z nBestHeight = 0
    2022-08-08T19:02:24Z Failed to open mempool file from disk. Continuing anyway.
    2022-08-08T19:02:24Z loadblk thread exit
    

    Also on the UI:

    image

  35. pablomartin4btc commented at 10:08 AM on August 9, 2022: member

    @Empact, I also get these 2 funtional tests failing when I run them locally (they pass on the master):

    image

  36. aureleoules commented at 4:53 PM on September 21, 2022: member

    Concept and Code Review ACK bba667e0701090180c0c3b7d2903a8a74e9875f7. I also verified that the warning is shown.

    CI fails because the tests p2p_dos_header_tree.py and wallet_crosschain.py try to spawn a testnet chain, which would be too big for the CI and creates an output on stderr which should not happen.

    <details> <summary>This fix works on my machine but I haven't tested in CI: </summary>

    diff --git a/test/functional/p2p_dos_header_tree.py b/test/functional/p2p_dos_header_tree.py
    index fde1e4bfa..922e65036 100755
    --- a/test/functional/p2p_dos_header_tree.py
    +++ b/test/functional/p2p_dos_header_tree.py
    @@ -22,6 +22,7 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework):
             self.setup_clean_chain = True
             self.chain = 'testnet3'  # Use testnet chain because it has an early checkpoint
             self.num_nodes = 2
    +        self.extra_args = [['-prune=550']] * self.num_nodes
     
         def add_options(self, parser):
             parser.add_argument(
    @@ -62,7 +63,7 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework):
     
             self.log.info("Feed all fork headers (succeeds without checkpoint)")
             # On node 0 it succeeds because checkpoints are disabled
    -        self.restart_node(0, extra_args=['-nocheckpoints'])
    +        self.restart_node(0, extra_args=['-nocheckpoints', '-prune=550'])
             peer_no_checkpoint = self.nodes[0].add_p2p_connection(P2PInterface())
             peer_no_checkpoint.send_and_ping(msg_headers(self.headers_fork))
             assert {
    diff --git a/test/functional/wallet_crosschain.py b/test/functional/wallet_crosschain.py
    index b6d0c8798..c0047542e 100755
    --- a/test/functional/wallet_crosschain.py
    +++ b/test/functional/wallet_crosschain.py
    @@ -21,7 +21,7 @@ class WalletCrossChain(BitcoinTestFramework):
     
             # Switch node 1 to testnet before starting it.
             self.nodes[1].chain = 'testnet3'
    -        self.nodes[1].extra_args = ['-maxconnections=0'] # disable testnet sync
    +        self.nodes[1].extra_args = ['-maxconnections=0', '-prune=550'] # disable testnet sync
             with open(self.nodes[1].bitcoinconf, 'r', encoding='utf8') as conf:
                 conf_data = conf.read()
             with open (self.nodes[1].bitcoinconf, 'w', encoding='utf8') as conf:
    @@ -51,7 +51,7 @@ class WalletCrossChain(BitcoinTestFramework):
             if not self.options.descriptors:
                 self.log.info("Override cross-chain wallet load protection")
                 self.stop_nodes()
    -            self.start_nodes([['-walletcrosschain']] * self.num_nodes)
    +            self.start_nodes([['-walletcrosschain', '-prune=550']] * self.num_nodes)
                 self.nodes[0].loadwallet(node1_wallet)
                 self.nodes[1].loadwallet(node0_wallet)
    

    </details>

    EDIT: it works in CI as well

  37. Empact force-pushed on Oct 10, 2022
  38. Empact force-pushed on Oct 10, 2022
  39. Empact force-pushed on Oct 10, 2022
  40. Add warning on first startup if free disk space is less than necessary
    To accommodate the expected blocks data.
    
    Co-authored-by: Antoine Poinsot <darosior@protonmail.com>
    Co-authored-by: benthecarman <benthecarman@live.com>
    Co-authored-by: Justin Litchfield <litch@me.com>
    Co-authored-by: Liran Cohen <c.liran.c@gmail.com>
    Co-authored-by: Ryan Loomba <ryan.loomba@gmail.com>
    Co-authored-by: Buck Perley <bucko.perley@gmail.com>
    Co-authored-by: bajjer <bajjer@bajjer.xyz>
    Co-authored-by: Suhail Saqan <suhail.saqan@gmail.com>
    Co-authored-by: Christopher Sweeney <sweeney.chris@gmail.com>
    Co-authored-by: Alyssa <orbitalturtle@protonmail.com>
    Co-authored-by: Ben Schroth <ben@styng.social>
    Co-authored-by: Jason Hester <mail@jason-hester.me>
    Co-authored-by: Matt Clough <Matt.clough@pm.me>
    Co-authored-by: Elise Schedler <eliseschedler@gmail.com>
    Co-authored-by: ghander <cen254@gmail.com>
    Co-authored-by: PopeLaz <btclz@fastmail.com>
    Co-authored-by: Aurèle Oulès <hello@aureleoules.com>
    6630a1e844
  41. Empact force-pushed on Oct 10, 2022
  42. aureleoules approved
  43. aureleoules commented at 5:06 PM on October 11, 2022: member

    ACK 6630a1e8448c633e4abaa8f5903f11cac6f433a7

  44. glozow requested review from mzumsande on Oct 12, 2022
  45. achow101 commented at 7:31 PM on October 12, 2022: member
  46. achow101 commented at 10:45 PM on October 25, 2022: member

    ACK 6630a1e8448c633e4abaa8f5903f11cac6f433a7

  47. willcl-ark commented at 8:45 PM on November 17, 2022: member

    tACK 6630a1e8448c633e4abaa8f5903f11cac6f433a7 rebased on master. Warning shows on first start but not on restart after some blocks have been downloaded.

  48. hernanmarino approved
  49. achow101 merged this on Nov 18, 2022
  50. achow101 closed this on Nov 18, 2022

  51. sidhujag referenced this in commit cdc7c7d7a3 on Nov 18, 2022
  52. Empact commented at 5:54 PM on November 18, 2022: member

    Thanks to all the reviewers and contributors. For posterity, here's the original session in which this was written: https://youtu.be/tRXIkqM8gSI

  53. bitcoin locked this on Jun 10, 2024

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

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