diff --git a/CMakeLists.txt b/CMakeLists.txt index b1297e716..287f93bd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -452,9 +452,12 @@ link_directories(${LIBUNWIND_LIBRARY_DIRS}) # Final setup for libpcsc if (PCSC_FOUND) + message(STATUS "Using PCSC include dir at ${PCSC_INCLUDE_DIR}") add_definitions(-DHAVE_PCSC) include_directories(${PCSC_INCLUDE_DIR}) link_directories(${LIBPCSC_LIBRARY_DIRS}) +else (PCSC_FOUND) + message(STATUS "Could not find PCSC") endif() if(MSVC) diff --git a/cmake/FindPCSC.cmake b/cmake/FindPCSC.cmake index 8dd9d0e76..8332abc49 100644 --- a/cmake/FindPCSC.cmake +++ b/cmake/FindPCSC.cmake @@ -18,6 +18,9 @@ ENDIF (NOT WIN32) FIND_PATH(PCSC_INCLUDE_DIR winscard.h HINTS + IF (WIN32) + ${MSYS2_FOLDER}/mingw64/x86_64-w64-mingw32/include + ENDIF (WIN32) /usr/include/PCSC ${PC_PCSC_INCLUDEDIR} ${PC_PCSC_INCLUDE_DIRS} @@ -26,6 +29,9 @@ FIND_PATH(PCSC_INCLUDE_DIR winscard.h FIND_LIBRARY(PCSC_LIBRARY NAMES pcsclite libpcsclite WinSCard PCSC HINTS + IF (WIN32) + ${MSYS2_FOLDER}/mingw64/x86_64-w64-mingw32/lib + ENDIF (WIN32) ${PC_PCSC_LIBDIR} ${PC_PCSC_LIBRARY_DIRS} ) diff --git a/cmake/Version.cmake b/cmake/Version.cmake index 439c4c5ae..3677e80d7 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -28,7 +28,7 @@ function (write_static_version_header hash) set(VERSIONTAG "${hash}") - configure_file("src/version.cpp.in" "version.cpp") + configure_file("${CMAKE_SOURCE_DIR}/src/version.cpp.in" "${CMAKE_BINARY_DIR}/version.cpp") endfunction () find_package(Git QUIET) diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h index 7a120931a..2b3ed8043 100644 --- a/src/crypto/chacha.h +++ b/src/crypto/chacha.h @@ -73,14 +73,14 @@ namespace crypto { static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); tools::scrubbed_arr pwd_hash; crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/); - memcpy(&key, pwd_hash.data(), sizeof(key)); + memcpy(&unwrap(key), pwd_hash.data(), sizeof(key)); } inline void generate_chacha_key_prehashed(const void *data, size_t size, chacha_key& key) { static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); tools::scrubbed_arr pwd_hash; crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/); - memcpy(&key, pwd_hash.data(), sizeof(key)); + memcpy(&unwrap(key), pwd_hash.data(), sizeof(key)); } inline void generate_chacha_key(std::string password, chacha_key& key) { diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index 494027560..ba0149240 100644 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -124,9 +124,9 @@ namespace crypto { random_scalar(rng); } sec = rng; - sc_reduce32(&sec); // reduce in case second round of keys (sendkeys) + sc_reduce32(&unwrap(sec)); // reduce in case second round of keys (sendkeys) - ge_scalarmult_base(&point, &sec); + ge_scalarmult_base(&point, &unwrap(sec)); ge_p3_tobytes(&pub, &point); return rng; @@ -139,10 +139,10 @@ namespace crypto { bool crypto_ops::secret_key_to_public_key(const secret_key &sec, public_key &pub) { ge_p3 point; - if (sc_check(&sec) != 0) { + if (sc_check(&unwrap(sec)) != 0) { return false; } - ge_scalarmult_base(&point, &sec); + ge_scalarmult_base(&point, &unwrap(sec)); ge_p3_tobytes(&pub, &point); return true; } @@ -155,7 +155,7 @@ namespace crypto { if (ge_frombytes_vartime(&point, &key1) != 0) { return false; } - ge_scalarmult(&point2, &key2, &point); + ge_scalarmult(&point2, &unwrap(key2), &point); ge_mul8(&point3, &point2); ge_p1p1_to_p2(&point2, &point3); ge_tobytes(&derivation, &point2); @@ -199,7 +199,7 @@ namespace crypto { ec_scalar scalar; assert(sc_check(&base) == 0); derivation_to_scalar(derivation, output_index, scalar); - sc_add(&derived_key, &base, &scalar); + sc_add(&unwrap(derived_key), &unwrap(base), &scalar); } bool crypto_ops::derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &derived_key) { @@ -254,7 +254,7 @@ namespace crypto { ge_scalarmult_base(&tmp3, &k); ge_p3_tobytes(&buf.comm, &tmp3); hash_to_scalar(&buf, sizeof(s_comm), sig.c); - sc_mulsub(&sig.r, &sig.c, &sec, &k); + sc_mulsub(&sig.r, &sig.c, &unwrap(sec), &k); } bool crypto_ops::check_signature(const hash &prefix_hash, const public_key &pub, const signature &sig) { @@ -347,7 +347,7 @@ namespace crypto { hash_to_scalar(&buf, sizeof(buf), sig.c); // sig.r = k - sig.c*r - sc_mulsub(&sig.r, &sig.c, &r, &k); + sc_mulsub(&sig.r, &sig.c, &unwrap(r), &k); } bool crypto_ops::check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional &B, const public_key &D, const signature &sig) { @@ -451,7 +451,7 @@ namespace crypto { ge_p2 point2; assert(sc_check(&sec) == 0); hash_to_ec(pub, point); - ge_scalarmult(&point2, &sec, &point); + ge_scalarmult(&point2, &unwrap(sec), &point); ge_tobytes(&image, &point2); } @@ -530,7 +530,7 @@ POP_WARNINGS } hash_to_scalar(buf.get(), rs_comm_size(pubs_count), h); sc_sub(&sig[sec_index].c, &h, &sum); - sc_mulsub(&sig[sec_index].r, &sig[sec_index].c, &sec, &k); + sc_mulsub(&sig[sec_index].r, &sig[sec_index].c, &unwrap(sec), &k); } bool crypto_ops::check_ring_signature(const hash &prefix_hash, const key_image &image, diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index feea259cb..b73a90c0f 100755 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -415,6 +415,53 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline MINFO("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block()); m_db->block_txn_stop(); + uint64_t num_popped_blocks = 0; + while (true) + { + const uint64_t top_height = m_db->height() - 1; + const crypto::hash top_id = m_db->top_block_hash(); + const block top_block = m_db->get_top_block(); + const uint8_t ideal_hf_version = get_ideal_hard_fork_version(top_height); + if (ideal_hf_version <= 1 || ideal_hf_version == top_block.major_version) + { + if (num_popped_blocks > 0) + MGINFO("Initial popping done, top block: " << top_id << ", top height: " << top_height << ", block version: " << (uint64_t)top_block.major_version); + break; + } + else + { + if (num_popped_blocks == 0) + MGINFO("Current top block " << top_id << " at height " << top_height << " has version " << (uint64_t)top_block.major_version << " which disagrees with the ideal version " << (uint64_t)ideal_hf_version); + if (num_popped_blocks % 100 == 0) + MGINFO("Popping blocks... " << top_height); + ++num_popped_blocks; + block popped_block; + std::vector popped_txs; + try + { + m_db->pop_block(popped_block, popped_txs); + } + // anything that could cause this to throw is likely catastrophic, + // so we re-throw + catch (const std::exception& e) + { + MERROR("Error popping block from blockchain: " << e.what()); + throw; + } + catch (...) + { + MERROR("Error popping block from blockchain, throwing!"); + throw; + } + } + } + if (num_popped_blocks > 0) + { + m_timestamps_and_difficulties_height = 0; + m_hardfork->reorganize_from_chain_height(get_current_blockchain_height()); + m_tx_pool.on_blockchain_dec(m_db->height()-1, get_tail_id()); + } + update_next_cumulative_size_limit(); return true; } diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index c2252fcc7..04a10044f 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -195,7 +195,7 @@ namespace cryptonote return addr.m_view_public_key; } //--------------------------------------------------------------- - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct, bool bulletproof, rct::multisig_out *msout) + bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct, bool bulletproof, rct::multisig_out *msout, bool shuffle_outs) { hw::device &hwdev = sender_account_keys.get_device(); @@ -600,7 +600,7 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct, bool bulletproof, rct::multisig_out *msout) + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct, bool bulletproof, rct::multisig_out *msout) { hw::device &hwdev = sender_account_keys.get_device(); hwdev.open_tx(tx_key); @@ -629,7 +629,8 @@ namespace cryptonote subaddresses[sender_account_keys.m_account_address.m_spend_public_key] = {0,0}; crypto::secret_key tx_key; std::vector additional_tx_keys; - return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, false, NULL); + std::vector destinations_copy = destinations; + return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, false, NULL); } //--------------------------------------------------------------- bool generate_genesis_block( diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index 1c390078d..a5d149fca 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -90,8 +90,8 @@ namespace cryptonote //--------------------------------------------------------------- crypto::public_key get_destination_view_key_pub(const std::vector &destinations, const boost::optional& change_addr); bool construct_tx(const account_keys& sender_account_keys, std::vector &sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time); - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct = false, bool bulletproof = false, rct::multisig_out *msout = NULL); - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct = false, bool bulletproof = false, rct::multisig_out *msout = NULL); + bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct = false, bool bulletproof = false, rct::multisig_out *msout = NULL, bool shuffle_outs = true); + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, std::vector extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct = false, bool bulletproof = false, rct::multisig_out *msout = NULL); bool generate_genesis_block( block& bl diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 64ce3a406..2efb501ea 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -720,6 +720,7 @@ bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash, req.txs_hashes.push_back(epee::string_tools::pod_to_hex(transaction_hash)); req.decode_as_json = false; + req.prune = false; if (m_is_rpc) { if (!m_rpc_client->rpc_request(req, res, "/gettransactions", fail_message.c_str())) diff --git a/src/device/device.hpp b/src/device/device.hpp index 9df0cb39d..ce20c9165 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -204,4 +204,3 @@ namespace hw { device& get_device(const std::string device_descriptor) ; } - diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index 3b9ab6744..aedaf8382 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -48,6 +48,15 @@ namespace hw { /* ===================================================================== */ /* === Debug ==== */ /* ===================================================================== */ + #ifdef WIN32 + static char *pcsc_stringify_error(LONG rv) { + static __thread char out[20]; + sprintf_s(out, sizeof(out), "0x%08lX", rv); + + return out; + } + #endif + void set_apdu_verbose(bool verbose) { apdu_verbose = verbose; } diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index f1fcaab87..b62bdf959 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -33,8 +33,13 @@ #include #include #include "device.hpp" +#ifdef WIN32 +#include +#define MAX_ATR_SIZE 33 +#else #include #include +#endif #include #include diff --git a/src/device/log.cpp b/src/device/log.cpp index cbbcfc953..e581cb4cd 100644 --- a/src/device/log.cpp +++ b/src/device/log.cpp @@ -1,3 +1,4 @@ + // Copyright (c) 2017-2018, The Monero Project // // All rights reserved. diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index b6f51883c..48f39b2d3 100755 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -3089,6 +3089,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) if (!m_trusted_daemon) message_writer() << (boost::format(tr("Warning: using an untrusted daemon at %s, privacy will be lessened")) % m_wallet->get_daemon_address()).str(); + if (m_wallet->get_ring_database().empty()) + fail_msg_writer() << tr("Failed to initialize ring database: privacy enhancing features will be inactive"); + m_wallet->callback(this); return true; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index fc78f0475..6be898295 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -305,14 +305,14 @@ uint64_t Wallet::maximumAllowedAmount() return std::numeric_limits::max(); } -void Wallet::init(const char *argv0, const char *default_log_base_name) { +void Wallet::init(const char *argv0, const char *default_log_base_name, const std::string &log_path, bool console) { #ifdef WIN32 // Activate UTF-8 support for Boost filesystem classes on Windows std::locale::global(boost::locale::generator().generate("")); boost::filesystem::path::imbue(std::locale()); #endif epee::string_tools::set_module_name_and_folder(argv0); - mlog_configure(mlog_get_default_log_path(default_log_base_name), true); + mlog_configure(log_path.empty() ? mlog_get_default_log_path(default_log_base_name) : log_path.c_str(), console); } void Wallet::debug(const std::string &category, const std::string &str) { diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 617b6035a..4fbc7298a 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -556,7 +556,8 @@ struct Wallet } static uint64_t maximumAllowedAmount(); // Easylogger wrapper - static void init(const char *argv0, const char *default_log_base_name); + static void init(const char *argv0, const char *default_log_base_name) { init(argv0, default_log_base_name, "", true); } + static void init(const char *argv0, const char *default_log_base_name, const std::string &log_path, bool console); static void debug(const std::string &category, const std::string &str); static void info(const std::string &category, const std::string &str); static void warning(const std::string &category, const std::string &str); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9d10809e8..b28539c18 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1007,7 +1007,7 @@ void wallet2::set_unspent(size_t idx) void wallet2::check_acc_out_precomp(const tx_out &o, const crypto::key_derivation &derivation, const std::vector &additional_derivations, size_t i, tx_scan_info_t &tx_scan_info) const { hw::device &hwdev = m_account.get_device(); - boost::unique_lock hwdev_lock (hwdev); + std::unique_lock hwdev_lock (hwdev); hwdev.set_mode(hw::device::TRANSACTION_PARSE); if (o.target.type() != typeid(txout_to_key)) { @@ -1085,7 +1085,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote //ensure device is let in NONE mode in any case hw::device &hwdev = m_account.get_device(); - boost::unique_lock hwdev_lock (hwdev); + std::unique_lock hwdev_lock (hwdev); hw::reset_mode rst(hwdev); hwdev_lock.unlock(); @@ -1180,7 +1180,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote 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) { - hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys, derivation, additional_derivations); + hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, tx_scan_info[i].received->derivation); scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs); } } @@ -1203,7 +1203,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote 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) { - hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys, derivation, additional_derivations); + hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, tx_scan_info[i].received->derivation); scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs); } } @@ -1219,7 +1219,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote { hwdev_lock.lock(); hwdev.set_mode(hw::device::NONE); - hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys, derivation, additional_derivations); + hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, tx_scan_info[i].received->derivation); scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs); hwdev_lock.unlock(); } @@ -2698,8 +2698,6 @@ 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_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR; - m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR; m_key_on_device = false; } else if(json.IsObject()) @@ -2820,10 +2818,6 @@ 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, 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); - m_subaddress_lookahead_minor = field_subaddress_lookahead_minor; } else { @@ -5141,7 +5135,7 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector wallet2::create_transactions(std::vectoradd_rings(key, tx); } catch (const std::exception &e) { return false; } } @@ -5526,7 +5532,8 @@ bool wallet2::add_rings(const cryptonote::transaction_prefix &tx) { crypto::chacha_key key; generate_chacha_key_from_secret_keys(key); - return add_rings(key, tx); + try { return add_rings(key, tx); } + catch (const std::exception &e) { return false; } } bool wallet2::remove_rings(const cryptonote::transaction_prefix &tx) @@ -5535,13 +5542,14 @@ bool wallet2::remove_rings(const cryptonote::transaction_prefix &tx) return false; crypto::chacha_key key; generate_chacha_key_from_secret_keys(key); - return m_ringdb->remove_rings(key, tx); + try { return m_ringdb->remove_rings(key, tx); } + catch (const std::exception &e) { return false; } } bool wallet2::get_ring(const crypto::chacha_key &key, const crypto::key_image &key_image, std::vector &outs) { if (!m_ringdb) - return false; + return true; try { return m_ringdb->get_ring(key, key_image, outs); } catch (const std::exception &e) { return false; } } @@ -5574,7 +5582,8 @@ bool wallet2::get_ring(const crypto::key_image &key_image, std::vector crypto::chacha_key key; generate_chacha_key_from_secret_keys(key); - return get_ring(key, key_image, outs); + try { return get_ring(key, key_image, outs); } + catch (const std::exception &e) { return false; } } bool wallet2::set_ring(const crypto::key_image &key_image, const std::vector &outs, bool relative) @@ -5585,7 +5594,8 @@ bool wallet2::set_ring(const crypto::key_image &key_image, const std::vectorset_ring(key, key_image, outs, relative); + try { return m_ringdb->set_ring(key, key_image, outs, relative); } + catch (const std::exception &e) { return false; } } bool wallet2::find_and_save_rings(bool force) @@ -5610,7 +5620,24 @@ bool wallet2::find_and_save_rings(bool force) txs_hashes.push_back(txid); } - MDEBUG("Found " << std::to_string(txs_hashes.size()) << " transactions"); + MDEBUG("Found " << std::to_string(req.txs_hashes.size()) << " transactions"); + + // get those transactions from the daemon + req.decode_as_json = false; + req.prune = true; + bool r; + { + const boost::lock_guard lock{m_daemon_rpc_mutex}; + r = epee::net_utils::invoke_http_json("/gettransactions", req, res, m_http_client, rpc_timeout); + } + THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "gettransactions"); + THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "gettransactions"); + THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::wallet_internal_error, "gettransactions"); + THROW_WALLET_EXCEPTION_IF(res.txs.size() != req.txs_hashes.size(), error::wallet_internal_error, + "daemon returned wrong response for gettransactions, wrong txs count = " + + std::to_string(res.txs.size()) + ", expected " + std::to_string(req.txs_hashes.size())); + + MDEBUG("Scanning " << res.txs.size() << " transactions"); crypto::chacha_key key; generate_chacha_key_from_secret_keys(key); @@ -5663,7 +5690,7 @@ bool wallet2::find_and_save_rings(bool force) bool wallet2::blackball_output(const crypto::public_key &output) { if (!m_ringdb) - return false; + return true; try { return m_ringdb->blackball(output); } catch (const std::exception &e) { return false; } } @@ -5671,7 +5698,7 @@ bool wallet2::blackball_output(const crypto::public_key &output) bool wallet2::set_blackballed_outputs(const std::vector &outputs, bool add) { if (!m_ringdb) - return false; + return true; try { bool ret = true; @@ -5687,7 +5714,7 @@ bool wallet2::set_blackballed_outputs(const std::vector &out bool wallet2::unblackball_output(const crypto::public_key &output) { if (!m_ringdb) - return false; + return true; try { return m_ringdb->unblackball(output); } catch (const std::exception &e) { return false; } } @@ -5695,7 +5722,7 @@ bool wallet2::unblackball_output(const crypto::public_key &output) bool wallet2::is_output_blackballed(const crypto::public_key &output) const { if (!m_ringdb) - return false; + return true; try { return m_ringdb->blackballed(output); } catch (const std::exception &e) { return false; } } @@ -5872,7 +5899,6 @@ void wallet2::get_outs(std::vector> auto end = std::unique(req_t.amounts.begin(), req_t.amounts.end()); req_t.amounts.resize(std::distance(req_t.amounts.begin(), end)); req_t.from_height = std::max(segregation_fork_height, RECENT_OUTPUT_BLOCKS) - RECENT_OUTPUT_BLOCKS; - req_t.to_height = segregation_fork_height + 1; req_t.cumulative = true; m_daemon_rpc_mutex.lock(); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_distribution", req_t, resp_t, m_http_client, rpc_timeout * 1000); @@ -6632,7 +6658,7 @@ void wallet2::transfer_selected_rct(std::vector