Add intervening v5 fork for increased min block size
Minimum mixin 4 and enforced ringct is moved from v5 to v6. v5 is now used for an increased minimum block size (from 60000 to 300000) to cater for larger typical/minimum transaction size. The fee algorithm is also changed to decrease the base per kB fee, and add a cheap tier for those transactions which we do not care if they get delayed (or even included in a block).
This commit is contained in:
parent
1dfed893e0
commit
3396a9f2af
|
@ -67,6 +67,15 @@ namespace cryptonote {
|
|||
/* Cryptonote helper functions */
|
||||
/************************************************************************/
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
size_t get_min_block_size(uint8_t version)
|
||||
{
|
||||
if (version < 2)
|
||||
return CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1;
|
||||
if (version < 5)
|
||||
return CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2;
|
||||
return CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
size_t get_max_block_size()
|
||||
{
|
||||
return CRYPTONOTE_MAX_BLOCK_SIZE;
|
||||
|
@ -89,7 +98,7 @@ namespace cryptonote {
|
|||
base_reward = FINAL_SUBSIDY_PER_MINUTE*target_minutes;
|
||||
}
|
||||
|
||||
uint64_t full_reward_zone = version < 2 ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 : CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2;
|
||||
uint64_t full_reward_zone = get_min_block_size(version);
|
||||
|
||||
//make it soft
|
||||
if (median_size < full_reward_zone) {
|
||||
|
|
|
@ -69,6 +69,7 @@ namespace cryptonote {
|
|||
/************************************************************************/
|
||||
/* Cryptonote helper functions */
|
||||
/************************************************************************/
|
||||
size_t get_min_block_size(uint8_t version);
|
||||
size_t get_max_block_size();
|
||||
size_t get_max_tx_size();
|
||||
bool get_block_reward(size_t median_size, size_t current_block_size, uint64_t already_generated_coins, uint64_t &reward, uint8_t version);
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#define CRYPTONOTE_REWARD_BLOCKS_WINDOW 100
|
||||
#define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 60000 //size of block (bytes) after which reward for block calculated using block size
|
||||
#define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 20000 //size of block (bytes) after which reward for block calculated using block size - before first fork
|
||||
#define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 300000 //size of block (bytes) after which reward for block calculated using block size - second change, from v5
|
||||
#define CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE 600
|
||||
#define CRYPTONOTE_DISPLAY_DECIMAL_POINT 12
|
||||
// COIN - number of smallest units in one coin
|
||||
|
@ -66,6 +67,7 @@
|
|||
#define FEE_PER_KB ((uint64_t)2000000000) // 2 * pow(10, 9)
|
||||
#define DYNAMIC_FEE_PER_KB_BASE_FEE ((uint64_t)2000000000) // 2 * pow(10,9)
|
||||
#define DYNAMIC_FEE_PER_KB_BASE_BLOCK_REWARD ((uint64_t)10000000000000) // 10 * pow(10,12)
|
||||
#define DYNAMIC_FEE_PER_KB_BASE_FEE_V5 ((uint64_t)2000000000 * (uint64_t)CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5)
|
||||
|
||||
#define ORPHANED_BLOCKS_MAX_COUNT 100
|
||||
|
||||
|
@ -128,6 +130,9 @@
|
|||
#define THREAD_STACK_SIZE 5 * 1024 * 1024
|
||||
|
||||
#define HF_VERSION_DYNAMIC_FEE 4
|
||||
#define HF_VERSION_MIN_MIXIN_4 6
|
||||
#define HF_VERSION_ENFORCE_RCT 6
|
||||
|
||||
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
|
||||
|
||||
// New constants are intended to go here
|
||||
|
|
|
@ -97,8 +97,8 @@ static const struct {
|
|||
// version 4 starts from block 1220516, which is on or around the 5th of January, 2017. Fork time finalised on 2016-09-18.
|
||||
{ 4, 1220516, 0, 1483574400 },
|
||||
|
||||
// version 5 starts from block 1406997, which is on or around the 20th of September, 2017. Fork time finalised on 2016-09-18.
|
||||
{ 5, 1406997, 0, 1505865600 },
|
||||
// version 5 starts from block 1288616, which is on or around the 15th of april, 2017. Fork time finalised on 2016-03-14.
|
||||
{ 5, 1288616, 0, 1489520158 },
|
||||
};
|
||||
static const uint64_t mainnet_hard_fork_version_1_till = 1009826;
|
||||
|
||||
|
@ -2426,7 +2426,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||
{
|
||||
size_t n_unmixable = 0, n_mixable = 0;
|
||||
size_t mixin = std::numeric_limits<size_t>::max();
|
||||
const size_t min_mixin = hf_version >= 5 ? 4 : 2;
|
||||
const size_t min_mixin = hf_version >= HF_VERSION_MIN_MIXIN_4 ? 4 : 2;
|
||||
for (const auto& txin : tx.vin)
|
||||
{
|
||||
// non txin_to_key inputs will be rejected below
|
||||
|
@ -2479,7 +2479,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||
tvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
const size_t min_tx_version = (n_unmixable > 0 ? 1 : (hf_version >= 5) ? 2 : 1);
|
||||
const size_t min_tx_version = (n_unmixable > 0 ? 1 : (hf_version >= HF_VERSION_ENFORCE_RCT) ? 2 : 1);
|
||||
if (tx.version < min_tx_version)
|
||||
{
|
||||
MERROR_VER("transaction version " << (unsigned)tx.version << " is lower than min accepted version " << min_tx_version);
|
||||
|
@ -2809,15 +2809,19 @@ static uint64_t get_fee_quantization_mask()
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
uint64_t Blockchain::get_dynamic_per_kb_fee(uint64_t block_reward, size_t median_block_size)
|
||||
uint64_t Blockchain::get_dynamic_per_kb_fee(uint64_t block_reward, size_t median_block_size, uint8_t version)
|
||||
{
|
||||
if (median_block_size < CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2)
|
||||
median_block_size = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2;
|
||||
const uint64_t min_block_size = get_min_block_size(version);
|
||||
const uint64_t fee_per_kb_base = version >= 5 ? DYNAMIC_FEE_PER_KB_BASE_FEE_V5 : DYNAMIC_FEE_PER_KB_BASE_FEE;
|
||||
|
||||
uint64_t unscaled_fee_per_kb = (DYNAMIC_FEE_PER_KB_BASE_FEE * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / median_block_size);
|
||||
if (median_block_size < min_block_size)
|
||||
median_block_size = min_block_size;
|
||||
|
||||
uint64_t unscaled_fee_per_kb = (fee_per_kb_base * min_block_size / 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);
|
||||
|
@ -2848,7 +2852,7 @@ bool Blockchain::check_fee(size_t blob_size, uint64_t fee) const
|
|||
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);
|
||||
fee_per_kb = get_dynamic_per_kb_fee(base_reward, median, version);
|
||||
}
|
||||
MDEBUG("Using " << print_money(fee) << "/kB fee");
|
||||
|
||||
|
@ -2875,14 +2879,15 @@ uint64_t Blockchain::get_dynamic_per_kb_fee_estimate(uint64_t grace_blocks) cons
|
|||
if (grace_blocks >= CRYPTONOTE_REWARD_BLOCKS_WINDOW)
|
||||
grace_blocks = CRYPTONOTE_REWARD_BLOCKS_WINDOW - 1;
|
||||
|
||||
const uint64_t min_block_size = get_min_block_size(version);
|
||||
std::vector<size_t> sz;
|
||||
get_last_n_blocks_sizes(sz, CRYPTONOTE_REWARD_BLOCKS_WINDOW - grace_blocks);
|
||||
for (size_t i = 0; i < grace_blocks; ++i)
|
||||
sz.push_back(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2);
|
||||
sz.push_back(min_block_size);
|
||||
|
||||
uint64_t median = epee::misc_utils::median(sz);
|
||||
if(median <= CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2)
|
||||
median = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2;
|
||||
if(median <= min_block_size)
|
||||
median = min_block_size;
|
||||
|
||||
uint64_t already_generated_coins = m_db->height() ? m_db->get_block_already_generated_coins(m_db->height() - 1) : 0;
|
||||
uint64_t base_reward;
|
||||
|
@ -2892,7 +2897,7 @@ uint64_t Blockchain::get_dynamic_per_kb_fee_estimate(uint64_t grace_blocks) cons
|
|||
base_reward = BLOCK_REWARD_OVERESTIMATE;
|
||||
}
|
||||
|
||||
uint64_t fee = get_dynamic_per_kb_fee(base_reward, median);
|
||||
uint64_t fee = get_dynamic_per_kb_fee(base_reward, median, version);
|
||||
MDEBUG("Estimating " << grace_blocks << "-block fee at " << print_money(fee) << "/kB");
|
||||
return fee;
|
||||
}
|
||||
|
@ -3411,7 +3416,7 @@ leave:
|
|||
//------------------------------------------------------------------
|
||||
bool Blockchain::update_next_cumulative_size_limit()
|
||||
{
|
||||
uint64_t full_reward_zone = get_current_hard_fork_version() < 2 ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 : CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2;
|
||||
uint64_t full_reward_zone = get_min_block_size(get_current_hard_fork_version());
|
||||
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
std::vector<size_t> sz;
|
||||
|
|
|
@ -520,10 +520,11 @@ namespace cryptonote
|
|||
*
|
||||
* @param block_reward the current block reward
|
||||
* @param median_block_size the median blob's size in the past window
|
||||
* @param version hard fork version for rules and constants to use
|
||||
*
|
||||
* @return the per kB fee
|
||||
*/
|
||||
static uint64_t get_dynamic_per_kb_fee(uint64_t block_reward, size_t median_block_size);
|
||||
static uint64_t get_dynamic_per_kb_fee(uint64_t block_reward, size_t median_block_size, uint8_t version);
|
||||
|
||||
/**
|
||||
* @brief get dynamic per kB fee estimate for the next few blocks
|
||||
|
|
|
@ -59,8 +59,6 @@ namespace cryptonote
|
|||
// codebase. As it stands, it is at best nontrivial to test
|
||||
// whether or not changing these parameters (or adding new)
|
||||
// will work correctly.
|
||||
size_t const TRANSACTION_SIZE_LIMIT_V1 = (((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE);
|
||||
size_t const TRANSACTION_SIZE_LIMIT_V2 = (((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE);
|
||||
time_t const MIN_RELAY_TIME = (60 * 5); // only start re-relaying transactions after that many seconds
|
||||
time_t const MAX_RELAY_TIME = (60 * 60 * 4); // at most that many seconds between resends
|
||||
float const ACCEPT_THRESHOLD = 1.0f;
|
||||
|
@ -78,6 +76,11 @@ namespace cryptonote
|
|||
{
|
||||
return amount * ACCEPT_THRESHOLD;
|
||||
}
|
||||
|
||||
uint64_t get_transaction_size_limit(uint8_t version)
|
||||
{
|
||||
return get_min_block_size(version) * 125 / 100 - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------
|
||||
|
@ -149,7 +152,7 @@ namespace cryptonote
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t tx_size_limit = (version < 2 ? TRANSACTION_SIZE_LIMIT_V1 : TRANSACTION_SIZE_LIMIT_V2);
|
||||
size_t tx_size_limit = get_transaction_size_limit(version);
|
||||
if (!kept_by_block && blob_size >= tx_size_limit)
|
||||
{
|
||||
LOG_PRINT_L1("transaction is too big: " << blob_size << " bytes, maximum size: " << tx_size_limit);
|
||||
|
@ -641,15 +644,6 @@ namespace cryptonote
|
|||
continue;
|
||||
}
|
||||
|
||||
#if 1
|
||||
// If we've exceeded the penalty free size,
|
||||
// stop including more tx
|
||||
if (total_size > median_size)
|
||||
{
|
||||
LOG_PRINT_L2(" would exceed median block size");
|
||||
break;
|
||||
}
|
||||
#else
|
||||
// If we're getting lower coinbase tx,
|
||||
// stop including more tx
|
||||
uint64_t block_reward;
|
||||
|
@ -666,7 +660,6 @@ namespace cryptonote
|
|||
sorted_it++;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Skip transactions that are not ready to be
|
||||
// included into the blockchain or that are
|
||||
|
@ -705,7 +698,7 @@ namespace cryptonote
|
|||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
size_t n_removed = 0;
|
||||
size_t tx_size_limit = (version < 2 ? TRANSACTION_SIZE_LIMIT_V1 : TRANSACTION_SIZE_LIMIT_V2);
|
||||
size_t tx_size_limit = get_transaction_size_limit(version);
|
||||
for (auto it = m_transactions.begin(); it != m_transactions.end(); ) {
|
||||
if (it->second.blob_size >= tx_size_limit) {
|
||||
LOG_PRINT_L1("Transaction " << get_transaction_hash(it->second.tx) << " is too big (" << it->second.blob_size << " bytes), removing it from pool");
|
||||
|
|
|
@ -491,7 +491,7 @@ bool simple_wallet::set_default_priority(const std::vector<std::string> &args/*
|
|||
{
|
||||
if (strchr(args[1].c_str(), '-'))
|
||||
{
|
||||
fail_msg_writer() << tr("priority must be 0, 1, 2, or 3 ");
|
||||
fail_msg_writer() << tr("priority must be 0, 1, 2, 3, or 4 ");
|
||||
return true;
|
||||
}
|
||||
if (args[1] == "0")
|
||||
|
@ -501,9 +501,9 @@ bool simple_wallet::set_default_priority(const std::vector<std::string> &args/*
|
|||
else
|
||||
{
|
||||
priority = boost::lexical_cast<int>(args[1]);
|
||||
if (priority != 1 && priority != 2 && priority != 3)
|
||||
if (priority < 1 || priority > 4)
|
||||
{
|
||||
fail_msg_writer() << tr("priority must be 0, 1, 2, or 3");
|
||||
fail_msg_writer() << tr("priority must be 0, 1, 2, 3,or 4");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +518,7 @@ bool simple_wallet::set_default_priority(const std::vector<std::string> &args/*
|
|||
}
|
||||
catch(const boost::bad_lexical_cast &)
|
||||
{
|
||||
fail_msg_writer() << tr("priority must be 0, 1, 2 or 3");
|
||||
fail_msg_writer() << tr("priority must be 0, 1, 2 3,or 4");
|
||||
return true;
|
||||
}
|
||||
catch(...)
|
||||
|
@ -659,7 +659,7 @@ simple_wallet::simple_wallet()
|
|||
m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), tr("Display private view key"));
|
||||
m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this, _1), tr("Display private spend key"));
|
||||
m_cmd_binder.set_handler("seed", boost::bind(&simple_wallet::seed, this, _1), tr("Display Electrum-style mnemonic seed"));
|
||||
m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), tr("Available options: seed language - set wallet seed language; always-confirm-transfers <1|0> - whether to confirm unsplit txes; print-ring-members <1|0> - whether to print detailed information about ring members during confirmation; store-tx-info <1|0> - whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference; default-mixin <n> - set default mixin (default is 4); auto-refresh <1|0> - whether to automatically sync new blocks from the daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - set wallet refresh behaviour; priority [1|2|3] - normal/elevated/priority fee; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - set default monero (sub-)unit"));
|
||||
m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), tr("Available options: seed language - set wallet seed language; always-confirm-transfers <1|0> - whether to confirm unsplit txes; print-ring-members <1|0> - whether to print detailed information about ring members during confirmation; store-tx-info <1|0> - whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference; default-mixin <n> - set default mixin (default is 4); auto-refresh <1|0> - whether to automatically sync new blocks from the daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - set wallet refresh behaviour; priority [0|1|2|3|4] - default/unimportant/normal/elevated/priority fee; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - set default monero (sub-)unit"));
|
||||
m_cmd_binder.set_handler("rescan_spent", boost::bind(&simple_wallet::rescan_spent, this, _1), tr("Rescan blockchain for spent outputs"));
|
||||
m_cmd_binder.set_handler("get_tx_key", boost::bind(&simple_wallet::get_tx_key, this, _1), tr("Get transaction key (r) for a given <txid>"));
|
||||
m_cmd_binder.set_handler("check_tx_key", boost::bind(&simple_wallet::check_tx_key, this, _1), tr("Check amount going to <address> in <txid>"));
|
||||
|
@ -795,7 +795,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
|||
{
|
||||
if (args.size() <= 1)
|
||||
{
|
||||
fail_msg_writer() << tr("set priority: needs an argument: 0, 1, 2, or 3");
|
||||
fail_msg_writer() << tr("set priority: needs an argument: 0, 1, 2, 3, or 4");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -3320,20 +3320,35 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wal
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
uint64_t wallet2::get_fee_multiplier(uint32_t priority, bool use_new_fee) const
|
||||
uint64_t wallet2::get_fee_multiplier(uint32_t priority, int fee_algorithm) const
|
||||
{
|
||||
static const uint64_t old_multipliers[3] = {1, 2, 3};
|
||||
static const uint64_t new_multipliers[3] = {1, 20, 166};
|
||||
static const uint64_t newer_multipliers[4] = {1, 4, 20, 166};
|
||||
|
||||
// 0 -> default (here, x1)
|
||||
// 0 -> default (here, x1 till fee algorithm 2, x4 from it)
|
||||
if (priority == 0)
|
||||
priority = m_default_priority;
|
||||
if (priority == 0)
|
||||
priority = 1;
|
||||
{
|
||||
if (fee_algorithm >= 2)
|
||||
priority = 2;
|
||||
else
|
||||
priority = 1;
|
||||
}
|
||||
|
||||
// 1 to 3 are allowed as priorities
|
||||
if (priority >= 1 && priority <= 3)
|
||||
return (use_new_fee ? new_multipliers : old_multipliers)[priority-1];
|
||||
// 1 to 3/4 are allowed as priorities
|
||||
uint32_t max_priority = (fee_algorithm >= 2) ? 4 : 3;
|
||||
if (priority >= 1 && priority <= max_priority)
|
||||
{
|
||||
switch (fee_algorithm)
|
||||
{
|
||||
case 0: return old_multipliers[priority-1];
|
||||
case 1: return new_multipliers[priority-1];
|
||||
case 2: return newer_multipliers[priority-1];
|
||||
default: THROW_WALLET_EXCEPTION_IF (true, error::invalid_priority);
|
||||
}
|
||||
}
|
||||
|
||||
THROW_WALLET_EXCEPTION_IF (false, error::invalid_priority);
|
||||
return 1;
|
||||
|
@ -3358,6 +3373,16 @@ uint64_t wallet2::get_per_kb_fee()
|
|||
return get_dynamic_per_kb_fee_estimate();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
int wallet2::get_fee_algorithm()
|
||||
{
|
||||
// changes at v3 and v5
|
||||
if (use_fork_rules(5, -720 * 14))
|
||||
return 2;
|
||||
if (use_fork_rules(3, -720 * 14))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// separated the call(s) to wallet2::transfer into their own function
|
||||
//
|
||||
// this function will make multiple calls to wallet2::transfer if multiple
|
||||
|
@ -3366,9 +3391,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
|
|||
{
|
||||
const std::vector<size_t> unused_transfers_indices = select_available_outputs_from_histogram(fake_outs_count + 1, true, true, true, trusted_daemon);
|
||||
|
||||
const bool use_new_fee = use_fork_rules(3, -720 * 14);
|
||||
const uint64_t fee_per_kb = get_per_kb_fee();
|
||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, use_new_fee);
|
||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
|
||||
|
||||
// failsafe split attempt counter
|
||||
size_t attempt_count = 0;
|
||||
|
@ -4147,9 +4171,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
|||
uint64_t upper_transaction_size_limit = get_upper_tranaction_size_limit();
|
||||
const bool use_rct = use_fork_rules(4, 0);
|
||||
|
||||
const bool use_new_fee = use_fork_rules(3, -720 * 14);
|
||||
const uint64_t fee_per_kb = get_per_kb_fee();
|
||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, use_new_fee);
|
||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
|
||||
|
||||
// throw if attempting a transaction with no destinations
|
||||
THROW_WALLET_EXCEPTION_IF(dsts.empty(), error::zero_destination);
|
||||
|
@ -4474,9 +4497,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
|||
std::vector<std::vector<get_outs_entry>> outs;
|
||||
|
||||
const bool use_rct = fake_outs_count > 0 && use_fork_rules(4, 0);
|
||||
const bool use_new_fee = use_fork_rules(3, -720 * 14);
|
||||
const uint64_t fee_per_kb = get_per_kb_fee();
|
||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, use_new_fee);
|
||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
|
||||
|
||||
LOG_PRINT_L2("Starting with " << unused_transfers_indices.size() << " non-dust outputs and " << unused_dust_indices.size() << " dust outputs");
|
||||
|
||||
|
@ -4637,7 +4659,7 @@ uint64_t wallet2::get_upper_tranaction_size_limit()
|
|||
{
|
||||
if (m_upper_transaction_size_limit > 0)
|
||||
return m_upper_transaction_size_limit;
|
||||
uint64_t full_reward_zone = use_fork_rules(2, 10) ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 : CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1;
|
||||
uint64_t full_reward_zone = use_fork_rules(5, 10) ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : use_fork_rules(2, 10) ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 : CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1;
|
||||
return ((full_reward_zone * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
@ -4763,7 +4785,6 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
|
|||
const bool hf1_rules = use_fork_rules(2, 10); // first hard fork has version 2
|
||||
tx_dust_policy dust_policy(hf1_rules ? 0 : ::config::DEFAULT_DUST_THRESHOLD);
|
||||
|
||||
const bool use_new_fee = use_fork_rules(3, -720 * 14);
|
||||
const uint64_t fee_per_kb = get_per_kb_fee();
|
||||
|
||||
// may throw
|
||||
|
|
|
@ -537,6 +537,7 @@ namespace tools
|
|||
|
||||
void get_hard_fork_info(uint8_t version, uint64_t &earliest_height);
|
||||
bool use_fork_rules(uint8_t version, int64_t early_blocks = 0);
|
||||
int get_fee_algorithm();
|
||||
|
||||
std::string get_wallet_file() const;
|
||||
std::string get_keys_file() const;
|
||||
|
@ -622,7 +623,7 @@ namespace tools
|
|||
void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const;
|
||||
uint64_t get_upper_tranaction_size_limit();
|
||||
std::vector<uint64_t> get_unspent_amounts_vector();
|
||||
uint64_t get_fee_multiplier(uint32_t priority, bool use_new_fee) const;
|
||||
uint64_t get_fee_multiplier(uint32_t priority, int fee_algorithm) const;
|
||||
uint64_t get_dynamic_per_kb_fee_estimate();
|
||||
uint64_t get_per_kb_fee();
|
||||
float get_output_relatedness(const transfer_details &td0, const transfer_details &td1) const;
|
||||
|
|
|
@ -58,46 +58,46 @@ namespace
|
|||
TEST_F(fee, 10xmr)
|
||||
{
|
||||
// CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 and lower are clamped
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2), clamp_fee(2000000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 2), clamp_fee(2000000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 100), clamp_fee(2000000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, 1), 2000000000);
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2, 3), clamp_fee(2000000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 2, 3), clamp_fee(2000000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 100, 3), clamp_fee(2000000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, 1, 3), 2000000000);
|
||||
|
||||
// higher is inverse proportional
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2), clamp_fee(2000000000 / 2));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10), clamp_fee(2000000000 / 10));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000), clamp_fee(2000000000 / 1000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull), clamp_fee(2000000000 / 20000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2, 3), clamp_fee(2000000000 / 2));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10, 3), clamp_fee(2000000000 / 10));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000, 3), clamp_fee(2000000000 / 1000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull, 3), clamp_fee(2000000000 / 20000));
|
||||
}
|
||||
|
||||
TEST_F(fee, 1xmr)
|
||||
{
|
||||
// CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 and lower are clamped
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2), clamp_fee(200000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 2), clamp_fee(200000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 100), clamp_fee(200000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, 1), 200000000);
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2, 3), clamp_fee(200000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 2, 3), clamp_fee(200000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 100, 3), clamp_fee(200000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, 1, 3), 200000000);
|
||||
|
||||
// higher is inverse proportional
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2), clamp_fee(200000000 / 2));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10), clamp_fee(200000000 / 10));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000), clamp_fee(200000000 / 1000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull), clamp_fee(200000000 / 20000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2, 3), clamp_fee(200000000 / 2));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10, 3), clamp_fee(200000000 / 10));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000, 3), clamp_fee(200000000 / 1000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull, 3), clamp_fee(200000000 / 20000));
|
||||
}
|
||||
|
||||
TEST_F(fee, dot3xmr)
|
||||
{
|
||||
// CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 and lower are clamped
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2), clamp_fee(60000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 2), clamp_fee(60000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 100), clamp_fee(60000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, 1), 60000000);
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2, 3), clamp_fee(60000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 2, 3), clamp_fee(60000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 100, 3), clamp_fee(60000000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, 1, 3), 60000000);
|
||||
|
||||
// higher is inverse proportional
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2), clamp_fee(60000000 / 2));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10), clamp_fee(60000000 / 10));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000), clamp_fee(60000000 / 1000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull), clamp_fee(60000000 / 20000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2, 3), clamp_fee(60000000 / 2));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10, 3), clamp_fee(60000000 / 10));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000, 3), clamp_fee(60000000 / 1000));
|
||||
ASSERT_EQ(Blockchain::get_dynamic_per_kb_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull, 3), clamp_fee(60000000 / 20000));
|
||||
}
|
||||
|
||||
static bool is_more_or_less(double x, double y)
|
||||
|
@ -129,7 +129,7 @@ namespace
|
|||
{
|
||||
for (uint64_t median_block_size: median_block_sizes)
|
||||
{
|
||||
ASSERT_TRUE(is_more_or_less(Blockchain::get_dynamic_per_kb_fee(block_reward, median_block_size) * (median_block_size / 1024.) * MAX_MULTIPLIER / (double)block_reward, 1.992 * 1000 / 1024));
|
||||
ASSERT_TRUE(is_more_or_less(Blockchain::get_dynamic_per_kb_fee(block_reward, median_block_size, 3) * (median_block_size / 1024.) * MAX_MULTIPLIER / (double)block_reward, 1.992 * 1000 / 1024));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue