chainparams.cpp raw

   1  // Copyright (c) 2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-present The Bitcoin Core 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 <tinyformat.h>
  13  #include <util/chaintype.h>
  14  #include <util/log.h>
  15  #include <util/strencodings.h>
  16  #include <util/string.h>
  17  
  18  #include <cassert>
  19  #include <cstdint>
  20  #include <limits>
  21  #include <stdexcept>
  22  #include <vector>
  23  
  24  using util::SplitString;
  25  
  26  static void HandleDeploymentArgs(const ArgsManager& args, CChainParams::DeploymentOptions& options)
  27  {
  28      for (const std::string& arg : args.GetArgs("-testactivationheight")) {
  29          const auto found{arg.find('@')};
  30          if (found == std::string::npos) {
  31              throw std::runtime_error(strprintf("Invalid format (%s) for -testactivationheight=name@height.", arg));
  32          }
  33  
  34          const auto value{arg.substr(found + 1)};
  35          const auto height{ToIntegral<int32_t>(value)};
  36          if (!height || *height < 0 || *height >= std::numeric_limits<int>::max()) {
  37              throw std::runtime_error(strprintf("Invalid height value (%s) for -testactivationheight=name@height.", arg));
  38          }
  39  
  40          const auto deployment_name{arg.substr(0, found)};
  41          if (const auto buried_deployment = GetBuriedDeployment(deployment_name)) {
  42              options.activation_heights[*buried_deployment] = *height;
  43          } else {
  44              throw std::runtime_error(strprintf("Invalid name (%s) for -testactivationheight=name@height.", arg));
  45          }
  46      }
  47  
  48      for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
  49          std::vector<std::string> vDeploymentParams = SplitString(strDeployment, ':');
  50          if (vDeploymentParams.size() < 3 || 4 < vDeploymentParams.size()) {
  51              throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height]");
  52          }
  53          CChainParams::VersionBitsParameters vbparams{};
  54          const auto start_time{ToIntegral<int64_t>(vDeploymentParams[1])};
  55          if (!start_time) {
  56              throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
  57          }
  58          vbparams.start_time = *start_time;
  59          const auto timeout{ToIntegral<int64_t>(vDeploymentParams[2])};
  60          if (!timeout) {
  61              throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
  62          }
  63          vbparams.timeout = *timeout;
  64          if (vDeploymentParams.size() >= 4) {
  65              const auto min_activation_height{ToIntegral<int64_t>(vDeploymentParams[3])};
  66              if (!min_activation_height) {
  67                  throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3]));
  68              }
  69              vbparams.min_activation_height = *min_activation_height;
  70          } else {
  71              vbparams.min_activation_height = 0;
  72          }
  73          bool found = false;
  74          for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
  75              if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
  76                  options.version_bits_parameters[Consensus::DeploymentPos(j)] = vbparams;
  77                  found = true;
  78                  LogInfo("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%d",
  79                          vDeploymentParams[0], vbparams.start_time, vbparams.timeout, vbparams.min_activation_height);
  80                  break;
  81              }
  82          }
  83          if (!found) {
  84              throw std::runtime_error(strprintf("Invalid deployment (%s)", vDeploymentParams[0]));
  85          }
  86      }
  87  }
  88  
  89  void ReadMainNetArgs(const ArgsManager& args, CChainParams::MainNetOptions& options)
  90  {
  91      HandleDeploymentArgs(args, options.dep_opts);
  92  }
  93  
  94  void ReadTestNetArgs(const ArgsManager& args, CChainParams::TestNetOptions& options)
  95  {
  96      HandleDeploymentArgs(args, options.dep_opts);
  97  }
  98  
  99  void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options)
 100  {
 101      if (!args.GetArgs("-signetseednode").empty()) {
 102          options.seeds.emplace(args.GetArgs("-signetseednode"));
 103      }
 104      if (!args.GetArgs("-signetchallenge").empty()) {
 105          const auto signet_challenge = args.GetArgs("-signetchallenge");
 106          if (signet_challenge.size() != 1) {
 107              throw std::runtime_error("-signetchallenge cannot be multiple values.");
 108          }
 109          const auto val{TryParseHex<uint8_t>(signet_challenge[0])};
 110          if (!val) {
 111              throw std::runtime_error(strprintf("-signetchallenge must be hex, not '%s'.", signet_challenge[0]));
 112          }
 113          options.challenge.emplace(*val);
 114      }
 115      HandleDeploymentArgs(args, options.dep_opts);
 116  }
 117  
 118  void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options)
 119  {
 120      if (auto value = args.GetBoolArg("-fastprune")) options.fastprune = *value;
 121      if (HasTestOption(args, "bip94")) options.enforce_bip94 = true;
 122  
 123      HandleDeploymentArgs(args, options.dep_opts);
 124  }
 125  
 126  static std::unique_ptr<const CChainParams> globalChainParams;
 127  
 128  const CChainParams &Params() {
 129      assert(globalChainParams);
 130      return *globalChainParams;
 131  }
 132  
 133  std::unique_ptr<const CChainParams> CreateChainParams(const ArgsManager& args, const ChainType chain)
 134  {
 135      switch (chain) {
 136      case ChainType::MAIN: {
 137          auto opts = CChainParams::MainNetOptions{};
 138          ReadMainNetArgs(args, opts);
 139          return CChainParams::Main(opts);
 140      }
 141      case ChainType::TESTNET: {
 142          auto opts = CChainParams::TestNetOptions{};
 143          ReadTestNetArgs(args, opts);
 144          return CChainParams::TestNet(opts);
 145      }
 146      case ChainType::TESTNET4: {
 147          auto opts = CChainParams::TestNetOptions{};
 148          ReadTestNetArgs(args, opts);
 149          return CChainParams::TestNet4(opts);
 150      }
 151      case ChainType::SIGNET: {
 152          auto opts = CChainParams::SigNetOptions{};
 153          ReadSigNetArgs(args, opts);
 154          return CChainParams::SigNet(opts);
 155      }
 156      case ChainType::REGTEST: {
 157          auto opts = CChainParams::RegTestOptions{};
 158          ReadRegTestArgs(args, opts);
 159          return CChainParams::RegTest(opts);
 160      }
 161      }
 162      assert(false);
 163  }
 164  
 165  void SelectParams(const ChainType chain)
 166  {
 167      SelectBaseParams(chain);
 168      globalChainParams = CreateChainParams(gArgs, chain);
 169  }
 170