diff options
author | Riccardo Spagni <ric@spagni.net> | 2016-08-28 22:41:11 +0200 |
---|---|---|
committer | Riccardo Spagni <ric@spagni.net> | 2016-08-28 22:41:12 +0200 |
commit | 8a5b766d17761f5fbdd3e30e638daa98a40a4c8a (patch) | |
tree | ea05e3f0fd47fd1d8728e64d081292d337825cb9 /src/wallet/wallet2.h | |
parent | Merge pull request #991 (diff) | |
parent | blockchain: testnet heights for v3, v4, and v5 (diff) | |
download | monero-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.tar.xz |
Merge pull request #961
887db9f blockchain: testnet heights for v3, v4, and v5 (moneromooo-monero)
f24ab58 ringct: remove unused code (moneromooo-monero)
b38452b ringct: pass structure by const ref, not value (moneromooo-monero)
fd11271 ringct: use memcpy/memset instead of handwritten loop where appropriate (moneromooo-monero)
5d38206 ringct: remove spurious copies (moneromooo-monero)
16732a8 rct: faster Cryptonote/rct conversions (moneromooo-monero)
fbd7c35 wallet: fix some "may be used uninitialized" warnings (moneromooo-monero)
4a41dd4 wallet: do not generate 0 change (moneromooo-monero)
a0925e6 core: use full rct signatures if just one input (moneromooo-monero)
94fd881 rct: early out on failure on verRange (moneromooo-monero)
45349b6 wallet: do not ask for duplicate histograms (moneromooo-monero)
b951bc8 wallet: transfer_selected_rct now also selects fake outs (moneromooo-monero)
4f887de increase minimum mixin to 4 on hard fork 5 (moneromooo-monero)
0815c72 core: allow v1 txes after HF 5 when sweeping unmixable outputs (moneromooo-monero)
f782d45 tests: hard fork list must end with a 0 (moneromooo-monero)
074e602 ringct: use Cryptonote serialization to hash non prunable data (moneromooo-monero)
c3b3260 New "Halfway RingCT" outputs for coinbase transactions (moneromooo-monero)
6f526cd rct: log why verification fails (moneromooo-monero)
d4b8991 rct: serialize txnFee as varint (moneromooo-monero)
d4b62a1 rct amount key modified as per luigi1111's recommendations (moneromooo-monero)
93f5c62 rct: rework v2 txes into prunable and non prunable data (moneromooo-monero)
d93746b rct: rework the verification preparation process (moneromooo-monero)
3ab2ab3 rct: change the simple flag to a type (moneromooo-monero)
c5be4b0 rct: avoid the need for the last II element (Shen Noether)
a47ceee wallet: do not store signatures in the wallet cache (moneromooo-monero)
0263dd2 core: add some locking around pool use (moneromooo-monero)
2c9d951 wallet2: factor m_spent changes (moneromooo-monero)
1303cda wallet: always use new algorithm for RPC transfers (moneromooo-monero)
b337aea rct: do not serialize senderPk - it is not used anymore (moneromooo-monero)
e5a9a47 core_tests: fix a couple pre-rct tests using rct (moneromooo-monero)
230fca2 wallet: use the prefered rct case only when enough rct outs exist (moneromooo-monero)
c27194a wallet: do not try to use rct txes a few blocks before the fork (moneromooo-monero)
1bf0698 tx_pool: log why a transaction was rejected for version checks (moneromooo-monero)
37bdf6e change fork settings to allow pre-rct txes for one more fork cycle (moneromooo-monero)
cc85cc6 simplewallet: better check_tx_key feedback (moneromooo-monero)
9b70856 rct: make the amount key derivable by a third party with the tx key (moneromooo-monero)
cf33e1a rct: do not serialize public keys in outPk (moneromooo-monero)
83ab315 wallet2_api: zero amounts are now allowed with rct (moneromooo-monero)
096ac06 wallet2_api: update on_money_{received,spent} prototypes for rct changes (moneromooo-monero)
3cb2ede rpc: send global indices along with blocks/transacions on refresh (moneromooo-monero)
414b424 core: always use the new simple rct variant (moneromooo-monero)
ce5de8b tests: add tests for wallet output selection (moneromooo-monero)
84c82cd wallet: better tx input selection (moneromooo-monero)
1e21651 rct: use the already defined H where possible (moneromooo-monero)
07d353d wallet: handle 0 change properly (moneromooo-monero)
e81a2b2 port get_tx_key/check_tx_key to rct (moneromooo-monero)
e06faef tests: add basic tests for simple rct api (moneromooo-monero)
a4d4d61 integrate simple rct api (moneromooo-monero)
1e8d37e serialization: add override for serializing bool (moneromooo-monero)
dbb5f2d ringct: optimization/cleanup of hash functions (Shen Noether)
4fd01f2 ringct: "simple" ringct variant (Shen Noether)
37c895e wallet: rct specific output selection (moneromooo-monero)
1181c57 wallet: make sweep_all work with rct txes too (moneromooo-monero)
c2ec6d3 mixable transactions must be rct for v3 (moneromooo-monero)
1017a75 wallet: factor transfer_rct code with transfer code (moneromooo-monero)
f5465d8 Condition v2 txes on v3 hard fork (moneromooo-monero)
59a66e2 move the rct commitments to the output_amounts database (moneromooo-monero)
6d0e471 rct: add the tx prefix hash into the MLSAG (moneromooo-monero)
35dce5c ringct: fix size unit mismatch calling keccak (moneromooo-monero)
20e50ec ringct: do not serialize what can be reconstructed (moneromooo-monero)
106e3dc Add rct core tests (moneromooo-monero)
ada5275 Use the supplied hard fork version in validate_miner_transaction (moneromooo-monero)
acbe06d wallet: update spent status when an accepted tx disappears (moneromooo-monero)
089df4a wallet: reset output spent status on blockchain reorg (moneromooo-monero)
73d59f1 ringct: catch errors from ge_frombytes_vartime (moneromooo-monero)
161551e tests: test for ringct rctSig data sizes (moneromooo-monero)
359f469 ringct: add missing size check for ecdhInfo (moneromooo-monero)
229968e ringct: change asserts to return false for boolean functions (moneromooo-monero)
dc4aad7 add rct to the protocol (moneromooo-monero)
211d1db db_lmdb: update reset for recent db changes (moneromooo-monero)
dee42d6 ringct: add functions to commit to an amount (moneromooo-monero)
cc7f449 make rct tx serialization work (moneromooo-monero)
e70e8a6 crypto: error out where appropriate (moneromooo-monero)
54f7429 ringct: allow no outputs, and add tests for this and fees (moneromooo-monero)
e99904a ringct: make fee optional (moneromooo-monero)
f8c04ad ringct: txn fee stuff (Shen Noether)
66f9626 ringct: new {gen,decode}Rct APIs for convenience (moneromooo-monero)
789b2e2 ringct: add more convenience functions (moneromooo-monero)
9856443 core: link against libringct (moneromooo-monero)
4258dab core: new /getrandom_rctouts.bin binary RPC call (moneromooo-monero)
c3a2e14 ringct: add convenience functions to bridge ringct and cryptonote (moneromooo-monero)
eb56d0f blockchain_db: add functions for adding/removing/getting rct commitments (moneromooo-monero)
82072e7 ringct: restore verRange check in debug mode (moneromooo-monero)
63856ca ringct: add check for destinations/amount size being equal (moneromooo-monero)
e816a09 ringct: fix off by 1 in mixin usage (moneromooo-monero)
09c5ea4 ringct: simplify random key generation (moneromooo-monero)
53cdf4d tests: new ringct test for checking H2 values (Shen Noether)
56f6549 ringct: cosmetic fixes (Shen Noether)
55ff136 ringct: changes to hashToPointSimple to calcualte H2 values (Shen Noether)
63733b1 ringct: compare keys with bitwise equality, not crypto ops (Shen Noether)
98f4c6f ringct: fix size argument to cn_fast_hash (Shen Noether)
720ac85 tests: zero inputs/outputs are in fact supposed to be accepted (moneromooo-monero)
84948ea ringct: add a test for prooveRange being non deterministic (moneromooo-monero)
09fb9f4 Fix sc_0 to skGen in ProveRange (Shen Noether)
d37c1db ringct: add a few consts where appropriate (moneromooo-monero)
700248f tests: more ringct range proof tests (moneromooo-monero)
d02f999 rct: add serialization machinery to rct types (moneromooo-monero)
0ff8305 serialization: declare do_serialize specializations before use (moneromooo-monero)
8b135e7 Added note on generating H2 (Shen Noether)
4d639d9 Fixed missing last index H2 (Shen Noether)
9e82b69 remove original Cryptonote blockchain_storage blockchain format (moneromooo-monero)
86b4426 ringct: lock access to the PRNG (moneromooo-monero)
4d7f073 ringct: add simple input validation (moneromooo-monero)
57779ab tests: add some more ringct building block tests (moneromooo-monero)
b656001 ringct: add convenience operators to key (moneromooo-monero)
2d6303f tests: add Shen Noether's basic ringct tests (moneromooo-monero)
9b1afe5 ringct: import of Shen Noether's ring confidential transactions (moneromooo-monero)
Diffstat (limited to 'src/wallet/wallet2.h')
-rw-r--r-- | src/wallet/wallet2.h | 143 |
1 files changed, 122 insertions, 21 deletions
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index d0c514a6d..0e87614b4 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -31,6 +31,7 @@ #pragma once #include <memory> +#include <boost/archive/binary_iarchive.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/vector.hpp> #include <atomic> @@ -46,6 +47,8 @@ #include "common/unordered_containers_boost_serialization.h" #include "crypto/chacha8.h" #include "crypto/hash.h" +#include "ringct/rctTypes.h" +#include "ringct/rctOps.h" #include "wallet_errors.h" @@ -58,8 +61,8 @@ namespace tools { public: virtual void on_new_block(uint64_t height, const cryptonote::block& block) {} - virtual void on_money_received(uint64_t height, const cryptonote::transaction& tx, size_t out_index) {} - virtual void on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, size_t out_index, const cryptonote::transaction& spend_tx) {} + virtual void on_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount) {} + virtual void on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, uint64_t amount, const cryptonote::transaction& spend_tx) {} virtual void on_skip_transaction(uint64_t height, const cryptonote::transaction& tx) {} virtual ~i_wallet2_callback() {} }; @@ -96,13 +99,19 @@ namespace tools struct transfer_details { uint64_t m_block_height; - cryptonote::transaction m_tx; + cryptonote::transaction_prefix m_tx; + crypto::hash m_txid; size_t m_internal_output_index; uint64_t m_global_output_index; bool m_spent; + uint64_t m_spent_height; crypto::key_image m_key_image; //TODO: key_image stored twice :( + rct::key m_mask; + uint64_t m_amount; + bool m_rct; - uint64_t amount() const { return m_tx.vout[m_internal_output_index].amount; } + bool is_rct() const { return m_rct; } + uint64_t amount() const { return m_amount; } }; struct payment_details @@ -116,7 +125,9 @@ namespace tools struct unconfirmed_transfer_details { - cryptonote::transaction m_tx; + cryptonote::transaction_prefix m_tx; + uint64_t m_amount_in; + uint64_t m_amount_out; uint64_t m_change; time_t m_sent_time; std::vector<cryptonote::tx_destination_entry> m_dests; @@ -137,7 +148,7 @@ namespace tools 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), m_timestamp(utd.m_timestamp) { get_inputs_money_amount(utd.m_tx, m_amount_in); } + m_amount_in(utd.m_amount_in), m_amount_out(utd.m_amount_out), 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) {} }; typedef std::vector<transfer_details> transfer_container; @@ -289,6 +300,8 @@ namespace tools template<typename T> void transfer_selected(const std::vector<cryptonote::tx_destination_entry>& dsts, const std::list<transfer_container::iterator> selected_transfers, 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_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::list<transfer_container::iterator> selected_transfers, 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 commit_tx(pending_tx& ptx_vector); void commit_tx(std::vector<pending_tx>& ptx_vector); @@ -308,6 +321,7 @@ namespace tools uint64_t get_blockchain_current_height() const { return m_local_bc_height; } void rescan_spent(); void rescan_blockchain(bool refresh = true); + bool is_transfer_unlocked(const transfer_details& td) const; template <class t_archive> inline void serialize(t_archive &a, const unsigned int ver) { @@ -339,6 +353,8 @@ namespace tools if(ver < 13) return; a & m_unconfirmed_payments; + if(ver < 14) + return; } /*! @@ -376,8 +392,10 @@ namespace tools bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) const; + uint64_t get_num_rct_outputs(); - bool use_fork_rules(uint8_t version); + void get_hard_fork_info(uint8_t version, uint64_t &earliest_height); + bool use_fork_rules(uint8_t version, uint64_t early_blocks = 0); std::string get_wallet_file() const; std::string get_keys_file() const; @@ -388,6 +406,9 @@ namespace tools std::vector<size_t> select_available_unmixable_outputs(bool trusted_daemon); std::vector<size_t> select_available_mixable_outputs(bool trusted_daemon); + size_t pop_best_value_from(const transfer_container &transfers, std::vector<size_t> &unused_dust_indices, const std::list<transfer_container::iterator>& selected_transfers) const; + size_t pop_best_value(std::vector<size_t> &unused_dust_indices, const std::list<transfer_container::iterator>& selected_transfers) const; + void set_tx_note(const crypto::hash &txid, const std::string ¬e); std::string get_tx_note(const crypto::hash &txid) const; @@ -413,32 +434,37 @@ 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 cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx, bool pool); - void process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const crypto::hash& bl_id, uint64_t height); + void process_new_transaction(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_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; bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height) const; - 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_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, std::vector<cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> &o_indices); 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); + 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, std::vector<cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> &o_indices, bool &error); + void process_blocks(uint64_t start_height, const std::list<cryptonote::block_complete_entry> &blocks, const std::vector<cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> &o_indices, uint64_t& blocks_added); 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 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 add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t amount_in, 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; - void check_acc_out(const cryptonote::account_keys &acc, const cryptonote::tx_out &o, const crypto::public_key &tx_pub_key, size_t i, uint64_t &money_transfered, bool &error) const; + void check_acc_out(const cryptonote::account_keys &acc, const cryptonote::tx_out &o, const crypto::public_key &tx_pub_key, size_t i, bool &received, uint64_t &money_transfered, bool &error) const; void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const; uint64_t get_upper_tranaction_size_limit(); std::vector<uint64_t> get_unspent_amounts_vector(); uint64_t sanitize_fee_multiplier(uint64_t fee_multiplier) const; + float get_output_relatedness(const transfer_details &td0, const transfer_details &td1) const; + std::vector<size_t> pick_prefered_rct_inputs(uint64_t needed_money) const; + void set_spent(transfer_details &td, uint64_t height); + void set_unspent(transfer_details &td); + template<typename entry> + void get_outs(std::vector<std::vector<entry>> &outs, const std::list<transfer_container::iterator> &selected_transfers, size_t fake_outputs_count); cryptonote::account_base m_account; std::string m_daemon_address; @@ -478,9 +504,10 @@ namespace tools uint64_t m_refresh_from_block_height; }; } -BOOST_CLASS_VERSION(tools::wallet2, 13) +BOOST_CLASS_VERSION(tools::wallet2, 14) +BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 4) BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1) -BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 3) +BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 5) BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2) namespace boost @@ -488,14 +515,72 @@ namespace boost namespace serialization { template <class Archive> + inline void initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver) + { + } + template<> + inline void initialize_transfer_details(boost::archive::binary_iarchive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver) + { + if (ver < 1) + { + x.m_mask = rct::identity(); + x.m_amount = x.m_tx.vout[x.m_internal_output_index].amount; + } + if (ver < 2) + { + x.m_spent_height = 0; + } + if (ver < 4) + { + x.m_rct = x.m_tx.vout[x.m_internal_output_index].amount == 0; + } + } + + template <class Archive> inline void serialize(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver) { a & x.m_block_height; a & x.m_global_output_index; a & x.m_internal_output_index; - a & x.m_tx; + if (ver < 3) + { + cryptonote::transaction tx; + a & tx; + x.m_tx = (const cryptonote::transaction_prefix&)tx; + x.m_txid = cryptonote::get_transaction_hash(tx); + } + else + { + a & x.m_tx; + } a & x.m_spent; a & x.m_key_image; + if (ver < 1) + { + // ensure mask and amount are set + initialize_transfer_details(a, x, ver); + return; + } + a & x.m_mask; + a & x.m_amount; + if (ver < 2) + { + initialize_transfer_details(a, x, ver); + return; + } + a & x.m_spent_height; + if (ver < 3) + { + initialize_transfer_details(a, x, ver); + return; + } + a & x.m_txid; + if (ver < 4) + { + initialize_transfer_details(a, x, ver); + return; + } + a & x.m_rct; } template <class Archive> @@ -503,7 +588,16 @@ namespace boost { a & x.m_change; a & x.m_sent_time; - a & x.m_tx; + if (ver < 5) + { + cryptonote::transaction tx; + a & tx; + x.m_tx = (const cryptonote::transaction_prefix&)tx; + } + else + { + a & x.m_tx; + } if (ver < 1) return; a & x.m_dests; @@ -514,6 +608,10 @@ namespace boost if (ver < 3) return; a & x.m_timestamp; + if (ver < 4) + return; + a & x.m_amount_in; + a & x.m_amount_out; } template <class Archive> @@ -688,6 +786,7 @@ namespace tools cryptonote::tx_source_entry& src = sources.back(); transfer_details& td = *it; src.amount = td.amount(); + src.rct = false; //paste mixin transaction if(daemon_resp.outs.size()) { @@ -698,7 +797,8 @@ namespace tools continue; tx_output_entry oe; oe.first = daemon_oe.global_amount_index; - oe.second = daemon_oe.out_key; + oe.second.dest = rct::pk2rct(daemon_oe.out_key); + oe.second.mask = rct::identity(); src.outputs.push_back(oe); if(src.outputs.size() >= fake_outputs_count) break; @@ -713,7 +813,8 @@ namespace tools //size_t real_index = src.outputs.size() ? (rand() % src.outputs.size() ):0; tx_output_entry real_oe; real_oe.first = td.m_global_output_index; - real_oe.second = boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key; + real_oe.second.dest = rct::pk2rct(boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key); + real_oe.second.mask = rct::identity(); auto interted_it = src.outputs.insert(it_to_insert, real_oe); src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_tx); src.real_output = interted_it - src.outputs.begin(); |