diff options
57 files changed, 536 insertions, 702 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 637e9c4e6..357719ffd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,10 @@ if (UNIX AND NOT APPLE) endif() # Handle OpenSSL, used for sha256sum on binary updates and light wallet ssl http +if (CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads") +endif () + if (APPLE AND NOT IOS) if (NOT OpenSSL_DIR) EXECUTE_PROCESS(COMMAND brew --prefix openssl @@ -675,6 +679,8 @@ elseif(FREEBSD) elseif(DRAGONFLY) find_library(COMPAT compat) set(EXTRA_LIBRARIES execinfo ${COMPAT}) +elseif(CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)") + set(EXTRA_LIBRARIES socket nsl resolv) elseif(NOT MSVC) find_library(RT rt) set(EXTRA_LIBRARIES ${RT}) @@ -688,8 +694,8 @@ if(USE_READLINE) if(READLINE_FOUND AND GNU_READLINE_FOUND) add_definitions(-DHAVE_READLINE) include_directories(${Readline_INCLUDE_DIR}) - list(APPEND EXTRA_LIBRARIES ${Readline_LIBRARY}) message(STATUS "Found readline library at: ${Readline_ROOT_DIR}") + set(EPEE_READLINE epee_readline) else() message(STATUS "Could not find GNU readline library so building without readline support") endif() @@ -430,6 +430,17 @@ doas make install Build monero: `env DEVELOPER_LOCAL_TOOLS=1 BOOST_ROOT=/usr/local make release-static` +### On Solaris: + +The default Solaris linker can't be used, you have to install GNU ld, then run cmake manually with the path to your copy of GNU ld: + + mkdir -p build/release + cd build/release + cmake -DCMAKE_LINKER=/path/to/ld -D CMAKE_BUILD_TYPE=Release ../.. + cd ../.. + +Then you can run make as usual. + ### On Linux for Android (using docker): # Build image (select android64.Dockerfile for aarch64) diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index 80a4504e3..d77c84c28 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -66,8 +66,6 @@ namespace epee namespace net_utils { -using namespace std; - /*struct url { public: diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt index 3b41f415e..bd6714791 100644 --- a/contrib/epee/src/CMakeLists.txt +++ b/contrib/epee/src/CMakeLists.txt @@ -26,10 +26,9 @@ # 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. +add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp) if (USE_READLINE AND GNU_READLINE_FOUND) - add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp readline_buffer.cpp) -else() - add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp) + add_library(epee_readline STATIC readline_buffer.cpp) endif() # Build and install libepee if we're building for GUI @@ -41,6 +40,10 @@ if (BUILD_GUI_DEPS) endif() install(TARGETS epee ARCHIVE DESTINATION ${lib_folder}) + if (USE_READLINE AND GNU_READLINE_FOUND) + install(TARGETS epee_readline + ARCHIVE DESTINATION ${lib_folder}) + endif() endif() target_link_libraries(epee @@ -51,3 +54,11 @@ target_link_libraries(epee PRIVATE ${OPENSSL_LIBRARIES} ${EXTRA_LIBRARIES}) + +if (USE_READLINE AND GNU_READLINE_FOUND) + target_link_libraries(epee_readline + PUBLIC + easylogging + PRIVATE + ${Readline_LIBRARY}) +endif() diff --git a/external/miniupnpc/CMakeLists.txt b/external/miniupnpc/CMakeLists.txt index 4c01b6d06..bc9685699 100644 --- a/external/miniupnpc/CMakeLists.txt +++ b/external/miniupnpc/CMakeLists.txt @@ -36,6 +36,9 @@ if (NOT WIN32) # add_definitions (-D_POSIX_C_SOURCE=200112L) add_definitions (-D_XOPEN_SOURCE=600) endif (NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" AND NOT CMAKE_SYSTEM_NAME STREQUAL "DragonFly") + if (CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)") + add_definitions (-D__EXTENSIONS__ -std=c99) + endif () else (NOT WIN32) add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends endif (NOT WIN32) diff --git a/external/unbound/CMakeLists.txt b/external/unbound/CMakeLists.txt index 8ac4bbd84..a2e475232 100644 --- a/external/unbound/CMakeLists.txt +++ b/external/unbound/CMakeLists.txt @@ -44,7 +44,12 @@ endif () set(RETSIGTYPE void) +if(CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)") +add_definitions(-D_XOPEN_SOURCE=600) +else() add_definitions(-D_GNU_SOURCE) +endif() +add_definitions(-std=c99) option(USE_ECDSA "Use ECDSA algorithms" ON) option(USE_SHA2 "Enable SHA2 support" ON) diff --git a/external/unbound/configure_checks.cmake b/external/unbound/configure_checks.cmake index 258f28138..2acf556d1 100644 --- a/external/unbound/configure_checks.cmake +++ b/external/unbound/configure_checks.cmake @@ -49,6 +49,11 @@ if (WIN32) iphlpapi ws2_32) endif () +if (CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)") + set(CMAKE_REQUIRED_LIBRARIES + socket + nsl) +endif () check_function_exists(_beginthreadex HAVE__BEGINTHREADEX) check_function_exists(arc4random HAVE_ARC4RANDOM) diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index d62a250ff..c3f6e3d87 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -208,7 +208,7 @@ uint64_t BlockchainDB::add_block( const block& blk time1 = epee::misc_utils::get_tick_count(); add_transaction(blk_hash, blk.miner_tx); int tx_i = 0; - crypto::hash tx_hash = null_hash; + crypto::hash tx_hash = crypto::null_hash; for (const transaction& tx : txs) { tx_hash = blk.tx_hashes[tx_i]; diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 6cf74b3b0..865558e07 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -49,6 +49,7 @@ #endif using epee::string_tools::pod_to_hex; +using namespace crypto; // Increase when the DB changes in a non backward compatible way, and there // is no automatic conversion, so that a full resync is needed. diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp index 60672eeda..78bb51ab6 100644 --- a/src/blockchain_utilities/blockchain_export.cpp +++ b/src/blockchain_utilities/blockchain_export.cpp @@ -30,6 +30,7 @@ #include "blocksdat_file.h" #include "common/command_line.h" #include "cryptonote_core/tx_pool.h" +#include "cryptonote_core/cryptonote_core.h" #include "blockchain_db/blockchain_db.h" #include "blockchain_db/db_types.h" #include "version.h" @@ -66,21 +67,16 @@ int main(int argc, char* argv[]) const command_line::arg_descriptor<std::string> arg_output_file = {"output-file", "Specify output file", "", true}; const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""}; const command_line::arg_descriptor<uint64_t> arg_block_stop = {"block-stop", "Stop at block number", block_stop}; - const command_line::arg_descriptor<bool> arg_testnet_on = { - "testnet" - , "Run on testnet." - , false - }; const command_line::arg_descriptor<std::string> arg_database = { "database", available_dbs.c_str(), default_db_type }; const command_line::arg_descriptor<bool> arg_blocks_dat = {"blocksdat", "Output in blocks.dat format", blocks_dat}; - command_line::add_arg(desc_cmd_sett, command_line::arg_data_dir, default_data_path.string()); - command_line::add_arg(desc_cmd_sett, command_line::arg_testnet_data_dir, default_testnet_data_path.string()); + command_line::add_arg(desc_cmd_sett, cryptonote::arg_data_dir, default_data_path.string()); + command_line::add_arg(desc_cmd_sett, cryptonote::arg_testnet_data_dir, default_testnet_data_path.string()); command_line::add_arg(desc_cmd_sett, arg_output_file); - command_line::add_arg(desc_cmd_sett, arg_testnet_on); + command_line::add_arg(desc_cmd_sett, cryptonote::arg_testnet_on); command_line::add_arg(desc_cmd_sett, arg_log_level); command_line::add_arg(desc_cmd_sett, arg_database); command_line::add_arg(desc_cmd_sett, arg_block_stop); @@ -117,12 +113,12 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("Starting..."); - bool opt_testnet = command_line::get_arg(vm, arg_testnet_on); + bool opt_testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on); bool opt_blocks_dat = command_line::get_arg(vm, arg_blocks_dat); std::string m_config_folder; - auto data_dir_arg = opt_testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir; + auto data_dir_arg = opt_testnet ? cryptonote::arg_testnet_data_dir : cryptonote::arg_data_dir; m_config_folder = command_line::get_arg(vm, data_dir_arg); std::string db_type = command_line::get_arg(vm, arg_database); diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index 2a956dbdb..a50b0bad6 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -256,7 +256,7 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path seek_height = start_height; BootstrapFile bootstrap; - streampos pos; + std::streampos pos; // BootstrapFile bootstrap(import_file_path); uint64_t total_source_blocks = bootstrap.count_blocks(import_file_path, pos, seek_height); MINFO("bootstrap file last block number: " << total_source_blocks-1 << " (zero-based height) total blocks: " << total_source_blocks); @@ -585,11 +585,6 @@ int main(int argc, char* argv[]) const command_line::arg_descriptor<uint64_t> arg_batch_size = {"batch-size", "", db_batch_size}; const command_line::arg_descriptor<uint64_t> arg_pop_blocks = {"pop-blocks", "Remove blocks from end of blockchain", num_blocks}; const command_line::arg_descriptor<bool> arg_drop_hf = {"drop-hard-fork", "Drop hard fork subdbs", false}; - const command_line::arg_descriptor<bool> arg_testnet_on = { - "testnet" - , "Run on testnet." - , false - }; const command_line::arg_descriptor<bool> arg_count_blocks = { "count-blocks" , "Count blocks in bootstrap file and exit" @@ -674,8 +669,8 @@ int main(int argc, char* argv[]) } } - opt_testnet = command_line::get_arg(vm, arg_testnet_on); - auto data_dir_arg = opt_testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir; + opt_testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on); + auto data_dir_arg = opt_testnet ? cryptonote::arg_testnet_data_dir : cryptonote::arg_data_dir; m_config_folder = command_line::get_arg(vm, data_dir_arg); db_arg_str = command_line::get_arg(vm, arg_database); diff --git a/src/blockchain_utilities/bootstrap_file.cpp b/src/blockchain_utilities/bootstrap_file.cpp index a004d3547..2c993460a 100644 --- a/src/blockchain_utilities/bootstrap_file.cpp +++ b/src/blockchain_utilities/bootstrap_file.cpp @@ -221,7 +221,7 @@ void BootstrapFile::write_block(block& block) // now add all regular transactions for (const auto& tx_id : block.tx_hashes) { - if (tx_id == null_hash) + if (tx_id == crypto::null_hash) { throw std::runtime_error("Aborting: tx == null_hash"); } @@ -433,7 +433,7 @@ uint64_t BootstrapFile::count_bytes(std::ifstream& import_file, uint64_t blocks, uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) { - streampos dummy_pos; + std::streampos dummy_pos; uint64_t dummy_height = 0; return count_blocks(import_file_path, dummy_pos, dummy_height); } @@ -441,7 +441,7 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) // If seek_height is non-zero on entry, return a stream position <= this height when finished. // And return the actual height corresponding to this position. Allows the caller to locate its // starting position without having to reread the entire file again. -uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, streampos &start_pos, uint64_t& seek_height) +uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::streampos &start_pos, uint64_t& seek_height) { boost::filesystem::path raw_file_path(import_file_path); boost::system::error_code ec; diff --git a/src/blockchain_utilities/bootstrap_file.h b/src/blockchain_utilities/bootstrap_file.h index c3969a357..0926ee2e5 100644 --- a/src/blockchain_utilities/bootstrap_file.h +++ b/src/blockchain_utilities/bootstrap_file.h @@ -57,7 +57,7 @@ class BootstrapFile public: uint64_t count_bytes(std::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit); - uint64_t count_blocks(const std::string& dir_path, streampos& start_pos, uint64_t& seek_height); + uint64_t count_blocks(const std::string& dir_path, std::streampos& start_pos, uint64_t& seek_height); uint64_t count_blocks(const std::string& dir_path); uint64_t seek_to_first_chunk(std::ifstream& import_file); diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index d4a28fc85..4b9ca9559 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -36,10 +36,6 @@ #include "cryptonote_config.h" #include "string_tools.h" -#ifdef HAVE_READLINE - #include "readline_buffer.h" -#endif - namespace command_line { namespace @@ -50,20 +46,6 @@ namespace command_line } } - std::string input_line(const std::string& prompt) - { -#ifdef HAVE_READLINE - rdln::suspend_readline pause_readline; -#endif - std::cout << prompt; - - std::string buf; - std::getline(std::cin, buf); - - return epee::string_tools::trim(buf); - - } - bool is_yes(const std::string& str) { if (str == "y" || str == "Y") @@ -94,49 +76,4 @@ namespace command_line const arg_descriptor<bool> arg_help = {"help", "Produce help message"}; const arg_descriptor<bool> arg_version = {"version", "Output version information"}; - const arg_descriptor<std::string> arg_data_dir = {"data-dir", "Specify data directory"}; - const arg_descriptor<std::string> arg_testnet_data_dir = {"testnet-data-dir", "Specify testnet data directory"}; - const arg_descriptor<bool> arg_test_drop_download = {"test-drop-download", "For net tests: in download, discard ALL blocks instead checking/saving them (very fast)"}; - const arg_descriptor<uint64_t> arg_test_drop_download_height = {"test-drop-download-height", "Like test-drop-download but disards only after around certain height", 0}; - const arg_descriptor<int> arg_test_dbg_lock_sleep = {"test-dbg-lock-sleep", "Sleep time in ms, defaults to 0 (off), used to debug before/after locking mutex. Values 100 to 1000 are good for tests."}; - const arg_descriptor<bool, false> arg_testnet_on = { - "testnet" - , "Run on testnet. The wallet must be launched with --testnet flag." - , false - }; - const arg_descriptor<bool> arg_dns_checkpoints = { - "enforce-dns-checkpointing" - , "checkpoints from DNS server will be enforced" - , false - }; - const command_line::arg_descriptor<uint64_t> arg_fast_block_sync = { - "fast-block-sync" - , "Sync up most of the way by using embedded, known block hashes." - , 1 - }; - const command_line::arg_descriptor<uint64_t> arg_prep_blocks_threads = { - "prep-blocks-threads" - , "Max number of threads to use when preparing block hashes in groups." - , 4 - }; - const command_line::arg_descriptor<uint64_t> arg_show_time_stats = { - "show-time-stats" - , "Show time-stats when processing blocks/txs and disk synchronization." - , 0 - }; - const command_line::arg_descriptor<size_t> arg_block_sync_size = { - "block-sync-size" - , "How many blocks to sync at once during chain synchronization (0 = adaptive)." - , 0 - }; - const command_line::arg_descriptor<std::string> arg_check_updates = { - "check-updates" - , "Check for new versions of monero: [disabled|notify|download|update]" - , "notify" - }; - const arg_descriptor<bool> arg_fluffy_blocks = { - "fluffy-blocks" - , "Relay blocks as fluffy blocks where possible (automatic on testnet)" - , false - }; } diff --git a/src/common/command_line.h b/src/common/command_line.h index bfc8b19c6..c2bac9cc8 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -41,8 +41,6 @@ namespace command_line { - std::string input_line(const std::string& prompt); - //! \return True if `str` is `is_iequal("y" || "yes" || `tr("yes"))`. bool is_yes(const std::string& str); //! \return True if `str` is `is_iequal("n" || "no" || `tr("no"))`. @@ -213,17 +211,4 @@ namespace command_line extern const arg_descriptor<bool> arg_help; extern const arg_descriptor<bool> arg_version; - extern const arg_descriptor<std::string> arg_data_dir; - extern const arg_descriptor<std::string> arg_testnet_data_dir; - extern const arg_descriptor<bool> arg_test_drop_download; - extern const arg_descriptor<uint64_t> arg_test_drop_download_height; - extern const arg_descriptor<int> arg_test_dbg_lock_sleep; - extern const arg_descriptor<bool, false> arg_testnet_on; - extern const arg_descriptor<bool> arg_dns_checkpoints; - extern const arg_descriptor<uint64_t> arg_fast_block_sync; - extern const arg_descriptor<uint64_t> arg_prep_blocks_threads; - extern const arg_descriptor<uint64_t> arg_show_time_stats; - extern const arg_descriptor<size_t> arg_block_sync_size; - extern const arg_descriptor<std::string> arg_check_updates; - extern const arg_descriptor<bool> arg_fluffy_blocks; } diff --git a/src/common/int-util.h b/src/common/int-util.h index 34288805a..7cec571ad 100644 --- a/src/common/int-util.h +++ b/src/common/int-util.h @@ -40,6 +40,10 @@ #include <byteswap.h> #endif +#if defined(__sun) && defined(__SVR4) +#include <endian.h> +#endif + #if defined(_MSC_VER) #include <stdlib.h> diff --git a/src/common/password.cpp b/src/common/password.cpp index b84d6fb2e..5d56464a5 100644 --- a/src/common/password.cpp +++ b/src/common/password.cpp @@ -238,9 +238,6 @@ namespace tools boost::optional<password_container> password_container::prompt(const bool verify, const char *message) { -#ifdef HAVE_READLINE - rdln::suspend_readline pause_readline; -#endif password_container pass1{}; password_container pass2{}; if (is_cin_tty() ? read_from_tty(verify, message, pass1.m_password, pass2.m_password) : read_from_file(pass1.m_password)) @@ -249,7 +246,7 @@ namespace tools return boost::none; } - boost::optional<login> login::parse(std::string&& userpass, bool verify, const char* message) + boost::optional<login> login::parse(std::string&& userpass, bool verify, const std::function<boost::optional<password_container>(bool)> &prompt) { login out{}; password_container wipe{std::move(userpass)}; @@ -257,7 +254,7 @@ namespace tools const auto loc = wipe.password().find(':'); if (loc == std::string::npos) { - auto result = tools::password_container::prompt(verify, message); + auto result = prompt(verify); if (!result) return boost::none; diff --git a/src/common/password.h b/src/common/password.h index 12f715df4..ba1c30a28 100644 --- a/src/common/password.h +++ b/src/common/password.h @@ -82,7 +82,7 @@ namespace tools \return The username and password, or boost::none if `password_container::prompt` fails. */ - static boost::optional<login> parse(std::string&& userpass, bool verify, const char* message = "Password"); + static boost::optional<login> parse(std::string&& userpass, bool verify, const std::function<boost::optional<password_container>(bool)> &prompt); login(const login&) = delete; login(login&&) = default; diff --git a/src/common/util.cpp b/src/common/util.cpp index 1e180d325..a13ac6e50 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -405,7 +405,7 @@ namespace tools #else std::string get_nix_version_display_string() { - utsname un; + struct utsname un; if(uname(&un) < 0) return std::string("*nix: failed to get os version"); diff --git a/src/crypto/initializer.h b/src/crypto/initializer.h index 619038ae6..eb1d1c069 100644 --- a/src/crypto/initializer.h +++ b/src/crypto/initializer.h @@ -31,8 +31,13 @@ #pragma once #if defined(__GNUC__) +#if defined(__sun) && defined(__SVR4) +#define INITIALIZER(name) __attribute__((constructor)) static void name(void) +#define FINALIZER(name) __attribute__((destructor)) static void name(void) +#else #define INITIALIZER(name) __attribute__((constructor(101))) static void name(void) #define FINALIZER(name) __attribute__((destructor(101))) static void name(void) +#endif #define REGISTER_FINALIZER(name) ((void) 0) #elif defined(_MSC_VER) diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index d09f4c432..1c28ca4d8 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -45,6 +45,8 @@ using namespace epee; // #define ENABLE_HASH_CASH_INTEGRITY_CHECK +using namespace crypto; + static const uint64_t valid_decomposed_outputs[] = { (uint64_t)1, (uint64_t)2, (uint64_t)3, (uint64_t)4, (uint64_t)5, (uint64_t)6, (uint64_t)7, (uint64_t)8, (uint64_t)9, // 1 piconero (uint64_t)10, (uint64_t)20, (uint64_t)30, (uint64_t)40, (uint64_t)50, (uint64_t)60, (uint64_t)70, (uint64_t)80, (uint64_t)90, diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 4e1ab8a48..3d586a704 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -61,6 +61,8 @@ #define FIND_BLOCKCHAIN_SUPPLEMENT_MAX_SIZE (100*1024*1024) // 100 MB +using namespace crypto; + //#include "serialization/json_archive.h" /* TODO: diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 3f56ffac7..acc76a8d6 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -38,6 +38,7 @@ using namespace epee; #include "common/updates.h" #include "common/download.h" #include "common/threadpool.h" +#include "common/command_line.h" #include "warnings.h" #include "crypto/crypto.h" #include "cryptonote_config.h" @@ -61,6 +62,69 @@ DISABLE_VS_WARNINGS(4355) namespace cryptonote { + const command_line::arg_descriptor<std::string> arg_data_dir = { + "data-dir" + , "Specify data directory" + }; + const command_line::arg_descriptor<std::string> arg_testnet_data_dir = { + "testnet-data-dir" + , "Specify testnet data directory" + }; + const command_line::arg_descriptor<bool, false> arg_testnet_on = { + "testnet" + , "Run on testnet. The wallet must be launched with --testnet flag." + , false + }; + + static const command_line::arg_descriptor<bool> arg_test_drop_download = { + "test-drop-download" + , "For net tests: in download, discard ALL blocks instead checking/saving them (very fast)" + }; + static const command_line::arg_descriptor<uint64_t> arg_test_drop_download_height = { + "test-drop-download-height" + , "Like test-drop-download but disards only after around certain height" + , 0 + }; + static const command_line::arg_descriptor<int> arg_test_dbg_lock_sleep = { + "test-dbg-lock-sleep" + , "Sleep time in ms, defaults to 0 (off), used to debug before/after locking mutex. Values 100 to 1000 are good for tests." + , 0 + }; + static const command_line::arg_descriptor<bool> arg_dns_checkpoints = { + "enforce-dns-checkpointing" + , "checkpoints from DNS server will be enforced" + , false + }; + static const command_line::arg_descriptor<uint64_t> arg_fast_block_sync = { + "fast-block-sync" + , "Sync up most of the way by using embedded, known block hashes." + , 1 + }; + static const command_line::arg_descriptor<uint64_t> arg_prep_blocks_threads = { + "prep-blocks-threads" + , "Max number of threads to use when preparing block hashes in groups." + , 4 + }; + static const command_line::arg_descriptor<uint64_t> arg_show_time_stats = { + "show-time-stats" + , "Show time-stats when processing blocks/txs and disk synchronization." + , 0 + }; + static const command_line::arg_descriptor<size_t> arg_block_sync_size = { + "block-sync-size" + , "How many blocks to sync at once during chain synchronization (0 = adaptive)." + , 0 + }; + static const command_line::arg_descriptor<std::string> arg_check_updates = { + "check-updates" + , "Check for new versions of monero: [disabled|notify|download|update]" + , "notify" + }; + static const command_line::arg_descriptor<bool> arg_fluffy_blocks = { + "fluffy-blocks" + , "Relay blocks as fluffy blocks where possible (automatic on testnet)" + , false + }; //----------------------------------------------------------------------------------------------- core::core(i_cryptonote_protocol* pprotocol): @@ -148,20 +212,21 @@ namespace cryptonote //----------------------------------------------------------------------------------- void core::init_options(boost::program_options::options_description& desc) { - command_line::add_arg(desc, command_line::arg_data_dir, tools::get_default_data_dir()); - command_line::add_arg(desc, command_line::arg_testnet_data_dir, (boost::filesystem::path(tools::get_default_data_dir()) / "testnet").string()); + command_line::add_arg(desc, arg_data_dir, tools::get_default_data_dir()); + command_line::add_arg(desc, arg_testnet_data_dir, (boost::filesystem::path(tools::get_default_data_dir()) / "testnet").string()); - command_line::add_arg(desc, command_line::arg_test_drop_download); - command_line::add_arg(desc, command_line::arg_test_drop_download_height); + command_line::add_arg(desc, arg_test_drop_download); + command_line::add_arg(desc, arg_test_drop_download_height); - command_line::add_arg(desc, command_line::arg_testnet_on); - command_line::add_arg(desc, command_line::arg_dns_checkpoints); - command_line::add_arg(desc, command_line::arg_prep_blocks_threads); - command_line::add_arg(desc, command_line::arg_fast_block_sync); - command_line::add_arg(desc, command_line::arg_show_time_stats); - command_line::add_arg(desc, command_line::arg_block_sync_size); - command_line::add_arg(desc, command_line::arg_check_updates); - command_line::add_arg(desc, command_line::arg_fluffy_blocks); + command_line::add_arg(desc, arg_testnet_on); + command_line::add_arg(desc, arg_dns_checkpoints); + command_line::add_arg(desc, arg_prep_blocks_threads); + command_line::add_arg(desc, arg_fast_block_sync); + command_line::add_arg(desc, arg_show_time_stats); + command_line::add_arg(desc, arg_block_sync_size); + command_line::add_arg(desc, arg_check_updates); + command_line::add_arg(desc, arg_fluffy_blocks); + command_line::add_arg(desc, arg_test_dbg_lock_sleep); // we now also need some of net_node's options (p2p bind arg, for separate data dir) command_line::add_arg(desc, nodetool::arg_testnet_p2p_bind_port, false); @@ -173,9 +238,9 @@ namespace cryptonote //----------------------------------------------------------------------------------------------- bool core::handle_command_line(const boost::program_options::variables_map& vm) { - m_testnet = command_line::get_arg(vm, command_line::arg_testnet_on); + m_testnet = command_line::get_arg(vm, arg_testnet_on); - auto data_dir_arg = m_testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir; + auto data_dir_arg = m_testnet ? arg_testnet_data_dir : arg_data_dir; m_config_folder = command_line::get_arg(vm, data_dir_arg); auto data_dir = boost::filesystem::path(m_config_folder); @@ -196,13 +261,15 @@ namespace cryptonote } - set_enforce_dns_checkpoints(command_line::get_arg(vm, command_line::arg_dns_checkpoints)); - test_drop_download_height(command_line::get_arg(vm, command_line::arg_test_drop_download_height)); - m_fluffy_blocks_enabled = m_testnet || get_arg(vm, command_line::arg_fluffy_blocks); + set_enforce_dns_checkpoints(command_line::get_arg(vm, arg_dns_checkpoints)); + test_drop_download_height(command_line::get_arg(vm, arg_test_drop_download_height)); + m_fluffy_blocks_enabled = m_testnet || get_arg(vm, arg_fluffy_blocks); - if (command_line::get_arg(vm, command_line::arg_test_drop_download) == true) + if (command_line::get_arg(vm, arg_test_drop_download) == true) test_drop_download(); + epee::debug::g_test_dbg_lock_sleep() = command_line::get_arg(vm, arg_test_dbg_lock_sleep); + return true; } //----------------------------------------------------------------------------------------------- @@ -268,7 +335,7 @@ namespace cryptonote m_fakechain = test_options != NULL; bool r = handle_command_line(vm); - bool testnet = command_line::get_arg(vm, command_line::arg_testnet_on); + bool testnet = command_line::get_arg(vm, arg_testnet_on); auto p2p_bind_arg = testnet ? nodetool::arg_testnet_p2p_bind_port : nodetool::arg_p2p_bind_port; std::string m_port = command_line::get_arg(vm, p2p_bind_arg); std::string m_config_folder_mempool = m_config_folder; @@ -281,9 +348,9 @@ namespace cryptonote std::string db_type = command_line::get_arg(vm, cryptonote::arg_db_type); std::string db_sync_mode = command_line::get_arg(vm, cryptonote::arg_db_sync_mode); bool db_salvage = command_line::get_arg(vm, cryptonote::arg_db_salvage) != 0; - bool fast_sync = command_line::get_arg(vm, command_line::arg_fast_block_sync) != 0; - uint64_t blocks_threads = command_line::get_arg(vm, command_line::arg_prep_blocks_threads); - std::string check_updates_string = command_line::get_arg(vm, command_line::arg_check_updates); + bool fast_sync = command_line::get_arg(vm, arg_fast_block_sync) != 0; + uint64_t blocks_threads = command_line::get_arg(vm, arg_prep_blocks_threads); + std::string check_updates_string = command_line::get_arg(vm, arg_check_updates); boost::filesystem::path folder(m_config_folder); if (m_fakechain) @@ -409,11 +476,11 @@ namespace cryptonote // transactions in the pool that do not conform to the current fork m_mempool.validate(m_blockchain_storage.get_current_hard_fork_version()); - bool show_time_stats = command_line::get_arg(vm, command_line::arg_show_time_stats) != 0; + bool show_time_stats = command_line::get_arg(vm, arg_show_time_stats) != 0; m_blockchain_storage.set_show_time_stats(show_time_stats); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage"); - block_sync_size = command_line::get_arg(vm, command_line::arg_block_sync_size); + block_sync_size = command_line::get_arg(vm, arg_block_sync_size); MGINFO("Loading checkpoints"); @@ -498,8 +565,8 @@ namespace cryptonote return false; } - tx_hash = null_hash; - tx_prefixt_hash = null_hash; + tx_hash = crypto::null_hash; + tx_prefixt_hash = crypto::null_hash; if(!parse_tx_from_blob(tx, tx_hash, tx_prefixt_hash, tx_blob)) { diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index a3d47280a..dc014206d 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -41,6 +41,7 @@ #include "storages/portable_storage_template_helper.h" #include "common/download.h" #include "common/threadpool.h" +#include "common/command_line.h" #include "tx_pool.h" #include "blockchain.h" #include "cryptonote_basic/miner.h" @@ -58,6 +59,10 @@ namespace cryptonote const std::pair<uint8_t, uint64_t> *hard_forks; }; + extern const command_line::arg_descriptor<std::string> arg_data_dir; + extern const command_line::arg_descriptor<std::string> arg_testnet_data_dir; + extern const command_line::arg_descriptor<bool, false> arg_testnet_on; + /************************************************************************/ /* */ /************************************************************************/ diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 9409a60a5..feefc1592 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -40,6 +40,8 @@ using namespace epee; #include "crypto/hash.h" #include "ringct/rctSigs.h" +using namespace crypto; + namespace cryptonote { //--------------------------------------------------------------- diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 6bfcfe529..e6f217463 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -51,6 +51,8 @@ DISABLE_VS_WARNINGS(4244 4345 4503) //'boost::foreach_detail_::or_' : decorated name length exceeded, name was truncated +using namespace crypto; + namespace cryptonote { namespace diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index e41491954..73433a8d8 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -297,9 +297,9 @@ namespace cryptonote m_core.set_target_blockchain_height((hshd.current_height)); int64_t diff = static_cast<int64_t>(hshd.current_height) - static_cast<int64_t>(m_core.get_current_blockchain_height()); uint64_t abs_diff = std::abs(diff); - uint64_t max_block_height = max(hshd.current_height,m_core.get_current_blockchain_height()); + uint64_t max_block_height = std::max(hshd.current_height,m_core.get_current_blockchain_height()); uint64_t last_block_v1 = m_core.get_testnet() ? 624633 : 1009826; - uint64_t diff_v2 = max_block_height > last_block_v1 ? min(abs_diff, max_block_height - last_block_v1) : 0; + uint64_t diff_v2 = max_block_height > last_block_v1 ? std::min(abs_diff, max_block_height - last_block_v1) : 0; MCLOG(is_inital ? el::Level::Info : el::Level::Debug, "global", context << "Sync data returned a new top block candidate: " << m_core.get_current_blockchain_height() << " -> " << hshd.current_height << " [Your node is " << abs_diff << " blocks (" << ((abs_diff - diff_v2) / (24 * 60 * 60 / DIFFICULTY_TARGET_V1)) + (diff_v2 / (24 * 60 * 60 / DIFFICULTY_TARGET_V2)) << " days) " << (0 <= diff ? std::string("behind") : std::string("ahead")) diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index d0fc1d846..2f9c2b2f9 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -94,6 +94,8 @@ target_link_libraries(daemon daemonizer serialization daemon_rpc_server + epee + ${EPEE_READLINE} version ${Boost_CHRONO_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} @@ -102,6 +104,7 @@ target_link_libraries(daemon ${Boost_SYSTEM_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${ZMQ_LIB} + ${Readline_LIBRARY} ${EXTRA_LIBRARIES}) set_property(TARGET daemon PROPERTY diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index faa620c54..cf7d5f8ab 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -88,7 +88,7 @@ t_daemon::t_daemon( ) : mp_internals{new t_internals{vm}} { - bool testnet = command_line::get_arg(vm, command_line::arg_testnet_on); + bool testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on); if (testnet) { zmq_rpc_bind_port = command_line::get_arg(vm, daemon_args::arg_zmq_testnet_rpc_bind_port); diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 5d548f410..ae83943b6 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -82,7 +82,6 @@ int main(int argc, char const * argv[]) command_line::add_arg(visible_options, daemon_args::arg_os_version); bf::path default_conf = default_data_dir / std::string(CRYPTONOTE_NAME ".conf"); command_line::add_arg(visible_options, daemon_args::arg_config_file, default_conf.string()); - command_line::add_arg(visible_options, command_line::arg_test_dbg_lock_sleep); // Settings bf::path default_log = default_data_dir / std::string(CRYPTONOTE_NAME ".log"); @@ -144,8 +143,6 @@ int main(int argc, char const * argv[]) return 0; } - epee::debug::g_test_dbg_lock_sleep() = command_line::get_arg(vm, command_line::arg_test_dbg_lock_sleep); - std::string db_type = command_line::get_arg(vm, cryptonote::arg_db_type); // verify that blockchaindb type is valid @@ -156,9 +153,9 @@ int main(int argc, char const * argv[]) return 0; } - bool testnet_mode = command_line::get_arg(vm, command_line::arg_testnet_on); + bool testnet_mode = command_line::get_arg(vm, cryptonote::arg_testnet_on); - auto data_dir_arg = testnet_mode ? command_line::arg_testnet_data_dir : command_line::arg_data_dir; + auto data_dir_arg = testnet_mode ? cryptonote::arg_testnet_data_dir : cryptonote::arg_data_dir; // data_dir // default: e.g. ~/.bitmonero/ or ~/.bitmonero/testnet @@ -250,7 +247,12 @@ int main(int argc, char const * argv[]) if (command_line::has_arg(vm, arg.rpc_login)) { login = tools::login::parse( - command_line::get_arg(vm, arg.rpc_login), false, "Daemon client password" + command_line::get_arg(vm, arg.rpc_login), false, [](bool verify) { +#ifdef HAVE_READLINE + rdln::suspend_readline pause_readline; +#endif + return tools::password_container::prompt(verify, "Daemon client password"); + } ); if (!login) { diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 83b04bff5..230b9f090 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -1011,7 +1011,7 @@ bool t_rpc_command_executor::print_transaction_pool_stats() { tools::msg_writer() << " Age Txes Bytes"; for (i=0; i<n; i++) { - tools::msg_writer() << get_time_hms(times[i]) << setw(8) << res.pool_stats.histo[i].txs << setw(12) << res.pool_stats.histo[i].bytes; + tools::msg_writer() << get_time_hms(times[i]) << std::setw(8) << res.pool_stats.histo[i].txs << std::setw(12) << res.pool_stats.histo[i].bytes; } } tools::msg_writer(); diff --git a/src/p2p/connection_basic.cpp b/src/p2p/connection_basic.cpp index b95f36b99..8edd75b3e 100644 --- a/src/p2p/connection_basic.cpp +++ b/src/p2p/connection_basic.cpp @@ -158,7 +158,7 @@ connection_basic::connection_basic(boost::asio::io_service& io_service, std::ato ++ref_sock_count; // increase the global counter mI->m_peer_number = sock_number.fetch_add(1); // use, and increase the generated number - string remote_addr_str = "?"; + std::string remote_addr_str = "?"; try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ; _note("Spawned connection p2p#"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_ref_sock_count); @@ -166,7 +166,7 @@ connection_basic::connection_basic(boost::asio::io_service& io_service, std::ato } connection_basic::~connection_basic() noexcept(false) { - string remote_addr_str = "?"; + std::string remote_addr_str = "?"; m_ref_sock_count--; try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ; _note("Destructing connection p2p#"<<mI->m_peer_number << " to " << remote_addr_str); diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index ee3ff160a..f64b29c1f 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -48,6 +48,7 @@ #include "net/local_ip.h" #include "crypto/crypto.h" #include "storages/levin_abstract_invoke2.h" +#include "cryptonote_core/cryptonote_core.h" // We have to look for miniupnpc headers in different places, dependent on if its compiled or external #ifdef UPNP_STATIC @@ -434,7 +435,7 @@ namespace nodetool bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm) { std::set<std::string> full_addrs; - m_testnet = command_line::get_arg(vm, command_line::arg_testnet_on); + m_testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on); if (m_testnet) { @@ -535,7 +536,7 @@ namespace nodetool bool res = handle_command_line(vm); CHECK_AND_ASSERT_MES(res, false, "Failed to handle command line"); - auto config_arg = m_testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir; + auto config_arg = m_testnet ? cryptonote::arg_testnet_data_dir : cryptonote::arg_data_dir; m_config_folder = command_line::get_arg(vm, config_arg); if ((!m_testnet && m_port != std::to_string(::config::P2P_DEFAULT_PORT)) diff --git a/src/ringct/rctOps.h b/src/ringct/rctOps.h index cb19bbbd6..412450c18 100644 --- a/src/ringct/rctOps.h +++ b/src/ringct/rctOps.h @@ -35,8 +35,6 @@ #define RCTOPS_H #include <cstddef> -#include <mutex> -#include <vector> #include <tuple> #include "crypto/generic-ops.h" @@ -57,9 +55,6 @@ extern "C" { #define DP(x) #endif -using namespace std; -using namespace crypto; - namespace rct { //Various key initialization functions @@ -99,13 +94,13 @@ namespace rct { key pkGen(); //generates a random secret and corresponding public key void skpkGen(key &sk, key &pk); - tuple<key, key> skpkGen(); + std::tuple<key, key> skpkGen(); //generates a <secret , public> / Pedersen commitment to the amount - tuple<ctkey, ctkey> ctskpkGen(xmr_amount amount); + std::tuple<ctkey, ctkey> ctskpkGen(xmr_amount amount); //generates C =aG + bH from b, a is random void genC(key & C, const key & a, xmr_amount amount); //this one is mainly for testing, can take arbitrary amounts.. - tuple<ctkey, ctkey> ctskpkGen(const key &bH); + std::tuple<ctkey, ctkey> ctskpkGen(const key &bH); // make a pedersen commitment with given key key commit(xmr_amount amount, const key &mask); // make a pedersen commitment with zero key diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h index ca40ddd85..d158f06f0 100644 --- a/src/ringct/rctSigs.h +++ b/src/ringct/rctSigs.h @@ -36,7 +36,6 @@ #define RCTSIGS_H #include <cstddef> -#include <mutex> #include <vector> #include <tuple> @@ -61,9 +60,6 @@ extern "C" { -using namespace std; -using namespace crypto; - namespace rct { boroSig genBorromean(const key64 x, const key64 P1, const key64 P2, const bits indices); @@ -110,7 +106,7 @@ namespace rct { //populateFromBlockchain creates a keymatrix with "mixin" columns and one of the columns is inPk // the return value are the key matrix, and the index where inPk was put (random). void getKeyFromBlockchain(ctkey & a, size_t reference_index); - tuple<ctkeyM, xmr_amount> populateFromBlockchain(ctkeyV inPk, int mixin); + std::tuple<ctkeyM, xmr_amount> populateFromBlockchain(ctkeyV inPk, int mixin); //RingCT protocol //genRct: @@ -122,10 +118,10 @@ namespace rct { //decodeRct: (c.f. http://eprint.iacr.org/2015/1098 section 5.1.1) // uses the attached ecdh info to find the amounts represented by each output commitment // must know the destination private key to find the correct amount, else will return a random number - rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, unsigned int index, ctkeyV &outSk); - rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> & amounts, const keyV &amount_keys, const int mixin); - rctSig genRctSimple(const key & message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> & inamounts, const vector<xmr_amount> & outamounts, const keyV &amount_keys, xmr_amount txnFee, unsigned int mixin); - rctSig genRctSimple(const key & message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> & inamounts, const vector<xmr_amount> & outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<unsigned int> & index, ctkeyV &outSk); + rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, unsigned int index, ctkeyV &outSk); + rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const keyV &amount_keys, const int mixin); + rctSig genRctSimple(const key & message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, const keyV &amount_keys, xmr_amount txnFee, unsigned int mixin); + rctSig genRctSimple(const key & message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<unsigned int> & index, ctkeyV &outSk); bool verRct(const rctSig & rv, bool semantics); static inline bool verRct(const rctSig & rv) { return verRct(rv, true) && verRct(rv, false); } bool verRctSimple(const rctSig & rv, bool semantics); diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index cc0000ad6..8147cb602 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -33,9 +33,7 @@ #define RCT_TYPES_H #include <cstddef> -#include <mutex> #include <vector> -#include <tuple> #include <iostream> #include <cinttypes> @@ -67,9 +65,6 @@ extern "C" { //for printing large ints -using namespace std; -using namespace crypto; - //Namespace specifically for ring ct code namespace rct { //basic ops containers @@ -89,8 +84,8 @@ namespace rct { bool operator==(const key &k) const { return !memcmp(bytes, k.bytes, sizeof(bytes)); } unsigned char bytes[32]; }; - typedef vector<key> keyV; //vector of keys - typedef vector<keyV> keyM; //matrix of keys (indexed by column first) + typedef std::vector<key> keyV; //vector of keys + typedef std::vector<keyV> keyM; //matrix of keys (indexed by column first) //containers For CT operations //if it's representing a private ctkey then "dest" contains the secret key of the address @@ -101,8 +96,8 @@ namespace rct { key dest; key mask; //C here if public }; - typedef vector<ctkey> ctkeyV; - typedef vector<ctkeyV> ctkeyM; + typedef std::vector<ctkey> ctkeyV; + typedef std::vector<ctkeyV> ctkeyM; //data for passing the amount to the receiver secretly // If the pedersen commitment to an amount is C = aG + bH, @@ -184,7 +179,7 @@ namespace rct { ctkeyM mixRing; //the set of all pubkeys / copy //pairs that you mix with keyV pseudoOuts; //C - for simple rct - vector<ecdhTuple> ecdhInfo; + std::vector<ecdhTuple> ecdhInfo; ctkeyV outPk; xmr_amount txnFee; // contains b @@ -245,8 +240,8 @@ namespace rct { } }; struct rctSigPrunable { - vector<rangeSig> rangeSigs; - vector<mgSig> MGs; // simple rct has N, full has 1 + std::vector<rangeSig> rangeSigs; + std::vector<mgSig> MGs; // simple rct has N, full has 1 template<bool W, template <bool> class Archive> bool serialize_rctsig_prunable(Archive<W> &ar, uint8_t type, size_t inputs, size_t outputs, size_t mixin) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 5801e515c..6e7fb7e8e 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -85,7 +85,7 @@ namespace cryptonote const boost::program_options::variables_map& vm ) { - m_testnet = command_line::get_arg(vm, command_line::arg_testnet_on); + m_testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on); m_net_server.set_threads_prefix("RPC"); auto p2p_bind_arg = m_testnet ? arg_testnet_rpc_bind_port : arg_rpc_bind_port; @@ -991,7 +991,7 @@ namespace cryptonote } blobdata block_blob = t_serializable_object_to_blob(b); crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(b.miner_tx); - if(tx_pub_key == null_pkey) + if(tx_pub_key == crypto::null_pkey) { error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; error_resp.message = "Internal error: failed to create block template"; diff --git a/src/rpc/rpc_args.cpp b/src/rpc/rpc_args.cpp index 93309bf3c..e03c5472d 100644 --- a/src/rpc/rpc_args.cpp +++ b/src/rpc/rpc_args.cpp @@ -83,7 +83,9 @@ namespace cryptonote if (command_line::has_arg(vm, arg.rpc_login)) { - config.login = tools::login::parse(command_line::get_arg(vm, arg.rpc_login), true, "RPC server password"); + config.login = tools::login::parse(command_line::get_arg(vm, arg.rpc_login), true, [](bool verify) { + return tools::password_container::prompt(verify, "RPC server password"); + }); if (!config.login) return boost::none; diff --git a/src/simplewallet/CMakeLists.txt b/src/simplewallet/CMakeLists.txt index 4ecda12d0..3ff4466fc 100644 --- a/src/simplewallet/CMakeLists.txt +++ b/src/simplewallet/CMakeLists.txt @@ -48,11 +48,14 @@ target_link_libraries(simplewallet cncrypto common mnemonics + epee + ${EPEE_READLINE} version ${Boost_CHRONO_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} + ${Readline_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_LIBRARIES}) set_property(TARGET simplewallet diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 3d8d395db..b274675d1 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -125,6 +125,37 @@ namespace const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""}; + std::string input_line(const std::string& prompt) + { +#ifdef HAVE_READLINE + rdln::suspend_readline pause_readline; +#endif + std::cout << prompt; + + std::string buf; + std::getline(std::cin, buf); + + return epee::string_tools::trim(buf); + } + + boost::optional<tools::password_container> password_prompter(const char *prompt, bool verify) + { +#ifdef HAVE_READLINE + rdln::suspend_readline pause_readline; +#endif + auto pwd_container = tools::password_container::prompt(verify, prompt); + if (!pwd_container) + { + tools::fail_msg_writer() << tr("failed to read wallet password"); + } + return pwd_container; + } + + boost::optional<tools::password_container> default_password_prompter(bool verify) + { + return password_prompter(verify ? tr("Enter new wallet password") : tr("Wallet password"), verify); + } + inline std::string interpret_rpc_response(bool ok, const std::string& status) { std::string err; @@ -270,7 +301,7 @@ namespace << tr("Is this OK? (Y/n) ") ; // prompt the user for confirmation given the dns query and dnssec status - std::string confirm_dns_ok = command_line::input_line(prompt.str()); + std::string confirm_dns_ok = input_line(prompt.str()); if (std::cin.eof()) { return {}; @@ -448,7 +479,7 @@ bool simple_wallet::change_password(const std::vector<std::string> &args) } // prompts for a new password, pass true to verify the password - const auto pwd_container = tools::wallet2::password_prompt(true); + const auto pwd_container = default_password_prompter(true); try { @@ -1020,7 +1051,7 @@ bool simple_wallet::ask_wallet_create_if_needed() do{ LOG_PRINT_L3("User asked to specify wallet file name."); - wallet_path = command_line::input_line( + wallet_path = input_line( tr(m_restoring ? "Specify a new wallet file name for your restored wallet (e.g., MyWallet).\n" "Wallet file name (or Ctrl-C to quit): " : "Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created.\n" @@ -1071,7 +1102,7 @@ bool simple_wallet::ask_wallet_create_if_needed() if (!m_restoring) { message_writer() << tr("No wallet found with that name. Confirm creation of new wallet named: ") << wallet_path; - confirm_creation = command_line::input_line(tr("(Y/Yes/N/No): ")); + confirm_creation = input_line(tr("(Y/Yes/N/No): ")); if(std::cin.eof()) { LOG_ERROR("Unexpected std::cin.eof() - Exited simple_wallet::ask_wallet_create_if_needed()"); @@ -1155,7 +1186,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) do { const char *prompt = m_electrum_seed.empty() ? "Specify Electrum seed: " : "Electrum seed continued: "; - std::string electrum_seed = command_line::input_line(prompt); + std::string electrum_seed = input_line(prompt); if (std::cin.eof()) return false; if (electrum_seed.empty()) @@ -1184,7 +1215,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { m_wallet_file = m_generate_from_view_key; // parse address - std::string address_string = command_line::input_line("Standard address: "); + std::string address_string = input_line("Standard address: "); if (std::cin.eof()) return false; if (address_string.empty()) { @@ -1204,7 +1235,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } // parse view secret key - std::string viewkey_string = command_line::input_line("View key: "); + std::string viewkey_string = input_line("View key: "); if (std::cin.eof()) return false; if (viewkey_string.empty()) { @@ -1258,7 +1289,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { m_wallet_file = m_generate_from_keys; // parse address - std::string address_string = command_line::input_line("Standard address: "); + std::string address_string = input_line("Standard address: "); if (std::cin.eof()) return false; if (address_string.empty()) { @@ -1278,7 +1309,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } // parse spend secret key - std::string spendkey_string = command_line::input_line("Secret spend key: "); + std::string spendkey_string = input_line("Secret spend key: "); if (std::cin.eof()) return false; if (spendkey_string.empty()) { @@ -1294,7 +1325,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) crypto::secret_key spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data()); // parse view secret key - std::string viewkey_string = command_line::input_line("Secret view key: "); + std::string viewkey_string = input_line("Secret view key: "); if (std::cin.eof()) return false; if (viewkey_string.empty()) { @@ -1341,7 +1372,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) unsigned int multisig_n; // parse multisig type - std::string multisig_type_string = command_line::input_line("Multisig type (input as M/N with M <= N and M > 1): "); + std::string multisig_type_string = input_line("Multisig type (input as M/N with M <= N and M > 1): "); if (std::cin.eof()) return false; if (multisig_type_string.empty()) @@ -1367,7 +1398,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) message_writer() << boost::format(tr("Generating master wallet from %u of %u multisig wallet keys")) % multisig_m % multisig_n; // parse multisig address - std::string address_string = command_line::input_line("Multisig wallet address: "); + std::string address_string = input_line("Multisig wallet address: "); if (std::cin.eof()) return false; if (address_string.empty()) { @@ -1382,7 +1413,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } // parse secret view key - std::string viewkey_string = command_line::input_line("Secret view key: "); + std::string viewkey_string = input_line("Secret view key: "); if (std::cin.eof()) return false; if (viewkey_string.empty()) @@ -1422,7 +1453,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) // get N secret spend keys from user for(unsigned int i=0; i<multisig_n; ++i) { - spendkey_string = command_line::input_line(tr((boost::format(tr("Secret spend key (%u of %u):")) % (i+i) % multisig_m).str().c_str())); + spendkey_string = input_line(tr((boost::format(tr("Secret spend key (%u of %u):")) % (i+i) % multisig_m).str().c_str())); if (std::cin.eof()) return false; if (spendkey_string.empty()) @@ -1470,7 +1501,15 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) else if (!m_generate_from_json.empty()) { m_wallet_file = m_generate_from_json; - m_wallet = tools::wallet2::make_from_json(vm, m_wallet_file); + try + { + m_wallet = tools::wallet2::make_from_json(vm, m_wallet_file, password_prompter); + } + catch (const std::exception &e) + { + fail_msg_writer() << e.what(); + return false; + } if (!m_wallet) return false; } @@ -1492,9 +1531,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { std::string heightstr; if (!connected || version < MAKE_CORE_RPC_VERSION(1, 6)) - heightstr = command_line::input_line("Restore from specific blockchain height (optional, default 0): "); + heightstr = input_line("Restore from specific blockchain height (optional, default 0): "); else - heightstr = command_line::input_line("Restore from specific blockchain height (optional, default 0),\nor alternatively from specific date (YYYY-MM-DD): "); + heightstr = input_line("Restore from specific blockchain height (optional, default 0),\nor alternatively from specific date (YYYY-MM-DD): "); if (std::cin.eof()) return false; if (heightstr.empty()) @@ -1530,7 +1569,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) day = boost::lexical_cast<uint16_t>(heightstr.substr(8,2)); m_restore_height = m_wallet->get_blockchain_height_by_date(year, month, day); success_msg_writer() << tr("Restore height is: ") << m_restore_height; - std::string confirm = command_line::input_line(tr("Is this okay? (Y/Yes/N/No): ")); + std::string confirm = input_line(tr("Is this okay? (Y/Yes/N/No): ")); if (std::cin.eof()) return false; if(command_line::is_yes(confirm)) @@ -1661,7 +1700,7 @@ std::string simple_wallet::get_mnemonic_language() } while (language_number < 0) { - language_choice = command_line::input_line(tr("Enter the number corresponding to the language of your choice: ")); + language_choice = input_line(tr("Enter the number corresponding to the language of your choice: ")); if (std::cin.eof()) return std::string(); try @@ -1683,7 +1722,7 @@ std::string simple_wallet::get_mnemonic_language() //---------------------------------------------------------------------------------------------------- boost::optional<tools::password_container> simple_wallet::get_and_verify_password() const { - auto pwd_container = tools::wallet2::password_prompt(m_wallet_file.empty()); + auto pwd_container = default_password_prompter(m_wallet_file.empty()); if (!pwd_container) return boost::none; @@ -1698,7 +1737,7 @@ boost::optional<tools::password_container> simple_wallet::get_and_verify_passwor bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, const crypto::secret_key& recovery_key, bool recover, bool two_random, const std::string &old_language) { - auto rc = tools::wallet2::make_new(vm); + auto rc = tools::wallet2::make_new(vm, password_prompter); m_wallet = std::move(rc.first); if (!m_wallet) { @@ -1779,7 +1818,7 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, const cryptonote::account_public_address& address, const boost::optional<crypto::secret_key>& spendkey, const crypto::secret_key& viewkey) { - auto rc = tools::wallet2::make_new(vm); + auto rc = tools::wallet2::make_new(vm, password_prompter); m_wallet = std::move(rc.first); if (!m_wallet) { @@ -1821,7 +1860,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm) std::string password; try { - auto rc = tools::wallet2::make_from_file(vm, m_wallet_file); + auto rc = tools::wallet2::make_from_file(vm, m_wallet_file, password_prompter); m_wallet = std::move(rc.first); password = std::move(rc.second).password(); if (!m_wallet) @@ -2552,6 +2591,101 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending return true; } //---------------------------------------------------------------------------------------------------- +static void handle_transfer_exception(const std::exception_ptr &e) +{ + try + { + std::rethrow_exception(e); + } + catch (const tools::error::daemon_busy&) + { + fail_msg_writer() << tr("daemon is busy. Please try again later."); + } + catch (const tools::error::no_connection_to_daemon&) + { + fail_msg_writer() << tr("no connection to daemon. Please make sure daemon is running."); + } + catch (const tools::error::wallet_rpc_error& e) + { + LOG_ERROR("RPC error: " << e.to_string()); + fail_msg_writer() << tr("RPC error: ") << e.what(); + } + catch (const tools::error::get_random_outs_error &e) + { + fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what(); + } + catch (const tools::error::not_enough_unlocked_money& e) + { + LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") % + print_money(e.available()) % + print_money(e.tx_amount())); + fail_msg_writer() << tr("Not enough money in unlocked balance"); + } + catch (const tools::error::not_enough_money& e) + { + LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") % + print_money(e.available()) % + print_money(e.tx_amount())); + fail_msg_writer() << tr("Not enough money in unlocked balance"); + } + catch (const tools::error::tx_not_possible& e) + { + LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") % + print_money(e.available()) % + print_money(e.tx_amount() + e.fee()) % + print_money(e.tx_amount()) % + print_money(e.fee())); + fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees"); + } + catch (const tools::error::not_enough_outs_to_mix& e) + { + auto writer = fail_msg_writer(); + writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":"; + for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs()) + { + writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second; + } + } + catch (const tools::error::tx_not_constructed&) + { + fail_msg_writer() << tr("transaction was not constructed"); + } + catch (const tools::error::tx_rejected& e) + { + fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); + std::string reason = e.reason(); + if (!reason.empty()) + fail_msg_writer() << tr("Reason: ") << reason; + } + catch (const tools::error::tx_sum_overflow& e) + { + fail_msg_writer() << e.what(); + } + catch (const tools::error::zero_destination&) + { + fail_msg_writer() << tr("one of destinations is zero"); + } + catch (const tools::error::tx_too_big& e) + { + fail_msg_writer() << tr("failed to find a suitable way to split transactions"); + } + catch (const tools::error::transfer_error& e) + { + LOG_ERROR("unknown transfer error: " << e.to_string()); + fail_msg_writer() << tr("unknown transfer error: ") << e.what(); + } + catch (const tools::error::wallet_internal_error& e) + { + LOG_ERROR("internal error: " << e.to_string()); + fail_msg_writer() << tr("internal error: ") << e.what(); + } + catch (const std::exception& e) + { + LOG_ERROR("unexpected error: " << e.what()); + fail_msg_writer() << tr("unexpected error: ") << e.what(); + } +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::string> &args_) { // "transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]" @@ -2711,7 +2845,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri // prompt is there is no payment id and confirmation is required if (!payment_id_seen && m_wallet->confirm_missing_payment_id()) { - std::string accepted = command_line::input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); + std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -2795,7 +2929,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri std::string prompt_str = prompt.str(); if (!prompt_str.empty()) { - std::string accepted = command_line::input_line(prompt_str); + std::string accepted = input_line(prompt_str); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -2866,7 +3000,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri } prompt << ENDL << tr("Is this okay? (Y/Yes/N/No): "); - std::string accepted = command_line::input_line(prompt.str()); + std::string accepted = input_line(prompt.str()); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -2895,92 +3029,9 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri commit_or_save(ptx_vector, m_do_not_relay); } } - catch (const tools::error::daemon_busy&) - { - fail_msg_writer() << tr("daemon is busy. Please try again later."); - } - catch (const tools::error::no_connection_to_daemon&) - { - fail_msg_writer() << tr("no connection to daemon. Please make sure daemon is running."); - } - catch (const tools::error::wallet_rpc_error& e) - { - LOG_ERROR("RPC error: " << e.to_string()); - fail_msg_writer() << tr("RPC error: ") << e.what(); - } - catch (const tools::error::get_random_outs_error &e) - { - fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what(); - } - catch (const tools::error::not_enough_unlocked_money& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") % - print_money(e.available()) % - print_money(e.tx_amount())); - fail_msg_writer() << tr("Not enough money in unlocked balance"); - } - catch (const tools::error::not_enough_money& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") % - print_money(e.available()) % - print_money(e.tx_amount())); - fail_msg_writer() << tr("Not enough money in overall balance"); - } - catch (const tools::error::tx_not_possible& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") % - print_money(e.available()) % - print_money(e.tx_amount() + e.fee()) % - print_money(e.tx_amount()) % - print_money(e.fee())); - fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees"); - } - catch (const tools::error::not_enough_outs_to_mix& e) - { - auto writer = fail_msg_writer(); - writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":"; - for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs()) - { - writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second; - } - } - catch (const tools::error::tx_not_constructed&) - { - fail_msg_writer() << tr("transaction was not constructed"); - } - catch (const tools::error::tx_rejected& e) - { - fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); - std::string reason = e.reason(); - if (!reason.empty()) - fail_msg_writer() << tr("Reason: ") << reason; - } - catch (const tools::error::tx_sum_overflow& e) - { - fail_msg_writer() << e.what(); - } - catch (const tools::error::zero_destination&) - { - fail_msg_writer() << tr("one of destinations is zero"); - } - catch (const tools::error::tx_too_big& e) - { - fail_msg_writer() << tr("failed to find a suitable way to split transactions"); - } - catch (const tools::error::transfer_error& e) - { - LOG_ERROR("unknown transfer error: " << e.to_string()); - fail_msg_writer() << tr("unknown transfer error: ") << e.what(); - } - catch (const tools::error::wallet_internal_error& e) - { - LOG_ERROR("internal error: " << e.to_string()); - fail_msg_writer() << tr("internal error: ") << e.what(); - } - catch (const std::exception& e) + catch (const std::exception &e) { - LOG_ERROR("unexpected error: " << e.what()); - fail_msg_writer() << tr("unexpected error: ") << e.what(); + handle_transfer_exception(std::current_exception()); } catch (...) { @@ -3046,7 +3097,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_) print_money(total_unmixable) % print_money(total_fee)).str(); } - std::string accepted = command_line::input_line(prompt_str); + std::string accepted = input_line(prompt_str); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -3074,92 +3125,9 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_) commit_or_save(ptx_vector, m_do_not_relay); } } - catch (const tools::error::daemon_busy&) - { - fail_msg_writer() << tr("daemon is busy. Please try again later."); - } - catch (const tools::error::no_connection_to_daemon&) - { - fail_msg_writer() << tr("no connection to daemon. Please make sure daemon is running."); - } - catch (const tools::error::wallet_rpc_error& e) - { - LOG_ERROR("RPC error: " << e.to_string()); - fail_msg_writer() << tr("RPC error: ") << e.what(); - } - catch (const tools::error::get_random_outs_error &e) - { - fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what(); - } - catch (const tools::error::not_enough_unlocked_money& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") % - print_money(e.available()) % - print_money(e.tx_amount())); - fail_msg_writer() << tr("Not enough money in unlocked balance"); - } - catch (const tools::error::not_enough_money& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") % - print_money(e.available()) % - print_money(e.tx_amount())); - fail_msg_writer() << tr("Not enough money in overall balance"); - } - catch (const tools::error::tx_not_possible& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") % - print_money(e.available()) % - print_money(e.tx_amount() + e.fee()) % - print_money(e.tx_amount()) % - print_money(e.fee())); - fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees"); - } - catch (const tools::error::not_enough_outs_to_mix& e) - { - auto writer = fail_msg_writer(); - writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":"; - for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs()) - { - writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second; - } - } - catch (const tools::error::tx_not_constructed&) - { - fail_msg_writer() << tr("transaction was not constructed"); - } - catch (const tools::error::tx_rejected& e) - { - fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); - std::string reason = e.reason(); - if (!reason.empty()) - fail_msg_writer() << tr("Reason: ") << reason; - } - catch (const tools::error::tx_sum_overflow& e) - { - fail_msg_writer() << e.what(); - } - catch (const tools::error::zero_destination&) - { - fail_msg_writer() << tr("one of destinations is zero"); - } - catch (const tools::error::tx_too_big& e) - { - fail_msg_writer() << tr("failed to find a suitable way to split transactions"); - } - catch (const tools::error::transfer_error& e) - { - LOG_ERROR("unknown transfer error: " << e.to_string()); - fail_msg_writer() << tr("unknown transfer error: ") << e.what(); - } - catch (const tools::error::wallet_internal_error& e) - { - LOG_ERROR("internal error: " << e.to_string()); - fail_msg_writer() << tr("internal error: ") << e.what(); - } - catch (const std::exception& e) + catch (const std::exception &e) { - LOG_ERROR("unexpected error: " << e.what()); - fail_msg_writer() << tr("unexpected error: ") << e.what(); + handle_transfer_exception(std::current_exception()); } catch (...) { @@ -3290,7 +3258,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a // prompt is there is no payment id and confirmation is required if (!payment_id_seen && m_wallet->confirm_missing_payment_id()) { - std::string accepted = command_line::input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); + std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -3348,7 +3316,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a print_money(total_sent) % print_money(total_fee); } - std::string accepted = command_line::input_line(prompt.str()); + std::string accepted = input_line(prompt.str()); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -3376,92 +3344,9 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a commit_or_save(ptx_vector, m_do_not_relay); } } - catch (const tools::error::daemon_busy&) - { - fail_msg_writer() << tr("daemon is busy. Please try again later."); - } - catch (const tools::error::no_connection_to_daemon&) - { - fail_msg_writer() << tr("no connection to daemon. Please make sure daemon is running."); - } - catch (const tools::error::wallet_rpc_error& e) - { - LOG_ERROR("RPC error: " << e.to_string()); - fail_msg_writer() << tr("RPC error: ") << e.what(); - } - catch (const tools::error::get_random_outs_error &e) - { - fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what(); - } - catch (const tools::error::not_enough_unlocked_money& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") % - print_money(e.available()) % - print_money(e.tx_amount())); - fail_msg_writer() << tr("Not enough money in unlocked balance"); - } - catch (const tools::error::not_enough_money& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") % - print_money(e.available()) % - print_money(e.tx_amount())); - fail_msg_writer() << tr("Not enough money in overall balance"); - } - catch (const tools::error::tx_not_possible& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") % - print_money(e.available()) % - print_money(e.tx_amount() + e.fee()) % - print_money(e.tx_amount()) % - print_money(e.fee())); - fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees"); - } - catch (const tools::error::not_enough_outs_to_mix& e) - { - auto writer = fail_msg_writer(); - writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":"; - for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs()) - { - writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second; - } - } - catch (const tools::error::tx_not_constructed&) - { - fail_msg_writer() << tr("transaction was not constructed"); - } - catch (const tools::error::tx_rejected& e) - { - fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); - std::string reason = e.reason(); - if (!reason.empty()) - fail_msg_writer() << tr("Reason: ") << reason; - } - catch (const tools::error::tx_sum_overflow& e) - { - fail_msg_writer() << e.what(); - } - catch (const tools::error::zero_destination&) - { - fail_msg_writer() << tr("one of destinations is zero"); - } - catch (const tools::error::tx_too_big& e) - { - fail_msg_writer() << tr("failed to find a suitable way to split transactions"); - } - catch (const tools::error::transfer_error& e) - { - LOG_ERROR("unknown transfer error: " << e.to_string()); - fail_msg_writer() << tr("unknown transfer error: ") << e.what(); - } - catch (const tools::error::wallet_internal_error& e) - { - LOG_ERROR("internal error: " << e.to_string()); - fail_msg_writer() << tr("internal error: ") << e.what(); - } catch (const std::exception& e) { - LOG_ERROR("unexpected error: " << e.what()); - fail_msg_writer() << tr("unexpected error: ") << e.what(); + handle_transfer_exception(std::current_exception()); } catch (...) { @@ -3644,7 +3529,7 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, uint64_t fee = amount - amount_to_dests; std::string prompt_str = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): ")) % (unsigned long)get_num_txes() % print_money(amount) % print_money(fee) % dest_string % change_string % (unsigned long)min_ring_size % payment_id_string % extra_message).str(); - return command_line::is_yes(command_line::input_line(prompt_str)); + return command_line::is_yes(input_line(prompt_str)); } //---------------------------------------------------------------------------------------------------- bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs) @@ -3733,92 +3618,9 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args_) commit_or_save(ptx_vector, false); } - catch (const tools::error::daemon_busy&) - { - fail_msg_writer() << tr("daemon is busy. Please try later"); - } - catch (const tools::error::no_connection_to_daemon&) - { - fail_msg_writer() << tr("no connection to daemon. Please, make sure daemon is running."); - } - catch (const tools::error::wallet_rpc_error& e) - { - LOG_ERROR("Unknown RPC error: " << e.to_string()); - fail_msg_writer() << tr("RPC error: ") << e.what(); - } - catch (const tools::error::get_random_outs_error &e) - { - fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what(); - } - catch (const tools::error::not_enough_unlocked_money& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") % - print_money(e.available()) % - print_money(e.tx_amount())); - fail_msg_writer() << tr("Not enough money in unlocked balance"); - } - catch (const tools::error::not_enough_money& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") % - print_money(e.available()) % - print_money(e.tx_amount())); - fail_msg_writer() << tr("Not enough money in overall balance"); - } - catch (const tools::error::tx_not_possible& e) - { - LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") % - print_money(e.available()) % - print_money(e.tx_amount() + e.fee()) % - print_money(e.tx_amount()) % - print_money(e.fee())); - fail_msg_writer() << tr("Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees"); - } - catch (const tools::error::not_enough_outs_to_mix& e) - { - auto writer = fail_msg_writer(); - writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":"; - for (std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs()) - { - writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second; - } - } - catch (const tools::error::tx_not_constructed&) - { - fail_msg_writer() << tr("transaction was not constructed"); - } - catch (const tools::error::tx_rejected& e) - { - fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); - std::string reason = e.reason(); - if (!reason.empty()) - fail_msg_writer() << tr("Reason: ") << reason; - } - catch (const tools::error::tx_sum_overflow& e) - { - fail_msg_writer() << e.what(); - } - catch (const tools::error::zero_destination&) - { - fail_msg_writer() << tr("one of destinations is zero"); - } - catch (const tools::error::tx_too_big& e) - { - fail_msg_writer() << tr("Failed to find a suitable way to split transactions"); - } - catch (const tools::error::transfer_error& e) - { - LOG_ERROR("unknown transfer error: " << e.to_string()); - fail_msg_writer() << tr("unknown transfer error: ") << e.what(); - } - catch (const tools::error::wallet_internal_error& e) - { - LOG_ERROR("internal error: " << e.to_string()); - fail_msg_writer() << tr("internal error: ") << e.what(); - } catch (const std::exception& e) { - LOG_ERROR("unexpected error: " << e.what()); - fail_msg_writer() << tr("unexpected error: ") << e.what(); + handle_transfer_exception(std::current_exception()); } catch (...) { @@ -4287,7 +4089,7 @@ bool simple_wallet::check_tx_proof(const std::vector<std::string> &args) return true; } crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx); - if (tx_pub_key == null_pkey) + if (tx_pub_key == crypto::null_pkey) { fail_msg_writer() << tr("Tx pubkey was not found"); return true; @@ -5015,7 +4817,7 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v fail_msg_writer() << tr("failed to parse address"); return true; } - crypto::hash payment_id = null_hash; + crypto::hash payment_id = crypto::null_hash; size_t description_start = 2; if (info.has_payment_id) { @@ -5671,6 +5473,7 @@ int main(int argc, char* argv[]) "monero-wallet-cli [--wallet-file=<file>|--generate-new-wallet=<file>] [<COMMAND>]", desc_params, positional_options, + [](const std::string &s, bool emphasis){ tools::scoped_message_writer(emphasis ? epee::console_color_white : epee::console_color_default, true) << s; }, "monero-wallet-cli.log" ); diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 4c00a4d51..7e061f480 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -108,6 +108,7 @@ if (NOT BUILD_GUI_DEPS) PRIVATE wallet epee + ${EPEE_READLINE} rpc cryptonote_core cncrypto diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a7161ffcb..f6361ee37 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -67,6 +67,8 @@ extern "C" #include "crypto/keccak.h" #include "crypto/crypto-ops.h" } +using namespace std; +using namespace crypto; using namespace cryptonote; #undef MONERO_DEFAULT_LOG_CATEGORY @@ -135,7 +137,7 @@ uint64_t calculate_fee(uint64_t fee_per_kb, const cryptonote::blobdata &blob, ui return calculate_fee(fee_per_kb, blob.size(), fee_multiplier); } -std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variables_map& vm, const options& opts) +std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) { const bool testnet = command_line::get_arg(vm, opts.testnet); const bool restricted = command_line::get_arg(vm, opts.restricted); @@ -144,17 +146,16 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl auto daemon_host = command_line::get_arg(vm, opts.daemon_host); auto daemon_port = command_line::get_arg(vm, opts.daemon_port); - if (!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port) - { - tools::fail_msg_writer() << tools::wallet2::tr("can't specify daemon host or port more than once"); - return nullptr; - } + THROW_WALLET_EXCEPTION_IF(!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port, + tools::error::wallet_internal_error, tools::wallet2::tr("can't specify daemon host or port more than once")); boost::optional<epee::net_utils::http::login> login{}; if (command_line::has_arg(vm, opts.daemon_login)) { auto parsed = tools::login::parse( - command_line::get_arg(vm, opts.daemon_login), false, "Daemon client password" + command_line::get_arg(vm, opts.daemon_login), false, [password_prompter](bool verify) { + return password_prompter("Daemon client password", verify); + } ); if (!parsed) return nullptr; @@ -178,12 +179,11 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl return wallet; } -boost::optional<tools::password_container> get_password(const boost::program_options::variables_map& vm, const options& opts, const bool verify) +boost::optional<tools::password_container> get_password(const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char*, bool)> &password_prompter, const bool verify) { if (command_line::has_arg(vm, opts.password) && command_line::has_arg(vm, opts.password_file)) { - tools::fail_msg_writer() << tools::wallet2::tr("can't specify more than one of --password and --password-file"); - return boost::none; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("can't specify more than one of --password and --password-file")); } if (command_line::has_arg(vm, opts.password)) @@ -196,21 +196,17 @@ boost::optional<tools::password_container> get_password(const boost::program_opt std::string password; bool r = epee::file_io_utils::load_file_to_string(command_line::get_arg(vm, opts.password_file), password); - if (!r) - { - tools::fail_msg_writer() << tools::wallet2::tr("the password file specified could not be read"); - return boost::none; - } + THROW_WALLET_EXCEPTION_IF(!r, tools::error::wallet_internal_error, tools::wallet2::tr("the password file specified could not be read")); // Remove line breaks the user might have inserted boost::trim_right_if(password, boost::is_any_of("\r\n")); return {tools::password_container{std::move(password)}}; } - return tools::wallet2::password_prompt(verify); + return password_prompter(verify ? tr("Enter new wallet password") : tr("Wallet password"), verify); } -std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, const options& opts) +std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) { const bool testnet = command_line::get_arg(vm, opts.testnet); @@ -221,22 +217,20 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const auto do_generate = [&]() -> bool { std::string buf; if (!epee::file_io_utils::load_file_to_string(json_file, buf)) { - tools::fail_msg_writer() << tools::wallet2::tr("Failed to load file ") << json_file; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("Failed to load file ")) + json_file); return false; } rapidjson::Document json; if (json.Parse(buf.c_str()).HasParseError()) { - tools::fail_msg_writer() << tools::wallet2::tr("Failed to parse JSON"); + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Failed to parse JSON")); return false; } GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true, 0); const int current_version = 1; - if (field_version > current_version) { - tools::fail_msg_writer() << boost::format(tools::wallet2::tr("Version %u too new, we can only grok up to %u")) % field_version % current_version; - return false; - } + THROW_WALLET_EXCEPTION_IF(field_version > current_version, tools::error::wallet_internal_error, + ((boost::format(tools::wallet2::tr("Version %u too new, we can only grok up to %u")) % field_version % current_version)).str()); GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true, std::string()); @@ -252,14 +246,12 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, cryptonote::blobdata viewkey_data; if(!epee::string_tools::parse_hexstr_to_binbuff(field_viewkey, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to parse view key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to parse view key secret key")); } viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data()); crypto::public_key pkey; if (!crypto::secret_key_to_public_key(viewkey, pkey)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key")); } } @@ -270,14 +262,12 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, cryptonote::blobdata spendkey_data; if(!epee::string_tools::parse_hexstr_to_binbuff(field_spendkey, spendkey_data) || spendkey_data.size() != sizeof(crypto::secret_key)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to parse spend key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to parse spend key secret key")); } spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data()); crypto::public_key pkey; if (!crypto::secret_key_to_public_key(spendkey, pkey)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key")); } } @@ -289,8 +279,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, { if (!crypto::ElectrumWords::words_to_bytes(field_seed, recovery_key, old_language)) { - tools::fail_msg_writer() << tools::wallet2::tr("Electrum-style word list failed verification"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Electrum-style word list failed verification")); } restore_deterministic_wallet = true; @@ -307,13 +296,11 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, // compatibility checks if (!field_seed_found && !field_viewkey_found && !field_spendkey_found) { - tools::fail_msg_writer() << tools::wallet2::tr("At least one of Electrum-style word list and private view key and private spend key must be specified"); - return false; + THROW_WALLET_EXCEPTION(tools::wallet2::tr("At least one of Electrum-style word list and private view key and private spend key must be specified")); } if (field_seed_found && (field_viewkey_found || field_spendkey_found)) { - tools::fail_msg_writer() << tools::wallet2::tr("Both Electrum-style word list and private key(s) specified"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Both Electrum-style word list and private key(s) specified")); } // if an address was given, we check keys against it, and deduce the spend @@ -323,43 +310,36 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, cryptonote::address_parse_info info; if(!get_account_address_from_str(info, testnet, field_address)) { - tools::fail_msg_writer() << tools::wallet2::tr("invalid address"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("invalid address")); } if (field_viewkey_found) { crypto::public_key pkey; if (!crypto::secret_key_to_public_key(viewkey, pkey)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key")); } if (info.address.m_view_public_key != pkey) { - tools::fail_msg_writer() << tools::wallet2::tr("view key does not match standard address"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("view key does not match standard address")); } } if (field_spendkey_found) { crypto::public_key pkey; if (!crypto::secret_key_to_public_key(spendkey, pkey)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key")); } if (info.address.m_spend_public_key != pkey) { - tools::fail_msg_writer() << tools::wallet2::tr("spend key does not match standard address"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("spend key does not match standard address")); } } } const bool deprecated_wallet = restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) || crypto::ElectrumWords::get_is_old_style_seed(field_seed)); - if (deprecated_wallet) { - tools::fail_msg_writer() << tools::wallet2::tr("Cannot create deprecated wallets from JSON"); - return false; - } + THROW_WALLET_EXCEPTION_IF(deprecated_wallet, tools::error::wallet_internal_error, + tools::wallet2::tr("Cannot create deprecated wallets from JSON")); - wallet.reset(make_basic(vm, opts).release()); + wallet.reset(make_basic(vm, opts, password_prompter).release()); wallet->set_refresh_from_block_height(field_scan_from_height); try @@ -376,8 +356,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, { cryptonote::account_public_address address; if (!crypto::secret_key_to_public_key(viewkey, address.m_view_public_key)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key")); } if (field_spendkey.empty()) @@ -389,8 +368,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, cryptonote::address_parse_info info; if(!get_account_address_from_str(info, testnet, field_address)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to parse address: ") << field_address; - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("failed to parse address: ")) + field_address); } address.m_spend_public_key = info.address.m_spend_public_key; } @@ -404,8 +382,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, else { if (!crypto::secret_key_to_public_key(spendkey, address.m_spend_public_key)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key")); } wallet->generate(field_filename, field_password, address, spendkey, viewkey); } @@ -413,8 +390,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, } catch (const std::exception& e) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to generate new wallet: ") << e.what(); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("failed to generate new wallet: ")) + e.what()); } return true; }; @@ -468,6 +444,19 @@ static void emplace_or_replace(std::unordered_multimap<crypto::hash, tools::wall container.emplace(key, pd); } +void drop_from_short_history(std::list<crypto::hash> &short_chain_history, size_t N) +{ + std::list<crypto::hash>::iterator right; + // drop early N off, skipping the genesis block + if (short_chain_history.size() > N) { + right = short_chain_history.end(); + std::advance(right,-1); + std::list<crypto::hash>::iterator left = right; + std::advance(left, -N); + short_chain_history.erase(left, right); + } +} + } //namespace namespace tools @@ -496,34 +485,22 @@ void wallet2::init_options(boost::program_options::options_description& desc_par command_line::add_arg(desc_params, opts.restricted); } -boost::optional<password_container> wallet2::password_prompt(const bool new_password) -{ - auto pwd_container = tools::password_container::prompt( - new_password, (new_password ? tr("Enter new wallet password") : tr("Wallet password")) - ); - if (!pwd_container) - { - tools::fail_msg_writer() << tr("failed to read wallet password"); - } - return pwd_container; -} - -std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file) +std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) { const options opts{}; - return generate_from_json(json_file, vm, opts); + return generate_from_json(json_file, vm, opts, password_prompter); } std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file( - const boost::program_options::variables_map& vm, const std::string& wallet_file) + const boost::program_options::variables_map& vm, const std::string& wallet_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) { const options opts{}; - auto pwd = get_password(vm, opts, false); + auto pwd = get_password(vm, opts, password_prompter, false); if (!pwd) { return {nullptr, password_container{}}; } - auto wallet = make_basic(vm, opts); + auto wallet = make_basic(vm, opts, password_prompter); if (wallet) { wallet->load(wallet_file, pwd->password()); @@ -531,21 +508,21 @@ std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file( return {std::move(wallet), std::move(*pwd)}; } -std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const boost::program_options::variables_map& vm) +std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const boost::program_options::variables_map& vm, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter) { const options opts{}; - auto pwd = get_password(vm, opts, true); + auto pwd = get_password(vm, opts, password_prompter, true); if (!pwd) { return {nullptr, password_container{}}; } - return {make_basic(vm, opts), std::move(*pwd)}; + return {make_basic(vm, opts, password_prompter), std::move(*pwd)}; } -std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::variables_map& vm) +std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::variables_map& vm, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) { const options opts{}; - return make_basic(vm, opts); + return make_basic(vm, opts, password_prompter); } //---------------------------------------------------------------------------------------------------- @@ -1521,6 +1498,8 @@ void wallet2::pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_hei try { + drop_from_short_history(short_chain_history, 3); + // prepend the last 3 blocks, should be enough to guard against a block or two's reorg cryptonote::block bl; std::list<cryptonote::block_complete_entry>::const_reverse_iterator i = prev_blocks.rbegin(); @@ -1810,16 +1789,8 @@ void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, if (hashes.size() <= 3) return; if (hashes.size() + current_index < stop_height) { - std::list<crypto::hash>::iterator right; - // drop early 3 off, skipping the genesis block - if (short_chain_history.size() > 3) { - right = short_chain_history.end(); - std::advance(right,-1); - std::list<crypto::hash>::iterator left = right; - std::advance(left, -3); - short_chain_history.erase(left, right); - } - right = hashes.end(); + drop_from_short_history(short_chain_history, 3); + std::list<crypto::hash>::iterator right = hashes.end(); // prepend 3 more for (int i = 0; i<3; i++) { right--; @@ -6523,16 +6494,12 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent std::string data; bool r = epee::file_io_utils::load_file_to_string(filename, data); - if (!r) - { - fail_msg_writer() << tr("failed to read file ") << filename; - return 0; - } + THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename); + const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC); if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen)) { - fail_msg_writer() << "Bad key image export file magic in " << filename; - return 0; + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename); } try @@ -6541,31 +6508,22 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent } catch (const std::exception &e) { - fail_msg_writer() << "Failed to decrypt " << filename << ": " << e.what(); - return 0; + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename + ": " + e.what()); } const size_t headerlen = 2 * sizeof(crypto::public_key); - if (data.size() < headerlen) - { - fail_msg_writer() << "Bad data size from file " << filename; - return 0; - } + THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename); const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[0]; const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[sizeof(crypto::public_key)]; const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key) { - fail_msg_writer() << "Key images from " << filename << " are for a different account"; - return 0; + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename + " are for a different account"); } const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature); - if ((data.size() - headerlen) % record_size) - { - fail_msg_writer() << "Bad data size from file " << filename; - return 0; - } + THROW_WALLET_EXCEPTION_IF((data.size() - headerlen) % record_size, + error::wallet_internal_error, std::string("Bad data size from file ") + filename); size_t nki = (data.size() - headerlen) / record_size; std::vector<std::pair<crypto::key_image, crypto::signature>> ski; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 8576227e8..b07295253 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -155,21 +155,18 @@ namespace tools static bool has_testnet_option(const boost::program_options::variables_map& vm); static void init_options(boost::program_options::options_description& desc_params); - //! \return Password retrieved from prompt. Logs error on failure. - static boost::optional<password_container> password_prompt(const bool new_password); - //! Uses stdin and stdout. Returns a wallet2 if no errors. - static std::unique_ptr<wallet2> make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file); + static std::unique_ptr<wallet2> make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter); //! Uses stdin and stdout. Returns a wallet2 and password for `wallet_file` if no errors. static std::pair<std::unique_ptr<wallet2>, password_container> - make_from_file(const boost::program_options::variables_map& vm, const std::string& wallet_file); + make_from_file(const boost::program_options::variables_map& vm, const std::string& wallet_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter); //! Uses stdin and stdout. Returns a wallet2 and password for wallet with no file if no errors. - static std::pair<std::unique_ptr<wallet2>, password_container> make_new(const boost::program_options::variables_map& vm); + static std::pair<std::unique_ptr<wallet2>, password_container> make_new(const boost::program_options::variables_map& vm, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter); //! Just parses variables. - static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm); + static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter); static bool verify_password(const std::string& keys_file_name, const std::string& password, bool watch_only); diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp index df01ec238..cc6bb1de2 100644 --- a/src/wallet/wallet_args.cpp +++ b/src/wallet/wallet_args.cpp @@ -30,7 +30,6 @@ #include <boost/filesystem/path.hpp> #include <boost/format.hpp> #include "common/i18n.h" -#include "common/scoped_message_writer.h" #include "common/util.h" #include "misc_log_ex.h" #include "string_tools.h" @@ -50,6 +49,20 @@ #define DEFAULT_MAX_CONCURRENCY 0 #endif +namespace +{ + class Print + { + public: + Print(const std::function<void(const std::string&, bool)> &p, bool em = false): print(p), emphasis(em) {} + ~Print() { print(ss.str(), emphasis); } + template<typename T> std::ostream &operator<<(const T &t) { ss << t; return ss; } + private: + const std::function<void(const std::string&, bool)> &print; + std::stringstream ss; + bool emphasis; + }; +} namespace wallet_args { @@ -73,6 +86,7 @@ namespace wallet_args const char* const usage, boost::program_options::options_description desc_params, const boost::program_options::positional_options_description& positional_options, + const std::function<void(const std::string&, bool)> &print, const char *default_log_name, bool log_to_console) @@ -118,16 +132,16 @@ namespace wallet_args if (command_line::get_arg(vm, command_line::arg_help)) { - tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL; - tools::msg_writer() << wallet_args::tr("This is the command line monero wallet. It needs to connect to a monero\n" + Print(print) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL; + Print(print) << wallet_args::tr("This is the command line monero wallet. It needs to connect to a monero\n" "daemon to work correctly.") << ENDL; - tools::msg_writer() << wallet_args::tr("Usage:") << ENDL << " " << usage; - tools::msg_writer() << desc_all; + Print(print) << wallet_args::tr("Usage:") << ENDL << " " << usage; + Print(print) << desc_all; return false; } else if (command_line::get_arg(vm, command_line::arg_version)) { - tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; + Print(print) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; return false; } @@ -142,7 +156,7 @@ namespace wallet_args } else { - tools::fail_msg_writer() << wallet_args::tr("Can't find config file ") << config; + MERROR(wallet_args::tr("Can't find config file ") << config); return false; } } @@ -167,14 +181,15 @@ namespace wallet_args if(command_line::has_arg(vm, arg_max_concurrency)) tools::set_max_concurrency(command_line::get_arg(vm, arg_max_concurrency)); - tools::scoped_message_writer(epee::console_color_white, true) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; + Print(print) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; if (!command_line::is_arg_defaulted(vm, arg_log_level)) MINFO("Setting log level = " << command_line::get_arg(vm, arg_log_level)); else MINFO("Setting log levels = " << getenv("MONERO_LOGS")); MINFO(wallet_args::tr("Logging to: ") << log_path); - tools::scoped_message_writer(epee::console_color_white, true) << boost::format(wallet_args::tr("Logging to %s")) % log_path; + + Print(print) << boost::format(wallet_args::tr("Logging to %s")) % log_path; return {std::move(vm)}; } diff --git a/src/wallet/wallet_args.h b/src/wallet/wallet_args.h index cf23ffded..8974098ad 100644 --- a/src/wallet/wallet_args.h +++ b/src/wallet/wallet_args.h @@ -50,5 +50,6 @@ namespace wallet_args const char* const usage, boost::program_options::options_description desc_params, const boost::program_options::positional_options_description& positional_options, + const std::function<void(const std::string&, bool)> &print, const char *default_log_name, bool log_to_console = false); } diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index 9d66f125e..41eb77451 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -765,6 +765,12 @@ namespace tools #define STRINGIZE_DETAIL(x) #x #define STRINGIZE(x) STRINGIZE_DETAIL(x) +#define THROW_WALLET_EXCEPTION(err_type, ...) \ + do { \ + LOG_ERROR("THROW EXCEPTION: " << #err_type); \ + tools::error::throw_wallet_ex<err_type>(std::string(__FILE__ ":" STRINGIZE(__LINE__)), ## __VA_ARGS__); \ + } while(0) + #define THROW_WALLET_EXCEPTION_IF(cond, err_type, ...) \ if (cond) \ { \ diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index fda8f244a..173cc7bbe 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -38,6 +38,7 @@ using namespace epee; #include "wallet/wallet_args.h" #include "common/command_line.h" #include "common/i18n.h" +#include "common/scoped_message_writer.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "cryptonote_basic/account.h" #include "wallet_rpc_server_commands_defs.h" @@ -60,6 +61,16 @@ namespace const command_line::arg_descriptor<std::string> arg_wallet_dir = {"wallet-dir", "Directory for newly created wallets"}; constexpr const char default_rpc_username[] = "monero"; + + boost::optional<tools::password_container> password_prompter(const char *prompt, bool verify) + { + auto pwd_container = tools::password_container::prompt(verify, prompt); + if (!pwd_container) + { + MERROR("failed to read wallet password"); + } + return pwd_container; + } } namespace tools @@ -131,7 +142,7 @@ namespace tools walvars = m_wallet; else { - tmpwal = tools::wallet2::make_dummy(*m_vm); + tmpwal = tools::wallet2::make_dummy(*m_vm, password_prompter); walvars = tmpwal.get(); } boost::optional<epee::net_utils::http::login> http_login{}; @@ -1798,7 +1809,7 @@ namespace tools command_line::add_arg(desc, arg_password); po::store(po::parse_command_line(argc, argv, desc), vm2); } - std::unique_ptr<tools::wallet2> wal = tools::wallet2::make_new(vm2).first; + std::unique_ptr<tools::wallet2> wal = tools::wallet2::make_new(vm2, password_prompter).first; if (!wal) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; @@ -1872,7 +1883,7 @@ namespace tools } std::unique_ptr<tools::wallet2> wal = nullptr; try { - wal = tools::wallet2::make_from_file(vm2, wallet_file).first; + wal = tools::wallet2::make_from_file(vm2, wallet_file, password_prompter).first; } catch (const std::exception& e) { @@ -1971,6 +1982,7 @@ int main(int argc, char** argv) { "monero-wallet-rpc [--wallet-file=<file>|--generate-from-json=<file>|--wallet-dir=<directory>] [--rpc-bind-port=<port>]", desc_params, po::positional_options_description(), + [](const std::string &s, bool emphasis){ tools::scoped_message_writer(emphasis ? epee::console_color_white : epee::console_color_default, true) << s; }, "monero-wallet-rpc.log", true ); @@ -2007,11 +2019,19 @@ int main(int argc, char** argv) { LOG_PRINT_L0(tools::wallet_rpc_server::tr("Loading wallet...")); if(!wallet_file.empty()) { - wal = tools::wallet2::make_from_file(*vm, wallet_file).first; + wal = tools::wallet2::make_from_file(*vm, wallet_file, password_prompter).first; } else { - wal = tools::wallet2::make_from_json(*vm, from_json); + try + { + wal = tools::wallet2::make_from_json(*vm, from_json, password_prompter); + } + catch (const std::exception &e) + { + MERROR("Error creating wallet: " << e.what()); + return 1; + } } if (!wal) { diff --git a/tests/core_proxy/core_proxy.cpp b/tests/core_proxy/core_proxy.cpp index 0dc314b49..fd07a5d2e 100644 --- a/tests/core_proxy/core_proxy.cpp +++ b/tests/core_proxy/core_proxy.cpp @@ -34,12 +34,8 @@ #include "include_base_utils.h" #include "version.h" - -using namespace epee; - #include <iostream> #include <sstream> -using namespace std; #include <boost/program_options.hpp> @@ -56,6 +52,8 @@ using namespace std; #endif namespace po = boost::program_options; +using namespace std; +using namespace epee; using namespace cryptonote; using namespace crypto; @@ -81,7 +79,7 @@ int main(int argc, char* argv[]) po::options_description desc("Allowed options"); // tools::get_default_data_dir() can't be called during static initialization - command_line::add_arg(desc, command_line::arg_data_dir, tools::get_default_data_dir()); + command_line::add_arg(desc, cryptonote::arg_data_dir, tools::get_default_data_dir()); nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> >::init_options(desc); po::variables_map vm; diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 2b713cab9..4c5dc6c9a 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -47,6 +47,7 @@ using namespace std; using namespace epee; +using namespace crypto; using namespace cryptonote; diff --git a/tests/fuzz/block.cpp b/tests/fuzz/block.cpp index 099e8e3bd..03751fc14 100644 --- a/tests/fuzz/block.cpp +++ b/tests/fuzz/block.cpp @@ -27,7 +27,6 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "include_base_utils.h" -#include "common/command_line.h" #include "file_io_utils.h" #include "cryptonote_protocol/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" diff --git a/tests/fuzz/cold-transaction.cpp b/tests/fuzz/cold-transaction.cpp index c35d604a8..25a80fc68 100644 --- a/tests/fuzz/cold-transaction.cpp +++ b/tests/fuzz/cold-transaction.cpp @@ -27,7 +27,6 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "include_base_utils.h" -#include "common/command_line.h" #include "file_io_utils.h" #include "cryptonote_protocol/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" diff --git a/tests/fuzz/signature.cpp b/tests/fuzz/signature.cpp index 071297ba8..42a8fa997 100644 --- a/tests/fuzz/signature.cpp +++ b/tests/fuzz/signature.cpp @@ -27,7 +27,6 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "include_base_utils.h" -#include "common/command_line.h" #include "file_io_utils.h" #include "cryptonote_protocol/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" diff --git a/tests/fuzz/transaction.cpp b/tests/fuzz/transaction.cpp index 21cd01bef..9e2b9f2cb 100644 --- a/tests/fuzz/transaction.cpp +++ b/tests/fuzz/transaction.cpp @@ -27,7 +27,6 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "include_base_utils.h" -#include "common/command_line.h" #include "file_io_utils.h" #include "cryptonote_protocol/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" diff --git a/tests/performance_tests/performance_utils.h b/tests/performance_tests/performance_utils.h index 061772cbd..6bf45ff83 100644 --- a/tests/performance_tests/performance_utils.h +++ b/tests/performance_tests/performance_utils.h @@ -40,7 +40,7 @@ void set_process_affinity(int core) { -#if defined (__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#if defined (__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__sun) return; #elif defined(BOOST_WINDOWS) DWORD_PTR mask = 1; @@ -62,7 +62,7 @@ void set_process_affinity(int core) void set_thread_high_priority() { -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__sun) return; #elif defined(BOOST_WINDOWS) ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS); diff --git a/tests/unit_tests/main.cpp b/tests/unit_tests/main.cpp index 76f2b2749..86e7bcef3 100644 --- a/tests/unit_tests/main.cpp +++ b/tests/unit_tests/main.cpp @@ -53,7 +53,7 @@ int main(int argc, char** argv) po::options_description desc_options("Command line options"); const command_line::arg_descriptor<std::string> arg_data_dir = {"data-dir", "Data files directory", "", true}; - command_line::add_arg(desc_options, command_line::arg_data_dir, ""); + command_line::add_arg(desc_options, arg_data_dir, ""); po::variables_map vm; bool r = command_line::handle_error_helper(desc_options, [&]() diff --git a/tests/unit_tests/ringct.cpp b/tests/unit_tests/ringct.cpp index af6afa636..ef6151efb 100644 --- a/tests/unit_tests/ringct.cpp +++ b/tests/unit_tests/ringct.cpp @@ -38,6 +38,7 @@ #include "ringct/rctSigs.h" #include "ringct/rctOps.h" +using namespace std; using namespace crypto; using namespace rct; diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp index 011082d1c..0750ab7d1 100644 --- a/tests/unit_tests/serialization.cpp +++ b/tests/unit_tests/serialization.cpp @@ -49,6 +49,7 @@ #include "gtest/gtest.h" #include "unit_tests_utils.h" using namespace std; +using namespace crypto; struct Struct { |