resolved the yield calculation issue
This commit is contained in:
@@ -368,33 +368,42 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
|
|||||||
// Now convert all of the residual balances into SAL
|
// Now convert all of the residual balances into SAL
|
||||||
boost::multiprecision::int128_t slippage_total_128 = 0;
|
boost::multiprecision::int128_t slippage_total_128 = 0;
|
||||||
uint64_t slippage_total = 0;
|
uint64_t slippage_total = 0;
|
||||||
for (const auto& tally: slippage_counts) {
|
if (blk.major_version >= HF_VERSION_ENABLE_CONVERT) {
|
||||||
boost::multiprecision::int128_t slippage_amount_128 = 0;
|
for (const auto& tally: slippage_counts) {
|
||||||
if (tally.first == "SAL") {
|
boost::multiprecision::int128_t slippage_amount_128 = 0;
|
||||||
slippage_amount_128 = tally.second;
|
if (tally.first == "SAL") {
|
||||||
} else {
|
slippage_amount_128 = tally.second;
|
||||||
// Sanity check - do we have a price for both source asset type and SAL in the PR?
|
} else {
|
||||||
boost::multiprecision::int128_t sal_price = blk.pricing_record["SAL"];
|
// Sanity check - do we have a price for both source asset type and SAL in the PR?
|
||||||
boost::multiprecision::int128_t asset_price = blk.pricing_record[tally.first];
|
boost::multiprecision::int128_t sal_price = blk.pricing_record["SAL"];
|
||||||
if (sal_price == 0) {
|
boost::multiprecision::int128_t asset_price = blk.pricing_record[tally.first];
|
||||||
// No price available - bail out, because block is invalid
|
if (sal_price == 0) {
|
||||||
throw std::runtime_error("Asset type 'SAL' is not present in available pricing record");
|
// No price available - bail out, because block is invalid
|
||||||
|
throw std::runtime_error("Asset type 'SAL' is not present in available pricing record");
|
||||||
|
}
|
||||||
|
if (asset_price == 0) {
|
||||||
|
// No price available - bail out, because block is invalid
|
||||||
|
throw std::runtime_error("Asset type '" + tally.first + "' is not present in available pricing record");
|
||||||
|
}
|
||||||
|
// Convert the VSD amount into SAL
|
||||||
|
boost::multiprecision::int128_t tally_128 = tally.second;
|
||||||
|
tally_128 *= asset_price;
|
||||||
|
tally_128 /= sal_price;
|
||||||
|
slippage_amount_128 = tally_128.convert_to<int64_t>();
|
||||||
}
|
}
|
||||||
if (asset_price == 0) {
|
slippage_total_128 += slippage_amount_128;
|
||||||
// No price available - bail out, because block is invalid
|
|
||||||
throw std::runtime_error("Asset type '" + tally.first + "' is not present in available pricing record");
|
|
||||||
}
|
|
||||||
// Convert the VSD amount into SAL
|
|
||||||
boost::multiprecision::int128_t tally_128 = tally.second;
|
|
||||||
tally_128 *= asset_price;
|
|
||||||
tally_128 /= sal_price;
|
|
||||||
slippage_amount_128 = tally_128.convert_to<int64_t>();
|
|
||||||
}
|
}
|
||||||
slippage_total_128 += slippage_amount_128;
|
if (slippage_total_128 < 0)
|
||||||
|
throw std::runtime_error("Found a negative slippage total when summing the burnt/minted amounts");
|
||||||
|
slippage_total = slippage_total_128.convert_to<uint64_t>();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Prior to activation of conversions, the staking reward is purely a percentage of the block reward
|
||||||
|
if (blk.miner_tx.amount_burnt == 0)
|
||||||
|
throw std::runtime_error("Staking reward is zero, but block reward is present");
|
||||||
|
slippage_total = blk.miner_tx.amount_burnt;
|
||||||
}
|
}
|
||||||
if (slippage_total_128 < 0)
|
|
||||||
throw std::runtime_error("Found a negative slippage total when summing the burnt/minted amounts");
|
|
||||||
slippage_total = slippage_total_128.convert_to<uint64_t>();
|
|
||||||
|
|
||||||
TIME_MEASURE_FINISH(time1);
|
TIME_MEASURE_FINISH(time1);
|
||||||
time_add_transaction += time1;
|
time_add_transaction += time1;
|
||||||
|
|||||||
@@ -219,13 +219,15 @@ namespace cryptonote
|
|||||||
FIELD(vout)
|
FIELD(vout)
|
||||||
FIELD(extra)
|
FIELD(extra)
|
||||||
VARINT_FIELD(type)
|
VARINT_FIELD(type)
|
||||||
if (type != cryptonote::transaction_type::MINER && type != cryptonote::transaction_type::PROTOCOL) {
|
if (type != cryptonote::transaction_type::PROTOCOL) {
|
||||||
FIELD(return_address)
|
|
||||||
FIELD(return_pubkey)
|
|
||||||
FIELD(source_asset_type)
|
|
||||||
FIELD(destination_asset_type)
|
|
||||||
VARINT_FIELD(amount_burnt)
|
VARINT_FIELD(amount_burnt)
|
||||||
VARINT_FIELD(amount_slippage_limit)
|
if (type != cryptonote::transaction_type::MINER) {
|
||||||
|
FIELD(return_address)
|
||||||
|
FIELD(return_pubkey)
|
||||||
|
FIELD(source_asset_type)
|
||||||
|
FIELD(destination_asset_type)
|
||||||
|
VARINT_FIELD(amount_slippage_limit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
|
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ namespace config
|
|||||||
0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10
|
0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10
|
||||||
} }; // Bender's nightmare
|
} }; // Bender's nightmare
|
||||||
|
|
||||||
std::string const GENESIS_TX = "0201ff000180c0d0c7bbbff60302e03c14d309ba99f81fe1e523cf7bac8cbbb10dcbb9aba66d20c31ec0ff7d0a880353414c3c000000000000002101345d3471cba278cb9969e63704569b2a531f4bd99f75224f6494ed16b966deb40100";
|
std::string const GENESIS_TX = "0201ff000180c0d0c7bbbff60302c33815291bac1b6d5c685129c1de6383e550688d005a3ce2b66a96b7050579060353414c3c00000000000000210149117096744b390170a118fc14d8f13edb40a7d2764fde3043d9fbae7d2efdef010000";
|
||||||
|
|
||||||
uint32_t const GENESIS_NONCE = 10000;
|
uint32_t const GENESIS_NONCE = 10000;
|
||||||
|
|
||||||
|
|||||||
@@ -464,17 +464,8 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline
|
|||||||
rx_set_main_seedhash(seedhash.data, tools::get_max_concurrency());
|
rx_set_main_seedhash(seedhash.data, tools::get_max_concurrency());
|
||||||
|
|
||||||
// Preload the yield_block_info cache
|
// Preload the yield_block_info cache
|
||||||
uint64_t yield_lock_period = get_config(m_nettype).YIELD_LOCK_PERIOD;
|
rebuild_ybi_cache();
|
||||||
m_yield_block_info_cache.clear();
|
|
||||||
uint64_t end_height = m_db->height();
|
|
||||||
uint64_t start_height = (end_height > yield_lock_period) ? (end_height - yield_lock_period) : 0;
|
|
||||||
for (uint64_t idx = start_height; idx < end_height; idx++) {
|
|
||||||
yield_block_info ybi;
|
|
||||||
int result = m_db->get_yield_block_info(idx, ybi);
|
|
||||||
if (result)
|
|
||||||
return false;
|
|
||||||
m_yield_block_info_cache[idx] = ybi;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
@@ -1590,7 +1581,7 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
|
|||||||
// Get the data for the block that matured this time
|
// Get the data for the block that matured this time
|
||||||
cryptonote::yield_block_info ybi_matured;
|
cryptonote::yield_block_info ybi_matured;
|
||||||
uint64_t lock_period = get_config(m_nettype).YIELD_LOCK_PERIOD;
|
uint64_t lock_period = get_config(m_nettype).YIELD_LOCK_PERIOD;
|
||||||
uint64_t start_height = (height > lock_period) ? height - lock_period : 0;
|
uint64_t start_height = (height > lock_period) ? height - lock_period - 1 : 0;
|
||||||
bool ok = get_ybi_entry(start_height, ybi_matured);
|
bool ok = get_ybi_entry(start_height, ybi_matured);
|
||||||
if (ok && ybi_matured.locked_coins_this_block > 0) {
|
if (ok && ybi_matured.locked_coins_this_block > 0) {
|
||||||
|
|
||||||
@@ -1881,7 +1872,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
|||||||
|
|
||||||
// Check to see if there are any matured YIELD TXs
|
// Check to see if there are any matured YIELD TXs
|
||||||
uint64_t yield_lock_period = get_config(m_nettype).YIELD_LOCK_PERIOD;
|
uint64_t yield_lock_period = get_config(m_nettype).YIELD_LOCK_PERIOD;
|
||||||
uint64_t start_height = (height > yield_lock_period) ? height - yield_lock_period : 0;
|
uint64_t start_height = (height > yield_lock_period) ? height - yield_lock_period - 1 : 0;
|
||||||
|
|
||||||
cryptonote::yield_block_info ybi_matured;
|
cryptonote::yield_block_info ybi_matured;
|
||||||
bool ok = get_ybi_entry(start_height, ybi_matured);
|
bool ok = get_ybi_entry(start_height, ybi_matured);
|
||||||
@@ -4296,7 +4287,7 @@ bool Blockchain::calculate_yield_payouts(const uint64_t start_height, std::vecto
|
|||||||
// Get the YIELD TX information for matured staked coins
|
// Get the YIELD TX information for matured staked coins
|
||||||
std::vector<cryptonote::yield_tx_info> yield_entries;
|
std::vector<cryptonote::yield_tx_info> yield_entries;
|
||||||
// We get the yield_tx_info from the block _before_ they started to accrue yield
|
// We get the yield_tx_info from the block _before_ they started to accrue yield
|
||||||
int yield_tx_result = m_db->get_yield_tx_info(start_height - 1, yield_entries);
|
int yield_tx_result = m_db->get_yield_tx_info(start_height, yield_entries);
|
||||||
if (!yield_entries.size()) {
|
if (!yield_entries.size()) {
|
||||||
|
|
||||||
// Report error and abort
|
// Report error and abort
|
||||||
@@ -4311,7 +4302,7 @@ bool Blockchain::calculate_yield_payouts(const uint64_t start_height, std::vecto
|
|||||||
|
|
||||||
// Iterate over the cached yield_block_info data
|
// Iterate over the cached yield_block_info data
|
||||||
uint64_t yield_lock_period = cryptonote::get_config(m_nettype).YIELD_LOCK_PERIOD;
|
uint64_t yield_lock_period = cryptonote::get_config(m_nettype).YIELD_LOCK_PERIOD;
|
||||||
for (uint64_t idx = start_height; idx < start_height + yield_lock_period; ++idx) {
|
for (uint64_t idx = start_height+1; idx <= start_height + yield_lock_period; ++idx) {
|
||||||
// Get the next block
|
// Get the next block
|
||||||
if (m_yield_block_info_cache.count(idx) == 0) {
|
if (m_yield_block_info_cache.count(idx) == 0) {
|
||||||
LOG_ERROR("failed to locate yield information for block height " << idx <<" - aborting");
|
LOG_ERROR("failed to locate yield information for block height " << idx <<" - aborting");
|
||||||
@@ -4321,7 +4312,6 @@ bool Blockchain::calculate_yield_payouts(const uint64_t start_height, std::vecto
|
|||||||
if (ybi.slippage_total_this_block == 0) continue;
|
if (ybi.slippage_total_this_block == 0) continue;
|
||||||
|
|
||||||
boost::multiprecision::int128_t slippage_128 = ybi.slippage_total_this_block;
|
boost::multiprecision::int128_t slippage_128 = ybi.slippage_total_this_block;
|
||||||
slippage_128 = (slippage_128 * 3) / 10;
|
|
||||||
|
|
||||||
// Get the total number of coins locked at this height
|
// Get the total number of coins locked at this height
|
||||||
boost::multiprecision::int128_t locked_total_128 = ybi.locked_coins_tally;
|
boost::multiprecision::int128_t locked_total_128 = ybi.locked_coins_tally;
|
||||||
@@ -4351,7 +4341,7 @@ bool Blockchain::rebuild_ybi_cache()
|
|||||||
// Get the size that the cache should be when fully populated (could be less than the lock period if the chain is young)
|
// Get the size that the cache should be when fully populated (could be less than the lock period if the chain is young)
|
||||||
uint64_t height = m_db->height();
|
uint64_t height = m_db->height();
|
||||||
uint64_t yield_lock_period = cryptonote::get_config(m_nettype).YIELD_LOCK_PERIOD;
|
uint64_t yield_lock_period = cryptonote::get_config(m_nettype).YIELD_LOCK_PERIOD;
|
||||||
uint64_t ybi_cache_expected_size = std::min(height, yield_lock_period);
|
uint64_t ybi_cache_expected_size = std::min(height, yield_lock_period+1);
|
||||||
|
|
||||||
// Now get this number of entries from the blockchain
|
// Now get this number of entries from the blockchain
|
||||||
for (uint64_t idx = height - ybi_cache_expected_size; idx < height; ++idx) {
|
for (uint64_t idx = height - ybi_cache_expected_size; idx < height; ++idx) {
|
||||||
@@ -4380,7 +4370,7 @@ bool Blockchain::validate_ybi_cache()
|
|||||||
// Get the size that the cache should be if fully populated
|
// Get the size that the cache should be if fully populated
|
||||||
uint64_t height = m_db->height();
|
uint64_t height = m_db->height();
|
||||||
uint64_t yield_lock_period = cryptonote::get_config(m_nettype).YIELD_LOCK_PERIOD;
|
uint64_t yield_lock_period = cryptonote::get_config(m_nettype).YIELD_LOCK_PERIOD;
|
||||||
uint64_t ybi_cache_expected_size = std::min(height, yield_lock_period);
|
uint64_t ybi_cache_expected_size = std::min(height, yield_lock_period + 1);
|
||||||
if (m_yield_block_info_cache.size() != ybi_cache_expected_size) {
|
if (m_yield_block_info_cache.size() != ybi_cache_expected_size) {
|
||||||
// It's not the right size - report error and bail out
|
// It's not the right size - report error and bail out
|
||||||
LOG_ERROR("YBI cache is incorrect size - should be " << ybi_cache_expected_size << ", but found " << m_yield_block_info_cache.size() << " - aborting");
|
LOG_ERROR("YBI cache is incorrect size - should be " << ybi_cache_expected_size << ", but found " << m_yield_block_info_cache.size() << " - aborting");
|
||||||
@@ -4884,8 +4874,8 @@ leave:
|
|||||||
uint64_t yield_lock_period = cryptonote::get_config(m_nettype).YIELD_LOCK_PERIOD;
|
uint64_t yield_lock_period = cryptonote::get_config(m_nettype).YIELD_LOCK_PERIOD;
|
||||||
uint64_t ybi_cache_expected_size = std::min(new_height, yield_lock_period);
|
uint64_t ybi_cache_expected_size = std::min(new_height, yield_lock_period);
|
||||||
if (new_height > yield_lock_period) {
|
if (new_height > yield_lock_period) {
|
||||||
if (m_yield_block_info_cache.count(new_height - yield_lock_period - 1) != 0) {
|
if (m_yield_block_info_cache.count(new_height - yield_lock_period - 2) != 0) {
|
||||||
m_yield_block_info_cache.erase(new_height - yield_lock_period - 1);
|
m_yield_block_info_cache.erase(new_height - yield_lock_period - 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_yield_block_info_cache[new_ybi.block_height] = new_ybi;
|
m_yield_block_info_cache[new_ybi.block_height] = new_ybi;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "string_tools.h"
|
#include "string_tools.h"
|
||||||
|
|
||||||
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
|
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
|
||||||
|
#include "blockchain_db/blockchain_db.h"
|
||||||
#include "cryptonote_basic/cryptonote_basic.h"
|
#include "cryptonote_basic/cryptonote_basic.h"
|
||||||
#include "cryptonote_basic/difficulty.h"
|
#include "cryptonote_basic/difficulty.h"
|
||||||
#include "crypto/hash.h"
|
#include "crypto/hash.h"
|
||||||
@@ -1222,6 +1223,27 @@ namespace cryptonote
|
|||||||
typedef epee::misc_utils::struct_init<response_t> response;
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct COMMAND_RPC_GET_YIELD_INFO
|
||||||
|
{
|
||||||
|
struct request_t
|
||||||
|
{
|
||||||
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
|
END_KV_SERIALIZE_MAP()
|
||||||
|
};
|
||||||
|
typedef epee::misc_utils::struct_init<request_t> request;
|
||||||
|
|
||||||
|
|
||||||
|
struct response_t
|
||||||
|
{
|
||||||
|
cryptonote::yield_block_info& latest_ybi;
|
||||||
|
|
||||||
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
|
KV_SERIALIZE(latest_ybi)
|
||||||
|
END_KV_SERIALIZE_MAP()
|
||||||
|
};
|
||||||
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
|
};
|
||||||
|
|
||||||
struct COMMAND_RPC_GET_LAST_BLOCK_HEADER
|
struct COMMAND_RPC_GET_LAST_BLOCK_HEADER
|
||||||
{
|
{
|
||||||
struct request_t: public rpc_access_request_base
|
struct request_t: public rpc_access_request_base
|
||||||
|
|||||||
@@ -6964,7 +6964,15 @@ bool simple_wallet::transfer_main(
|
|||||||
if (subaddr_indices.size() > 1)
|
if (subaddr_indices.size() > 1)
|
||||||
prompt << tr("WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy.\n");
|
prompt << tr("WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy.\n");
|
||||||
}
|
}
|
||||||
prompt << boost::format(tr("Sending %s. ")) % print_money(total_sent);
|
if (transfer_type == Burn) {
|
||||||
|
prompt << boost::format(tr("Burning %s %s. ")) % print_money(total_sent) % source_asset;
|
||||||
|
} else if (transfer_type == Convert) {
|
||||||
|
prompt << boost::format(tr("Converting %s %s to %s. ")) % print_money(total_sent) % source_asset % dest_asset;
|
||||||
|
} else if (transfer_type == LockForYield) {
|
||||||
|
prompt << boost::format(tr("Staking %s %s for yield accrual. ")) % print_money(total_sent) % source_asset;
|
||||||
|
} else {
|
||||||
|
prompt << boost::format(tr("Sending %s %s. ")) % print_money(total_sent) % source_asset;
|
||||||
|
}
|
||||||
if (ptx_vector.size() > 1)
|
if (ptx_vector.size() > 1)
|
||||||
{
|
{
|
||||||
prompt << boost::format(tr("Your transaction needs to be split into %llu transactions. "
|
prompt << boost::format(tr("Your transaction needs to be split into %llu transactions. "
|
||||||
|
|||||||
Reference in New Issue
Block a user