diff --git a/libraries/plugins/peerplays_sidechain/common/ws_client.cpp b/libraries/plugins/peerplays_sidechain/common/ws_client.cpp index da751563..b849afc1 100644 --- a/libraries/plugins/peerplays_sidechain/common/ws_client.cpp +++ b/libraries/plugins/peerplays_sidechain/common/ws_client.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -144,25 +145,21 @@ ws_reply ws_client::send_post_request(std::string body, bool show_log) { // Look up the domain name auto const results = resolver.resolve(host, port); - //// Make the connection on the IP address we get from a lookup - //boost::beast::net::connect(ws.next_layer(), results.begin(), results.end()); - // - //// Set a decorator to change the User-Agent of the handshake - //ws.set_option(websocket::stream_base::decorator( - // [](websocket::request_type &req) { - // req.set(http::field::user_agent, - // std::string(BOOST_BEAST_VERSION_STRING) + - // " websocket-client-coro"); - // })); + // Make the connection on the IP address we get from a lookup + boost::beast::net::connect(ws.next_layer(), results.begin(), results.end()); - //// Set up an HTTP GET request message - //boost::beast::http::request req{boost::beast::http::verb::post, target, 11}; - //req.set(boost::beast::http::field::host, host + ":" + port); - //req.set(boost::beast::http::field::accept, "application/json"); - //req.set(boost::beast::http::field::content_type, "application/json"); - //req.set(boost::beast::http::field::content_encoding, "utf-8"); - //req.set(boost::beast::http::field::content_length, body.length()); - //req.body() = body; + // Set a decorator to change the User-Agent of the handshake + ws.set_option(boost::beast::websocket::stream_base::decorator( + [](boost::beast::websocket::request_type &req) { + //// Set up an HTTP GET request message + //boost::beast::http::request req{boost::beast::http::verb::post, target, 11}; + //req.set(boost::beast::http::field::host, host + ":" + port); + //req.set(boost::beast::http::field::accept, "application/json"); + //req.set(boost::beast::http::field::content_type, "application/json"); + //req.set(boost::beast::http::field::content_encoding, "utf-8"); + //req.set(boost::beast::http::field::content_length, body.length()); + //req.body() = body; + })); // Perform the websocket handshake ws.handshake(host, "/"); @@ -173,27 +170,14 @@ ws_reply ws_client::send_post_request(std::string body, bool show_log) { // This buffer is used for reading and must be persisted boost::beast::flat_buffer buffer; - // Declare a container to hold the response - boost::beast::http::response res; + // Read a message into our buffer + ws.read(buffer); - //// Receive the HTTP response - //boost::beast::http::read(stream, buffer, res); - // - ////// Write the message to standard out - ////std::cout << res << std::endl; - // - //// Gracefully close the socket - //boost::beast::error_code ec; - //stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); - // - //// not_connected happens sometimes - //// so don't bother reporting it. - //// - //if (ec && ec != boost::beast::errc::not_connected) - // throw boost::beast::system_error{ec}; + // Close the WebSocket connection + ws.close(boost::beast::websocket::close_code::normal); + + std::string rbody = boost::beast::make_printable(buffer.data()); - std::string rbody{boost::asio::buffers_begin(res.body().data()), - boost::asio::buffers_end(res.body().data())}; ws_reply reply; reply.status = 200; reply.body = rbody; diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_ethereum.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_ethereum.hpp index 745c26bb..0a04aff8 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_ethereum.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_ethereum.hpp @@ -6,8 +6,8 @@ #include -#include #include +#include #include namespace graphene { namespace peerplays_sidechain { @@ -24,6 +24,11 @@ public: std::string get_network_id(); }; +class ethereum_ws_client : public ws_client { +public: + ethereum_ws_client(const std::string &url, const std::string &user_name, const std::string &password, bool debug_rpc_calls); +}; + class sidechain_net_handler_ethereum : public sidechain_net_handler { public: sidechain_net_handler_ethereum(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options); @@ -42,9 +47,13 @@ private: std::string rpc_url; std::string rpc_user; std::string rpc_password; + std::string ws_url; + std::string ws_user; + std::string ws_password; std::string wallet_contract_address; - ethereum_rpc_client *ethereum_client; + ethereum_rpc_client *ethereum_client_rpc; + ethereum_ws_client *ethereum_client_ws; ethereum::chain_id_type chain_id; ethereum::network_id_type network_id; diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_hive.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_hive.hpp index a0cb6038..72539db2 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_hive.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_hive.hpp @@ -6,7 +6,6 @@ #include -#include #include #include diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 73bef93f..0bcd84e0 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -161,6 +161,9 @@ void peerplays_sidechain_plugin_impl::plugin_set_program_options( cli.add_options()("ethereum-node-rpc-url", bpo::value()->default_value("127.0.0.1:8545"), "Ethereum node RPC URL [http[s]://]host[:port]"); cli.add_options()("ethereum-node-rpc-user", bpo::value(), "Ethereum RPC user"); cli.add_options()("ethereum-node-rpc-password", bpo::value(), "Ethereum RPC password"); + cli.add_options()("ethereum-node-ws-url", bpo::value()->default_value("127.0.0.1:8546"), "Ethereum node WS URL [ws[s]://]host[:port]"); + cli.add_options()("ethereum-node-ws-user", bpo::value(), "Ethereum WS user"); + cli.add_options()("ethereum-node-ws-password", bpo::value(), "Ethereum WS password"); cli.add_options()("ethereum-wallet-contract-address", bpo::value()->default_value("0000000000000000000000000000000000000000"), "Ethereum wallet contract address"), cli.add_options()("ethereum-private-key", bpo::value>()->composing()->multitoken()->DEFAULT_VALUE_VECTOR(std::make_pair("5fbbb31be52608d2f52247e8400b7fcaa9e0bc12", "9bedac2bd8fe2a6f6528e066c67fc8ac0622e96828d40c0e820d83c5bd2b0589")), "Tuple of [Ethereum public key, Ethereum private key] (may specify multiple times)"); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_ethereum.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_ethereum.cpp index 0dde6927..c34d1ea7 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_ethereum.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_ethereum.cpp @@ -49,6 +49,9 @@ std::string ethereum_rpc_client::get_network_id() { return retrieve_value_from_reply(reply_str, "protocols.eth.network"); } +ethereum_ws_client::ethereum_ws_client(const std::string &url, const std::string &user_name, const std::string &password, bool debug_rpc_calls) : + ws_client(url, user_name, password, debug_rpc_calls){}; + sidechain_net_handler_ethereum::sidechain_net_handler_ethereum(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) : sidechain_net_handler(_plugin, options) { sidechain = sidechain_type::ethereum; @@ -69,6 +72,18 @@ sidechain_net_handler_ethereum::sidechain_net_handler_ethereum(peerplays_sidecha rpc_password = ""; } + ws_url = options.at("ethereum-node-ws-url").as(); + if (options.count("ethereum-node-ws-user")) { + ws_user = options.at("ethereum-node-ws-user").as(); + } else { + ws_user = ""; + } + if (options.count("ethereum-node-ws-password")) { + rpc_password = options.at("ethereum-node-ws-password").as(); + } else { + ws_password = ""; + } + wallet_contract_address = options.at("ethereum-wallet-contract-address").as(); if (options.count("ethereum-private-key")) { @@ -83,15 +98,16 @@ sidechain_net_handler_ethereum::sidechain_net_handler_ethereum(peerplays_sidecha } } - ethereum_client = new ethereum_rpc_client(rpc_url, rpc_user, rpc_password, debug_rpc_calls); + ethereum_client_rpc = new ethereum_rpc_client(rpc_url, rpc_user, rpc_password, debug_rpc_calls); + ethereum_client_ws = new ethereum_ws_client(ws_url, ws_user, ws_password, debug_rpc_calls); - std::string chain_id_str = ethereum_client->get_chain_id(); + std::string chain_id_str = ethereum_client_rpc->get_chain_id(); if (chain_id_str.empty()) { elog("No Ethereum node running at ${url}", ("url", rpc_url)); FC_ASSERT(false); } chain_id = std::stoll(chain_id_str); - std::string network_id_str = ethereum_client->get_network_id(); + std::string network_id_str = ethereum_client_rpc->get_network_id(); network_id = std::stoll(network_id_str); ilog("Running on Ethereum network, chain id ${chain_id_str}, network id ${network_id_str}", ("chain_id_str", chain_id_str)("network_id_str", network_id_str)); @@ -327,7 +343,7 @@ void sidechain_net_handler_ethereum::schedule_ethereum_listener() { void sidechain_net_handler_ethereum::ethereum_listener_loop() { schedule_ethereum_listener(); - std::string reply = ethereum_client->eth_get_block_by_number("latest", true); + std::string reply = ethereum_client_rpc->eth_get_block_by_number("latest", true); } void sidechain_net_handler_ethereum::handle_event(const std::string &event_data) {