chainparams.cpp raw

   1  // Copyright (c) 2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-2022 The Limenka developers
   3  // Distributed under the MIT software license, see the accompanying
   4  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  
   6  #include <chainparams.h>
   7  
   8  #include <chainparamsbase.h>
   9  #include <common/args.h>
  10  #include <consensus/params.h>
  11  #include <deploymentinfo.h>
  12  #include <kernel/chainparams.h>
  13  #include <logging.h>
  14  #include <tinyformat.h>
  15  #include <util/chaintype.h>
  16  #include <util/strencodings.h>
  17  #include <util/string.h>
  18  
  19  #include <cassert>
  20  #include <cstdint>
  21  #include <limits>
  22  #include <stdexcept>
  23  #include <vector>
  24  
  25  using util::SplitString;
  26  
  27  void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options)
  28  {
  29      if (!args.GetArgs("-signetseednode").empty()) {
  30          options.seeds.emplace(args.GetArgs("-signetseednode"));
  31      }
  32      if (!args.GetArgs("-signetchallenge").empty()) {
  33          const auto signet_challenge = args.GetArgs("-signetchallenge");
  34          if (signet_challenge.size() != 1) {
  35              throw std::runtime_error("-signetchallenge cannot be multiple values.");
  36          }
  37          const auto val{TryParseHex<uint8_t>(signet_challenge[0])};
  38          if (!val) {
  39              throw std::runtime_error(strprintf("-signetchallenge must be hex, not '%s'.", signet_challenge[0]));
  40          }
  41          options.challenge.emplace(*val);
  42      }
  43      if (const auto signetblocktime{args.GetIntArg("-signetblocktime")}) {
  44          if (!args.IsArgSet("-signetchallenge")) {
  45              throw std::runtime_error("-signetblocktime cannot be set without -signetchallenge");
  46          }
  47          if (*signetblocktime <= 0) {
  48              throw std::runtime_error("-signetblocktime must be greater than 0");
  49          }
  50          options.pow_target_spacing = *signetblocktime;
  51      }
  52  }
  53  
  54  void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options)
  55  {
  56      if (auto value = args.GetBoolArg("-fastprune")) options.fastprune = *value;
  57      if (HasTestOption(args, "bip94")) options.enforce_bip94 = true;
  58  
  59      for (const std::string& arg : args.GetArgs("-testactivationheight")) {
  60          const auto found{arg.find('@')};
  61          if (found == std::string::npos) {
  62              throw std::runtime_error(strprintf("Invalid format (%s) for -testactivationheight=name@height.", arg));
  63          }
  64  
  65          const auto value{arg.substr(found + 1)};
  66          int32_t height;
  67          if (!ParseInt32(value, &height) || height < 0 || height >= std::numeric_limits<int>::max()) {
  68              throw std::runtime_error(strprintf("Invalid height value (%s) for -testactivationheight=name@height.", arg));
  69          }
  70  
  71          const auto deployment_name{arg.substr(0, found)};
  72          if (const auto buried_deployment = GetBuriedDeployment(deployment_name)) {
  73              options.activation_heights[*buried_deployment] = height;
  74          } else {
  75              throw std::runtime_error(strprintf("Invalid name (%s) for -testactivationheight=name@height.", arg));
  76          }
  77      }
  78  
  79      for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
  80          std::vector<std::string> vDeploymentParams = SplitString(strDeployment, ':');
  81          if (vDeploymentParams.size() < 3 || 7 < vDeploymentParams.size()) {
  82              throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height[:max_activation_height[:active_duration[:threshold]]]]");
  83          }
  84          CChainParams::VersionBitsParameters vbparams{};
  85          if (!ParseInt64(vDeploymentParams[1], &vbparams.start_time)) {
  86              throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
  87          }
  88          if (!ParseInt64(vDeploymentParams[2], &vbparams.timeout)) {
  89              throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
  90          }
  91          if (vDeploymentParams.size() >= 4) {
  92              if (!ParseInt32(vDeploymentParams[3], &vbparams.min_activation_height)) {
  93                  throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3]));
  94              }
  95          } else {
  96              vbparams.min_activation_height = 0;
  97          }
  98          if (vDeploymentParams.size() >= 5) {
  99              if (!ParseInt32(vDeploymentParams[4], &vbparams.max_activation_height)) {
 100                  throw std::runtime_error(strprintf("Invalid max_activation_height (%s)", vDeploymentParams[4]));
 101              }
 102          }
 103          if (vDeploymentParams.size() >= 6) {
 104              if (!ParseInt32(vDeploymentParams[5], &vbparams.active_duration)) {
 105                  throw std::runtime_error(strprintf("Invalid active_duration (%s)", vDeploymentParams[5]));
 106              }
 107          }
 108          if (vDeploymentParams.size() >= 7) {
 109              if (!ParseInt32(vDeploymentParams[6], &vbparams.threshold)) {
 110                  throw std::runtime_error(strprintf("Invalid threshold (%s)", vDeploymentParams[6]));
 111              }
 112          }
 113          // Validate that timeout and max_activation_height are mutually exclusive
 114          if (vbparams.timeout != Consensus::BIP9Deployment::NO_TIMEOUT && vbparams.max_activation_height < std::numeric_limits<int>::max()) {
 115              throw std::runtime_error(strprintf("Cannot specify both timeout (%ld) and max_activation_height (%d) for deployment %s. Use timeout for BIP9 or max_activation_height for mandatory activation deadline, not both.", vbparams.timeout, vbparams.max_activation_height, vDeploymentParams[0]));
 116          }
 117          bool found = false;
 118          for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
 119              if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
 120                  options.version_bits_parameters[Consensus::DeploymentPos(j)] = vbparams;
 121                  found = true;
 122                  LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%d, max_activation_height=%d, active_duration=%d, threshold=%d\n", vDeploymentParams[0], vbparams.start_time, vbparams.timeout, vbparams.min_activation_height, vbparams.max_activation_height, vbparams.active_duration, vbparams.threshold);
 123                  break;
 124              }
 125          }
 126          if (!found) {
 127              throw std::runtime_error(strprintf("Invalid deployment (%s)", vDeploymentParams[0]));
 128          }
 129      }
 130  }
 131  
 132  static std::unique_ptr<const CChainParams> globalChainParams;
 133  
 134  const CChainParams &Params() {
 135      assert(globalChainParams);
 136      return *globalChainParams;
 137  }
 138  
 139  std::unique_ptr<const CChainParams> CreateChainParams(const ArgsManager& args, const ChainType chain)
 140  {
 141      g_rdts_consent = static_cast<RDTSConsentFlag>(args.GetIntArg("rdts_consent_flag", static_cast<int64_t>(g_rdts_consent)));
 142      g_enable_rdts = g_rdts_consent != RDTSConsentFlag::UNSUPPORTED_UNSAFE_NO_ENFORCEMENT;
 143      if (g_rdts_consent == RDTSConsentFlag::UNSUPPORTED_UNSAFE_NO_ENFORCEMENT && !g_enable_rdts) {
 144          for (const auto& rulesok : args.GetArgs(CONSENSUSRULES_CONFIG_NAME)) {
 145              if (rulesok == CONSENSUSRULES_REQUIRED) {
 146                  g_enable_rdts = true;
 147                  break;
 148              }
 149          }
 150      }
 151  
 152      switch (chain) {
 153      case ChainType::MAIN:
 154          return CChainParams::Main();
 155      case ChainType::TESTNET:
 156          return CChainParams::TestNet();
 157      case ChainType::TESTNET4:
 158          return CChainParams::TestNet4();
 159      case ChainType::SIGNET: {
 160          auto opts = CChainParams::SigNetOptions{};
 161          ReadSigNetArgs(args, opts);
 162          return CChainParams::SigNet(opts);
 163      }
 164      case ChainType::REGTEST: {
 165          auto opts = CChainParams::RegTestOptions{};
 166          ReadRegTestArgs(args, opts);
 167          return CChainParams::RegTest(opts);
 168      }
 169      case ChainType::FORK: {
 170          auto params = CChainParams::Fork();
 171          if (auto mtp = args.GetIntArg("-forkactivationtime")) {
 172              const_cast<Consensus::Params&>(params->GetConsensus()).nForkActivationMTP = *mtp;
 173          }
 174          if (auto steps = args.GetIntArg("-forkdelaysteps")) {
 175              const_cast<Consensus::Params&>(params->GetConsensus()).nForkDelaySteps = *steps;
 176          }
 177          if (args.GetBoolArg("-forkmineondemand", false)) {
 178              // Test/launch mining: fixed regtest-class powLimit, no
 179              // retargeting, mine via generatetoaddress.  Used by the
 180              // functional test and for bootstrapping the testnet's
 181              // first blocks.
 182              const_cast<Consensus::Params&>(params->GetConsensus()).fPowNoRetargeting = true;
 183              const_cast<Consensus::Params&>(params->GetConsensus()).powLimit = uint256{"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"};
 184          }
 185          if (args.GetBoolArg("-forkstandalone", false)) {
 186              // Standalone chain (testnet deployment): fresh chain from
 187              // the fork's own genesis, no parent-chain bootstrap.  Zero
 188              // the inherited mainnet chain-work/assumevalid so the node
 189              // leaves IBD at genesis instead of waiting for the
 190              // parent's cumulative work, and drop the inherited mainnet
 191              // checkpoints (a fresh chain can never match their hashes).
 192              const_cast<Consensus::Params&>(params->GetConsensus()).nMinimumChainWork = uint256{};
 193              const_cast<Consensus::Params&>(params->GetConsensus()).defaultAssumeValid = uint256{};
 194              params->ClearCheckpoints();
 195          }
 196          return params;
 197      }
 198      }
 199      assert(false);
 200  }
 201  
 202  void SelectParams(const ChainType chain)
 203  {
 204      SelectBaseParams(chain);
 205      globalChainParams = CreateChainParams(gArgs, chain);
 206  }
 207