Merge pull request #4071
d6d78f1
Allow fractional outputs to be ignored (stoffu)
This commit is contained in:
commit
be81a27fa4
@ -2091,6 +2091,19 @@ bool simple_wallet::set_segregation_height(const std::vector<std::string> &args/
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool simple_wallet::set_ignore_fractional_outputs(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->ignore_fractional_outputs(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())
|
||||||
@ -2478,6 +2491,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
|||||||
const std::pair<size_t, size_t> lookahead = m_wallet->get_subaddress_lookahead();
|
const std::pair<size_t, size_t> lookahead = m_wallet->get_subaddress_lookahead();
|
||||||
success_msg_writer() << "subaddress-lookahead = " << lookahead.first << ":" << lookahead.second;
|
success_msg_writer() << "subaddress-lookahead = " << lookahead.first << ":" << lookahead.second;
|
||||||
success_msg_writer() << "segregation-height = " << m_wallet->segregation_height();
|
success_msg_writer() << "segregation-height = " << m_wallet->segregation_height();
|
||||||
|
success_msg_writer() << "ignore-fractional-outputs = " << m_wallet->ignore_fractional_outputs();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2532,6 +2546,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
|||||||
CHECK_SIMPLE_VARIABLE("key-reuse-mitigation2", set_key_reuse_mitigation2, tr("0 or 1"));
|
CHECK_SIMPLE_VARIABLE("key-reuse-mitigation2", set_key_reuse_mitigation2, tr("0 or 1"));
|
||||||
CHECK_SIMPLE_VARIABLE("subaddress-lookahead", set_subaddress_lookahead, tr("<major>:<minor>"));
|
CHECK_SIMPLE_VARIABLE("subaddress-lookahead", set_subaddress_lookahead, tr("<major>:<minor>"));
|
||||||
CHECK_SIMPLE_VARIABLE("segregation-height", set_segregation_height, tr("unsigned integer"));
|
CHECK_SIMPLE_VARIABLE("segregation-height", set_segregation_height, tr("unsigned integer"));
|
||||||
|
CHECK_SIMPLE_VARIABLE("ignore-fractional-outputs", set_ignore_fractional_outputs, tr("0 or 1"));
|
||||||
}
|
}
|
||||||
fail_msg_writer() << tr("set: unrecognized argument(s)");
|
fail_msg_writer() << tr("set: unrecognized argument(s)");
|
||||||
return true;
|
return true;
|
||||||
|
@ -137,6 +137,7 @@ namespace cryptonote
|
|||||||
bool set_key_reuse_mitigation2(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_key_reuse_mitigation2(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_subaddress_lookahead(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_subaddress_lookahead(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_segregation_height(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_segregation_height(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
|
bool set_ignore_fractional_outputs(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);
|
||||||
|
@ -676,6 +676,7 @@ wallet2::wallet2(network_type nettype, bool restricted):
|
|||||||
m_segregate_pre_fork_outputs(true),
|
m_segregate_pre_fork_outputs(true),
|
||||||
m_key_reuse_mitigation2(true),
|
m_key_reuse_mitigation2(true),
|
||||||
m_segregation_height(0),
|
m_segregation_height(0),
|
||||||
|
m_ignore_fractional_outputs(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),
|
||||||
@ -2800,6 +2801,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
|
|||||||
value2.SetUint(m_segregation_height);
|
value2.SetUint(m_segregation_height);
|
||||||
json.AddMember("segregation_height", value2, json.GetAllocator());
|
json.AddMember("segregation_height", value2, json.GetAllocator());
|
||||||
|
|
||||||
|
value2.SetInt(m_ignore_fractional_outputs ? 1 : 0);
|
||||||
|
json.AddMember("ignore_fractional_outputs", value2, json.GetAllocator());
|
||||||
|
|
||||||
value2.SetUint(m_subaddress_lookahead_major);
|
value2.SetUint(m_subaddress_lookahead_major);
|
||||||
json.AddMember("subaddress_lookahead_major", value2, json.GetAllocator());
|
json.AddMember("subaddress_lookahead_major", value2, json.GetAllocator());
|
||||||
|
|
||||||
@ -2882,6 +2886,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
|||||||
m_segregate_pre_fork_outputs = true;
|
m_segregate_pre_fork_outputs = true;
|
||||||
m_key_reuse_mitigation2 = true;
|
m_key_reuse_mitigation2 = true;
|
||||||
m_segregation_height = 0;
|
m_segregation_height = 0;
|
||||||
|
m_ignore_fractional_outputs = true;
|
||||||
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
|
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
|
||||||
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
|
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
|
||||||
m_key_on_device = false;
|
m_key_on_device = false;
|
||||||
@ -3008,6 +3013,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
|||||||
m_key_reuse_mitigation2 = field_key_reuse_mitigation2;
|
m_key_reuse_mitigation2 = field_key_reuse_mitigation2;
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, segregation_height, int, Uint, false, 0);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, segregation_height, int, Uint, false, 0);
|
||||||
m_segregation_height = field_segregation_height;
|
m_segregation_height = field_segregation_height;
|
||||||
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, ignore_fractional_outputs, int, Int, false, true);
|
||||||
|
m_ignore_fractional_outputs = field_ignore_fractional_outputs;
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_major, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MAJOR);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_major, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MAJOR);
|
||||||
m_subaddress_lookahead_major = field_subaddress_lookahead_major;
|
m_subaddress_lookahead_major = field_subaddress_lookahead_major;
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_minor, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MINOR);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_minor, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MINOR);
|
||||||
@ -7691,12 +7698,24 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
|||||||
for (uint32_t i : subaddr_indices)
|
for (uint32_t i : subaddr_indices)
|
||||||
LOG_PRINT_L2("Candidate subaddress index for spending: " << i);
|
LOG_PRINT_L2("Candidate subaddress index for spending: " << i);
|
||||||
|
|
||||||
|
// determine threshold for fractional amount
|
||||||
|
const size_t tx_size_one_ring = estimate_tx_size(use_rct, 1, fake_outs_count, 2, 0, bulletproof);
|
||||||
|
const size_t tx_size_two_rings = estimate_tx_size(use_rct, 2, fake_outs_count, 2, 0, bulletproof);
|
||||||
|
THROW_WALLET_EXCEPTION_IF(tx_size_one_ring > tx_size_two_rings, error::wallet_internal_error, "Estimated tx size with 1 input is larger than with 2 inputs!");
|
||||||
|
const size_t tx_size_per_ring = tx_size_two_rings - tx_size_one_ring;
|
||||||
|
const uint64_t fractional_threshold = (fee_multiplier * fee_per_kb * tx_size_per_ring) / 1024;
|
||||||
|
|
||||||
// gather all dust and non-dust outputs belonging to specified subaddresses
|
// gather all dust and non-dust outputs belonging to specified subaddresses
|
||||||
size_t num_nondust_outputs = 0;
|
size_t num_nondust_outputs = 0;
|
||||||
size_t num_dust_outputs = 0;
|
size_t num_dust_outputs = 0;
|
||||||
for (size_t i = 0; i < m_transfers.size(); ++i)
|
for (size_t i = 0; i < m_transfers.size(); ++i)
|
||||||
{
|
{
|
||||||
const transfer_details& td = m_transfers[i];
|
const transfer_details& td = m_transfers[i];
|
||||||
|
if (m_ignore_fractional_outputs && td.amount() < fractional_threshold)
|
||||||
|
{
|
||||||
|
MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below threshold " << print_money(fractional_threshold));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!td.m_spent && !td.m_key_image_partial && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
|
if (!td.m_spent && !td.m_key_image_partial && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
|
||||||
{
|
{
|
||||||
const uint32_t index_minor = td.m_subaddr_index.minor;
|
const uint32_t index_minor = td.m_subaddr_index.minor;
|
||||||
|
@ -925,6 +925,8 @@ namespace tools
|
|||||||
void key_reuse_mitigation2(bool value) { m_key_reuse_mitigation2 = value; }
|
void key_reuse_mitigation2(bool value) { m_key_reuse_mitigation2 = value; }
|
||||||
uint64_t segregation_height() const { return m_segregation_height; }
|
uint64_t segregation_height() const { return m_segregation_height; }
|
||||||
void segregation_height(uint64_t height) { m_segregation_height = height; }
|
void segregation_height(uint64_t height) { m_segregation_height = height; }
|
||||||
|
bool ignore_fractional_outputs() const { return m_ignore_fractional_outputs; }
|
||||||
|
void ignore_fractional_outputs(bool value) { m_ignore_fractional_outputs = value; }
|
||||||
bool confirm_non_default_ring_size() const { return m_confirm_non_default_ring_size; }
|
bool confirm_non_default_ring_size() const { return m_confirm_non_default_ring_size; }
|
||||||
void confirm_non_default_ring_size(bool always) { m_confirm_non_default_ring_size = always; }
|
void confirm_non_default_ring_size(bool always) { m_confirm_non_default_ring_size = always; }
|
||||||
|
|
||||||
@ -1284,6 +1286,7 @@ namespace tools
|
|||||||
bool m_segregate_pre_fork_outputs;
|
bool m_segregate_pre_fork_outputs;
|
||||||
bool m_key_reuse_mitigation2;
|
bool m_key_reuse_mitigation2;
|
||||||
uint64_t m_segregation_height;
|
uint64_t m_segregation_height;
|
||||||
|
bool m_ignore_fractional_outputs;
|
||||||
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];
|
||||||
|
Loading…
Reference in New Issue
Block a user