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