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