aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet2.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet2.h')
-rw-r--r--src/wallet/wallet2.h88
1 files changed, 77 insertions, 11 deletions
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 26680c3da..ba2fc567d 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -244,6 +244,12 @@ namespace tools
bool m_incoming;
};
+ struct pool_payment_details
+ {
+ payment_details m_pd;
+ bool m_double_spend_seen;
+ };
+
struct unconfirmed_transfer_details
{
cryptonote::transaction_prefix m_tx;
@@ -467,8 +473,8 @@ namespace tools
size_t get_num_subaddresses(uint32_t index_major) const { return index_major < m_subaddress_labels.size() ? m_subaddress_labels[index_major].size() : 0; }
void add_subaddress(uint32_t index_major, const std::string& label); // throws when index is out of bound
void expand_subaddresses(const cryptonote::subaddress_index& index);
- std::string get_subaddress_label(const cryptonote::subaddress_index& index) const; // throws when index is out of bound
- void set_subaddress_label(const cryptonote::subaddress_index &index, const std::string &label); // throws when index is out of bound
+ std::string get_subaddress_label(const cryptonote::subaddress_index& index) const;
+ void set_subaddress_label(const cryptonote::subaddress_index &index, const std::string &label);
/*!
* \brief Tells if the wallet file is deprecated.
*/
@@ -530,7 +536,7 @@ namespace tools
void get_payments_out(std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>>& confirmed_payments,
uint64_t min_height, uint64_t max_height = (uint64_t)-1, const boost::optional<uint32_t>& subaddr_account = boost::none, const std::set<uint32_t>& subaddr_indices = {}) const;
void get_unconfirmed_payments_out(std::list<std::pair<crypto::hash,wallet2::unconfirmed_transfer_details>>& unconfirmed_payments, const boost::optional<uint32_t>& subaddr_account = boost::none, const std::set<uint32_t>& subaddr_indices = {}) const;
- void get_unconfirmed_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& unconfirmed_payments, const boost::optional<uint32_t>& subaddr_account = boost::none, const std::set<uint32_t>& subaddr_indices = {}) const;
+ void get_unconfirmed_payments(std::list<std::pair<crypto::hash,wallet2::pool_payment_details>>& unconfirmed_payments, const boost::optional<uint32_t>& subaddr_account = boost::none, const std::set<uint32_t>& subaddr_indices = {}) const;
uint64_t get_blockchain_current_height() const { return m_local_bc_height; }
void rescan_spent();
@@ -585,7 +591,7 @@ namespace tools
std::unordered_map<crypto::hash, payment_details> m;
a & m;
for (std::unordered_map<crypto::hash, payment_details>::const_iterator i = m.begin(); i != m.end(); ++i)
- m_unconfirmed_payments.insert(*i);
+ m_unconfirmed_payments.insert(std::make_pair(i->first, pool_payment_details{i->second, false}));
}
if(ver < 14)
return;
@@ -607,7 +613,15 @@ namespace tools
a & m_address_book;
if(ver < 17)
return;
- a & m_unconfirmed_payments;
+ if (ver < 21)
+ {
+ // we're loading an old version, where m_unconfirmed_payments payload was payment_details
+ std::unordered_map<crypto::hash, payment_details> m;
+ a & m;
+ for (const auto &i: m)
+ m_unconfirmed_payments.insert(std::make_pair(i.first, pool_payment_details{i.second, false}));
+ return;
+ }
if(ver < 18)
return;
a & m_scanned_pool_txs[0];
@@ -618,6 +632,12 @@ namespace tools
a & m_subaddresses_inv;
a & m_subaddress_labels;
a & m_additional_tx_keys;
+ if(ver < 21)
+ return;
+ a & m_attributes;
+ if(ver < 22)
+ return;
+ a & m_unconfirmed_payments;
}
/*!
@@ -703,6 +723,9 @@ namespace tools
void set_tx_note(const crypto::hash &txid, const std::string &note);
std::string get_tx_note(const crypto::hash &txid) const;
+ void set_description(const std::string &description);
+ std::string get_description() const;
+
std::string sign(const std::string &data) const;
bool verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const;
@@ -757,6 +780,25 @@ namespace tools
// check if key image is ours
bool light_wallet_key_image_is_ours(const crypto::key_image& key_image, const crypto::public_key& tx_public_key, uint64_t out_index);
+ /*
+ * "attributes" are a mechanism to store an arbitrary number of string values
+ * on the level of the wallet as a whole, identified by keys. Their introduction,
+ * technically the unordered map m_attributes stored as part of a wallet file,
+ * led to a new wallet file version, but now new singular pieces of info may be added
+ * without the need for a new version.
+ *
+ * The first and so far only value stored as such an attribute is the description.
+ * It's stored under the standard key ATTRIBUTE_DESCRIPTION (see method set_description).
+ *
+ * The mechanism is open to all clients and allows them to use it for storing basically any
+ * single string values in a wallet. To avoid the problem that different clients possibly
+ * overwrite or misunderstand each other's attributes, a two-part key scheme is
+ * proposed: <client name>.<value name>
+ */
+ const char* const ATTRIBUTE_DESCRIPTION = "wallet2.description";
+ void set_attribute(const std::string &key, const std::string &value);
+ std::string get_attribute(const std::string &key) const;
+
private:
/*!
* \brief Stores wallet information to wallet file.
@@ -772,7 +814,7 @@ namespace tools
* \param password Password of wallet file
*/
bool load_keys(const std::string& keys_file_name, const std::string& password);
- void process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector<uint64_t> &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool);
+ void process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector<uint64_t> &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen);
void process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const crypto::hash& bl_id, uint64_t height, const cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices &o_indices);
void detach_blockchain(uint64_t height);
void get_short_chain_history(std::list<crypto::hash>& ids) const;
@@ -821,7 +863,7 @@ namespace tools
std::atomic<uint64_t> m_local_bc_height; //temporary workaround
std::unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs;
std::unordered_map<crypto::hash, confirmed_transfer_details> m_confirmed_txs;
- std::unordered_multimap<crypto::hash, payment_details> m_unconfirmed_payments;
+ std::unordered_multimap<crypto::hash, pool_payment_details> m_unconfirmed_payments;
std::unordered_map<crypto::hash, crypto::secret_key> m_tx_keys;
cryptonote::checkpoints m_checkpoints;
std::unordered_map<crypto::hash, std::vector<crypto::secret_key>> m_additional_tx_keys;
@@ -835,6 +877,7 @@ namespace tools
std::unordered_map<cryptonote::subaddress_index, crypto::public_key> m_subaddresses_inv;
std::vector<std::vector<std::string>> m_subaddress_labels;
std::unordered_map<crypto::hash, std::string> m_tx_notes;
+ std::unordered_map<std::string, std::string> m_attributes;
std::vector<tools::wallet2::address_book_row> m_address_book;
uint64_t m_upper_transaction_size_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value
@@ -882,9 +925,10 @@ namespace tools
std::unordered_map<crypto::public_key, std::map<uint64_t, crypto::key_image> > m_key_image_cache;
};
}
-BOOST_CLASS_VERSION(tools::wallet2, 20)
+BOOST_CLASS_VERSION(tools::wallet2, 22)
BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 8)
BOOST_CLASS_VERSION(tools::wallet2::payment_details, 2)
+BOOST_CLASS_VERSION(tools::wallet2::pool_payment_details, 1)
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 7)
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 5)
BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 17)
@@ -1042,7 +1086,10 @@ namespace boost
x.m_amount_out += x.m_change;
}
if (ver < 7)
+ {
+ x.m_subaddr_account = 0;
return;
+ }
a & x.m_subaddr_account;
a & x.m_subaddr_indices;
}
@@ -1083,7 +1130,10 @@ namespace boost
}
a & x.m_unlock_time;
if (ver < 5)
+ {
+ x.m_subaddr_account = 0;
return;
+ }
a & x.m_subaddr_account;
a & x.m_subaddr_indices;
}
@@ -1099,10 +1149,20 @@ namespace boost
return;
a & x.m_timestamp;
if (ver < 2)
+ {
+ x.m_subaddr_index = {};
return;
+ }
a & x.m_subaddr_index;
}
-
+
+ template <class Archive>
+ inline void serialize(Archive& a, tools::wallet2::pool_payment_details& x, const boost::serialization::version_type ver)
+ {
+ a & x.m_pd;
+ a & x.m_double_spend_seen;
+ }
+
template <class Archive>
inline void serialize(Archive& a, tools::wallet2::address_book_row& x, const boost::serialization::version_type ver)
{
@@ -1110,7 +1170,10 @@ namespace boost
a & x.m_payment_id;
a & x.m_description;
if (ver < 17)
+ {
+ x.m_is_subaddress = false;
return;
+ }
a & x.m_is_subaddress;
}
@@ -1140,7 +1203,10 @@ namespace boost
a & x.use_rct;
a & x.dests;
if (ver < 1)
+ {
+ x.subaddr_account = 0;
return;
+ }
a & x.subaddr_account;
a & x.subaddr_indices;
}
@@ -1249,10 +1315,10 @@ namespace tools
}
// randomly select inputs for transaction
- // throw if requested send amount is greater than amount available to send
+ // throw if requested send amount is greater than (unlocked) amount available to send
std::list<size_t> selected_transfers;
uint64_t found_money = select_transfers(needed_money, unused_transfers_indices, selected_transfers, trusted_daemon);
- THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_money, found_money, needed_money - fee, fee);
+ THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_unlocked_money, found_money, needed_money - fee, fee);
uint32_t subaddr_account = m_transfers[*selected_transfers.begin()].m_subaddr_index.major;
for (auto i = ++selected_transfers.begin(); i != selected_transfers.end(); ++i)