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  }