aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/simplewallet/simplewallet.cpp28
-rw-r--r--src/simplewallet/simplewallet.h2
-rw-r--r--src/wallet/wallet2.cpp33
-rw-r--r--src/wallet/wallet2.h21
4 files changed, 74 insertions, 10 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 45ccaa692..47e6fd45b 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -1777,7 +1777,7 @@ bool simple_wallet::show_incoming_transfers(const std::vector<std::string>& args
}
std::string verbose_string;
if (verbose)
- verbose_string = (boost::format("%68s%68s") % td.get_public_key() % td.m_key_image).str();
+ verbose_string = (boost::format("%68s%68s") % td.get_public_key() % (td.m_key_image_known ? epee::string_tools::pod_to_hex(td.m_key_image) : std::string('?', 64))).str();
message_writer(td.m_spent ? epee::log_space::console_color_magenta : epee::log_space::console_color_green, false) <<
boost::format("%21s%8s%12s%8s%16u%68s%s") %
print_money(td.amount()) %
@@ -2774,7 +2774,7 @@ bool simple_wallet::sweep_all(const std::vector<std::string> &args_)
return true;
}
//----------------------------------------------------------------------------------------------------
-bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx)
+bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message)
{
// gather info to ask the user
uint64_t amount = 0, amount_to_dests = 0, change = 0;
@@ -2847,19 +2847,25 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes,
change_string += tr("no change");
uint64_t fee = amount - amount_to_dests;
- std::string prompt_str = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. Is this okay? (Y/Yes/N/No)")) % (unsigned long)get_num_txes() % print_money(amount) % print_money(fee) % dest_string % change_string % (unsigned long)min_mixin).str();
+ std::string prompt_str = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. %sIs this okay? (Y/Yes/N/No)")) % (unsigned long)get_num_txes() % print_money(amount) % print_money(fee) % dest_string % change_string % (unsigned long)min_mixin % extra_message).str();
std::string accepted = command_line::input_line(prompt_str);
return is_it_true(accepted);
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs)
{
- return accept_loaded_tx([&txs](){return txs.txes.size();}, [&txs](size_t n)->const tools::wallet2::tx_construction_data&{return txs.txes[n];});
+ std::string extra_message;
+ if (!txs.transfers.empty())
+ extra_message = (boost::format("%u outputs to import. ") % (unsigned)txs.transfers.size()).str();
+ return accept_loaded_tx([&txs](){return txs.txes.size();}, [&txs](size_t n)->const tools::wallet2::tx_construction_data&{return txs.txes[n];}, extra_message);
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::accept_loaded_tx(const tools::wallet2::signed_tx_set &txs)
{
- return accept_loaded_tx([&txs](){return txs.ptx.size();}, [&txs](size_t n)->const tools::wallet2::tx_construction_data&{return txs.ptx[n].construction_data;});
+ std::string extra_message;
+ if (!txs.key_images.empty())
+ extra_message = (boost::format("%u key images to import. ") % (unsigned)txs.key_images.size()).str();
+ return accept_loaded_tx([&txs](){return txs.ptx.size();}, [&txs](size_t n)->const tools::wallet2::tx_construction_data&{return txs.ptx[n].construction_data;}, extra_message);
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::sign_transfer(const std::vector<std::string> &args_)
@@ -2870,9 +2876,10 @@ bool simple_wallet::sign_transfer(const std::vector<std::string> &args_)
return true;
}
+ std::vector<tools::wallet2::pending_tx> ptx;
try
{
- bool r = m_wallet->sign_tx("unsigned_monero_tx", "signed_monero_tx", [&](const tools::wallet2::unsigned_tx_set &tx){ return accept_loaded_tx(tx); });
+ bool r = m_wallet->sign_tx("unsigned_monero_tx", "signed_monero_tx", ptx, [&](const tools::wallet2::unsigned_tx_set &tx){ return accept_loaded_tx(tx); });
if (!r)
{
fail_msg_writer() << tr("Failed to sign transaction");
@@ -2885,7 +2892,14 @@ bool simple_wallet::sign_transfer(const std::vector<std::string> &args_)
return true;
}
- success_msg_writer(true) << tr("Transaction successfully signed to file: ") << "signed_monero_tx";
+ std::string txids_as_text;
+ for (const auto &t: ptx)
+ {
+ if (!txids_as_text.empty())
+ txids_as_text += (", ");
+ txids_as_text += epee::string_tools::pod_to_hex(get_transaction_hash(t.tx));
+ }
+ success_msg_writer(true) << tr("Transaction successfully signed to file ") << "signed_monero_tx" << ", txid " << txids_as_text;
return true;
}
//----------------------------------------------------------------------------------------------------
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index 4fe1b0417..0d83f429b 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -155,7 +155,7 @@ namespace cryptonote
uint64_t get_daemon_blockchain_height(std::string& err);
bool try_connect_to_daemon(bool silent = false);
bool ask_wallet_create_if_needed();
- bool accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx);
+ bool accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message = std::string());
bool accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs);
bool accept_loaded_tx(const tools::wallet2::signed_tx_set &txs);
bool get_address_from_str(const std::string &str, cryptonote::account_public_address &address, bool &has_payment_id, crypto::hash8 &payment_id);
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index bf7c1537a..093e5c2aa 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -2953,6 +2953,7 @@ bool wallet2::save_tx(const std::vector<pending_tx>& ptx_vector, const std::stri
unsigned_tx_set txs;
for (auto &tx: ptx_vector)
txs.txes.push_back(tx.construction_data);
+ txs.transfers = m_transfers;
std::string s = obj_to_json_str(txs);
if (s.empty())
return false;
@@ -2963,7 +2964,7 @@ bool wallet2::save_tx(const std::vector<pending_tx>& ptx_vector, const std::stri
return epee::file_io_utils::save_string_to_file(filename, std::string(UNSIGNED_TX_PREFIX) + s);
}
//----------------------------------------------------------------------------------------------------
-bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::function<bool(const unsigned_tx_set&)> accept_func)
+bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::vector<wallet2::pending_tx> &txs, std::function<bool(const unsigned_tx_set&)> accept_func)
{
std::string s;
boost::system::error_code errcode;
@@ -2998,6 +2999,8 @@ bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &s
return false;
}
+ import_outputs(exported_txs.transfers);
+
// sign the transactions
signed_tx_set signed_txes;
for (size_t n = 0; n < exported_txs.txes.size(); ++n)
@@ -3043,6 +3046,17 @@ bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &s
ptx.tx_key = rct::rct2sk(rct::identity()); // don't send it back to the untrusted view wallet
ptx.dests = sd.splitted_dsts;
ptx.construction_data = sd;
+
+ txs.push_back(ptx);
+ }
+
+ // add key images
+ signed_txes.key_images.resize(m_transfers.size());
+ for (size_t i = 0; i < m_transfers.size(); ++i)
+ {
+ if (!m_transfers[i].m_key_image_known)
+ LOG_PRINT_L0("WARNING: key image not known in signing wallet at index " << i);
+ signed_txes.key_images[i] = m_transfers[i].m_key_image;
}
s = obj_to_json_str(signed_txes);
@@ -3092,6 +3106,23 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wal
return false;
}
+ // import key images
+ if (signed_txs.key_images.size() > m_transfers.size())
+ {
+ LOG_PRINT_L1("More key images returned that we know outputs for");
+ return false;
+ }
+ for (size_t i = 0; i < signed_txs.key_images.size(); ++i)
+ {
+ transfer_details &td = m_transfers[i];
+ if (td.m_key_image_known && td.m_key_image != signed_txs.key_images[i])
+ LOG_PRINT_L0("WARNING: imported key image differs from previously known key image at index " << i << ": trusting imported one");
+ td.m_key_image = signed_txs.key_images[i];
+ m_key_images[m_transfers[i].m_key_image] = i;
+ td.m_key_image_known = true;
+ m_pub_keys[m_transfers[i].get_public_key()] = i;
+ }
+
ptx = signed_txs.ptx;
return true;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 417e754a5..d0075e2ec 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -133,6 +133,21 @@ namespace tools
bool is_rct() const { return m_rct; }
uint64_t amount() const { return m_amount; }
const crypto::public_key &get_public_key() const { return boost::get<const cryptonote::txout_to_key>(m_tx.vout[m_internal_output_index].target).key; }
+
+ BEGIN_SERIALIZE_OBJECT()
+ FIELD(m_block_height)
+ FIELD(m_tx)
+ FIELD(m_txid)
+ FIELD(m_internal_output_index)
+ FIELD(m_global_output_index)
+ FIELD(m_spent)
+ FIELD(m_spent_height)
+ FIELD(m_key_image)
+ FIELD(m_mask)
+ FIELD(m_amount)
+ FIELD(m_rct)
+ FIELD(m_key_image_known)
+ END_SERIALIZE()
};
struct payment_details
@@ -226,16 +241,20 @@ namespace tools
struct unsigned_tx_set
{
std::vector<tx_construction_data> txes;
+ wallet2::transfer_container transfers;
BEGIN_SERIALIZE_OBJECT()
FIELD(txes)
+ FIELD(transfers)
END_SERIALIZE()
};
struct signed_tx_set
{
std::vector<pending_tx> ptx;
+ std::vector<crypto::key_image> key_images;
BEGIN_SERIALIZE_OBJECT()
FIELD(ptx)
+ FIELD(key_images)
END_SERIALIZE()
};
@@ -377,7 +396,7 @@ namespace tools
void commit_tx(pending_tx& ptx_vector);
void commit_tx(std::vector<pending_tx>& ptx_vector);
bool save_tx(const std::vector<pending_tx>& ptx_vector, const std::string &filename);
- bool sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::function<bool(const unsigned_tx_set&)> accept_func = NULL);
+ bool sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::vector<wallet2::pending_tx> &ptx, std::function<bool(const unsigned_tx_set&)> accept_func = NULL);
bool load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
std::vector<pending_tx> create_transactions(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon);
std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon);