Add locked_transfer

This commit is contained in:
Oyvind Kvanes 2016-09-28 16:27:45 +02:00
parent d5f918a0b1
commit 7d020bde5e
1 changed files with 84 additions and 88 deletions

View File

@ -652,7 +652,7 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("bc_height", boost::bind(&simple_wallet::show_blockchain_height, this, _1), tr("Show blockchain height"));
m_cmd_binder.set_handler("transfer_original", boost::bind(&simple_wallet::transfer, this, _1), tr("transfer [<mixin_count>] <addr_1> <amount_1> [<addr_2> <amount_2> ... <addr_N> <amount_N>] [payment_id] - Transfer <amount_1>,... <amount_N> to <address_1>,... <address_N>, respectively. <mixin_count> is the number of extra inputs to include for untraceability (from 0 to maximum available)"));
m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer_new, this, _1), tr("Same as transfer_original, but using a new transaction building algorithm"));
m_cmd_binder.set_handler("locked_transfer", boost::bind(&simple_wallet::locked_transfer, this, _1), tr("Make a transfer using unlock_time"));
m_cmd_binder.set_handler("locked_transfer", boost::bind(&simple_wallet::locked_transfer, this, _1), tr("transfer [<mixin_count>] <addr> <amount> <locktime>(Number of blocks to lock the transaction for) [payment_id]"));
m_cmd_binder.set_handler("sweep_unmixable", boost::bind(&simple_wallet::sweep_unmixable, this, _1), tr("Send all unmixable outputs to yourself with mixin 0"));
m_cmd_binder.set_handler("sweep_all", boost::bind(&simple_wallet::sweep_all, this, _1), tr("Send all unlocked balance an address"));
m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), tr("set_log <level> - Change current log detail level, <0-4>"));
@ -836,7 +836,7 @@ bool simple_wallet::ask_wallet_create_if_needed()
bool valid_path = false;
do {
wallet_path = command_line::input_line(
tr("NOTE: This is my Wallet- Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created.\n"
tr("Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created.\n"
"Wallet file name: ")
);
if (std::cin.eof())
@ -2582,7 +2582,7 @@ bool simple_wallet::locked_transfer(const std::vector<std::string> &args_)
}
}
if(local_args.size() < 2)
if(local_args.size() < 3 )
{
fail_msg_writer() << tr("wrong number of arguments");
return true;
@ -2593,10 +2593,12 @@ bool simple_wallet::locked_transfer(const std::vector<std::string> &args_)
fail_msg_writer() << tr("this is a watch only wallet");
return true;
}
int given_unlock_time = 10;
int given_unlock_time = 0;
std::vector<uint8_t> extra;
bool payment_id_seen = false;
if (1 == local_args.size() % 2)
if (local_args.size() < 5)
{
if (local_args.size() == 4)
{
std::string payment_id_str = local_args.back();
local_args.pop_back();
@ -2624,19 +2626,23 @@ bool simple_wallet::locked_transfer(const std::vector<std::string> &args_)
if(!r)
{
fail_msg_writer() << tr("payment id has invalid format, expected 16 or 64 character hex string: ") << payment_id_str;
std::string err;
int bc_height = get_daemon_blockchain_height(err);
given_unlock_time = bc_height + std::stoi(payment_id_str);
//return true;
payment_id_seen = false;
return true;
}
}
//std::string unlock_time_string = local_args.back();
given_unlock_time = std::stoi( local_args.back() );
local_args.pop_back();
}
else
{
fail_msg_writer() << tr("wrong number of arguments");
return true;
}
vector<cryptonote::tx_destination_entry> dsts;
for (size_t i = 0; i < local_args.size(); i += 2)
for (size_t i = 0; i < 1; i += 2)
{
cryptonote::tx_destination_entry de;
bool has_payment_id;
@ -2677,12 +2683,12 @@ bool simple_wallet::locked_transfer(const std::vector<std::string> &args_)
{
// figure out what tx will be necessary
std::vector<tools::wallet2::pending_tx> ptx_vector;
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, given_unlock_time /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon);
std::string err;
int bc_height = get_daemon_blockchain_height(err);
int unlock_time = given_unlock_time + bc_height;
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_time , 0 /* unused fee arg*/, extra, m_trusted_daemon);
// if more than one tx necessary, prompt user to confirm
if (m_wallet->always_confirm_transfers() || ptx_vector.size() > 1)
{
uint64_t total_fee = 0;
uint64_t dust_not_in_fee = 0;
uint64_t dust_in_fee = 0;
@ -2705,17 +2711,18 @@ bool simple_wallet::locked_transfer(const std::vector<std::string> &args_)
}
else
{
std::string err;
int bc_height = get_daemon_blockchain_height(err);
float days = (float)(given_unlock_time - bc_height) / 720.0;
prompt << boost::format(tr("The transaction fee is %s")) %
prompt << boost::format(tr("Transaction fee is %s")) %
print_money(total_fee);
prompt << boost::format(tr("The unlock time is approximately %s days")) %
days;
}
if (dust_in_fee != 0) prompt << boost::format(tr(", of which %s is dust from change")) % print_money(dust_in_fee);
if (dust_not_in_fee != 0) prompt << tr(".") << ENDL << boost::format(tr("A total of %s from dust change will be sent to dust address"))
% print_money(dust_not_in_fee);
float days = (float)(given_unlock_time) / 720.0;
prompt << boost::format(tr(".\nThe unlock time is approximately %s days")) %
days;
prompt << tr(".") << ENDL << tr("Is this okay? (Y/Yes/N/No)");
std::string accepted = command_line::input_line(prompt.str());
@ -2724,12 +2731,8 @@ bool simple_wallet::locked_transfer(const std::vector<std::string> &args_)
if (accepted != "Y" && accepted != "y" && accepted != "Yes" && accepted != "yes")
{
fail_msg_writer() << tr("transaction cancelled.");
// would like to return false, because no tx made, but everything else returns true
// and I don't know what returning false might adversely affect. *sigh*
return true;
}
}
// actually commit the transactions
while (!ptx_vector.empty())
@ -2761,18 +2764,11 @@ bool simple_wallet::locked_transfer(const std::vector<std::string> &args_)
}
catch (const tools::error::not_enough_money& e)
{
std::stringstream prompt;
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
print_money(e.available()) %
print_money(e.tx_amount() + e.fee()) %
print_money(e.tx_amount()) %
print_money(e.fee()));
prompt << boost::format(tr("Available %s, transaction amount %s = %s + %s (fee)")) %
print_money(e.available()) %
print_money(e.tx_amount() + e.fee()) %
print_money(e.tx_amount()) %
print_money(e.fee());
std::string accepted = command_line::input_line(prompt.str());
fail_msg_writer() << tr("Failed to find a way to create transactions, too bad. This is usually due to dust which is so small it cannot pay for itself in fees");
}
catch (const tools::error::not_enough_outs_to_mix& e)