github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/core/net_ipc/ipc_interface.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/ipc_interface.h"
    21  #include "common/configuration.h"
    22  #include "core/net_ipc/nipc_pkg.h"
    23  #include "core/net_ipc/server/nipc_server.h"
    24  
    25  std::shared_ptr<neb::core::nipc_server> _ipc;
    26  
    27  int start_nbre_ipc(nbre_params_t params) {
    28    try {
    29      LOG(INFO) << "log-to-stderr: " << neb::glog_log_to_stderr;
    30      if (neb::glog_log_to_stderr) {
    31        FLAGS_log_dir = params.m_nbre_log_dir;
    32        LOG(INFO) << "log dir server " << FLAGS_log_dir;
    33        google::InitGoogleLogging("nbre-server");
    34      }
    35  
    36      _ipc = std::make_shared<neb::core::nipc_server>();
    37      LOG(INFO) << "ipc server construct";
    38      _ipc->init_params(params);
    39  
    40      LOG(INFO) << "ipc listen " << params.m_nipc_listen;
    41      LOG(INFO) << "ipc port " << params.m_nipc_port;
    42      if (_ipc->start()) {
    43        LOG(INFO) << "start nbre succ";
    44        return ipc_status_succ;
    45      } else {
    46        LOG(ERROR) << "start nbre failed";
    47        return ipc_status_fail;
    48      }
    49    } catch (const std::exception &e) {
    50      LOG(ERROR) << "start nbre got exception " << typeid(e).name() << ":"
    51                 << e.what();
    52      return ipc_status_exception;
    53    } catch (...) {
    54      LOG(ERROR) << "start nbre got unknown exception ";
    55      return ipc_status_exception;
    56    }
    57  }
    58  
    59  void nbre_ipc_shutdown() {
    60    if (!_ipc)
    61      return;
    62    _ipc->shutdown();
    63    _ipc.reset();
    64  }
    65  
    66  //////////////////////////////////////
    67  template <typename P1, typename... Params> struct set_bind_helper {
    68    template <typename PkgPtrType, typename A1, typename... Args>
    69    static void set(PkgPtrType &pkg, A1 a, Args... args) {
    70      pkg->template set<P1>(a);
    71      set_bind_helper<Params...>::set(pkg, args...);
    72    }
    73    template <typename PkgPtrType, typename... Args>
    74    static void set(PkgPtrType &pkg, void *a, Args... args) {
    75      pkg->template set<P1>(reinterpret_cast<uint64_t>(a));
    76      set_bind_helper<Params...>::set(pkg, args...);
    77    }
    78  };
    79  
    80  template <typename P1> struct set_bind_helper<P1> {
    81    template <typename PkgPtrType, typename A1>
    82    static void set(PkgPtrType &pkg, A1 a) {
    83      pkg->template set<P1>(a);
    84    }
    85    template <typename PkgPtrType> static void set(PkgPtrType &pkg, void *a) {
    86      pkg->template set<P1>(reinterpret_cast<uint64_t>(a));
    87    }
    88  };
    89  
    90  template <typename PkgType, typename... Params> struct ipc_call {
    91    template <typename... Args> static int bind(Args... args) {
    92      std::shared_ptr<PkgType> pkg(new PkgType());
    93      set_bind_helper<Params...>::set(pkg, args...);
    94      void *holder = reinterpret_cast<void *>(pkg->template get<p_holder>());
    95      if (!_ipc)
    96        return ipc_status_fail;
    97      return _ipc->send_api_pkg<PkgType>(holder, pkg);
    98    }
    99  };
   100  ///////////////////////////////////////
   101  
   102  template <typename IT,
   103            typename DT = typename ::ff::util::internal::nt_traits<IT>::type>
   104  struct get_param_helper {
   105    template <typename PkgPtrType> static DT get(const PkgPtrType &pkg) {
   106      return pkg->template get<IT>();
   107    };
   108  };
   109  
   110  template <>
   111  struct get_param_helper<
   112      p_holder, typename ::ff::util::internal::nt_traits<p_holder>::type> {
   113    template <typename PkgPtrType> static void *get(const PkgPtrType &pkg) {
   114      return reinterpret_cast<void *>(pkg->template get<p_holder>());
   115    };
   116  };
   117  // template <typename IT> struct get_param_helper<IT, std::string> {
   118  // template <typename PkgPtrType> static const char *get(const PkgPtrType &pkg)
   119  // { auto t = pkg->template get<IT>().c_str(); LOG(INFO) << "get param: " << t
   120  //<< ", should be: " << pkg->template get<IT>();
   121  // return t;
   122  //};
   123  //};
   124  
   125  template <typename PkgType, typename... Params> struct ipc_callback {
   126  
   127    // template <typename T, typename PkgPtrType>
   128    // static auto get_param_for_callback(const PkgPtrType &pkg) {
   129    // return get_param_helper<T>::get(pkg);
   130    //}
   131  
   132    template <typename T> static auto get_param_for_callback(const T &val) {
   133      return val;
   134    }
   135    static const char *get_param_for_callback(const std::string &val) {
   136      return val.c_str();
   137    }
   138  
   139    template <typename T1, typename Func>
   140    static void callback_invoke(Func &&f, PkgType *pkg,
   141                                enum ipc_status_code code) {
   142      auto t1 = get_param_helper<T1>::get(pkg);
   143      f(code, get_param_for_callback(t1));
   144    }
   145    template <typename T1, typename T2, typename Func>
   146    static void callback_invoke(Func &&f, PkgType *pkg,
   147                                enum ipc_status_code code) {
   148      auto t1 = get_param_helper<T1>::get(pkg);
   149      auto t2 = get_param_helper<T2>::get(pkg);
   150      f(code, get_param_for_callback(t1), get_param_for_callback(t2));
   151    }
   152    template <typename T1, typename T2, typename T3, typename Func>
   153    static void callback_invoke(Func &&f, PkgType *pkg,
   154                                enum ipc_status_code code) {
   155      auto t1 = get_param_helper<T1>::get(pkg);
   156      auto t2 = get_param_helper<T2>::get(pkg);
   157      auto t3 = get_param_helper<T3>::get(pkg);
   158      f(code, get_param_for_callback(t1), get_param_for_callback(t2),
   159        get_param_for_callback(t3));
   160    }
   161    template <typename T1, typename T2, typename T3, typename T4, typename Func>
   162    static void callback_invoke(Func &&f, PkgType *pkg,
   163                                enum ipc_status_code code) {
   164      auto t1 = get_param_helper<T1>::get(pkg);
   165      auto t2 = get_param_helper<T2>::get(pkg);
   166      auto t3 = get_param_helper<T3>::get(pkg);
   167      auto t4 = get_param_helper<T4>::get(pkg);
   168      f(code, get_param_for_callback(t1), get_param_for_callback(t2),
   169        get_param_for_callback(t3), get_param_for_callback(t4));
   170    }
   171    template <typename T1, typename T2, typename T3, typename T4, typename T5,
   172              typename Func>
   173    static void callback_invoke(Func &&f, PkgType *pkg,
   174                                enum ipc_status_code code) {
   175      auto t1 = get_param_helper<T1>::get(pkg);
   176      auto t2 = get_param_helper<T2>::get(pkg);
   177      auto t3 = get_param_helper<T3>::get(pkg);
   178      auto t4 = get_param_helper<T4>::get(pkg);
   179      auto t5 = get_param_helper<T5>::get(pkg);
   180      f(code, get_param_for_callback(t1), get_param_for_callback(t2),
   181        get_param_for_callback(t3), get_param_for_callback(t4),
   182        get_param_for_callback(t5));
   183    }
   184    template <typename T1, typename T2, typename T3, typename T4, typename T5,
   185              typename T6, typename Func>
   186    static void callback_invoke(Func &&f, PkgType *pkg,
   187                                enum ipc_status_code code) {
   188      auto t1 = get_param_helper<T1>::get(pkg);
   189      auto t2 = get_param_helper<T2>::get(pkg);
   190      auto t3 = get_param_helper<T3>::get(pkg);
   191      auto t4 = get_param_helper<T4>::get(pkg);
   192      auto t5 = get_param_helper<T5>::get(pkg);
   193      auto t6 = get_param_helper<T6>::get(pkg);
   194      f(code, get_param_for_callback(t1), get_param_for_callback(t2),
   195        get_param_for_callback(t3), get_param_for_callback(t4),
   196        get_param_for_callback(t5), get_param_for_callback(t6));
   197    }
   198    template <typename Func, typename... Args>
   199    static void bind(Func &&func, Args... args) {
   200      neb::core::ipc_callback_holder::instance().add_callback(
   201          PkgType().type_id(),
   202          [func, args...](enum ipc_status_code code, ff::net::package *pkg) {
   203            PkgType *ack = (PkgType *)pkg;
   204            if (code == ipc_status_succ) {
   205              callback_invoke<Params...>(func, ack, code);
   206            } else {
   207              neb::core::issue_callback_with_error(func, code);
   208            }
   209          });
   210    }
   211  };
   212  
   213  ////////////////////////////////////////////////
   214  int ipc_nbre_version(void *holder, uint64_t height) {
   215    return ipc_call<nbre_version_req, p_holder, p_height>::bind(holder, height);
   216  }
   217  void set_recv_nbre_version_callback(nbre_version_callback_t func) {
   218    ipc_callback<nbre_version_ack, p_holder, p_major, p_minor, p_patch>::bind(
   219        func, _2, _3, _4, _5);
   220  }
   221  int ipc_nbre_ir_list(void *holder) {
   222    return ipc_call<nbre_ir_list_req, p_holder>::bind(holder);
   223  }
   224  
   225  void set_recv_nbre_ir_list_callback(nbre_ir_list_callback_t func) {
   226    ipc_callback<nbre_ir_list_ack, p_holder, p_ir_name_list>::bind(func, _2, _3);
   227  }
   228  
   229  // interface ipc_nbre_ir_versions
   230  int ipc_nbre_ir_versions(void *holder, const char *ir_name) {
   231    return ipc_call<nbre_ir_versions_req, p_holder, p_ir_name>::bind(holder,
   232                                                                     ir_name);
   233  }
   234  void set_recv_nbre_ir_versions_callback(nbre_ir_versions_callback_t func) {
   235    ipc_callback<nbre_ir_versions_ack, p_holder, p_ir_versions>::bind(func, _2,
   236                                                                      _3);
   237  }
   238  
   239  // interface get nr handle
   240  int ipc_nbre_nr_handle(void *holder, uint64_t start_block, uint64_t end_block,
   241                         uint64_t nr_version) {
   242    return ipc_call<nbre_nr_handle_req, p_holder, p_start_block, p_end_block,
   243                    p_nr_version>::bind(holder, start_block, end_block,
   244                                        nr_version);
   245  }
   246  void set_recv_nbre_nr_handle_callback(nbre_nr_handle_callback_t func) {
   247    ipc_callback<nbre_nr_handle_ack, p_holder, p_nr_handle>::bind(func, _2, _3);
   248  }
   249  
   250  // interface get nr result by handle
   251  int ipc_nbre_nr_result_by_handle(void *holder, const char *nr_handle) {
   252    return ipc_call<nbre_nr_result_by_handle_req, p_holder, p_nr_handle>::bind(
   253        holder, nr_handle);
   254  }
   255  void set_recv_nbre_nr_result_by_handle_callback(
   256      nbre_nr_result_by_handle_callback_t func) {
   257    ipc_callback<nbre_nr_result_by_handle_ack, p_holder, p_nr_result>::bind(
   258        func, _2, _3);
   259  }
   260  
   261  // interface get nr result by height
   262  int ipc_nbre_nr_result_by_height(void *holder, uint64_t height) {
   263    return ipc_call<nbre_nr_result_by_height_req, p_holder, p_height>::bind(
   264        holder, height);
   265  }
   266  void set_recv_nbre_nr_result_by_height_callback(
   267      nbre_nr_result_by_height_callback_t func) {
   268    ipc_callback<nbre_nr_result_by_height_ack, p_holder, p_nr_result>::bind(
   269        func, _2, _3);
   270  }
   271  
   272  // interface get nr sum
   273  int ipc_nbre_nr_sum(void *holder, uint64_t height) {
   274    return ipc_call<nbre_nr_sum_req, p_holder, p_height>::bind(holder, height);
   275  }
   276  void set_recv_nbre_nr_sum_callback(nbre_nr_sum_callback_t func) {
   277    ipc_callback<nbre_nr_sum_ack, p_holder, p_nr_sum>::bind(func, _2, _3);
   278  }
   279  
   280  // interface get dip reward
   281  int ipc_nbre_dip_reward(void *holder, uint64_t height, uint64_t version) {
   282    return ipc_call<nbre_dip_reward_req, p_holder, p_height, p_version>::bind(
   283        holder, height, version);
   284  }
   285  void set_recv_nbre_dip_reward_callback(nbre_dip_reward_callback_t func) {
   286    ipc_callback<nbre_dip_reward_ack, p_holder, p_dip_reward>::bind(func, _2, _3);
   287  }
   288  
   289  // interface send ir transactions
   290  std::unique_ptr<std::vector<std::string>> _txs_ptr;
   291  uint64_t _height;
   292  int ipc_nbre_ir_transactions_create(void *holder, uint64_t height) {
   293    _txs_ptr = std::make_unique<std::vector<std::string>>();
   294    _height = height;
   295    return ipc_status_succ;
   296  }
   297  int ipc_nbre_ir_transactions_append(void *holder, uint64_t height,
   298                                      const char *tx_bytes,
   299                                      int32_t tx_bytes_len) {
   300    if (height != _height) {
   301      return ipc_status_fail;
   302    }
   303    _txs_ptr->push_back(std::string(tx_bytes, tx_bytes_len));
   304    return ipc_status_succ;
   305  }
   306  int ipc_nbre_ir_transactions_send(void *holder, uint64_t height) {
   307    if (height != _height) {
   308      return ipc_status_fail;
   309    }
   310    return ipc_call<nbre_ir_transactions_req, p_holder, p_height,
   311                    p_ir_transactions>::bind(holder, _height, *_txs_ptr);
   312  }
   313