36 #include <boost/program_options/options_description.hpp> 37 #include <boost/program_options/variables_map.hpp> 38 #include <boost/serialization/list.hpp> 39 #include <boost/serialization/vector.hpp> 42 #include "include_base_utils.h" 46 #include "net/http_client.h" 47 #include "storages/http_abstract_invoke.h" 65 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY 66 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "wallet.wallet2" 68 class Serialization_portability_wallet_Test;
99 friend class ::Serialization_portability_wallet_Test;
101 static constexpr
const std::chrono::seconds
rpc_timeout = std::chrono::minutes(3) + std::chrono::seconds(30);
111 wallet2(
const wallet2&) :
m_run(
true),
m_callback(0),
m_testnet(
false),
m_always_confirm_transfers(
true),
m_print_ring_members(
false),
m_store_tx_info(
true),
m_default_priority(0),
m_refresh_type(
RefreshOptimizeCoinbase),
m_auto_refresh(
true),
m_refresh_from_block_height(0),
m_confirm_missing_payment_id(
true),
m_ask_password(
true),
m_min_output_count(0),
m_min_output_value(0),
m_merge_destinations(
false),
m_confirm_backlog(
true),
m_display_progress_indicator(
false),
m_is_initialized(
false),
m_node_rpc_proxy(
m_http_client,
m_daemon_rpc_mutex) {}
114 static const char*
tr(
const char* str);
117 static void init_options(boost::program_options::options_description& desc_params);
120 static boost::optional<password_container>
password_prompt(
const bool new_password);
137 wallet2(
bool testnet =
false,
bool restricted =
false) :
m_run(
true),
m_callback(0),
m_testnet(
testnet),
m_always_confirm_transfers(
true),
m_print_ring_members(
false),
m_store_tx_info(
true),
m_default_priority(0),
m_refresh_type(
RefreshOptimizeCoinbase),
m_auto_refresh(
true),
m_refresh_from_block_height(0),
m_confirm_missing_payment_id(
true),
m_ask_password(
true),
m_min_output_count(0),
m_min_output_value(0),
m_merge_destinations(
false),
m_confirm_backlog(
true),
m_display_progress_indicator(
false),
m_is_initialized(
false),
m_restricted(
restricted),
is_old_file_format(
false),
m_node_rpc_proxy(
m_http_client,
m_daemon_rpc_mutex) {}
192 std::vector<cryptonote::tx_destination_entry>
m_dests;
204 std::vector<cryptonote::tx_destination_entry>
m_dests;
211 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), m_unlock_time(utd.
m_tx.unlock_time) {}
216 std::vector<cryptonote::tx_source_entry>
sources;
223 std::vector<cryptonote::tx_destination_entry>
dests;
229 FIELD(selected_transfers)
253 std::vector<cryptonote::tx_destination_entry>
dests;
261 FIELD(dust_added_to_fee)
263 FIELD(selected_transfers)
266 FIELD(additional_tx_keys)
268 FIELD(construction_data)
276 std::vector<tx_construction_data>
txes;
282 std::vector<pending_tx>
ptx;
288 crypto::chacha8_iv
iv;
299 crypto::chacha8_iv
iv;
329 bool two_random =
false);
337 void generate(
const std::string& wallet,
const std::string& password,
346 void generate(
const std::string& wallet,
const std::string& password,
354 void rewrite(
const std::string& wallet_name,
const std::string& password);
356 void load(
const std::string& wallet,
const std::string& password);
363 void store_to(
const std::string &
path,
const std::string &password);
365 std::string
path()
const;
383 bool init(std::string daemon_address =
"http://localhost:8080",
384 boost::optional<epee::net_utils::http::login> daemon_login = boost::none, std::string blockchain_db_path =
"", uint64_t upper_transaction_size_limit = 0);
386 void stop() {
m_run.store(
false, std::memory_order_relaxed); }
395 bool get_seed(std::string& electrum_words)
const;
409 void refresh(uint64_t start_height, uint64_t & blocks_fetched);
410 void refresh(uint64_t start_height, uint64_t & blocks_fetched,
bool& received_money);
411 bool refresh(uint64_t & blocks_fetched,
bool& received_money,
bool& ok);
424 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);
426 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);
427 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);
428 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);
430 void transfer_selected(
const std::vector<cryptonote::tx_destination_entry>& dsts,
const std::list<size_t> selected_transfers,
size_t fake_outputs_count,
431 std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
433 void transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts,
const std::list<size_t> selected_transfers,
size_t fake_outputs_count,
434 std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
435 uint64_t unlock_time, uint64_t fee,
const std::vector<uint8_t>& extra,
cryptonote::transaction& tx, pending_tx &ptx);
438 void commit_tx(std::vector<pending_tx>& ptx_vector);
439 bool save_tx(
const std::vector<pending_tx>& ptx_vector,
const std::string &filename);
441 bool sign_tx(
const std::string &unsigned_filename,
const std::string &signed_filename, std::vector<wallet2::pending_tx> &ptx, std::function<
bool(
const unsigned_tx_set&)> accept_func = NULL);
443 bool sign_tx(unsigned_tx_set &exported_txs,
const std::string &signed_filename, std::vector<wallet2::pending_tx> &ptx);
445 bool load_unsigned_tx(
const std::string &unsigned_filename, unsigned_tx_set &exported_txs);
446 bool load_tx(
const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<
bool(
const signed_tx_set&)> accept_func = NULL);
447 std::vector<pending_tx>
create_transactions(std::vector<cryptonote::tx_destination_entry> dsts,
const size_t fake_outs_count,
const uint64_t unlock_time, uint32_t priority,
const std::vector<uint8_t> extra,
bool trusted_daemon);
448 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, uint32_t priority,
const std::vector<uint8_t> extra,
bool trusted_daemon);
450 std::vector<wallet2::pending_tx>
create_transactions_from(
const cryptonote::account_public_address &address, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices,
const size_t fake_outs_count,
const uint64_t unlock_time, uint32_t priority,
const std::vector<uint8_t> extra,
bool trusted_daemon);
455 void get_payments(
const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments, uint64_t min_height = 0)
const;
456 void get_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& payments, uint64_t min_height, uint64_t max_height = (uint64_t)-1)
const;
457 void get_payments_out(std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>>& confirmed_payments,
458 uint64_t min_height, uint64_t max_height = (uint64_t)-1)
const;
459 void get_unconfirmed_payments_out(std::list<std::pair<crypto::hash,wallet2::unconfirmed_transfer_details>>& unconfirmed_payments)
const;
460 void get_unconfirmed_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& unconfirmed_payments)
const;
466 template <
class t_archive>
469 uint64_t dummy_refresh_height = 0;
490 a & dummy_refresh_height;
499 std::unordered_map<crypto::hash, payment_details> m;
501 for (std::unordered_map<crypto::hash, payment_details>::const_iterator i = m.begin(); i != m.end(); ++i)
537 static void wallet_exists(
const std::string& file_path,
bool& keys_file_exists,
bool& wallet_file_exists);
555 uint64_t now =
time(NULL);
556 uint64_t diff =
ts > now ?
ts - now : now -
ts;
558 strftime(buffer,
sizeof(buffer),
"%Y-%m-%d", &tm);
560 strftime(buffer,
sizeof(buffer),
"%I:%M:%S %p", &tm);
561 return std::string(buffer);
628 size_t pop_best_value(std::vector<size_t> &unused_dust_indices,
const std::list<size_t>& selected_transfers,
bool smallest =
false)
const;
633 std::string
sign(
const std::string &data)
const;
636 std::vector<tools::wallet2::transfer_details>
export_outputs()
const;
637 size_t import_outputs(
const std::vector<tools::wallet2::transfer_details> &outputs);
640 std::vector<std::pair<crypto::key_image, crypto::signature>>
export_key_images()
const;
641 uint64_t
import_key_images(
const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, uint64_t &spent, uint64_t &unspent);
642 uint64_t
import_key_images(
const std::string &filename, uint64_t &spent, uint64_t &unspent);
651 std::string
make_uri(
const std::string &address,
const std::string &payment_id, uint64_t
amount,
const std::string &tx_description,
const std::string &recipient_name, std::string &error);
652 bool parse_uri(
const std::string &uri, std::string &address, std::string &payment_id, uint64_t &
amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error);
658 std::vector<std::pair<uint64_t, uint64_t>>
estimate_backlog(uint64_t min_blob_size, uint64_t max_blob_size,
const std::vector<uint64_t> &fees);
676 bool store_keys(
const std::string& keys_file_name,
const std::string& password,
bool watch_only =
false);
682 bool load_keys(
const std::string& keys_file_name,
const std::string& password);
689 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);
690 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);
691 void fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history);
692 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);
693 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);
694 uint64_t
select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::list<size_t>& selected_transfers,
bool trusted_daemon);
714 void get_outs(std::vector<std::vector<get_outs_entry>> &outs,
const std::list<size_t> &selected_transfers,
size_t fake_outputs_count);
717 bool should_pick_a_second_output(
bool use_rct,
size_t n_transfers,
const std::vector<size_t> &unused_transfers_indices,
const std::vector<size_t> &unused_dust_indices)
const;
718 std::vector<size_t>
get_only_rct(
const std::vector<size_t> &unused_dust_indices,
const std::vector<size_t> &unused_transfers_indices)
const;
735 std::unordered_map<crypto::hash, crypto::secret_key>
m_tx_keys;
795 template <
class Archive>
799 template <
class Archive>
825 template <
class Archive>
892 template <
class Archive>
926 if (!
typename Archive::is_saving() && x.
m_change != (uint64_t)-1)
931 template <
class Archive>
953 if (!
typename Archive::is_saving() && x.
m_change != (uint64_t)-1)
961 if (!
typename Archive::is_saving())
968 template <
class Archive>
980 template <
class Archive>
987 template <
class Archive>
995 template <
class Archive>
1002 template <
class Archive>
1009 template <
class Archive>
1022 template <
class Archive>
1047 std::vector<cryptonote::tx_destination_entry>& splitted_dsts, std::vector<cryptonote::tx_destination_entry> &dust_dsts)
1049 splitted_dsts.clear();
1055 [&](uint64_t chunk) { splitted_dsts.push_back(cryptonote::tx_destination_entry(chunk, de.addr)); },
1056 [&](uint64_t a_dust) { splitted_dsts.push_back(cryptonote::tx_destination_entry(a_dust, de.addr)); } );
1060 [&](uint64_t chunk) {
1061 if (chunk <= dust_threshold)
1062 dust_dsts.push_back(cryptonote::tx_destination_entry(chunk, change_dst.addr));
1064 splitted_dsts.push_back(cryptonote::tx_destination_entry(chunk, change_dst.addr));
1066 [&](uint64_t a_dust) { dust_dsts.push_back(cryptonote::tx_destination_entry(a_dust, change_dst.addr)); } );
1071 std::vector<cryptonote::tx_destination_entry>& splitted_dsts, std::vector<cryptonote::tx_destination_entry> &dust_dsts)
1073 splitted_dsts = dsts;
1076 uint64_t change = change_dst.
amount;
1086 std::string indexes;
1093 template<
typename T>
1094 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,
1095 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)
1099 transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, destination_split_strategy, dust_policy, tx, ptx, trusted_daemon);
1102 template<
typename T>
1103 void wallet2::transfer(
const std::vector<cryptonote::tx_destination_entry>& dsts,
size_t fake_outputs_count,
const std::vector<size_t> &unused_transfers_indices,
1111 uint64_t needed_money = fee;
1118 needed_money += dt.amount;
1124 std::list<size_t> selected_transfers;
1125 uint64_t found_money =
select_transfers(needed_money, unused_transfers_indices, selected_transfers, trusted_daemon);
1132 if(fake_outputs_count)
1136 for(
size_t idx: selected_transfers)
1138 const transfer_container::const_iterator it =
m_transfers.begin() + idx;
1140 "m_internal_output_index = " +
std::to_string(it->m_internal_output_index) +
1141 " is greater or equal to outputs count = " +
std::to_string(it->m_tx.vout.size()));
1142 req.
amounts.push_back(it->amount());
1152 "daemon returned wrong response for getrandom_outs.bin, wrong amounts count = " +
1155 std::unordered_map<uint64_t, uint64_t> scanty_outs;
1158 if (amount_outs.
outs.size() < fake_outputs_count)
1160 scanty_outs[amount_outs.
amount] = amount_outs.
outs.size();
1168 std::vector<cryptonote::tx_source_entry> sources;
1169 for(
size_t idx: selected_transfers)
1171 sources.resize(sources.size()+1);
1177 if(daemon_resp.
outs.size())
1179 daemon_resp.
outs[i].outs.sort([](
const out_entry&
a,
const out_entry&
b){
return a.global_amount_index <
b.global_amount_index;});
1180 for(out_entry& daemon_oe: daemon_resp.
outs[i].outs)
1185 oe.first = daemon_oe.global_amount_index;
1189 if(src.
outputs.size() >= fake_outputs_count)
1195 auto it_to_insert = std::find_if(src.
outputs.begin(), src.
outputs.end(), [&](
const tx_output_entry&
a)
1200 tx_output_entry real_oe;
1204 auto interted_it = src.
outputs.insert(it_to_insert, real_oe);
1213 if (needed_money < found_money)
1216 change_dts.
amount = found_money - needed_money;
1219 std::vector<cryptonote::tx_destination_entry> splitted_dsts, dust_dsts;
1221 destination_split_strategy(dsts, change_dts, dust_policy.
dust_threshold, splitted_dsts, dust_dsts);
1222 for(
auto&
d: dust_dsts) {
1226 for(
auto&
d: dust_dsts) {
1237 std::string key_images;
1238 bool all_are_txin_to_key = std::all_of(tx.vin.begin(), tx.vin.end(), [&](
const txin_v& s_e) ->
bool 1249 if (dust_policy.
add_to_fee || dust_sent_elsewhere) change_dts.
amount -= dust;
1253 ptx.
dust = ((dust_policy.
add_to_fee || dust_sent_elsewhere) ? dust : 0);
Definition: binary_utils.h:37
const uint32_t T[512]
Definition: groestl_tables.h:34
crypto::public_key real_out_tx_key
Definition: cryptonote_tx_utils.h:49
Definition: core_rpc_server_commands_defs.h:339
Definition: unordered_containers_boost_serialization.h:38
Definition: core_rpc_server_commands_defs.h:328
Definition: cryptonote_basic.h:437
Definition: cryptonote_protocol_defs.h:110
static const unsigned char iv[64]
Definition: sha512-hash.c:13
POD_CLASS key_derivation
Definition: crypto.h:89
Definition: cryptonote_basic.h:382
size_t get_object_blobsize(const t_object &o)
Definition: cryptonote_format_utils.h:139
void decompose_amount_into_digits(uint64_t amount, uint64_t dust_threshold, const chunk_handler_t &chunk_handler, const dust_handler_t &dust_handler)
Definition: cryptonote_format_utils.h:166
Definition: core_rpc_server_commands_defs.h:321
uint64_t height
Definition: blockchain.cpp:87
#define CORE_RPC_STATUS_BUSY
Definition: core_rpc_server_commands_defs.h:42
static const crypto::hash null_hash
Definition: cryptonote_basic.h:58
Definition: core_rpc_server_commands_defs.h:110
crypto namespace.
Definition: crypto.cpp:47
Definition: block_queue.cpp:41
Definition: cryptonote_basic.h:83
bool rct
Definition: cryptonote_tx_utils.h:53
tools::wallet2::RefreshType refresh_type
Definition: simplewallet.cpp:181
uint64_t amount
Definition: cryptonote_tx_utils.h:52
Definition: MicroCore.h:23
size_t real_output
Definition: cryptonote_tx_utils.h:48
#define CORE_RPC_STATUS_OK
Definition: core_rpc_server_commands_defs.h:41
#define END_SERIALIZE()
self-explanatory
Definition: serialization.h:207
const account_keys & get_keys() const
Definition: account.cpp:127
static const rct::key pk2rct(const crypto::public_key &pk)
Definition: rctTypes.h:428
Definition: cryptonote_basic.h:172
BOOST_CLASS_VERSION(nodetool::node_server< cryptonote::t_cryptonote_protocol_handler< cryptonote::core > >, 1)
std::vector< tx_out > vout
Definition: cryptonote_basic.h:181
Holds cryptonote related classes and helpers.
Definition: db_bdb.cpp:225
Definition: core_rpc_server_commands_defs.h:310
crypto::public_key m_spend_public_key
Definition: cryptonote_basic.h:423
time_t time
Definition: blockchain.cpp:89
uint64_t amount
Definition: core_rpc_server_commands_defs.h:330
declaration and default definition for the functions used the API
std::vector< uint64_t > amounts
Definition: core_rpc_server_commands_defs.h:312
crypto::public_key m_view_public_key
Definition: cryptonote_basic.h:424
uint64_t outs_count
Definition: core_rpc_server_commands_defs.h:313
Definition: cryptonote_tx_utils.h:43
Definition: rctTypes.h:82
#define ts
Definition: skein.c:522
Definition: core_rpc_server_commands_defs.h:80
int b
Definition: base.py:1
Definition: cryptonote_basic.h:130
#define BEGIN_SERIALIZE_OBJECT()
begins the environment of the DSL for described the serialization of an object
Definition: serialization.h:188
crypto::public_key get_tx_pub_key_from_extra(const std::vector< uint8_t > &tx_extra, size_t pk_index)
Definition: cryptonote_format_utils.cpp:246
std::string status
Definition: core_rpc_server_commands_defs.h:342
uint64_t amount
Definition: cryptonote_tx_utils.h:75
type
Definition: json.h:74
#define false
Definition: stdbool.h:38
Definition: core_rpc_server_commands_defs.h:182
POD_CLASS public_key
Definition: crypto.h:65
uint8_t version
Definition: blockchain.cpp:86
account_public_address addr
Definition: cryptonote_tx_utils.h:76
std::string blobdata
Definition: blobdatatype.h:36
#define blocks
Definition: sha512-hash.c:11
account_public_address m_account_address
Definition: account.h:43
POD_CLASS signature
Definition: crypto.h:99
Definition: cryptonote_basic.h:421
key identity()
Definition: rctOps.h:75
POD_CLASS hash8
Definition: hash.h:49
Definition: core_rpc_server_commands_defs.h:172
crypto::public_key key
Definition: cryptonote_basic.h:87
POD_CLASS key_image
Definition: crypto.h:93
POD_CLASS secret_key
Definition: crypto.h:69
#define THROW_WALLET_EXCEPTION_IF(cond, err_type,...)
Definition: wallet_errors.h:742
txout_target_v target
Definition: cryptonote_basic.h:152
size_t real_output_in_tx_index
Definition: cryptonote_tx_utils.h:51
string a
Definition: MakeCryptoOps.py:15
crypto::hash get_transaction_hash(const transaction &t)
Definition: cryptonote_format_utils.cpp:575
std::vector< outs_for_amount > outs
Definition: core_rpc_server_commands_defs.h:341
bool construct_tx_and_get_tx_key(const account_keys &sender_account_keys, const std::vector< tx_source_entry > &sources, const std::vector< tx_destination_entry > &destinations, std::vector< uint8_t > extra, transaction &tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct)
Definition: cryptonote_tx_utils.cpp:157
std::vector< output_entry > outputs
Definition: cryptonote_tx_utils.h:47
Definition: cryptonote_tx_utils.h:73
boost::variant< txin_gen, txin_to_script, txin_to_scripthash, txin_to_key > txin_v
Definition: cryptonote_basic.h:144
POD_CLASS hash
Definition: hash.h:46
std::string to_string(t_connection_type type)
Definition: connection_basic.cpp:96
std::pair< uint64_t, rct::ctkey > output_entry
Definition: cryptonote_tx_utils.h:45
std::string print_money(uint64_t amount, unsigned int decimal_point)
Definition: cryptonote_format_utils.cpp:554
Definition: cryptonote_basic.h:149
std::enable_if< Archive::is_loading::value, void >::type initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
Definition: wallet2.h:800
#define FIELD(f)
tags the field with the variable name and then serializes it
Definition: serialization.h:236
std::list< out_entry > outs
Definition: core_rpc_server_commands_defs.h:331
Definition: core_rpc_server_commands_defs.h:101
Definition: cryptonote_basic.h:198
#define true
Definition: stdbool.h:37
Definition: blockchain.h:80