github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/test/runtime/dip/gtest_dip_reward.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  
    21  #include "common/common.h"
    22  #include "runtime/dip/dip_reward.h"
    23  #include "runtime/util.h"
    24  #include <gtest/gtest.h>
    25  #include <random>
    26  #define PRECESION 1e-5
    27  
    28  template <typename T> T precesion(const T &x, float pre = PRECESION) {
    29    return std::fabs(T(x * pre));
    30  }
    31  
    32  std::vector<std::shared_ptr<neb::rt::dip::dip_info_t>>
    33  gen_dip_infos(std::vector<std::pair<std::string, std::string>> &meta) {
    34  
    35    std::random_device rd;
    36    std::mt19937 mt(rd());
    37    std::uniform_int_distribution<> dis(0, std::numeric_limits<int16_t>::max());
    38  
    39    std::vector<std::shared_ptr<neb::rt::dip::dip_info_t>> ret;
    40    meta.push_back(std::make_pair("start_height", std::to_string(dis(mt))));
    41    meta.push_back(std::make_pair("end_height", std::to_string(dis(mt))));
    42    meta.push_back(std::make_pair("version", std::to_string(dis(mt))));
    43    int32_t infos_size = std::sqrt(dis(mt));
    44    for (int32_t i = 0; i < infos_size; i++) {
    45      auto info_ptr =
    46          std::shared_ptr<neb::rt::dip::dip_info_t>(new neb::rt::dip::dip_info_t{
    47              neb::to_address(std::to_string(uint32_t(std::pow(dis(mt), 0.3)))),
    48              neb::to_address(std::to_string(uint32_t(std::pow(dis(mt), 0.3)))),
    49              std::to_string(dis(mt))});
    50      ret.push_back(info_ptr);
    51    }
    52    return ret;
    53  }
    54  
    55  TEST(test_runtime_dip_reward, json_seri_deseri) {
    56    neb::rt::dip::dip_ret_type dip_ret;
    57    std::get<0>(dip_ret) = 1;
    58    std::vector<std::pair<std::string, std::string>> meta;
    59    auto &ret = std::get<2>(dip_ret);
    60    ret = gen_dip_infos(meta);
    61    std::get<1>(dip_ret) = neb::rt::meta_info_to_json(meta);
    62    auto str_ptr = neb::rt::dip::dip_reward::dip_info_to_json(dip_ret);
    63    dip_ret = neb::rt::dip::dip_reward::json_to_dip_info(*str_ptr);
    64    auto &info_v = std::get<2>(dip_ret);
    65    EXPECT_EQ(ret.size(), info_v.size());
    66  
    67    for (size_t i = 0; i < ret.size(); i++) {
    68      EXPECT_EQ(ret[i]->m_deployer, info_v[i]->m_deployer);
    69      EXPECT_EQ(ret[i]->m_contract, info_v[i]->m_contract);
    70      EXPECT_EQ(ret[i]->m_reward, info_v[i]->m_reward);
    71    }
    72  }
    73  
    74  TEST(test_runtime_dip_reward, back_to_coinbase) {
    75    std::vector<std::shared_ptr<neb::rt::dip::dip_info_t>> infos;
    76    neb::floatxx_t reward_left(0);
    77    neb::address_t coinbase_addr = neb::to_address(std::string());
    78    neb::rt::dip::dip_reward::back_to_coinbase(infos, reward_left, coinbase_addr);
    79    EXPECT_TRUE(infos.empty());
    80  
    81    infos.clear();
    82    reward_left = 1;
    83    neb::rt::dip::dip_reward::back_to_coinbase(infos, reward_left, coinbase_addr);
    84    EXPECT_TRUE(infos.empty());
    85  
    86    infos.clear();
    87    coinbase_addr = neb::to_address(std::string("a"));
    88    neb::rt::dip::dip_reward::back_to_coinbase(infos, reward_left, coinbase_addr);
    89    EXPECT_TRUE(!infos.empty());
    90  
    91    infos.clear();
    92    reward_left = 0;
    93    neb::rt::dip::dip_reward::back_to_coinbase(infos, reward_left, coinbase_addr);
    94    EXPECT_TRUE(infos.empty());
    95  
    96    std::vector<std::pair<std::string, std::string>> meta;
    97    auto ret = gen_dip_infos(meta);
    98    std::random_device rd;
    99    std::mt19937 mt(rd());
   100    std::uniform_int_distribution<> dis(1, std::numeric_limits<int16_t>::max());
   101  
   102    infos.clear();
   103    infos = ret;
   104    size_t infos_size = infos.size();
   105    reward_left = dis(mt);
   106    coinbase_addr = std::pow(dis(mt), 0.3);
   107    neb::rt::dip::dip_reward::back_to_coinbase(infos, reward_left, coinbase_addr);
   108    EXPECT_TRUE(!infos.empty());
   109    EXPECT_EQ(infos_size + 1, infos.size());
   110  }
   111  
   112  TEST(test_runtime_dip_reward, ignore_account_transfer_contract) {
   113    std::random_device rd;
   114    std::mt19937 mt(rd());
   115    std::uniform_int_distribution<> dis(1, std::numeric_limits<int16_t>::max());
   116    size_t txs_size = std::sqrt(dis(mt));
   117  
   118    std::vector<std::string> tx_type_v({"binary", "call", "deploy", "protocol"});
   119    std::unordered_map<std::string, int32_t> tx_type_cnt;
   120    std::vector<neb::fs::transaction_info_t> txs;
   121  
   122    for (size_t i = 0; i < txs_size; i++) {
   123      neb::fs::transaction_info_t info;
   124      info.m_tx_type = tx_type_v[dis(mt) % tx_type_v.size()];
   125      txs.push_back(info);
   126      tx_type_cnt[info.m_tx_type]++;
   127    }
   128  
   129    std::string type = tx_type_v[dis(mt) % tx_type_v.size()];
   130    neb::rt::dip::dip_reward::ignore_account_transfer_contract(txs, type);
   131    EXPECT_EQ(txs.size(), txs_size - tx_type_cnt[type]);
   132  }
   133  
   134  TEST(test_runtime_dip_reward, account_call_contract_count) {
   135    size_t ch_size = 'z' - 'a';
   136    std::random_device rd;
   137    std::mt19937 mt(rd());
   138    std::uniform_int_distribution<> dis(0, ch_size);
   139    size_t txs_size = dis(mt) * dis(mt);
   140    txs_size++;
   141  
   142    std::vector<std::vector<int32_t>> s2t = std::vector<std::vector<int32_t>>(
   143        ch_size + 1, std::vector<int32_t>(ch_size + 1, 0));
   144  
   145    std::vector<neb::fs::transaction_info_t> txs;
   146    for (size_t i = 0; i < txs_size; i++) {
   147      char ch_s = 'a' + dis(mt);
   148      char ch_t = 'A' + dis(mt);
   149  
   150      s2t[ch_s - 'a'][ch_t - 'A']++;
   151  
   152      neb::fs::transaction_info_t info;
   153      info.m_from = neb::to_address(std::string(1, ch_s));
   154      info.m_to = neb::to_address(std::string(1, ch_t));
   155      txs.push_back(info);
   156    }
   157  
   158    auto ret = neb::rt::dip::dip_reward::account_call_contract_count(txs);
   159    for (size_t i = 0; i < s2t.size(); i++) {
   160      int32_t row_not_empty = 0;
   161      for (size_t j = 0; j < s2t[0].size(); j++) {
   162        if (s2t[i][j]) {
   163          row_not_empty++;
   164        }
   165      }
   166      auto tmp = ret->find(neb::to_address(std::string(1, 'a' + i)));
   167      if (row_not_empty) {
   168        EXPECT_TRUE(tmp != ret->end());
   169        EXPECT_EQ(row_not_empty, tmp->second.size());
   170      } else {
   171        EXPECT_TRUE(tmp == ret->end());
   172      }
   173    }
   174    for (size_t i = 0; i < s2t.size(); i++) {
   175      for (size_t j = 0; j < s2t[0].size(); j++) {
   176        if (s2t[i][j]) {
   177          auto tmp = ret->find(neb::to_address(std::string(1, 'a' + i)));
   178          EXPECT_TRUE(tmp != ret->end());
   179          auto temp = tmp->second.find(neb::to_address(std::string(1, 'A' + j)));
   180          EXPECT_TRUE(temp != tmp->second.end());
   181          EXPECT_EQ(s2t[i][j], temp->second);
   182        }
   183      }
   184    }
   185  }
   186  
   187  TEST(test_runtime_dip_reward, account_to_contract_votes) {
   188    std::vector<neb::fs::transaction_info_t> txs;
   189    neb::fs::transaction_info_t tx;
   190    tx.m_from = neb::to_address("a");
   191    tx.m_to = neb::to_address("A");
   192    txs.push_back(tx);
   193  
   194    std::vector<std::shared_ptr<neb::rt::nr::nr_info_t>> nr_infos;
   195    auto info_ptr = std::make_shared<neb::rt::nr::nr_info_t>();
   196    info_ptr->m_address = neb::to_address("a");
   197    info_ptr->m_nr_score = 1;
   198    nr_infos.push_back(info_ptr);
   199  
   200    auto ret = neb::rt::dip::dip_reward::account_to_contract_votes(txs, nr_infos);
   201    EXPECT_EQ(ret->size(), 1);
   202    auto tmp = ret->find(neb::to_address("a"));
   203    EXPECT_TRUE(tmp != ret->end());
   204    auto temp = tmp->second.find(neb::to_address("A"));
   205    EXPECT_TRUE(temp != tmp->second.end());
   206    EXPECT_EQ(temp->second, 1);
   207  
   208    // add account
   209    tx.m_from = neb::to_address("b");
   210    tx.m_to = neb::to_address("A");
   211    txs.push_back(tx);
   212    info_ptr = std::make_shared<neb::rt::nr::nr_info_t>();
   213    info_ptr->m_address = neb::to_address("b");
   214    info_ptr->m_nr_score = 1;
   215    nr_infos.push_back(info_ptr);
   216  
   217    ret = neb::rt::dip::dip_reward::account_to_contract_votes(txs, nr_infos);
   218    EXPECT_EQ(ret->size(), 2);
   219    tmp = ret->find(neb::to_address("a"));
   220    EXPECT_TRUE(tmp != ret->end());
   221    temp = tmp->second.find(neb::to_address("A"));
   222    EXPECT_TRUE(temp != tmp->second.end());
   223    EXPECT_EQ(temp->second, 1);
   224  
   225    tmp = ret->find(neb::to_address("b"));
   226    EXPECT_TRUE(tmp != ret->end());
   227    temp = tmp->second.find(neb::to_address("A"));
   228    EXPECT_TRUE(temp != tmp->second.end());
   229    EXPECT_EQ(temp->second, 1);
   230  }
   231  
   232  TEST(test_runtime_dip_reward, dapp_votes) {
   233    std::vector<neb::fs::transaction_info_t> txs;
   234    neb::fs::transaction_info_t tx;
   235    tx.m_from = neb::to_address("a");
   236    tx.m_to = neb::to_address("A");
   237    txs.push_back(tx);
   238  
   239    std::vector<std::shared_ptr<neb::rt::nr::nr_info_t>> nr_infos;
   240    auto info_ptr = std::make_shared<neb::rt::nr::nr_info_t>();
   241    info_ptr->m_address = neb::to_address("a");
   242    info_ptr->m_nr_score = 1;
   243    nr_infos.push_back(info_ptr);
   244  
   245    auto tmp = neb::rt::dip::dip_reward::account_to_contract_votes(txs, nr_infos);
   246    auto ret = neb::rt::dip::dip_reward::dapp_votes(*tmp);
   247    EXPECT_EQ(ret->size(), 1);
   248    EXPECT_EQ(ret->begin()->first, neb::to_address("A"));
   249    neb::floatxx_t val = ret->begin()->second;
   250    EXPECT_TRUE(neb::math::abs(val, neb::floatxx_t(1)) < precesion(1e-1));
   251  
   252    tx.m_from = neb::to_address("b");
   253    tx.m_to = neb::to_address("A");
   254    txs.push_back(tx);
   255    info_ptr = std::make_shared<neb::rt::nr::nr_info_t>();
   256    info_ptr->m_address = neb::to_address("b");
   257    info_ptr->m_nr_score = 1;
   258    nr_infos.push_back(info_ptr);
   259  
   260    tmp = neb::rt::dip::dip_reward::account_to_contract_votes(txs, nr_infos);
   261    ret = neb::rt::dip::dip_reward::dapp_votes(*tmp);
   262    EXPECT_EQ(ret->size(), 1);
   263    EXPECT_EQ(ret->begin()->first, neb::to_address("A"));
   264    val = ret->begin()->second;
   265    EXPECT_TRUE(neb::math::abs(val, neb::floatxx_t(2)) < precesion(1e-1));
   266  }
   267  
   268  TEST(test_runtime_dip_reward, participate_lambda) {
   269    std::vector<neb::fs::transaction_info_t> txs;
   270    neb::fs::transaction_info_t tx;
   271    tx.m_from = neb::to_address("a");
   272    tx.m_to = neb::to_address("A");
   273    txs.push_back(tx);
   274  
   275    std::vector<std::shared_ptr<neb::rt::nr::nr_info_t>> nr_infos;
   276    auto info_ptr = std::make_shared<neb::rt::nr::nr_info_t>();
   277    neb::rt::nr::nr_info_t &info = *info_ptr;
   278    info.m_address = neb::to_address("a");
   279    info.m_nr_score = 1;
   280    nr_infos.push_back(info_ptr);
   281  
   282    neb::floatxx_t alpha = 1;
   283    neb::floatxx_t beta = 1;
   284    neb::floatxx_t lambda =
   285        neb::rt::dip::dip_reward::participate_lambda(alpha, beta, txs, nr_infos);
   286    EXPECT_TRUE(neb::math::abs(lambda, neb::floatxx_t(1)) < precesion(1e-1));
   287  }