aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/FindReadline.cmake4
-rw-r--r--contrib/epee/include/misc_log_ex.h2
-rw-r--r--src/blockchain_utilities/blockchain_import.cpp4
-rw-r--r--src/blockchain_utilities/bootstrap_file.cpp4
-rw-r--r--src/cryptonote_basic/cryptonote_basic_impl.cpp2
-rw-r--r--src/cryptonote_core/blockchain.cpp2
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp3
-rw-r--r--src/rpc/core_rpc_server.cpp2
-rw-r--r--src/simplewallet/simplewallet.cpp37
-rw-r--r--src/simplewallet/simplewallet.h5
-rw-r--r--src/wallet/wallet2.cpp39
-rw-r--r--src/wallet/wallet2.h2
-rw-r--r--src/wallet/wallet_rpc_server.cpp2
-rw-r--r--src/wallet/wallet_rpc_server_commands_defs.h3
-rw-r--r--tests/performance_tests/ge_frombytes_vartime.h17
-rw-r--r--tests/performance_tests/ge_tobytes.h79
-rw-r--r--tests/performance_tests/main.cpp2
-rw-r--r--tests/unit_tests/keccak.cpp2
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); \