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