diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_eth.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_eth.hpp index 7816e99e..44aa29f6 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_eth.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_eth.hpp @@ -3,7 +3,6 @@ #include #include -#include #include @@ -14,13 +13,27 @@ #include #include -#include -#include + +#include +#include namespace graphene { namespace peerplays_sidechain { +typedef websocketpp::client client; + +using websocketpp::lib::placeholders::_1; +using websocketpp::lib::placeholders::_2; +using websocketpp::lib::bind; + +// pull out the type of messages sent by our config +typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr; +typedef websocketpp::lib::shared_ptr context_ptr; +typedef client::connection_ptr connection_ptr; + class eth_rpc_client { public: + typedef eth_rpc_client type; + enum class multi_type { script, address @@ -40,8 +53,17 @@ public: public: eth_rpc_client(const std::string &url, const std::string &user_name, const std::string &password, bool debug_rpc_calls); - void connect(); + void start(std::string uri); + void on_socket_init(websocketpp::connection_hdl); + void on_fail(websocketpp::connection_hdl hdl); + void on_open(websocketpp::connection_hdl hdl); + void on_message(websocketpp::connection_hdl hdl, message_ptr msg); + void on_close(websocketpp::connection_hdl); + std::string get_chain_id(); + std::string eth_getTransactionReceipt(const std::string& tx_id); + std::string eth_call(const std::string& to, const std::string& data); + std::string eth_sendTransaction(const std::string& from, const std::string& to, const std::string& data); std::string addmultisigaddress(const uint32_t nrequired, const std::vector public_keys); std::string combinepsbt(const vector &psbts); @@ -72,6 +94,8 @@ public: private: std::string geth_url; + uint64_t t_id; + std::string ip; uint32_t rpc_port; std::string user; @@ -82,8 +106,8 @@ private: fc::http::header authorization; - fc::http::websocket_client client; - std::shared_ptr client_connection; + client m_endpoint; + websocketpp::connection_hdl m_hdl; }; // ============================================================================= diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_eth.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_eth.cpp index 0f8b5328..2320ef74 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_eth.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_eth.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -19,7 +20,6 @@ #include namespace graphene { namespace peerplays_sidechain { - // ============================================================================= eth_rpc_client::eth_rpc_client(const std::string &url, const std::string &user_name, const std::string &password, bool debug_rpc_calls) { @@ -27,18 +27,88 @@ eth_rpc_client::eth_rpc_client(const std::string &url, const std::string &user_n user = user_name; this->password = password; this->debug_rpc_calls = debug_rpc_calls; + t_id = 1; ilog("eth_rpc_client"); ilog("### Geth URL: ${url}", ("url", url)); + + m_endpoint.set_access_channels(websocketpp::log::alevel::none); + m_endpoint.set_error_channels(websocketpp::log::elevel::none); + + // Initialize ASIO + m_endpoint.init_asio(); + + // Register our handlers + m_endpoint.set_socket_init_handler(bind(&type::on_socket_init,this,::_1)); + m_endpoint.set_message_handler(bind(&type::on_message,this,::_1,::_2)); + m_endpoint.set_open_handler(bind(&type::on_open,this,::_1)); + m_endpoint.set_close_handler(bind(&type::on_close,this,::_1)); + m_endpoint.set_fail_handler(bind(&type::on_fail,this,::_1)); } -void eth_rpc_client::connect() { - client_connection = std::make_shared(client.connect(geth_url), GRAPHENE_MAX_NESTED_OBJECTS); +void eth_rpc_client::start(std::string uri) { + websocketpp::lib::error_code ec; + client::connection_ptr con = m_endpoint.get_connection(uri, ec); + m_hdl = con->get_handle(); + + if (ec) { + m_endpoint.get_alog().write(websocketpp::log::alevel::app,ec.message()); + return; + } + + m_endpoint.connect(con); + + // Start the ASIO io_service run loop + m_endpoint.run(); +} + +void eth_rpc_client::on_socket_init(websocketpp::connection_hdl) { +} + +void eth_rpc_client::on_fail(websocketpp::connection_hdl hdl) { + client::connection_ptr con = m_endpoint.get_con_from_hdl(hdl); + + elog("Ethereum websocket fail"); + //elog("get_state: ${state}", ("state", con->get_state() ) ); + elog("get_local_close_code: ${code}", ("code", con->get_local_close_code())); + elog("get_local_close_reason: ${close}", ("close",con->get_local_close_reason())); + elog("get_remote_close_code: ${close}", ("close", con->get_remote_close_code())); + elog("get_remote_close_reason: ${close}", ("close", con->get_remote_close_reason())); + elog("get_ec().message(): ${ec}", ("ec", con->get_ec().message())); +} + +void eth_rpc_client::on_open(websocketpp::connection_hdl hdl) { + m_endpoint.send(hdl, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_chainId\",\"params\":[],\"id\":84}", websocketpp::frame::opcode::text); +} + +void eth_rpc_client::on_message(websocketpp::connection_hdl hdl, message_ptr msg) { + + ilog("on_message: ${msg}", ("msg", msg->get_payload())); + + //m_endpoint.close(hdl,websocketpp::close::status::going_away,""); +} + +void eth_rpc_client::on_close(websocketpp::connection_hdl) { + ilog("Ethereum websocket close"); } std::string eth_rpc_client::get_chain_id() { - //std::string reply_str = database_api_get_version(); - return "";//retrieve_value_from_reply(reply_str, "chain_id"); + std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\":\"eth_chainId\",\"params\":[],\"id\":%1%}") % t_id++); + m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text); +} + +std::string eth_rpc_client::eth_getTransactionReceipt(const std::string& tx_id) { + std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionReceipt\",\"params\":[\"0xbc262e1222ff48cd026a62fd925912ab5006650e311b7711a7216054461a64e0\"],\"id\":%1%}") % t_id++); + m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text); + return ""; +} + +std::string eth_rpc_client::eth_call(const std::string& to, const std::string& data) { + return ""; +} + +std::string eth_rpc_client::eth_sendTransaction(const std::string& from, const std::string& to, const std::string& data) { + return ""; } std::string eth_rpc_client::addmultisigaddress(const uint32_t nrequired, const std::vector public_keys) { @@ -155,7 +225,7 @@ sidechain_net_handler_eth::sidechain_net_handler_eth(peerplays_sidechain_plugin url = options.at("ethereum-node-rpc-url").as(); eth_client = std::unique_ptr(new eth_rpc_client(url, rpc_user, rpc_password, debug_rpc_calls)); - eth_client->connect(); + eth_client->start(url); /* if (!wallet.empty()) { eth_client->loadwallet(wallet);