diff options
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r-- | src/wallet/wallet2.cpp | 226 |
1 files changed, 147 insertions, 79 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5b21cd224..66f1fecbc 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -676,6 +676,7 @@ wallet2::wallet2(network_type nettype, bool restricted): m_segregate_pre_fork_outputs(true), m_key_reuse_mitigation2(true), m_segregation_height(0), + m_ignore_fractional_outputs(true), m_is_initialized(false), m_restricted(restricted), is_old_file_format(false), @@ -950,6 +951,7 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index) } m_subaddress_labels.resize(index.major + 1, {"Untitled account"}); m_subaddress_labels[index.major].resize(index.minor + 1); + get_account_tags(); } else if (m_subaddress_labels[index.major].size() <= index.minor) { @@ -1056,6 +1058,16 @@ void wallet2::check_acc_out_precomp(const tx_out &o, const crypto::key_derivatio tx_scan_info.error = false; } //---------------------------------------------------------------------------------------------------- +void wallet2::check_acc_out_precomp_once(const tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, const is_out_data *is_out_data, tx_scan_info_t &tx_scan_info, bool &already_seen) const +{ + tx_scan_info.received = boost::none; + if (already_seen) + return; + check_acc_out_precomp(o, derivation, additional_derivations, i, is_out_data, tx_scan_info); + if (tx_scan_info.received) + already_seen = true; +} +//---------------------------------------------------------------------------------------------------- static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation &derivation, unsigned int i, rct::key & mask, hw::device &hwdev) { crypto::secret_key scalar1; @@ -1172,6 +1184,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote // Don't try to extract tx public key if tx has no ouputs size_t pk_index = 0; std::vector<tx_scan_info_t> tx_scan_info(tx.vout.size()); + std::deque<bool> output_found(tx.vout.size(), false); while (!tx.vout.empty()) { // if tx.vout is not empty, we loop through all tx pubkeys @@ -1216,16 +1229,19 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote memcpy(&derivation, rct::identity().bytes, sizeof(derivation)); } - // additional tx pubkeys and derivations for multi-destination transfers involving one or more subaddresses - if (find_tx_extra_field_by_type(tx_extra_fields, additional_tx_pub_keys)) + if (pk_index == 1) { - for (size_t i = 0; i < additional_tx_pub_keys.data.size(); ++i) + // additional tx pubkeys and derivations for multi-destination transfers involving one or more subaddresses + if (find_tx_extra_field_by_type(tx_extra_fields, additional_tx_pub_keys)) { - additional_derivations.push_back({}); - if (!hwdev.generate_key_derivation(additional_tx_pub_keys.data[i], keys.m_view_secret_key, additional_derivations.back())) + for (size_t i = 0; i < additional_tx_pub_keys.data.size(); ++i) { - MWARNING("Failed to generate key derivation from additional tx pubkey in " << txid << ", skipping"); - memcpy(&additional_derivations.back(), rct::identity().bytes, sizeof(crypto::key_derivation)); + additional_derivations.push_back({}); + if (!hwdev.generate_key_derivation(additional_tx_pub_keys.data[i], keys.m_view_secret_key, additional_derivations.back())) + { + MWARNING("Failed to generate key derivation from additional tx pubkey in " << txid << ", skipping"); + memcpy(&additional_derivations.back(), rct::identity().bytes, sizeof(crypto::key_derivation)); + } } } } @@ -1236,10 +1252,13 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote error::wallet_internal_error, "pk_index out of range of tx_cache_data"); is_out_data_ptr = &tx_cache_data.primary[pk_index - 1]; derivation = tx_cache_data.primary[pk_index - 1].derivation; - for (size_t n = 0; n < tx_cache_data.additional.size(); ++n) + if (pk_index == 1) { - additional_tx_pub_keys.data.push_back(tx_cache_data.additional[n].pkey); - additional_derivations.push_back(tx_cache_data.additional[n].derivation); + for (size_t n = 0; n < tx_cache_data.additional.size(); ++n) + { + additional_tx_pub_keys.data.push_back(tx_cache_data.additional[n].pkey); + additional_derivations.push_back(tx_cache_data.additional[n].derivation); + } } } @@ -1249,7 +1268,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote } else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase) { - check_acc_out_precomp(tx.vout[0], derivation, additional_derivations, 0, is_out_data_ptr, tx_scan_info[0]); + check_acc_out_precomp_once(tx.vout[0], derivation, additional_derivations, 0, is_out_data_ptr, tx_scan_info[0], output_found[0]); THROW_WALLET_EXCEPTION_IF(tx_scan_info[0].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys()); // this assumes that the miner tx pays a single address @@ -1259,8 +1278,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote // the first one was already checked for (size_t i = 1; i < tx.vout.size(); ++i) { - tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i, - std::cref(is_out_data_ptr), std::ref(tx_scan_info[i])), true); + tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp_once, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i, + std::cref(is_out_data_ptr), std::ref(tx_scan_info[i]), std::ref(output_found[i])), true); } waiter.wait(&tpool); // then scan all outputs from 0 @@ -1282,8 +1301,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote { for (size_t i = 0; i < tx.vout.size(); ++i) { - tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i, - std::cref(is_out_data_ptr), std::ref(tx_scan_info[i])), true); + tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp_once, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i, + std::cref(is_out_data_ptr), std::ref(tx_scan_info[i]), std::ref(output_found[i])), true); } waiter.wait(&tpool); @@ -1304,7 +1323,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote { for (size_t i = 0; i < tx.vout.size(); ++i) { - check_acc_out_precomp(tx.vout[i], derivation, additional_derivations, i, is_out_data_ptr, tx_scan_info[i]); + check_acc_out_precomp_once(tx.vout[i], derivation, additional_derivations, i, is_out_data_ptr, tx_scan_info[i], output_found[i]); THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys()); if (tx_scan_info[i].received) { @@ -1538,6 +1557,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote { // We got a payment ID to go with this tx LOG_PRINT_L2("Found encrypted payment ID: " << payment_id8); + MINFO("Consider using subaddresses instead of encrypted payment IDs"); if (tx_pub_key != null_pkey) { if (!m_account.get_device().decrypt_payment_id(payment_id8, tx_pub_key, m_account.get_keys().m_view_secret_key)) @@ -1561,12 +1581,9 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote else if (get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) { LOG_PRINT_L2("Found unencrypted payment ID: " << payment_id); + MWARNING("Found unencrypted payment ID: these are bad for privacy, consider using subaddresses instead"); } } - else if (get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) - { - LOG_PRINT_L2("Found unencrypted payment ID: " << payment_id); - } for (const auto& i : tx_money_got_in_outs) { @@ -1805,7 +1822,7 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry blocks_added = 0; THROW_WALLET_EXCEPTION_IF(blocks.size() != parsed_blocks.size(), error::wallet_internal_error, "size mismatch"); - THROW_WALLET_EXCEPTION_IF(!m_blockchain.is_in_bounds(current_index), error::wallet_internal_error, "Index out of bounds of hashchain"); + THROW_WALLET_EXCEPTION_IF(!m_blockchain.is_in_bounds(current_index), error::out_of_hashchain_bounds_error); tools::threadpool& tpool = tools::threadpool::getInstance(); tools::threadpool::waiter waiter; @@ -2037,8 +2054,8 @@ void wallet2::update_pool_state(bool refreshed) MDEBUG("update_pool_state start"); // get the pool state - cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request req; - cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response res; + cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request req; + cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response res; m_daemon_rpc_mutex.lock(); bool r = epee::net_utils::invoke_http_json("/get_transaction_pool_hashes.bin", req, res, m_http_client, rpc_timeout); m_daemon_rpc_mutex.unlock(); @@ -2251,12 +2268,12 @@ void wallet2::update_pool_state(bool refreshed) MDEBUG("update_pool_state end"); } //---------------------------------------------------------------------------------------------------- -void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history) +void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, bool force) { std::vector<crypto::hash> hashes; const uint64_t checkpoint_height = m_checkpoints.get_max_height(); - if (stop_height > checkpoint_height && m_blockchain.size()-1 < checkpoint_height) + if ((stop_height > checkpoint_height && m_blockchain.size()-1 < checkpoint_height) && !force) { // we will drop all these, so don't bother getting them uint64_t missing_blocks = m_checkpoints.get_max_height() - m_blockchain.size(); @@ -2421,6 +2438,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo std::vector<cryptonote::block_complete_entry> next_blocks; std::vector<parsed_block> next_parsed_blocks; bool error = false; + added_blocks = 0; if (!first && blocks.empty()) { refreshed = false; @@ -2430,7 +2448,33 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo if (!first) { - process_parsed_blocks(blocks_start_height, blocks, parsed_blocks, added_blocks); + try + { + process_parsed_blocks(blocks_start_height, blocks, parsed_blocks, added_blocks); + } + catch (const tools::error::out_of_hashchain_bounds_error&) + { + MINFO("Daemon claims next refresh block is out of hash chain bounds, resetting hash chain"); + uint64_t stop_height = m_blockchain.offset(); + std::vector<crypto::hash> tip(m_blockchain.size() - m_blockchain.offset()); + for (size_t i = m_blockchain.offset(); i < m_blockchain.size(); ++i) + tip[i - m_blockchain.offset()] = m_blockchain[i]; + cryptonote::block b; + generate_genesis(b); + m_blockchain.clear(); + m_blockchain.push_back(get_block_hash(b)); + short_chain_history.clear(); + get_short_chain_history(short_chain_history); + fast_refresh(stop_height, blocks_start_height, short_chain_history, true); + THROW_WALLET_EXCEPTION_IF(m_blockchain.size() != stop_height, error::wallet_internal_error, "Unexpected hashchain size"); + THROW_WALLET_EXCEPTION_IF(m_blockchain.offset() != 0, error::wallet_internal_error, "Unexpected hashchain offset"); + for (const auto &h: tip) + m_blockchain.push_back(h); + short_chain_history.clear(); + get_short_chain_history(short_chain_history); + start_height = stop_height; + throw std::runtime_error(""); // loop again + } blocks_fetched += added_blocks; } waiter.wait(&tpool); @@ -2460,6 +2504,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo if(try_count < 3) { LOG_PRINT_L1("Another try pull_blocks (try_count=" << try_count << ")..."); + first = true; ++try_count; } else @@ -2636,7 +2681,7 @@ void wallet2::detach_blockchain(uint64_t height) bool wallet2::deinit() { m_is_initialized=false; - m_keys_file_locker.reset(); + unlock_keys_file(); return true; } //---------------------------------------------------------------------------------------------------- @@ -2782,6 +2827,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable value2.SetUint(m_segregation_height); json.AddMember("segregation_height", value2, json.GetAllocator()); + value2.SetInt(m_ignore_fractional_outputs ? 1 : 0); + json.AddMember("ignore_fractional_outputs", value2, json.GetAllocator()); + value2.SetUint(m_subaddress_lookahead_major); json.AddMember("subaddress_lookahead_major", value2, json.GetAllocator()); @@ -2803,12 +2851,12 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable crypto::chacha20(account_data.data(), account_data.size(), key, keys_file_data.iv, &cipher[0]); keys_file_data.account_data = cipher; - m_keys_file_locker.reset(); + unlock_keys_file(); std::string buf; r = ::serialization::dump_binary(keys_file_data, buf); r = r && epee::file_io_utils::save_string_to_file(keys_file_name, buf); //and never touch wallet_keys_file again, only read CHECK_AND_ASSERT_MES(r, false, "failed to generate wallet keys file " << keys_file_name); - m_keys_file_locker.reset(new tools::file_locker(m_keys_file)); + lock_keys_file(); return true; } @@ -2864,6 +2912,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ m_segregate_pre_fork_outputs = true; m_key_reuse_mitigation2 = true; m_segregation_height = 0; + m_ignore_fractional_outputs = true; m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR; m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR; m_key_on_device = false; @@ -2990,6 +3039,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ m_key_reuse_mitigation2 = field_key_reuse_mitigation2; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, segregation_height, int, Uint, false, 0); m_segregation_height = field_segregation_height; + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, ignore_fractional_outputs, int, Int, false, true); + m_ignore_fractional_outputs = field_ignore_fractional_outputs; 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); @@ -3029,9 +3080,13 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ * can be used prior to rewriting wallet keys file, to ensure user has entered the correct password * */ -bool wallet2::verify_password(const epee::wipeable_string& password) const +bool wallet2::verify_password(const epee::wipeable_string& password) { - return verify_password(m_keys_file, password, m_watch_only || m_multisig, m_account.get_device()); + // this temporary unlocking is necessary for Windows (otherwise the file couldn't be loaded). + unlock_keys_file(); + bool r = verify_password(m_keys_file, password, m_watch_only || m_multisig, m_account.get_device()); + lock_keys_file(); + return r; } /*! @@ -3938,17 +3993,17 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass boost::system::error_code e; bool exists = boost::filesystem::exists(m_keys_file, e); THROW_WALLET_EXCEPTION_IF(e || !exists, error::file_not_found, m_keys_file); - m_keys_file_locker.reset(new tools::file_locker(m_keys_file)); - THROW_WALLET_EXCEPTION_IF(!m_keys_file_locker->locked(), error::wallet_internal_error, "internal error: \"" + m_keys_file + "\" is opened by another wallet program"); + lock_keys_file(); + THROW_WALLET_EXCEPTION_IF(!is_keys_file_locked(), error::wallet_internal_error, "internal error: \"" + m_keys_file + "\" is opened by another wallet program"); // this temporary unlocking is necessary for Windows (otherwise the file couldn't be loaded). - m_keys_file_locker.reset(); + unlock_keys_file(); if (!load_keys(m_keys_file, password)) { THROW_WALLET_EXCEPTION_IF(true, error::file_read_error, m_keys_file); } LOG_PRINT_L0("Loaded wallet keys file, with public address: " << m_account.get_public_address_str(m_nettype)); - m_keys_file_locker.reset(new tools::file_locker(m_keys_file)); + lock_keys_file(); //keys loaded ok! //try to load wallet file. but even if we failed, it is not big problem @@ -5047,7 +5102,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_f return false; } - if (!epee::file_io_utils::save_string_to_file(signed_filename, std::string(SIGNED_TX_PREFIX) + ciphertext)) + if (!epee::file_io_utils::save_string_to_file(signed_filename, ciphertext)) { LOG_PRINT_L0("Failed to save file to " << signed_filename); return false; @@ -5600,15 +5655,10 @@ uint32_t wallet2::adjust_priority(uint32_t priority) } // get the current full reward zone - cryptonote::COMMAND_RPC_GET_INFO::request getinfo_req = AUTO_VAL_INIT(getinfo_req); - cryptonote::COMMAND_RPC_GET_INFO::response getinfo_res = AUTO_VAL_INIT(getinfo_res); - m_daemon_rpc_mutex.lock(); - bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", getinfo_req, getinfo_res, m_http_client); - m_daemon_rpc_mutex.unlock(); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info"); - THROW_WALLET_EXCEPTION_IF(getinfo_res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info"); - THROW_WALLET_EXCEPTION_IF(getinfo_res.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error); - const uint64_t full_reward_zone = getinfo_res.block_size_limit / 2; + uint64_t block_size_limit = 0; + const auto result = m_node_rpc_proxy.get_block_size_limit(block_size_limit); + throw_on_rpc_response_error(result, "get_info"); + const uint64_t full_reward_zone = block_size_limit / 2; // get the last N block headers and sum the block sizes const size_t N = 10; @@ -5622,7 +5672,7 @@ uint32_t wallet2::adjust_priority(uint32_t priority) m_daemon_rpc_mutex.lock(); getbh_req.start_height = m_blockchain.size() - N; getbh_req.end_height = m_blockchain.size() - 1; - r = net_utils::invoke_http_json_rpc("/json_rpc", "getblockheadersrange", getbh_req, getbh_res, m_http_client, rpc_timeout); + bool r = net_utils::invoke_http_json_rpc("/json_rpc", "getblockheadersrange", getbh_req, getbh_res, m_http_client, rpc_timeout); m_daemon_rpc_mutex.unlock(); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getblockheadersrange"); THROW_WALLET_EXCEPTION_IF(getbh_res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getblockheadersrange"); @@ -5989,6 +6039,33 @@ bool wallet2::is_output_blackballed(const crypto::public_key &output) const catch (const std::exception &e) { return false; } } +bool wallet2::lock_keys_file() +{ + if (m_keys_file_locker) + { + MDEBUG(m_keys_file << " is already locked."); + return false; + } + m_keys_file_locker.reset(new tools::file_locker(m_keys_file)); + return true; +} + +bool wallet2::unlock_keys_file() +{ + if (!m_keys_file_locker) + { + MDEBUG(m_keys_file << " is already unlocked."); + return false; + } + m_keys_file_locker.reset(); + return true; +} + +bool wallet2::is_keys_file_locked() const +{ + return m_keys_file_locker->locked(); +} + bool wallet2::tx_add_fake_output(std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, uint64_t global_index, const crypto::public_key& output_public_key, const rct::key& mask, uint64_t real_index, bool unlocked) const { if (!unlocked) // don't add locked outs @@ -7758,12 +7835,24 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp for (uint32_t i : subaddr_indices) LOG_PRINT_L2("Candidate subaddress index for spending: " << i); + // determine threshold for fractional amount + const size_t tx_size_one_ring = estimate_tx_size(use_rct, 1, fake_outs_count, 2, 0, bulletproof); + const size_t tx_size_two_rings = estimate_tx_size(use_rct, 2, fake_outs_count, 2, 0, bulletproof); + THROW_WALLET_EXCEPTION_IF(tx_size_one_ring > tx_size_two_rings, error::wallet_internal_error, "Estimated tx size with 1 input is larger than with 2 inputs!"); + const size_t tx_size_per_ring = tx_size_two_rings - tx_size_one_ring; + const uint64_t fractional_threshold = (fee_multiplier * fee_per_kb * tx_size_per_ring) / 1024; + // gather all dust and non-dust outputs belonging to specified subaddresses size_t num_nondust_outputs = 0; size_t num_dust_outputs = 0; for (size_t i = 0; i < m_transfers.size(); ++i) { const transfer_details& td = m_transfers[i]; + if (m_ignore_fractional_outputs && td.amount() < fractional_threshold) + { + MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below threshold " << print_money(fractional_threshold)); + continue; + } if (!td.m_spent && !td.m_key_image_partial && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1) { const uint32_t index_minor = td.m_subaddr_index.minor; @@ -9469,31 +9558,15 @@ uint64_t wallet2::get_daemon_blockchain_height(string &err) const uint64_t wallet2::get_daemon_blockchain_target_height(string &err) { - cryptonote::COMMAND_RPC_GET_INFO::request req_t = AUTO_VAL_INIT(req_t); - cryptonote::COMMAND_RPC_GET_INFO::response resp_t = AUTO_VAL_INIT(resp_t); - m_daemon_rpc_mutex.lock(); - bool ok = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", req_t, resp_t, m_http_client); - m_daemon_rpc_mutex.unlock(); - if (ok) - { - if (resp_t.status == CORE_RPC_STATUS_BUSY) - { - err = "daemon is busy. Please try again later."; - } - else if (resp_t.status != CORE_RPC_STATUS_OK) - { - err = resp_t.status; - } - else // success, cleaning up error message - { - err = ""; - } - } - else + err = ""; + uint64_t target_height = 0; + const auto result = m_node_rpc_proxy.get_target_height(target_height); + if (result && *result != CORE_RPC_STATUS_OK) { - err = "possibly lost connection to daemon"; + err= *result; + return 0; } - return resp_t.target_height; + return target_height; } uint64_t wallet2::get_approximate_blockchain_height() const @@ -9911,7 +9984,7 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag std::unordered_set<crypto::hash> spent_txids; // For each spent key image, search for a tx in m_transfers that uses it as input. std::vector<size_t> swept_transfers; // If such a spending tx wasn't found in m_transfers, this means the spending tx // was created by sweep_all, so we can't know the spent height and other detailed info. - for(size_t i = 0; i < m_transfers.size(); ++i) + for(size_t i = 0; i < signed_key_images.size(); ++i) { transfer_details &td = m_transfers[i]; uint64_t amount = td.amount(); @@ -10851,15 +10924,10 @@ std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(const std:: THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_txpool_backlog"); THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error); - cryptonote::COMMAND_RPC_GET_INFO::request req_t = AUTO_VAL_INIT(req_t); - cryptonote::COMMAND_RPC_GET_INFO::response resp_t = AUTO_VAL_INIT(resp_t); - m_daemon_rpc_mutex.lock(); - r = net_utils::invoke_http_json_rpc("/json_rpc", "get_info", req_t, resp_t, m_http_client); - m_daemon_rpc_mutex.unlock(); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info"); - THROW_WALLET_EXCEPTION_IF(resp_t.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info"); - THROW_WALLET_EXCEPTION_IF(resp_t.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error); - uint64_t full_reward_zone = resp_t.block_size_limit / 2; + uint64_t block_size_limit = 0; + const auto result = m_node_rpc_proxy.get_block_size_limit(block_size_limit); + throw_on_rpc_response_error(result, "get_info"); + uint64_t full_reward_zone = block_size_limit / 2; std::vector<std::pair<uint64_t, uint64_t>> blocks; for (const auto &fee_level: fee_levels) |