github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/fs/ir_manager/ir_manager_helper.cpp (about) 1 // Copyright (C) 2018 go-nebulas authors // 2 // This file is part of the go-nebulas library. 3 // 4 // the go-nebulas library is free software: you can redistribute it and/or 5 // modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // the go-nebulas library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with the go-nebulas library. If not, see 17 // <http://www.gnu.org/licenses/>. 18 // 19 20 #include "fs/ir_manager/ir_manager_helper.h" 21 #include "common/configuration.h" 22 #include "fs/ir_manager/api/ir_api.h" 23 #include "jit/cpp_ir.h" 24 #include "jit/jit_driver.h" 25 #include <boost/foreach.hpp> 26 #include <boost/property_tree/json_parser.hpp> 27 28 namespace neb { 29 namespace fs { 30 31 void ir_manager_helper::set_failed_flag(rocksdb_storage *rs, 32 const std::string &flag) { 33 rs->put(flag, neb::string_to_byte(flag)); 34 } 35 36 bool ir_manager_helper::has_failed_flag(rocksdb_storage *rs, 37 const std::string &flag) { 38 try { 39 rs->get(flag); 40 } catch (const std::exception &e) { 41 // LOG(INFO) << "nbre failed flag not found " << e.what(); 42 return false; 43 } 44 return true; 45 } 46 47 void ir_manager_helper::del_failed_flag(rocksdb_storage *rs, 48 const std::string &flag) { 49 rs->del(flag); 50 } 51 52 block_height_t ir_manager_helper::nbre_block_height(rocksdb_storage *rs) { 53 54 block_height_t start_height = 0; 55 try { 56 start_height = neb::byte_to_number<block_height_t>(rs->get( 57 std::string(neb::configuration::instance().nbre_max_height_name(), 58 std::allocator<char>()))); 59 } catch (std::exception &e) { 60 LOG(INFO) << "to init nbre max height " << e.what(); 61 start_height = neb::configuration::instance().nbre_start_height(); 62 rs->put(std::string(neb::configuration::instance().nbre_max_height_name(), 63 std::allocator<char>()), 64 neb::number_to_byte<neb::bytes>(start_height)); 65 } 66 return start_height; 67 } 68 69 block_height_t ir_manager_helper::lib_block_height(blockchain *bc) { 70 71 std::unique_ptr<corepb::Block> end_block = bc->load_LIB_block(); 72 block_height_t end_height = end_block->height(); 73 return end_height; 74 } 75 76 void ir_manager_helper::run_auth_table( 77 nbre::NBREIR &nbre_ir, std::map<auth_key_t, auth_val_t> &auth_table) { 78 79 auth_table_t rows; 80 81 try { 82 std::stringstream ss; 83 ss << nbre_ir.name() << nbre_ir.version(); 84 std::vector<nbre::NBREIR> irs; 85 irs.push_back(nbre_ir); 86 87 jit_driver &jd = jit_driver::instance(); 88 rows = jd.run<auth_table_t>( 89 ss.str(), irs, neb::configuration::instance().auth_func_name()); 90 91 } catch (const std::exception &e) { 92 LOG(INFO) << "execute auth table failed " << e.what(); 93 return; 94 } 95 96 auth_table.clear(); 97 for (auto &r : rows) { 98 assert(std::tuple_size<std::remove_reference<decltype(r)>::type>::value == 99 4); 100 auth_key_t k = std::make_tuple(std::get<0>(r), to_address(std::get<1>(r))); 101 auth_val_t v = std::make_tuple(std::get<2>(r), std::get<3>(r)); 102 auth_table.insert(std::make_pair(k, v)); 103 } 104 return; 105 } 106 107 void ir_manager_helper::load_auth_table( 108 rocksdb_storage *rs, std::map<auth_key_t, auth_val_t> &auth_table) { 109 110 // auth table exists in memory 111 if (!auth_table.empty()) { 112 return; 113 } 114 115 std::unique_ptr<nbre::NBREIR> nbre_ir = std::make_unique<nbre::NBREIR>(); 116 neb::bytes payload_bytes; 117 try { 118 payload_bytes = 119 rs->get(neb::configuration::instance().nbre_auth_table_name()); 120 } catch (const std::exception &e) { 121 LOG(INFO) << "auth table not deploy yet " << e.what(); 122 return; 123 } 124 125 bool ret = 126 nbre_ir->ParseFromArray(payload_bytes.value(), payload_bytes.size()); 127 if (!ret) { 128 throw std::runtime_error("parse payload auth table failed"); 129 } 130 131 run_auth_table(*nbre_ir.get(), auth_table); 132 } 133 134 void ir_manager_helper::deploy_auth_table( 135 rocksdb_storage *rs, nbre::NBREIR &nbre_ir, 136 std::map<auth_key_t, auth_val_t> &auth_table, 137 const neb::bytes &payload_bytes) { 138 139 // TODO expect auth table exceed 128k bytes size 140 LOG(INFO) << "before set auth table by jit, auth table size: " 141 << auth_table.size(); 142 ir_manager_helper::run_auth_table(nbre_ir, auth_table); 143 rs->put(neb::configuration::instance().nbre_auth_table_name(), payload_bytes); 144 LOG(INFO) << "updating auth table..."; 145 LOG(INFO) << "after set auth table by jit, auth table size: " 146 << auth_table.size(); 147 assert(!auth_table.empty()); 148 } 149 150 void ir_manager_helper::show_auth_table( 151 const std::map<auth_key_t, auth_val_t> &auth_table) { 152 153 LOG(INFO) << "\nshow auth table"; 154 for (auto &r : auth_table) { 155 std::string key = 156 boost::str(boost::format("key <%1%, %2%>") % std::get<0>(r.first) % 157 std::get<1>(r.first).to_base58()); 158 std::string val = boost::str(boost::format("val <%1%, %2%>") % 159 std::get<0>(r.second) % std::get<1>(r.second)); 160 LOG(INFO) << key << val; 161 } 162 } 163 164 void ir_manager_helper::update_to_storage( 165 const std::string &key, const boost::property_tree::ptree &val_pt, 166 rocksdb_storage *rs) { 167 168 std::stringstream ss; 169 boost::property_tree::json_parser::write_json(ss, val_pt, false); 170 rs->put(key, neb::string_to_byte(ss.str())); 171 } 172 173 void ir_manager_helper::update_ir_list(const std::string &name, 174 rocksdb_storage *rs) { 175 std::string ir_list = neb::configuration::instance().ir_list_name(); 176 neb::bytes ir_list_bytes; 177 try { 178 ir_list_bytes = rs->get(ir_list); 179 } catch (const std::exception &e) { 180 LOG(INFO) << "ir_list not in storage, append " << name << " to ir_list " 181 << e.what(); 182 183 boost::property_tree::ptree ele, arr, root; 184 ele.put("", name); 185 arr.push_back(std::make_pair("", ele)); 186 root.add_child(ir_list, arr); 187 update_to_storage(ir_list, root, rs); 188 return; 189 } 190 191 192 boost::property_tree::ptree root; 193 std::stringstream ss(neb::byte_to_string(ir_list_bytes)); 194 boost::property_tree::json_parser::read_json(ss, root); 195 196 BOOST_FOREACH (boost::property_tree::ptree::value_type &v, 197 root.get_child(ir_list)) { 198 boost::property_tree::ptree pt = v.second; 199 if (name == pt.get<std::string>(std::string())) { 200 // ir name already exists 201 return; 202 } 203 } 204 205 boost::property_tree::ptree &arr = root.get_child(ir_list); 206 boost::property_tree::ptree ele; 207 ele.put("", name); 208 arr.push_back(std::make_pair("", ele)); 209 210 update_to_storage(ir_list, root, rs); 211 } 212 213 void ir_manager_helper::update_ir_versions(const std::string &name, 214 uint64_t version, 215 rocksdb_storage *rs) { 216 neb::bytes ir_versions_bytes; 217 try { 218 ir_versions_bytes = rs->get(name); 219 } catch (const std::exception &e) { 220 LOG(INFO) << "no such ir, to update new ir named " << name 221 << " with version " << version << ' ' << e.what(); 222 223 boost::property_tree::ptree ele, arr, root; 224 ele.put("", version); 225 arr.push_back(std::make_pair("", ele)); 226 root.add_child(name, arr); 227 update_to_storage(name, root, rs); 228 return; 229 } 230 231 boost::property_tree::ptree root; 232 std::stringstream ss(neb::byte_to_string(ir_versions_bytes)); 233 boost::property_tree::json_parser::read_json(ss, root); 234 235 BOOST_FOREACH (boost::property_tree::ptree::value_type &v, 236 root.get_child(name)) { 237 boost::property_tree::ptree pt = v.second; 238 if (version == pt.get<uint64_t>(std::string())) { 239 // ir version already exists 240 return; 241 } 242 } 243 244 boost::property_tree::ptree &arr = root.get_child(name); 245 boost::property_tree::ptree ele; 246 ele.put("", version); 247 arr.push_back(std::make_pair("", ele)); 248 249 update_to_storage(name, root, rs); 250 } 251 252 void ir_manager_helper::deploy_ir(const std::string &name, uint64_t version, 253 const neb::bytes &payload_bytes, 254 rocksdb_storage *rs) { 255 std::stringstream ss; 256 ss << name << version; 257 rs->put(ss.str(), payload_bytes); 258 LOG(INFO) << "deploy " << name << " version " << version << " successfully!"; 259 } 260 261 void ir_manager_helper::deploy_cpp(const std::string &name, uint64_t version, 262 const std::string &cpp_content, 263 rocksdb_storage *rs) { 264 std::stringstream ss; 265 ss << name << version << "_cpp"; 266 rs->put(ss.str(), string_to_byte(cpp_content)); 267 LOG(INFO) << "deploy " << name << " version " << version << " source code!"; 268 } 269 270 void ir_manager_helper::compile_payload_code(nbre::NBREIR *nbre_ir, 271 bytes &payload_bytes) { 272 if (nbre_ir->ir_type() == ::neb::ir_type::cpp) { 273 //! We need compile the code 274 std::stringstream ss; 275 ss << nbre_ir->name(); 276 ss << nbre_ir->version(); 277 cpp::cpp_ir ci(std::make_pair(ss.str(), nbre_ir->ir())); 278 279 neb::bytes ir = ci.llvm_ir_content(); 280 nbre_ir->set_ir(neb::byte_to_string(ir)); 281 282 auto bytes_long = nbre_ir->ByteSizeLong(); 283 payload_bytes = neb::bytes(bytes_long); 284 nbre_ir->SerializeToArray((void *)payload_bytes.value(), 285 payload_bytes.size()); 286 } else { 287 } 288 } 289 } // namespace fs 290 } // namespace neb