a number of fixes; disabled return_payment as the functionality is changing to NOT require returning the same output
This commit is contained in:
+13
-3
@@ -264,6 +264,8 @@ namespace config
|
||||
uint32_t const GENESIS_NONCE = 10000;
|
||||
|
||||
const uint64_t YIELD_LOCK_PERIOD = 5;//30*24*30;
|
||||
|
||||
std::string const TREASURY_ADDRESS = "fuLMowH85abK8nz9BBMEem7MAfUbQu4aSHHUV9j5Z86o6Go9Lv2U5ZQiJCWPY9R9HA8p5idburazjAhCqDngLo7fYPCD9ciM9ee1A";
|
||||
|
||||
// Hash domain separators
|
||||
const char HASH_KEY_BULLETPROOF_EXPONENT[] = "bulletproof";
|
||||
@@ -342,6 +344,8 @@ namespace config
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5YBxWx1AZCA9jTUk8Pr2uZ9jpfRt\n"
|
||||
"KWv3Vo1/Gny+1vfaxsXhBQiG1KlHkafNGarzoL0WHW4ocqaaqF5iv8i35A==\n"
|
||||
"-----END PUBLIC KEY-----\n";
|
||||
|
||||
std::string const TREASURY_ADDRESS = "fuLMowH85abK8nz9BBMEem7MAfUbQu4aSHHUV9j5Z86o6Go9Lv2U5ZQiJCWPY9R9HA8p5idburazjAhCqDngLo7fYPCD9ciM9ee1A";
|
||||
}
|
||||
|
||||
namespace stagenet
|
||||
@@ -366,6 +370,8 @@ namespace config
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5YBxWx1AZCA9jTUk8Pr2uZ9jpfRt\n"
|
||||
"KWv3Vo1/Gny+1vfaxsXhBQiG1KlHkafNGarzoL0WHW4ocqaaqF5iv8i35A==\n"
|
||||
"-----END PUBLIC KEY-----\n";
|
||||
|
||||
std::string const TREASURY_ADDRESS = "fuLMowH85abK8nz9BBMEem7MAfUbQu4aSHHUV9j5Z86o6Go9Lv2U5ZQiJCWPY9R9HA8p5idburazjAhCqDngLo7fYPCD9ciM9ee1A";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,6 +399,7 @@ namespace cryptonote
|
||||
std::array<std::string, 3> const ORACLE_URLS;
|
||||
std::string const ORACLE_PUBLIC_KEY;
|
||||
uint64_t YIELD_LOCK_PERIOD;
|
||||
std::string TREASURY_ADDRESS;
|
||||
};
|
||||
inline const config_t& get_config(network_type nettype)
|
||||
{
|
||||
@@ -408,7 +415,8 @@ namespace cryptonote
|
||||
::config::GENESIS_NONCE,
|
||||
::config::ORACLE_URLS,
|
||||
::config::ORACLE_PUBLIC_KEY,
|
||||
::config::YIELD_LOCK_PERIOD
|
||||
::config::YIELD_LOCK_PERIOD,
|
||||
::config::TREASURY_ADDRESS
|
||||
};
|
||||
static const config_t testnet = {
|
||||
::config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX,
|
||||
@@ -422,7 +430,8 @@ namespace cryptonote
|
||||
::config::testnet::GENESIS_NONCE,
|
||||
::config::testnet::ORACLE_URLS,
|
||||
::config::testnet::ORACLE_PUBLIC_KEY,
|
||||
::config::testnet::YIELD_LOCK_PERIOD
|
||||
::config::testnet::YIELD_LOCK_PERIOD,
|
||||
::config::testnet::TREASURY_ADDRESS
|
||||
};
|
||||
static const config_t stagenet = {
|
||||
::config::stagenet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX,
|
||||
@@ -436,7 +445,8 @@ namespace cryptonote
|
||||
::config::stagenet::GENESIS_NONCE,
|
||||
::config::stagenet::ORACLE_URLS,
|
||||
::config::stagenet::ORACLE_PUBLIC_KEY,
|
||||
::config::stagenet::YIELD_LOCK_PERIOD
|
||||
::config::stagenet::YIELD_LOCK_PERIOD,
|
||||
::config::stagenet::TREASURY_ADDRESS
|
||||
};
|
||||
switch (nettype)
|
||||
{
|
||||
|
||||
@@ -1898,7 +1898,10 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
|
||||
// Time to construct the protocol_tx
|
||||
uint64_t protocol_fee = 0;
|
||||
ok = construct_protocol_tx(height, protocol_fee, b.protocol_tx, protocol_entries, circ_supply, pr, b.major_version);
|
||||
address_parse_info treasury_address_info;
|
||||
ok = cryptonote::get_account_address_from_str(treasury_address_info, m_nettype, get_config(m_nettype).TREASURY_ADDRESS);
|
||||
CHECK_AND_ASSERT_MES(ok, false, "Failed to obtain treasury address info");
|
||||
ok = construct_protocol_tx(height, protocol_fee, b.protocol_tx, protocol_entries, circ_supply, pr, miner_address, treasury_address_info.address, b.major_version);
|
||||
CHECK_AND_ASSERT_MES(ok, false, "Failed to construct protocol tx");
|
||||
|
||||
pool_cookie = m_tx_pool.cookie();
|
||||
|
||||
@@ -197,18 +197,12 @@ namespace cryptonote
|
||||
// Apply slippage to the burnt amount
|
||||
amount_slippage = amount_burnt >> 5; // (1/32)
|
||||
|
||||
if (hf_version >= HF_VERSION_SLIPPAGE_YIELD) {
|
||||
|
||||
// Apply slippage to the burnt amount
|
||||
amount_slippage = amount_burnt >> 5; // (1/32)
|
||||
|
||||
// Check that the slippage is acceptable
|
||||
if (amount_slippage > amount_slippage_limit) {
|
||||
// Bail out with no conversion
|
||||
LOG_PRINT_L1("Unable to convert - slippage limit was too low");
|
||||
amount_minted = 0;
|
||||
return true;
|
||||
}
|
||||
// Check that the slippage is acceptable
|
||||
if (amount_slippage > amount_slippage_limit) {
|
||||
// Bail out with no conversion
|
||||
LOG_PRINT_L1("Unable to convert - slippage limit was too low");
|
||||
amount_minted = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Work out the converted amount
|
||||
@@ -224,11 +218,13 @@ namespace cryptonote
|
||||
std::vector<protocol_data_entry>& protocol_data,
|
||||
std::map<std::string, uint64_t> circ_supply,
|
||||
const oracle::pricing_record& pr,
|
||||
const account_public_address &miner_address,
|
||||
const account_public_address &treasury_address,
|
||||
const uint8_t hf_version) {
|
||||
|
||||
// A vector to contain all of the additional _tx_secret_keys_
|
||||
//std::vector<crypto::secret_key>& additional_tx_keys;
|
||||
|
||||
|
||||
// Clear the TX contents
|
||||
tx.set_null();
|
||||
tx.type = cryptonote::transaction_type::PROTOCOL;
|
||||
@@ -255,6 +251,7 @@ namespace cryptonote
|
||||
|
||||
// Calculate the slippage for the output amounts
|
||||
LOG_PRINT_L2("Creating protocol_tx...");
|
||||
uint64_t slippage_total = 0;
|
||||
std::vector<crypto::public_key> additional_tx_public_keys;
|
||||
for (auto const& entry: protocol_data) {
|
||||
if (entry.destination_asset == "BURN") {
|
||||
@@ -337,6 +334,19 @@ namespace cryptonote
|
||||
// CONVERTED
|
||||
LOG_PRINT_L2("Conversion TX submitted - converted " << print_money(entry.amount_burnt) << " " << entry.source_asset << " to " << print_money(amount_minted) << " " << entry.destination_asset << "(slippage " << print_money(amount_slippage) << ")");
|
||||
txin_gen_totals[entry.destination_asset] += amount_minted;
|
||||
|
||||
// Add the slippage to our total for the block
|
||||
if (entry.source_asset == "FULM") {
|
||||
slippage_total += amount_slippage;
|
||||
} else {
|
||||
// Convert the slippage into a FULM amount so we can pay a proportion to the miner
|
||||
uint64_t conversion_rate = 0, amount_slippage_converted = 0;
|
||||
ok = get_conversion_rate(pr, entry.source_asset, entry.destination_asset, conversion_rate);
|
||||
CHECK_AND_ASSERT_MES(ok, false, "Failed to get conversion rate for miner payout");
|
||||
ok = get_converted_amount(conversion_rate, amount_slippage, amount_slippage_converted);
|
||||
CHECK_AND_ASSERT_MES(ok, false, "Failed to get converted slippage amount for miner payout");
|
||||
slippage_total += amount_slippage_converted;
|
||||
}
|
||||
|
||||
// Create the TX output for this conversion
|
||||
tx_out out;
|
||||
@@ -359,9 +369,46 @@ namespace cryptonote
|
||||
tx.vout.push_back(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add in all of the additional TX pubkeys we need to process the payments
|
||||
add_additional_tx_pub_keys_to_extra(tx.extra, additional_tx_public_keys);
|
||||
|
||||
if (slippage_total > 0) {
|
||||
|
||||
// Add a payout for the miner
|
||||
uint64_t slippage_miner = slippage_total / 5;
|
||||
|
||||
crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
|
||||
crypto::public_key out_eph_public_key = AUTO_VAL_INIT(out_eph_public_key);
|
||||
bool r = crypto::generate_key_derivation(miner_address.m_view_public_key, txkey.sec, derivation);
|
||||
CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to generate_key_derivation(" << miner_address.m_view_public_key << ", " << txkey.sec << ")");
|
||||
|
||||
// Calculate the uniqueness
|
||||
crypto::key_image k_image;
|
||||
ec_scalar uniqueness;
|
||||
CHECK_AND_ASSERT_MES(calculate_uniqueness(tx.type, k_image, height, ((size_t)-1), uniqueness), false, "while constructing miner_tx: failed to calculate uniqueness");
|
||||
|
||||
r = crypto::derive_public_key(derivation, uniqueness, miner_address.m_spend_public_key, out_eph_public_key);
|
||||
CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to derive_public_key(" << derivation << ", " << 0 << ", "<< miner_address.m_spend_public_key << ")");
|
||||
|
||||
tx_out out_miner;
|
||||
cryptonote::set_tx_out(slippage_miner, "FULM", 0, out_eph_public_key, false, crypto::view_tag{}, out_miner);
|
||||
tx.vout.push_back(out_miner);
|
||||
|
||||
// Add a payout for the treasury
|
||||
crypto::key_derivation derivation_treasury = AUTO_VAL_INIT(derivation_treasury);
|
||||
crypto::public_key out_eph_public_key_treasury = AUTO_VAL_INIT(out_eph_public_key_treasury);
|
||||
r = crypto::generate_key_derivation(treasury_address.m_view_public_key, txkey.sec, derivation_treasury);
|
||||
CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to generate_key_derivation(" << treasury_address.m_view_public_key << ", " << txkey.sec << ")");
|
||||
|
||||
r = crypto::derive_public_key(derivation_treasury, uniqueness, treasury_address.m_spend_public_key, out_eph_public_key_treasury);
|
||||
CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to derive_public_key(" << derivation << ", " << 0 << ", "<< miner_address.m_spend_public_key << ")");
|
||||
|
||||
uint64_t slippage_treasury = slippage_miner >> 1;
|
||||
tx_out out_treasury;
|
||||
cryptonote::set_tx_out(slippage_treasury, "FULM", 0, out_eph_public_key_treasury, false, crypto::view_tag{}, out_treasury);
|
||||
tx.vout.push_back(out_treasury);
|
||||
}
|
||||
|
||||
// Create the txin_gen now
|
||||
txin_gen in;
|
||||
@@ -930,6 +977,7 @@ namespace cryptonote
|
||||
// Do not create outputs that are for the destination asset type - discard them as unused
|
||||
if (dst_entr.asset_type == dest_asset) {
|
||||
tx.amount_burnt += dst_entr.amount;
|
||||
tx.amount_slippage_limit = dst_entr.slippage_limit;
|
||||
continue;
|
||||
}
|
||||
} else if (tx_type == cryptonote::transaction_type::YIELD) {
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace cryptonote
|
||||
crypto::public_key return_pubkey;
|
||||
};
|
||||
|
||||
bool construct_protocol_tx(const size_t height, uint64_t& protocol_fee, transaction& tx, std::vector<protocol_data_entry>& protocol_data, std::map<std::string, uint64_t> circ_supply, const oracle::pricing_record& pr, const uint8_t hf_version);
|
||||
bool construct_protocol_tx(const size_t height, uint64_t& protocol_fee, transaction& tx, std::vector<protocol_data_entry>& protocol_data, std::map<std::string, uint64_t> circ_supply, const oracle::pricing_record& pr, const account_public_address &miner_address, const account_public_address &treasury_address, const uint8_t hf_version);
|
||||
//---------------------------------------------------------------
|
||||
bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1);
|
||||
bool construct_protocol_tx(size_t height, transaction& tx, size_t max_outs = 999, uint8_t hard_fork_version = 1);
|
||||
@@ -111,15 +111,16 @@ namespace cryptonote
|
||||
{
|
||||
std::string original;
|
||||
uint64_t amount; //money
|
||||
uint64_t slippage_limit; //percentage of slippage permitted
|
||||
account_public_address addr; //destination address
|
||||
std::string asset_type;
|
||||
bool is_subaddress;
|
||||
bool is_integrated;
|
||||
bool is_change;
|
||||
|
||||
tx_destination_entry() : amount(0), addr(AUTO_VAL_INIT(addr)), asset_type("FULM"), is_subaddress(false), is_integrated(false), is_change(false) { }
|
||||
tx_destination_entry(uint64_t a, const account_public_address &ad, bool is_subaddress) : amount(a), addr(ad), is_subaddress(is_subaddress), is_integrated(false), is_change(false) { }
|
||||
tx_destination_entry(const std::string &o, uint64_t a, const account_public_address &ad, bool is_subaddress) : original(o), amount(a), addr(ad), is_subaddress(is_subaddress), is_integrated(false) { }
|
||||
tx_destination_entry() : amount(0), slippage_limit(0), addr(AUTO_VAL_INIT(addr)), asset_type("FULM"), is_subaddress(false), is_integrated(false), is_change(false) { }
|
||||
tx_destination_entry(uint64_t a, const account_public_address &ad, bool is_subaddress) : amount(a), slippage_limit(0), addr(ad), is_subaddress(is_subaddress), is_integrated(false), is_change(false) { }
|
||||
tx_destination_entry(const std::string &o, uint64_t a, const account_public_address &ad, bool is_subaddress) : original(o), amount(a), slippage_limit(0), addr(ad), is_subaddress(is_subaddress), is_integrated(false) { }
|
||||
|
||||
std::string address(network_type nettype, const crypto::hash &payment_id) const
|
||||
{
|
||||
@@ -139,6 +140,7 @@ namespace cryptonote
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(original)
|
||||
VARINT_FIELD(amount)
|
||||
VARINT_FIELD(slippage_limit)
|
||||
FIELD(addr)
|
||||
FIELD(asset_type)
|
||||
FIELD(is_subaddress)
|
||||
|
||||
@@ -6707,6 +6707,7 @@ bool simple_wallet::transfer_main(
|
||||
|
||||
vector<cryptonote::address_parse_info> dsts_info;
|
||||
vector<cryptonote::tx_destination_entry> dsts;
|
||||
double slippage_limit = 0.0;
|
||||
for (size_t i = 0; i < local_args.size(); )
|
||||
{
|
||||
dsts_info.emplace_back();
|
||||
@@ -6737,15 +6738,27 @@ bool simple_wallet::transfer_main(
|
||||
}
|
||||
else if (i + 1 < local_args.size())
|
||||
{
|
||||
r = cryptonote::get_account_address_from_str_or_url(info, m_wallet->nettype(), local_args[i], oa_prompter);
|
||||
bool ok = cryptonote::parse_amount(de.amount, local_args[i + 1]);
|
||||
if(!ok || 0 == de.amount)
|
||||
{
|
||||
fail_msg_writer() << tr("amount is wrong: ") << local_args[i] << ' ' << local_args[i + 1] <<
|
||||
", " << tr("expected number from 0 to ") << print_money(std::numeric_limits<uint64_t>::max());
|
||||
return false;
|
||||
if (transfer_type == Convert) {
|
||||
bool ok = cryptonote::parse_amount(de.amount, local_args[i]);
|
||||
if(!ok || 0 == de.amount)
|
||||
{
|
||||
fail_msg_writer() << tr("amount is wrong: ") << local_args[i] << ", " << tr("expected number from 0 to ") << print_money(std::numeric_limits<uint64_t>::max());
|
||||
return false;
|
||||
}
|
||||
double slippage_limit = std::stod(local_args[i+1]); // Already validated in simple_wallet::convert()
|
||||
de.slippage_limit = ((uint64_t)((double)de.amount * slippage_limit)) / 100;
|
||||
} else {
|
||||
r = cryptonote::get_account_address_from_str_or_url(info, m_wallet->nettype(), local_args[i], oa_prompter);
|
||||
bool ok = cryptonote::parse_amount(de.amount, local_args[i + 1]);
|
||||
if(!ok || 0 == de.amount)
|
||||
{
|
||||
fail_msg_writer() << tr("amount is wrong: ") << local_args[i] << ' ' << local_args[i + 1] <<
|
||||
", " << tr("expected number from 0 to ") << print_money(std::numeric_limits<uint64_t>::max());
|
||||
return false;
|
||||
}
|
||||
de.original = local_args[i];
|
||||
de.slippage_limit = 0;
|
||||
}
|
||||
de.original = local_args[i];
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
@@ -6759,6 +6772,7 @@ bool simple_wallet::transfer_main(
|
||||
return false;
|
||||
}
|
||||
de.asset_type = source_asset;
|
||||
de.slippage_limit = 0;
|
||||
++i;
|
||||
} else {
|
||||
if (boost::starts_with(local_args[i], "fulmo:"))
|
||||
@@ -7871,6 +7885,9 @@ bool simple_wallet::sweep_below(const std::vector<std::string> &args_)
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::return_payment(const std::vector<std::string> &args_)
|
||||
{
|
||||
if (!try_connect_to_daemon())
|
||||
return true;
|
||||
|
||||
// TODO: add locked versions
|
||||
if (args_.size() != 1)
|
||||
{
|
||||
@@ -7891,11 +7908,13 @@ bool simple_wallet::return_payment(const std::vector<std::string> &args_)
|
||||
|
||||
// Get the TX details
|
||||
tools::wallet2::transfer_container transfers;
|
||||
crypto::key_image ki;
|
||||
bool found_ki = false;
|
||||
m_wallet->get_transfers(transfers);
|
||||
for (const auto& td: transfers) {
|
||||
// Skip entries we don't care about
|
||||
if (td.m_txid != txid) continue;
|
||||
|
||||
|
||||
// Found the specified entry - make sure we can return it
|
||||
if (td.m_tx.type != cryptonote::transaction_type::TRANSFER) {
|
||||
fail_msg_writer() << tr("incorrect TX type for txid ") << local_args[0];
|
||||
@@ -7908,9 +7927,158 @@ bool simple_wallet::return_payment(const std::vector<std::string> &args_)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create the destination address...somehow
|
||||
//construct_tx_with_tx_key(
|
||||
// Check that we have the key image information, and that it is usable
|
||||
if (!td.m_key_image_known || td.m_key_image_partial || td.m_spent || td.m_frozen) {
|
||||
fail_msg_writer() << tr("key image is unavailable (partial / unknown / spent / frozen) for txid ") << local_args[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
ki = td.m_key_image;
|
||||
found_ki = true;
|
||||
}
|
||||
|
||||
// Check we have a valid key_image
|
||||
if (!found_ki) {
|
||||
fail_msg_writer() << tr("key image is unavailable (partial / unknown / spent / frozen) for txid ") << local_args[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is nonsense, really - priority isn't really a problem for Fulmo
|
||||
uint32_t priority = 0;
|
||||
priority = m_wallet->adjust_priority(priority);
|
||||
|
||||
// This should be fixed by the protocol - any changes would stand out like a sore thumb
|
||||
size_t fake_outs_count = m_wallet->get_min_ring_size() - 1;
|
||||
uint64_t adjusted_fake_outs_count = m_wallet->adjust_mixin(fake_outs_count);
|
||||
if (adjusted_fake_outs_count > fake_outs_count)
|
||||
{
|
||||
fail_msg_writer() << (boost::format(tr("ring size %u is too small, minimum is %u")) % (fake_outs_count+1) % (adjusted_fake_outs_count+1)).str();
|
||||
return true;
|
||||
}
|
||||
if (adjusted_fake_outs_count < fake_outs_count)
|
||||
{
|
||||
fail_msg_writer() << (boost::format(tr("ring size %u is too large, maximum is %u")) % (fake_outs_count+1) % (adjusted_fake_outs_count+1)).str();
|
||||
return true;
|
||||
}
|
||||
|
||||
// We will only use one output - the one we are returning - to pay for the transaction fully
|
||||
size_t outputs = 1;
|
||||
|
||||
std::vector<uint8_t> extra;
|
||||
|
||||
SCOPED_WALLET_UNLOCK();
|
||||
/*
|
||||
try
|
||||
{
|
||||
// figure out what tx will be necessary
|
||||
auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, outputs, fake_outs_count, 0, priority, extra);
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
fail_msg_writer() << tr("No outputs found");
|
||||
return true;
|
||||
}
|
||||
if (ptx_vector.size() > 1)
|
||||
{
|
||||
fail_msg_writer() << tr("Multiple transactions are created, which is not supposed to happen");
|
||||
return true;
|
||||
}
|
||||
if (ptx_vector[0].selected_transfers.size() != 1)
|
||||
{
|
||||
fail_msg_writer() << tr("The transaction uses multiple or no inputs, which is not supposed to happen");
|
||||
return true;
|
||||
}
|
||||
|
||||
// give user total and fee, and prompt to confirm
|
||||
uint64_t total_fee = ptx_vector[0].fee;
|
||||
uint64_t total_sent = m_wallet->get_transfer_details(ptx_vector[0].selected_transfers.front()).amount();
|
||||
std::ostringstream prompt;
|
||||
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
|
||||
return true;
|
||||
prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay?")) %
|
||||
print_money(total_sent) %
|
||||
print_money(total_fee);
|
||||
std::string accepted = input_line(prompt.str(), true);
|
||||
if (std::cin.eof())
|
||||
return true;
|
||||
if (!command_line::is_yes(accepted))
|
||||
{
|
||||
fail_msg_writer() << tr("transaction cancelled.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// actually commit the transactions
|
||||
if (m_wallet->multisig())
|
||||
{
|
||||
CHECK_MULTISIG_ENABLED();
|
||||
bool r = m_wallet->save_multisig_tx(ptx_vector, "multisig_monero_tx");
|
||||
if (!r)
|
||||
{
|
||||
fail_msg_writer() << tr("Failed to write transaction(s) to file");
|
||||
}
|
||||
else
|
||||
{
|
||||
success_msg_writer(true) << tr("Unsigned transaction(s) successfully written to file: ") << "multisig_monero_tx";
|
||||
}
|
||||
}
|
||||
else if (m_wallet->get_account().get_device().has_tx_cold_sign())
|
||||
{
|
||||
try
|
||||
{
|
||||
tools::wallet2::signed_tx_set signed_tx;
|
||||
std::vector<cryptonote::address_parse_info> dsts_info;
|
||||
dsts_info.push_back(info);
|
||||
|
||||
if (!cold_sign_tx(ptx_vector, signed_tx, dsts_info, [&](const tools::wallet2::signed_tx_set &tx){ return accept_loaded_tx(tx); })){
|
||||
fail_msg_writer() << tr("Failed to cold sign transaction with HW wallet");
|
||||
return true;
|
||||
}
|
||||
|
||||
commit_or_save(signed_tx.ptx, m_do_not_relay);
|
||||
success_msg_writer(true) << tr("Money successfully sent, transaction: ") << get_transaction_hash(ptx_vector[0].tx);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_transfer_exception(std::current_exception(), m_wallet->is_trusted_daemon());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_ERROR("Unknown error");
|
||||
fail_msg_writer() << tr("unknown error");
|
||||
}
|
||||
}
|
||||
else if (m_wallet->watch_only())
|
||||
{
|
||||
bool r = m_wallet->save_tx(ptx_vector, "unsigned_monero_tx");
|
||||
if (!r)
|
||||
{
|
||||
fail_msg_writer() << tr("Failed to write transaction(s) to file");
|
||||
}
|
||||
else
|
||||
{
|
||||
success_msg_writer(true) << tr("Unsigned transaction(s) successfully written to file: ") << "unsigned_monero_tx";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wallet->commit_tx(ptx_vector[0]);
|
||||
success_msg_writer(true) << tr("Money successfully sent, transaction: ") << get_transaction_hash(ptx_vector[0].tx);
|
||||
}
|
||||
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_transfer_exception(std::current_exception(), m_wallet->is_trusted_daemon());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_ERROR("unknown error");
|
||||
fail_msg_writer() << tr("unknown error");
|
||||
}
|
||||
*/
|
||||
|
||||
fail_msg_writer() << tr("return_payment() is not implemented");
|
||||
return true;
|
||||
|
||||
fail_msg_writer() << tr("failed to locate txid ") << local_args[0];
|
||||
return true;
|
||||
@@ -7947,18 +8115,49 @@ bool simple_wallet::burn(const std::vector<std::string> &args_)
|
||||
bool simple_wallet::convert(const std::vector<std::string> &args_)
|
||||
{
|
||||
// TODO: add locked versions
|
||||
if (args_.size() != 3)
|
||||
if (args_.size() not_eq 3 and args_.size() not_eq 4)
|
||||
{
|
||||
fail_msg_writer() << tr("missing / extraneous argument(s)");
|
||||
PRINT_USAGE(USAGE_CONVERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> local_args = args_;
|
||||
std::string strLastArg = local_args.back();
|
||||
|
||||
// Check to see if the last arg is "slippage_limit" (a decimal number)
|
||||
double slippage_limit = 0.0;
|
||||
if (args_.size() == 4) {
|
||||
// Expect to be able to parse the last arg as a double
|
||||
try
|
||||
{
|
||||
slippage_limit = std::stod(strLastArg);
|
||||
if (slippage_limit < 0.0 or slippage_limit > 90.0) {
|
||||
fail_msg_writer() << tr("invalid slippage_limit value : expected 0.0-90.0, got ") << slippage_limit;
|
||||
PRINT_USAGE(USAGE_CONVERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Update the last arg value
|
||||
local_args.pop_back();
|
||||
strLastArg = local_args.back();
|
||||
}
|
||||
catch (std::invalid_argument const& ex)
|
||||
{
|
||||
fail_msg_writer() << tr("invalid argument(s): ") << ex.what();
|
||||
PRINT_USAGE(USAGE_CONVERT);
|
||||
return true;
|
||||
}
|
||||
catch (std::out_of_range const& ex)
|
||||
{
|
||||
fail_msg_writer() << tr("out of range for slippage limit: ") << ex.what();
|
||||
PRINT_USAGE(USAGE_CONVERT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the destination asset type
|
||||
std::string source_asset, dest_asset;
|
||||
std::string strLastArg = local_args.back();
|
||||
std::transform(strLastArg.begin(), strLastArg.end(), strLastArg.begin(), ::toupper);
|
||||
if (strLastArg not_eq "FULM" and strLastArg not_eq "FUSD") {
|
||||
fail_msg_writer() << tr("invalid destination asset_type");
|
||||
@@ -7984,6 +8183,11 @@ bool simple_wallet::convert(const std::vector<std::string> &args_)
|
||||
PRINT_USAGE(USAGE_CONVERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for slippage_limit again
|
||||
if (slippage_limit != 0.0) {
|
||||
local_args.push_back(std::to_string(slippage_limit));
|
||||
}
|
||||
|
||||
transfer_main(Convert, source_asset, dest_asset, local_args, false);
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user