diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 0f32ea091..c3610c562 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -121,6 +121,7 @@ namespace const command_line::arg_descriptor arg_trusted_daemon = {"trusted-daemon", sw::tr("Enable commands which rely on a trusted daemon"), false}; const command_line::arg_descriptor arg_allow_mismatched_daemon_version = {"allow-mismatched-daemon-version", sw::tr("Allow communicating with a daemon that uses a different RPC version"), false}; const command_line::arg_descriptor arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0}; + const command_line::arg_descriptor arg_do_not_relay = {"do-not-relay", sw::tr("The newly created transaction will not be relayed to the monero network"), false}; const command_line::arg_descriptor< std::vector > arg_command = {"command", ""}; @@ -1507,6 +1508,7 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_ m_trusted_daemon = command_line::get_arg(vm, arg_trusted_daemon); m_allow_mismatched_daemon_version = command_line::get_arg(vm, arg_allow_mismatched_daemon_version); m_restore_height = command_line::get_arg(vm, arg_restore_height); + m_do_not_relay = command_line::get_arg(vm, arg_do_not_relay); m_restoring = !m_generate_from_view_key.empty() || !m_generate_from_keys.empty() || !m_generate_from_multisig_keys.empty() || @@ -2778,15 +2780,9 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vectorcommit_tx(ptx); - success_msg_writer(true) << tr("Transaction successfully submitted, transaction ") << get_transaction_hash(ptx.tx) << ENDL - << tr("You can check its status by using the `show_transfers` command."); - - // if no exception, remove element from vector - ptx_vector.pop_back(); + commit_or_save(ptx_vector, m_do_not_relay); } } catch (const tools::error::daemon_busy&) @@ -2956,14 +2952,9 @@ bool simple_wallet::sweep_unmixable(const std::vector &args_) success_msg_writer(true) << tr("Unsigned transaction(s) successfully written to file: ") << "unsigned_monero_tx"; } } - else while (!ptx_vector.empty()) + else { - auto & ptx = ptx_vector.back(); - m_wallet->commit_tx(ptx); - success_msg_writer(true) << tr("Money successfully sent, transaction: ") << get_transaction_hash(ptx.tx); - - // if no exception, remove element from vector - ptx_vector.pop_back(); + commit_or_save(ptx_vector, m_do_not_relay); } } catch (const tools::error::daemon_busy&) @@ -3241,14 +3232,9 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector &a success_msg_writer(true) << tr("Unsigned transaction(s) successfully written to file: ") << "unsigned_monero_tx"; } } - else while (!ptx_vector.empty()) + else { - auto & ptx = ptx_vector.back(); - m_wallet->commit_tx(ptx); - success_msg_writer(true) << tr("Money successfully sent, transaction: ") << get_transaction_hash(ptx.tx); - - // if no exception, remove element from vector - ptx_vector.pop_back(); + commit_or_save(ptx_vector, m_do_not_relay); } } catch (const tools::error::daemon_busy&) @@ -3599,16 +3585,7 @@ bool simple_wallet::submit_transfer(const std::vector &args_) return true; } - // actually commit the transactions - while (!ptx_vector.empty()) - { - auto & ptx = ptx_vector.back(); - m_wallet->commit_tx(ptx); - success_msg_writer(true) << tr("Money successfully sent, transaction: ") << get_transaction_hash(ptx.tx); - - // if no exception, remove element from vector - ptx_vector.pop_back(); - } + commit_or_save(ptx_vector, false); } catch (const tools::error::daemon_busy&) { @@ -5442,6 +5419,35 @@ void simple_wallet::interrupt() } } //---------------------------------------------------------------------------------------------------- +void simple_wallet::commit_or_save(std::vector& ptx_vector, bool do_not_relay) +{ + size_t i = 0; + while (!ptx_vector.empty()) + { + auto & ptx = ptx_vector.back(); + const crypto::hash txid = get_transaction_hash(ptx.tx); + if (do_not_relay) + { + cryptonote::blobdata blob; + tx_to_blob(ptx.tx, blob); + const std::string blob_hex = epee::string_tools::buff_to_hex_nodelimer(blob); + const std::string filename = "raw_monero_tx" + (ptx_vector.size() == 1 ? "" : ("_" + std::to_string(i++))); + if (epee::file_io_utils::save_string_to_file(filename, blob_hex)) + success_msg_writer(true) << tr("Transaction successfully saved to ") << filename << tr(", txid ") << txid; + else + fail_msg_writer() << tr("Failed to save transaction to ") << filename << tr(", txid ") << txid; + } + else + { + m_wallet->commit_tx(ptx); + success_msg_writer(true) << tr("Transaction successfully submitted, transaction ") << txid << ENDL + << tr("You can check its status by using the `show_transfers` command."); + } + // if no exception, remove element from vector + ptx_vector.pop_back(); + } +} +//---------------------------------------------------------------------------------------------------- int main(int argc, char* argv[]) { po::options_description desc_params(wallet_args::tr("Wallet options")); @@ -5461,6 +5467,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_trusted_daemon); command_line::add_arg(desc_params, arg_allow_mismatched_daemon_version); command_line::add_arg(desc_params, arg_restore_height); + command_line::add_arg(desc_params, arg_do_not_relay); po::positional_options_description positional_options; positional_options.add(arg_command.name, -1); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 3525e82bc..a1f42ba9d 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -207,6 +207,12 @@ namespace cryptonote */ std::string get_mnemonic_language(); + /*! + * \brief When --do-not-relay option is specified, save the raw tx hex blob to a file instead of calling m_wallet->commit_tx(ptx). + * \param ptx_vector Pending tx(es) created by transfer/sweep_all + */ + void commit_or_save(std::vector& ptx_vector, bool do_not_relay); + //----------------- i_wallet2_callback --------------------- virtual void on_new_block(uint64_t height, const cryptonote::block& block); virtual void on_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount, const cryptonote::subaddress_index& subaddr_index); @@ -287,6 +293,7 @@ namespace cryptonote bool m_allow_mismatched_daemon_version; bool m_restoring; // are we restoring, by whatever method? uint64_t m_restore_height; // optional + bool m_do_not_relay; epee::console_handlers_binder m_cmd_binder;