implementation of yield_info function
This commit is contained in:
@@ -400,7 +400,7 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
|
||||
} else {
|
||||
|
||||
// Prior to activation of conversions, the staking reward is purely a percentage of the block reward
|
||||
if (blk.miner_tx.amount_burnt == 0)
|
||||
if (blk.miner_tx.amount_burnt == 0 and prev_height != 0)
|
||||
throw std::runtime_error("Staking reward is zero, but block reward is present");
|
||||
slippage_total = blk.miner_tx.amount_burnt;
|
||||
}
|
||||
|
||||
@@ -197,14 +197,6 @@ struct txpool_tx_meta_t
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct yield_block_info {
|
||||
uint64_t block_height;
|
||||
uint64_t slippage_total_this_block;
|
||||
uint64_t locked_coins_this_block;
|
||||
uint64_t locked_coins_tally;
|
||||
uint8_t network_health_percentage;
|
||||
} yield_block_info;
|
||||
|
||||
typedef struct yield_tx_info {
|
||||
uint64_t block_height;
|
||||
crypto::hash tx_hash;
|
||||
|
||||
@@ -498,6 +498,24 @@ namespace cryptonote
|
||||
return boost::apply_visitor(txin_signature_size_visitor(), tx_in);
|
||||
}
|
||||
|
||||
struct yield_block_info {
|
||||
uint64_t block_height;
|
||||
uint64_t slippage_total_this_block;
|
||||
uint64_t locked_coins_this_block;
|
||||
uint64_t locked_coins_tally;
|
||||
uint8_t network_health_percentage;
|
||||
|
||||
BEGIN_SERIALIZE()
|
||||
VARINT_FIELD(block_height)
|
||||
VARINT_FIELD(slippage_total_this_block)
|
||||
VARINT_FIELD(locked_coins_this_block)
|
||||
VARINT_FIELD(locked_coins_tally)
|
||||
VARINT_FIELD(network_health_percentage)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <boost/serialization/is_bitwise_serializable.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include "blockchain_db/blockchain_db.h"
|
||||
#include "cryptonote_basic.h"
|
||||
#include "difficulty.h"
|
||||
#include "common/unordered_containers_boost_serialization.h"
|
||||
@@ -236,6 +237,16 @@ namespace boost
|
||||
a & pr.signature;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, cryptonote::yield_block_info &ybi, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & ybi.block_height;
|
||||
a & ybi.slippage_total_this_block;
|
||||
a & ybi.locked_coins_this_block;
|
||||
a & ybi.locked_coins_tally;
|
||||
a & ybi.network_health_percentage;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, cryptonote::block &b, const boost::serialization::version_type ver)
|
||||
{
|
||||
|
||||
@@ -4393,6 +4393,27 @@ bool Blockchain::validate_ybi_cache()
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::get_ybi_cache(std::map<uint64_t, yield_block_info>& ybi_cache)
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
|
||||
// Clear the provided container
|
||||
ybi_cache.clear();
|
||||
|
||||
// Make sure the cache is fully populated and up to date
|
||||
if (!validate_ybi_cache()) {
|
||||
LOG_PRINT_L1("yield information cache is invalid - rebuilding cache");
|
||||
if (!rebuild_ybi_cache()) {
|
||||
LOG_ERROR("Failed to rebuild yield information cache - aborting");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the cache
|
||||
ybi_cache = m_yield_block_info_cache;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::get_ybi_entry(const uint64_t height, cryptonote::yield_block_info& ybi)
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
|
||||
@@ -1154,6 +1154,17 @@ namespace cryptonote
|
||||
*/
|
||||
bool calculate_yield_payouts(const uint64_t start_height, std::vector<std::pair<yield_tx_info, uint64_t>>& yield_payouts);
|
||||
|
||||
/**
|
||||
* @brief get the complete YBI cache
|
||||
*
|
||||
* Retrieve the YBI local cache.
|
||||
* If the cache is out of date, the cache will (attempt to) be rebuilt
|
||||
* before being returned.
|
||||
*
|
||||
* @return TRUE if the call is successful, FALSE otherwise
|
||||
*/
|
||||
bool get_ybi_cache(std::map<uint64_t, yield_block_info>& ybi_cache);
|
||||
|
||||
/**
|
||||
* @brief get the YBI entry for a particular height from the cache
|
||||
*
|
||||
|
||||
@@ -2939,6 +2939,35 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_get_yield_info(const COMMAND_RPC_GET_YIELD_INFO::request& req, COMMAND_RPC_GET_YIELD_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||
{
|
||||
PERF_TIMER(on_get_yield_info);
|
||||
uint64_t height = m_core.get_current_blockchain_height();
|
||||
std::map<uint64_t, yield_block_info> ybi_cache;
|
||||
if (!m_core.get_blockchain_storage().get_ybi_cache(ybi_cache)) {
|
||||
res.status = "failed to get YBI data from blockchain";
|
||||
return true;
|
||||
}
|
||||
// Iterate over the cache, supplying the data in a more accessible format
|
||||
res.yield_data.clear();
|
||||
for (const auto& entry: ybi_cache) {
|
||||
// Skip this entry if out-of=range
|
||||
if (req.from_height > 0 and entry.first < req.from_height) continue;
|
||||
if (req.to_height > 0 and entry.first > req.to_height) continue;
|
||||
|
||||
// Clone the data into the response
|
||||
COMMAND_RPC_GET_YIELD_INFO::yield_data_t yd;
|
||||
yd.block_height = entry.second.block_height;
|
||||
yd.slippage_total_this_block = entry.second.slippage_total_this_block;
|
||||
yd.locked_coins_this_block = entry.second.locked_coins_this_block;
|
||||
yd.locked_coins_tally = entry.second.locked_coins_tally;
|
||||
yd.network_health_percentage = entry.second.network_health_percentage;
|
||||
res.yield_data.push_back(yd);
|
||||
}
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_get_base_fee_estimate(const COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||
{
|
||||
RPC_TRACKER(get_base_fee_estimate);
|
||||
|
||||
@@ -175,6 +175,7 @@ namespace cryptonote
|
||||
MAP_JON_RPC_WE("get_version", on_get_version, COMMAND_RPC_GET_VERSION)
|
||||
MAP_JON_RPC_WE_IF("get_coinbase_tx_sum", on_get_coinbase_tx_sum, COMMAND_RPC_GET_COINBASE_TX_SUM, !m_restricted)
|
||||
MAP_JON_RPC_WE("get_circulating_supply", on_get_circulating_supply, COMMAND_RPC_GET_CIRCULATING_SUPPLY)
|
||||
MAP_JON_RPC_WE("get_yield_info", on_get_yield_info, COMMAND_RPC_GET_YIELD_INFO)
|
||||
MAP_JON_RPC_WE("get_fee_estimate", on_get_base_fee_estimate, COMMAND_RPC_GET_BASE_FEE_ESTIMATE)
|
||||
MAP_JON_RPC_WE_IF("get_alternate_chains",on_get_alternate_chains, COMMAND_RPC_GET_ALTERNATE_CHAINS, !m_restricted)
|
||||
MAP_JON_RPC_WE_IF("relay_tx", on_relay_tx, COMMAND_RPC_RELAY_TX, !m_restricted)
|
||||
@@ -253,6 +254,7 @@ namespace cryptonote
|
||||
bool on_get_version(const COMMAND_RPC_GET_VERSION::request& req, COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_get_coinbase_tx_sum(const COMMAND_RPC_GET_COINBASE_TX_SUM::request& req, COMMAND_RPC_GET_COINBASE_TX_SUM::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_get_circulating_supply(const COMMAND_RPC_GET_CIRCULATING_SUPPLY::request& req, COMMAND_RPC_GET_CIRCULATING_SUPPLY::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_get_yield_info(const COMMAND_RPC_GET_YIELD_INFO::request& req, COMMAND_RPC_GET_YIELD_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_get_base_fee_estimate(const COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_get_alternate_chains(const COMMAND_RPC_GET_ALTERNATE_CHAINS::request& req, COMMAND_RPC_GET_ALTERNATE_CHAINS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
|
||||
@@ -1225,9 +1225,31 @@ namespace cryptonote
|
||||
|
||||
struct COMMAND_RPC_GET_YIELD_INFO
|
||||
{
|
||||
struct yield_data_t
|
||||
{
|
||||
uint64_t block_height;
|
||||
uint64_t slippage_total_this_block;
|
||||
uint64_t locked_coins_this_block;
|
||||
uint64_t locked_coins_tally;
|
||||
uint8_t network_health_percentage;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(block_height)
|
||||
KV_SERIALIZE(slippage_total_this_block)
|
||||
KV_SERIALIZE(locked_coins_this_block)
|
||||
KV_SERIALIZE(locked_coins_tally)
|
||||
KV_SERIALIZE(network_health_percentage)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct request_t
|
||||
{
|
||||
uint64_t from_height;
|
||||
uint64_t to_height;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_OPT(from_height, (uint64_t)0)
|
||||
KV_SERIALIZE_OPT(to_height, (uint64_t)0)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
@@ -1235,10 +1257,11 @@ namespace cryptonote
|
||||
|
||||
struct response_t
|
||||
{
|
||||
cryptonote::yield_block_info& latest_ybi;
|
||||
|
||||
std::string status;
|
||||
std::vector<COMMAND_RPC_GET_YIELD_INFO::yield_data_t> yield_data;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(latest_ybi)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(yield_data)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
|
||||
@@ -8167,25 +8167,41 @@ bool simple_wallet::supply_info(const std::vector<std::string> &args) {
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::yield_info(const std::vector<std::string> &args) {
|
||||
// get circulating supply
|
||||
|
||||
// Get the total circulating supply of SALs
|
||||
std::vector<std::pair<std::string, std::string>> supply_amounts;
|
||||
if(!m_wallet->get_circulating_supply(supply_amounts)) {
|
||||
fail_msg_writer() << "failed to get circulating supply. Make sure you are connected to a daemon.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// get pricing record
|
||||
std::string err;
|
||||
uint64_t bc_height = get_daemon_blockchain_height(err);
|
||||
oracle::pricing_record pr;
|
||||
if (!m_wallet->get_pricing_record(pr, bc_height-1)) {
|
||||
fail_msg_writer() << "failed to get pricing record. Make sure you are connected to a daemon.";
|
||||
return false;
|
||||
boost::multiprecision::uint128_t total_supply_128 = 0;
|
||||
for (auto supply_asset: supply_amounts) {
|
||||
if (supply_asset.first == "SAL") {
|
||||
boost::multiprecision::uint128_t supply_128(supply_asset.second);
|
||||
total_supply_128 = supply_128;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate current block cap
|
||||
//uint64_t block_cap = cryptonote::get_block_cap(supply_amounts, pr, m_wallet->get_current_hard_fork());
|
||||
//message_writer() << boost::format(tr("Current Block Cap(height %d): %d XHV")) % bc_height % print_money(block_cap);
|
||||
|
||||
// Get the yield data from the blockchain
|
||||
std::vector<cryptonote::yield_block_info> ybi_data;
|
||||
bool r = m_wallet->get_yield_info(ybi_data);
|
||||
if (!r)
|
||||
return false;
|
||||
|
||||
// Scan the entries we have received to gather the state (total yield over period captured)
|
||||
uint64_t total_yield = 0;
|
||||
for (const auto& entry: ybi_data) {
|
||||
total_yield += entry.slippage_total_this_block;
|
||||
}
|
||||
|
||||
// Output the necessary information
|
||||
message_writer(console_color_default, false) << boost::format(tr("YIELD INFO:\n\tTotal SAL supply: %d\n\tTotal coins locked: %d\n\tYield accrued over %s: %d"))
|
||||
% print_money(total_supply_128.convert_to<uint64_t>())
|
||||
% print_money(ybi_data.back().locked_coins_tally)
|
||||
% get_human_readable_timespan(ybi_data.size() * DIFFICULTY_TARGET_V2)
|
||||
% print_money(total_yield);
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -2035,6 +2035,36 @@ bool wallet2::get_circulating_supply(std::vector<std::pair<std::string, std::str
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::get_yield_info(std::vector<cryptonote::yield_block_info>& ybi_data)
|
||||
{
|
||||
// Issue an RPC call to get the block header (and thus the pricing record) at the specified height
|
||||
cryptonote::COMMAND_RPC_GET_YIELD_INFO::request req = AUTO_VAL_INIT(req);
|
||||
cryptonote::COMMAND_RPC_GET_YIELD_INFO::response res = AUTO_VAL_INIT(res);
|
||||
m_daemon_rpc_mutex.lock();
|
||||
bool r = invoke_http_json_rpc("/json_rpc", "get_yield_info", req, res, rpc_timeout);
|
||||
m_daemon_rpc_mutex.unlock();
|
||||
if (r && res.status == CORE_RPC_STATUS_OK)
|
||||
{
|
||||
ybi_data.clear();
|
||||
for (const auto& entry: res.yield_data) {
|
||||
// Create a YBI
|
||||
cryptonote::yield_block_info ybi;
|
||||
ybi.block_height = entry.block_height;
|
||||
ybi.slippage_total_this_block = entry.slippage_total_this_block;
|
||||
ybi.locked_coins_this_block = entry.locked_coins_this_block;
|
||||
ybi.locked_coins_tally = entry.locked_coins_tally;
|
||||
ybi.network_health_percentage = entry.network_health_percentage;
|
||||
ybi_data.push_back(ybi);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MERROR("Failed to retrieve yield info from daemon");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector<uint64_t> &o_indices, const std::vector<uint64_t> &asset_type_output_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen, const tx_cache_data &tx_cache_data, std::map<std::pair<uint64_t, uint64_t>, size_t> *output_tracker_cache)
|
||||
{
|
||||
PERF_TIMER(process_new_transaction);
|
||||
|
||||
@@ -1694,6 +1694,7 @@ private:
|
||||
|
||||
bool get_pricing_record(oracle::pricing_record& pr, const uint64_t height);
|
||||
bool get_circulating_supply(std::vector<std::pair<std::string, std::string>> &amounts);
|
||||
bool get_yield_info(std::vector<cryptonote::yield_block_info>& ybi_data);
|
||||
|
||||
private:
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user