From bdd9e834189cec21e3ca65002f5b14d5e7f0b29d Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 25 Oct 2023 21:34:50 +0200 Subject: [PATCH] simplewallet's "list_outputs" command and wallet2::get_transfers_str() were improved to support assets --- src/simplewallet/simplewallet.cpp | 41 +++++++++++++++++++------------ src/wallet/wallet2.cpp | 34 +++++++++++++++++++++---- src/wallet/wallet2.h | 2 +- 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index b80d01d5..d26d0849 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -269,7 +269,8 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("incoming_counts", boost::bind(&simple_wallet::show_incoming_transfers_counts, this, ph::_1), "incoming_transfers counts"); m_cmd_binder.set_handler("list_recent_transfers", boost::bind(&simple_wallet::list_recent_transfers, this, ph::_1), "list_recent_transfers [offset] [count] - Show recent maximum 1000 transfers, offset default = 0, count default = 100 "); m_cmd_binder.set_handler("export_recent_transfers", boost::bind(&simple_wallet::export_recent_transfers, this, ph::_1), "list_recent_transfers_tx - Write recent transfer in json to wallet_recent_transfers.txt"); - m_cmd_binder.set_handler("list_outputs", boost::bind(&simple_wallet::list_outputs, this, ph::_1), "list_outputs [spent|unspent] - Lists all the outputs that have ever been sent to this wallet if called without arguments, otherwise it lists only the spent or unspent outputs"); + m_cmd_binder.set_handler("list_outputs", boost::bind(&simple_wallet::list_outputs, this, ph::_1), "list_outputs [spent|unspent] [ticker=ZANO] [unknown] - Lists all the outputs. The result may be filtered by spent status, asset ticker or unknown asset ids."); + m_cmd_binder.set_handler("lo", boost::bind(&simple_wallet::list_outputs, this, ph::_1), "alias for list_outputs"); m_cmd_binder.set_handler("dump_transfers", boost::bind(&simple_wallet::dump_trunsfers, this, ph::_1), "dump_transfers - Write transfers in json to dump_transfers.txt"); m_cmd_binder.set_handler("dump_keyimages", boost::bind(&simple_wallet::dump_key_images, this, ph::_1), "dump_keyimages - Write key_images in json to dump_key_images.txt"); m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, ph::_1), "payments [ ... ] - Show payments , ... "); @@ -1775,28 +1776,36 @@ bool simple_wallet::save_watch_only(const std::vector &args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::list_outputs(const std::vector &args) { - if (args.size() > 1) - { - fail_msg_writer() << "invalid syntax: one or none parameters are expected, " << args.size() << " was given"; - return true; - } + bool include_spent = true, include_unspent = true, show_only_unknown = false; + std::string filter_asset_ticker{}; - bool include_spent = true, include_unspent = true; - if (args.size() == 1) - { - if (args[0] == "unspent" || args[0] == "available") - include_spent = false; - else if (args[0] == "spent" || args[0] == "unavailable") - include_unspent = false; + bool arg_spent_flags = false, arg_unknown_assets = false, arg_ticker_filer = false; + + auto process_arg = [&](const std::string& arg) -> bool { + if (!arg_spent_flags && (arg == "u" || arg == "unspent" || arg == "available")) + arg_spent_flags = true, include_spent = false; + else if (!arg_spent_flags && (arg == "s" || arg == "spent" || arg == "unavailable")) + arg_spent_flags = true, include_unspent = false; + else if (!arg_unknown_assets && (arg == "unknown")) + arg_unknown_assets = true, show_only_unknown = true; + else if (!arg_ticker_filer && (arg.find("ticker=") == 0 || arg.find("t=") == 0)) + arg_ticker_filer = true, filter_asset_ticker = boost::erase_all_copy(boost::erase_all_copy(arg, "ticker="), "t="); else + return false; + return true; + }; + + for(auto& arg : args) + { + if (!process_arg(arg)) { - fail_msg_writer() << "invalid parameter: " << args[0]; + fail_msg_writer() << "invalid parameter: " << arg; return true; } } - success_msg_writer() << "list of all the outputs that have ever been sent to this wallet:" << ENDL << - m_wallet->get_transfers_str(include_spent, include_unspent); + success_msg_writer() << m_wallet->get_transfers_str(include_spent, include_unspent, show_only_unknown, filter_asset_ticker); + return true; } //---------------------------------------------------------------------------------------------------- diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index b828d36d..4f4117c1 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3590,12 +3590,13 @@ bool wallet2::generate_utxo_defragmentation_transaction_if_needed(currency::tran return true; } //---------------------------------------------------------------------------------------------------- -std::string wallet2::get_transfers_str(bool include_spent /*= true*/, bool include_unspent /*= true*/) const +std::string wallet2::get_transfers_str(bool include_spent /*= true*/, bool include_unspent /*= true*/, bool show_only_unknown /*= false*/, const std::string& filter_asset_ticker /*= std::string{}*/) const { - static const char* header = "index amount g_index flags block tx out# key image"; + static const char* header = "index amount ticker g_index flags block tx out# asset id"; std::stringstream ss; ss << header << ENDL; size_t count = 0; + size_t unknown_assets_outs_count = 0; for (size_t i = 0; i != m_transfers.size(); ++i) { const transfer_details& td = m_transfers[i]; @@ -3603,21 +3604,44 @@ std::string wallet2::get_transfers_str(bool include_spent /*= true*/, bool inclu if ((td.is_spent() && !include_spent) || (!td.is_spent() && !include_unspent)) continue; + bool native_coin = td.is_native_coin(); + asset_descriptor_base adb{}; + bool whitelisted = false; + if (get_asset_id_info(td.get_asset_id(), adb, whitelisted) == show_only_unknown) + { + if (!show_only_unknown) + ++unknown_assets_outs_count; + continue; + } + + if (!filter_asset_ticker.empty() && adb.ticker != filter_asset_ticker) + continue; + ss << std::right << std::setw(5) << i << " " << - std::setw(21) << print_money(td.amount()) << " " << + std::setw(21) << print_asset_money(td.m_amount, adb.decimal_point) << " " << + std::setw(6) << std::left << (native_coin ? std::string(" ") : adb.ticker) << " " << std::right << std::setw(7) << td.m_global_output_index << " " << std::setw(2) << std::setfill('0') << td.m_flags << std::setfill(' ') << ":" << std::setw(5) << transfer_flags_to_str(td.m_flags) << " " << std::setw(7) << td.m_ptx_wallet_info->m_block_height << " " << get_transaction_hash(td.m_ptx_wallet_info->m_tx) << " " << - std::setw(4) << td.m_internal_output_index << " " << - td.m_key_image << ENDL; + std::setw(4) << td.m_internal_output_index << " "; + if (native_coin) + ss << " "; + else + ss << td.get_asset_id(); + ss << ENDL; + ++count; } ss << "printed " << count << " outputs of " << m_transfers.size() << " total" << ENDL; + if (unknown_assets_outs_count == 1) + ss << "(" << unknown_assets_outs_count << " output with unrecognized asset id is not shown, use 'list_outputs unknown' to see it)" << ENDL; + else if (unknown_assets_outs_count > 1) + ss << "(" << unknown_assets_outs_count << " outputs with unrecognized asset ids are not shown, use 'list_outputs unknown' to see them)" << ENDL; return ss.str(); } //---------------------------------------------------------------------------------------------------- diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 5c3a08f6..63eb6d0c 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -833,7 +833,7 @@ namespace tools bool fill_mining_context(mining_context& ctx); void get_transfers(wallet2::transfer_container& incoming_transfers) const; - std::string get_transfers_str(bool include_spent = true, bool include_unspent = true) const; + std::string get_transfers_str(bool include_spent = true, bool include_unspent = true, bool show_only_unknown = false, const std::string& filter_asset_ticker = std::string{}) const; std::string get_balance_str() const; // Returns all payments by given id in unspecified order