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