diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2017-03-24 20:58:02 +0000 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2017-03-24 21:04:08 +0000 |
commit | 0ad87db01f19eff22ab9c3998826b7aa943975cf (patch) | |
tree | 5f9f29576f209ea777fdad8b3392314d6022c680 /src/simplewallet/simplewallet.cpp | |
parent | Merge pull request #1916 (diff) | |
download | monero-0ad87db01f19eff22ab9c3998826b7aa943975cf.tar.xz |
wallet: try to save large outputs when using an unneeded second input
When a single input is enough to satisfy a transfer, the code would
previously try to add a second input, to match the "canonical" makeup
of a transaction with two inputs and two outputs. This would cause
wallets to slowly merge outputs till all the monero ends up in a
single output, which causes trouble when making two transactions
one after the other, since change is locked for 10 blocks, and an
increasing portion of the remaining balance would end up locked on
each transaction.
There are two new settings (min-output-count and min-output-value)
which can control when to stop adding such unneeded second outputs.
The idea is that small "dust" outputs will still get added, but
larger ones will not.
Enable with, eg:
set min-output-count 10
set min-output-value 30
to avoid using an unneeded second output of 30 monero or more, if
there would be less than 10 such outputs left.
This does not invalidate any other reason why such outputs would
be used (ie, when they're really needed to satisfy a transfer, or
when randomly picked in the normal course of selection). This may
be improved in the future.
Diffstat (limited to 'src/simplewallet/simplewallet.cpp')
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 6cbdf1a1e..9c58d71d4 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -615,6 +615,42 @@ bool simple_wallet::set_unit(const std::vector<std::string> &args/* = std::vecto return true; } +bool simple_wallet::set_min_output_count(const std::vector<std::string> &args/* = std::vector<std::string>()*/) +{ + uint32_t count; + if (!string_tools::get_xtype_from_string(count, args[1])) + { + fail_msg_writer() << tr("invalid count: must be an unsigned integer"); + return true; + } + + const auto pwd_container = get_and_verify_password(); + if (pwd_container) + { + m_wallet->set_min_output_count(count); + m_wallet->rewrite(m_wallet_file, pwd_container->password()); + } + return true; +} + +bool simple_wallet::set_min_output_value(const std::vector<std::string> &args/* = std::vector<std::string>()*/) +{ + uint64_t value; + if (!cryptonote::parse_amount(value, args[1])) + { + fail_msg_writer() << tr("invalid value"); + return true; + } + + const auto pwd_container = get_and_verify_password(); + if (pwd_container) + { + m_wallet->set_min_output_value(value); + 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>()*/) { success_msg_writer() << get_commands_str(); @@ -654,7 +690,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 [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("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; min-output-count [n] - try to keep at least that many outputs of value at least min-output-value; min-output-value [n] - try to keep at least min-output-count outputs of at least that value")); 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>")); @@ -690,6 +726,8 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args) success_msg_writer() << "confirm-missing-payment-id = " << m_wallet->confirm_missing_payment_id(); success_msg_writer() << "ask-password = " << m_wallet->ask_password(); success_msg_writer() << "unit = " << cryptonote::get_unit(m_wallet->get_default_decimal_point()); + success_msg_writer() << "min-outputs-count = " << m_wallet->get_min_output_count(); + success_msg_writer() << "min-outputs-value = " << cryptonote::print_money(m_wallet->get_min_output_value()); return true; } else @@ -838,6 +876,32 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args) return true; } } + else if (args[0] == "min-outputs-count") + { + if (args.size() <= 1) + { + fail_msg_writer() << tr("set min-outputs-count: needs an argument (unsigned integer)"); + return true; + } + else + { + set_min_output_count(args); + return true; + } + } + else if (args[0] == "min-outputs-value") + { + if (args.size() <= 1) + { + fail_msg_writer() << tr("set min-outputs-value: needs an argument (unsigned integer)"); + return true; + } + else + { + set_min_output_value(args); + return true; + } + } } fail_msg_writer() << tr("set: unrecognized argument(s)"); return true; |