diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/util.cpp | 39 | ||||
-rw-r--r-- | src/daemon/command_parser_executor.cpp | 7 | ||||
-rw-r--r-- | src/daemon/command_parser_executor.h | 2 | ||||
-rw-r--r-- | src/daemon/command_server.cpp | 5 | ||||
-rw-r--r-- | src/daemon/main.cpp | 45 | ||||
-rw-r--r-- | src/device/device_default.hpp | 2 | ||||
-rw-r--r-- | src/device/device_ledger.hpp | 2 | ||||
-rw-r--r-- | src/p2p/net_node.inl | 13 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 34 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_commands_defs.h | 2 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 15 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.h | 1 | ||||
-rw-r--r-- | src/wallet/api/wallet2_api.h | 14 | ||||
-rw-r--r-- | src/wallet/api/wallet_manager.cpp | 44 | ||||
-rw-r--r-- | src/wallet/api/wallet_manager.h | 16 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 4 |
16 files changed, 168 insertions, 77 deletions
diff --git a/src/common/util.cpp b/src/common/util.cpp index 1877acb57..7e77e19b1 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -43,6 +43,7 @@ using namespace epee; #include "crypto/crypto.h" #include "util.h" +#include "stack_trace.h" #include "memwipe.h" #include "cryptonote_config.h" #include "net/http_client.h" // epee::net_utils::... @@ -560,10 +561,48 @@ std::string get_nix_version_display_string() } return false; } + +#ifdef STACK_TRACE +#ifdef _WIN32 + // https://stackoverflow.com/questions/1992816/how-to-handle-seg-faults-under-windows + static LONG WINAPI windows_crash_handler(PEXCEPTION_POINTERS pExceptionInfo) + { + tools::log_stack_trace("crashing"); + exit(1); + return EXCEPTION_CONTINUE_SEARCH; + } + static void setup_crash_dump() + { + SetUnhandledExceptionFilter(windows_crash_handler); + } +#else + static void posix_crash_handler(int signal) + { + tools::log_stack_trace(("crashing with fatal signal " + std::to_string(signal)).c_str()); +#ifdef NDEBUG + _exit(1); +#else + abort(); +#endif + } + static void setup_crash_dump() + { + signal(SIGSEGV, posix_crash_handler); + signal(SIGBUS, posix_crash_handler); + signal(SIGILL, posix_crash_handler); + signal(SIGFPE, posix_crash_handler); + } +#endif +#else + static void setup_crash_dump() {} +#endif + bool on_startup() { mlog_configure("", true); + setup_crash_dump(); + sanitize_locale(); #ifdef __GLIBC__ diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index 7a89ebc0c..28a7f1366 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -27,6 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "common/dns_utils.h" +#include "version.h" #include "daemon/command_parser_executor.h" #undef MONERO_DEFAULT_LOG_CATEGORY @@ -664,4 +665,10 @@ bool t_command_parser_executor::sync_info(const std::vector<std::string>& args) return m_executor.sync_info(); } +bool t_command_parser_executor::version(const std::vector<std::string>& args) +{ + std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << std::endl; + return true; +} + } // namespace daemonize diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h index 2c09a4748..a70070171 100644 --- a/src/daemon/command_parser_executor.h +++ b/src/daemon/command_parser_executor.h @@ -138,6 +138,8 @@ public: bool relay_tx(const std::vector<std::string>& args); bool sync_info(const std::vector<std::string>& args); + + bool version(const std::vector<std::string>& args); }; } // namespace daemonize diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index a50dbea69..144603597 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -280,6 +280,11 @@ t_command_server::t_command_server( , std::bind(&t_command_parser_executor::sync_info, &m_parser, p::_1) , "Print information about the blockchain sync state." ); + m_command_lookup.set_handler( + "version" + , std::bind(&t_command_parser_executor::version, &m_parser, p::_1) + , "Print version information." + ); } bool t_command_server::process_command_str(const std::string& cmd) diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 50384b2a6..49494e889 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -138,6 +138,28 @@ int main(int argc, char const * argv[]) return 0; } + std::string config = command_line::get_arg(vm, daemon_args::arg_config_file); + boost::filesystem::path config_path(config); + boost::system::error_code ec; + if (bf::exists(config_path, ec)) + { + try + { + po::store(po::parse_config_file<char>(config_path.string<std::string>().c_str(), core_settings), vm); + } + catch (const std::exception &e) + { + // log system isn't initialized yet + std::cerr << "Error parsing config file: " << e.what() << std::endl; + throw; + } + } + else if (!command_line::is_arg_defaulted(vm, daemon_args::arg_config_file)) + { + std::cerr << "Can't find config file " << config << std::endl; + return 1; + } + const bool testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on); const bool stagenet = command_line::get_arg(vm, cryptonote::arg_stagenet_on); if (testnet && stagenet) @@ -170,29 +192,6 @@ int main(int argc, char const * argv[]) //bf::path relative_path_base = daemonizer::get_relative_path_base(vm); bf::path relative_path_base = data_dir; - std::string config = command_line::get_arg(vm, daemon_args::arg_config_file); - - boost::filesystem::path data_dir_path(data_dir); - boost::filesystem::path config_path(config); - if (!config_path.has_parent_path()) - { - config_path = data_dir / config_path; - } - - boost::system::error_code ec; - if (bf::exists(config_path, ec)) - { - try - { - po::store(po::parse_config_file<char>(config_path.string<std::string>().c_str(), core_settings), vm); - } - catch (const std::exception &e) - { - // log system isn't initialized yet - std::cerr << "Error parsing config file: " << e.what() << std::endl; - throw; - } - } po::notify(vm); // log_file_path diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp index 649fed862..771fbba72 100644 --- a/src/device/device_default.hpp +++ b/src/device/device_default.hpp @@ -93,7 +93,7 @@ namespace hw { bool sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) override; crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) override; bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) override; - bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations); + bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations) override; bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) override; bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) override; bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) override; diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index 9f73bd070..f1fcaab87 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -169,7 +169,7 @@ namespace hw { bool sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) override; crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) override; bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) override; - bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations); + bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations) override; bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) override; bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) override; bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) override; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 3b0d1c394..9b21705ec 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -49,16 +49,9 @@ #include "storages/levin_abstract_invoke2.h" #include "cryptonote_core/cryptonote_core.h" -// We have to look for miniupnpc headers in different places, dependent on if its compiled or external -#ifdef UPNP_STATIC - #include <miniupnpc/miniupnpc.h> - #include <miniupnpc/upnpcommands.h> - #include <miniupnpc/upnperrors.h> -#else - #include "miniupnpc.h" - #include "upnpcommands.h" - #include "upnperrors.h" -#endif +#include <miniupnp/miniupnpc/miniupnpc.h> +#include <miniupnp/miniupnpc/upnpcommands.h> +#include <miniupnp/miniupnpc/upnperrors.h> #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.p2p" diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 79792e387..aa5728fc3 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -2082,10 +2082,27 @@ namespace cryptonote //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp) { + PERF_TIMER(on_get_output_distribution); try { for (uint64_t amount: req.amounts) { + static struct D + { + boost::mutex mutex; + std::vector<uint64_t> cached_distribution; + uint64_t cached_from, cached_to, cached_start_height, cached_base; + bool cached; + D(): cached_from(0), cached_to(0), cached_start_height(0), cached_base(0), cached(false) {} + } d; + boost::unique_lock<boost::mutex> lock(d.mutex); + + if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req.to_height) + { + res.distributions.push_back({amount, d.cached_start_height, d.cached_distribution, d.cached_base}); + continue; + } + std::vector<uint64_t> distribution; uint64_t start_height, base; if (!m_core.get_output_distribution(amount, req.from_height, start_height, distribution, base)) @@ -2094,12 +2111,29 @@ namespace cryptonote error_resp.message = "Failed to get rct distribution"; return false; } + if (req.to_height > 0 && req.to_height >= req.from_height) + { + uint64_t offset = std::max(req.from_height, start_height); + if (offset <= req.to_height && req.to_height - offset + 1 < distribution.size()) + distribution.resize(req.to_height - offset + 1); + } if (req.cumulative) { distribution[0] += base; for (size_t n = 1; n < distribution.size(); ++n) distribution[n] += distribution[n-1]; } + + if (amount == 0) + { + d.cached_from = req.from_height; + d.cached_to = req.to_height; + d.cached_distribution = distribution; + d.cached_start_height = start_height; + d.cached_base = base; + d.cached = true; + } + res.distributions.push_back({amount, start_height, std::move(distribution), base}); } } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index df5b4893f..a97277c0e 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -2212,11 +2212,13 @@ namespace cryptonote { std::vector<uint64_t> amounts; uint64_t from_height; + uint64_t to_height; bool cumulative; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(amounts) KV_SERIALIZE_OPT(from_height, (uint64_t)0) + KV_SERIALIZE_OPT(to_height, (uint64_t)0) KV_SERIALIZE_OPT(cumulative, false) END_KV_SERIALIZE_MAP() }; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 33615ffe2..639b394f3 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -62,6 +62,7 @@ #include "ringct/rctSigs.h" #include "multisig/multisig.h" #include "wallet/wallet_args.h" +#include "version.h" #include <stdexcept> #ifdef WIN32 @@ -1584,6 +1585,12 @@ bool simple_wallet::save_known_rings(const std::vector<std::string> &args) return true; } +bool simple_wallet::version(const std::vector<std::string> &args) +{ + message_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; + return true; +} + bool simple_wallet::set_always_confirm_transfers(const std::vector<std::string> &args/* = std::vector<std::string>()*/) { const auto pwd_container = get_and_verify_password(); @@ -2074,8 +2081,8 @@ simple_wallet::simple_wallet() tr("Donate <amount> to the development team (donate.getmonero.org).")); m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), - tr("sign_transfer <file>"), - tr("Sign a transaction from a <file>.")); + tr("sign_transfer [export]"), + tr("Sign a transaction from a file.")); m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), tr("Submit a signed transaction from a file.")); @@ -2335,6 +2342,10 @@ simple_wallet::simple_wallet() boost::bind(&simple_wallet::blackballed, this, _1), tr("blackballed <output public key>"), tr("Checks whether an output is blackballed")); + m_cmd_binder.set_handler("version", + boost::bind(&simple_wallet::version, this, _1), + tr("version"), + tr("Returns version information")); m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), tr("help [<command>]"), diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index f26f69353..39a91c5f5 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -218,6 +218,7 @@ namespace cryptonote bool blackball(const std::vector<std::string>& args); bool unblackball(const std::vector<std::string>& args); bool blackballed(const std::vector<std::string>& args); + bool version(const std::vector<std::string>& args); uint64_t get_daemon_blockchain_height(std::string& err); bool try_connect_to_daemon(bool silent = false, uint32_t* version = nullptr); diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index d4e41c5aa..617b6035a 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -956,25 +956,25 @@ struct WalletManager virtual void setDaemonAddress(const std::string &address) = 0; //! returns whether the daemon can be reached, and its version number - virtual bool connected(uint32_t *version = NULL) const = 0; + virtual bool connected(uint32_t *version = NULL) = 0; //! returns current blockchain height - virtual uint64_t blockchainHeight() const = 0; + virtual uint64_t blockchainHeight() = 0; //! returns current blockchain target height - virtual uint64_t blockchainTargetHeight() const = 0; + virtual uint64_t blockchainTargetHeight() = 0; //! returns current network difficulty - virtual uint64_t networkDifficulty() const = 0; + virtual uint64_t networkDifficulty() = 0; //! returns current mining hash rate (0 if not mining) - virtual double miningHashRate() const = 0; + virtual double miningHashRate() = 0; //! returns current block target - virtual uint64_t blockTarget() const = 0; + virtual uint64_t blockTarget() = 0; //! returns true iff mining - virtual bool isMining() const = 0; + virtual bool isMining() = 0; //! starts mining with the set number of threads virtual bool startMining(const std::string &address, uint32_t threads = 1, bool background_mining = false, bool ignore_battery = true) = 0; diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index 80f5780b5..a63716576 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -47,15 +47,6 @@ namespace epee { unsigned int g_test_dbg_lock_sleep = 0; } -namespace { - template<typename Request, typename Response> - bool connect_and_invoke(const std::string& address, const std::string& path, const Request& request, Response& response) - { - epee::net_utils::http::http_simple_client client{}; - return client.set_server(address, boost::none) && epee::net_utils::invoke_http_json(path, request, response, client); - } -} - namespace Monero { Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::string &password, @@ -193,16 +184,19 @@ std::string WalletManagerImpl::errorString() const void WalletManagerImpl::setDaemonAddress(const std::string &address) { m_daemonAddress = address; + if(m_http_client.is_connected()) + m_http_client.disconnect(); + m_http_client.set_server(address, boost::none); } -bool WalletManagerImpl::connected(uint32_t *version) const +bool WalletManagerImpl::connected(uint32_t *version) { epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_VERSION::request> req_t = AUTO_VAL_INIT(req_t); epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_VERSION::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); req_t.jsonrpc = "2.0"; req_t.id = epee::serialization::storage_entry(0); req_t.method = "get_version"; - if (!connect_and_invoke(m_daemonAddress, "/json_rpc", req_t, resp_t)) + if (!epee::net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client)) return false; if (version) @@ -210,65 +204,65 @@ bool WalletManagerImpl::connected(uint32_t *version) const return true; } -uint64_t WalletManagerImpl::blockchainHeight() const +uint64_t WalletManagerImpl::blockchainHeight() { cryptonote::COMMAND_RPC_GET_INFO::request ireq; cryptonote::COMMAND_RPC_GET_INFO::response ires; - if (!connect_and_invoke(m_daemonAddress, "/getinfo", ireq, ires)) + if (!epee::net_utils::invoke_http_json("/getinfo", ireq, ires, m_http_client)) return 0; return ires.height; } -uint64_t WalletManagerImpl::blockchainTargetHeight() const +uint64_t WalletManagerImpl::blockchainTargetHeight() { cryptonote::COMMAND_RPC_GET_INFO::request ireq; cryptonote::COMMAND_RPC_GET_INFO::response ires; - if (!connect_and_invoke(m_daemonAddress, "/getinfo", ireq, ires)) + if (!epee::net_utils::invoke_http_json("/getinfo", ireq, ires, m_http_client)) return 0; return ires.target_height >= ires.height ? ires.target_height : ires.height; } -uint64_t WalletManagerImpl::networkDifficulty() const +uint64_t WalletManagerImpl::networkDifficulty() { cryptonote::COMMAND_RPC_GET_INFO::request ireq; cryptonote::COMMAND_RPC_GET_INFO::response ires; - if (!connect_and_invoke(m_daemonAddress, "/getinfo", ireq, ires)) + if (!epee::net_utils::invoke_http_json("/getinfo", ireq, ires, m_http_client)) return 0; return ires.difficulty; } -double WalletManagerImpl::miningHashRate() const +double WalletManagerImpl::miningHashRate() { cryptonote::COMMAND_RPC_MINING_STATUS::request mreq; cryptonote::COMMAND_RPC_MINING_STATUS::response mres; epee::net_utils::http::http_simple_client http_client; - if (!connect_and_invoke(m_daemonAddress, "/mining_status", mreq, mres)) + if (!epee::net_utils::invoke_http_json("/mining_status", mreq, mres, m_http_client)) return 0.0; if (!mres.active) return 0.0; return mres.speed; } -uint64_t WalletManagerImpl::blockTarget() const +uint64_t WalletManagerImpl::blockTarget() { cryptonote::COMMAND_RPC_GET_INFO::request ireq; cryptonote::COMMAND_RPC_GET_INFO::response ires; - if (!connect_and_invoke(m_daemonAddress, "/getinfo", ireq, ires)) + if (!epee::net_utils::invoke_http_json("/getinfo", ireq, ires, m_http_client)) return 0; return ires.target; } -bool WalletManagerImpl::isMining() const +bool WalletManagerImpl::isMining() { cryptonote::COMMAND_RPC_MINING_STATUS::request mreq; cryptonote::COMMAND_RPC_MINING_STATUS::response mres; - if (!connect_and_invoke(m_daemonAddress, "/mining_status", mreq, mres)) + if (!epee::net_utils::invoke_http_json("/mining_status", mreq, mres, m_http_client)) return false; return mres.active; } @@ -283,7 +277,7 @@ bool WalletManagerImpl::startMining(const std::string &address, uint32_t threads mreq.ignore_battery = ignore_battery; mreq.do_background_mining = background_mining; - if (!connect_and_invoke(m_daemonAddress, "/start_mining", mreq, mres)) + if (!epee::net_utils::invoke_http_json("/start_mining", mreq, mres, m_http_client)) return false; return mres.status == CORE_RPC_STATUS_OK; } @@ -293,7 +287,7 @@ bool WalletManagerImpl::stopMining() cryptonote::COMMAND_RPC_STOP_MINING::request mreq; cryptonote::COMMAND_RPC_STOP_MINING::response mres; - if (!connect_and_invoke(m_daemonAddress, "/stop_mining", mreq, mres)) + if (!epee::net_utils::invoke_http_json("/stop_mining", mreq, mres, m_http_client)) return false; return mres.status == CORE_RPC_STATUS_OK; } diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h index 409a6d499..26238b658 100644 --- a/src/wallet/api/wallet_manager.h +++ b/src/wallet/api/wallet_manager.h @@ -30,6 +30,7 @@ #include "wallet/api/wallet2_api.h" +#include "net/http_client.h" #include <string> namespace Monero { @@ -69,13 +70,13 @@ public: std::vector<std::string> findWallets(const std::string &path); std::string errorString() const; void setDaemonAddress(const std::string &address); - bool connected(uint32_t *version = NULL) const; - uint64_t blockchainHeight() const; - uint64_t blockchainTargetHeight() const; - uint64_t networkDifficulty() const; - double miningHashRate() const; - uint64_t blockTarget() const; - bool isMining() const; + bool connected(uint32_t *version = NULL); + uint64_t blockchainHeight(); + uint64_t blockchainTargetHeight(); + uint64_t networkDifficulty(); + double miningHashRate(); + uint64_t blockTarget(); + bool isMining(); bool startMining(const std::string &address, uint32_t threads = 1, bool background_mining = false, bool ignore_battery = true); bool stopMining(); std::string resolveOpenAlias(const std::string &address, bool &dnssec_valid) const; @@ -84,6 +85,7 @@ private: WalletManagerImpl() {} friend struct WalletManagerFactory; std::string m_daemonAddress; + epee::net_utils::http::http_simple_client m_http_client; std::string m_errorString; }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index bbd3108d3..c9934af68 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5910,9 +5910,10 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> 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<uint64_t>(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); + bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_distribution", req_t, resp_t, m_http_client, rpc_timeout * 1000); m_daemon_rpc_mutex.unlock(); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "transfer_selected"); THROW_WALLET_EXCEPTION_IF(resp_t.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_distribution"); @@ -5929,6 +5930,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> { THROW_WALLET_EXCEPTION_IF(d.start_height > segregation_fork_height, error::get_output_distribution, "Distribution start_height too high"); THROW_WALLET_EXCEPTION_IF(segregation_fork_height - d.start_height >= d.distribution.size(), error::get_output_distribution, "Distribution size too small"); + THROW_WALLET_EXCEPTION_IF(segregation_fork_height - RECENT_OUTPUT_BLOCKS - d.start_height >= d.distribution.size(), error::get_output_distribution, "Distribution size too small"); THROW_WALLET_EXCEPTION_IF(segregation_fork_height <= RECENT_OUTPUT_BLOCKS, error::wallet_internal_error, "Fork height too low"); THROW_WALLET_EXCEPTION_IF(segregation_fork_height - RECENT_OUTPUT_BLOCKS < d.start_height, error::get_output_distribution, "Bad start height"); uint64_t till_fork = d.distribution[segregation_fork_height - d.start_height]; |