github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/fs/blockchain/account/account_db.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 "fs/blockchain/account/account_db.h"
    22  #include "common/nebulas_currency.h"
    23  #include "fs/blockchain/trie/trie.h"
    24  #include "fs/util.h"
    25  
    26  namespace neb {
    27  namespace fs {
    28  
    29  account_db::account_db(blockchain_api_base *blockchain_ptr)
    30      : m_blockchain(blockchain_ptr) {}
    31  
    32  wei_t account_db::get_balance(const address_t &addr, block_height_t height) {
    33    auto corepb_account_ptr = m_blockchain->get_account_api(addr, height);
    34    std::string balance_str = corepb_account_ptr->balance();
    35    return storage_to_wei(neb::string_to_byte(balance_str));
    36  }
    37  
    38  address_t account_db::get_contract_deployer(const address_t &addr,
    39                                              block_height_t height) {
    40    auto corepb_account_ptr = m_blockchain->get_account_api(addr, height);
    41    std::string birth_place = corepb_account_ptr->birth_place();
    42    auto corepb_txs_ptr = m_blockchain->get_transaction_api(birth_place, height);
    43    return to_address(corepb_txs_ptr->from());
    44  }
    45  
    46  void account_db::set_height_address_val_internal(
    47      const std::vector<transaction_info_t> &txs,
    48      std::unordered_map<address_t, wei_t> &addr_balance) {
    49  
    50    for (auto it = txs.begin(); it != txs.end(); it++) {
    51      address_t from = it->m_from;
    52      address_t to = it->m_to;
    53  
    54      block_height_t height = it->m_height;
    55      wei_t tx_value = it->m_tx_value;
    56      wei_t value = tx_value;
    57  
    58      if (addr_balance.find(from) == addr_balance.end()) {
    59        addr_balance.insert(std::make_pair(from, 0));
    60      }
    61      if (addr_balance.find(to) == addr_balance.end()) {
    62        addr_balance.insert(std::make_pair(to, 0));
    63      }
    64  
    65      int32_t status = it->m_status;
    66      if (status) {
    67        addr_balance[from] -= value;
    68        addr_balance[to] += value;
    69      }
    70  
    71      wei_t gas_used = it->m_gas_used;
    72      if (gas_used != 0) {
    73        wei_t gas_val = gas_used * it->m_gas_price;
    74        addr_balance[from] -= gas_val;
    75      }
    76  
    77      if (m_height_addr_val.find(height) == m_height_addr_val.end()) {
    78        std::unordered_map<address_t, wei_t> addr_val = {
    79            {from, addr_balance[from]}, {to, addr_balance[to]}};
    80        m_height_addr_val.insert(std::make_pair(height, addr_val));
    81      } else {
    82        std::unordered_map<address_t, wei_t> &addr_val =
    83            m_height_addr_val[height];
    84        if (addr_val.find(from) == addr_val.end()) {
    85          addr_val.insert(std::make_pair(from, addr_balance[from]));
    86        } else {
    87          addr_val[from] = addr_balance[from];
    88        }
    89        if (addr_val.find(to) == addr_val.end()) {
    90          addr_val.insert(std::make_pair(to, addr_balance[to]));
    91        } else {
    92          addr_val[to] = addr_balance[to];
    93        }
    94      }
    95  
    96      if (m_addr_height_list.find(from) == m_addr_height_list.end()) {
    97        std::vector<block_height_t> v{height};
    98        m_addr_height_list.insert(std::make_pair(from, v));
    99      } else {
   100        std::vector<block_height_t> &v = m_addr_height_list[from];
   101        // expect reading transactions order by height asc
   102        if (!v.empty() && v.back() < height) {
   103          v.push_back(height);
   104        }
   105      }
   106  
   107      if (m_addr_height_list.find(to) == m_addr_height_list.end()) {
   108        std::vector<block_height_t> v{height};
   109        m_addr_height_list.insert(std::make_pair(to, v));
   110      } else {
   111        std::vector<block_height_t> &v = m_addr_height_list[to];
   112        if (!v.empty() && v.back() < height) {
   113          v.push_back(height);
   114        }
   115      }
   116    }
   117  }
   118  
   119  wei_t account_db::get_account_balance_internal(const address_t &address,
   120                                                 block_height_t height) {
   121    auto addr_it = m_addr_height_list.find(address);
   122    if (addr_it == m_addr_height_list.end()) {
   123      return 0;
   124    }
   125    auto height_it =
   126        std::lower_bound(addr_it->second.begin(), addr_it->second.end(), height);
   127  
   128    if (height_it == addr_it->second.end()) {
   129      height_it--;
   130      return m_height_addr_val[*height_it][address];
   131    }
   132  
   133    if (height_it == addr_it->second.begin()) {
   134      if (*height_it == height) {
   135        return m_height_addr_val[*height_it][address];
   136      } else {
   137        return 0;
   138      }
   139    }
   140  
   141    if (*height_it != height) {
   142      height_it--;
   143    }
   144  
   145    return m_height_addr_val[*height_it][address];
   146  }
   147  
   148  floatxx_t account_db::get_normalized_value(floatxx_t value) {
   149    uint64_t ratio = 1000000000000000000ULL;
   150    return value / floatxx_t(ratio);
   151  }
   152  } // namespace fs
   153  } // namespace neb