github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/core/net_ipc/client/client_driver.cpp (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 #include "core/net_ipc/client/client_driver.h" 21 #include "common/address.h" 22 #include "common/configuration.h" 23 #include "core/ir_warden.h" 24 #include "fs/bc_storage_session.h" 25 #include "fs/ir_manager/api/ir_api.h" 26 #include "fs/storage_holder.h" 27 #include "jit/jit_driver.h" 28 #include "runtime/dip/dip_handler.h" 29 #include "runtime/nr/impl/nr_handler.h" 30 #include "runtime/util.h" 31 #include "runtime/version.h" 32 #include <boost/filesystem.hpp> 33 #include <boost/property_tree/json_parser.hpp> 34 #include <boost/property_tree/ptree.hpp> 35 #include <ff/functionflow.h> 36 37 namespace neb { 38 namespace core { 39 namespace internal { 40 41 client_driver_base::client_driver_base() : m_exit_flag(false) {} 42 client_driver_base::~client_driver_base() { 43 LOG(INFO) << "to destroy client driver base"; 44 if (m_timer_thread) { 45 m_timer_thread->join(); 46 } 47 } 48 49 bool client_driver_base::init() { 50 ff::initialize(8); 51 m_client = std::unique_ptr<nipc_client>(new nipc_client()); 52 LOG(INFO) << "ipc client construct"; 53 add_handlers(); 54 55 //! we should make share wait_until_sync first 56 57 bool ret = m_client->start(); 58 if (!ret) 59 return ret; 60 61 m_ipc_conn = m_client->connection(); 62 63 auto p = std::make_shared<nbre_init_req>(); 64 65 LOG(INFO) << "to send nbre_init_req"; 66 m_ipc_conn->send(p); 67 68 return true; 69 } 70 71 void client_driver_base::run() { 72 neb::core::command_queue::instance().listen_command<neb::core::exit_command>( 73 this, [this](const std::shared_ptr<neb::core::exit_command> &) { 74 m_exit_flag = true; 75 }); 76 neb::exception_queue &eq = neb::exception_queue::instance(); 77 while (!m_exit_flag) { 78 std::shared_ptr<neb::neb_exception> ep = eq.pop_front(); 79 handle_exception(ep); 80 } 81 } 82 83 void client_driver_base::handle_exception( 84 const std::shared_ptr<neb::neb_exception> &p) { 85 86 switch (p->type()) { 87 LOG(ERROR) << p->what(); 88 case neb_exception::neb_std_exception: 89 neb::core::command_queue::instance().send_command( 90 std::make_shared<neb::core::exit_command>()); 91 break; 92 case neb_exception::neb_shm_queue_failure: 93 neb::core::command_queue::instance().send_command( 94 std::make_shared<neb::core::exit_command>()); 95 break; 96 case neb_exception::neb_shm_service_failure: 97 neb::core::command_queue::instance().send_command( 98 std::make_shared<neb::core::exit_command>()); 99 break; 100 case neb_exception::neb_shm_session_already_start: 101 neb::core::command_queue::instance().send_command( 102 std::make_shared<neb::core::exit_command>()); 103 break; 104 case neb_exception::neb_shm_session_timeout: 105 neb::core::command_queue::instance().send_command( 106 std::make_shared<neb::core::exit_command>()); 107 break; 108 case neb_exception::neb_shm_session_failure: 109 neb::core::command_queue::instance().send_command( 110 std::make_shared<neb::core::exit_command>()); 111 break; 112 case neb_exception::neb_configure_general_failure: 113 neb::core::command_queue::instance().send_command( 114 std::make_shared<neb::core::exit_command>()); 115 break; 116 case neb_exception::neb_json_general_failure: 117 neb::core::command_queue::instance().send_command( 118 std::make_shared<neb::core::exit_command>()); 119 break; 120 case neb_exception::neb_storage_exception_no_such_key: 121 neb::core::command_queue::instance().send_command( 122 std::make_shared<neb::core::exit_command>()); 123 break; 124 case neb_exception::neb_storage_exception_no_init: 125 neb::core::command_queue::instance().send_command( 126 std::make_shared<neb::core::exit_command>()); 127 break; 128 case neb_exception::neb_storage_general_failure: 129 neb::core::command_queue::instance().send_command( 130 std::make_shared<neb::core::exit_command>()); 131 break; 132 default: 133 break; 134 } 135 } 136 137 void client_driver_base::init_timer_thread() { 138 if (m_timer_thread) { 139 return; 140 } 141 m_timer_thread = std::unique_ptr<std::thread>(new std::thread([this]() { 142 boost::asio::io_service io_service; 143 144 m_timer_loop = 145 std::unique_ptr<util::timer_loop>(new util::timer_loop(&io_service)); 146 m_timer_loop->register_timer_and_callback( 147 neb::configuration::instance().ir_warden_time_interval(), 148 []() { ir_warden::instance().on_timer(); }); 149 150 m_timer_loop->register_timer_and_callback( 151 1, []() { jit_driver::instance().timer_callback(); }); 152 153 io_service.run(); 154 })); 155 } 156 157 void client_driver_base::init_nbre() { 158 159 fs::bc_storage_session::instance().init( 160 configuration::instance().neb_db_dir(), fs::storage_open_for_readonly); 161 162 auto *rs = neb::fs::storage_holder::instance().nbre_db_ptr(); 163 neb::block_height_t height = 1; 164 try { 165 auto tmp = rs->get(neb::configuration::instance().nbre_max_height_name()); 166 height = neb::byte_to_number<neb::block_height_t>(tmp); 167 } catch (const std::exception &e) { 168 } 169 LOG(INFO) << "init dip params with height " << height; 170 neb::rt::dip::dip_handler::instance().check_dip_params(height); 171 } 172 } // end namespace internal 173 174 client_driver::client_driver() : internal::client_driver_base() {} 175 client_driver::~client_driver() { LOG(INFO) << "to destroy client driver"; } 176 177 void client_driver::add_handlers() { 178 179 LOG(INFO) << "client is " << m_client.get(); 180 m_client->add_handler<nbre_version_req>( 181 [this](std::shared_ptr<nbre_version_req> req) { 182 LOG(INFO) << "recv nbre_version_req"; 183 auto ack = new_ack_pkg<nbre_version_ack>(req); 184 if (ack == nullptr) { 185 return; 186 } 187 188 neb::version v = neb::rt::get_version(); 189 ack->set<p_major>(v.major_version()); 190 ack->set<p_minor>(v.minor_version()); 191 ack->set<p_patch>(v.patch_version()); 192 m_ipc_conn->send(ack); 193 }); 194 195 m_client->add_handler<nbre_init_ack>([this]( 196 std::shared_ptr<nbre_init_ack> ack) { 197 LOG(INFO) << "recv nbre_init_ack"; 198 try { 199 configuration::instance().nbre_root_dir() = 200 ack->get<p_nbre_root_dir>().c_str(); 201 configuration::instance().nbre_exe_name() = 202 ack->get<p_nbre_exe_name>().c_str(); 203 configuration::instance().neb_db_dir() = ack->get<p_neb_db_dir>().c_str(); 204 configuration::instance().nbre_db_dir() = 205 ack->get<p_nbre_db_dir>().c_str(); 206 configuration::instance().nbre_log_dir() = 207 ack->get<p_nbre_log_dir>().c_str(); 208 configuration::instance().nbre_start_height() = 209 ack->get<p_nbre_start_height>(); 210 211 std::string addr = ack->get<p_admin_pub_addr>().c_str(); 212 // neb::util::bytes addr_bytes = 213 // neb::util::bytes::from_base58(addr_base58); 214 configuration::instance().admin_pub_addr() = to_address(addr); 215 216 LOG(INFO) << configuration::instance().nbre_db_dir(); 217 LOG(INFO) << configuration::instance().neb_db_dir(); 218 // LOG(INFO) << addr_base58; 219 220 init_nbre(); 221 init_timer_thread(); 222 ir_warden::instance().wait_until_sync(); 223 } catch (const std::exception &e) { 224 LOG(ERROR) << "got exception " << typeid(e).name() 225 << " with what: " << e.what(); 226 } 227 }); 228 229 m_client->add_handler<nbre_ir_list_req>( 230 [this](std::shared_ptr<nbre_ir_list_req> req) { 231 LOG(INFO) << "recv nbre_ir_list_req"; 232 try { 233 auto ack = new_ack_pkg<nbre_ir_list_ack>(req); 234 235 auto rs = neb::fs::storage_holder::instance().nbre_db_ptr(); 236 auto irs_ptr = neb::fs::ir_api::get_ir_list(rs); 237 238 boost::property_tree::ptree pt, root; 239 for (auto &ir : *irs_ptr) { 240 boost::property_tree::ptree child; 241 child.put("", ir); 242 pt.push_back(std::make_pair("", child)); 243 } 244 root.add_child(neb::configuration::instance().ir_list_name(), pt); 245 std::stringstream ss; 246 boost::property_tree::json_parser::write_json(ss, root); 247 248 ack->set<p_ir_name_list>(ss.str()); 249 m_ipc_conn->send(ack); 250 251 } catch (const std::exception &e) { 252 LOG(ERROR) << "got exception " << typeid(e).name() 253 << " with what: " << e.what(); 254 } 255 }); 256 257 m_client->add_handler<nbre_ir_versions_req>( 258 [this](std::shared_ptr<nbre_ir_versions_req> req) { 259 LOG(INFO) << "recv nbre_ir_versions_req"; 260 try { 261 auto ack = new_ack_pkg<nbre_ir_versions_ack>(req); 262 auto ir_name = req->get<p_ir_name>(); 263 264 auto rs = neb::fs::storage_holder::instance().nbre_db_ptr(); 265 auto ir_versions_ptr = 266 neb::fs::ir_api::get_ir_versions(ir_name.c_str(), rs); 267 268 boost::property_tree::ptree pt, root; 269 for (auto &v : *ir_versions_ptr) { 270 boost::property_tree::ptree child; 271 child.put("", v); 272 pt.push_back(std::make_pair("", child)); 273 } 274 root.add_child(ir_name.c_str(), pt); 275 276 std::stringstream ss; 277 boost::property_tree::json_parser::write_json(ss, root); 278 279 m_ipc_conn->send(ack); 280 } catch (const std::exception &e) { 281 LOG(ERROR) << "got exception " << typeid(e).name() 282 << " with what: " << e.what(); 283 } 284 }); 285 286 m_client->add_handler<nbre_nr_handle_req>( 287 [this](std::shared_ptr<nbre_nr_handle_req> req) { 288 LOG(INFO) << "recv nbre_nr_handle_req"; 289 try { 290 uint64_t start_block = req->get<p_start_block>(); 291 uint64_t end_block = req->get<p_end_block>(); 292 uint64_t nr_version = req->get<p_nr_version>(); 293 294 std::stringstream ss; 295 ss << neb::number_to_byte<neb::bytes>(start_block).to_hex() 296 << neb::number_to_byte<neb::bytes>(end_block).to_hex() 297 << neb::number_to_byte<neb::bytes>(nr_version).to_hex(); 298 299 auto ack = new_ack_pkg<nbre_nr_handle_ack>(req); 300 ack->set<p_nr_handle>(ss.str()); 301 neb::rt::nr::nr_handler::instance().start(ss.str()); 302 m_ipc_conn->send(ack); 303 304 } catch (const std::exception &e) { 305 LOG(ERROR) << "got exception " << typeid(e).name() 306 << " with what: " << e.what(); 307 } 308 }); 309 310 m_client->add_handler<nbre_nr_result_by_handle_req>( 311 [this](std::shared_ptr<nbre_nr_result_by_handle_req> req) { 312 LOG(INFO) << "recv nbre_nr_result_by_handle_req"; 313 try { 314 auto ack = new_ack_pkg<nbre_nr_result_by_handle_ack>(req); 315 std::string nr_handle = req->get<p_nr_handle>(); 316 auto nr_ret = 317 neb::rt::nr::nr_handler::instance().get_nr_result(nr_handle); 318 if (!std::get<0>(nr_ret)) { 319 ack->set<p_nr_result>(std::get<1>(nr_ret)); 320 m_ipc_conn->send(ack); 321 return; 322 } 323 324 auto str_ptr = neb::rt::nr::nebulas_rank::nr_info_to_json(nr_ret); 325 LOG(INFO) << "nr result \n" << *str_ptr; 326 ack->set<p_nr_result>(*str_ptr); 327 m_ipc_conn->send(ack); 328 } catch (const std::exception &e) { 329 LOG(ERROR) << "got exception " << typeid(e).name() 330 << " with what: " << e.what(); 331 } 332 }); 333 334 m_client->add_handler<nbre_nr_result_by_height_req>( 335 [this](std::shared_ptr<nbre_nr_result_by_height_req> req) { 336 LOG(INFO) << "recv nbre_nr_result_by_height_req"; 337 try { 338 auto ack = new_ack_pkg<nbre_nr_result_by_height_ack>(req); 339 auto height = req->get<p_height>(); 340 auto ret_ptr = 341 neb::rt::dip::dip_handler::instance().get_nr_result(height); 342 LOG(INFO) << "nr result \n" << *ret_ptr; 343 ack->set<p_nr_result>(*ret_ptr); 344 m_ipc_conn->send(ack); 345 } catch (const std::exception &e) { 346 LOG(ERROR) << "got exception " << typeid(e).name() 347 << " with what: " << e.what(); 348 } 349 }); 350 351 m_client->add_handler<nbre_nr_sum_req>( 352 [this](std::shared_ptr<nbre_nr_sum_req> req) { 353 LOG(INFO) << "recv nbre_nr_sum_req"; 354 try { 355 auto ack = new_ack_pkg<nbre_nr_sum_ack>(req); 356 auto height = req->get<p_height>(); 357 auto ret_ptr = 358 neb::rt::dip::dip_handler::instance().get_nr_sum(height); 359 LOG(INFO) << "nr sum \n" << *ret_ptr; 360 ack->set<p_nr_sum>(*ret_ptr); 361 m_ipc_conn->send(ack); 362 } catch (const std::exception &e) { 363 LOG(ERROR) << "got exception " << typeid(e).name() 364 << " with what: " << e.what(); 365 } 366 }); 367 368 m_client->add_handler<nbre_dip_reward_req>( 369 [this](std::shared_ptr<nbre_dip_reward_req> req) { 370 LOG(INFO) << "recv nbre_dip_reward_req"; 371 try { 372 auto ack = new_ack_pkg<nbre_dip_reward_ack>(req); 373 auto height = req->get<p_height>(); 374 auto ret_ptr = 375 neb::rt::dip::dip_handler::instance().get_dip_reward(height); 376 ack->set<p_dip_reward>(*ret_ptr); 377 m_ipc_conn->send(ack); 378 } catch (const std::exception &e) { 379 LOG(ERROR) << "got exception " << typeid(e).name() 380 << " with what: " << e.what(); 381 } 382 }); 383 384 m_client->add_handler<nbre_ir_transactions_req>( 385 [this](std::shared_ptr<nbre_ir_transactions_req> req) { 386 try { 387 ir_warden::instance().on_receive_ir_transactions(req); 388 } catch (const std::exception &e) { 389 LOG(ERROR) << "got exception " << typeid(e).name() 390 << " with what: " << e.what(); 391 } 392 }); 393 } 394 } // namespace core 395 } // namespace neb