-
-
Save ismaelsadeeq/a5e3edb3fbf2d7f3c6698c1610622d22 to your computer and use it in GitHub Desktop.
Generate block on regtest concurrently
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <curl/curl.h> | |
| #include <future> | |
| #include <iostream> | |
| #include <string> | |
| #include <thread> | |
| #include <vector> | |
| #include "nlohmann/json.hpp" | |
| using json = nlohmann::json; | |
| static int ITERATIONS{1000}; | |
| struct Config { | |
| std::string url; | |
| std::string auth; | |
| }; | |
| // Helper function for curl write callback | |
| size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) { | |
| userp->append((char*)contents, size * nmemb); | |
| return size * nmemb; | |
| } | |
| // RPC request class | |
| class RPCRequest { | |
| private: | |
| CURL* curl; | |
| std::string response; | |
| struct curl_slist* headers; | |
| Config config; | |
| public: | |
| RPCRequest(const Config& cfg) : config(cfg) { | |
| curl = curl_easy_init(); | |
| headers = curl_slist_append(nullptr, "content-type: application/json"); | |
| curl_easy_setopt(curl, CURLOPT_URL, config.url.c_str()); | |
| curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); | |
| curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); | |
| curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); | |
| curl_easy_setopt(curl, CURLOPT_USERPWD, config.auth.c_str()); | |
| } | |
| ~RPCRequest() { | |
| curl_slist_free_all(headers); | |
| curl_easy_cleanup(curl); | |
| } | |
| json makeRequest(const json& payload) { | |
| std::string data = payload.dump(); | |
| curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); | |
| response.clear(); | |
| CURLcode res = curl_easy_perform(curl); | |
| if (res != CURLE_OK) { | |
| throw std::runtime_error(curl_easy_strerror(res)); | |
| } | |
| return json::parse(response)["result"]; | |
| } | |
| CURL* getCurl() { return curl; } | |
| }; | |
| class BlockGenerator { | |
| protected: | |
| int num_threads; | |
| Config config; | |
| public: | |
| BlockGenerator(const Config& cfg) : num_threads(std::thread::hardware_concurrency()), config(cfg) {} | |
| virtual ~BlockGenerator() = default; | |
| virtual void generateBlocks(int number) = 0; | |
| std::string getnewaddress(RPCRequest& rpc) { | |
| json payload = { | |
| {"method", "getnewaddress"}, | |
| {"params", {}}, | |
| {"id", 1} | |
| }; | |
| return rpc.makeRequest(payload); | |
| } | |
| json generateBlock(RPCRequest& rpc, const std::string& address) { | |
| json payload = { | |
| {"method", "generateblock"}, | |
| {"params", {address, json::array()}}, | |
| {"id", 1} | |
| }; | |
| return rpc.makeRequest(payload); | |
| } | |
| }; | |
| class ThreadPoolGenerator : public BlockGenerator { | |
| public: | |
| using BlockGenerator::BlockGenerator; | |
| void generateBlocks(int number) override { | |
| std::vector<std::future<void>> futures; | |
| for (int i = 0; i < num_threads; ++i) { | |
| futures.push_back(std::async(std::launch::async, [&, i]() { | |
| RPCRequest rpc(config); | |
| for (int j = i; j < number; j += num_threads) { | |
| auto address = getnewaddress(rpc); | |
| std::cout << "getting block " << j << std::endl; | |
| auto block = generateBlock(rpc, address); | |
| } | |
| })); | |
| } | |
| for (auto& future : futures) { | |
| future.wait(); | |
| } | |
| } | |
| }; | |
| int main() { | |
| try { | |
| Config config{"http://127.0.0.1:18443", "abubakar:sadeeq"}; | |
| ThreadPoolGenerator threadPool(config); | |
| threadPool.generateBlocks(ITERATIONS); | |
| } catch (const std::exception& ex) { | |
| std::cerr << "Error: " << ex.what() << std::endl; | |
| return 1; | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment