github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/core/neb_ipc/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/driver.h" 21 #include "common/configuration.h" 22 #include "core/ir_warden.h" 23 #include "core/neb_ipc/server/ipc_configuration.h" 24 #include "fs/fs_storage.h" 25 #include "fs/ir_manager/api/ir_api.h" 26 #include "jit/jit_driver.h" 27 #include "runtime/dip/dip_handler.h" 28 #include "runtime/nr/impl/nr_handler.h" 29 #include "runtime/version.h" 30 #include <ff/functionflow.h> 31 32 namespace neb { 33 namespace core { 34 namespace internal { 35 36 driver_base::driver_base() : m_exit_flag(false) {} 37 38 bool driver_base::init() { 39 ff::initialize(8); 40 m_client = std::unique_ptr<ipc_client_endpoint>(new ipc_client_endpoint()); 41 LOG(INFO) << "ipc client construct"; 42 add_handlers(); 43 44 //! we should make share wait_until_sync first 45 46 bool ret = m_client->start(); 47 if (!ret) 48 return ret; 49 50 m_ipc_conn = m_client->ipc_connection(); 51 52 auto p = m_ipc_conn->construct<ipc_pkg::nbre_init_req>( 53 nullptr, m_ipc_conn->default_allocator()); 54 m_ipc_conn->push_back(p); 55 56 return true; 57 } 58 59 void driver_base::run() { 60 neb::core::command_queue::instance().listen_command<neb::core::exit_command>( 61 this, [this](const std::shared_ptr<neb::core::exit_command> &) { 62 m_exit_flag = true; 63 }); 64 neb::exception_queue &eq = neb::exception_queue::instance(); 65 while (!m_exit_flag) { 66 std::shared_ptr<neb::neb_exception> ep = eq.pop_front(); 67 handle_exception(ep); 68 } 69 } 70 71 void driver_base::handle_exception( 72 const std::shared_ptr<neb::neb_exception> &p) { 73 switch (p->type()) { 74 LOG(ERROR) << p->what(); 75 case neb_exception::neb_std_exception: 76 neb::core::command_queue::instance().send_command( 77 std::make_shared<neb::core::exit_command>()); 78 break; 79 case neb_exception::neb_shm_queue_failure: 80 neb::core::command_queue::instance().send_command( 81 std::make_shared<neb::core::exit_command>()); 82 break; 83 case neb_exception::neb_shm_service_failure: 84 neb::core::command_queue::instance().send_command( 85 std::make_shared<neb::core::exit_command>()); 86 break; 87 case neb_exception::neb_shm_session_already_start: 88 neb::core::command_queue::instance().send_command( 89 std::make_shared<neb::core::exit_command>()); 90 break; 91 case neb_exception::neb_shm_session_timeout: 92 neb::core::command_queue::instance().send_command( 93 std::make_shared<neb::core::exit_command>()); 94 break; 95 case neb_exception::neb_shm_session_failure: 96 neb::core::command_queue::instance().send_command( 97 std::make_shared<neb::core::exit_command>()); 98 break; 99 case neb_exception::neb_configure_general_failure: 100 neb::core::command_queue::instance().send_command( 101 std::make_shared<neb::core::exit_command>()); 102 break; 103 case neb_exception::neb_json_general_failure: 104 neb::core::command_queue::instance().send_command( 105 std::make_shared<neb::core::exit_command>()); 106 break; 107 case neb_exception::neb_storage_exception_no_such_key: 108 neb::core::command_queue::instance().send_command( 109 std::make_shared<neb::core::exit_command>()); 110 break; 111 case neb_exception::neb_storage_exception_no_init: 112 neb::core::command_queue::instance().send_command( 113 std::make_shared<neb::core::exit_command>()); 114 break; 115 case neb_exception::neb_storage_general_failure: 116 neb::core::command_queue::instance().send_command( 117 std::make_shared<neb::core::exit_command>()); 118 break; 119 default: 120 break; 121 } 122 } 123 124 void driver_base::init_timer_thread() { 125 if (m_timer_thread) { 126 return; 127 } 128 m_timer_thread = std::unique_ptr<std::thread>(new std::thread([this]() { 129 boost::asio::io_service io_service; 130 131 m_timer_loop = std::unique_ptr<timer_loop>(new timer_loop(&io_service)); 132 m_timer_loop->register_timer_and_callback( 133 neb::configuration::instance().ir_warden_time_interval(), 134 []() { ir_warden::instance().on_timer(); }); 135 136 m_timer_loop->register_timer_and_callback( 137 1, []() { jit_driver::instance().timer_callback(); }); 138 139 io_service.run(); 140 })); 141 } 142 143 void driver_base::init_nbre() { 144 145 LOG(INFO) << "call func init_nbre"; 146 auto rs = neb::fs::fs_storage::instance().nbre_db_ptr(); 147 neb::rt::dip::dip_handler::instance().read_dip_reward_from_storage(); 148 149 try { 150 auto nbre_max_height_bytes = 151 rs->get(neb::configuration::instance().nbre_max_height_name()); 152 auto nbre_max_height = 153 neb::util::byte_to_number<block_height_t>(nbre_max_height_bytes); 154 LOG(INFO) << "nbre max height " << nbre_max_height; 155 neb::rt::dip::dip_handler::instance().init_dip_params(nbre_max_height); 156 LOG(INFO) << "init dip params done when init nbre"; 157 } catch (const std::exception &e) { 158 LOG(INFO) << "nbre max height not init " << e.what(); 159 } 160 LOG(INFO) << "driver init nbre done"; 161 } 162 163 } // end namespace internal 164 165 driver::driver() : internal::driver_base() {} 166 167 void driver::add_handlers() { 168 m_client->add_handler<ipc_pkg::nbre_version_req>( 169 [this](ipc_pkg::nbre_version_req *req) { 170 neb::core::ipc_pkg::nbre_version_ack *ack = 171 m_ipc_conn->construct<neb::core::ipc_pkg::nbre_version_ack>( 172 req->m_holder, m_ipc_conn->default_allocator()); 173 if (ack == nullptr) { 174 return; 175 } 176 neb::util::version v = neb::rt::get_version(); 177 ack->set<neb::core::ipc_pkg::major>(v.major_version()); 178 ack->set<neb::core::ipc_pkg::minor>(v.minor_version()); 179 ack->set<neb::core::ipc_pkg::patch>(v.patch_version()); 180 m_ipc_conn->push_back(ack); 181 }); 182 183 m_client->add_handler<ipc_pkg::nbre_init_ack>( 184 [this](ipc_pkg::nbre_init_ack *ack) { 185 LOG(INFO) << "get init ack"; 186 187 ipc_configuration::instance().nbre_root_dir() = 188 ack->get<ipc_pkg::nbre_root_dir>().c_str(); 189 ipc_configuration::instance().nbre_exe_name() = 190 ack->get<ipc_pkg::nbre_exe_name>().c_str(); 191 ipc_configuration::instance().neb_db_dir() = 192 ack->get<ipc_pkg::neb_db_dir>().c_str(); 193 ipc_configuration::instance().nbre_db_dir() = 194 ack->get<ipc_pkg::nbre_db_dir>().c_str(); 195 ipc_configuration::instance().nbre_log_dir() = 196 ack->get<ipc_pkg::nbre_log_dir>().c_str(); 197 ipc_configuration::instance().nbre_start_height() = 198 ack->get<ipc_pkg::nbre_start_height>(); 199 200 std::string addr_base58 = ack->get<ipc_pkg::admin_pub_addr>().c_str(); 201 neb::util::bytes addr_bytes = 202 neb::util::bytes::from_base58(addr_base58); 203 ipc_configuration::instance().admin_pub_addr() = 204 neb::util::byte_to_string(addr_bytes); 205 206 LOG(INFO) << ipc_configuration::instance().nbre_db_dir(); 207 LOG(INFO) << ipc_configuration::instance().admin_pub_addr(); 208 FLAGS_log_dir = ipc_configuration::instance().nbre_log_dir(); 209 google::InitGoogleLogging("nbre-client"); 210 211 init_nbre(); 212 init_timer_thread(); 213 ir_warden::instance().wait_until_sync(); 214 }); 215 216 m_client->add_handler<ipc_pkg::nbre_ir_list_req>( 217 [this](ipc_pkg::nbre_ir_list_req *req) { 218 neb::core::ipc_pkg::nbre_ir_list_ack *ack = 219 m_ipc_conn->construct<neb::core::ipc_pkg::nbre_ir_list_ack>( 220 req->m_holder, m_ipc_conn->default_allocator()); 221 if (ack == nullptr) { 222 return; 223 } 224 225 auto rs = neb::fs::fs_storage::instance().nbre_db_ptr(); 226 auto irs_ptr = neb::fs::ir_api::get_ir_list(rs); 227 for (auto &ir : *irs_ptr) { 228 neb::ipc::char_string_t ir_name(ir.c_str(), 229 m_ipc_conn->default_allocator()); 230 ack->get<neb::core::ipc_pkg::ir_name_list>().push_back(ir_name); 231 } 232 m_ipc_conn->push_back(ack); 233 }); 234 235 m_client->add_handler<ipc_pkg::nbre_ir_versions_req>( 236 [this](ipc_pkg::nbre_ir_versions_req *req) { 237 neb::core::ipc_pkg::nbre_ir_versions_ack *ack = 238 m_ipc_conn->construct<neb::core::ipc_pkg::nbre_ir_versions_ack>( 239 req->m_holder, m_ipc_conn->default_allocator()); 240 if (ack == nullptr) { 241 return; 242 } 243 244 auto ir_name = req->get<ipc_pkg::ir_name>(); 245 ack->set<neb::core::ipc_pkg::ir_name>(ir_name); 246 247 auto rs = neb::fs::fs_storage::instance().nbre_db_ptr(); 248 auto ir_versions_ptr = 249 neb::fs::ir_api::get_ir_versions(ir_name.c_str(), rs); 250 251 for (auto &v : *ir_versions_ptr) { 252 ack->get<neb::core::ipc_pkg::ir_versions>().push_back(v); 253 } 254 m_ipc_conn->push_back(ack); 255 }); 256 257 m_client->add_handler<ipc_pkg::nbre_nr_handler_req>( 258 [this](ipc_pkg::nbre_nr_handler_req *req) { 259 neb::core::ipc_pkg::nbre_nr_handler_ack *ack = 260 m_ipc_conn->construct<neb::core::ipc_pkg::nbre_nr_handler_ack>( 261 req->m_holder, m_ipc_conn->default_allocator()); 262 if (ack == nullptr) { 263 return; 264 } 265 266 if (!neb::rt::nr::nr_handler::instance().get_nr_handler_id().empty()) { 267 ack->set<neb::core::ipc_pkg::nr_handler_id>( 268 std::string("nr handler not available").c_str()); 269 m_ipc_conn->push_back(ack); 270 return; 271 } 272 273 uint64_t start_block = req->get<ipc_pkg::start_block>(); 274 uint64_t end_block = req->get<ipc_pkg::end_block>(); 275 uint64_t nr_version = req->get<ipc_pkg::nr_version>(); 276 277 std::stringstream ss; 278 ss << neb::util::number_to_byte<neb::util::bytes>(start_block).to_hex() 279 << neb::util::number_to_byte<neb::util::bytes>(end_block).to_hex() 280 << neb::util::number_to_byte<neb::util::bytes>(nr_version).to_hex(); 281 282 neb::ipc::char_string_t cstr_handler_id( 283 ss.str().c_str(), m_ipc_conn->default_allocator()); 284 ack->set<neb::core::ipc_pkg::nr_handler_id>(cstr_handler_id); 285 neb::rt::nr::nr_handler::instance().start(ss.str()); 286 m_ipc_conn->push_back(ack); 287 288 }); 289 290 m_client->add_handler<ipc_pkg::nbre_nr_result_req>( 291 [this](ipc_pkg::nbre_nr_result_req *req) { 292 neb::core::ipc_pkg::nbre_nr_result_ack *ack = 293 m_ipc_conn->construct<neb::core::ipc_pkg::nbre_nr_result_ack>( 294 req->m_holder, m_ipc_conn->default_allocator()); 295 if (ack == nullptr) { 296 return; 297 } 298 299 std::string nr_handler_id = req->get<ipc_pkg::nr_handler_id>().c_str(); 300 neb::ipc::char_string_t cstr_nr_result( 301 neb::rt::nr::nr_handler::instance() 302 .get_nr_result(nr_handler_id) 303 .c_str(), 304 m_ipc_conn->default_allocator()); 305 ack->set<neb::core::ipc_pkg::nr_result>(cstr_nr_result); 306 m_ipc_conn->push_back(ack); 307 }); 308 309 m_client->add_handler<ipc_pkg::nbre_dip_reward_req>( 310 [this](ipc_pkg::nbre_dip_reward_req *req) { 311 neb::core::ipc_pkg::nbre_dip_reward_ack *ack = 312 m_ipc_conn->construct<neb::core::ipc_pkg::nbre_dip_reward_ack>( 313 req->m_holder, m_ipc_conn->default_allocator()); 314 if (ack == nullptr) { 315 return; 316 } 317 318 auto height = req->get<ipc_pkg::height>(); 319 LOG(INFO) << "ipc client receive dip reward req, height " << height; 320 neb::ipc::char_string_t cstr_dip_reward( 321 neb::rt::dip::dip_handler::instance() 322 .get_dip_reward(height) 323 .c_str(), 324 m_ipc_conn->default_allocator()); 325 ack->set<neb::core::ipc_pkg::dip_reward>(cstr_dip_reward); 326 m_ipc_conn->push_back(ack); 327 }); 328 } 329 } 330 } // namespace neb