aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r--src/wallet/wallet2.cpp200
1 files changed, 122 insertions, 78 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 251475230..39fe4608c 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -243,9 +243,10 @@ struct options {
const command_line::arg_descriptor<std::string> daemon_ssl = {"daemon-ssl", tools::wallet2::tr("Enable SSL on daemon RPC connections: enabled|disabled|autodetect"), "autodetect"};
const command_line::arg_descriptor<std::string> daemon_ssl_private_key = {"daemon-ssl-private-key", tools::wallet2::tr("Path to a PEM format private key"), ""};
const command_line::arg_descriptor<std::string> daemon_ssl_certificate = {"daemon-ssl-certificate", tools::wallet2::tr("Path to a PEM format certificate"), ""};
- const command_line::arg_descriptor<std::vector<std::string>> daemon_ssl_allowed_certificates = {"daemon-ssl-allowed-certificates", tools::wallet2::tr("List of paths to PEM format certificates of allowed RPC servers")};
+ const command_line::arg_descriptor<std::string> daemon_ssl_ca_certificates = {"daemon-ssl-ca-certificates", tools::wallet2::tr("Path to file containing concatenated PEM format certificate(s) to replace system CA(s).")};
const command_line::arg_descriptor<std::vector<std::string>> daemon_ssl_allowed_fingerprints = {"daemon-ssl-allowed-fingerprints", tools::wallet2::tr("List of valid fingerprints of allowed RPC servers")};
const command_line::arg_descriptor<bool> daemon_ssl_allow_any_cert = {"daemon-ssl-allow-any-cert", tools::wallet2::tr("Allow any SSL certificate from the daemon"), false};
+ const command_line::arg_descriptor<bool> daemon_ssl_allow_chained = {"daemon-ssl-allow-chained", tools::wallet2::tr("Allow user (via --daemon-ssl-ca-certificates) chain certificates"), false};
const command_line::arg_descriptor<bool> testnet = {"testnet", tools::wallet2::tr("For testnet. Daemon must also be launched with --testnet flag"), false};
const command_line::arg_descriptor<bool> stagenet = {"stagenet", tools::wallet2::tr("For stagenet. Daemon must also be launched with --stagenet flag"), false};
const command_line::arg_descriptor<std::string, false, true, 2> shared_ringdb_dir = {
@@ -314,6 +315,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
const uint64_t kdf_rounds = command_line::get_arg(vm, opts.kdf_rounds);
THROW_WALLET_EXCEPTION_IF(kdf_rounds == 0, tools::error::wallet_internal_error, "KDF rounds must not be 0");
+ const bool use_proxy = command_line::has_arg(vm, opts.proxy);
auto daemon_address = command_line::get_arg(vm, opts.daemon_address);
auto daemon_host = command_line::get_arg(vm, opts.daemon_host);
auto daemon_port = command_line::get_arg(vm, opts.daemon_port);
@@ -321,13 +323,37 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
auto device_derivation_path = command_line::get_arg(vm, opts.hw_device_derivation_path);
auto daemon_ssl_private_key = command_line::get_arg(vm, opts.daemon_ssl_private_key);
auto daemon_ssl_certificate = command_line::get_arg(vm, opts.daemon_ssl_certificate);
- auto daemon_ssl_allowed_certificates = command_line::get_arg(vm, opts.daemon_ssl_allowed_certificates);
+ auto daemon_ssl_ca_file = command_line::get_arg(vm, opts.daemon_ssl_ca_certificates);
auto daemon_ssl_allowed_fingerprints = command_line::get_arg(vm, opts.daemon_ssl_allowed_fingerprints);
auto daemon_ssl_allow_any_cert = command_line::get_arg(vm, opts.daemon_ssl_allow_any_cert);
auto daemon_ssl = command_line::get_arg(vm, opts.daemon_ssl);
- epee::net_utils::ssl_support_t ssl_support;
- THROW_WALLET_EXCEPTION_IF(!epee::net_utils::ssl_support_from_string(ssl_support, daemon_ssl), tools::error::wallet_internal_error,
- tools::wallet2::tr("Invalid argument for ") + std::string(opts.daemon_ssl.name));
+
+ // user specified CA file or fingeprints implies enabled SSL by default
+ epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_enabled;
+ if (command_line::get_arg(vm, opts.daemon_ssl_allow_any_cert))
+ ssl_options.verification = epee::net_utils::ssl_verification_t::none;
+ else if (!daemon_ssl_ca_file.empty() || !daemon_ssl_allowed_fingerprints.empty())
+ {
+ std::vector<std::vector<uint8_t>> ssl_allowed_fingerprints{ daemon_ssl_allowed_fingerprints.size() };
+ std::transform(daemon_ssl_allowed_fingerprints.begin(), daemon_ssl_allowed_fingerprints.end(), ssl_allowed_fingerprints.begin(), epee::from_hex::vector);
+
+ ssl_options = epee::net_utils::ssl_options_t{
+ std::move(ssl_allowed_fingerprints), std::move(daemon_ssl_ca_file)
+ };
+
+ if (command_line::get_arg(vm, opts.daemon_ssl_allow_chained))
+ ssl_options.verification = epee::net_utils::ssl_verification_t::user_ca;
+ }
+
+ if (ssl_options.verification != epee::net_utils::ssl_verification_t::user_certificates || !command_line::is_arg_defaulted(vm, opts.daemon_ssl))
+ {
+ THROW_WALLET_EXCEPTION_IF(!epee::net_utils::ssl_support_from_string(ssl_options.support, daemon_ssl), tools::error::wallet_internal_error,
+ tools::wallet2::tr("Invalid argument for ") + std::string(opts.daemon_ssl.name));
+ }
+
+ ssl_options.auth = epee::net_utils::ssl_authentication_t{
+ std::move(daemon_ssl_private_key), std::move(daemon_ssl_certificate)
+ };
THROW_WALLET_EXCEPTION_IF(!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port,
tools::error::wallet_internal_error, tools::wallet2::tr("can't specify daemon host or port more than once"));
@@ -357,22 +383,24 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
if (daemon_address.empty())
daemon_address = std::string("http://") + daemon_host + ":" + std::to_string(daemon_port);
- boost::asio::ip::tcp::endpoint proxy{};
- if (command_line::has_arg(vm, opts.proxy))
{
- namespace ip = boost::asio::ip;
const boost::string_ref real_daemon = boost::string_ref{daemon_address}.substr(0, daemon_address.rfind(':'));
- // onion and i2p addresses contain information about the server cert
- // which both authenticates and encrypts
- const bool unencrypted_proxy =
- !real_daemon.ends_with(".onion") && !real_daemon.ends_with(".i2p") &&
- daemon_ssl_allowed_certificates.empty() && daemon_ssl_allowed_fingerprints.empty();
+ const bool verification_required =
+ ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || use_proxy;
+
THROW_WALLET_EXCEPTION_IF(
- unencrypted_proxy,
+ verification_required && !ssl_options.has_strong_verification(real_daemon),
tools::error::wallet_internal_error,
- std::string{"Use of --"} + opts.proxy.name + " requires --" + opts.daemon_ssl_allowed_certificates.name + " or --" + opts.daemon_ssl_allowed_fingerprints.name + " or use of a .onion/.i2p domain"
+ tools::wallet2::tr("Enabling --") + std::string{use_proxy ? opts.proxy.name : opts.daemon_ssl.name} + tools::wallet2::tr(" requires --") +
+ opts.daemon_ssl_ca_certificates.name + tools::wallet2::tr(" or --") + opts.daemon_ssl_allowed_fingerprints.name + tools::wallet2::tr(" or use of a .onion/.i2p domain")
);
+ }
+
+ boost::asio::ip::tcp::endpoint proxy{};
+ if (use_proxy)
+ {
+ namespace ip = boost::asio::ip;
const auto proxy_address = command_line::get_arg(vm, opts.proxy);
@@ -416,22 +444,8 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
catch (const std::exception &e) { }
}
- std::list<std::string> ssl_allowed_certificates;
- for (const std::string &path: daemon_ssl_allowed_certificates)
- {
- ssl_allowed_certificates.push_back({});
- if (!epee::file_io_utils::load_file_to_string(path, ssl_allowed_certificates.back()))
- {
- MERROR("Failed to load certificate: " << path);
- ssl_allowed_certificates.back() = std::string();
- }
- }
-
- std::vector<std::vector<uint8_t>> ssl_allowed_fingerprints{ daemon_ssl_allowed_fingerprints.size() };
- std::transform(daemon_ssl_allowed_fingerprints.begin(), daemon_ssl_allowed_fingerprints.end(), ssl_allowed_fingerprints.begin(), epee::from_hex::vector);
-
std::unique_ptr<tools::wallet2> wallet(new tools::wallet2(nettype, kdf_rounds, unattended));
- wallet->init(std::move(daemon_address), std::move(login), std::move(proxy), 0, *trusted_daemon, ssl_support, std::make_pair(daemon_ssl_private_key, daemon_ssl_certificate), ssl_allowed_certificates, ssl_allowed_fingerprints, daemon_ssl_allow_any_cert);
+ wallet->init(std::move(daemon_address), std::move(login), std::move(proxy), 0, *trusted_daemon, std::move(ssl_options));
boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir);
wallet->set_ring_database(ringdb_path.string());
wallet->get_message_store().set_options(vm);
@@ -1032,6 +1046,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended):
m_segregation_height(0),
m_ignore_fractional_outputs(true),
m_track_uses(false),
+ m_setup_background_mining(BackgroundMiningMaybe),
m_is_initialized(false),
m_kdf_rounds(kdf_rounds),
is_old_file_format(false),
@@ -1100,9 +1115,10 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
command_line::add_arg(desc_params, opts.daemon_ssl);
command_line::add_arg(desc_params, opts.daemon_ssl_private_key);
command_line::add_arg(desc_params, opts.daemon_ssl_certificate);
- command_line::add_arg(desc_params, opts.daemon_ssl_allowed_certificates);
+ command_line::add_arg(desc_params, opts.daemon_ssl_ca_certificates);
command_line::add_arg(desc_params, opts.daemon_ssl_allowed_fingerprints);
command_line::add_arg(desc_params, opts.daemon_ssl_allow_any_cert);
+ command_line::add_arg(desc_params, opts.daemon_ssl_allow_chained);
command_line::add_arg(desc_params, opts.testnet);
command_line::add_arg(desc_params, opts.stagenet);
command_line::add_arg(desc_params, opts.shared_ringdb_dir);
@@ -1154,21 +1170,26 @@ std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::varia
}
//----------------------------------------------------------------------------------------------------
-bool wallet2::init(std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, boost::asio::ip::tcp::endpoint proxy, uint64_t upper_transaction_weight_limit, bool trusted_daemon, epee::net_utils::ssl_support_t ssl_support, const std::pair<std::string, std::string> &private_key_and_certificate_path, const std::list<std::string> &allowed_certificates, const std::vector<std::vector<uint8_t>> &allowed_fingerprints, bool allow_any_cert)
+bool wallet2::set_daemon(std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, bool trusted_daemon, epee::net_utils::ssl_options_t ssl_options)
{
- m_checkpoints.init_default_checkpoints(m_nettype);
if(m_http_client.is_connected())
m_http_client.disconnect();
- m_is_initialized = true;
- m_upper_transaction_weight_limit = upper_transaction_weight_limit;
m_daemon_address = std::move(daemon_address);
m_daemon_login = std::move(daemon_login);
m_trusted_daemon = trusted_daemon;
+
+ MINFO("setting daemon to " << get_daemon_address());
+ return m_http_client.set_server(get_daemon_address(), get_daemon_login(), std::move(ssl_options));
+}
+//----------------------------------------------------------------------------------------------------
+bool wallet2::init(std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, boost::asio::ip::tcp::endpoint proxy, uint64_t upper_transaction_weight_limit, bool trusted_daemon, epee::net_utils::ssl_options_t ssl_options)
+{
+ m_checkpoints.init_default_checkpoints(m_nettype);
+ m_is_initialized = true;
+ m_upper_transaction_weight_limit = upper_transaction_weight_limit;
if (proxy != boost::asio::ip::tcp::endpoint{})
m_http_client.set_connector(net::socks::connector{std::move(proxy)});
-
- // When switching from light wallet to full wallet, we need to reset the height we got from lw node.
- return m_http_client.set_server(get_daemon_address(), get_daemon_login(), ssl_support, private_key_and_certificate_path, allowed_certificates, allowed_fingerprints, allow_any_cert);
+ return set_daemon(daemon_address, daemon_login, trusted_daemon, std::move(ssl_options));
}
//----------------------------------------------------------------------------------------------------
bool wallet2::is_deterministic() const
@@ -2267,6 +2288,12 @@ void wallet2::process_outgoing(const crypto::hash &txid, const cryptonote::trans
add_rings(tx);
}
//----------------------------------------------------------------------------------------------------
+bool wallet2::should_skip_block(const cryptonote::block &b, uint64_t height) const
+{
+ // seeking only for blocks that are not older then the wallet creation time plus 1 day. 1 day is for possible user incorrect time setup
+ return !(b.timestamp + 60*60*24 > m_account.get_createtime() && height >= m_refresh_from_block_height);
+}
+//----------------------------------------------------------------------------------------------------
void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const parsed_block &parsed_block, const crypto::hash& bl_id, uint64_t height, const std::vector<tx_cache_data> &tx_cache_data, size_t tx_cache_data_offset, std::map<std::pair<uint64_t, uint64_t>, size_t> *output_tracker_cache)
{
THROW_WALLET_EXCEPTION_IF(bche.txs.size() + 1 != parsed_block.o_indices.indices.size(), error::wallet_internal_error,
@@ -2276,7 +2303,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry
//handle transactions from new block
//optimization: seeking only for blocks that are not older then the wallet creation time plus 1 day. 1 day is for possible user incorrect time setup
- if(b.timestamp + 60*60*24 > m_account.get_createtime() && height >= m_refresh_from_block_height)
+ if (!should_skip_block(b, height))
{
TIME_MEASURE_START(miner_tx_handle_time);
if (m_refresh_type != RefreshNoCoinbase)
@@ -2340,9 +2367,7 @@ void wallet2::get_short_chain_history(std::list<crypto::hash>& ids, uint64_t gra
//----------------------------------------------------------------------------------------------------
void wallet2::parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const
{
- error = !cryptonote::parse_and_validate_block_from_blob(blob, bl);
- if (!error)
- bl_id = get_block_hash(bl);
+ error = !cryptonote::parse_and_validate_block_from_blob(blob, bl, bl_id);
}
//----------------------------------------------------------------------------------------------------
void wallet2::pull_blocks(uint64_t start_height, uint64_t &blocks_start_height, const std::list<crypto::hash> &short_chain_history, std::vector<cryptonote::block_complete_entry> &blocks, std::vector<cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> &o_indices)
@@ -2408,6 +2433,11 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
{
THROW_WALLET_EXCEPTION_IF(parsed_blocks[i].txes.size() != parsed_blocks[i].block.tx_hashes.size(),
error::wallet_internal_error, "Mismatched parsed_blocks[i].txes.size() and parsed_blocks[i].block.tx_hashes.size()");
+ if (should_skip_block(parsed_blocks[i].block, start_height + i))
+ {
+ txidx += 1 + parsed_blocks[i].block.tx_hashes.size();
+ continue;
+ }
if (m_refresh_type != RefreshNoCoinbase)
tpool.submit(&waiter, [&, i, txidx](){ cache_tx_data(parsed_blocks[i].block.miner_tx, get_transaction_hash(parsed_blocks[i].block.miner_tx), tx_cache_data[txidx]); });
++txidx;
@@ -2436,6 +2466,8 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
for (size_t i = 0; i < tx_cache_data.size(); ++i)
{
+ if (tx_cache_data[i].empty())
+ continue;
tpool.submit(&waiter, [&hwdev, &gender, &tx_cache_data, i]() {
auto &slot = tx_cache_data[i];
boost::unique_lock<hw::device> hwdev_lock(hwdev);
@@ -2454,6 +2486,7 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
if (o.target.type() == typeid(cryptonote::txout_to_key))
{
std::vector<crypto::key_derivation> additional_derivations;
+ additional_derivations.reserve(tx_cache_data[txidx].additional.size());
for (const auto &iod: tx_cache_data[txidx].additional)
additional_derivations.push_back(iod.derivation);
const auto &key = boost::get<txout_to_key>(o.target).key;
@@ -2471,6 +2504,12 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
txidx = 0;
for (size_t i = 0; i < blocks.size(); ++i)
{
+ if (should_skip_block(parsed_blocks[i].block, start_height + i))
+ {
+ txidx += 1 + parsed_blocks[i].block.tx_hashes.size();
+ continue;
+ }
+
if (m_refresh_type != RefreshType::RefreshNoCoinbase)
{
THROW_WALLET_EXCEPTION_IF(txidx >= tx_cache_data.size(), error::wallet_internal_error, "txidx out of range");
@@ -3514,6 +3553,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
value2.SetInt(m_track_uses ? 1 : 0);
json.AddMember("track_uses", value2, json.GetAllocator());
+ value2.SetInt(m_setup_background_mining);
+ json.AddMember("setup_background_mining", value2, json.GetAllocator());
+
value2.SetUint(m_subaddress_lookahead_major);
json.AddMember("subaddress_lookahead_major", value2, json.GetAllocator());
@@ -3643,13 +3685,16 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
m_multisig_derivations.clear();
m_always_confirm_transfers = false;
m_print_ring_members = false;
+ m_store_tx_info = true;
m_default_mixin = 0;
m_default_priority = 0;
m_auto_refresh = true;
m_refresh_type = RefreshType::RefreshDefault;
+ m_refresh_from_block_height = 0;
m_confirm_missing_payment_id = true;
m_confirm_non_default_ring_size = true;
m_ask_password = AskPasswordToDecrypt;
+ cryptonote::set_default_decimal_point(CRYPTONOTE_DISPLAY_DECIMAL_POINT);
m_min_output_count = 0;
m_min_output_value = 0;
m_merge_destinations = false;
@@ -3662,6 +3707,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
m_segregation_height = 0;
m_ignore_fractional_outputs = true;
m_track_uses = false;
+ m_setup_background_mining = BackgroundMiningMaybe;
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
m_original_keys_available = false;
@@ -3816,6 +3862,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
m_ignore_fractional_outputs = field_ignore_fractional_outputs;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, track_uses, int, Int, false, false);
m_track_uses = field_track_uses;
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, setup_background_mining, BackgroundMiningSetupType, Int, false, BackgroundMiningMaybe);
+ m_setup_background_mining = field_setup_background_mining;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_major, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MAJOR);
m_subaddress_lookahead_major = field_subaddress_lookahead_major;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_minor, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MINOR);
@@ -4117,6 +4165,17 @@ bool wallet2::query_device(hw::device::device_type& device_type, const std::stri
return true;
}
+void wallet2::init_type(hw::device::device_type device_type)
+{
+ m_account_public_address = m_account.get_keys().m_account_address;
+ m_watch_only = false;
+ m_multisig = false;
+ m_multisig_threshold = 0;
+ m_multisig_signers.clear();
+ m_original_keys_available = false;
+ m_key_device_type = device_type;
+}
+
/*!
* \brief Generates a wallet or restores one.
* \param wallet_ Name of wallet file
@@ -4186,18 +4245,15 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
m_account.make_multisig(view_secret_key, spend_secret_key, spend_public_key, multisig_keys);
m_account.finalize_multisig(spend_public_key);
- m_account_public_address = m_account.get_keys().m_account_address;
- m_watch_only = false;
+ // Not possible to restore a multisig wallet that is able to activate the MMS
+ // (because the original keys are not (yet) part of the restore info), so
+ // keep m_original_keys_available to false
+ init_type(hw::device::device_type::SOFTWARE);
m_multisig = true;
m_multisig_threshold = threshold;
m_multisig_signers = multisig_signers;
- m_key_device_type = hw::device::device_type::SOFTWARE;
setup_keys(password);
- // Not possible to restore a multisig wallet that is able to activate the MMS
- // (because the original keys are not (yet) part of the restore info)
- m_original_keys_available = false;
-
create_keys_file(wallet_, false, password, m_nettype != MAINNET || create_address_file);
setup_new_blockchain();
@@ -4230,13 +4286,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
crypto::secret_key retval = m_account.generate(recovery_param, recover, two_random);
- m_account_public_address = m_account.get_keys().m_account_address;
- m_watch_only = false;
- m_multisig = false;
- m_multisig_threshold = 0;
- m_multisig_signers.clear();
- m_original_keys_available = false;
- m_key_device_type = hw::device::device_type::SOFTWARE;
+ init_type(hw::device::device_type::SOFTWARE);
setup_keys(password);
// calculate a starting refresh height
@@ -4319,13 +4369,9 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
}
m_account.create_from_viewkey(account_public_address, viewkey);
- m_account_public_address = account_public_address;
+ init_type(hw::device::device_type::SOFTWARE);
m_watch_only = true;
- m_multisig = false;
- m_multisig_threshold = 0;
- m_multisig_signers.clear();
- m_original_keys_available = false;
- m_key_device_type = hw::device::device_type::SOFTWARE;
+ m_account_public_address = account_public_address;
setup_keys(password);
create_keys_file(wallet_, true, password, m_nettype != MAINNET || create_address_file);
@@ -4360,13 +4406,8 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
}
m_account.create_from_keys(account_public_address, spendkey, viewkey);
+ init_type(hw::device::device_type::SOFTWARE);
m_account_public_address = account_public_address;
- m_watch_only = false;
- m_multisig = false;
- m_multisig_threshold = 0;
- m_multisig_signers.clear();
- m_original_keys_available = false;
- m_key_device_type = hw::device::device_type::SOFTWARE;
setup_keys(password);
create_keys_file(wallet_, false, password, create_address_file);
@@ -4401,13 +4442,7 @@ void wallet2::restore(const std::string& wallet_, const epee::wipeable_string& p
hwdev.set_callback(get_device_callback());
m_account.create_from_device(hwdev);
- m_key_device_type = m_account.get_device().get_type();
- m_account_public_address = m_account.get_keys().m_account_address;
- m_watch_only = false;
- m_multisig = false;
- m_multisig_threshold = 0;
- m_multisig_signers.clear();
- m_original_keys_available = false;
+ init_type(m_account.get_device().get_type());
setup_keys(password);
m_device_name = device_name;
@@ -4539,10 +4574,9 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
"Failed to create multisig wallet due to bad keys");
memwipe(&spend_skey, sizeof(rct::key));
- m_account_public_address = m_account.get_keys().m_account_address;
- m_watch_only = false;
+ init_type(hw::device::device_type::SOFTWARE);
+ m_original_keys_available = true;
m_multisig = true;
- m_key_device_type = hw::device::device_type::SOFTWARE;
m_multisig_threshold = threshold;
m_multisig_signers = multisig_signers;
++m_multisig_rounds_passed;
@@ -12973,4 +13007,14 @@ void wallet2::finish_rescan_bc_keep_key_images(uint64_t transfer_height, const c
m_transfers[it->second].m_key_image_known = true;
}
}
+//----------------------------------------------------------------------------------------------------
+uint64_t wallet2::get_bytes_sent() const
+{
+ return m_http_client.get_bytes_sent();
+}
+//----------------------------------------------------------------------------------------------------
+uint64_t wallet2::get_bytes_received() const
+{
+ return m_http_client.get_bytes_received();
+}
}