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