@@ -43,6 +43,8 @@ static void SetupBitcoinUtilArgs(ArgsManager &argsman)
43
43
44
44
argsman.AddArg (" -version" , " Print version and exit" , ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
45
45
46
+ argsman.AddCommand (" grind" , " Perform proof of work on hex header string" , OptionsCategory::COMMANDS);
47
+
46
48
SetupChainParamsBaseOptions (argsman);
47
49
}
48
50
@@ -57,15 +59,7 @@ static int AppInitUtil(int argc, char* argv[])
57
59
return EXIT_FAILURE;
58
60
}
59
61
60
- // Check for chain settings (Params() calls are only valid after this clause)
61
- try {
62
- SelectParams (gArgs .GetChainName ());
63
- } catch (const std::exception& e) {
64
- tfm::format (std::cerr, " Error: %s\n " , e.what ());
65
- return EXIT_FAILURE;
66
- }
67
-
68
- if (argc < 2 || HelpRequested (gArgs ) || gArgs .IsArgSet (" -version" )) {
62
+ if (HelpRequested (gArgs ) || gArgs .IsArgSet (" -version" )) {
69
63
// First part of help message is specific to this utility
70
64
std::string strUsage = PACKAGE_NAME " bitcoin-util utility version " + FormatFullVersion () + " \n " ;
71
65
if (!gArgs .IsArgSet (" -version" )) {
@@ -82,6 +76,15 @@ static int AppInitUtil(int argc, char* argv[])
82
76
}
83
77
return EXIT_SUCCESS;
84
78
}
79
+
80
+ // Check for chain settings (Params() calls are only valid after this clause)
81
+ try {
82
+ SelectParams (gArgs .GetChainName ());
83
+ } catch (const std::exception& e) {
84
+ tfm::format (std::cerr, " Error: %s\n " , e.what ());
85
+ return EXIT_FAILURE;
86
+ }
87
+
85
88
return CONTINUE_EXECUTION;
86
89
}
87
90
@@ -111,17 +114,17 @@ static void grind_task(uint32_t nBits, CBlockHeader& header_orig, uint32_t offse
111
114
}
112
115
}
113
116
114
- static int Grind (int argc, char * argv[] , std::string& strPrint)
117
+ static int Grind (std::vector<std::string> args , std::string& strPrint)
115
118
{
116
- if (argc != 1 ) {
119
+ if (args. size () != 1 ) {
117
120
strPrint = " Must specify block header to grind" ;
118
- return 1 ;
121
+ return EXIT_FAILURE ;
119
122
}
120
123
121
124
CBlockHeader header;
122
- if (!DecodeHexBlockHeader (header, argv [0 ])) {
125
+ if (!DecodeHexBlockHeader (header, args [0 ])) {
123
126
strPrint = " Could not decode block header" ;
124
- return 1 ;
127
+ return EXIT_FAILURE ;
125
128
}
126
129
127
130
uint32_t nBits = header.nBits ;
@@ -137,49 +140,13 @@ static int Grind(int argc, char* argv[], std::string& strPrint)
137
140
}
138
141
if (!found) {
139
142
strPrint = " Could not satisfy difficulty target" ;
140
- return 1 ;
143
+ return EXIT_FAILURE ;
141
144
}
142
145
143
146
CDataStream ss (SER_NETWORK, PROTOCOL_VERSION);
144
147
ss << header;
145
148
strPrint = HexStr (ss);
146
- return 0 ;
147
- }
148
-
149
- static int CommandLineUtil (int argc, char * argv[])
150
- {
151
- if (argc <= 1 ) return 1 ;
152
-
153
- std::string strPrint;
154
- int nRet = 0 ;
155
-
156
- try {
157
- while (argc > 1 && IsSwitchChar (argv[1 ][0 ]) && (argv[1 ][1 ] != 0 )) {
158
- --argc;
159
- ++argv;
160
- }
161
-
162
- char * command = argv[1 ];
163
- if (strcmp (command, " grind" ) == 0 ) {
164
- nRet = Grind (argc-2 , argv+2 , strPrint);
165
- } else {
166
- strPrint = strprintf (" Unknown command %s" , command);
167
- nRet = 1 ;
168
- }
169
- }
170
- catch (const std::exception& e) {
171
- strPrint = std::string (" error: " ) + e.what ();
172
- nRet = EXIT_FAILURE;
173
- }
174
- catch (...) {
175
- PrintExceptionContinue (nullptr , " CommandLineUtil()" );
176
- throw ;
177
- }
178
-
179
- if (strPrint != " " ) {
180
- tfm::format (nRet == 0 ? std::cout : std::cerr, " %s\n " , strPrint);
181
- }
182
- return nRet;
149
+ return EXIT_SUCCESS;
183
150
}
184
151
185
152
#ifdef WIN32
@@ -199,23 +166,37 @@ int main(int argc, char* argv[])
199
166
int ret = AppInitUtil (argc, argv);
200
167
if (ret != CONTINUE_EXECUTION)
201
168
return ret;
202
- }
203
- catch (const std::exception& e) {
169
+ } catch (const std::exception& e) {
204
170
PrintExceptionContinue (&e, " AppInitUtil()" );
205
171
return EXIT_FAILURE;
206
172
} catch (...) {
207
173
PrintExceptionContinue (nullptr , " AppInitUtil()" );
208
174
return EXIT_FAILURE;
209
175
}
210
176
177
+ const auto cmd = gArgs .GetCommand ();
178
+ if (!cmd) {
179
+ tfm::format (std::cerr, " Error: must specify a command\n " );
180
+ return EXIT_FAILURE;
181
+ }
182
+
211
183
int ret = EXIT_FAILURE;
184
+ std::string strPrint;
212
185
try {
213
- ret = CommandLineUtil (argc, argv);
214
- }
215
- catch (const std::exception& e) {
216
- PrintExceptionContinue (&e, " CommandLineUtil()" );
186
+ if (cmd->command == " grind" ) {
187
+ ret = Grind (cmd->args , strPrint);
188
+ } else {
189
+ assert (false ); // unknown command should be caught earlier
190
+ }
191
+ } catch (const std::exception& e) {
192
+ strPrint = std::string (" error: " ) + e.what ();
217
193
} catch (...) {
218
- PrintExceptionContinue (nullptr , " CommandLineUtil()" );
194
+ strPrint = " unknown error" ;
195
+ }
196
+
197
+ if (strPrint != " " ) {
198
+ tfm::format (ret == 0 ? std::cout : std::cerr, " %s\n " , strPrint);
219
199
}
200
+
220
201
return ret;
221
202
}
0 commit comments