aboutsummaryrefslogtreecommitdiff
path: root/src/simplewallet/simplewallet.cpp
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2016-08-28 22:41:11 +0200
committerRiccardo Spagni <ric@spagni.net>2016-08-28 22:41:12 +0200
commit8a5b766d17761f5fbdd3e30e638daa98a40a4c8a (patch)
treeea05e3f0fd47fd1d8728e64d081292d337825cb9 /src/simplewallet/simplewallet.cpp
parenta569b264bc4d4ca1a07c2eadcc24b5ab75fd0c84 (diff)
parent887db9f93670da8c1eb28c9d53d6d4f055486e3b (diff)
downloadmonzero-core-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.tar.gz
monzero-core-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.tar.xz
monzero-core-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.zip
Merge pull request #961
887db9f blockchain: testnet heights for v3, v4, and v5 (moneromooo-monero) f24ab58 ringct: remove unused code (moneromooo-monero) b38452b ringct: pass structure by const ref, not value (moneromooo-monero) fd11271 ringct: use memcpy/memset instead of handwritten loop where appropriate (moneromooo-monero) 5d38206 ringct: remove spurious copies (moneromooo-monero) 16732a8 rct: faster Cryptonote/rct conversions (moneromooo-monero) fbd7c35 wallet: fix some "may be used uninitialized" warnings (moneromooo-monero) 4a41dd4 wallet: do not generate 0 change (moneromooo-monero) a0925e6 core: use full rct signatures if just one input (moneromooo-monero) 94fd881 rct: early out on failure on verRange (moneromooo-monero) 45349b6 wallet: do not ask for duplicate histograms (moneromooo-monero) b951bc8 wallet: transfer_selected_rct now also selects fake outs (moneromooo-monero) 4f887de increase minimum mixin to 4 on hard fork 5 (moneromooo-monero) 0815c72 core: allow v1 txes after HF 5 when sweeping unmixable outputs (moneromooo-monero) f782d45 tests: hard fork list must end with a 0 (moneromooo-monero) 074e602 ringct: use Cryptonote serialization to hash non prunable data (moneromooo-monero) c3b3260 New "Halfway RingCT" outputs for coinbase transactions (moneromooo-monero) 6f526cd rct: log why verification fails (moneromooo-monero) d4b8991 rct: serialize txnFee as varint (moneromooo-monero) d4b62a1 rct amount key modified as per luigi1111's recommendations (moneromooo-monero) 93f5c62 rct: rework v2 txes into prunable and non prunable data (moneromooo-monero) d93746b rct: rework the verification preparation process (moneromooo-monero) 3ab2ab3 rct: change the simple flag to a type (moneromooo-monero) c5be4b0 rct: avoid the need for the last II element (Shen Noether) a47ceee wallet: do not store signatures in the wallet cache (moneromooo-monero) 0263dd2 core: add some locking around pool use (moneromooo-monero) 2c9d951 wallet2: factor m_spent changes (moneromooo-monero) 1303cda wallet: always use new algorithm for RPC transfers (moneromooo-monero) b337aea rct: do not serialize senderPk - it is not used anymore (moneromooo-monero) e5a9a47 core_tests: fix a couple pre-rct tests using rct (moneromooo-monero) 230fca2 wallet: use the prefered rct case only when enough rct outs exist (moneromooo-monero) c27194a wallet: do not try to use rct txes a few blocks before the fork (moneromooo-monero) 1bf0698 tx_pool: log why a transaction was rejected for version checks (moneromooo-monero) 37bdf6e change fork settings to allow pre-rct txes for one more fork cycle (moneromooo-monero) cc85cc6 simplewallet: better check_tx_key feedback (moneromooo-monero) 9b70856 rct: make the amount key derivable by a third party with the tx key (moneromooo-monero) cf33e1a rct: do not serialize public keys in outPk (moneromooo-monero) 83ab315 wallet2_api: zero amounts are now allowed with rct (moneromooo-monero) 096ac06 wallet2_api: update on_money_{received,spent} prototypes for rct changes (moneromooo-monero) 3cb2ede rpc: send global indices along with blocks/transacions on refresh (moneromooo-monero) 414b424 core: always use the new simple rct variant (moneromooo-monero) ce5de8b tests: add tests for wallet output selection (moneromooo-monero) 84c82cd wallet: better tx input selection (moneromooo-monero) 1e21651 rct: use the already defined H where possible (moneromooo-monero) 07d353d wallet: handle 0 change properly (moneromooo-monero) e81a2b2 port get_tx_key/check_tx_key to rct (moneromooo-monero) e06faef tests: add basic tests for simple rct api (moneromooo-monero) a4d4d61 integrate simple rct api (moneromooo-monero) 1e8d37e serialization: add override for serializing bool (moneromooo-monero) dbb5f2d ringct: optimization/cleanup of hash functions (Shen Noether) 4fd01f2 ringct: "simple" ringct variant (Shen Noether) 37c895e wallet: rct specific output selection (moneromooo-monero) 1181c57 wallet: make sweep_all work with rct txes too (moneromooo-monero) c2ec6d3 mixable transactions must be rct for v3 (moneromooo-monero) 1017a75 wallet: factor transfer_rct code with transfer code (moneromooo-monero) f5465d8 Condition v2 txes on v3 hard fork (moneromooo-monero) 59a66e2 move the rct commitments to the output_amounts database (moneromooo-monero) 6d0e471 rct: add the tx prefix hash into the MLSAG (moneromooo-monero) 35dce5c ringct: fix size unit mismatch calling keccak (moneromooo-monero) 20e50ec ringct: do not serialize what can be reconstructed (moneromooo-monero) 106e3dc Add rct core tests (moneromooo-monero) ada5275 Use the supplied hard fork version in validate_miner_transaction (moneromooo-monero) acbe06d wallet: update spent status when an accepted tx disappears (moneromooo-monero) 089df4a wallet: reset output spent status on blockchain reorg (moneromooo-monero) 73d59f1 ringct: catch errors from ge_frombytes_vartime (moneromooo-monero) 161551e tests: test for ringct rctSig data sizes (moneromooo-monero) 359f469 ringct: add missing size check for ecdhInfo (moneromooo-monero) 229968e ringct: change asserts to return false for boolean functions (moneromooo-monero) dc4aad7 add rct to the protocol (moneromooo-monero) 211d1db db_lmdb: update reset for recent db changes (moneromooo-monero) dee42d6 ringct: add functions to commit to an amount (moneromooo-monero) cc7f449 make rct tx serialization work (moneromooo-monero) e70e8a6 crypto: error out where appropriate (moneromooo-monero) 54f7429 ringct: allow no outputs, and add tests for this and fees (moneromooo-monero) e99904a ringct: make fee optional (moneromooo-monero) f8c04ad ringct: txn fee stuff (Shen Noether) 66f9626 ringct: new {gen,decode}Rct APIs for convenience (moneromooo-monero) 789b2e2 ringct: add more convenience functions (moneromooo-monero) 9856443 core: link against libringct (moneromooo-monero) 4258dab core: new /getrandom_rctouts.bin binary RPC call (moneromooo-monero) c3a2e14 ringct: add convenience functions to bridge ringct and cryptonote (moneromooo-monero) eb56d0f blockchain_db: add functions for adding/removing/getting rct commitments (moneromooo-monero) 82072e7 ringct: restore verRange check in debug mode (moneromooo-monero) 63856ca ringct: add check for destinations/amount size being equal (moneromooo-monero) e816a09 ringct: fix off by 1 in mixin usage (moneromooo-monero) 09c5ea4 ringct: simplify random key generation (moneromooo-monero) 53cdf4d tests: new ringct test for checking H2 values (Shen Noether) 56f6549 ringct: cosmetic fixes (Shen Noether) 55ff136 ringct: changes to hashToPointSimple to calcualte H2 values (Shen Noether) 63733b1 ringct: compare keys with bitwise equality, not crypto ops (Shen Noether) 98f4c6f ringct: fix size argument to cn_fast_hash (Shen Noether) 720ac85 tests: zero inputs/outputs are in fact supposed to be accepted (moneromooo-monero) 84948ea ringct: add a test for prooveRange being non deterministic (moneromooo-monero) 09fb9f4 Fix sc_0 to skGen in ProveRange (Shen Noether) d37c1db ringct: add a few consts where appropriate (moneromooo-monero) 700248f tests: more ringct range proof tests (moneromooo-monero) d02f999 rct: add serialization machinery to rct types (moneromooo-monero) 0ff8305 serialization: declare do_serialize specializations before use (moneromooo-monero) 8b135e7 Added note on generating H2 (Shen Noether) 4d639d9 Fixed missing last index H2 (Shen Noether) 9e82b69 remove original Cryptonote blockchain_storage blockchain format (moneromooo-monero) 86b4426 ringct: lock access to the PRNG (moneromooo-monero) 4d7f073 ringct: add simple input validation (moneromooo-monero) 57779ab tests: add some more ringct building block tests (moneromooo-monero) b656001 ringct: add convenience operators to key (moneromooo-monero) 2d6303f tests: add Shen Noether's basic ringct tests (moneromooo-monero) 9b1afe5 ringct: import of Shen Noether's ring confidential transactions (moneromooo-monero)
Diffstat (limited to 'src/simplewallet/simplewallet.cpp')
-rw-r--r--src/simplewallet/simplewallet.cpp151
1 files changed, 112 insertions, 39 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 1840e54c9..44b5b0c70 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -58,6 +58,7 @@
#include "mnemonics/electrum-words.h"
#include "rapidjson/document.h"
#include "common/json_util.h"
+#include "ringct/rctSigs.h"
#include <stdexcept>
#if defined(WIN32)
@@ -99,6 +100,11 @@ typedef cryptonote::simple_wallet sw;
m_auto_refresh_enabled.store(auto_refresh_enabled, std::memory_order_relaxed); \
})
+enum TransferType {
+ TransferOriginal,
+ TransferNew,
+};
+
namespace
{
const command_line::arg_descriptor<std::string> arg_wallet_file = {"wallet-file", sw::tr("Use wallet <arg>"), ""};
@@ -642,8 +648,8 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("incoming_transfers", boost::bind(&simple_wallet::show_incoming_transfers, this, _1), tr("incoming_transfers [available|unavailable] - Show incoming transfers, all or filtered by availability"));
m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, _1), tr("payments <PID_1> [<PID_2> ... <PID_N>] - Show payments for given payment ID[s]"));
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", 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_new", boost::bind(&simple_wallet::transfer_new, this, _1), tr("Same as transfer, but using a new transaction building algorithm"));
+ 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("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>"));
@@ -973,22 +979,22 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
return false;
}
- GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true);
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true, 0);
const int current_version = 1;
if (field_version > current_version) {
fail_msg_writer() << boost::format(tr("Version %u too new, we can only grok up to %u")) % field_version % current_version;
return false;
}
- GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true);
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true, std::string());
- GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, scan_from_height, uint64_t, Uint64, false);
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, scan_from_height, uint64_t, Uint64, false, 0);
bool recover = field_scan_from_height_found;
- GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, password, std::string, String, false);
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, password, std::string, String, false, std::string());
password = field_password;
- GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, viewkey, std::string, String, false);
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, viewkey, std::string, String, false, std::string());
crypto::secret_key viewkey;
if (field_viewkey_found)
{
@@ -1006,7 +1012,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
}
}
- GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, spendkey, std::string, String, false);
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, spendkey, std::string, String, false, std::string());
crypto::secret_key spendkey;
if (field_spendkey_found)
{
@@ -1024,7 +1030,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
}
}
- GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed, std::string, String, false);
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed, std::string, String, false, std::string());
std::string old_language;
if (field_seed_found)
{
@@ -1037,7 +1043,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
m_restore_deterministic_wallet = true;
}
- GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, address, std::string, String, false);
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, address, std::string, String, false, std::string());
// compatibility checks
if (!field_seed_found && !field_viewkey_found)
@@ -1888,24 +1894,24 @@ void simple_wallet::on_new_block(uint64_t height, const cryptonote::block& block
m_refresh_progress_reporter.update(height, false);
}
//----------------------------------------------------------------------------------------------------
-void simple_wallet::on_money_received(uint64_t height, const cryptonote::transaction& tx, size_t out_index)
+void simple_wallet::on_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount)
{
message_writer(epee::log_space::console_color_green, false) << "\r" <<
tr("Height ") << height << ", " <<
tr("transaction ") << get_transaction_hash(tx) << ", " <<
- tr("received ") << print_money(tx.vout[out_index].amount);
+ tr("received ") << print_money(amount);
if (m_auto_refresh_refreshing)
m_cmd_binder.print_prompt();
else
m_refresh_progress_reporter.update(height, true);
}
//----------------------------------------------------------------------------------------------------
-void simple_wallet::on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, size_t out_index, const cryptonote::transaction& spend_tx)
+void simple_wallet::on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, uint64_t amount, const cryptonote::transaction& spend_tx)
{
message_writer(epee::log_space::console_color_magenta, false) << "\r" <<
tr("Height ") << height << ", " <<
tr("transaction ") << get_transaction_hash(spend_tx) << ", " <<
- tr("spent ") << print_money(in_tx.vout[out_index].amount);
+ tr("spent ") << print_money(amount);
if (m_auto_refresh_refreshing)
m_cmd_binder.print_prompt();
else
@@ -2052,15 +2058,17 @@ bool simple_wallet::show_incoming_transfers(const std::vector<std::string>& args
{
if (!transfers_found)
{
- message_writer() << boost::format("%21s%8s%16s%68s") % tr("amount") % tr("spent") % tr("global index") % tr("tx id");
+ message_writer() << boost::format("%21s%8s%12s%8s%16s%68s") % tr("amount") % tr("spent") % tr("unlocked") % tr("ringct") % tr("global index") % tr("tx id");
transfers_found = true;
}
message_writer(td.m_spent ? epee::log_space::console_color_magenta : epee::log_space::console_color_green, false) <<
- boost::format("%21s%8s%16u%68s") %
+ boost::format("%21s%8s%12s%8s%16u%68s") %
print_money(td.amount()) %
(td.m_spent ? tr("T") : tr("F")) %
+ (m_wallet->is_transfer_unlocked(td) ? tr("unlocked") : tr("locked")) %
+ (td.is_rct() ? tr("RingCT") : tr("-")) %
td.m_global_output_index %
- get_transaction_hash (td.m_tx);
+ td.m_txid;
}
}
@@ -2274,7 +2282,7 @@ bool simple_wallet::get_address_from_str(const std::string &str, cryptonote::acc
return true;
}
//----------------------------------------------------------------------------------------------------
-bool simple_wallet::transfer_main(bool new_algorithm, const std::vector<std::string> &args_)
+bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::string> &args_)
{
if (!try_connect_to_daemon())
return true;
@@ -2386,10 +2394,17 @@ bool simple_wallet::transfer_main(bool new_algorithm, const std::vector<std::str
{
// figure out what tx will be necessary
std::vector<tools::wallet2::pending_tx> ptx_vector;
- if (new_algorithm)
- ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon);
- else
- ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon);
+ switch (transfer_type)
+ {
+ case TransferNew:
+ ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon);
+ break;
+ default:
+ LOG_ERROR("Unknown transfer method, using original");
+ case TransferOriginal:
+ ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon);
+ break;
+ }
// if more than one tx necessary, prompt user to confirm
if (m_wallet->always_confirm_transfers() || ptx_vector.size() > 1)
@@ -2531,14 +2546,13 @@ bool simple_wallet::transfer_main(bool new_algorithm, const std::vector<std::str
//----------------------------------------------------------------------------------------------------
bool simple_wallet::transfer(const std::vector<std::string> &args_)
{
- return transfer_main(false, args_);
+ return transfer_main(TransferOriginal, args_);
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::transfer_new(const std::vector<std::string> &args_)
{
- return transfer_main(true, args_);
+ return transfer_main(TransferNew, args_);
}
-
//----------------------------------------------------------------------------------------------------
bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
{
@@ -2944,15 +2958,15 @@ bool simple_wallet::get_tx_key(const std::vector<std::string> &args_)
LOCK_IDLE_SCOPE();
crypto::secret_key tx_key;
- bool r = m_wallet->get_tx_key(txid, tx_key);
- if (r)
+ std::vector<crypto::secret_key> amount_keys;
+ if (m_wallet->get_tx_key(txid, tx_key))
{
- success_msg_writer() << tr("Tx key: ") << tx_key;
+ success_msg_writer() << tr("Tx key: ") << epee::string_tools::pod_to_hex(tx_key);
return true;
}
else
{
- fail_msg_writer() << tr("no tx key found for this txid");
+ fail_msg_writer() << tr("no tx keys found for this txid");
return true;
}
}
@@ -2979,13 +2993,19 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_)
LOCK_IDLE_SCOPE();
+ if (local_args[1].size() < 64 || local_args[1].size() % 64)
+ {
+ fail_msg_writer() << tr("failed to parse tx key");
+ return true;
+ }
+ crypto::secret_key tx_key;
cryptonote::blobdata tx_key_data;
if(!epee::string_tools::parse_hexstr_to_binbuff(local_args[1], tx_key_data))
{
fail_msg_writer() << tr("failed to parse tx key");
return true;
}
- crypto::secret_key tx_key = *reinterpret_cast<const crypto::secret_key*>(tx_key_data.data());
+ tx_key = *reinterpret_cast<const crypto::secret_key*>(tx_key_data.data());
cryptonote::account_public_address address;
bool has_payment_id;
@@ -3000,14 +3020,14 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_)
COMMAND_RPC_GET_TRANSACTIONS::response res;
req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid));
if (!net_utils::invoke_http_json_remote_command2(m_daemon_address + "/gettransactions", req, res, m_http_client) ||
- (res.txs.empty() && res.txs_as_hex.empty()))
+ (res.txs.size() != 1 && res.txs_as_hex.size() != 1))
{
fail_msg_writer() << tr("failed to get transaction from daemon");
return true;
}
cryptonote::blobdata tx_data;
bool ok;
- if (!res.txs.empty())
+ if (res.txs.size() == 1)
ok = string_tools::parse_hexstr_to_binbuff(res.txs.front().as_hex, tx_data);
else
ok = string_tools::parse_hexstr_to_binbuff(res.txs_as_hex.front(), tx_data);
@@ -3046,13 +3066,49 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_)
crypto::public_key pubkey;
derive_public_key(derivation, n, address.m_spend_public_key, pubkey);
if (pubkey == tx_out_to_key.key)
- received += tx.vout[n].amount;
+ {
+ uint64_t amount;
+ if (tx.version == 1)
+ {
+ amount = tx.vout[n].amount;
+ }
+ else
+ {
+ try
+ {
+ rct::key Ctmp;
+ //rct::key amount_key = rct::hash_to_scalar(rct::scalarmultKey(rct::pk2rct(address.m_view_public_key), rct::sk2rct(tx_key)));
+ crypto::key_derivation derivation;
+ bool r = crypto::generate_key_derivation(address.m_view_public_key, tx_key, derivation);
+ if (!r)
+ {
+ LOG_ERROR("Failed to generate key derivation to decode rct output " << n);
+ amount = 0;
+ }
+ else
+ {
+ crypto::secret_key scalar1;
+ crypto::derivation_to_scalar(derivation, n, scalar1);
+ rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
+ rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1));
+ rct::key C = tx.rct_signatures.outPk[n].mask;
+ rct::addKeys2(Ctmp, ecdh_info.mask, ecdh_info.amount, rct::H);
+ if (rct::equalKeys(C, Ctmp))
+ amount = rct::h2d(ecdh_info.amount);
+ else
+ amount = 0;
+ }
+ }
+ catch (...) { amount = 0; }
+ }
+ received += amount;
+ }
}
}
- catch(...)
+ catch(const std::exception &e)
{
- LOG_ERROR("unknown error");
- fail_msg_writer() << tr("unknown error");
+ LOG_ERROR("error: " << e.what());
+ fail_msg_writer() << tr("error: ") << e.what();
return true;
}
@@ -3064,6 +3120,24 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_)
{
fail_msg_writer() << get_account_address_as_str(m_wallet->testnet(), address) << " " << tr("received nothing in txid") << " " << txid;
}
+ if (res.txs.front().in_pool)
+ {
+ success_msg_writer() << tr("WARNING: this transaction is not yet included in the blockchain!");
+ }
+ else
+ {
+ std::string err;
+ uint64_t bc_height = get_daemon_blockchain_height(err);
+ if (err.empty())
+ {
+ uint64_t confirmations = bc_height - (res.txs.front().block_height + 1);
+ success_msg_writer() << boost::format(tr("This transaction has %u confirmations")) % confirmations;
+ }
+ else
+ {
+ success_msg_writer() << tr("WARNING: failed to determine number of confirmations!");
+ }
+ }
return true;
}
@@ -3228,9 +3302,8 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
m_wallet->get_unconfirmed_payments_out(upayments);
for (std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>>::const_iterator i = upayments.begin(); i != upayments.end(); ++i) {
const tools::wallet2::unconfirmed_transfer_details &pd = i->second;
- uint64_t amount = 0;
- cryptonote::get_inputs_money_amount(pd.m_tx, amount);
- uint64_t fee = amount - get_outs_money_amount(pd.m_tx);
+ uint64_t amount = pd.m_amount_in;
+ uint64_t fee = amount - pd.m_amount_out;
std::string payment_id = string_tools::pod_to_hex(i->second.m_payment_id);
if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
payment_id = payment_id.substr(0,16);