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