mirror of
https://github.com/monero-project/monero.git
synced 2024-12-13 20:06:32 +02:00
Merge pull request #3123
30c44bce
wallet: automatically use low priority if safe (no backlog & recent blocks not full) (stoffu)c903df5e
simplewallet: bug fix for backlog estimate (stoffu)2f5a9b6b
wallet2: split estimate_backlog to allow for raw fee levels (moneromooo-monero)
This commit is contained in:
commit
29fafa4ca7
@ -1519,6 +1519,19 @@ bool simple_wallet::set_refresh_from_block_height(const std::vector<std::string>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool simple_wallet::set_auto_low_priority(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||||
|
{
|
||||||
|
const auto pwd_container = get_and_verify_password();
|
||||||
|
if (pwd_container)
|
||||||
|
{
|
||||||
|
parse_bool_and_use(args[1], [&](bool r) {
|
||||||
|
m_wallet->auto_low_priority(r);
|
||||||
|
m_wallet->rewrite(m_wallet_file, pwd_container->password());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||||
{
|
{
|
||||||
if(args.empty())
|
if(args.empty())
|
||||||
@ -1691,7 +1704,9 @@ simple_wallet::simple_wallet()
|
|||||||
"confirm-backlog-threshold [n]\n "
|
"confirm-backlog-threshold [n]\n "
|
||||||
" Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks.\n "
|
" Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks.\n "
|
||||||
"refresh-from-block-height [n]\n "
|
"refresh-from-block-height [n]\n "
|
||||||
" Set the height before which to ignore blocks."));
|
" Set the height before which to ignore blocks.\n "
|
||||||
|
"auto-low-priority <1|0>\n "
|
||||||
|
" Whether to automatically use the low priority fee level when it's safe to do so."));
|
||||||
m_cmd_binder.set_handler("encrypted_seed",
|
m_cmd_binder.set_handler("encrypted_seed",
|
||||||
boost::bind(&simple_wallet::encrypted_seed, this, _1),
|
boost::bind(&simple_wallet::encrypted_seed, this, _1),
|
||||||
tr("Display the encrypted Electrum-style mnemonic seed."));
|
tr("Display the encrypted Electrum-style mnemonic seed."));
|
||||||
@ -1858,6 +1873,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
|||||||
success_msg_writer() << "confirm-backlog-threshold = " << m_wallet->get_confirm_backlog_threshold();
|
success_msg_writer() << "confirm-backlog-threshold = " << m_wallet->get_confirm_backlog_threshold();
|
||||||
success_msg_writer() << "confirm-export-overwrite = " << m_wallet->confirm_export_overwrite();
|
success_msg_writer() << "confirm-export-overwrite = " << m_wallet->confirm_export_overwrite();
|
||||||
success_msg_writer() << "refresh-from-block-height = " << m_wallet->get_refresh_from_block_height();
|
success_msg_writer() << "refresh-from-block-height = " << m_wallet->get_refresh_from_block_height();
|
||||||
|
success_msg_writer() << "auto-low-priority = " << m_wallet->auto_low_priority();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1907,6 +1923,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
|||||||
CHECK_SIMPLE_VARIABLE("confirm-backlog-threshold", set_confirm_backlog_threshold, tr("unsigned integer"));
|
CHECK_SIMPLE_VARIABLE("confirm-backlog-threshold", set_confirm_backlog_threshold, tr("unsigned integer"));
|
||||||
CHECK_SIMPLE_VARIABLE("confirm-export-overwrite", set_confirm_export_overwrite, tr("0 or 1"));
|
CHECK_SIMPLE_VARIABLE("confirm-export-overwrite", set_confirm_export_overwrite, tr("0 or 1"));
|
||||||
CHECK_SIMPLE_VARIABLE("refresh-from-block-height", set_refresh_from_block_height, tr("block height"));
|
CHECK_SIMPLE_VARIABLE("refresh-from-block-height", set_refresh_from_block_height, tr("block height"));
|
||||||
|
CHECK_SIMPLE_VARIABLE("auto-low-priority", set_auto_low_priority, tr("0 or 1"));
|
||||||
}
|
}
|
||||||
fail_msg_writer() << tr("set: unrecognized argument(s)");
|
fail_msg_writer() << tr("set: unrecognized argument(s)");
|
||||||
return true;
|
return true;
|
||||||
@ -3667,6 +3684,8 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
|||||||
if (local_args.size() > 0 && parse_priority(local_args[0], priority))
|
if (local_args.size() > 0 && parse_priority(local_args[0], priority))
|
||||||
local_args.erase(local_args.begin());
|
local_args.erase(local_args.begin());
|
||||||
|
|
||||||
|
priority = m_wallet->adjust_priority(priority);
|
||||||
|
|
||||||
size_t fake_outs_count = 0;
|
size_t fake_outs_count = 0;
|
||||||
if(local_args.size() > 0) {
|
if(local_args.size() > 0) {
|
||||||
size_t ring_size;
|
size_t ring_size;
|
||||||
@ -3854,7 +3873,6 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
|||||||
{
|
{
|
||||||
std::stringstream prompt;
|
std::stringstream prompt;
|
||||||
double worst_fee_per_byte = std::numeric_limits<double>::max();
|
double worst_fee_per_byte = std::numeric_limits<double>::max();
|
||||||
uint64_t size = 0, fee = 0;
|
|
||||||
for (size_t n = 0; n < ptx_vector.size(); ++n)
|
for (size_t n = 0; n < ptx_vector.size(); ++n)
|
||||||
{
|
{
|
||||||
const uint64_t blob_size = cryptonote::tx_to_blob(ptx_vector[n].tx).size();
|
const uint64_t blob_size = cryptonote::tx_to_blob(ptx_vector[n].tx).size();
|
||||||
@ -3862,13 +3880,11 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
|||||||
if (fee_per_byte < worst_fee_per_byte)
|
if (fee_per_byte < worst_fee_per_byte)
|
||||||
{
|
{
|
||||||
worst_fee_per_byte = fee_per_byte;
|
worst_fee_per_byte = fee_per_byte;
|
||||||
fee = ptx_vector[n].fee;
|
|
||||||
}
|
}
|
||||||
size += blob_size;
|
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::vector<std::pair<uint64_t, uint64_t>> nblocks = m_wallet->estimate_backlog(size, size, {fee});
|
std::vector<std::pair<uint64_t, uint64_t>> nblocks = m_wallet->estimate_backlog({std::make_pair(worst_fee_per_byte, worst_fee_per_byte)});
|
||||||
if (nblocks.size() != 1)
|
if (nblocks.size() != 1)
|
||||||
{
|
{
|
||||||
prompt << "Internal error checking for backlog. " << tr("Is this okay anyway? (Y/Yes/N/No): ");
|
prompt << "Internal error checking for backlog. " << tr("Is this okay anyway? (Y/Yes/N/No): ");
|
||||||
@ -4147,6 +4163,8 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a
|
|||||||
if (local_args.size() > 0 && parse_priority(local_args[0], priority))
|
if (local_args.size() > 0 && parse_priority(local_args[0], priority))
|
||||||
local_args.erase(local_args.begin());
|
local_args.erase(local_args.begin());
|
||||||
|
|
||||||
|
priority = m_wallet->adjust_priority(priority);
|
||||||
|
|
||||||
size_t fake_outs_count = 0;
|
size_t fake_outs_count = 0;
|
||||||
if(local_args.size() > 0) {
|
if(local_args.size() > 0) {
|
||||||
size_t ring_size;
|
size_t ring_size;
|
||||||
@ -4359,17 +4377,11 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
|
|||||||
|
|
||||||
std::vector<std::string> local_args = args_;
|
std::vector<std::string> local_args = args_;
|
||||||
|
|
||||||
int priority = 0;
|
uint32_t priority = 0;
|
||||||
if(local_args.size() > 0) {
|
if (local_args.size() > 0 && parse_priority(local_args[0], priority))
|
||||||
auto priority_pos = std::find(
|
local_args.erase(local_args.begin());
|
||||||
allowed_priority_strings.begin(),
|
|
||||||
allowed_priority_strings.end(),
|
priority = m_wallet->adjust_priority(priority);
|
||||||
local_args[0]);
|
|
||||||
if(priority_pos != allowed_priority_strings.end()) {
|
|
||||||
local_args.erase(local_args.begin());
|
|
||||||
priority = std::distance(allowed_priority_strings.begin(), priority_pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t fake_outs_count = 0;
|
size_t fake_outs_count = 0;
|
||||||
if(local_args.size() > 0) {
|
if(local_args.size() > 0) {
|
||||||
|
@ -130,6 +130,7 @@ namespace cryptonote
|
|||||||
bool set_confirm_backlog_threshold(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_confirm_backlog_threshold(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_confirm_export_overwrite(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_confirm_export_overwrite(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_refresh_from_block_height(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_refresh_from_block_height(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
|
bool set_auto_low_priority(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool help(const std::vector<std::string> &args = std::vector<std::string>());
|
bool help(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool start_mining(const std::vector<std::string> &args);
|
bool start_mining(const std::vector<std::string> &args);
|
||||||
bool stop_mining(const std::vector<std::string> &args);
|
bool stop_mining(const std::vector<std::string> &args);
|
||||||
|
@ -1074,6 +1074,8 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
|
|||||||
if (fake_outs_count == 0)
|
if (fake_outs_count == 0)
|
||||||
fake_outs_count = DEFAULT_MIXIN;
|
fake_outs_count = DEFAULT_MIXIN;
|
||||||
|
|
||||||
|
uint32_t adjusted_priority = m_wallet->adjust_priority(static_cast<uint32_t>(priority));
|
||||||
|
|
||||||
PendingTransactionImpl * transaction = new PendingTransactionImpl(*this);
|
PendingTransactionImpl * transaction = new PendingTransactionImpl(*this);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -1133,7 +1135,7 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
|
|||||||
de.is_subaddress = info.is_subaddress;
|
de.is_subaddress = info.is_subaddress;
|
||||||
dsts.push_back(de);
|
dsts.push_back(de);
|
||||||
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */,
|
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */,
|
||||||
static_cast<uint32_t>(priority),
|
adjusted_priority,
|
||||||
extra, subaddr_account, subaddr_indices, m_trustedDaemon);
|
extra, subaddr_account, subaddr_indices, m_trustedDaemon);
|
||||||
} else {
|
} else {
|
||||||
// for the GUI, sweep_all (i.e. amount set as "(all)") will always sweep all the funds in all the addresses
|
// for the GUI, sweep_all (i.e. amount set as "(all)") will always sweep all the funds in all the addresses
|
||||||
@ -1143,7 +1145,7 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
|
|||||||
subaddr_indices.insert(index);
|
subaddr_indices.insert(index);
|
||||||
}
|
}
|
||||||
transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */,
|
transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */,
|
||||||
static_cast<uint32_t>(priority),
|
adjusted_priority,
|
||||||
extra, subaddr_account, subaddr_indices, m_trustedDaemon);
|
extra, subaddr_account, subaddr_indices, m_trustedDaemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ struct PendingTransaction
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum Priority {
|
enum Priority {
|
||||||
|
Priority_Default = 0,
|
||||||
Priority_Low = 1,
|
Priority_Low = 1,
|
||||||
Priority_Medium = 2,
|
Priority_Medium = 2,
|
||||||
Priority_High = 3,
|
Priority_High = 3,
|
||||||
|
@ -612,6 +612,7 @@ wallet2::wallet2(bool testnet, bool restricted):
|
|||||||
m_confirm_backlog(true),
|
m_confirm_backlog(true),
|
||||||
m_confirm_backlog_threshold(0),
|
m_confirm_backlog_threshold(0),
|
||||||
m_confirm_export_overwrite(true),
|
m_confirm_export_overwrite(true),
|
||||||
|
m_auto_low_priority(true),
|
||||||
m_is_initialized(false),
|
m_is_initialized(false),
|
||||||
m_restricted(restricted),
|
m_restricted(restricted),
|
||||||
is_old_file_format(false),
|
is_old_file_format(false),
|
||||||
@ -2447,6 +2448,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
|
|||||||
value2.SetInt(m_confirm_export_overwrite ? 1 :0);
|
value2.SetInt(m_confirm_export_overwrite ? 1 :0);
|
||||||
json.AddMember("confirm_export_overwrite", value2, json.GetAllocator());
|
json.AddMember("confirm_export_overwrite", value2, json.GetAllocator());
|
||||||
|
|
||||||
|
value2.SetInt(m_auto_low_priority ? 1 : 0);
|
||||||
|
json.AddMember("auto_low_priority", value2, json.GetAllocator());
|
||||||
|
|
||||||
value2.SetInt(m_testnet ? 1 :0);
|
value2.SetInt(m_testnet ? 1 :0);
|
||||||
json.AddMember("testnet", value2, json.GetAllocator());
|
json.AddMember("testnet", value2, json.GetAllocator());
|
||||||
|
|
||||||
@ -2529,6 +2533,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
|||||||
m_confirm_backlog = true;
|
m_confirm_backlog = true;
|
||||||
m_confirm_backlog_threshold = 0;
|
m_confirm_backlog_threshold = 0;
|
||||||
m_confirm_export_overwrite = true;
|
m_confirm_export_overwrite = true;
|
||||||
|
m_auto_low_priority = true;
|
||||||
}
|
}
|
||||||
else if(json.IsObject())
|
else if(json.IsObject())
|
||||||
{
|
{
|
||||||
@ -2630,6 +2635,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
|||||||
m_confirm_backlog_threshold = field_confirm_backlog_threshold;
|
m_confirm_backlog_threshold = field_confirm_backlog_threshold;
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, confirm_export_overwrite, int, Int, false, true);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, confirm_export_overwrite, int, Int, false, true);
|
||||||
m_confirm_export_overwrite = field_confirm_export_overwrite;
|
m_confirm_export_overwrite = field_confirm_export_overwrite;
|
||||||
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, m_auto_low_priority, int, Int, false, true);
|
||||||
|
m_auto_low_priority = field_m_auto_low_priority;
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, testnet, int, Int, false, m_testnet);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, testnet, int, Int, false, m_testnet);
|
||||||
// Wallet is being opened with testnet flag, but is saved as a mainnet wallet
|
// Wallet is being opened with testnet flag, but is saved as a mainnet wallet
|
||||||
THROW_WALLET_EXCEPTION_IF(m_testnet && !field_testnet, error::wallet_internal_error, "Mainnet wallet can not be opened as testnet wallet");
|
THROW_WALLET_EXCEPTION_IF(m_testnet && !field_testnet, error::wallet_internal_error, "Mainnet wallet can not be opened as testnet wallet");
|
||||||
@ -5033,6 +5040,90 @@ uint64_t wallet2::adjust_mixin(uint64_t mixin) const
|
|||||||
return mixin;
|
return mixin;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
uint32_t wallet2::adjust_priority(uint32_t priority)
|
||||||
|
{
|
||||||
|
if (priority == 0 && get_default_priority() != 1 && auto_low_priority())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// check if there's a backlog in the tx pool
|
||||||
|
const double fee_level = get_fee_multiplier(1) * get_per_kb_fee() * (12/(double)13) / (double)1024;
|
||||||
|
const std::vector<std::pair<uint64_t, uint64_t>> blocks = estimate_backlog({std::make_pair(fee_level, fee_level)});
|
||||||
|
if (blocks.size() != 1)
|
||||||
|
{
|
||||||
|
MERROR("Bad estimated backlog array size");
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
else if (blocks[0].first > 0)
|
||||||
|
{
|
||||||
|
MINFO("We don't use the low priority because there's a backlog in the tx pool.");
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the current full reward zone
|
||||||
|
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_INFO::request> getinfo_req = AUTO_VAL_INIT(getinfo_req);
|
||||||
|
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_INFO::response, std::string> getinfo_res = AUTO_VAL_INIT(getinfo_res);
|
||||||
|
m_daemon_rpc_mutex.lock();
|
||||||
|
getinfo_req.jsonrpc = "2.0";
|
||||||
|
getinfo_req.id = epee::serialization::storage_entry(0);
|
||||||
|
getinfo_req.method = "get_info";
|
||||||
|
bool r = net_utils::invoke_http_json("/json_rpc", getinfo_req, getinfo_res, m_http_client);
|
||||||
|
m_daemon_rpc_mutex.unlock();
|
||||||
|
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(getinfo_res.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(getinfo_res.result.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error);
|
||||||
|
const uint64_t full_reward_zone = getinfo_res.result.block_size_limit / 2;
|
||||||
|
|
||||||
|
// get the last N block headers and sum the block sizes
|
||||||
|
const size_t N = 10;
|
||||||
|
if (m_blockchain.size() < N)
|
||||||
|
{
|
||||||
|
MERROR("The blockchain is too short");
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request> getbh_req = AUTO_VAL_INIT(getbh_req);
|
||||||
|
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response, std::string> getbh_res = AUTO_VAL_INIT(getbh_res);
|
||||||
|
m_daemon_rpc_mutex.lock();
|
||||||
|
getbh_req.jsonrpc = "2.0";
|
||||||
|
getbh_req.id = epee::serialization::storage_entry(0);
|
||||||
|
getbh_req.method = "getblockheadersrange";
|
||||||
|
getbh_req.params.start_height = m_blockchain.size() - N;
|
||||||
|
getbh_req.params.end_height = m_blockchain.size() - 1;
|
||||||
|
r = net_utils::invoke_http_json("/json_rpc", getbh_req, getbh_res, m_http_client, rpc_timeout);
|
||||||
|
m_daemon_rpc_mutex.unlock();
|
||||||
|
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getblockheadersrange");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(getbh_res.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getblockheadersrange");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(getbh_res.result.status != CORE_RPC_STATUS_OK, error::get_blocks_error, getbh_res.result.status);
|
||||||
|
if (getbh_res.result.headers.size() != N)
|
||||||
|
{
|
||||||
|
MERROR("Bad blockheaders size");
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
size_t block_size_sum = 0;
|
||||||
|
for (const cryptonote::block_header_response &i : getbh_res.result.headers)
|
||||||
|
{
|
||||||
|
block_size_sum += i.block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// estimate how 'full' the last N blocks are
|
||||||
|
const size_t P = 100 * block_size_sum / (N * full_reward_zone);
|
||||||
|
MINFO((boost::format("The last %d blocks fill roughly %d%% of the full reward zone.") % N % P).str());
|
||||||
|
if (P > 80)
|
||||||
|
{
|
||||||
|
MINFO("We don't use the low priority because recent blocks are quite full.");
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
MINFO("We'll use the low priority because probably it's safe to do so.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
MERROR(e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
// separated the call(s) to wallet2::transfer into their own function
|
// separated the call(s) to wallet2::transfer into their own function
|
||||||
//
|
//
|
||||||
// this function will make multiple calls to wallet2::transfer if multiple
|
// this function will make multiple calls to wallet2::transfer if multiple
|
||||||
@ -9473,13 +9564,12 @@ bool wallet2::is_synced() const
|
|||||||
return get_blockchain_current_height() >= height;
|
return get_blockchain_current_height() >= height;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(uint64_t min_blob_size, uint64_t max_blob_size, const std::vector<uint64_t> &fees)
|
std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(const std::vector<std::pair<double, double>> &fee_levels)
|
||||||
{
|
{
|
||||||
THROW_WALLET_EXCEPTION_IF(min_blob_size == 0, error::wallet_internal_error, "Invalid 0 fee");
|
for (const auto &fee_level: fee_levels)
|
||||||
THROW_WALLET_EXCEPTION_IF(max_blob_size == 0, error::wallet_internal_error, "Invalid 0 fee");
|
|
||||||
for (uint64_t fee: fees)
|
|
||||||
{
|
{
|
||||||
THROW_WALLET_EXCEPTION_IF(fee == 0, error::wallet_internal_error, "Invalid 0 fee");
|
THROW_WALLET_EXCEPTION_IF(fee_level.first == 0.0, error::wallet_internal_error, "Invalid 0 fee");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(fee_level.second == 0.0, error::wallet_internal_error, "Invalid 0 fee");
|
||||||
}
|
}
|
||||||
|
|
||||||
// get txpool backlog
|
// get txpool backlog
|
||||||
@ -9509,9 +9599,10 @@ std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(uint64_t mi
|
|||||||
uint64_t full_reward_zone = resp_t.result.block_size_limit / 2;
|
uint64_t full_reward_zone = resp_t.result.block_size_limit / 2;
|
||||||
|
|
||||||
std::vector<std::pair<uint64_t, uint64_t>> blocks;
|
std::vector<std::pair<uint64_t, uint64_t>> blocks;
|
||||||
for (uint64_t fee: fees)
|
for (const auto &fee_level: fee_levels)
|
||||||
{
|
{
|
||||||
double our_fee_byte_min = fee / (double)min_blob_size, our_fee_byte_max = fee / (double)max_blob_size;
|
const double our_fee_byte_min = fee_level.first;
|
||||||
|
const double our_fee_byte_max = fee_level.second;
|
||||||
uint64_t priority_size_min = 0, priority_size_max = 0;
|
uint64_t priority_size_min = 0, priority_size_max = 0;
|
||||||
for (const auto &i: res.result.backlog)
|
for (const auto &i: res.result.backlog)
|
||||||
{
|
{
|
||||||
@ -9529,14 +9620,31 @@ std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(uint64_t mi
|
|||||||
|
|
||||||
uint64_t nblocks_min = priority_size_min / full_reward_zone;
|
uint64_t nblocks_min = priority_size_min / full_reward_zone;
|
||||||
uint64_t nblocks_max = priority_size_max / full_reward_zone;
|
uint64_t nblocks_max = priority_size_max / full_reward_zone;
|
||||||
MDEBUG("estimate_backlog: priority_size " << priority_size_min << " - " << priority_size_max << " for " << fee
|
MDEBUG("estimate_backlog: priority_size " << priority_size_min << " - " << priority_size_max << " for "
|
||||||
<< " (" << our_fee_byte_min << " - " << our_fee_byte_max << " piconero byte fee), "
|
<< our_fee_byte_min << " - " << our_fee_byte_max << " piconero byte fee, "
|
||||||
<< nblocks_min << " - " << nblocks_max << " blocks at block size " << full_reward_zone);
|
<< nblocks_min << " - " << nblocks_max << " blocks at block size " << full_reward_zone);
|
||||||
blocks.push_back(std::make_pair(nblocks_min, nblocks_max));
|
blocks.push_back(std::make_pair(nblocks_min, nblocks_max));
|
||||||
}
|
}
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(uint64_t min_blob_size, uint64_t max_blob_size, const std::vector<uint64_t> &fees)
|
||||||
|
{
|
||||||
|
THROW_WALLET_EXCEPTION_IF(min_blob_size == 0, error::wallet_internal_error, "Invalid 0 fee");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(max_blob_size == 0, error::wallet_internal_error, "Invalid 0 fee");
|
||||||
|
for (uint64_t fee: fees)
|
||||||
|
{
|
||||||
|
THROW_WALLET_EXCEPTION_IF(fee == 0, error::wallet_internal_error, "Invalid 0 fee");
|
||||||
|
}
|
||||||
|
std::vector<std::pair<double, double>> fee_levels;
|
||||||
|
for (uint64_t fee: fees)
|
||||||
|
{
|
||||||
|
double our_fee_byte_min = fee / (double)min_blob_size, our_fee_byte_max = fee / (double)max_blob_size;
|
||||||
|
fee_levels.emplace_back(our_fee_byte_min, our_fee_byte_max);
|
||||||
|
}
|
||||||
|
return estimate_backlog(fee_levels);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::generate_genesis(cryptonote::block& b) const {
|
void wallet2::generate_genesis(cryptonote::block& b) const {
|
||||||
if (m_testnet)
|
if (m_testnet)
|
||||||
{
|
{
|
||||||
|
@ -838,6 +838,8 @@ namespace tools
|
|||||||
uint32_t get_confirm_backlog_threshold() const { return m_confirm_backlog_threshold; };
|
uint32_t get_confirm_backlog_threshold() const { return m_confirm_backlog_threshold; };
|
||||||
bool confirm_export_overwrite() const { return m_confirm_export_overwrite; }
|
bool confirm_export_overwrite() const { return m_confirm_export_overwrite; }
|
||||||
void confirm_export_overwrite(bool always) { m_confirm_export_overwrite = always; }
|
void confirm_export_overwrite(bool always) { m_confirm_export_overwrite = always; }
|
||||||
|
bool auto_low_priority() const { return m_auto_low_priority; }
|
||||||
|
void auto_low_priority(bool value) { m_auto_low_priority = value; }
|
||||||
|
|
||||||
bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const;
|
bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const;
|
||||||
void check_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations);
|
void check_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations);
|
||||||
@ -956,11 +958,13 @@ namespace tools
|
|||||||
|
|
||||||
bool is_synced() const;
|
bool is_synced() const;
|
||||||
|
|
||||||
|
std::vector<std::pair<uint64_t, uint64_t>> estimate_backlog(const std::vector<std::pair<double, double>> &fee_levels);
|
||||||
std::vector<std::pair<uint64_t, uint64_t>> estimate_backlog(uint64_t min_blob_size, uint64_t max_blob_size, const std::vector<uint64_t> &fees);
|
std::vector<std::pair<uint64_t, uint64_t>> estimate_backlog(uint64_t min_blob_size, uint64_t max_blob_size, const std::vector<uint64_t> &fees);
|
||||||
|
|
||||||
uint64_t get_fee_multiplier(uint32_t priority, int fee_algorithm = -1) const;
|
uint64_t get_fee_multiplier(uint32_t priority, int fee_algorithm = -1) const;
|
||||||
uint64_t get_per_kb_fee() const;
|
uint64_t get_per_kb_fee() const;
|
||||||
uint64_t adjust_mixin(uint64_t mixin) const;
|
uint64_t adjust_mixin(uint64_t mixin) const;
|
||||||
|
uint32_t adjust_priority(uint32_t priority);
|
||||||
|
|
||||||
// Light wallet specific functions
|
// Light wallet specific functions
|
||||||
// fetch unspent outs from lw node and store in m_transfers
|
// fetch unspent outs from lw node and store in m_transfers
|
||||||
@ -1121,6 +1125,7 @@ namespace tools
|
|||||||
bool m_confirm_backlog;
|
bool m_confirm_backlog;
|
||||||
uint32_t m_confirm_backlog_threshold;
|
uint32_t m_confirm_backlog_threshold;
|
||||||
bool m_confirm_export_overwrite;
|
bool m_confirm_export_overwrite;
|
||||||
|
bool m_auto_low_priority;
|
||||||
bool m_is_initialized;
|
bool m_is_initialized;
|
||||||
NodeRPCProxy m_node_rpc_proxy;
|
NodeRPCProxy m_node_rpc_proxy;
|
||||||
std::unordered_set<crypto::hash> m_scanned_pool_txs[2];
|
std::unordered_set<crypto::hash> m_scanned_pool_txs[2];
|
||||||
|
@ -786,7 +786,8 @@ namespace tools
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
|
uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
|
||||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, req.priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon);
|
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||||
|
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon);
|
||||||
|
|
||||||
if (ptx_vector.empty())
|
if (ptx_vector.empty())
|
||||||
{
|
{
|
||||||
@ -837,8 +838,9 @@ namespace tools
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
|
uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
|
||||||
|
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||||
LOG_PRINT_L2("on_transfer_split calling create_transactions_2");
|
LOG_PRINT_L2("on_transfer_split calling create_transactions_2");
|
||||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, req.priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon);
|
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon);
|
||||||
LOG_PRINT_L2("on_transfer_split called create_transactions_2");
|
LOG_PRINT_L2("on_transfer_split called create_transactions_2");
|
||||||
|
|
||||||
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.multisig_txset, req.do_not_relay,
|
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.multisig_txset, req.do_not_relay,
|
||||||
@ -903,7 +905,8 @@ namespace tools
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
|
uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
|
||||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, mixin, req.unlock_time, req.priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon);
|
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||||
|
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon);
|
||||||
|
|
||||||
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.multisig_txset, req.do_not_relay,
|
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.multisig_txset, req.do_not_relay,
|
||||||
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er);
|
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er);
|
||||||
@ -950,7 +953,8 @@ namespace tools
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
|
uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
|
||||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_single(ki, dsts[0].addr, dsts[0].is_subaddress, mixin, req.unlock_time, req.priority, extra, m_trusted_daemon);
|
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||||
|
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_single(ki, dsts[0].addr, dsts[0].is_subaddress, mixin, req.unlock_time, priority, extra, m_trusted_daemon);
|
||||||
|
|
||||||
if (ptx_vector.empty())
|
if (ptx_vector.empty())
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user