mirror of
https://github.com/monero-project/monero.git
synced 2026-01-01 15:36:08 -08:00
core: dynamic fee algorithm from ArticMine
The fee will vary based on the base reward and the current block size limit: fee = (R/R0) * (M0/M) * F0 R: base reward R0: reference base reward (10 monero) M: block size limit M0: minimum block size limit (60000) F0: 0.002 monero Starts applying at v4
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
#include "misc_language.h"
|
||||
#include "profile_tools.h"
|
||||
#include "file_io_utils.h"
|
||||
#include "common/int-util.h"
|
||||
#include "common/boost_serialization_helper.h"
|
||||
#include "warnings.h"
|
||||
#include "crypto/hash.h"
|
||||
@@ -2708,6 +2709,57 @@ void Blockchain::check_ring_signature(const crypto::hash &tx_prefix_hash, const
|
||||
result = crypto::check_ring_signature(tx_prefix_hash, key_image, p_output_keys, sig.data()) ? 1 : 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
uint64_t Blockchain::get_dynamic_per_kb_fee(uint64_t block_reward, size_t median_block_size)
|
||||
{
|
||||
if (median_block_size < CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2)
|
||||
median_block_size = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2;
|
||||
|
||||
uint64_t unscaled_fee_per_kb = (DYNAMIC_FEE_PER_KB_BASE_FEE * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / median_block_size);
|
||||
uint64_t hi, lo = mul128(unscaled_fee_per_kb, block_reward, &hi);
|
||||
static_assert(DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD % 1000000 == 0, "DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD must be divisible by 1000000");
|
||||
static_assert(DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD / 1000000 <= std::numeric_limits<uint32_t>::max(), "DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD is too large");
|
||||
// divide in two steps, since the divisor must be 32 bits, but DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD isn't
|
||||
div128_32(hi, lo, DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD / 1000000, &hi, &lo);
|
||||
div128_32(hi, lo, 1000000, &hi, &lo);
|
||||
assert(hi == 0);
|
||||
|
||||
return lo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::check_fee(size_t blob_size, uint64_t fee) const
|
||||
{
|
||||
const uint8_t version = get_current_hard_fork_version();
|
||||
|
||||
uint64_t fee_per_kb;
|
||||
if (version < HF_VERSION_DYNAMIC_FEE)
|
||||
{
|
||||
fee_per_kb = FEE_PER_KB;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t median = m_current_block_cumul_sz_limit / 2;
|
||||
uint64_t already_generated_coins = m_db->height() ? m_db->get_block_already_generated_coins(m_db->height() - 1) : 0;
|
||||
uint64_t base_reward;
|
||||
if (!get_block_reward(median, 1, already_generated_coins, base_reward, version))
|
||||
return false;
|
||||
fee_per_kb = get_dynamic_per_kb_fee(base_reward, median);
|
||||
}
|
||||
LOG_PRINT_L2("Using " << print_money(fee) << "/kB fee");
|
||||
|
||||
uint64_t needed_fee = blob_size / 1024;
|
||||
needed_fee += (blob_size % 1024) ? 1 : 0;
|
||||
needed_fee *= fee_per_kb;
|
||||
|
||||
if (fee < needed_fee)
|
||||
{
|
||||
LOG_PRINT_L1("transaction fee is not enough: " << print_money(fee) << ", minimum fee: " << print_money(needed_fee));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// This function checks to see if a tx is unlocked. unlock_time is either
|
||||
// a block index or a unix time.
|
||||
|
||||
Reference in New Issue
Block a user