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 }