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