chainstatemanager_args.cpp raw

   1  // Copyright (c) 2022-present The Bitcoin Core developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #include <node/chainstatemanager_args.h>
   6  
   7  #include <arith_uint256.h>
   8  #include <common/args.h>
   9  #include <common/system.h>
  10  #include <node/coins_view_args.h>
  11  #include <node/database_args.h>
  12  #include <tinyformat.h>
  13  #include <uint256.h>
  14  #include <util/byte_units.h>
  15  #include <util/log.h>
  16  #include <util/result.h>
  17  #include <util/strencodings.h>
  18  #include <util/translation.h>
  19  #include <validation.h>
  20  
  21  #include <algorithm>
  22  #include <chrono>
  23  #include <string>
  24  
  25  namespace node {
  26  util::Result<void> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts)
  27  {
  28      if (auto value{args.GetIntArg("-checkblockindex")}) {
  29          // Interpret bare -checkblockindex argument as 1 instead of 0.
  30          opts.check_block_index = args.GetArg("-checkblockindex")->empty() ? 1 : *value;
  31      }
  32  
  33      if (auto value{args.GetArg("-minimumchainwork")}) {
  34          if (auto min_work{uint256::FromUserHex(*value)}) {
  35              opts.minimum_chain_work = UintToArith256(*min_work);
  36          } else {
  37              return util::Error{Untranslated(strprintf("Invalid minimum work specified (%s), must be up to %d hex digits", *value, uint256::size() * 2))};
  38          }
  39      }
  40  
  41      if (auto value{args.GetArg("-assumevalid")}) {
  42          if (auto block_hash{uint256::FromUserHex(*value)}) {
  43              opts.assumed_valid_block = *block_hash;
  44          } else {
  45              return util::Error{Untranslated(strprintf("Invalid assumevalid block hash specified (%s), must be up to %d hex digits (or 0 to disable)", *value, uint256::size() * 2))};
  46          }
  47      }
  48  
  49      if (auto value{args.GetIntArg("-maxtipage")}) opts.max_tip_age = std::chrono::seconds{*value};
  50  
  51      ReadDatabaseArgs(args, opts.coins_db);
  52      ReadCoinsViewArgs(args, opts.coins_view);
  53  
  54      int script_threads = args.GetIntArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
  55      if (script_threads <= 0) {
  56          // -par=0 means autodetect (number of cores - 1 script threads)
  57          // -par=-n means "leave n cores free" (number of cores - n - 1 script threads)
  58          script_threads += GetNumCores();
  59      }
  60      // Subtract 1 because the main thread counts towards the par threads.
  61      opts.worker_threads_num = script_threads - 1;
  62  
  63      if (auto value{args.GetArg<int32_t>("-prevoutfetchthreads")}) {
  64          if (*value < 0) {
  65              return util::Error{Untranslated(strprintf("-prevoutfetchthreads must be non-negative (got %d). Use 0 to disable parallel input fetching.", *value))};
  66          }
  67          opts.prevoutfetch_threads_num = std::min(*value, MAX_PREVOUTFETCH_THREADS);
  68      }
  69  
  70      if (auto max_size = args.GetIntArg("-maxsigcachesize")) {
  71          // 1. When supplied with a max_size of 0, both the signature cache and
  72          //    script execution cache create the minimum possible cache (2
  73          //    elements). Therefore, we can use 0 as a floor here.
  74          // 2. Multiply first, divide after to avoid integer truncation.
  75          size_t clamped_size_each{size_t(std::max<int64_t>(*max_size, 0) * 1_MiB / 2)};
  76          opts.script_execution_cache_bytes = clamped_size_each;
  77          opts.signature_cache_bytes = clamped_size_each;
  78      }
  79  
  80      return {};
  81  }
  82  } // namespace node
  83