From 78f622ead1ec1bac665f5f50c267cbed1af33de2 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 10 Dec 2024 21:27:34 +0100 Subject: [PATCH] bcs: get_block_reward_by_main_chain_height(), get_block_reward_by_hash() implemented; 2) core_rpc_server::fill_block_header_response() now correctly fills 'reward' --- src/currency_core/blockchain_storage.cpp | 51 ++++++++++++++++++++++++ src/currency_core/blockchain_storage.h | 2 + src/rpc/core_rpc_server.cpp | 17 +++++--- src/rpc/core_rpc_server.h | 2 +- 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 0d6d41f8..2a6af842 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -973,6 +973,57 @@ bool blockchain_storage::get_block_by_hash(const crypto::hash &h, block &blk) c return false; } +//------------------------------------------------------------------ +bool blockchain_storage::get_block_reward_by_main_chain_height(const uint64_t height, uint64_t& reward_with_fee) const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + static const boost::multiprecision::uint128_t amount_max_mp = UINT64_MAX; + + if (height >= m_db_blocks.size()) + return false; + + boost::multiprecision::uint128_t reward_with_fee_mp{}; + if (height != 0) + reward_with_fee_mp = m_db_blocks[height]->already_generated_coins - m_db_blocks[height - 1]->already_generated_coins; + else + reward_with_fee_mp = m_db_blocks[height]->already_generated_coins; + + if (reward_with_fee_mp > amount_max_mp) + return false; + + reward_with_fee = reward_with_fee_mp.convert_to(); + return true; +} +//------------------------------------------------------------------ +bool blockchain_storage::get_block_reward_by_hash(const crypto::hash &h, uint64_t& reward_with_fee) const +{ + CRITICAL_REGION_LOCAL(m_read_lock); + static const boost::multiprecision::uint128_t amount_max_mp = UINT64_MAX; + + block_extended_info bei{}; + if (!get_block_extended_info_by_hash(h, bei)) + return false; + + boost::multiprecision::uint128_t reward_with_fee_mp{}; + if (bei.height != 0) + { + block_extended_info bei_prev{}; + if (!get_block_extended_info_by_hash(bei.bl.prev_id, bei_prev)) + return false; + reward_with_fee_mp = bei.already_generated_coins - bei_prev.already_generated_coins; + } + else + { + reward_with_fee_mp = bei.already_generated_coins; + } + + if (reward_with_fee_mp > amount_max_mp) + return false; + + reward_with_fee = reward_with_fee_mp.convert_to(); + return true; +} +//------------------------------------------------------------------ bool blockchain_storage::is_tx_related_to_altblock(crypto::hash tx_id) const { CRITICAL_REGION_LOCAL1(m_alternative_chains_lock); diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 78c75e66..5ebc328c 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -233,6 +233,8 @@ namespace currency size_t get_alternative_blocks_count() const; crypto::hash get_block_id_by_height(uint64_t height) const; bool get_block_by_hash(const crypto::hash &h, block &blk) const; + bool get_block_reward_by_main_chain_height(const uint64_t height, uint64_t& reward_with_fee) const; // only for main chain blocks + bool get_block_reward_by_hash(const crypto::hash &h, uint64_t& reward_with_fee) const; // works for main chain and alt chain blocks bool get_block_extended_info_by_height(uint64_t h, block_extended_info &blk) const; bool get_block_extended_info_by_hash(const crypto::hash &h, block_extended_info &blk) const; bool get_block_by_height(uint64_t h, block &blk) const; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 88938641..2cbf9a08 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1156,16 +1156,22 @@ namespace currency return true; } //------------------------------------------------------------------------------------------------------------------------------ - uint64_t core_rpc_server::get_block_reward(const block& blk) + uint64_t core_rpc_server::get_block_reward(const block& blk, const crypto::hash& h) { + if (blk.miner_tx.version >= TRANSACTION_VERSION_POST_HF4) + { + uint64_t reward_with_fee = 0; + m_core.get_blockchain_storage().get_block_reward_by_hash(h, reward_with_fee); + return reward_with_fee; + } + + // legacy version, pre HF4 uint64_t reward = 0; BOOST_FOREACH(const auto& out, blk.miner_tx.vout) { VARIANT_SWITCH_BEGIN(out); VARIANT_CASE_CONST(tx_out_bare, out) reward += out.amount; - VARIANT_CASE_CONST(tx_out_zarcanum, out) - //@#@ VARIANT_SWITCH_END(); } return reward; @@ -1173,6 +1179,7 @@ namespace currency //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::fill_block_header_response(const block& blk, bool orphan_status, block_header_response& response) { + crypto::hash block_hash = get_block_hash(blk); response.major_version = blk.major_version; response.minor_version = blk.minor_version; response.timestamp = blk.timestamp; @@ -1181,9 +1188,9 @@ namespace currency response.orphan_status = orphan_status; response.height = get_block_height(blk); response.depth = m_core.get_current_blockchain_size() - response.height - 1; - response.hash = string_tools::pod_to_hex(get_block_hash(blk)); + response.hash = string_tools::pod_to_hex(block_hash); response.difficulty = m_core.get_blockchain_storage().block_difficulty(response.height).convert_to(); - response.reward = get_block_reward(blk); + response.reward = get_block_reward(blk, block_hash); return true; } //------------------------------------------------------------------------------------------------------------------------------ diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index e95f5a41..0e55204b 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -182,7 +182,7 @@ namespace currency bool check_core_ready_(const std::string& calling_method); //utils - uint64_t get_block_reward(const block& blk); + uint64_t get_block_reward(const block& blk, const crypto::hash& h); bool fill_block_header_response(const block& blk, bool orphan_status, block_header_response& response); void set_session_blob(const std::string& session_id, const currency::block& blob); bool get_session_blob(const std::string& session_id, currency::block& blob);