github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/cmd/dummy_neb/dummies/stress_dummy.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 "cmd/dummy_neb/dummies/stress_dummy.h" 21 #include "cmd/dummy_neb/dummy_callback.h" 22 #include "cmd/dummy_neb/generator/checkers.h" 23 #include "fs/util.h" 24 25 stress_dummy::stress_dummy(const std::string &name, int initial_account_num, 26 nas initial_nas, int account_num, int contract_num, 27 int transfer_tx_num, int call_tx_num, 28 const std::string &rpc_listen, uint16_t rpc_port) 29 : dummy_base(name), m_initial_account_num(initial_account_num), 30 m_initial_nas(initial_nas), m_account_num(account_num), 31 m_contract_num(contract_num), m_transfer_tx_num(transfer_tx_num), 32 m_call_tx_num(call_tx_num), m_rpc_listen(rpc_listen), 33 m_rpc_port(rpc_port) { 34 35 m_cli_generator = std::make_unique<cli_generator>(); 36 m_thread = std::make_unique<std::thread>([this]() { 37 ff::net::net_nervure nn; 38 m_p_nn = &nn; 39 ff::net::typed_pkg_hub hub; 40 41 hub.tcp_to_recv_pkg<cli_submit_ir_t>( 42 [this](std::shared_ptr<cli_submit_ir_t> req, 43 ff::net::tcp_connection_base *conn) { 44 auto ack = std::make_shared<cli_submit_ack_t>(); 45 ack->set<p_result>("got ir"); 46 conn->send(ack); 47 m_pkgs.push_back(req); 48 }); 49 hub.to_recv_pkg<nbre_nr_handle_req>( 50 [this](std::shared_ptr<nbre_nr_handle_req> req) { 51 m_pkgs.push_back(req); 52 }); 53 54 hub.to_recv_pkg<nbre_nr_result_by_handle_req>( 55 [this](std::shared_ptr<nbre_nr_result_by_handle_req> req) { 56 m_pkgs.push_back(req); 57 }); 58 59 hub.to_recv_pkg<nbre_nr_result_by_height_req>( 60 [this](std::shared_ptr<nbre_nr_result_by_height_req> req) { 61 LOG(INFO) << "dummy server recv cli nr result req with height " 62 << req->get<p_height>(); 63 m_pkgs.push_back(req); 64 }); 65 66 hub.to_recv_pkg<nbre_nr_sum_req>( 67 [this](std::shared_ptr<nbre_nr_sum_req> req) { 68 m_pkgs.push_back(req); 69 }); 70 hub.to_recv_pkg<nbre_dip_reward_req>( 71 [this](std::shared_ptr<nbre_dip_reward_req> req) { 72 m_pkgs.push_back(req); 73 }); 74 75 nn.get_event_handler() 76 ->listen<::ff::net::event::more::tcp_server_accept_connection>( 77 [this](::ff::net::tcp_connection_base_ptr conn) { m_conn = conn; }); 78 79 nn.add_pkg_hub(hub); 80 nn.add_tcp_server(m_rpc_listen, m_rpc_port); 81 nn.run(); 82 }); 83 } 84 85 stress_dummy::~stress_dummy() { 86 if (m_p_nn) { 87 m_p_nn->stop(); 88 } 89 LOG(INFO) << "to kill thread"; 90 if (m_thread) 91 m_thread->join(); 92 LOG(INFO) << "kill thread done"; 93 } 94 95 void stress_dummy::handle_cli_pkgs() { 96 while (!m_pkgs.empty()) { 97 auto ret = m_pkgs.try_pop_front(); 98 if (!ret.first) 99 continue; 100 auto pkg = ret.second; 101 if (pkg->type_id() == cli_submit_ir_pkg) { 102 m_cli_generator->append_pkg(pkg); 103 } else if (pkg->type_id() == nbre_nr_handle_req_pkg) { 104 nbre_nr_handle_req *req = (nbre_nr_handle_req *)pkg.get(); 105 106 callback_handler::instance().add_nr_handler( 107 req->get<p_holder>(), 108 [this](uint64_t holder, const char *nr_handle_id) { 109 std::shared_ptr<nbre_nr_handle_ack> ack = 110 std::make_shared<nbre_nr_handle_ack>(); 111 ack->set<p_holder>(holder); 112 ack->set<p_nr_handle>(std::string(nr_handle_id)); 113 m_conn->send(ack); 114 }); 115 LOG(INFO) << "forward nr handle req"; 116 ipc_nbre_nr_handle(reinterpret_cast<void *>(req->get<p_holder>()), 117 req->get<p_start_block>(), req->get<p_end_block>(), 118 req->get<p_nr_version>()); 119 120 } else if (pkg->type_id() == nbre_nr_result_by_handle_req_pkg) { 121 nbre_nr_result_by_handle_req *req = 122 (nbre_nr_result_by_handle_req *)pkg.get(); 123 callback_handler::instance().add_nr_result_handler( 124 req->get<p_holder>(), [this](uint64_t holder, const char *nr_result) { 125 std::shared_ptr<nbre_nr_result_by_handle_ack> ack = 126 std::make_shared<nbre_nr_result_by_handle_ack>(); 127 ack->set<p_holder>(holder); 128 ack->set<p_nr_result>(std::string(nr_result)); 129 m_conn->send(ack); 130 }); 131 ipc_nbre_nr_result_by_handle( 132 reinterpret_cast<void *>(req->get<p_holder>()), 133 req->get<p_nr_handle>().c_str()); 134 } else if (pkg->type_id() == nbre_nr_result_by_height_req_pkg) { 135 LOG(INFO) << "handle pkg nr result by height req"; 136 nbre_nr_result_by_height_req *req = 137 (nbre_nr_result_by_height_req *)pkg.get(); 138 callback_handler::instance().add_nr_result_by_height_handler( 139 req->get<p_holder>(), [this](uint64_t holder, const char *nr_result) { 140 std::shared_ptr<nbre_nr_result_by_height_ack> ack = 141 std::make_shared<nbre_nr_result_by_height_ack>(); 142 ack->set<p_holder>(holder); 143 ack->set<p_nr_result>(std::string(nr_result)); 144 m_conn->send(ack); 145 }); 146 ipc_nbre_nr_result_by_height( 147 reinterpret_cast<void *>(req->get<p_holder>()), req->get<p_height>()); 148 } else if (pkg->type_id() == nbre_nr_sum_req_pkg) { 149 nbre_nr_sum_req *req = (nbre_nr_sum_req *)pkg.get(); 150 callback_handler::instance().add_nr_sum_handler( 151 req->get<p_holder>(), [this](uint64_t holder, const char *nr_sum) { 152 std::shared_ptr<nbre_nr_sum_ack> ack = 153 std::make_shared<nbre_nr_sum_ack>(); 154 ack->set<p_holder>(holder); 155 ack->set<p_nr_sum>(std::string(nr_sum)); 156 m_conn->send(ack); 157 }); 158 ipc_nbre_nr_sum(reinterpret_cast<void *>(req->get<p_holder>()), 159 req->get<p_height>()); 160 } else if (pkg->type_id() == nbre_dip_reward_req_pkg) { 161 nbre_dip_reward_req *req = (nbre_dip_reward_req *)pkg.get(); 162 callback_handler::instance().add_dip_reward_handler( 163 req->get<p_holder>(), 164 [this](uint64_t holder, const char *dip_reward) { 165 std::shared_ptr<nbre_dip_reward_ack> ack = 166 std::make_shared<nbre_dip_reward_ack>(); 167 ack->set<p_holder>(holder); 168 ack->set<p_dip_reward>(std::string(dip_reward)); 169 m_conn->send(ack); 170 }); 171 ipc_nbre_dip_reward(reinterpret_cast<void *>(req->get<p_holder>()), 172 req->get<p_height>(), req->get<p_version>()); 173 } else { 174 LOG(INFO) << "pkg type id " << pkg->type_id() << " not found"; 175 } 176 } 177 } 178 179 void stress_dummy::init_ir_and_accounts() { 180 LOG(INFO) << "init ir and accounts"; 181 std::shared_ptr<generate_block> ret = 182 std::make_shared<generate_block>(&m_all_accounts, m_current_height); 183 for (auto i = 0; i < m_account_num; i++) { 184 ret->gen_user_account(); 185 } 186 LOG(INFO) << "gen user account done"; 187 188 m_contract_gen = 189 std::make_unique<contract_generator>(ret.get(), m_initial_account_num); 190 m_contract_gen->run(); 191 192 // gen auth 193 m_auth_gen = 194 std::make_unique<auth_table_generator>(&m_all_accounts, ret.get()); 195 m_auth_gen->set_auth_admin_addr(m_auth_admin_addr); 196 m_auth_gen->set_nr_admin_addr(m_auth_admin_addr); 197 m_auth_gen->set_dip_admin_addr(m_auth_admin_addr); 198 m_auth_gen->run(); 199 LOG(INFO) << "gen auth done"; 200 201 // gen nr 202 neb::version nr_v(0); 203 m_nr_gen = std::make_unique<nr_ir_generator>(ret.get(), m_auth_admin_addr); 204 random_increase_version(nr_v); 205 m_nr_gen->m_major_version = nr_v.major_version(); 206 m_nr_gen->m_minor_version = nr_v.minor_version(); 207 m_nr_gen->m_patch_version = nr_v.patch_version(); 208 m_nr_gen->run(); 209 LOG(INFO) << "gen nr done"; 210 211 // gen dip 212 neb::version dip_v(0); 213 m_dip_gen = std::make_unique<dip_ir_generator>(ret.get(), m_auth_admin_addr); 214 random_increase_version(dip_v); 215 m_dip_gen->m_major_version = dip_v.major_version(); 216 m_dip_gen->m_minor_version = dip_v.minor_version(); 217 m_dip_gen->m_patch_version = dip_v.patch_version(); 218 m_dip_gen->m_nr_version = nr_v.data(); 219 m_dip_gen->run(); 220 LOG(INFO) << "gen dip done"; 221 } 222 223 std::shared_ptr<generate_block> stress_dummy::generate_LIB_block() { 224 225 handle_cli_pkgs(); 226 227 std::shared_ptr<generate_block> ret = 228 std::make_shared<generate_block>(&m_all_accounts, m_current_height); 229 230 if (m_current_height == 0) { 231 genesis_generator g(ret.get(), m_initial_account_num, m_initial_nas); 232 g.run(); 233 m_current_height++; 234 return ret; 235 } 236 237 if (m_current_height == 1) { 238 init_ir_and_accounts(); 239 } 240 241 int32_t week_blocks = 7 * 24 * 3600 / 15; 242 double tx_ratio = m_account_num * 1.0 / week_blocks; 243 double contract_ratio = m_contract_num * 1.0 / week_blocks; 244 double call_ratio = m_call_tx_num * 1.0 / week_blocks; 245 246 int32_t tx_num = tx_ratio; 247 int32_t contract_num = contract_ratio; 248 int32_t call_num = call_ratio; 249 250 // binary tx 251 if (tx_ratio > 1.0) { 252 tx_ratio -= tx_num; 253 } 254 if (std::rand() % week_blocks < tx_ratio * week_blocks) { 255 tx_num++; 256 } 257 m_tx_gen = std::make_unique<transaction_generator>(&m_all_accounts, ret.get(), 258 0, tx_num); 259 m_tx_gen->run(); 260 261 // deploy tx 262 if (contract_ratio > 1.0) { 263 contract_ratio -= contract_num; 264 } 265 if (std::rand() % week_blocks < contract_ratio * week_blocks) { 266 contract_num++; 267 } 268 m_contract_gen = 269 std::make_unique<contract_generator>(ret.get(), contract_num); 270 m_contract_gen->run(); 271 272 // call tx 273 if (call_ratio > 1.0) { 274 call_ratio -= call_num; 275 } 276 if (std::rand() % week_blocks < call_ratio * week_blocks) { 277 call_num++; 278 } 279 m_call_gen = std::make_unique<call_tx_generator>(ret.get(), call_num); 280 m_call_gen->run(); 281 282 m_current_height++; 283 return ret; 284 } 285 286 std::shared_ptr<checker_task_base> stress_dummy::generate_checker_task() { 287 auto ret = std::make_shared<nbre_version_checker>(); 288 return ret; 289 } 290 291 address_t stress_dummy::get_auth_admin_addr() { 292 if (m_current_height == 0) { 293 generate_LIB_block(); 294 } 295 if (m_auth_admin_addr.empty()) { 296 m_auth_admin_addr = m_all_accounts.random_user_addr(); 297 } 298 return m_auth_admin_addr; 299 } 300