aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/wallet2.cpp69
-rw-r--r--src/wallet/wallet2.h42
2 files changed, 95 insertions, 16 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 788f96415..f26809af8 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -270,7 +270,14 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
LOG_PRINT_L2("Found unencrypted payment ID: " << 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 (tx_money_spent_in_ins > 0)
+ {
+ process_outgoing(tx, height, tx_money_spent_in_ins, tx_money_got_in_outs);
+ }
+
if (0 < received)
{
payment_details payment;
@@ -288,7 +295,7 @@ void wallet2::process_unconfirmed(const cryptonote::transaction& tx, uint64_t he
crypto::hash txid = get_transaction_hash(tx);
auto unconf_it = m_unconfirmed_txs.find(txid);
if(unconf_it != m_unconfirmed_txs.end()) {
- if (store_tx_keys()) {
+ if (store_tx_info()) {
try {
m_confirmed_txs.insert(std::make_pair(txid, confirmed_transfer_details(unconf_it->second, height)));
}
@@ -301,6 +308,18 @@ void wallet2::process_unconfirmed(const cryptonote::transaction& tx, uint64_t he
}
}
//----------------------------------------------------------------------------------------------------
+void wallet2::process_outgoing(const cryptonote::transaction &tx, uint64_t height, uint64_t spent, uint64_t received)
+{
+ crypto::hash txid = get_transaction_hash(tx);
+ confirmed_transfer_details &ctd = m_confirmed_txs[txid];
+ // operator[] creates if not found
+ // fill with the info we know, some info might already be there
+ ctd.m_amount_in = spent;
+ ctd.m_amount_out = get_outs_money_amount(tx);
+ ctd.m_change = received;
+ ctd.m_block_height = height;
+}
+//----------------------------------------------------------------------------------------------------
void wallet2::process_new_blockchain_entry(const cryptonote::block& b, cryptonote::block_complete_entry& bche, crypto::hash& bl_id, uint64_t height)
{
//handle transactions from new block
@@ -551,8 +570,8 @@ bool wallet2::store_keys(const std::string& keys_file_name, const std::string& p
value2.SetInt(m_always_confirm_transfers ? 1 :0);
json.AddMember("always_confirm_transfers", value2, json.GetAllocator());
- value2.SetInt(m_store_tx_keys ? 1 :0);
- json.AddMember("store_tx_keys", value2, json.GetAllocator());
+ value2.SetInt(m_store_tx_info ? 1 :0);
+ json.AddMember("store_tx_info", value2, json.GetAllocator());
value2.SetUint(m_default_mixin);
json.AddMember("default_mixin", value2, json.GetAllocator());
@@ -638,7 +657,8 @@ void wallet2::load_keys(const std::string& keys_file_name, const std::string& pa
m_watch_only = false;
}
m_always_confirm_transfers = json.HasMember("always_confirm_transfers") && (json["always_confirm_transfers"].GetInt() != 0);
- m_store_tx_keys = json.HasMember("store_tx_keys") && (json["store_tx_keys"].GetInt() != 0);
+ m_store_tx_info = (json.HasMember("store_tx_keys") && (json["store_tx_keys"].GetInt() != 0))
+ || (json.HasMember("store_tx_info") && (json["store_tx_info"].GetInt() != 0));
m_default_mixin = json.HasMember("default_mixin") ? json["default_mixin"].GetUint() : 0;
}
@@ -1206,12 +1226,14 @@ uint64_t wallet2::select_transfers(uint64_t needed_money, bool add_dust, uint64_
return found_money;
}
//----------------------------------------------------------------------------------------------------
-void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t change_amount)
+void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, const std::vector<cryptonote::tx_destination_entry> &dests, const crypto::hash &payment_id, uint64_t change_amount)
{
unconfirmed_transfer_details& utd = m_unconfirmed_txs[cryptonote::get_transaction_hash(tx)];
utd.m_change = change_amount;
utd.m_sent_time = time(NULL);
utd.m_tx = tx;
+ utd.m_dests = dests;
+ utd.m_payment_id = payment_id;
}
//----------------------------------------------------------------------------------------------------
@@ -1345,6 +1367,30 @@ std::string wallet2::address_from_txt_record(const std::string& s)
return std::string();
}
+crypto::hash wallet2::get_payment_id(const pending_tx &ptx) const
+{
+ std::vector<tx_extra_field> tx_extra_fields;
+ if(!parse_tx_extra(ptx.tx.extra, tx_extra_fields))
+ return cryptonote::null_hash;
+ tx_extra_nonce extra_nonce;
+ crypto::hash payment_id = null_hash;
+ if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
+ {
+ crypto::hash8 payment_id8 = null_hash8;
+ if(get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8))
+ {
+ if (decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key))
+ {
+ memcpy(payment_id.data, payment_id8.data, 8);
+ }
+ }
+ else if (!get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id))
+ {
+ payment_id = cryptonote::null_hash;
+ }
+ }
+ return payment_id;
+}
//----------------------------------------------------------------------------------------------------
// take a pending tx and actually send it to the daemon
void wallet2::commit_tx(pending_tx& ptx)
@@ -1361,8 +1407,15 @@ void wallet2::commit_tx(pending_tx& ptx)
THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status != CORE_RPC_STATUS_OK, error::tx_rejected, ptx.tx, daemon_send_resp.status);
txid = get_transaction_hash(ptx.tx);
- add_unconfirmed_tx(ptx.tx, ptx.change_dts.amount);
- if (store_tx_keys())
+ crypto::hash payment_id = cryptonote::null_hash;
+ std::vector<cryptonote::tx_destination_entry> dests;
+ if (store_tx_info())
+ {
+ payment_id = get_payment_id(ptx);
+ dests = ptx.dests;
+ }
+ add_unconfirmed_tx(ptx.tx, dests, payment_id, ptx.change_dts.amount);
+ if (store_tx_info())
m_tx_keys.insert(std::make_pair(txid, ptx.tx_key));
LOG_PRINT_L2("transaction " << txid << " generated ok and sent to daemon, key_images: [" << ptx.key_images << "]");
@@ -1639,6 +1692,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
ptx.change_dts = change_dts;
ptx.selected_transfers = selected_transfers;
ptx.tx_key = tx_key;
+ ptx.dests = dsts;
}
// Another implementation of transaction creation that is hopefully better
@@ -1987,6 +2041,7 @@ void wallet2::transfer_dust(size_t num_outputs, uint64_t unlock_time, uint64_t n
ptx.change_dts = change_dts;
ptx.selected_transfers = selected_transfers;
ptx.tx_key = tx_key;
+ ptx.dests = dsts;
}
//----------------------------------------------------------------------------------------------------
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index dbd305a02..8df6c757d 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -79,9 +79,9 @@ namespace tools
class wallet2
{
- wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false), m_always_confirm_transfers (false), m_store_tx_keys(false), m_default_mixin(0) {}
+ wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false), m_always_confirm_transfers (false), m_store_tx_info(true), m_default_mixin(0) {}
public:
- wallet2(bool testnet = false, bool restricted = false) : m_run(true), m_callback(0), m_testnet(testnet), m_restricted(restricted), is_old_file_format(false), m_store_tx_keys(false), m_default_mixin(0) {}
+ wallet2(bool testnet = false, bool restricted = false) : m_run(true), m_callback(0), m_testnet(testnet), m_restricted(restricted), is_old_file_format(false), m_store_tx_info(true), m_default_mixin(0) {}
struct transfer_details
{
uint64_t m_block_height;
@@ -107,6 +107,8 @@ namespace tools
cryptonote::transaction m_tx;
uint64_t m_change;
time_t m_sent_time;
+ std::vector<cryptonote::tx_destination_entry> m_dests;
+ crypto::hash m_payment_id;
};
struct confirmed_transfer_details
@@ -115,9 +117,12 @@ namespace tools
uint64_t m_amount_out;
uint64_t m_change;
uint64_t m_block_height;
- confirmed_transfer_details() {}
+ std::vector<cryptonote::tx_destination_entry> m_dests;
+ crypto::hash m_payment_id;
+
+ confirmed_transfer_details(): m_amount_in(0), m_amount_out(0), m_change((uint64_t)-1), m_block_height(0), m_payment_id(cryptonote::null_hash) {}
confirmed_transfer_details(const unconfirmed_transfer_details &utd, uint64_t height):
- m_amount_out(get_outs_money_amount(utd.m_tx)), m_change(utd.m_change), m_block_height(height) { get_inputs_money_amount(utd.m_tx, m_amount_in); }
+ m_amount_out(get_outs_money_amount(utd.m_tx)), m_change(utd.m_change), m_block_height(height), m_dests(utd.m_dests), m_payment_id(utd.m_payment_id) { get_inputs_money_amount(utd.m_tx, m_amount_in); }
};
typedef std::vector<transfer_details> transfer_container;
@@ -131,6 +136,7 @@ namespace tools
std::list<transfer_container::iterator> selected_transfers;
std::string key_images;
crypto::secret_key tx_key;
+ std::vector<cryptonote::tx_destination_entry> dests;
};
struct keys_file_data
@@ -308,8 +314,8 @@ namespace tools
bool always_confirm_transfers() const { return m_always_confirm_transfers; }
void always_confirm_transfers(bool always) { m_always_confirm_transfers = always; }
- bool store_tx_keys() const { return m_store_tx_keys; }
- void store_tx_keys(bool store) { m_store_tx_keys = store; }
+ bool store_tx_info() const { return m_store_tx_info; }
+ void store_tx_info(bool store) { m_store_tx_info = store; }
uint32_t default_mixin() const { return m_default_mixin; }
void default_mixin(uint32_t m) { m_default_mixin = m; }
@@ -341,10 +347,12 @@ namespace tools
uint64_t select_transfers(uint64_t needed_money, bool add_dust, uint64_t dust, std::list<transfer_container::iterator>& selected_transfers);
bool prepare_file_names(const std::string& file_path);
void process_unconfirmed(const cryptonote::transaction& tx, uint64_t height);
- void add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t change_amount);
+ void process_outgoing(const cryptonote::transaction& tx, uint64_t height, uint64_t spent, uint64_t received);
+ void add_unconfirmed_tx(const cryptonote::transaction& tx, const std::vector<cryptonote::tx_destination_entry> &dests, const crypto::hash &payment_id, uint64_t change_amount);
void generate_genesis(cryptonote::block& b);
void check_genesis(const crypto::hash& genesis_hash) const; //throws
bool generate_chacha8_key_from_secret_keys(crypto::chacha8_key &key) const;
+ crypto::hash get_payment_id(const pending_tx &ptx) const;
cryptonote::account_base m_account;
std::string m_daemon_address;
@@ -372,11 +380,11 @@ namespace tools
bool is_old_file_format; /*!< Whether the wallet file is of an old file format */
bool m_watch_only; /*!< no spend key */
bool m_always_confirm_transfers;
- bool m_store_tx_keys; /*!< request txkey to be returned in RPC, and store in the wallet cache file */
+ bool m_store_tx_info; /*!< request txkey to be returned in RPC, and store in the wallet cache file */
uint32_t m_default_mixin;
};
}
-BOOST_CLASS_VERSION(tools::wallet2, 9)
+BOOST_CLASS_VERSION(tools::wallet2, 10)
namespace boost
{
@@ -399,6 +407,10 @@ namespace boost
a & x.m_change;
a & x.m_sent_time;
a & x.m_tx;
+ if (ver < 9)
+ return;
+ a & x.m_dests;
+ a & x.m_payment_id;
}
template <class Archive>
@@ -408,6 +420,10 @@ namespace boost
a & x.m_amount_out;
a & x.m_change;
a & x.m_block_height;
+ if (ver < 9)
+ return;
+ a & x.m_dests;
+ a & x.m_payment_id;
}
template <class Archive>
@@ -418,6 +434,13 @@ namespace boost
a & x.m_block_height;
a & x.m_unlock_time;
}
+
+ template <class Archive>
+ inline void serialize(Archive& a, cryptonote::tx_destination_entry& x, const boost::serialization::version_type ver)
+ {
+ a & x.amount;
+ a & x.addr;
+ }
}
}
@@ -628,6 +651,7 @@ namespace tools
ptx.change_dts = change_dts;
ptx.selected_transfers = selected_transfers;
ptx.tx_key = tx_key;
+ ptx.dests = dsts;
}