29 std::vector<std::byte> bytes;
30 bytes.reserve(hex.length() / 2);
32 for (
size_t i{0}; i < hex.length(); i += 2) {
34 auto [ptr, ec] = std::from_chars(hex.data() + i, hex.data() + i + 2, byte_value, 16);
36 if (ec != std::errc{} || ptr != hex.data() + i + 2) {
37 throw std::invalid_argument(
"Invalid hex character");
39 bytes.push_back(
static_cast<std::byte
>(byte_value));
144int main(
int argc,
char* argv[])
147 const bool has_regtest_flag{argc == 3 && std::string(argv[1]) ==
"-regtest"};
148 if (argc < 2 || argc > 3 || (argc == 3 && !has_regtest_flag)) {
150 <<
"Usage: " << argv[0] <<
" [-regtest] DATADIR" << std::endl
151 <<
"Display DATADIR information, and process hex-encoded blocks on standard input." << std::endl
152 <<
"Uses mainnet parameters by default, regtest with -regtest flag" << std::endl
154 <<
"IMPORTANT: THIS EXECUTABLE IS EXPERIMENTAL, FOR TESTING ONLY, AND EXPECTED TO" << std::endl
155 <<
" BREAK IN FUTURE VERSIONS. DO NOT USE ON YOUR ACTUAL DATADIR." << std::endl;
158 std::filesystem::path abs_datadir{std::filesystem::absolute(argv[argc-1])};
159 std::filesystem::create_directories(abs_datadir);
162 .log_timestamps =
true,
163 .log_time_micros =
false,
164 .log_threadnames =
false,
165 .log_sourcelocations =
false,
166 .always_print_category_levels =
true,
171 Logger logger{std::make_unique<KernelLog>()};
173 ContextOptions options{};
175 options.SetChainParams(params);
177 options.SetNotifications(std::make_shared<TestKernelNotifications>());
178 options.SetValidationInterface(std::make_shared<TestValidationInterface>());
180 Context context{options};
182 ChainstateManagerOptions chainman_opts{context, abs_datadir.string(), (abs_datadir /
"blocks").
string()};
183 chainman_opts.SetWorkerThreads(4);
185 std::unique_ptr<ChainMan> chainman;
187 chainman = std::make_unique<ChainMan>(context, chainman_opts);
188 }
catch (std::exception&) {
189 std::cerr <<
"Failed to instantiate ChainMan, exiting" << std::endl;
193 std::cout <<
"Enter the block you want to validate on the next line:" << std::endl;
195 for (std::string line; std::getline(std::cin, line);) {
197 std::cerr <<
"Empty line found, try again:" << std::endl;
202 std::unique_ptr<Block> block;
204 block = std::make_unique<Block>(raw_block);
205 }
catch (std::exception&) {
206 std::cerr <<
"Block decode failed, try again:" << std::endl;
210 bool new_block =
false;
211 bool accepted = chainman->ProcessBlock(*block, &new_block);
213 std::cerr <<
"Block has not yet been rejected" << std::endl;
215 std::cerr <<
"Block was not accepted" << std::endl;
218 std::cerr <<
"Block is a duplicate" << std::endl;