diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index b9d247779..f3e02dfb2 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -368,33 +368,42 @@ uint64_t BlockchainDB::add_block( const std::pair& blck // Now convert all of the residual balances into SAL boost::multiprecision::int128_t slippage_total_128 = 0; uint64_t slippage_total = 0; - for (const auto& tally: slippage_counts) { - boost::multiprecision::int128_t slippage_amount_128 = 0; - if (tally.first == "SAL") { - slippage_amount_128 = tally.second; - } else { - // Sanity check - do we have a price for both source asset type and SAL in the PR? - boost::multiprecision::int128_t sal_price = blk.pricing_record["SAL"]; - boost::multiprecision::int128_t asset_price = blk.pricing_record[tally.first]; - if (sal_price == 0) { - // No price available - bail out, because block is invalid - throw std::runtime_error("Asset type 'SAL' is not present in available pricing record"); + if (blk.major_version >= HF_VERSION_ENABLE_CONVERT) { + for (const auto& tally: slippage_counts) { + boost::multiprecision::int128_t slippage_amount_128 = 0; + if (tally.first == "SAL") { + slippage_amount_128 = tally.second; + } else { + // Sanity check - do we have a price for both source asset type and SAL in the PR? + boost::multiprecision::int128_t sal_price = blk.pricing_record["SAL"]; + boost::multiprecision::int128_t asset_price = blk.pricing_record[tally.first]; + if (sal_price == 0) { + // 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(); } - 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(); + slippage_total_128 += slippage_amount_128; } - 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(); + + } 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(); TIME_MEASURE_FINISH(time1); time_add_transaction += time1; diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 8d6493bd3..588ed1caf 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -219,13 +219,15 @@ namespace cryptonote FIELD(vout) FIELD(extra) VARINT_FIELD(type) - if (type != cryptonote::transaction_type::MINER && type != cryptonote::transaction_type::PROTOCOL) { - FIELD(return_address) - FIELD(return_pubkey) - FIELD(source_asset_type) - FIELD(destination_asset_type) + if (type != cryptonote::transaction_type::PROTOCOL) { 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() diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 57446b994..212192225 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -259,7 +259,7 @@ namespace config 0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10 } }; // Bender's nightmare - std::string const GENESIS_TX = "0201ff000180c0d0c7bbbff60302e03c14d309ba99f81fe1e523cf7bac8cbbb10dcbb9aba66d20c31ec0ff7d0a880353414c3c000000000000002101345d3471cba278cb9969e63704569b2a531f4bd99f75224f6494ed16b966deb40100"; + std::string const GENESIS_TX = "0201ff000180c0d0c7bbbff60302c33815291bac1b6d5c685129c1de6383e550688d005a3ce2b66a96b7050579060353414c3c00000000000000210149117096744b390170a118fc14d8f13edb40a7d2764fde3043d9fbae7d2efdef010000"; uint32_t const GENESIS_NONCE = 10000; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 00f447f98..dd62ee8b6 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -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()); // Preload the yield_block_info cache - uint64_t yield_lock_period = get_config(m_nettype).YIELD_LOCK_PERIOD; - 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; - } + rebuild_ybi_cache(); + 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 cryptonote::yield_block_info ybi_matured; 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); 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 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; 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 std::vector yield_entries; // 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()) { // 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 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 if (m_yield_block_info_cache.count(idx) == 0) { 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; 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 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) uint64_t height = m_db->height(); 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 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 uint64_t height = m_db->height(); 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) { // 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"); @@ -4884,8 +4874,8 @@ leave: 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); if (new_height > yield_lock_period) { - if (m_yield_block_info_cache.count(new_height - yield_lock_period - 1) != 0) { - m_yield_block_info_cache.erase(new_height - yield_lock_period - 1); + 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 - 2); } } m_yield_block_info_cache[new_ybi.block_height] = new_ybi; diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 1af48cb44..38fdbc401 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -33,6 +33,7 @@ #include "string_tools.h" #include "cryptonote_protocol/cryptonote_protocol_defs.h" +#include "blockchain_db/blockchain_db.h" #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/difficulty.h" #include "crypto/hash.h" @@ -1222,6 +1223,27 @@ namespace cryptonote typedef epee::misc_utils::struct_init 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; + + + 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; + }; + struct COMMAND_RPC_GET_LAST_BLOCK_HEADER { struct request_t: public rpc_access_request_base diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 2c308a341..064fc90f2 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -6964,7 +6964,15 @@ bool simple_wallet::transfer_main( if (subaddr_indices.size() > 1) 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) { prompt << boost::format(tr("Your transaction needs to be split into %llu transactions. "