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, 60 insertions, 28 deletions
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index fc700a3de..c2d387acd 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -110,6 +110,7 @@ namespace tools
uint64_t m_amount;
uint64_t m_block_height;
uint64_t m_unlock_time;
+ uint64_t m_timestamp;
};
struct unconfirmed_transfer_details
@@ -120,6 +121,7 @@ namespace tools
std::vector<cryptonote::tx_destination_entry> m_dests;
crypto::hash m_payment_id;
enum { pending, pending_not_in_pool, failed } m_state;
+ uint64_t m_timestamp;
};
struct confirmed_transfer_details
@@ -130,10 +132,11 @@ namespace tools
uint64_t m_block_height;
std::vector<cryptonote::tx_destination_entry> m_dests;
crypto::hash m_payment_id;
+ uint64_t m_timestamp;
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), m_dests(utd.m_dests), m_payment_id(utd.m_payment_id) { 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), m_timestamp(utd.m_timestamp) { get_inputs_money_amount(utd.m_tx, m_amount_in); }
};
typedef std::vector<transfer_details> transfer_container;
@@ -143,6 +146,7 @@ namespace tools
{
cryptonote::transaction tx;
uint64_t dust, fee;
+ bool dust_added_to_fee;
cryptonote::tx_destination_entry change_dts;
std::list<transfer_container::iterator> selected_transfers;
std::string key_images;
@@ -274,11 +278,11 @@ namespace tools
uint64_t unlocked_balance() const;
uint64_t unlocked_dust_balance(const tx_dust_policy &dust_policy) const;
template<typename T>
- void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy);
+ void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, bool trusted_daemon);
template<typename T>
- void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx& ptx);
- void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra);
- void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx);
+ void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx& ptx, bool trusted_daemon);
+ void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, bool trusted_daemon);
+ void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx, bool trusted_daemon);
template<typename T>
void transfer_from(const std::vector<size_t> &outs, size_t num_outputs, uint64_t unlock_time, uint64_t needed_fee, T destination_split_strategy, const tx_dust_policy& dust_policy, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx);
template<typename T>
@@ -287,8 +291,9 @@ namespace tools
void commit_tx(pending_tx& ptx_vector);
void commit_tx(std::vector<pending_tx>& ptx_vector);
- std::vector<pending_tx> create_transactions(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee, const std::vector<uint8_t> extra);
- 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, const uint64_t fee_UNUSED, const std::vector<uint8_t> extra);
+ std::vector<pending_tx> create_transactions(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee, 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, const uint64_t fee_UNUSED, const std::vector<uint8_t> extra, bool trusted_daemon);
+ std::vector<wallet2::pending_tx> create_transactions_all(const cryptonote::account_public_address &address, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector<uint8_t> extra, bool trusted_daemon);
std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon);
bool check_connection();
void get_transfers(wallet2::transfer_container& incoming_transfers) const;
@@ -303,6 +308,7 @@ namespace tools
template <class t_archive>
inline void serialize(t_archive &a, const unsigned int ver)
{
+ uint64_t dummy_refresh_height = 0; // moved to keys file
if(ver < 5)
return;
a & m_blockchain;
@@ -323,7 +329,10 @@ namespace tools
a & m_confirmed_txs;
if(ver < 11)
return;
- a & m_refresh_from_block_height;
+ a & dummy_refresh_height;
+ if(ver < 12)
+ return;
+ a & m_tx_notes;
}
/*!
@@ -364,6 +373,15 @@ namespace tools
std::string get_wallet_file() const;
std::string get_keys_file() const;
+
+ std::vector<size_t> select_available_outputs_from_histogram(uint64_t count, bool atleast, bool trusted_daemon);
+ std::vector<size_t> select_available_outputs(const std::function<bool(const transfer_details &td)> &f);
+ std::vector<size_t> select_available_unmixable_outputs(bool trusted_daemon);
+ std::vector<size_t> select_available_mixable_outputs(bool trusted_daemon);
+
+ void set_tx_note(const crypto::hash &txid, const std::string &note);
+ std::string get_tx_note(const crypto::hash &txid) const;
+
private:
/*!
* \brief Stores wallet information to wallet file.
@@ -378,8 +396,8 @@ namespace tools
* \param keys_file_name Name of wallet file
* \param password Password of wallet file
*/
- void load_keys(const std::string& keys_file_name, const std::string& password);
- void process_new_transaction(const cryptonote::transaction& tx, uint64_t height, bool miner_tx);
+ bool load_keys(const std::string& keys_file_name, const std::string& password);
+ void process_new_transaction(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx);
void process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const crypto::hash& bl_id, uint64_t height);
void detach_blockchain(uint64_t height);
void get_short_chain_history(std::list<crypto::hash>& ids) const;
@@ -387,12 +405,14 @@ namespace tools
bool is_transfer_unlocked(const transfer_details& td) const;
bool clear();
void pull_blocks(uint64_t start_height, uint64_t& blocks_start_height, const std::list<crypto::hash> &short_chain_history, std::list<cryptonote::block_complete_entry> &blocks);
+ void pull_hashes(uint64_t start_height, uint64_t& blocks_start_height, const std::list<crypto::hash> &short_chain_history, std::list<crypto::hash> &hashes);
+ void fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history);
void pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, const std::list<cryptonote::block_complete_entry> &prev_blocks, std::list<cryptonote::block_complete_entry> &blocks, bool &error);
void process_blocks(uint64_t start_height, const std::list<cryptonote::block_complete_entry> &blocks, uint64_t& blocks_added);
- uint64_t select_transfers(uint64_t needed_money, bool add_dust, uint64_t dust, bool hf2_rules, std::list<transfer_container::iterator>& selected_transfers);
+ uint64_t select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::list<transfer_container::iterator>& selected_transfers, bool trusted_daemon);
bool prepare_file_names(const std::string& file_path);
void process_unconfirmed(const cryptonote::transaction& tx, uint64_t height);
- void process_outgoing(const cryptonote::transaction& tx, uint64_t height, uint64_t spent, uint64_t received);
+ void process_outgoing(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, 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
@@ -403,8 +423,6 @@ namespace tools
uint64_t get_upper_tranaction_size_limit();
void check_pending_txes();
std::vector<uint64_t> get_unspent_amounts_vector();
- std::vector<size_t> select_available_outputs(const std::function<bool(const transfer_details &td)> &f);
- std::vector<size_t> select_available_unmixable_outputs(bool trusted_daemon);
cryptonote::account_base m_account;
std::string m_daemon_address;
@@ -421,6 +439,7 @@ namespace tools
payment_container m_payments;
std::unordered_map<crypto::key_image, size_t> m_key_images;
cryptonote::account_public_address m_account_public_address;
+ std::unordered_map<crypto::hash, std::string> m_tx_notes;
uint64_t m_upper_transaction_size_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value
std::atomic<bool> m_run;
@@ -441,10 +460,10 @@ namespace tools
uint64_t m_refresh_from_block_height;
};
}
-BOOST_CLASS_VERSION(tools::wallet2, 11)
-BOOST_CLASS_VERSION(tools::wallet2::payment_details, 0)
-BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 2)
-BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 1)
+BOOST_CLASS_VERSION(tools::wallet2, 12)
+BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1)
+BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 3)
+BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2)
namespace boost
{
@@ -474,6 +493,9 @@ namespace boost
if (ver < 2)
return;
a & x.m_state;
+ if (ver < 3)
+ return;
+ a & x.m_timestamp;
}
template <class Archive>
@@ -487,6 +509,9 @@ namespace boost
return;
a & x.m_dests;
a & x.m_payment_id;
+ if (ver < 2)
+ return;
+ a & x.m_timestamp;
}
template <class Archive>
@@ -496,6 +521,9 @@ namespace boost
a & x.m_amount;
a & x.m_block_height;
a & x.m_unlock_time;
+ if (ver < 1)
+ return;
+ a & x.m_timestamp;
}
template <class Archive>
@@ -562,17 +590,17 @@ namespace tools
}
//----------------------------------------------------------------------------------------------------
template<typename T>
- void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count,
- uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy)
+ void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outs_count, const std::vector<size_t> &unused_transfers_indices,
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, bool trusted_daemon)
{
pending_tx ptx;
cryptonote::transaction tx;
- transfer(dsts, fake_outputs_count, unlock_time, fee, extra, destination_split_strategy, dust_policy, tx, ptx);
+ transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, destination_split_strategy, dust_policy, tx, ptx, trusted_daemon);
}
template<typename T>
- void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count,
- uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx)
+ void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices,
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx, bool trusted_daemon)
{
using namespace cryptonote;
// throw if attempting a transaction with no destinations
@@ -593,9 +621,7 @@ namespace tools
// randomly select inputs for transaction
// throw if requested send amount is greater than amount available to send
std::list<transfer_container::iterator> selected_transfers;
- bool hf2_rules = use_fork_rules(2); // first fork has version 2
- const bool add_dust = (0 == fake_outputs_count) && hf2_rules;
- uint64_t found_money = select_transfers(needed_money, add_dust, dust_policy.dust_threshold, hf2_rules, 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);
typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry;
@@ -711,10 +737,16 @@ namespace tools
return true;
});
THROW_WALLET_EXCEPTION_IF(!all_are_txin_to_key, error::unexpected_txin_type, tx);
+
+ bool dust_sent_elsewhere = (dust_policy.addr_for_dust.m_view_public_key != change_dts.addr.m_view_public_key
+ || dust_policy.addr_for_dust.m_spend_public_key != change_dts.addr.m_spend_public_key);
+
+ if (dust_policy.add_to_fee || dust_sent_elsewhere) change_dts.amount -= dust;
ptx.key_images = key_images;
- ptx.fee = fee;
- ptx.dust = dust;
+ ptx.fee = (dust_policy.add_to_fee ? fee+dust : fee);
+ ptx.dust = ((dust_policy.add_to_fee || dust_sent_elsewhere) ? dust : 0);
+ ptx.dust_added_to_fee = dust_policy.add_to_fee;
ptx.tx = tx;
ptx.change_dts = change_dts;
ptx.selected_transfers = selected_transfers;