From 6f2886e135450fc909aa5129507a45be8bdfcd44 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 21 Mar 2018 19:00:27 +0000 Subject: [PATCH 01/43] simplewallet: add --untrusted-daemon option --- src/simplewallet/simplewallet.cpp | 56 ++++++++++++++++++------------- src/simplewallet/simplewallet.h | 3 +- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 447dcd111..d21eb9717 100755 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -127,6 +127,7 @@ namespace const command_line::arg_descriptor arg_restore_multisig_wallet = {"restore-multisig-wallet", sw::tr("Recover multisig wallet using Electrum-style mnemonic seed"), false}; const command_line::arg_descriptor arg_non_deterministic = {"non-deterministic", sw::tr("Generate non-deterministic view and spend keys"), false}; const command_line::arg_descriptor arg_trusted_daemon = {"trusted-daemon", sw::tr("Enable commands which rely on a trusted daemon"), false}; + const command_line::arg_descriptor arg_untrusted_daemon = {"untrusted-daemon", sw::tr("Disable commands which rely on a trusted daemon"), false}; const command_line::arg_descriptor arg_allow_mismatched_daemon_version = {"allow-mismatched-daemon-version", sw::tr("Allow communicating with a daemon that uses a different RPC version"), false}; const command_line::arg_descriptor arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0}; const command_line::arg_descriptor arg_do_not_relay = {"do-not-relay", sw::tr("The newly created transaction will not be relayed to the wownero network"), false}; @@ -1060,7 +1061,7 @@ bool simple_wallet::import_multisig(const std::vector &args) fail_msg_writer() << tr("Failed to import multisig info: ") << e.what(); return true; } - if (m_trusted_daemon) + if (is_daemon_trusted()) { try { @@ -1212,7 +1213,7 @@ bool simple_wallet::submit_multisig(const std::vector &args) } catch (const std::exception &e) { - handle_transfer_exception(std::current_exception(), m_trusted_daemon); + handle_transfer_exception(std::current_exception(), is_daemon_trusted()); } catch (...) { @@ -3078,18 +3079,21 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) return false; } - // set --trusted-daemon if local - try + // set --trusted-daemon if local and not overridden + if (!m_trusted_daemon) { - if (tools::is_local_address(m_wallet->get_daemon_address())) + try { - MINFO(tr("Daemon is local, assuming trusted")); - m_trusted_daemon = true; + if (tools::is_local_address(m_wallet->get_daemon_address())) + { + MINFO(tr("Daemon is local, assuming trusted")); + m_trusted_daemon = true; + } } + catch (const std::exception &e) { } } - catch (const std::exception &e) { } - if (!m_trusted_daemon) + if (!is_daemon_trusted()) 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()) @@ -3123,7 +3127,10 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_ m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet); m_restore_multisig_wallet = command_line::get_arg(vm, arg_restore_multisig_wallet); m_non_deterministic = command_line::get_arg(vm, arg_non_deterministic); - m_trusted_daemon = command_line::get_arg(vm, arg_trusted_daemon); + if (!command_line::is_arg_defaulted(vm, arg_trusted_daemon) || !command_line::is_arg_defaulted(vm, arg_untrusted_daemon)) + m_trusted_daemon = command_line::get_arg(vm, arg_trusted_daemon) && !command_line::get_arg(vm, arg_untrusted_daemon); + if (!command_line::is_arg_defaulted(vm, arg_trusted_daemon) && !command_line::is_arg_defaulted(vm, arg_untrusted_daemon)) + message_writer() << tr("--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted"); m_allow_mismatched_daemon_version = command_line::get_arg(vm, arg_allow_mismatched_daemon_version); m_restore_height = command_line::get_arg(vm, arg_restore_height); m_do_not_relay = command_line::get_arg(vm, arg_do_not_relay); @@ -3612,7 +3619,7 @@ bool simple_wallet::save_watch_only(const std::vector &args/* = std //---------------------------------------------------------------------------------------------------- bool simple_wallet::start_mining(const std::vector& args) { - if (!m_trusted_daemon) + if (!is_daemon_trusted()) { fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon"); return true; @@ -4108,7 +4115,7 @@ bool simple_wallet::show_blockchain_height(const std::vector& args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::rescan_spent(const std::vector &args) { - if (!m_trusted_daemon) + if (!is_daemon_trusted()) { fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon"); return true; @@ -4439,16 +4446,16 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vectorcreate_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, m_trusted_daemon); + ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, is_daemon_trusted()); break; case TransferNew: - ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, m_trusted_daemon); + ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, is_daemon_trusted()); break; default: LOG_ERROR("Unknown transfer method, using original"); /* FALLTHRU */ case TransferOriginal: - ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_trusted_daemon); + ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, is_daemon_trusted()); break; } @@ -4607,7 +4614,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector &args_) try { // figure out what tx will be necessary - auto ptx_vector = m_wallet->create_unmixable_sweep_transactions(m_trusted_daemon); + auto ptx_vector = m_wallet->create_unmixable_sweep_transactions(is_daemon_trusted()); if (ptx_vector.empty()) { @@ -4715,7 +4722,7 @@ bool simple_wallet::sweep_unmixable(const std::vector &args_) } catch (const std::exception &e) { - handle_transfer_exception(std::current_exception(), m_trusted_daemon); + handle_transfer_exception(std::current_exception(), is_daemon_trusted()); } catch (...) { @@ -4846,7 +4853,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector &a try { // figure out what tx will be necessary - auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, m_trusted_daemon); + auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, is_daemon_trusted()); if (ptx_vector.empty()) { @@ -4930,7 +4937,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector &a } catch (const std::exception& e) { - handle_transfer_exception(std::current_exception(), m_trusted_daemon); + handle_transfer_exception(std::current_exception(), is_daemon_trusted()); } catch (...) { @@ -5045,7 +5052,7 @@ bool simple_wallet::sweep_single(const std::vector &args_) try { // figure out what tx will be necessary - auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */, priority, extra, m_trusted_daemon); + auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */, priority, extra, is_daemon_trusted()); if (ptx_vector.empty()) { @@ -5115,7 +5122,7 @@ bool simple_wallet::sweep_single(const std::vector &args_) } catch (const std::exception& e) { - handle_transfer_exception(std::current_exception(), m_trusted_daemon); + handle_transfer_exception(std::current_exception(), is_daemon_trusted()); } catch (...) { @@ -5420,7 +5427,7 @@ bool simple_wallet::submit_transfer(const std::vector &args_) } catch (const std::exception& e) { - handle_transfer_exception(std::current_exception(), m_trusted_daemon); + handle_transfer_exception(std::current_exception(), is_daemon_trusted()); } catch (...) { @@ -7008,7 +7015,7 @@ bool simple_wallet::import_key_images(const std::vector &args) fail_msg_writer() << tr("command not supported by HW wallet"); return true; } - if (!m_trusted_daemon) + if (!is_daemon_trusted()) { fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon"); return true; @@ -7394,6 +7401,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_non_deterministic ); command_line::add_arg(desc_params, arg_electrum_seed ); command_line::add_arg(desc_params, arg_trusted_daemon); + command_line::add_arg(desc_params, arg_untrusted_daemon); command_line::add_arg(desc_params, arg_allow_mismatched_daemon_version); command_line::add_arg(desc_params, arg_restore_height); command_line::add_arg(desc_params, arg_do_not_relay); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index dfedf2863..125e849d5 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -228,6 +228,7 @@ namespace cryptonote bool print_ring_members(const std::vector& ptx_vector, std::ostream& ostr); std::string get_prompt() const; bool print_seed(bool encrypted); + bool is_daemon_trusted() const { return *m_trusted_daemon; } /*! * \brief Prints the seed with a nice message @@ -330,7 +331,7 @@ namespace cryptonote bool m_restore_deterministic_wallet; // recover flag bool m_restore_multisig_wallet; // recover flag bool m_non_deterministic; // old 2-random generation - bool m_trusted_daemon; + boost::optional m_trusted_daemon; bool m_allow_mismatched_daemon_version; bool m_restoring; // are we restoring, by whatever method? uint64_t m_restore_height; // optional -- 2.25.1 From 821276231229483579bbcfdc3d7a085310be5adf Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 18 May 2018 09:38:38 +0100 Subject: [PATCH 02/43] core: lock incoming tx lock when checking the txpool and chain This gets rid of an innocuous race trying to add the same tx twice to the txpool --- src/cryptonote_core/cryptonote_core.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index da82924a4..bfcca9a49 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -676,6 +676,7 @@ namespace cryptonote bool core::handle_incoming_txs(const std::list& tx_blobs, std::vector& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { TRY_ENTRY(); + CRITICAL_REGION_LOCAL(m_incoming_tx_lock); struct result { bool res; cryptonote::transaction tx; crypto::hash hash; crypto::hash prefix_hash; bool in_txpool; bool in_blockchain; }; std::vector results(tx_blobs.size()); -- 2.25.1 From 7df1321b30b4b7c88c36b68f19507068567264d6 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 24 May 2018 09:12:16 +0100 Subject: [PATCH 03/43] fix build with GCC 8.1.0 --- src/cryptonote_basic/account.cpp | 2 +- src/daemon/rpc_command_executor.cpp | 2 +- src/rpc/core_rpc_server_commands_defs.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp index bab991d19..aac6ec22b 100644 --- a/src/cryptonote_basic/account.cpp +++ b/src/cryptonote_basic/account.cpp @@ -157,7 +157,7 @@ DISABLE_VS_WARNINGS(4244 4345) void account_base::create_from_viewkey(const cryptonote::account_public_address& address, const crypto::secret_key& viewkey) { crypto::secret_key fake; - memset(&fake, 0, sizeof(fake)); + memset(&unwrap(fake), 0, sizeof(fake)); create_from_keys(address, fake, viewkey); } //----------------------------------------------------------------- diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 0a672ba27..c73d98a84 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -973,7 +973,7 @@ bool t_rpc_command_executor::print_transaction_pool_stats() { } else { - memset(&res.pool_stats, 0, sizeof(res.pool_stats)); + res.pool_stats = {}; if (!m_rpc_server->on_get_transaction_pool_stats(req, res, false) || res.status != CORE_RPC_STATUS_OK) { tools::fail_msg_writer() << make_error(fail_message, res.status); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 250c88e90..1227afef5 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1554,6 +1554,8 @@ namespace cryptonote std::vector histo; uint32_t num_double_spends; + txpool_stats(): bytes_total(0), bytes_min(0), bytes_max(0), bytes_med(0), fee_total(0), oldest(0), txs_total(0), num_failing(0), num_10m(0), num_not_relayed(0), histo_98pc(0), num_double_spends(0) {} + BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(bytes_total) KV_SERIALIZE(bytes_min) -- 2.25.1 From 6489ad8a1ab6fe57b227987083e118074715edf6 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 28 May 2018 14:55:09 +0100 Subject: [PATCH 04/43] disable file size sanity check when loading the wallet cache --- contrib/epee/include/file_io_utils.h | 6 +++--- src/wallet/wallet2.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h index 196610674..0afff800f 100644 --- a/contrib/epee/include/file_io_utils.h +++ b/contrib/epee/include/file_io_utils.h @@ -128,7 +128,7 @@ namespace file_io_utils inline - bool load_file_to_string(const std::string& path_to_file, std::string& target_str) + bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000) { #ifdef WIN32 WCHAR wide_path[1000]; @@ -139,7 +139,7 @@ namespace file_io_utils if (file_handle == INVALID_HANDLE_VALUE) return false; DWORD file_size = GetFileSize(file_handle, NULL); - if ((file_size == INVALID_FILE_SIZE) || (file_size > 1000000000)) { + if ((file_size == INVALID_FILE_SIZE) || (uint64_t)file_size > (uint64_t)max_size) { CloseHandle(file_handle); return false; } @@ -159,7 +159,7 @@ namespace file_io_utils std::ifstream::pos_type file_size = fstream.tellg(); - if(file_size > 1000000000) + if((uint64_t)file_size > (uint64_t)max_size) // ensure a large domain for comparison, and negative -> too large return false;//don't go crazy size_t file_size_t = static_cast(file_size); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index bb548f0b4..74f1d0769 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3769,7 +3769,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass { wallet2::cache_file_data cache_file_data; std::string buf; - bool r = epee::file_io_utils::load_file_to_string(m_wallet_file, buf); + bool r = epee::file_io_utils::load_file_to_string(m_wallet_file, buf, std::numeric_limits::max()); THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, m_wallet_file); // try to read it as an encrypted cache -- 2.25.1 From 9a2fa460b0cbf60a9df80e3737e2facb7c287d51 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 31 May 2018 12:13:03 +0100 Subject: [PATCH 05/43] daemon: fix readline interfering with std::cerr usage Once readline is initialized, std::cerr's operator<< will output a 0xff byte for unknown reasons. --- src/daemon/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 52ba7c452..0559be831 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -262,6 +262,9 @@ int main(int argc, char const * argv[]) } else { +#ifdef HAVE_READLINE + rdln::suspend_readline pause_readline; +#endif std::cerr << "Unknown command: " << command.front() << std::endl; return 1; } -- 2.25.1 From 9d366226cb33d2c8a3a3630a134e146987922237 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 1 Jun 2018 21:09:46 +0100 Subject: [PATCH 06/43] epee: fix detection of 172.16.0.0/172.31.255.255 local IP range --- contrib/epee/include/net/local_ip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/epee/include/net/local_ip.h b/contrib/epee/include/net/local_ip.h index 0d458963c..52c5855b9 100644 --- a/contrib/epee/include/net/local_ip.h +++ b/contrib/epee/include/net/local_ip.h @@ -48,7 +48,7 @@ namespace epee if( (ip | 0xffffff00) == 0xffffffac) { - uint32_t second_num = (ip << 8) & 0xff000000; + uint32_t second_num = (ip >> 8) & 0xff; if(second_num >= 16 && second_num <= 31 ) return true; } -- 2.25.1 From 6270a903c8b7ae2e3171280e7adf67af7f2f4f73 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 1 Jun 2018 21:52:04 +0100 Subject: [PATCH 07/43] blockchain: return error when requesting non existent output avoids RPC thread dying, causing the wallet to timeout --- src/cryptonote_core/blockchain.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 661bec03a..5f29de9f0 100755 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1942,14 +1942,21 @@ bool Blockchain::get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMA res.outs.clear(); res.outs.reserve(req.outputs.size()); - for (const auto &i: req.outputs) + try { - // get tx_hash, tx_out_index from DB - const output_data_t od = m_db->get_output_key(i.amount, i.index); - tx_out_index toi = m_db->get_output_tx_and_index(i.amount, i.index); - bool unlocked = is_tx_spendtime_unlocked(m_db->get_tx_unlock_time(toi.first)); + for (const auto &i: req.outputs) + { + // get tx_hash, tx_out_index from DB + const output_data_t od = m_db->get_output_key(i.amount, i.index); + tx_out_index toi = m_db->get_output_tx_and_index(i.amount, i.index); + bool unlocked = is_tx_spendtime_unlocked(m_db->get_tx_unlock_time(toi.first)); - res.outs.push_back({od.pubkey, od.commitment, unlocked, od.height, toi.first}); + res.outs.push_back({od.pubkey, od.commitment, unlocked, od.height, toi.first}); + } + } + catch (const std::exception &e) + { + return false; } return true; } -- 2.25.1 From 2b863521ba98dd55929769719bc36beb907d02dc Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 4 Jun 2018 20:46:24 +0900 Subject: [PATCH 08/43] blockchain: pop forked blocks only when DB is not read-only --- src/cryptonote_core/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 5f29de9f0..8d7daa700 100755 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -409,7 +409,7 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline m_db->block_txn_stop(); uint64_t num_popped_blocks = 0; - while (true) + while (!m_db->is_read_only()) { const uint64_t top_height = m_db->height() - 1; const crypto::hash top_id = m_db->top_block_hash(); -- 2.25.1 From edf18e227d99a43d501d61cfe73de69dec87c3c5 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 5 Jun 2018 10:45:01 +0100 Subject: [PATCH 09/43] simplewallet: add optional trusted/untrusted argument to set_daemon Otherwise the previous daemon's trustedness would carry over. If not specified, the local address check is performed again. --- src/simplewallet/simplewallet.cpp | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index d21eb9717..bcb5e4385 100755 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1990,7 +1990,7 @@ simple_wallet::simple_wallet() tr("Stop mining in the daemon.")); m_cmd_binder.set_handler("set_daemon", boost::bind(&simple_wallet::set_daemon, this, _1), - tr("set_daemon [:]"), + tr("set_daemon [:] [trusted|untrusted]"), tr("Set another daemon to connect to.")); m_cmd_binder.set_handler("save_bc", boost::bind(&simple_wallet::save_bc, this, _1), @@ -3730,6 +3730,33 @@ bool simple_wallet::set_daemon(const std::vector& args) } LOCK_IDLE_SCOPE(); m_wallet->init(daemon_url); + + if (args.size() == 2) + { + if (args[1] == "trusted") + m_trusted_daemon = true; + else if (args[1] == "untrusted") + m_trusted_daemon = false; + else + { + fail_msg_writer() << tr("Expected trusted or untrusted, got ") << args[1] << ": assuming untrusted"; + m_trusted_daemon = false; + } + } + else + { + m_trusted_daemon = false; + try + { + if (tools::is_local_address(m_wallet->get_daemon_address())) + { + MINFO(tr("Daemon is local, assuming trusted")); + m_trusted_daemon = true; + } + } + catch (const std::exception &e) { } + } + success_msg_writer() << boost::format("Daemon set to %s, %s") % daemon_url % (*m_trusted_daemon ? tr("trusted") : tr("untrusted")); } else { fail_msg_writer() << tr("This does not seem to be a valid daemon URL."); } -- 2.25.1 From 8345f0aabcc200be12a29ee5341fb2b011bb0249 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 5 Jun 2018 11:32:35 +0100 Subject: [PATCH 10/43] util: consider Tor/I2P addresses to be non local --- src/common/util.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/common/util.cpp b/src/common/util.cpp index 7e77e19b1..d17d24928 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -657,6 +657,13 @@ std::string get_nix_version_display_string() bool is_local_address(const std::string &address) { + // always assume Tor/I2P addresses to be untrusted by default + if (boost::ends_with(address, ".onion") || boost::ends_with(address, ".i2p")) + { + MDEBUG("Address '" << address << "' is Tor/I2P, non local"); + return false; + } + // extract host epee::net_utils::http::url_content u_c; if (!epee::net_utils::parse_url(address, u_c)) -- 2.25.1 From 7f3f9230218c7b4bc40538c9aee11fbbe98764ab Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 5 Jun 2018 19:59:45 +0100 Subject: [PATCH 11/43] tx_pool: initialize bitflags padding since it gets written to storage Avoids valgrind reporting uninitialized data usage --- src/blockchain_db/blockchain_db.h | 1 + src/cryptonote_core/tx_pool.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 1ed715315..442ae9e8b 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -148,6 +148,7 @@ struct txpool_tx_meta_t uint8_t relayed; uint8_t do_not_relay; uint8_t double_spend_seen: 1; + uint8_t bf_padding: 7; uint8_t padding[76]; // till 192 bytes }; diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 5dfbc1dd4..684a6b363 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -239,6 +239,7 @@ namespace cryptonote meta.relayed = relayed; meta.do_not_relay = do_not_relay; meta.double_spend_seen = have_tx_keyimges_as_spent(tx); + meta.bf_padding = 0; memset(meta.padding, 0, sizeof(meta.padding)); try { @@ -278,6 +279,7 @@ namespace cryptonote meta.relayed = relayed; meta.do_not_relay = do_not_relay; meta.double_spend_seen = false; + meta.bf_padding = 0; memset(meta.padding, 0, sizeof(meta.padding)); try -- 2.25.1 From fea950a61b5641ad1b2088c63ecb5034b3fde951 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 6 Jun 2018 10:12:45 +0100 Subject: [PATCH 12/43] wallet: do not log by default if we're not asked to log to console This means monero-wallet-rpc still does, but the user level program does not. --- src/wallet/wallet_args.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp index ed738e3e1..fcd9cc0f1 100644 --- a/src/wallet/wallet_args.cpp +++ b/src/wallet/wallet_args.cpp @@ -179,6 +179,10 @@ namespace wallet_args { mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str()); } + else if (!log_to_console) + { + mlog_set_categories(""); + } if (notice) Print(print) << notice << ENDL; -- 2.25.1 From b27b34d90a7b8e146bb53b6ab8996adfeb46afd7 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 26 May 2018 23:38:08 +0100 Subject: [PATCH 13/43] epee: fallback to a counter if gmtime fails when rotating logs --- contrib/epee/src/mlog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp index fb0b4ac2b..0c810729d 100644 --- a/contrib/epee/src/mlog.cpp +++ b/contrib/epee/src/mlog.cpp @@ -47,6 +47,7 @@ using namespace epee; static std::string generate_log_filename(const char *base) { std::string filename(base); + static unsigned int fallback_counter = 0; char tmp[200]; struct tm tm; time_t now = time(NULL); @@ -56,7 +57,7 @@ static std::string generate_log_filename(const char *base) #else (!gmtime_r(&now, &tm)) #endif - strcpy(tmp, "unknown"); + snprintf(tmp, sizeof(tmp), "part-%u", ++fallback_counter); else strftime(tmp, sizeof(tmp), "%Y-%m-%d-%H-%M-%S", &tm); tmp[sizeof(tmp) - 1] = 0; -- 2.25.1 From dc4b05bfd4db17acf46cb5f9a48a192f6bfe3459 Mon Sep 17 00:00:00 2001 From: stoffu Date: Wed, 13 Jun 2018 01:06:44 +0900 Subject: [PATCH 14/43] wallet2: use decoded amount when reporting repeated output key --- src/wallet/wallet2.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 74f1d0769..a4ff9897c 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1308,20 +1308,20 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote m_callback->on_money_received(height, txid, tx, td.m_amount, td.m_subaddr_index); } } - else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx.vout[o].amount) + else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx_scan_info[o].amount) { LOG_ERROR("Public key " << epee::string_tools::pod_to_hex(kit->first) - << " from received " << print_money(tx.vout[o].amount) << " output already exists with " + << " from received " << print_money(tx_scan_info[o].amount) << " output already exists with " << (m_transfers[kit->second].m_spent ? "spent" : "unspent") << " " - << print_money(m_transfers[kit->second].amount()) << ", received output ignored"); + << print_money(m_transfers[kit->second].amount()) << " in tx " << m_transfers[kit->second].m_txid << ", received output ignored"); } else { LOG_ERROR("Public key " << epee::string_tools::pod_to_hex(kit->first) - << " from received " << print_money(tx.vout[o].amount) << " output already exists with " + << " from received " << print_money(tx_scan_info[o].amount) << " output already exists with " << print_money(m_transfers[kit->second].amount()) << ", replacing with new output"); // The new larger output replaced a previous smaller one - tx_money_got_in_outs[tx_scan_info[o].received->index] -= tx.vout[o].amount; + tx_money_got_in_outs[tx_scan_info[o].received->index] -= tx_scan_info[o].amount; if (!pool) { -- 2.25.1 From f4fa62e1db0f58f5dbf49f3ba36fa005094a761c Mon Sep 17 00:00:00 2001 From: stoffu Date: Tue, 12 Jun 2018 12:44:40 +0900 Subject: [PATCH 15/43] wallet: allow unspendable unmixable outputs to be discarded --- src/simplewallet/simplewallet.cpp | 14 ++++++++++++++ src/wallet/wallet2.cpp | 10 ++++++++++ src/wallet/wallet2.h | 1 + 3 files changed, 25 insertions(+) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index bcb5e4385..60e772190 100755 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -4747,6 +4747,20 @@ bool simple_wallet::sweep_unmixable(const std::vector &args_) commit_or_save(ptx_vector, m_do_not_relay); } } + catch (const tools::error::not_enough_unlocked_money& e) + { + fail_msg_writer() << tr("Not enough money in unlocked balance"); + std::string accepted = input_line((boost::format(tr("Discarding %s of unmixable outputs that cannot be spent, which can be undone by \"rescan_spent\". Is this okay? (Y/Yes/N/No): ")) % print_money(e.available())).str()); + if (std::cin.eof()) + return true; + if (command_line::is_yes(accepted)) + { + try + { + m_wallet->discard_unmixable_outputs(is_daemon_trusted()); + } catch (...) {} + } + } catch (const std::exception &e) { handle_transfer_exception(std::current_exception(), is_daemon_trusted()); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a4ff9897c..a5da651a5 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -8238,6 +8238,16 @@ std::vector wallet2::create_unmixable_sweep_transactions(bo return create_transactions_from(m_account_public_address, false, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 0 /* unlock_time */, 1 /*priority */, std::vector(), trusted_daemon); } +//---------------------------------------------------------------------------------------------------- +void wallet2::discard_unmixable_outputs(bool trusted_daemon) +{ + // may throw + std::vector unmixable_outputs = select_available_unmixable_outputs(trusted_daemon); + for (size_t idx : unmixable_outputs) + { + m_transfers[idx].m_spent = true; + } +} bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector &additional_tx_keys) const { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index d996207bd..4841c13a1 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -706,6 +706,7 @@ namespace tools bool sign_multisig_tx(multisig_tx_set &exported_txs, std::vector &txids); bool sign_multisig_tx_to_file(multisig_tx_set &exported_txs, const std::string &filename, std::vector &txids); std::vector create_unmixable_sweep_transactions(bool trusted_daemon); + void discard_unmixable_outputs(bool trusted_daemon); bool check_connection(uint32_t *version = NULL, uint32_t timeout = 200000); void get_transfers(wallet2::transfer_container& incoming_transfers) const; void get_payments(const crypto::hash& payment_id, std::list& payments, uint64_t min_height = 0, const boost::optional& subaddr_account = boost::none, const std::set& subaddr_indices = {}) const; -- 2.25.1 From 4bd2b033f62ed1737b12b14c22415971ecf72169 Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 4 Jun 2018 19:18:18 +0900 Subject: [PATCH 16/43] wallet2: lower default for subaddress lookahead when restoring with hardware --- src/wallet/wallet2.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a5da651a5..55a2878b5 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3257,6 +3257,12 @@ void wallet2::restore(const std::string& wallet_, const epee::wipeable_string& p cryptonote::block b; generate_genesis(b); m_blockchain.push_back(get_block_hash(b)); + if (m_subaddress_lookahead_major == SUBADDRESS_LOOKAHEAD_MAJOR && m_subaddress_lookahead_minor == SUBADDRESS_LOOKAHEAD_MINOR) + { + // the default lookahead setting (50:200) is clearly too much for hardware wallet + m_subaddress_lookahead_major = 5; + m_subaddress_lookahead_minor = 20; + } add_subaddress_account(tr("Primary account")); if (!wallet_.empty()) { store(); -- 2.25.1 From 86e6008036ab61a88e3a5540d3386b499f33e95b Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 4 Jun 2018 16:54:35 +0900 Subject: [PATCH 17/43] Move parse_subaddress_lookahead() from simplewallet.cpp to util.cpp --- src/common/util.cpp | 18 ++++++++++++++++++ src/common/util.h | 3 +++ src/simplewallet/simplewallet.cpp | 17 +++-------------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/common/util.cpp b/src/common/util.cpp index d17d24928..8e4ea7fa5 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -757,4 +757,22 @@ std::string get_nix_version_display_string() return false; return true; } + + boost::optional> parse_subaddress_lookahead(const std::string& str) + { + auto pos = str.find(":"); + bool r = pos != std::string::npos; + uint32_t major; + r = r && epee::string_tools::get_xtype_from_string(major, str.substr(0, pos)); + uint32_t minor; + r = r && epee::string_tools::get_xtype_from_string(minor, str.substr(pos + 1)); + if (r) + { + return std::make_pair(major, minor); + } + else + { + return {}; + } + } } diff --git a/src/common/util.h b/src/common/util.h index d3ba47a4f..0bf5c941e 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -212,4 +213,6 @@ namespace tools bool sha256sum(const uint8_t *data, size_t len, crypto::hash &hash); bool sha256sum(const std::string &filename, crypto::hash &hash); + + boost::optional> parse_subaddress_lookahead(const std::string& str); } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 60e772190..677744b46 100755 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -377,21 +377,10 @@ namespace boost::optional> parse_subaddress_lookahead(const std::string& str) { - auto pos = str.find(":"); - bool r = pos != std::string::npos; - uint32_t major; - r = r && epee::string_tools::get_xtype_from_string(major, str.substr(0, pos)); - uint32_t minor; - r = r && epee::string_tools::get_xtype_from_string(minor, str.substr(pos + 1)); - if (r) - { - return std::make_pair(major, minor); - } - else - { + auto r = tools::parse_subaddress_lookahead(str); + if (!r) fail_msg_writer() << tr("invalid format for subaddress lookahead; must be :"); - return {}; - } + return r; } void handle_transfer_exception(const std::exception_ptr &e, bool trusted_daemon) -- 2.25.1 From 6463a6da6ff7fca0acf5778bdecfb86b96fa31db Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 25 Jun 2018 09:44:07 +0900 Subject: [PATCH 18/43] epee.string_tools: add conversion between UTF-8 and UTF-16 --- contrib/epee/include/file_io_utils.h | 25 ++++++++------------ contrib/epee/include/string_tools.h | 35 ++++++++++++++++++++++++++++ src/common/util.cpp | 31 ++++++++++++++---------- 3 files changed, 64 insertions(+), 27 deletions(-) diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h index 0afff800f..3c4ae1493 100644 --- a/contrib/epee/include/file_io_utils.h +++ b/contrib/epee/include/file_io_utils.h @@ -33,6 +33,7 @@ #include #ifdef WIN32 #include +#include "string_tools.h" #endif // On Windows there is a problem with non-ASCII characters in path and file names @@ -72,11 +73,9 @@ namespace file_io_utils bool save_string_to_file(const std::string& path_to_file, const std::string& str) { #ifdef WIN32 - WCHAR wide_path[1000]; - int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000); - if (chars == 0) - return false; - HANDLE file_handle = CreateFileW(wide_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + std::wstring wide_path; + try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; } + HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file_handle == INVALID_HANDLE_VALUE) return false; DWORD bytes_written; @@ -131,11 +130,9 @@ namespace file_io_utils bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000) { #ifdef WIN32 - WCHAR wide_path[1000]; - int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000); - if (chars == 0) - return false; - HANDLE file_handle = CreateFileW(wide_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + std::wstring wide_path; + try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; } + HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (file_handle == INVALID_HANDLE_VALUE) return false; DWORD file_size = GetFileSize(file_handle, NULL); @@ -202,11 +199,9 @@ namespace file_io_utils bool get_file_size(const std::string& path_to_file, uint64_t &size) { #ifdef WIN32 - WCHAR wide_path[1000]; - int chars = MultiByteToWideChar(CP_UTF8, 0, path_to_file.c_str(), path_to_file.size() + 1, wide_path, 1000); - if (chars == 0) - return false; - HANDLE file_handle = CreateFileW(wide_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + std::wstring wide_path; + try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; } + HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (file_handle == INVALID_HANDLE_VALUE) return false; LARGE_INTEGER file_size; diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h index 63705e401..8d8603076 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/string_tools.h @@ -381,6 +381,41 @@ POP_WARNINGS res = str.substr(0, pos); return res; } + //---------------------------------------------------------------------------- +#ifdef _WIN32 + inline std::wstring utf8_to_utf16(const std::string& str) + { + if (str.empty()) + return {}; + int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0); + if (wstr_size == 0) + { + throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); + } + std::wstring wstr(wstr_size, wchar_t{}); + if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size)) + { + throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); + } + return wstr; + } + inline std::string utf16_to_utf8(const std::wstring& wstr) + { + if (wstr.empty()) + return {}; + int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL); + if (str_size == 0) + { + throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); + } + std::string str(str_size, char{}); + if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL)) + { + throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); + } + return str; + } +#endif } } #endif //_STRING_TOOLS_H_ diff --git a/src/common/util.cpp b/src/common/util.cpp index 8e4ea7fa5..17bc7a21d 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -440,10 +440,15 @@ std::string get_nix_version_display_string() if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate)) { - int size_needed = WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), NULL, 0, NULL, NULL); - std::string folder_name(size_needed, 0); - WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), &folder_name[0], size_needed, NULL, NULL); - return folder_name; + try + { + return string_tools::utf16_to_utf8(psz_path); + } + catch (const std::exception &e) + { + MERROR("utf16_to_utf8 failed: " << e.what()); + return ""; + } } LOG_ERROR("SHGetSpecialFolderPathW() failed, could not obtain requested path."); @@ -504,18 +509,20 @@ std::string get_nix_version_display_string() int code; #if defined(WIN32) // Maximizing chances for success - WCHAR wide_replacement_name[1000]; - MultiByteToWideChar(CP_UTF8, 0, replacement_name.c_str(), replacement_name.size() + 1, wide_replacement_name, 1000); - WCHAR wide_replaced_name[1000]; - MultiByteToWideChar(CP_UTF8, 0, replaced_name.c_str(), replaced_name.size() + 1, wide_replaced_name, 1000); - - DWORD attributes = ::GetFileAttributesW(wide_replaced_name); + std::wstring wide_replacement_name; + try { wide_replacement_name = string_tools::utf8_to_utf16(replacement_name); } + catch (...) { return std::error_code(GetLastError(), std::system_category()); } + std::wstring wide_replaced_name; + try { wide_replaced_name = string_tools::utf8_to_utf16(replaced_name); } + catch (...) { return std::error_code(GetLastError(), std::system_category()); } + + DWORD attributes = ::GetFileAttributesW(wide_replaced_name.c_str()); if (INVALID_FILE_ATTRIBUTES != attributes) { - ::SetFileAttributesW(wide_replaced_name, attributes & (~FILE_ATTRIBUTE_READONLY)); + ::SetFileAttributesW(wide_replaced_name.c_str(), attributes & (~FILE_ATTRIBUTE_READONLY)); } - bool ok = 0 != ::MoveFileExW(wide_replacement_name, wide_replaced_name, MOVEFILE_REPLACE_EXISTING); + bool ok = 0 != ::MoveFileExW(wide_replacement_name.c_str(), wide_replaced_name.c_str(), MOVEFILE_REPLACE_EXISTING); code = ok ? 0 : static_cast(::GetLastError()); #else bool ok = 0 == std::rename(replacement_name.c_str(), replaced_name.c_str()); -- 2.25.1 From 65f483ca5bff545e581807f0eb1fdfca196faefe Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 12 Jun 2018 07:25:01 +0100 Subject: [PATCH 19/43] abstract_tcp_server2: restart async accept on error --- .../epee/include/net/abstract_tcp_server2.inl | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index f5ced8fdd..fa39be5eb 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -1029,7 +1029,8 @@ POP_WARNINGS void boosted_tcp_server::handle_accept(const boost::system::error_code& e) { MDEBUG("handle_accept"); - TRY_ENTRY(); + try + { if (!e) { if (m_connection_type == e_connection_type_RPC) { @@ -1047,11 +1048,25 @@ POP_WARNINGS conn->start(true, 1 < m_threads_count); conn->save_dbg_log(); - }else + return; + } + else + { + MERROR("Error in boosted_tcp_server::handle_accept: " << e); + } + } + catch (const std::exception &e) { - _erro("Some problems at accept: " << e.message() << ", connections_count = " << m_sock_count); + MERROR("Exception in boosted_tcp_server::handle_accept: " << e.what()); } - CATCH_ENTRY_L0("boosted_tcp_server::handle_accept", void()); + + // error path, if e or exception + _erro("Some problems at accept: " << e.message() << ", connections_count = " << m_sock_count); + misc_utils::sleep_no_w(100); + new_connection_.reset(new connection(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type)); + acceptor_.async_accept(new_connection_->socket(), + boost::bind(&boosted_tcp_server::handle_accept, this, + boost::asio::placeholders::error)); } //--------------------------------------------------------------------------------- template -- 2.25.1 From 7ba35598be4b9cfbc5a9d8a218f654b8a14c7b35 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 15 Jun 2018 20:17:25 +0100 Subject: [PATCH 20/43] wallet2: fix out of sync account tag cache This would cause crashes when trying to tag an account that was just created --- src/wallet/wallet2.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 55a2878b5..4daf054e9 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -938,6 +938,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) { -- 2.25.1 From 2c9c795f0c12a56e365137b212c6abf82a1c58b0 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 15 Jun 2018 20:13:19 +0100 Subject: [PATCH 21/43] Fix RPC crashes that didn't check for an open wallet --- src/wallet/wallet_rpc_server.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 22873c55e..12abf6023 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -500,6 +500,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_get_account_tags(const wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::response& res, epee::json_rpc::error& er) { + if (!m_wallet) return not_open(er); const std::pair, std::vector> account_tags = m_wallet->get_account_tags(); for (const std::pair& p : account_tags.first) { @@ -518,6 +519,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_tag_accounts(const wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::response& res, epee::json_rpc::error& er) { + if (!m_wallet) return not_open(er); try { m_wallet->set_account_tag(req.accounts, req.tag); @@ -532,6 +534,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_untag_accounts(const wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::response& res, epee::json_rpc::error& er) { + if (!m_wallet) return not_open(er); try { m_wallet->set_account_tag(req.accounts, ""); @@ -546,6 +549,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_set_account_tag_description(const wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::request& req, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::response& res, epee::json_rpc::error& er) { + if (!m_wallet) return not_open(er); try { m_wallet->set_account_tag_description(req.tag, req.description); @@ -2054,6 +2058,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er) { + if (!m_wallet) return not_open(er); std::string error; std::string uri = m_wallet->make_uri(req.address, req.payment_id, req.amount, req.tx_description, req.recipient_name, error); if (uri.empty()) @@ -2267,6 +2272,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_stop_mining(const wallet_rpc::COMMAND_RPC_STOP_MINING::request& req, wallet_rpc::COMMAND_RPC_STOP_MINING::response& res, epee::json_rpc::error& er) { + if (!m_wallet) return not_open(er); cryptonote::COMMAND_RPC_STOP_MINING::request daemon_req; cryptonote::COMMAND_RPC_STOP_MINING::response daemon_res; bool r = m_wallet->invoke_http_json("/stop_mining", daemon_req, daemon_res); -- 2.25.1 From 5cdbfe4e8b7465834ee3862d0bee727e0c940c42 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 17 Jun 2018 13:48:12 +0100 Subject: [PATCH 22/43] zmq_server: fix bind call when address and/or port are empty --- src/rpc/zmq_server.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rpc/zmq_server.cpp b/src/rpc/zmq_server.cpp index 3aee8c4c7..edd3e6669 100644 --- a/src/rpc/zmq_server.cpp +++ b/src/rpc/zmq_server.cpp @@ -104,6 +104,10 @@ bool ZmqServer::addTCPSocket(std::string address, std::string port) rep_socket->setsockopt(ZMQ_RCVTIMEO, &DEFAULT_RPC_RECV_TIMEOUT_MS, sizeof(DEFAULT_RPC_RECV_TIMEOUT_MS)); + if (address.empty()) + address = "*"; + if (port.empty()) + port = "*"; std::string bind_address = addr_prefix + address + std::string(":") + port; rep_socket->bind(bind_address.c_str()); } -- 2.25.1 From 0bd04bdfad06a4260f17a87898cbe617ee92c47d Mon Sep 17 00:00:00 2001 From: stoffu Date: Thu, 21 Jun 2018 10:49:03 +0900 Subject: [PATCH 23/43] wallet-rpc.getaddress: throw if index is out of bound --- src/wallet/wallet_rpc_server.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 12abf6023..21916d0ae 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -362,6 +362,7 @@ namespace tools if (!m_wallet) return not_open(er); try { + THROW_WALLET_EXCEPTION_IF(req.account_index >= m_wallet->get_num_subaddress_accounts(), error::account_index_outofbound); res.addresses.clear(); std::vector req_address_index; if (req.address_index.empty()) @@ -377,6 +378,7 @@ namespace tools m_wallet->get_transfers(transfers); for (uint32_t i : req_address_index) { + THROW_WALLET_EXCEPTION_IF(i >= m_wallet->get_num_subaddresses(req.account_index), error::address_index_outofbound); res.addresses.resize(res.addresses.size() + 1); auto& info = res.addresses.back(); const cryptonote::subaddress_index index = {req.account_index, i}; -- 2.25.1 From 90a4ba36a62ad6d548e9b1c3ad2647130698426b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 23 Jun 2018 09:20:34 +0100 Subject: [PATCH 24/43] wallet2: fix read buffer overflow in import_key_images --- src/wallet/wallet2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 4daf054e9..aea308583 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -9533,7 +9533,7 @@ uint64_t wallet2::import_key_images(const std::vector spent_txids; // For each spent key image, search for a tx in m_transfers that uses it as input. std::vector 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(); -- 2.25.1 From 05b49cc1bb463c6db23bfdfa5f35695582a2a3e6 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 23 Jun 2018 09:53:09 +0100 Subject: [PATCH 25/43] simplewallet: init trusted daemon flag to false when autodetecting --- src/simplewallet/simplewallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 677744b46..c74e28ffc 100755 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -3073,6 +3073,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { try { + m_trusted_daemon = false; if (tools::is_local_address(m_wallet->get_daemon_address())) { MINFO(tr("Daemon is local, assuming trusted")); -- 2.25.1 From 6eaa228b16e3c214b00873d03d8fb1f8810f72dc Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 29 Jun 2018 15:40:19 +0100 Subject: [PATCH 26/43] abstract_tcp_server2: fix use after free --- contrib/epee/include/net/abstract_tcp_server2.inl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index fa39be5eb..b0d1be594 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -652,13 +652,13 @@ PRAGMA_WARNING_DISABLE_VS(4355) m_timer.cancel(); boost::system::error_code ignored_ec; socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); - m_was_shutdown = true; - m_protocol_handler.release_protocol(); if (!m_host.empty()) { host_count(m_host, -1); m_host = ""; } + m_was_shutdown = true; + m_protocol_handler.release_protocol(); return true; } //--------------------------------------------------------------------------------- -- 2.25.1 From 68505da66fa57f737432ccaead302353c8bb57ee Mon Sep 17 00:00:00 2001 From: m2049r Date: Fri, 30 Mar 2018 13:01:41 +0200 Subject: [PATCH 27/43] malloc scratchpad for all supported android archs --- src/crypto/slow-hash.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c index 35e98f2f5..d3c4da428 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -905,10 +905,35 @@ STATIC INLINE void aes_pseudo_round_xor(const uint8_t *in, uint8_t *out, const u } } +STATIC INLINE void* aligned_malloc(size_t size, size_t align) +{ + void *result; +#ifdef _MSC_VER + result = _aligned_malloc(size, align); +#else + if (posix_memalign(&result, align, size)) result = NULL; +#endif + return result; +} + +STATIC INLINE void aligned_free(void *ptr) +{ +#ifdef _MSC_VER + _aligned_free(ptr); +#else + free(ptr); +#endif +} + void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { RDATA_ALIGN16 uint8_t expandedKey[240]; + +#ifndef FORCE_USE_HEAP RDATA_ALIGN16 uint8_t hp_state[MEMORY]; +#else + uint8_t *hp_state = (uint8_t *)aligned_malloc(MEMORY,16); +#endif uint8_t text[INIT_SIZE_BYTE]; RDATA_ALIGN16 uint64_t a[2]; @@ -993,6 +1018,10 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int memcpy(state.init, text, INIT_SIZE_BYTE); hash_permutation(&state.hs); extra_hashes[state.hs.b[0] & 3](&state, 200, hash); + +#ifdef FORCE_USE_HEAP + aligned_free(hp_state); +#endif } #else /* aarch64 && crypto */ @@ -1127,8 +1156,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int #ifndef FORCE_USE_HEAP uint8_t long_state[MEMORY]; #else - uint8_t *long_state = NULL; - long_state = (uint8_t *)malloc(MEMORY); + uint8_t *long_state = (uint8_t *)malloc(MEMORY); #endif if (prehashed) { @@ -1294,7 +1322,12 @@ union cn_slow_hash_state { #pragma pack(pop) void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { +#ifndef FORCE_USE_HEAP uint8_t long_state[MEMORY]; +#else + uint8_t *long_state = (uint8_t *)malloc(MEMORY); +#endif + union cn_slow_hash_state state; uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; @@ -1370,6 +1403,10 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int /*memcpy(hash, &state, 32);*/ extra_hashes[state.hs.b[0] & 3](&state, 200, hash); oaes_free((OAES_CTX **) &aes_ctx); + +#ifdef FORCE_USE_HEAP + free(long_state); +#endif } #endif -- 2.25.1 From 0f4ed31a61f49934e34e621982f20755d228a845 Mon Sep 17 00:00:00 2001 From: wowario <38101080+wowario@users.noreply.github.com> Date: Sat, 7 Jul 2018 13:32:51 +0300 Subject: [PATCH 28/43] bump version to 0.2.2.0 --- src/version.cpp.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.cpp.in b/src/version.cpp.in index a2cf4c7f3..2212a5bd8 100755 --- a/src/version.cpp.in +++ b/src/version.cpp.in @@ -1,5 +1,5 @@ #define DEF_MONERO_VERSION_TAG "@VERSIONTAG@" -#define DEF_MONERO_VERSION "0.2.1.0-master" +#define DEF_MONERO_VERSION "0.2.2.0-master" #define DEF_MONERO_RELEASE_NAME "Busty Brazzers" #define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG -- 2.25.1 From a2d3bc992d3957578880aa9bc7de9a7993420579 Mon Sep 17 00:00:00 2001 From: wowario Date: Mon, 23 Jul 2018 20:57:33 -0700 Subject: [PATCH 29/43] update lwma2 --- src/cryptonote_basic/difficulty.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/cryptonote_basic/difficulty.cpp b/src/cryptonote_basic/difficulty.cpp index f3ff538c8..39e97695d 100644 --- a/src/cryptonote_basic/difficulty.cpp +++ b/src/cryptonote_basic/difficulty.cpp @@ -243,33 +243,35 @@ namespace cryptonote { // LWMA-2 difficulty algorithm // Copyright (c) 2017-2018 Zawy, MIT License -// See commented version in https://github.com/zawy12/difficulty-algorithms/issues/3 -// for required config file changes. +// https://github.com/zawy12/difficulty-algorithms/issues/3 +// See commented version for required config file changes. -difficulty_type next_difficulty_v3(std::vector timestamps, std::vector cumulative_difficulties) { +difficulty_type next_difficulty_v3(std::vector timestamps, std::vector cumulative_difficulties) { int64_t T = DIFFICULTY_TARGET_V2; int64_t N = DIFFICULTY_WINDOW_V2; int64_t FTL = CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V3; int64_t L(0), ST, sum_3_ST(0), next_D, prev_D; + assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= static_cast(N+1) ); + // TODO: change initial_difficulty_guess before v9 mainnet hard fork // if ( height >= fork_height && height <= fork_height+N ) { return difficulty_guess; } - uint64_t initial_difficulty_guess = 100; - if (timestamps.size() <= 6 ) { return initial_difficulty_guess; } - else if ( timestamps.size() < static_cast(N +1) ) { N=timestamps.size()-1; } + uint64_t difficulty_guess = 100; + if (timestamps.size() <= 10 ) { return difficulty_guess; } + if ( timestamps.size() < static_cast(N +1) ) { N = timestamps.size()-1; } for ( int64_t i = 1; i <= N; i++) { - ST = std::max(-FTL, std::min( (int64_t)(timestamps[i]) - (int64_t)(timestamps[i-1]), 6*T)); - L += ST * i ; + ST = std::max(-FTL, std::min( static_cast(timestamps[i]) - static_cast(timestamps[i-1]), 6*T)); + L += ST * i ; if ( i > N-3 ) { sum_3_ST += ST; } } - next_D = ((int64_t)(cumulative_difficulties[N] - cumulative_difficulties[0])*T*(N+1)*99)/(100*2*L); + next_D = (static_cast(cumulative_difficulties[N] - cumulative_difficulties[0])*T*(N+1)*99)/(100*2*L); prev_D = cumulative_difficulties[N] - cumulative_difficulties[N-1]; next_D = std::max((prev_D*67)/100, std::min( next_D, (prev_D*150)/100)); - if ( sum_3_ST < (8*T)/10) { next_D = (prev_D*110)/100; } + if ( sum_3_ST < (8*T)/10) { next_D = std::max(next_D,(prev_D*110)/100); } return static_cast(next_D); } -- 2.25.1 From 4cb1fa324385e760e898d134fe733b7ab57815c2 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 8 Jul 2018 11:01:13 +0100 Subject: [PATCH 30/43] wallet2: ensure outputs are processed only once This should be proof against any way one might get to multiple processing, such as generating the same derivation from the same pubkey, etc --- src/wallet/wallet2.cpp | 31 +++++++++++++++++-------------- src/wallet/wallet2.h | 1 + 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index bb548f0b4..c7e40ace4 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1027,6 +1027,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 &additional_derivations, size_t i, 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, 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; @@ -1107,7 +1117,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(tx.vout.size()); - std::unordered_set public_keys_seen; + std::deque output_found(tx.vout.size(), false); while (!tx.vout.empty()) { // if tx.vout is not empty, we loop through all tx pubkeys @@ -1123,13 +1133,6 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote break; } - if (public_keys_seen.find(pub_key_field.pub_key) != public_keys_seen.end()) - { - MWARNING("The same transaction pubkey is present more than once, ignoring extra instance"); - continue; - } - public_keys_seen.insert(pub_key_field.pub_key); - int num_vouts_received = 0; tx_pub_key = pub_key_field.pub_key; tools::threadpool& tpool = tools::threadpool::getInstance(); @@ -1169,7 +1172,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, tx_scan_info[0]); + check_acc_out_precomp_once(tx.vout[0], derivation, additional_derivations, 0, 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 @@ -1179,8 +1182,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::ref(tx_scan_info[i]))); + 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::ref(tx_scan_info[i]), std::ref(output_found[i]))); } waiter.wait(); // then scan all outputs from 0 @@ -1202,8 +1205,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::ref(tx_scan_info[i]))); + 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::ref(tx_scan_info[i]), std::ref(output_found[i]))); } waiter.wait(); @@ -1224,7 +1227,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, tx_scan_info[i]); + check_acc_out_precomp_once(tx.vout[i], derivation, additional_derivations, i, 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) { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index d996207bd..b85ddc19e 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1109,6 +1109,7 @@ namespace tools bool generate_chacha_key_from_secret_keys(crypto::chacha_key &key) const; crypto::hash get_payment_id(const pending_tx &ptx) const; void check_acc_out_precomp(const cryptonote::tx_out &o, const crypto::key_derivation &derivation, const std::vector &additional_derivations, size_t i, tx_scan_info_t &tx_scan_info) const; + void check_acc_out_precomp_once(const cryptonote::tx_out &o, const crypto::key_derivation &derivation, const std::vector &additional_derivations, size_t i, tx_scan_info_t &tx_scan_info, bool &already_seen) const; void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const; uint64_t get_upper_transaction_size_limit() const; std::vector get_unspent_amounts_vector() const; -- 2.25.1 From e492718cd079af3b4129ba9e992879f7e362208f Mon Sep 17 00:00:00 2001 From: Teutone Date: Mon, 30 Apr 2018 19:01:58 +0200 Subject: [PATCH 31/43] add .load() to make Boost 1.67 happy with its new is_integral check --- src/wallet/api/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 04abae750..9a278e673 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1740,7 +1740,7 @@ void WalletImpl::refreshThreadFunc() // if auto refresh enabled, we wait for the "m_refreshIntervalSeconds" interval. // if not - we wait forever if (m_refreshIntervalMillis > 0) { - boost::posix_time::milliseconds wait_for_ms(m_refreshIntervalMillis); + boost::posix_time::milliseconds wait_for_ms(m_refreshIntervalMillis.load()); m_refreshCV.timed_wait(lock, wait_for_ms); } else { m_refreshCV.wait(lock); -- 2.25.1 From a8966035567572fd038c67293d3decd135a6b4d7 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 27 Jun 2018 18:34:15 +0100 Subject: [PATCH 32/43] blockchain: set the m_verifivation_failed flag in a couple more places when a block being added to the main chain is invalid. This ensures the peer is banned after a number of these. --- src/cryptonote_core/blockchain.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 661bec03a..21f80bfb6 100755 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -3291,6 +3291,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash& if(bl.prev_id != get_tail_id()) { MERROR_VER("Block with id: " << id << std::endl << "has wrong prev_id: " << bl.prev_id << std::endl << "expected: " << get_tail_id()); + bvc.m_verifivation_failed = true; leave: m_db->block_txn_stop(); return false; @@ -3591,6 +3592,7 @@ leave: { //TODO: figure out the best way to deal with this failure LOG_ERROR("Error adding block with hash: " << id << " to blockchain, what = " << e.what()); + bvc.m_verifivation_failed = true; return_tx_to_pool(txs); return false; } -- 2.25.1 From f2b1dca6aa4bb8ba3479d153eb207dc1e8f89739 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 28 Jun 2018 16:37:10 +0100 Subject: [PATCH 33/43] remove epee from link lines where it's redundant For some reason, this confuses and kills ASAN on startup as it thinks const uint8_t ipv4_network_address::ID is defined multiple times. --- src/common/CMakeLists.txt | 1 - src/daemon/CMakeLists.txt | 1 - src/p2p/CMakeLists.txt | 1 - src/rpc/CMakeLists.txt | 1 - src/simplewallet/CMakeLists.txt | 1 - src/wallet/CMakeLists.txt | 1 - tests/unit_tests/CMakeLists.txt | 1 - 7 files changed, 7 deletions(-) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 808ef7630..f0df05b0d 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -78,7 +78,6 @@ monero_add_library(common DEPENDS generate_translations_header) target_link_libraries(common PUBLIC - epee cncrypto ${UNBOUND_LIBRARY} ${LIBUNWIND_LIBRARIES} diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index afeab2c07..3c0ece586 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -92,7 +92,6 @@ target_link_libraries(daemon daemonizer serialization daemon_rpc_server - epee ${EPEE_READLINE} version ${Boost_CHRONO_LIBRARY} diff --git a/src/p2p/CMakeLists.txt b/src/p2p/CMakeLists.txt index 83bdffab5..9b924907e 100644 --- a/src/p2p/CMakeLists.txt +++ b/src/p2p/CMakeLists.txt @@ -38,7 +38,6 @@ source_group(p2p FILES ${P2P}) monero_add_library(p2p ${P2P}) target_link_libraries(p2p PUBLIC - epee version cryptonote_core ${UPNP_LIBRARIES} diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt index 7162317ed..4f8f96524 100644 --- a/src/rpc/CMakeLists.txt +++ b/src/rpc/CMakeLists.txt @@ -111,7 +111,6 @@ target_link_libraries(rpc common cryptonote_core cryptonote_protocol - epee ${Boost_REGEX_LIBRARY} ${Boost_THREAD_LIBRARY} PRIVATE diff --git a/src/simplewallet/CMakeLists.txt b/src/simplewallet/CMakeLists.txt index 83649ec23..02e25156c 100755 --- a/src/simplewallet/CMakeLists.txt +++ b/src/simplewallet/CMakeLists.txt @@ -48,7 +48,6 @@ target_link_libraries(simplewallet cncrypto common mnemonics - epee ${EPEE_READLINE} version ${Boost_CHRONO_LIBRARY} diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 258f7bed9..4d16f312d 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -85,7 +85,6 @@ monero_add_executable(wallet_rpc_server target_link_libraries(wallet_rpc_server PRIVATE wallet - epee rpc_base cryptonote_core cncrypto diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index 9c58536c9..c98e0928e 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -86,7 +86,6 @@ target_link_libraries(unit_tests wallet p2p version - epee ${Boost_CHRONO_LIBRARY} ${Boost_THREAD_LIBRARY} ${GTEST_LIBRARIES} -- 2.25.1 From 39ff8c91c7ae0952d25c37a741a826a51d27b531 Mon Sep 17 00:00:00 2001 From: stoffu Date: Wed, 20 Jun 2018 12:08:40 +0900 Subject: [PATCH 34/43] miner: show id and height when a block is found --- src/cryptonote_basic/miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 2c777f5a2..62cdaaa53 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -485,7 +485,7 @@ namespace cryptonote { //we lucky! ++m_config.current_extra_message_index; - MGINFO_GREEN("Found block for difficulty: " << local_diff); + MGINFO_GREEN("Found block " << get_block_hash(b) << " at height " << height << " for difficulty: " << local_diff); if(!m_phandler->handle_block_found(b)) { --m_config.current_extra_message_index; -- 2.25.1 From a28b9e2e441391d40317d951cb219b50e3bc0adf Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 17 Jun 2018 22:07:15 +0100 Subject: [PATCH 35/43] rpc: add blockchain disk size to getinfo This should help new nodes predict how much disk space will be needed for a full sync --- src/blockchain_db/blockchain_db.h | 7 +++++++ src/blockchain_db/lmdb/db_lmdb.cpp | 11 +++++++++++ src/blockchain_db/lmdb/db_lmdb.h | 2 ++ src/rpc/core_rpc_server.cpp | 2 ++ src/rpc/core_rpc_server_commands_defs.h | 2 ++ tests/unit_tests/hardfork.cpp | 1 + 6 files changed, 25 insertions(+) diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 1ed715315..cf2de55d3 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -1505,6 +1505,13 @@ public: */ virtual bool is_read_only() const = 0; + /** + * @brief get disk space requirements + * + * @return the size required + */ + virtual uint64_t get_database_size() const = 0; + // TODO: this should perhaps be (or call) a series of functions which // progressively update through version updates /** diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index fbf7629c6..732badfc9 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -35,6 +35,7 @@ #include #include "string_tools.h" +#include "file_io_utils.h" #include "common/util.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "crypto/crypto.h" @@ -3293,6 +3294,16 @@ bool BlockchainLMDB::is_read_only() const return false; } +uint64_t BlockchainLMDB::get_database_size() const +{ + uint64_t size = 0; + boost::filesystem::path datafile(m_folder); + datafile /= CRYPTONOTE_BLOCKCHAINDATA_FILENAME; + if (!epee::file_io_utils::get_file_size(datafile.string(), size)) + size = 0; + return size; +} + void BlockchainLMDB::fixup() { LOG_PRINT_L3("BlockchainLMDB::" << __func__); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index f1773bac8..296e23137 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -364,6 +364,8 @@ private: virtual bool is_read_only() const; + virtual uint64_t get_database_size() const; + // fix up anything that may be wrong due to past bugs virtual void fixup(); diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 3ec67e7e0..826882d31 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -207,6 +207,7 @@ namespace cryptonote boost::shared_lock lock(m_bootstrap_daemon_mutex); res.was_bootstrap_ever_used = m_was_bootstrap_ever_used; } + res.database_size = m_core.get_blockchain_storage().get_db().get_database_size(); return true; } //------------------------------------------------------------------------------------------------------------------------------ @@ -1591,6 +1592,7 @@ namespace cryptonote boost::shared_lock lock(m_bootstrap_daemon_mutex); res.was_bootstrap_ever_used = m_was_bootstrap_ever_used; } + res.database_size = m_core.get_blockchain_storage().get_db().get_database_size(); return true; } //------------------------------------------------------------------------------------------------------------------------------ diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 250c88e90..639f76304 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -964,6 +964,7 @@ namespace cryptonote std::string bootstrap_daemon_address; uint64_t height_without_bootstrap; bool was_bootstrap_ever_used; + uint64_t database_size; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(status) @@ -993,6 +994,7 @@ namespace cryptonote KV_SERIALIZE(bootstrap_daemon_address) KV_SERIALIZE(height_without_bootstrap) KV_SERIALIZE(was_bootstrap_ever_used) + KV_SERIALIZE(database_size) END_KV_SERIALIZE_MAP() }; }; diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp index f60b18eef..9c123ae3a 100644 --- a/tests/unit_tests/hardfork.cpp +++ b/tests/unit_tests/hardfork.cpp @@ -122,6 +122,7 @@ public: virtual void remove_txpool_tx(const crypto::hash& txid) {} virtual bool get_txpool_tx_meta(const crypto::hash& txid, txpool_tx_meta_t &meta) const { return false; } virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const { return false; } + virtual uint64_t get_database_size() const { return 0; } virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const { return ""; } virtual bool for_all_txpool_txes(std::function, bool include_blob = false, bool include_unrelayed_txes = false) const { return false; } -- 2.25.1 From fa3ae1a16d384f7985c85d1282967410ee79d542 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 19 May 2018 23:53:05 +0100 Subject: [PATCH 36/43] alt_chain_info can now give more info about a particular alt chain --- src/cryptonote_core/blockchain.cpp | 11 +++++---- src/cryptonote_core/blockchain.h | 2 +- src/daemon/command_parser_executor.cpp | 6 ++--- src/daemon/command_server.cpp | 1 + src/daemon/rpc_command_executor.cpp | 32 ++++++++++++++++++++----- src/daemon/rpc_command_executor.h | 2 +- src/rpc/core_rpc_server.cpp | 16 +++++++++++-- src/rpc/core_rpc_server_commands_defs.h | 4 ++++ 8 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 21f80bfb6..478c90b3d 100755 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -4391,9 +4391,9 @@ std::map> Blockchain:: get_ou return m_db->get_output_histogram(amounts, unlocked, recent_cutoff, min_count); } -std::list> Blockchain::get_alternative_chains() const +std::list>> Blockchain::get_alternative_chains() const { - std::list> chains; + std::list>> chains; for (const auto &i: m_alternative_chains) { @@ -4409,15 +4409,16 @@ std::list> Blockchain::get_a } if (!found) { - uint64_t length = 1; + std::vector chain; auto h = i.second.bl.prev_id; + chain.push_back(top); blocks_ext_by_hash::const_iterator prev; while ((prev = m_alternative_chains.find(h)) != m_alternative_chains.end()) { + chain.push_back(h); h = prev->second.bl.prev_id; - ++length; } - chains.push_back(std::make_pair(i.second, length)); + chains.push_back(std::make_pair(i.second, chain)); } } return chains; diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index cc0ed8181..75763e7a2 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -929,7 +929,7 @@ namespace cryptonote * * @return a list of chains */ - std::list> get_alternative_chains() const; + std::list>> get_alternative_chains() const; void add_txpool_tx(transaction &tx, const txpool_tx_meta_t &meta); void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t &meta); diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index 365c8ba95..ccc767b66 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -599,13 +599,13 @@ bool t_command_parser_executor::print_coinbase_tx_sum(const std::vector& args) { - if(args.size()) + if(args.size() > 1) { - std::cout << "No parameters allowed" << std::endl; + std::cout << "usage: alt_chain_info [block_hash]" << std::endl; return false; } - return m_executor.alt_chain_info(); + return m_executor.alt_chain_info(args.size() == 1 ? args[0] : ""); } bool t_command_parser_executor::print_blockchain_dynamic_stats(const std::vector& args) diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 4f29829e0..74b4f0a53 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -255,6 +255,7 @@ t_command_server::t_command_server( m_command_lookup.set_handler( "alt_chain_info" , std::bind(&t_command_parser_executor::alt_chain_info, &m_parser, p::_1) + , "alt_chain_info [blockhash]" , "Print the information about alternative chains." ); m_command_lookup.set_handler( diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 0a672ba27..a4c97dce6 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -1625,7 +1625,7 @@ bool t_rpc_command_executor::print_coinbase_tx_sum(uint64_t height, uint64_t cou return true; } -bool t_rpc_command_executor::alt_chain_info() +bool t_rpc_command_executor::alt_chain_info(const std::string &tip) { cryptonote::COMMAND_RPC_GET_INFO::request ireq; cryptonote::COMMAND_RPC_GET_INFO::response ires; @@ -1660,12 +1660,32 @@ bool t_rpc_command_executor::alt_chain_info() } } - tools::msg_writer() << boost::lexical_cast(res.chains.size()) << " alternate chains found:"; - for (const auto &chain: res.chains) + if (tip.empty()) { - uint64_t start_height = (chain.height - chain.length + 1); - tools::msg_writer() << chain.length << " blocks long, from height " << start_height << " (" << (ires.height - start_height - 1) - << " deep), diff " << chain.difficulty << ": " << chain.block_hash; + tools::msg_writer() << boost::lexical_cast(res.chains.size()) << " alternate chains found:"; + for (const auto &chain: res.chains) + { + uint64_t start_height = (chain.height - chain.length + 1); + tools::msg_writer() << chain.length << " blocks long, from height " << start_height << " (" << (ires.height - start_height - 1) + << " deep), diff " << chain.difficulty << ": " << chain.block_hash; + } + } + else + { + const auto i = std::find_if(res.chains.begin(), res.chains.end(), [&tip](cryptonote::COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info &info){ return info.block_hash == tip; }); + if (i != res.chains.end()) + { + const auto &chain = *i; + tools::success_msg_writer() << "Found alternate chain with tip " << tip; + uint64_t start_height = (chain.height - chain.length + 1); + tools::msg_writer() << chain.length << " blocks long, from height " << start_height << " (" << (ires.height - start_height - 1) + << " deep), diff " << chain.difficulty << ":"; + for (const std::string &block_id: chain.block_hashes) + tools::msg_writer() << " " << block_id; + tools::msg_writer() << "Chain parent on main chain: " << chain.main_chain_parent_block; + } + else + tools::fail_msg_writer() << "Block hash " << tip << " is not the tip of any known alternate chain"; } return true; } diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index 46168c93b..9e6010c5b 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -143,7 +143,7 @@ public: bool print_coinbase_tx_sum(uint64_t height, uint64_t count); - bool alt_chain_info(); + bool alt_chain_info(const std::string &tip); bool print_blockchain_dynamic_stats(uint64_t nblocks); diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 826882d31..99ed408ea 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1790,10 +1790,22 @@ namespace cryptonote PERF_TIMER(on_get_alternate_chains); try { - std::list> chains = m_core.get_blockchain_storage().get_alternative_chains(); + std::list>> chains = m_core.get_blockchain_storage().get_alternative_chains(); for (const auto &i: chains) { - res.chains.push_back(COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info{epee::string_tools::pod_to_hex(get_block_hash(i.first.bl)), i.first.height, i.second, i.first.cumulative_difficulty}); + res.chains.push_back(COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info{epee::string_tools::pod_to_hex(get_block_hash(i.first.bl)), i.first.height, i.second.size(), i.first.cumulative_difficulty, {}, std::string()}); + res.chains.back().block_hashes.reserve(i.second.size()); + for (const crypto::hash &block_id: i.second) + res.chains.back().block_hashes.push_back(epee::string_tools::pod_to_hex(block_id)); + if (i.first.height < i.second.size()) + { + res.status = "Error finding alternate chain attachment point"; + return true; + } + cryptonote::block main_chain_parent_block; + try { main_chain_parent_block = m_core.get_blockchain_storage().get_db().get_block_from_height(i.first.height - i.second.size()); } + catch (const std::exception &e) { res.status = "Error finding alternate chain attachment point"; return true; } + res.chains.back().main_chain_parent_block = epee::string_tools::pod_to_hex(get_block_hash(main_chain_parent_block)); } res.status = CORE_RPC_STATUS_OK; } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 639f76304..a4f603356 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -2075,12 +2075,16 @@ namespace cryptonote uint64_t height; uint64_t length; uint64_t difficulty; + std::vector block_hashes; + std::string main_chain_parent_block; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(block_hash) KV_SERIALIZE(height) KV_SERIALIZE(length) KV_SERIALIZE(difficulty) + KV_SERIALIZE(block_hashes) + KV_SERIALIZE(main_chain_parent_block) END_KV_SERIALIZE_MAP() }; -- 2.25.1 From 668489a322865bda2acd62c6f347647d5df0594d Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 11 Jul 2018 18:14:22 +0100 Subject: [PATCH 37/43] db_lmdb: don't sync a read only DB This would only throw --- src/blockchain_db/lmdb/db_lmdb.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 732badfc9..cf2acc435 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -1337,6 +1337,9 @@ void BlockchainLMDB::sync() LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); + if (is_read_only()) + return; + // Does nothing unless LMDB environment was opened with MDB_NOSYNC or in part // MDB_NOMETASYNC. Force flush to be synchronous. if (auto result = mdb_env_sync(m_env, true)) -- 2.25.1 From e2a3f7187051601b6e8cd7b057cc6261062f8a05 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 10 Jul 2018 14:37:56 +0100 Subject: [PATCH 38/43] memwipe: don't call the workhorse for 0 bytes Some of them don't like it --- contrib/epee/src/memwipe.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contrib/epee/src/memwipe.c b/contrib/epee/src/memwipe.c index e3a2f76c8..c2a26c392 100644 --- a/contrib/epee/src/memwipe.c +++ b/contrib/epee/src/memwipe.c @@ -50,7 +50,7 @@ void *memwipe(void *ptr, size_t n) { - if (memset_s(ptr, n, 0, n)) + if (n > 0 && memset_s(ptr, n, 0, n)) { #ifdef NDEBUG fprintf(stderr, "Error: memset_s failed\n"); @@ -67,7 +67,8 @@ void *memwipe(void *ptr, size_t n) void *memwipe(void *ptr, size_t n) { - explicit_bzero(ptr, n); + if (n > 0) + explicit_bzero(ptr, n); SCARECROW return ptr; } @@ -105,7 +106,8 @@ static void memory_cleanse(void *ptr, size_t len) void *memwipe(void *ptr, size_t n) { - memory_cleanse(ptr, n); + if (n > 0) + memory_cleanse(ptr, n); SCARECROW return ptr; } -- 2.25.1 From 13e9035505feaebbce4a15096ac525bcd99d0366 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 6 Jul 2018 19:11:01 +0100 Subject: [PATCH 39/43] blockchain: cache next block difficulty after adding a block It's not 100% certain it'll be needed, but it avoids getinfo needing the blockchain lock and potentially blocking --- src/cryptonote_core/blockchain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 478c90b3d..a60c72149 100755 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -3622,6 +3622,7 @@ leave: // appears to be a NOP *and* is called elsewhere. wat? m_tx_pool.on_blockchain_inc(new_height, id); + get_difficulty_for_next_block(); // just to cache it return true; } -- 2.25.1 From db77273f3f8931f2025c5eaa68696c45bc98295f Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 30 Jun 2018 22:06:09 +0100 Subject: [PATCH 40/43] node_rpc_proxy: factor a few RPC calls using get_info Takes advantage of caching --- src/simplewallet/simplewallet.cpp | 7 +-- src/wallet/node_rpc_proxy.cpp | 72 +++++++++++++++---------------- src/wallet/node_rpc_proxy.h | 7 ++- src/wallet/wallet2.cpp | 58 +++++++------------------ 4 files changed, 58 insertions(+), 86 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 447dcd111..316e60273 100755 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -4084,12 +4084,7 @@ uint64_t simple_wallet::get_daemon_blockchain_height(std::string& err) { throw std::runtime_error("simple_wallet null wallet"); } - - COMMAND_RPC_GET_HEIGHT::request req; - COMMAND_RPC_GET_HEIGHT::response res = boost::value_initialized(); - bool r = m_wallet->invoke_http_json("/getheight", req, res); - err = interpret_rpc_response(r, res.status); - return res.height; + return m_wallet->get_daemon_blockchain_height(err); } //---------------------------------------------------------------------------------------------------- bool simple_wallet::show_blockchain_height(const std::vector& args) diff --git a/src/wallet/node_rpc_proxy.cpp b/src/wallet/node_rpc_proxy.cpp index c5d869354..401ada61b 100644 --- a/src/wallet/node_rpc_proxy.cpp +++ b/src/wallet/node_rpc_proxy.cpp @@ -41,21 +41,13 @@ static const std::chrono::seconds rpc_timeout = std::chrono::minutes(3) + std::c NodeRPCProxy::NodeRPCProxy(epee::net_utils::http::http_simple_client &http_client, boost::mutex &mutex) : m_http_client(http_client) , m_daemon_rpc_mutex(mutex) - , m_height(0) - , m_height_time(0) - , m_earliest_height() - , m_dynamic_per_kb_fee_estimate(0) - , m_dynamic_per_kb_fee_estimate_cached_height(0) - , m_dynamic_per_kb_fee_estimate_grace_blocks(0) - , m_rpc_version(0) - , m_target_height(0) - , m_target_height_time(0) -{} +{ + invalidate(); +} void NodeRPCProxy::invalidate() { m_height = 0; - m_height_time = 0; for (size_t n = 0; n < 256; ++n) m_earliest_height[n] = 0; m_dynamic_per_kb_fee_estimate = 0; @@ -63,7 +55,8 @@ void NodeRPCProxy::invalidate() m_dynamic_per_kb_fee_estimate_grace_blocks = 0; m_rpc_version = 0; m_target_height = 0; - m_target_height_time = 0; + m_block_size_limit = 0; + m_get_info_time = 0; } boost::optional NodeRPCProxy::get_rpc_version(uint32_t &rpc_version) const @@ -84,36 +77,15 @@ boost::optional NodeRPCProxy::get_rpc_version(uint32_t &rpc_version return boost::optional(); } -boost::optional NodeRPCProxy::get_height(uint64_t &height) const -{ - const time_t now = time(NULL); - if (m_height == 0 || now >= m_height_time + 30) // re-cache every 30 seconds - { - cryptonote::COMMAND_RPC_GET_HEIGHT::request req = AUTO_VAL_INIT(req); - cryptonote::COMMAND_RPC_GET_HEIGHT::response res = AUTO_VAL_INIT(res); - - m_daemon_rpc_mutex.lock(); - bool r = net_utils::invoke_http_json("/getheight", req, res, m_http_client, rpc_timeout); - m_daemon_rpc_mutex.unlock(); - CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon"); - CHECK_AND_ASSERT_MES(res.status != CORE_RPC_STATUS_BUSY, res.status, "Failed to connect to daemon"); - CHECK_AND_ASSERT_MES(res.status == CORE_RPC_STATUS_OK, res.status, "Failed to get current blockchain height"); - m_height = res.height; - m_height_time = now; - } - height = m_height; - return boost::optional(); -} - void NodeRPCProxy::set_height(uint64_t h) { m_height = h; } -boost::optional NodeRPCProxy::get_target_height(uint64_t &height) const +boost::optional NodeRPCProxy::get_info() const { const time_t now = time(NULL); - if (m_target_height == 0 || now >= m_target_height_time + 30) // re-cache every 30 seconds + if (now >= m_get_info_time + 30) // re-cache every 30 seconds { 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); @@ -125,13 +97,41 @@ boost::optional NodeRPCProxy::get_target_height(uint64_t &height) c CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(resp_t.status != CORE_RPC_STATUS_BUSY, resp_t.status, "Failed to connect to daemon"); CHECK_AND_ASSERT_MES(resp_t.status == CORE_RPC_STATUS_OK, resp_t.status, "Failed to get target blockchain height"); + m_height = resp_t.height; m_target_height = resp_t.target_height; - m_target_height_time = now; + m_block_size_limit = resp_t.block_size_limit; + m_get_info_time = now; } + return boost::optional(); +} + +boost::optional NodeRPCProxy::get_height(uint64_t &height) const +{ + auto res = get_info(); + if (res) + return res; + height = m_height; + return boost::optional(); +} + +boost::optional NodeRPCProxy::get_target_height(uint64_t &height) const +{ + auto res = get_info(); + if (res) + return res; height = m_target_height; return boost::optional(); } +boost::optional NodeRPCProxy::get_block_size_limit(uint64_t &block_size_limit) const +{ + auto res = get_info(); + if (res) + return res; + block_size_limit = m_block_size_limit; + return boost::optional(); +} + boost::optional NodeRPCProxy::get_earliest_height(uint8_t version, uint64_t &earliest_height) const { if (m_earliest_height[version] == 0) diff --git a/src/wallet/node_rpc_proxy.h b/src/wallet/node_rpc_proxy.h index 1b183212d..8a65884f7 100644 --- a/src/wallet/node_rpc_proxy.h +++ b/src/wallet/node_rpc_proxy.h @@ -47,22 +47,25 @@ public: boost::optional get_height(uint64_t &height) const; void set_height(uint64_t h); boost::optional get_target_height(uint64_t &height) const; + boost::optional get_block_size_limit(uint64_t &block_size_limit) const; boost::optional get_earliest_height(uint8_t version, uint64_t &earliest_height) const; boost::optional get_dynamic_per_kb_fee_estimate(uint64_t grace_blocks, uint64_t &fee) const; private: + boost::optional get_info() const; + epee::net_utils::http::http_simple_client &m_http_client; boost::mutex &m_daemon_rpc_mutex; mutable uint64_t m_height; - mutable time_t m_height_time; mutable uint64_t m_earliest_height[256]; mutable uint64_t m_dynamic_per_kb_fee_estimate; mutable uint64_t m_dynamic_per_kb_fee_estimate_cached_height; mutable uint64_t m_dynamic_per_kb_fee_estimate_grace_blocks; mutable uint32_t m_rpc_version; mutable uint64_t m_target_height; - mutable time_t m_target_height_time; + mutable uint64_t m_block_size_limit; + mutable time_t m_get_info_time; }; } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c7e40ace4..5984eb622 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5349,15 +5349,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; @@ -5371,7 +5366,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"); @@ -9115,31 +9110,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 @@ -10381,15 +10360,10 @@ std::vector> 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> blocks; for (const auto &fee_level: fee_levels) -- 2.25.1 From 5b7063c15a652ad027f722847c311e9cca469c7c Mon Sep 17 00:00:00 2001 From: stoffu Date: Thu, 14 Jun 2018 11:15:53 +0900 Subject: [PATCH 41/43] db_lmdb: enable batch transactions by default --- src/blockchain_db/lmdb/db_lmdb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 296e23137..dd7ad7f4e 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -157,7 +157,7 @@ struct mdb_txn_safe class BlockchainLMDB : public BlockchainDB { public: - BlockchainLMDB(bool batch_transactions=false); + BlockchainLMDB(bool batch_transactions=true); ~BlockchainLMDB(); virtual void open(const std::string& filename, const int mdb_flags=0); -- 2.25.1 From 6fa2c65993294e9974845b5f117074470591eea6 Mon Sep 17 00:00:00 2001 From: wowario Date: Sat, 28 Jul 2018 00:47:26 -0500 Subject: [PATCH 42/43] Reset testnet timestamp --- src/wallet/wallet2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index aea308583..26e95fc71 100755 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -9159,7 +9159,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err) uint64_t wallet2::get_approximate_blockchain_height() const { // time of v8 fork - const time_t fork_time = m_nettype == TESTNET ? 1530634467 : m_nettype == STAGENET ? 1530635153 : 1524622167; + const time_t fork_time = m_nettype == TESTNET ? 1532756009 : m_nettype == STAGENET ? 1530635153 : 1524622167; // v8 fork block const uint64_t fork_block = m_nettype == TESTNET ? 10 : m_nettype == STAGENET ? 10 : 6969; // avg seconds per block -- 2.25.1 From 0cae683a75f2cec4cd5b8b6d2e4dbd3205bdd163 Mon Sep 17 00:00:00 2001 From: wowario Date: Wed, 1 Aug 2018 10:32:05 -0500 Subject: [PATCH 43/43] update checkpoints.dat for point release --- src/blocks/checkpoints.dat | Bin 2308 -> 4356 bytes src/cryptonote_core/blockchain.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks/checkpoints.dat b/src/blocks/checkpoints.dat index 43f948ae61549c7d0fe85d378bc5609aff4be932..fe930e38758d7d6e70aced7f2027c641af650a99 100644 GIT binary patch delta 2075 zcmV+$2;}#K5`-cFh_L|!34hr3g<>Cw@r z?r9>z!a0!&y@azWK>eykUFbxB z><8Nto#aou*`8qucfZF{GP4ED;s`U!!r-bt^|H#K1j-UD@6oywwW`erUH+Jvwm$f& ztL|E>sFy-j_-Vg>+<#(h27``!`yY>}VG?|8pqWO3uf5IjZa!JFaAhq1^2B+@5%0U% zIa$slqcXE1Uemw>+ouT(2K+A7=+5GhNuEg!dJsC2Q&933!Nlp9S`&R zCmA&&GGU+v3Xq{b4kO;J^^_F{Iy9-hl(oWC`wA4(Naa2rAZq+J8kh*@1+M;0 zzS=mTTNs1$+uBj*QD;2w{%5PJfc62%+<4Mb~i-`Ih?qJQ}o^o$%F^5)Izn^O@Q%4e`X zrqd^dW6BxkmjIW|4wiSu_|sE11_j-*T+Bx~YGFBQ_z~1G{>m5UqUx@tL#JWEYQ*YT zVZ2qNcEu1{iM+I{*G!CnLSo{6QL|HJUsob3S7i-1d~UVt%_=t>#7BcG z+p3O`tIB72pPkf?w>tho(43*K*aok+<3wF#Vsldl^iBAB8QT6bt_PM5K}4Y+A406% z|9_g)U&mUpbiR%LmAXC3tS`L2$p^Q#)yYPr%9;mOGjz`jdN)apP}K~gS(Z;S>!$fR z*)@iq2gANaWqTh_+s9H>F3Ak_>-3meI-7kxg5c`i7rxRDg>E0R5)odrfhS7F^R&#) ze#HWHIB|ahbOFnwL%HPKWhEi)`W|)%?0?sAYn20LK5V99*uBMY?=rexfq5XP^$zs5 zA;JyLUOXLqu3q6I0;A&3jNn}g-%PL=KaYokaaCi+5hr~Q+fLGx1i+wGIm3>XeA=X*sn5dIJI8LevJ#-a+D|z} zlKcZ%k(1Wd_fS9;-Ia%B*NH`y2jj2SUOMK;C0;BIB`Hk@f3MDhY@c2f1%JvwU=nQY zDu17xoeb*Ep5mPfDMIQv>~U2{-}GB}DAEDP`jRh0srk@YbIlg%C_jJ3k@zj=Z}ws( z`gWOK&QKQ+bYPuKKpY}dQ&|H5xWsV$p*s^o}GVx z1%G{moPc73>Ew>mR?~n&kbge%XTfVTRJR2=_Zl+ohJt2k?n5iEX98`dcb3qB4t|Qj zYpJ*->vR?$Nw2E8rmXW+q|6v6A1PX@-3ybq@57f zlx39|)Y4f5>(yfsEDxo42=wW{#hm z1!k#vKT6(q%%Rxbq`3G3m==1Zg!{xsvzi?^D<{hODVpTBPWf;2u(5eq2Os!k7elSf z@Pf9AXp!PzMZXIMTf;hV()0|*FC-nojFP03Y3g*?aFNeYp%9#izczt97>av*06M9w F_y(5z5a<8^ delta 10 RcmZosY7t`e*vQDt2>=g90z?1+ diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 661bec03a..88111605e 100755 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -4427,7 +4427,7 @@ void Blockchain::cancel() } #if defined(PER_BLOCK_CHECKPOINT) -static const char expected_block_hashes_hash[] = "b81e87c72cf3d1c0567077bb0eac6152a4bba8eeb2b4a7e1b69d1e866d341a3e"; +static const char expected_block_hashes_hash[] = "1ed4338c8e3f8eb877caae719bda776252b3a731be1613e0c4130fc67ea5280a"; void Blockchain::load_compiled_in_block_hashes() { const bool testnet = m_nettype == TESTNET; -- 2.25.1