diff options
-rw-r--r-- | cmake/FindReadline.cmake | 4 | ||||
-rw-r--r-- | contrib/epee/include/misc_log_ex.h | 2 | ||||
-rw-r--r-- | src/blockchain_utilities/blockchain_import.cpp | 4 | ||||
-rw-r--r-- | src/blockchain_utilities/bootstrap_file.cpp | 4 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_basic_impl.cpp | 2 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 2 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 3 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 2 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 37 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.h | 5 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 39 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_commands_defs.h | 3 | ||||
-rw-r--r-- | tests/performance_tests/ge_frombytes_vartime.h | 17 | ||||
-rw-r--r-- | tests/performance_tests/ge_tobytes.h | 79 | ||||
-rw-r--r-- | tests/performance_tests/main.cpp | 2 | ||||
-rw-r--r-- | tests/unit_tests/keccak.cpp | 2 |
18 files changed, 179 insertions, 32 deletions
diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake index de9ddc46d..f26911b26 100644 --- a/cmake/FindReadline.cmake +++ b/cmake/FindReadline.cmake @@ -66,7 +66,9 @@ check_function_exists(rl_copy_text HAVE_COPY_TEXT) check_function_exists(rl_filename_completion_function HAVE_COMPLETION_FUNCTION) if(NOT HAVE_COMPLETION_FUNCTION) - set(CMAKE_REQUIRED_LIBRARIES ${Readline_LIBRARY} ${Termcap_LIBRARY}) + if (Readline_LIBRARY) + set(CMAKE_REQUIRED_LIBRARIES ${Readline_LIBRARY} ${Termcap_LIBRARY}) + endif(Readline_LIBRARY) check_function_exists(rl_copy_text HAVE_COPY_TEXT_TC) check_function_exists(rl_filename_completion_function HAVE_COMPLETION_FUNCTION_TC) set(HAVE_COMPLETION_FUNCTION ${HAVE_COMPLETION_FUNCTION_TC}) diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index 530f8e636..9100a8db3 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -32,7 +32,9 @@ #include "easylogging++.h" +#undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "default" + #define MAX_LOG_FILE_SIZE 104850000 // 100 MB - 7600 bytes #define MAX_LOG_FILES 50 diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index 7f92ecd87..eae078ea2 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -396,7 +396,7 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path { std::cout << refresh_string << "block " << h-1 << " / " << block_stop - << std::flush; + << "\r" << std::flush; std::cout << ENDL << ENDL; MINFO("Specified block number reached - stopping. block: " << h-1 << " total blocks: " << h); quit = 1; @@ -432,7 +432,7 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path { std::cout << refresh_string << "block " << h-1 << " / " << block_stop - << std::flush; + << "\r" << std::flush; } if (opt_verify) diff --git a/src/blockchain_utilities/bootstrap_file.cpp b/src/blockchain_utilities/bootstrap_file.cpp index beaad2abc..a8c46d661 100644 --- a/src/blockchain_utilities/bootstrap_file.cpp +++ b/src/blockchain_utilities/bootstrap_file.cpp @@ -304,7 +304,7 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem } if (m_cur_height % progress_interval == 0) { std::cout << refresh_string; - std::cout << "block " << m_cur_height << "/" << block_stop << std::flush; + std::cout << "block " << m_cur_height << "/" << block_stop << "\r" << std::flush; } } // NOTE: use of NUM_BLOCKS_PER_CHUNK is a placeholder in case multi-block chunks are later supported. @@ -479,7 +479,7 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::s bytes_read += count_bytes(import_file, progress_interval, blocks, quit); h += blocks; std::cout << "\r" << "block height: " << h-1 << - " " << + " \r" << std::flush; // std::cout << refresh_string; diff --git a/src/cryptonote_basic/cryptonote_basic_impl.cpp b/src/cryptonote_basic/cryptonote_basic_impl.cpp index b18ef1c5c..c4e10851e 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.cpp +++ b/src/cryptonote_basic/cryptonote_basic_impl.cpp @@ -328,7 +328,7 @@ bool parse_hash256(const std::string str_hash, crypto::hash& hash) bool res = epee::string_tools::parse_hexstr_to_binbuff(str_hash, buf); if (!res || buf.size() != sizeof(crypto::hash)) { - std::cout << "invalid hash format: <" << str_hash << '>' << std::endl; + MERROR("invalid hash format: " << str_hash); return false; } else diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 77b6d0b69..e908c2012 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -2530,7 +2530,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, } } - if (hf_version >= HF_VERSION_MIN_MIXIN_10 && mixin != 10) + if (((hf_version == HF_VERSION_MIN_MIXIN_10 || hf_version == HF_VERSION_MIN_MIXIN_10+1) && mixin != 10) || (hf_version >= HF_VERSION_MIN_MIXIN_10+2 && mixin > 10)) { MERROR_VER("Tx " << get_transaction_hash(tx) << " has invalid ring size (" << (mixin + 1) << "), it should be 11"); tvc.m_low_mixin = true; diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 4b806c282..c405c996a 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1716,7 +1716,8 @@ namespace cryptonote for (size_t n = 0; n < sizeof(seconds)/sizeof(seconds[0]); ++n) { unsigned int b = 0; - for (time_t ts: timestamps) b += ts >= now - static_cast<time_t>(seconds[n]); + const time_t time_boundary = now - static_cast<time_t>(seconds[n]); + for (time_t ts: timestamps) b += ts >= time_boundary; const double p = probability(b, seconds[n] / DIFFICULTY_TARGET_V2); MDEBUG("blocks in the last " << seconds[n] / 60 << " minutes: " << b << " (probability " << p << ")"); if (p < threshold) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 574f6c126..6c1972a3f 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -701,7 +701,7 @@ namespace cryptonote res.status = "Failed"; res.reason = ""; if ((res.low_mixin = tvc.m_low_mixin)) - add_reason(res.reason, "ring size too small"); + add_reason(res.reason, "bad ring size"); if ((res.double_spend = tvc.m_double_spend)) add_reason(res.reason, "double spend"); if ((res.invalid_input = tvc.m_invalid_input)) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index a711943e8..702ff22cb 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2547,6 +2547,7 @@ simple_wallet::simple_wallet() tr("Show the unspent outputs of a specified address within an optional amount range.")); m_cmd_binder.set_handler("rescan_bc", boost::bind(&simple_wallet::rescan_blockchain, this, _1), + tr("rescan_bc [hard]"), tr("Rescan the blockchain from scratch, losing any information which can not be recovered from the blockchain itself.")); m_cmd_binder.set_handler("set_tx_note", boost::bind(&simple_wallet::set_tx_note, this, _1), @@ -4298,15 +4299,15 @@ boost::optional<epee::wipeable_string> simple_wallet::on_get_password(const char return pwd_container->password(); } //---------------------------------------------------------------------------------------------------- -bool simple_wallet::refresh_main(uint64_t start_height, bool reset, bool is_init) +bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bool is_init) { if (!try_connect_to_daemon(is_init)) return true; LOCK_IDLE_SCOPE(); - if (reset) - m_wallet->rescan_blockchain(false); + if (reset != ResetNone) + m_wallet->rescan_blockchain(reset == ResetHard, false); #ifdef HAVE_READLINE rdln::suspend_readline pause_readline; @@ -4385,7 +4386,7 @@ bool simple_wallet::refresh(const std::vector<std::string>& args) start_height = 0; } } - return refresh_main(start_height, false); + return refresh_main(start_height, ResetNone); } //---------------------------------------------------------------------------------------------------- bool simple_wallet::show_balance_unlocked(bool detailed) @@ -7097,15 +7098,29 @@ bool simple_wallet::unspent_outputs(const std::vector<std::string> &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::rescan_blockchain(const std::vector<std::string> &args_) { - message_writer() << tr("Warning: this will lose any information which can not be recovered from the blockchain."); - message_writer() << tr("This includes destination addresses, tx secret keys, tx notes, etc"); - std::string confirm = input_line(tr("Rescan anyway ? (Y/Yes/N/No): ")); - if(!std::cin.eof()) + bool hard = false; + if (!args_.empty()) { - if (!command_line::is_yes(confirm)) + if (args_[0] != "hard") + { + fail_msg_writer() << tr("usage: rescan_bc [hard]"); return true; + } + hard = true; + } + + if (hard) + { + message_writer() << tr("Warning: this will lose any information which can not be recovered from the blockchain."); + message_writer() << tr("This includes destination addresses, tx secret keys, tx notes, etc"); + std::string confirm = input_line(tr("Rescan anyway ? (Y/Yes/N/No): ")); + if(!std::cin.eof()) + { + if (!command_line::is_yes(confirm)) + return true; + } } - return refresh_main(0, true); + return refresh_main(0, hard ? ResetHard : ResetSoft, true); } //---------------------------------------------------------------------------------------------------- void simple_wallet::wallet_idle_thread() @@ -7153,7 +7168,7 @@ bool simple_wallet::run() // check and display warning, but go on anyway try_connect_to_daemon(); - refresh_main(0, false, true); + refresh_main(0, ResetNone, true); m_auto_refresh_enabled = m_wallet->auto_refresh(); m_idle_thread = boost::thread([&]{wallet_idle_thread();}); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 7d813ceb0..26d51a431 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -83,6 +83,9 @@ namespace cryptonote std::string get_commands_str(); std::string get_command_usage(const std::vector<std::string> &args); private: + + enum ResetType { ResetNone, ResetSoft, ResetHard }; + bool handle_command_line(const boost::program_options::variables_map& vm); bool run_console_handler(); @@ -189,7 +192,7 @@ namespace cryptonote bool show_transfers(const std::vector<std::string> &args); bool unspent_outputs(const std::vector<std::string> &args); bool rescan_blockchain(const std::vector<std::string> &args); - bool refresh_main(uint64_t start_height, bool reset = false, bool is_init = false); + bool refresh_main(uint64_t start_height, ResetType reset, bool is_init = false); bool set_tx_note(const std::vector<std::string> &args); bool get_tx_note(const std::vector<std::string> &args); bool set_description(const std::vector<std::string> &args); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a5faee71b..58ed5dcad 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5105,11 +5105,27 @@ void wallet2::rescan_spent() } } //---------------------------------------------------------------------------------------------------- -void wallet2::rescan_blockchain(bool refresh) +void wallet2::rescan_blockchain(bool hard, bool refresh) { - clear(); + if(hard) + { + clear(); + setup_new_blockchain(); + } + else + { + m_blockchain.clear(); + m_transfers.clear(); + m_key_images.clear(); + m_pub_keys.clear(); + m_scanned_pool_txs[0].clear(); + m_scanned_pool_txs[1].clear(); - setup_new_blockchain(); + cryptonote::block b; + generate_genesis(b); + m_blockchain.push_back(get_block_hash(b)); + m_last_block_reward = cryptonote::get_outs_money_amount(b.miner_tx); + } if (refresh) this->refresh(false); @@ -7199,6 +7215,9 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> break; } } + bool use_histogram = amount != 0 || !has_rct_distribution; + if (!use_histogram) + num_outs = rct_offsets[rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE]; // make sure the real outputs we asked for are really included, along // with the correct key and mask: this guards against an active attack @@ -7291,6 +7310,20 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> outs.push_back(v); } } + + // save those outs in the ringdb for reuse + for (size_t i = 0; i < selected_transfers.size(); ++i) + { + const size_t idx = selected_transfers[i]; + THROW_WALLET_EXCEPTION_IF(idx >= m_transfers.size(), error::wallet_internal_error, "selected_transfers entry out of range"); + const transfer_details &td = m_transfers[idx]; + std::vector<uint64_t> ring; + ring.reserve(outs[i].size()); + for (const auto &e: outs[i]) + ring.push_back(std::get<0>(e)); + if (!set_ring(td.m_key_image, ring, false)) + MERROR("Failed to set ring for " << td.m_key_image); + } } template<typename T> diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 1ae76a4b7..dbfd45c53 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -788,7 +788,7 @@ namespace tools uint64_t get_blockchain_current_height() const { return m_light_wallet_blockchain_height ? m_light_wallet_blockchain_height : m_blockchain.size(); } void rescan_spent(); - void rescan_blockchain(bool refresh = true); + void rescan_blockchain(bool hard, bool refresh = true); bool is_transfer_unlocked(const transfer_details& td) const; bool is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height) const; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index eabdd9a6a..d91a69ed1 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -1781,7 +1781,7 @@ namespace tools try { - m_wallet->rescan_blockchain(); + m_wallet->rescan_blockchain(req.hard); } catch (const std::exception& e) { diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 026b75a9e..20cd65e8e 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -1057,7 +1057,10 @@ namespace wallet_rpc { struct request { + bool hard; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(hard, false); END_KV_SERIALIZE_MAP() }; diff --git a/tests/performance_tests/ge_frombytes_vartime.h b/tests/performance_tests/ge_frombytes_vartime.h index ef9625d6b..3f7d55182 100644 --- a/tests/performance_tests/ge_frombytes_vartime.h +++ b/tests/performance_tests/ge_frombytes_vartime.h @@ -49,22 +49,29 @@ public: if (!base_class::init()) return false; + cryptonote::account_base m_alice; + cryptonote::transaction m_tx; + m_alice.generate(); std::vector<tx_destination_entry> destinations; destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false)); - return construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx, 0); + if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx, 0)) + return false; + + const cryptonote::txin_to_key& txin = boost::get<cryptonote::txin_to_key>(m_tx.vin[0]); + m_key = rct::ki2rct(txin.k_image); + + return true; } bool test() { ge_p3 unp; - const cryptonote::txin_to_key& txin = boost::get<cryptonote::txin_to_key>(m_tx.vin[0]); - return ge_frombytes_vartime(&unp, (const unsigned char*) &txin.k_image) == 0; + return ge_frombytes_vartime(&unp, (const unsigned char*) &m_key) == 0; } private: - cryptonote::account_base m_alice; - cryptonote::transaction m_tx; + rct::key m_key; }; diff --git a/tests/performance_tests/ge_tobytes.h b/tests/performance_tests/ge_tobytes.h new file mode 100644 index 000000000..3d46f4838 --- /dev/null +++ b/tests/performance_tests/ge_tobytes.h @@ -0,0 +1,79 @@ +// Copyright (c) 2014-2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#pragma once + +#include "crypto/crypto.h" +#include "cryptonote_basic/cryptonote_basic.h" + +#include "single_tx_test_base.h" + +class test_ge_tobytes : public multi_tx_test_base<1> +{ +public: + static const size_t loop_count = 10000; + + typedef multi_tx_test_base<1> base_class; + + bool init() + { + using namespace cryptonote; + + if (!base_class::init()) + return false; + + cryptonote::account_base m_alice; + cryptonote::transaction m_tx; + + m_alice.generate(); + + std::vector<tx_destination_entry> destinations; + destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false)); + + if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx, 0)) + return false; + + const cryptonote::txin_to_key& txin = boost::get<cryptonote::txin_to_key>(m_tx.vin[0]); + if (ge_frombytes_vartime(&m_p3, (const unsigned char*) &txin.k_image) != 0) + return false; + + return true; + } + + bool test() + { + rct::key key; + ge_p3_tobytes(key.bytes, &m_p3); + return true; + } + +private: + ge_p3 m_p3; +}; diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index 3765d1249..58daf6220 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -42,6 +42,7 @@ #include "derive_public_key.h" #include "derive_secret_key.h" #include "ge_frombytes_vartime.h" +#include "ge_tobytes.h" #include "generate_key_derivation.h" #include "generate_key_image.h" #include "generate_key_image_helper.h" @@ -183,6 +184,7 @@ int main(int argc, char** argv) TEST_PERFORMANCE0(filter, p, test_derive_public_key); TEST_PERFORMANCE0(filter, p, test_derive_secret_key); TEST_PERFORMANCE0(filter, p, test_ge_frombytes_vartime); + TEST_PERFORMANCE0(filter, p, test_ge_tobytes); TEST_PERFORMANCE0(filter, p, test_generate_keypair); TEST_PERFORMANCE0(filter, p, test_sc_reduce32); TEST_PERFORMANCE0(filter, p, test_sc_check); diff --git a/tests/unit_tests/keccak.cpp b/tests/unit_tests/keccak.cpp index 4276b0e1d..37da65d76 100644 --- a/tests/unit_tests/keccak.cpp +++ b/tests/unit_tests/keccak.cpp @@ -37,7 +37,7 @@ extern "C" { #define TEST_KECCAK(sz, chunks) \ std::string data; \ data.resize(sz); \ - for (size_t i = 0; i < sz; ++i) \ + for (size_t i = 0; i < data.size(); ++i) \ data[i] = i * 17; \ uint8_t md0[32], md1[32]; \ keccak((const uint8_t*)data.data(), data.size(), md0, 32); \ |