github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/cmd/dummy_neb/dummies/random_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/random_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 random_dummy::random_dummy(const std::string &name, int initial_account_num, 26 nas initial_nas, double account_increase_ratio, 27 const std::string &rpc_listen, uint16_t rpc_port) 28 : dummy_base(name), m_initial_account_num(initial_account_num), 29 m_initial_nas(initial_nas), 30 m_account_increase_ratio(account_increase_ratio), m_auth_ratio(0), 31 m_rpc_listen(rpc_listen), m_rpc_port(rpc_port) { 32 m_cli_generator = std::make_unique<cli_generator>(); 33 m_thread = std::make_unique<std::thread>([this]() { 34 ff::net::net_nervure nn; 35 m_p_nn = &nn; 36 ff::net::typed_pkg_hub hub; 37 hub.tcp_to_recv_pkg<cli_brief_req_t>( 38 [this](std::shared_ptr<cli_brief_req_t> req, 39 ff::net::tcp_connection_base *conn) { 40 auto ack = std::make_shared<cli_brief_ack_t>(); 41 ack->set<p_height>(m_current_height); 42 ack->set<p_account_num>(m_all_accounts.size()); 43 // ack->set<p_nr_ir_status>(std::string()); 44 // ack->set<p_auth_ir_status>(std::string()); 45 // ack->set<p_dip_ir_status>(std::string()); 46 auto status = checker_tasks::instance().status(); 47 std::string fp = 48 neb::fs::join_path(neb::configuration::instance().nbre_db_dir(), 49 "checker_status.txt"); 50 std::ofstream ifp(fp); 51 ifp << status; 52 ifp.close(); 53 ack->set<p_checker_status>(fp); 54 conn->send(ack); 55 }); 56 57 hub.tcp_to_recv_pkg<cli_submit_ir_t>( 58 [this](std::shared_ptr<cli_submit_ir_t> req, 59 ff::net::tcp_connection_base *conn) { 60 auto ack = std::make_shared<cli_submit_ack_t>(); 61 ack->set<p_result>("got ir"); 62 conn->send(ack); 63 m_pkgs.push_back(req); 64 }); 65 hub.to_recv_pkg<nbre_nr_handle_req>( 66 [this](std::shared_ptr<nbre_nr_handle_req> req) { 67 m_pkgs.push_back(req); 68 }); 69 70 hub.to_recv_pkg<nbre_nr_result_by_handle_req>( 71 [this](std::shared_ptr<nbre_nr_result_by_handle_req> req) { 72 m_pkgs.push_back(req); 73 }); 74 75 hub.to_recv_pkg<nbre_nr_result_by_height_req>( 76 [this](std::shared_ptr<nbre_nr_result_by_height_req> req) { 77 LOG(INFO) << "dummy server recv cli nr result req with height " 78 << req->get<p_height>(); 79 m_pkgs.push_back(req); 80 }); 81 82 hub.to_recv_pkg<nbre_nr_sum_req>( 83 [this](std::shared_ptr<nbre_nr_sum_req> req) { 84 m_pkgs.push_back(req); 85 }); 86 hub.to_recv_pkg<nbre_dip_reward_req>( 87 [this](std::shared_ptr<nbre_dip_reward_req> req) { 88 m_pkgs.push_back(req); 89 }); 90 91 nn.get_event_handler() 92 ->listen<::ff::net::event::more::tcp_server_accept_connection>( 93 [this](::ff::net::tcp_connection_base_ptr conn) { m_conn = conn; }); 94 95 nn.add_pkg_hub(hub); 96 nn.add_tcp_server(m_rpc_listen, m_rpc_port); 97 nn.run(); 98 }); 99 } 100 101 random_dummy::~random_dummy() { 102 if (m_p_nn) { 103 m_p_nn->stop(); 104 } 105 LOG(INFO) << "to kill thread"; 106 if (m_thread) 107 m_thread->join(); 108 LOG(INFO) << "kill thread done"; 109 } 110 111 std::shared_ptr<generate_block> random_dummy::generate_LIB_block() { 112 113 handle_cli_pkgs(); 114 115 std::shared_ptr<generate_block> ret = 116 std::make_shared<generate_block>(&m_all_accounts, m_current_height); 117 118 if (m_current_height == 0) { 119 genesis_generator g(ret.get(), m_initial_account_num, m_initial_nas); 120 g.run(); 121 } else { 122 int account_num = m_account_increase_ratio * m_initial_account_num; 123 int tx_num = account_num + std::rand() % m_initial_account_num; 124 LOG(INFO) << "transaction num is : " << tx_num; 125 m_tx_gen = std::make_unique<transaction_generator>( 126 &m_all_accounts, ret.get(), 127 m_account_increase_ratio * m_initial_account_num, tx_num); 128 m_tx_gen->run(); 129 130 if (std::abs(m_auth_ratio) > 1e-9 && 131 std::rand() % 1000 < m_auth_ratio * 1000 && 132 m_current_height % m_auth_interval == 0) { 133 m_auth_gen = 134 std::make_unique<auth_table_generator>(&m_all_accounts, ret.get()); 135 address_t nr_admin_addr = m_auth_admin_addr; 136 address_t dip_admin_addr = m_auth_admin_addr; 137 m_nr_admin_addr = nr_admin_addr; 138 m_dip_admin_addr = dip_admin_addr; 139 m_auth_gen->set_auth_admin_addr(m_auth_admin_addr); 140 m_auth_gen->set_nr_admin_addr(nr_admin_addr); 141 m_auth_gen->set_dip_admin_addr(dip_admin_addr); 142 m_auth_gen->run(); 143 } 144 145 if (std::abs(m_nr_ratio) > 1e-9 && std::rand() % 1000 < m_nr_ratio * 1000 && 146 m_current_height % m_nr_interval == 0) { 147 if (m_nr_admin_addr.empty()) { 148 m_nr_admin_addr = m_auth_admin_addr; 149 } 150 m_nr_gen = std::make_unique<nr_ir_generator>(ret.get(), m_nr_admin_addr); 151 random_increase_version(m_nr_version); 152 m_nr_gen->m_major_version = m_nr_version.major_version(); 153 m_nr_gen->m_minor_version = m_nr_version.minor_version(); 154 m_nr_gen->m_patch_version = m_nr_version.patch_version(); 155 156 m_nr_gen->run(); 157 } 158 159 if (std::abs(m_dip_ratio) > 1e-9 && 160 std::rand() % 1000 < m_dip_ratio * 1000 && 161 m_current_height % m_dip_interval == 0) { 162 if (m_dip_admin_addr.empty()) { 163 m_dip_admin_addr = m_auth_admin_addr; 164 } 165 m_dip_gen = 166 std::make_unique<dip_ir_generator>(ret.get(), m_dip_admin_addr); 167 random_increase_version(m_dip_version); 168 m_dip_gen->m_major_version = m_dip_version.major_version(); 169 m_dip_gen->m_minor_version = m_dip_version.minor_version(); 170 m_dip_gen->m_patch_version = m_dip_version.patch_version(); 171 m_dip_gen->m_nr_version = m_nr_version.data(); 172 173 m_dip_gen->run(); 174 } 175 176 if (std::abs(m_contract_ratio) > 1e-9 && 177 std::rand() % 1000 < m_contract_ratio * 1000) { 178 m_contract_gen = std::make_unique<contract_generator>(ret.get(), 1); 179 m_contract_gen->run(); 180 } 181 if (std::abs(m_call_ratio) > 1e-9 && 182 std::rand() % 1000 < m_call_ratio * 1000) { 183 m_call_gen = std::make_unique<call_tx_generator>( 184 ret.get(), std::rand() % (m_all_accounts.size() / 5)); 185 m_call_gen->run(); 186 } 187 188 m_cli_generator->m_auth_admin_addr = m_auth_admin_addr; 189 m_cli_generator->m_nr_admin_addr = m_nr_admin_addr; 190 m_cli_generator->m_dip_admin_addr = m_dip_admin_addr; 191 m_cli_generator->update_info(ret.get()); 192 m_cli_generator->run(); 193 m_auth_admin_addr = m_cli_generator->m_auth_admin_addr; 194 m_nr_admin_addr = m_cli_generator->m_nr_admin_addr; 195 m_dip_admin_addr = m_cli_generator->m_dip_admin_addr; 196 } 197 198 m_current_height++; 199 return ret; 200 } 201 202 address_t 203 random_dummy::enable_auth_gen_with_ratio(double auth_ratio, 204 block_height_t block_interval) { 205 if (m_current_height == 0) 206 generate_LIB_block(); 207 corepb::Account *admin_account = m_all_accounts.random_user_account(); 208 address_t admin_addr = neb::to_address(admin_account->address()); 209 m_auth_admin_addr = admin_addr; 210 m_auth_ratio = auth_ratio; 211 m_auth_interval = block_interval; 212 return admin_addr; 213 } 214 void random_dummy::enable_nr_ir_with_ratio(double nr_ratio, 215 block_height_t block_interval) { 216 if (m_current_height == 0) 217 generate_LIB_block(); 218 m_nr_ratio = nr_ratio; 219 m_nr_interval = block_interval; 220 } 221 void random_dummy::enable_dip_ir_with_ratio(double dip_ratio, 222 block_height_t block_interval) { 223 if (m_current_height == 0) 224 generate_LIB_block(); 225 m_dip_ratio = dip_ratio; 226 m_dip_interval = block_interval; 227 } 228 229 void random_dummy::enable_call_tx_with_ratio(double contract_ratio, 230 double call_ratio) { 231 if (m_current_height == 0) 232 generate_LIB_block(); 233 m_contract_ratio = contract_ratio; 234 m_call_ratio = call_ratio; 235 } 236 237 std::shared_ptr<checker_task_base> random_dummy::generate_checker_task() { 238 std::shared_ptr<checker_task_base> ret; 239 if (m_current_height > 0 && m_current_height % 2 == 0) { 240 int m = std::rand() % 5; 241 switch (m) { 242 case 0: 243 if (!m_version_checker) { 244 m_version_checker = std::make_shared<nbre_version_checker>(); 245 ret = m_version_checker; 246 } 247 break; 248 case 1: { 249 uint64_t t1 = std::rand() % m_current_height; 250 uint64_t t2 = std::rand() % m_current_height; 251 ret = std::make_shared<nbre_nr_handle_check>(std::min(t1, t2), 252 std::max(t1, t2)); 253 break; 254 } 255 case 2: 256 break; 257 case 3: 258 ret = std::make_shared<nbre_dip_reward_check>(std::rand() % 259 m_current_height); 260 break; 261 case 4: 262 break; 263 } 264 265 if (ret) { 266 checker_tasks::instance().add_task(ret); 267 } 268 } 269 return ret; 270 } 271 272 address_t random_dummy::get_auth_admin_addr() { 273 if (m_current_height == 0) 274 generate_LIB_block(); 275 if (m_auth_admin_addr.empty()) { 276 m_auth_admin_addr = m_all_accounts.random_user_addr(); 277 } 278 return m_auth_admin_addr; 279 } 280 281 void random_dummy::handle_cli_pkgs() { 282 while (!m_pkgs.empty()) { 283 auto ret = m_pkgs.try_pop_front(); 284 if (!ret.first) 285 continue; 286 auto pkg = ret.second; 287 if (pkg->type_id() == cli_submit_ir_pkg) { 288 m_cli_generator->append_pkg(pkg); 289 } else if (pkg->type_id() == nbre_nr_handle_req_pkg) { 290 nbre_nr_handle_req *req = (nbre_nr_handle_req *)pkg.get(); 291 292 callback_handler::instance().add_nr_handler( 293 req->get<p_holder>(), 294 [this](uint64_t holder, const char *nr_handle_id) { 295 std::shared_ptr<nbre_nr_handle_ack> ack = 296 std::make_shared<nbre_nr_handle_ack>(); 297 ack->set<p_holder>(holder); 298 ack->set<p_nr_handle>(std::string(nr_handle_id)); 299 m_conn->send(ack); 300 }); 301 LOG(INFO) << "forward nr handle req"; 302 ipc_nbre_nr_handle(reinterpret_cast<void *>(req->get<p_holder>()), 303 req->get<p_start_block>(), req->get<p_end_block>(), 304 req->get<p_nr_version>()); 305 306 } else if (pkg->type_id() == nbre_nr_result_by_handle_req_pkg) { 307 nbre_nr_result_by_handle_req *req = 308 (nbre_nr_result_by_handle_req *)pkg.get(); 309 callback_handler::instance().add_nr_result_handler( 310 req->get<p_holder>(), [this](uint64_t holder, const char *nr_result) { 311 std::shared_ptr<nbre_nr_result_by_handle_ack> ack = 312 std::make_shared<nbre_nr_result_by_handle_ack>(); 313 ack->set<p_holder>(holder); 314 ack->set<p_nr_result>(std::string(nr_result)); 315 m_conn->send(ack); 316 }); 317 ipc_nbre_nr_result_by_handle( 318 reinterpret_cast<void *>(req->get<p_holder>()), 319 req->get<p_nr_handle>().c_str()); 320 } else if (pkg->type_id() == nbre_nr_result_by_height_req_pkg) { 321 LOG(INFO) << "handle pkg nr result by height req"; 322 nbre_nr_result_by_height_req *req = 323 (nbre_nr_result_by_height_req *)pkg.get(); 324 callback_handler::instance().add_nr_result_by_height_handler( 325 req->get<p_holder>(), [this](uint64_t holder, const char *nr_result) { 326 std::shared_ptr<nbre_nr_result_by_height_ack> ack = 327 std::make_shared<nbre_nr_result_by_height_ack>(); 328 ack->set<p_holder>(holder); 329 ack->set<p_nr_result>(std::string(nr_result)); 330 m_conn->send(ack); 331 }); 332 ipc_nbre_nr_result_by_height( 333 reinterpret_cast<void *>(req->get<p_holder>()), req->get<p_height>()); 334 } else if (pkg->type_id() == nbre_nr_sum_req_pkg) { 335 nbre_nr_sum_req *req = (nbre_nr_sum_req *)pkg.get(); 336 callback_handler::instance().add_nr_sum_handler( 337 req->get<p_holder>(), [this](uint64_t holder, const char *nr_sum) { 338 std::shared_ptr<nbre_nr_sum_ack> ack = 339 std::make_shared<nbre_nr_sum_ack>(); 340 ack->set<p_holder>(holder); 341 ack->set<p_nr_sum>(std::string(nr_sum)); 342 m_conn->send(ack); 343 }); 344 ipc_nbre_nr_sum(reinterpret_cast<void *>(req->get<p_holder>()), 345 req->get<p_height>()); 346 } else if (pkg->type_id() == nbre_dip_reward_req_pkg) { 347 nbre_dip_reward_req *req = (nbre_dip_reward_req *)pkg.get(); 348 callback_handler::instance().add_dip_reward_handler( 349 req->get<p_holder>(), 350 [this](uint64_t holder, const char *dip_reward) { 351 std::shared_ptr<nbre_dip_reward_ack> ack = 352 std::make_shared<nbre_dip_reward_ack>(); 353 ack->set<p_holder>(holder); 354 ack->set<p_dip_reward>(std::string(dip_reward)); 355 m_conn->send(ack); 356 }); 357 ipc_nbre_dip_reward(reinterpret_cast<void *>(req->get<p_holder>()), 358 req->get<p_height>(), req->get<p_version>()); 359 } else { 360 LOG(INFO) << "pkg type id " << pkg->type_id() << " not found"; 361 } 362 } 363 }