aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r--src/wallet/wallet2.cpp119
1 files changed, 92 insertions, 27 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 9bd487997..e8d67eec2 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -22,6 +22,23 @@ using namespace epee;
using namespace cryptonote;
+namespace
+{
+void do_prepare_file_names(const std::string& file_path, std::string& keys_file, std::string& wallet_file)
+{
+ keys_file = file_path;
+ wallet_file = file_path;
+ boost::system::error_code e;
+ if(string_tools::get_extension(keys_file) == "keys")
+ {//provided keys file name
+ wallet_file = string_tools::cut_off_extension(wallet_file);
+ }else
+ {//provided wallet file name
+ keys_file += ".keys";
+ }
+}
+} //namespace
+
namespace tools
{
//----------------------------------------------------------------------------------------------------
@@ -36,17 +53,25 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
process_unconfirmed(tx);
std::vector<size_t> outs;
uint64_t tx_money_got_in_outs = 0;
- crypto::public_key tx_pub_key = null_pkey;
- bool r = parse_and_validate_tx_extra(tx, tx_pub_key);
-
- // Temporarily disabled due to messed up tx_extra from someone
- // screwing around with MMing. 2014-04-30
- // THROW_WALLET_EXCEPTION_IF(!r, error::tx_extra_parse_error, tx);
-
- // We don't know how to handle this weird tx, so return
- if (!r) return;
-
- r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs);
+
+ std::vector<tx_extra_field> tx_extra_fields;
+ if(!parse_tx_extra(tx.extra, tx_extra_fields))
+ {
+ // Extra may only be partially parsed, it's OK if tx_extra_fields contains public key
+ LOG_PRINT_L0("Transaction extra has unsupported format: " << get_transaction_hash(tx));
+ }
+
+ tx_extra_pub_key pub_key_field;
+ if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field))
+ {
+ LOG_PRINT_L0("Public key wasn't found in the transaction extra. Skipping transaction " << get_transaction_hash(tx));
+ if(0 != m_callback)
+ m_callback->on_skip_transaction(height, tx);
+ return;
+ }
+
+ crypto::public_key tx_pub_key = pub_key_field.pub_key;
+ bool r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs);
THROW_WALLET_EXCEPTION_IF(!r, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
if(!outs.empty() && tx_money_got_in_outs)
@@ -87,6 +112,8 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index);
}
}
+
+ uint64_t tx_money_spent_in_ins = 0;
// check all outputs for spending (compare key images)
BOOST_FOREACH(auto& in, tx.vin)
{
@@ -96,12 +123,33 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
if(it != m_key_images.end())
{
LOG_PRINT_L0("Spent money: " << print_money(boost::get<cryptonote::txin_to_key>(in).amount) << ", with tx: " << get_transaction_hash(tx));
+ tx_money_spent_in_ins += boost::get<cryptonote::txin_to_key>(in).amount;
transfer_details& td = m_transfers[it->second];
td.m_spent = true;
if (0 != m_callback)
m_callback->on_money_spent(height, td.m_tx, td.m_internal_output_index, tx);
}
}
+
+ tx_extra_nonce extra_nonce;
+ if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
+ {
+ crypto::hash payment_id;
+ if(get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id))
+ {
+ uint64_t received = (tx_money_spent_in_ins < tx_money_got_in_outs) ? tx_money_got_in_outs - tx_money_spent_in_ins : 0;
+ if (0 < received && null_hash != payment_id)
+ {
+ payment_details payment;
+ payment.m_tx_hash = cryptonote::get_transaction_hash(tx);
+ payment.m_amount = received;
+ payment.m_block_height = height;
+ payment.m_unlock_time = tx.unlock_time;
+ m_payments.emplace(payment_id, payment);
+ LOG_PRINT_L2("Payment found: " << payment_id << " / " << payment.m_tx_hash << " / " << payment.m_amount);
+ }
+ }
+ }
}
//----------------------------------------------------------------------------------------------------
void wallet2::process_unconfirmed(const cryptonote::transaction& tx)
@@ -203,7 +251,7 @@ void wallet2::pull_blocks(size_t& blocks_added)
{
//split detected here !!!
THROW_WALLET_EXCEPTION_IF(current_index == res.start_height, error::wallet_internal_error,
- "wrong daemon response: split starts from the first block in response " + string_tools::pod_to_hex(bl_id) +
+ "wrong daemon response: split starts from the first block in response " + string_tools::pod_to_hex(bl_id) +
" (height " + std::to_string(res.start_height) + "), local block id at this height: " +
string_tools::pod_to_hex(m_blockchain[current_index]));
@@ -304,6 +352,14 @@ void wallet2::detach_blockchain(uint64_t height)
m_blockchain.erase(m_blockchain.begin()+height, m_blockchain.end());
m_local_bc_height -= blocks_detached;
+ for (auto it = m_payments.begin(); it != m_payments.end(); )
+ {
+ if(height <= it->second.m_block_height)
+ it = m_payments.erase(it);
+ else
+ ++it;
+ }
+
LOG_PRINT_L0("Detached blockchain on height " << height << ", transfers detached " << transfers_detached << ", blocks detached " << blocks_detached);
}
//----------------------------------------------------------------------------------------------------
@@ -399,18 +455,19 @@ void wallet2::generate(const std::string& wallet_, const std::string& password)
store();
}
//----------------------------------------------------------------------------------------------------
+void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exitst)
+{
+ std::string keys_file, wallet_file;
+ do_prepare_file_names(file_path, keys_file, wallet_file);
+
+ boost::system::error_code ignore;
+ keys_file_exists = boost::filesystem::exists(keys_file, ignore);
+ wallet_file_exitst = boost::filesystem::exists(wallet_file, ignore);
+}
+//----------------------------------------------------------------------------------------------------
bool wallet2::prepare_file_names(const std::string& file_path)
{
- m_keys_file = file_path;
- m_wallet_file = file_path;
- boost::system::error_code e;
- if(string_tools::get_extension(m_keys_file) == "keys")
- {//provided keys file name
- m_wallet_file = string_tools::cut_off_extension(m_wallet_file);
- }else
- {//provided wallet file name
- m_keys_file += ".keys";
- }
+ do_prepare_file_names(file_path, m_keys_file, m_wallet_file);
return true;
}
//----------------------------------------------------------------------------------------------------
@@ -422,7 +479,7 @@ bool wallet2::check_connection()
net_utils::http::url_content u;
net_utils::parse_url(m_daemon_address, u);
if(!u.port)
- u.port = RPC_DEFAULT_PORT;
+ u.port = RPC_DEFAULT_PORT;
return m_http_client.connect(u.host, std::to_string(u.port), WALLET_RCP_CONNECTION_TIMEOUT);
}
//----------------------------------------------------------------------------------------------------
@@ -497,6 +554,14 @@ void wallet2::get_transfers(wallet2::transfer_container& incoming_transfers) con
incoming_transfers = m_transfers;
}
//----------------------------------------------------------------------------------------------------
+void wallet2::get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments) const
+{
+ auto range = m_payments.equal_range(payment_id);
+ std::for_each(range.first, range.second, [&payments](const payment_container::value_type& x) {
+ payments.push_back(x.second);
+ });
+}
+//----------------------------------------------------------------------------------------------------
bool wallet2::is_transfer_unlocked(const transfer_details& td) const
{
if(!is_tx_spendtime_unlocked(td.m_tx.unlock_time))
@@ -596,16 +661,16 @@ void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t cha
}
//----------------------------------------------------------------------------------------------------
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count,
- uint64_t unlock_time, uint64_t fee, cryptonote::transaction& tx)
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx)
{
- transfer(dsts, fake_outputs_count, unlock_time, fee, detail::digit_split_strategy, tx_dust_policy(fee), tx);
+ transfer(dsts, fake_outputs_count, unlock_time, fee, extra, detail::digit_split_strategy, tx_dust_policy(fee), tx);
}
//----------------------------------------------------------------------------------------------------
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count,
- uint64_t unlock_time, uint64_t fee)
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra)
{
cryptonote::transaction tx;
- transfer(dsts, fake_outputs_count, unlock_time, fee, tx);
+ transfer(dsts, fake_outputs_count, unlock_time, fee, extra, tx);
}
//----------------------------------------------------------------------------------------------------
}