diff options
101 files changed, 6778 insertions, 1986 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 45745abee..3d53e049e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -392,6 +392,9 @@ else() set(ARCH_FLAG "") elseif(PPC64LE) set(ARCH_FLAG "-mcpu=${ARCH}") + elseif(IOS AND ARCH STREQUAL "arm64") + message(STATUS "IOS: Changing arch from arm64 to armv8") + set(ARCH_FLAG "-march=armv8") else() set(ARCH_FLAG "-march=${ARCH}") endif() @@ -41,7 +41,11 @@ debug-test: debug-all: mkdir -p build/debug - cd build/debug && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Debug ../.. && $(MAKE) + cd build/debug && cmake -D BUILD_TESTS=ON -D BUILD_SHARED_LIBS=OFF -D CMAKE_BUILD_TYPE=Debug ../.. && $(MAKE) + +debug-static-all: + mkdir -p build/debug + cd build/debug && cmake -D BUILD_TESTS=ON -D STATIC=ON -D CMAKE_BUILD_TYPE=Debug ../.. && $(MAKE) cmake-release: mkdir -p build/release @@ -1,6 +1,7 @@ # Monero Copyright (c) 2014-2017, The Monero Project +Portions Copyright (c) 2012-2013, The Cryptonote developers ## Development Resources @@ -322,6 +323,15 @@ You will have to add the serialization, date_time, and regex modules to Boost wh To build: `env CC=egcc CXX=eg++ CPP=ecpp DEVELOPER_LOCAL_TOOLS=1 BOOST_ROOT=/path/to/the/boost/you/built make release-static-64` +### On Linux for Android (using docker): + + # Build image (select android64.Dockerfile for aarch64) + cd utils/build_scripts/ && docker build -f android32.Dockerfile -t monero-android . + # Create container + docker create -it --name monero-android monero-android bash + # Get binaries + docker cp monero-android:/opt/android/monero/build/release/bin . + ### Building Portable Statically Linked Binaries By default, in either dynamically or statically linked builds, binaries target the specific host processor on which the build happens and are not portable to other processors. Portable binaries can be built using the following targets: diff --git a/cmake/FindMiniupnpc.cmake b/cmake/FindMiniupnpc.cmake index ab525b3a7..77675db48 100644 --- a/cmake/FindMiniupnpc.cmake +++ b/cmake/FindMiniupnpc.cmake @@ -4,10 +4,7 @@ # MINIUPNP_FOUND, if false, do not try to link to miniupnp # MINIUPNP_LIBRARY, the miniupnp variant # MINIUPNP_INCLUDE_DIR, where to find miniupnpc.h and family) -# MINIUPNPC_VERSION_PRE1_6 --> set if we detect the version of miniupnpc is -# pre 1.6 -# MINIUPNPC_VERSION_PRE1_5 --> set if we detect the version of miniupnpc is -# pre 1.5 +# MINIUPNPC_VERSION_1_7_OR_HIGHER, set if we detect the version of miniupnpc is 1.7 or higher # # Note that the expected include convention is # #include "miniupnpc.h" @@ -16,170 +13,47 @@ # This is because, the miniupnpc location is not standardized and may exist # in locations other than miniupnpc/ -#============================================================================= -# Copyright 2011 Mark Vejvoda -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY) # Already in cache, be silent set(MINIUPNP_FIND_QUIETLY TRUE) endif () find_path(MINIUPNP_INCLUDE_DIR miniupnpc.h - PATH_SUFFIXES miniupnpc) -find_library(MINIUPNP_LIBRARY miniupnpc) - -if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY) - set (MINIUPNP_FOUND TRUE) -endif () - -if (MINIUPNP_FOUND) - include(CheckCXXSourceRuns) - if (NOT MINIUPNP_FIND_QUIETLY) - message (STATUS "Found the miniupnpc libraries at ${MINIUPNP_LIBRARY}") - message (STATUS "Found the miniupnpc headers at ${MINIUPNP_INCLUDE_DIR}") - endif () - - message(STATUS "Detecting version of miniupnpc in path: ${MINIUPNP_INCLUDE_DIR}") - - set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) - set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) - check_cxx_source_runs(" - #include <miniwget.h> - #include <miniupnpc.h> - #include <upnpcommands.h> - #include <stdio.h> - int main() - { - static struct UPNPUrls urls; - static struct IGDdatas data; - - GetUPNPUrls (&urls, &data, \"myurl\",0); - - return 0; - }" - MINIUPNPC_VERSION_1_7_OR_HIGHER) - -IF (NOT MINIUPNPC_VERSION_1_7_OR_HIGHER) - set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) - set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) - check_cxx_source_runs(" - #include <miniwget.h> - #include <miniupnpc.h> - #include <upnpcommands.h> - #include <stdio.h> - int main() - { - struct UPNPDev *devlist = NULL; - int upnp_delay = 5000; - const char *upnp_multicastif = NULL; - const char *upnp_minissdpdsock = NULL; - int upnp_sameport = 0; - int upnp_ipv6 = 0; - int upnp_error = 0; - devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport, upnp_ipv6, &upnp_error); - - return 0; - }" - MINIUPNPC_VERSION_PRE1_7) - ENDIF() - - IF (NOT MINIUPNPC_VERSION_PRE1_7 AND NOT MINIUPNPC_VERSION_1_7_OR_HIGHER) - set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) - set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) - check_cxx_source_runs(" - #include <miniwget.h> - #include <miniupnpc.h> - #include <upnpcommands.h> - #include <stdio.h> - int main() - { - struct UPNPDev *devlist = NULL; - int upnp_delay = 5000; - const char *upnp_multicastif = NULL; - const char *upnp_minissdpdsock = NULL; - int upnp_sameport = 0; - int upnp_ipv6 = 0; - int upnp_error = 0; - devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport); - - return 0; - }" - MINIUPNPC_VERSION_PRE1_6) - - ENDIF() - - IF (NOT MINIUPNPC_VERSION_PRE1_6 AND NOT MINIUPNPC_VERSION_PRE1_7 AND NOT MINIUPNPC_VERSION_1_7_OR_HIGHER) - set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) - set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) - check_cxx_source_runs(" - #include <miniwget.h> - #include <miniupnpc.h> - #include <upnpcommands.h> - #include <stdio.h> - static struct UPNPUrls urls; - static struct IGDdatas data; - int main() - { - char externalIP[16] = \"\"; - UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP); - - return 0; - }" - MINIUPNPC_VERSION_1_5_OR_HIGHER) - ENDIF() - - IF (NOT MINIUPNPC_VERSION_1_5_OR_HIGHER AND NOT MINIUPNPC_VERSION_PRE1_6 AND NOT MINIUPNPC_VERSION_PRE1_7 AND NOT MINIUPNPC_VERSION_1_7_OR_HIGHER) - set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) - set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) - check_cxx_source_runs(" - #include <miniwget.h> - #include <miniupnpc.h> - #include <upnpcommands.h> - #include <stdio.h> - static struct UPNPUrls urls; - static struct IGDdatas data; - int main() - { - char externalIP[16] = \"\"; - UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP); - - return 0; - }" - MINIUPNPC_VERSION_PRE1_5) - -ENDIF() - -IF(MINIUPNPC_VERSION_PRE1_5) - message(STATUS "Found miniupnpc version is pre v1.5") -ENDIF() -IF(MINIUPNPC_VERSION_PRE1_6) - message(STATUS "Found miniupnpc version is pre v1.6") + HINTS $ENV{MINIUPNP_INCLUDE_DIR} + PATH_SUFFIXES miniupnpc +) + +find_library(MINIUPNP_LIBRARY miniupnpc + HINTS $ENV{MINIUPNP_LIBRARY} +) + +find_library(MINIUPNP_STATIC_LIBRARY libminiupnpc.a + HINTS $ENV{MINIUPNP_STATIC_LIBRARY} +) + +set(MINIUPNP_INCLUDE_DIRS ${MINIUPNP_INCLUDE_DIR}) +set(MINIUPNP_LIBRARIES ${MINIUPNP_LIBRARY}) +set(MINIUPNP_STATIC_LIBRARIES ${MINIUPNP_STATIC_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + MiniUPnPc DEFAULT_MSG + MINIUPNP_INCLUDE_DIR + MINIUPNP_LIBRARY +) + +IF(MINIUPNPC_FOUND) + file(STRINGS "${MINIUPNP_INCLUDE_DIR}/miniupnpc.h" MINIUPNPC_API_VERSION_STR REGEX "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+[0-9]+") + if(MINIUPNPC_API_VERSION_STR MATCHES "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)") + set(MINIUPNPC_API_VERSION "${CMAKE_MATCH_1}") + endif() + + if (${MINIUPNPC_API_VERSION} GREATER "10" OR ${MINIUPNPC_API_VERSION} EQUAL "10") + message(STATUS "Found miniupnpc API version " ${MINIUPNPC_API_VERSION}) + set(MINIUPNP_FOUND true) + set(MINIUPNPC_VERSION_1_7_OR_HIGHER true) + endif() ENDIF() -IF(MINIUPNPC_VERSION_PRE1_7) - message(STATUS "Found miniupnpc version is pre v1.7") -ENDIF() - -IF(NOT MINIUPNPC_VERSION_PRE1_5 AND NOT MINIUPNPC_VERSION_PRE1_6 AND NOT MINIUPNPC_VERSION_PRE1_7) - IF(MINIUPNPC_VERSION_1_5_OR_HIGHER) - message(STATUS "Found miniupnpc version is v1.5 or higher") - ELSE() - message(STATUS "Found miniupnpc version is v1.7 or higher") - ENDIF() -ENDIF() - -else () - message (STATUS "Could not find miniupnp") -endif () -MARK_AS_ADVANCED(MINIUPNP_INCLUDE_DIR MINIUPNP_LIBRARY) +mark_as_advanced(MINIUPNP_INCLUDE_DIR MINIUPNP_LIBRARY MINIUPNP_STATIC_LIBRARY) # --------------------------------- FindMiniupnpc End --------------------------------- diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index 6eeb1441f..ec4bcbe2d 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -60,6 +60,7 @@ #define MCDEBUG(cat,x) CLOG(DEBUG,cat) << x #define MCTRACE(cat,x) CLOG(TRACE,cat) << x #define MCLOG(level,cat,x) ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::NormalLog, cat) << x +#define MCLOG_FILE(level,cat,x) ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::FileOnlyLog, cat) << x #define MCLOG_COLOR(level,cat,color,x) MCLOG(level,cat,"\033[1;" color "m" << x << "\033[0m") #define MCLOG_RED(level,cat,x) MCLOG_COLOR(level,cat,"31",x) diff --git a/contrib/epee/include/misc_os_dependent.h b/contrib/epee/include/misc_os_dependent.h index 806d3e83e..69ded09e5 100644 --- a/contrib/epee/include/misc_os_dependent.h +++ b/contrib/epee/include/misc_os_dependent.h @@ -48,17 +48,17 @@ namespace epee namespace misc_utils { - inline uint64_t get_tick_count() + inline uint64_t get_ns_count() { #if defined(_MSC_VER) - return ::GetTickCount64(); + return ::GetTickCount64() * 1000000; #elif defined(WIN32) static LARGE_INTEGER pcfreq = {0}; LARGE_INTEGER ticks; if (!pcfreq.QuadPart) QueryPerformanceFrequency(&pcfreq); QueryPerformanceCounter(&ticks); - ticks.QuadPart *= 1000; /* we want msec */ + ticks.QuadPart *= 1000000000; /* we want nsec */ return ticks.QuadPart / pcfreq.QuadPart; #elif defined(__MACH__) clock_serv_t cclock; @@ -68,16 +68,21 @@ namespace misc_utils clock_get_time(cclock, &mts); mach_port_deallocate(mach_task_self(), cclock); - return (mts.tv_sec * 1000) + (mts.tv_nsec/1000000); + return (mts.tv_sec * 1000000000) + (mts.tv_nsec); #else struct timespec ts; if(clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { return 0; } - return (ts.tv_sec * 1000) + (ts.tv_nsec/1000000); + return (ts.tv_sec * 1000000000) + (ts.tv_nsec); #endif } + inline uint64_t get_tick_count() + { + return get_ns_count() / 1000000; + } + inline int call_sys_cmd(const std::string& cmd) { diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl index d9eca2479..c92a13bcc 100644 --- a/contrib/epee/include/net/http_protocol_handler.inl +++ b/contrib/epee/include/net/http_protocol_handler.inl @@ -547,7 +547,7 @@ namespace net_utils LOG_PRINT_L3("HTTP_RESPONSE_HEAD: << \r\n" << response_data); m_psnd_hndlr->do_send((void*)response_data.data(), response_data.size()); - if(response.m_body.size()) + if(response.m_body.size() && (query_info.m_http_method != http::http_method_head)) m_psnd_hndlr->do_send((void*)response.m_body.data(), response.m_body.size()); return res; } diff --git a/contrib/epee/include/net/levin_client.inl b/contrib/epee/include/net/levin_client.inl index 50a01aaa5..ab7c32c32 100644 --- a/contrib/epee/include/net/levin_client.inl +++ b/contrib/epee/include/net/levin_client.inl @@ -99,7 +99,7 @@ int levin_client_impl::invoke(int command, const std::string& in_buff, std::stri if(head.m_signature!=LEVIN_SIGNATURE) { - LOG_PRINT_L1("Signature missmatch in response"); + LOG_PRINT_L1("Signature mismatch in response"); return -1; } @@ -160,7 +160,7 @@ inline if(head.m_signature!=LEVIN_SIGNATURE) { - LOG_PRINT_L1("Signature missmatch in response"); + LOG_PRINT_L1("Signature mismatch in response"); return -1; } diff --git a/contrib/epee/include/net/levin_client_async.h b/contrib/epee/include/net/levin_client_async.h index 4b48070d6..337d345c4 100644 --- a/contrib/epee/include/net/levin_client_async.h +++ b/contrib/epee/include/net/levin_client_async.h @@ -408,7 +408,7 @@ namespace levin if(head.m_signature!=LEVIN_SIGNATURE) { - LOG_ERROR("Signature missmatch in response"); + LOG_ERROR("Signature mismatch in response"); return false; } diff --git a/contrib/epee/include/net/levin_helper.h b/contrib/epee/include/net/levin_helper.h index c51d7244b..05560dd90 100644 --- a/contrib/epee/include/net/levin_helper.h +++ b/contrib/epee/include/net/levin_helper.h @@ -94,7 +94,7 @@ namespace levin } if(head.m_cb != buff.size()-sizeof(levin::bucket_head)) { - LOG_PRINT_L3("sizes missmatch, at load_struct_from_levin_message"); + LOG_PRINT_L3("sizes mismatch, at load_struct_from_levin_message"); return false; } @@ -121,7 +121,7 @@ namespace levin } if(head.m_cb != buff.size()-sizeof(levin::bucket_head)) { - LOG_ERROR("sizes missmatch, at load_struct_from_levin_message"); + LOG_ERROR("sizes mismatch, at load_struct_from_levin_message"); return false; } diff --git a/contrib/epee/include/net/levin_protocol_handler.h b/contrib/epee/include/net/levin_protocol_handler.h index 3e1b8493a..fbc9727e2 100644 --- a/contrib/epee/include/net/levin_protocol_handler.h +++ b/contrib/epee/include/net/levin_protocol_handler.h @@ -103,7 +103,7 @@ namespace levin { if(m_cach_in_buffer.size() >= sizeof(uint64_t) && *((uint64_t*)m_cach_in_buffer.data()) != LEVIN_SIGNATURE) { - LOG_ERROR_CC(m_conn_context, "Signature missmatch on accepted connection"); + LOG_ERROR_CC(m_conn_context, "Signature mismatch on accepted connection"); return false; } is_continue = false; @@ -113,7 +113,7 @@ namespace levin bucket_head* phead = (bucket_head*)m_cach_in_buffer.data(); if(LEVIN_SIGNATURE != phead->m_signature) { - LOG_ERROR_CC(m_conn_context, "Signature missmatch on accepted connection"); + LOG_ERROR_CC(m_conn_context, "Signature mismatch on accepted connection"); return false; } m_current_head = *phead; diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 8aa0faba1..60a667690 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -88,6 +88,8 @@ public: bool request_callback(boost::uuids::uuid connection_id); template<class callback_t> bool foreach_connection(callback_t cb); + template<class callback_t> + bool for_connection(const boost::uuids::uuid &connection_id, callback_t cb); size_t get_connections_count(); async_protocol_handler_config():m_pcommands_handler(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE) @@ -804,6 +806,18 @@ bool async_protocol_handler_config<t_connection_context>::foreach_connection(cal return true; } //------------------------------------------------------------------------------------------ +template<class t_connection_context> template<class callback_t> +bool async_protocol_handler_config<t_connection_context>::for_connection(const boost::uuids::uuid &connection_id, callback_t cb) +{ + CRITICAL_REGION_LOCAL(m_connects_lock); + async_protocol_handler<t_connection_context>* aph = find_connection(connection_id); + if (!aph) + return false; + if(!cb(aph->get_context_ref())) + return false; + return true; +} +//------------------------------------------------------------------------------------------ template<class t_connection_context> size_t async_protocol_handler_config<t_connection_context>::get_connections_count() { diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h index 432169990..1d808cc4c 100644 --- a/contrib/epee/include/net/net_helper.h +++ b/contrib/epee/include/net/net_helper.h @@ -473,7 +473,7 @@ namespace net_utils if(bytes_transfered != buff.size()) { - LOG_ERROR("Transferred missmatch with transfer_at_least value: m_bytes_transferred=" << bytes_transfered << " at_least value=" << buff.size()); + LOG_ERROR("Transferred mismatch with transfer_at_least value: m_bytes_transferred=" << bytes_transfered << " at_least value=" << buff.size()); return false; } diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h index 3bea11985..ef3a1d146 100644 --- a/contrib/epee/include/net/net_utils_base.h +++ b/contrib/epee/include/net/net_utils_base.h @@ -155,7 +155,6 @@ namespace net_utils const network_address m_remote_address; const bool m_is_income; const time_t m_started; - bool m_in_timedsync; time_t m_last_recv; time_t m_last_send; uint64_t m_recv_cnt; @@ -171,7 +170,6 @@ namespace net_utils m_remote_address(remote_address), m_is_income(is_income), m_started(time(NULL)), - m_in_timedsync(false), m_last_recv(last_recv), m_last_send(last_send), m_recv_cnt(recv_cnt), @@ -184,7 +182,6 @@ namespace net_utils m_remote_address(new ipv4_network_address(0,0)), m_is_income(false), m_started(time(NULL)), - m_in_timedsync(false), m_last_recv(0), m_last_send(0), m_recv_cnt(0), diff --git a/contrib/epee/include/profile_tools.h b/contrib/epee/include/profile_tools.h index d3b1e4db4..f285fe48b 100644 --- a/contrib/epee/include/profile_tools.h +++ b/contrib/epee/include/profile_tools.h @@ -57,8 +57,15 @@ namespace epee #define TIME_MEASURE_START(var_name) uint64_t var_name = epee::misc_utils::get_tick_count(); +#define TIME_MEASURE_PAUSE(var_name) var_name = epee::misc_utils::get_tick_count() - var_name; +#define TIME_MEASURE_RESTART(var_name) var_name = epee::misc_utils::get_tick_count() - var_name; #define TIME_MEASURE_FINISH(var_name) var_name = epee::misc_utils::get_tick_count() - var_name; +#define TIME_MEASURE_NS_START(var_name) uint64_t var_name = epee::misc_utils::get_ns_count(); +#define TIME_MEASURE_NS_PAUSE(var_name) var_name = epee::misc_utils::get_ns_count() - var_name; +#define TIME_MEASURE_NS_RESTART(var_name) var_name = epee::misc_utils::get_ns_count() - var_name; +#define TIME_MEASURE_NS_FINISH(var_name) var_name = epee::misc_utils::get_ns_count() - var_name; + namespace profile_tools { struct local_call_account diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index bf2c8dacd..d4413a71b 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -70,6 +70,15 @@ public: \ #define KV_SERIALIZE_N(varialble, val_name) \ epee::serialization::selector<is_store>::serialize(this_ref.varialble, stg, hparent_section, val_name); + template<typename T> inline void serialize_default(const T &t, T v) { } + template<typename T> inline void serialize_default(T &t, T v) { t = v; } + +#define KV_SERIALIZE_OPT_N(variable, val_name, default_value) \ + do { \ + if (!epee::serialization::selector<is_store>::serialize(this_ref.variable, stg, hparent_section, val_name)) \ + epee::serialize_default(this_ref.variable, default_value); \ + } while (0); + #define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name) \ epee::serialization::selector<is_store>::serialize_t_val_as_blob(this_ref.varialble, stg, hparent_section, val_name); @@ -86,6 +95,7 @@ public: \ #define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble) #define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble) +#define KV_SERIALIZE_OPT(variable,default_value) KV_SERIALIZE_OPT_N(variable, #variable, default_value) } diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h index ba9292306..2023e2f2a 100644 --- a/contrib/epee/include/storages/portable_storage.h +++ b/contrib/epee/include/storages/portable_storage.h @@ -158,7 +158,7 @@ namespace epee pbuff->m_signature_b != PORTABLE_STORAGE_SIGNATUREB ) { - LOG_ERROR("portable_storage: wrong binary format - signature missmatch"); + LOG_ERROR("portable_storage: wrong binary format - signature mismatch"); return false; } if(pbuff->m_ver != PORTABLE_STORAGE_FORMAT_VER) diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp index a51654d36..2ac3138f9 100644 --- a/contrib/epee/src/mlog.cpp +++ b/contrib/epee/src/mlog.cpp @@ -91,7 +91,7 @@ static const char *get_default_categories(int level) switch (level) { case 0: - categories = "*:WARNING,net:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO"; + categories = "*:WARNING,net:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO"; break; case 1: categories = "*:WARNING,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO"; @@ -129,7 +129,7 @@ void mlog_configure(const std::string &filename_base, bool console) el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog); el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput); el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck); - el::Helpers::installPreRollOutCallback([&filename_base](const char *name, size_t){ + el::Helpers::installPreRollOutCallback([filename_base](const char *name, size_t){ std::string rname = generate_log_filename(filename_base.c_str()); rename(name, rname.c_str()); }); diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp index 549f49d45..ce8260ef6 100644 --- a/contrib/epee/src/readline_buffer.cpp +++ b/contrib/epee/src/readline_buffer.cpp @@ -152,13 +152,11 @@ static int process_input() static void handle_line(char* line) { - if(last_line == "exit" || last_line == "q") - { - return; - } - std::lock_guard<std::mutex> lock(sync_mutex); - rl_set_prompt(last_prompt.c_str()); - rl_already_prompted = 1; + // This function never gets called now as we are trapping newlines. + // However, it still needs to be present for readline to know we are + // manually handling lines. + rl_done = 1; + return; } static int handle_enter(int x, int y) @@ -167,30 +165,42 @@ static int handle_enter(int x, int y) char* line = NULL; line = rl_copy_text(0, rl_end); + std::string test_line = line; + boost::trim_right(test_line); + rl_crlf(); rl_on_new_line(); + + if(test_line.empty()) + { + last_line = ""; + rl_set_prompt(last_prompt.c_str()); + rl_replace_line("", 1); + rl_redisplay(); + have_line.notify_one(); + return 0; + } + rl_set_prompt(""); rl_replace_line("", 1); rl_redisplay(); - std::string test_line = line; - boost::trim_right(test_line); - if (test_line.length() > 0) + if (!test_line.empty()) { last_line = test_line; add_history(test_line.c_str()); - have_line.notify_one(); + history_set_pos(history_length); } free(line); if(last_line != "exit" && last_line != "q") { rl_set_prompt(last_prompt.c_str()); - rl_on_new_line_with_prompt(); + rl_replace_line("", 1); rl_redisplay(); } - rl_done = 1; + have_line.notify_one(); return 0; } @@ -236,6 +246,7 @@ static void install_line_handler() rl_startup_hook = startup_hook; rl_attempted_completion_function = attempted_completion; rl_callback_handler_install("", handle_line); + stifle_history(500); } static void remove_line_handler() diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index 136d4fa80..a6774a25c 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -31,6 +31,7 @@ #include "blockchain_db.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "profile_tools.h" +#include "ringct/rctOps.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "blockchain.db" diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 6bb96d1db..0073ddf54 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -37,6 +37,7 @@ #include "cryptonote_basic/cryptonote_format_utils.h" #include "crypto/crypto.h" #include "profile_tools.h" +#include "ringct/rctOps.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "blockchain.db.lmdb" diff --git a/src/blockchain_utilities/CMakeLists.txt b/src/blockchain_utilities/CMakeLists.txt index bb23cdc8b..628c037b3 100644 --- a/src/blockchain_utilities/CMakeLists.txt +++ b/src/blockchain_utilities/CMakeLists.txt @@ -26,6 +26,16 @@ # 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. +set(blocksdat "") +if(PER_BLOCK_CHECKPOINT) + if(APPLE) + add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*) + else() + add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat) + endif() + set(blocksdat "blocksdat.o") +endif() + set(blockchain_import_sources blockchain_import.cpp bootstrap_file.cpp @@ -33,7 +43,6 @@ set(blockchain_import_sources ) set(blockchain_import_private_headers - fake_core.h bootstrap_file.h blocksdat_file.h bootstrap_serialization.h @@ -65,7 +74,8 @@ set(cn_deserialize_sources monero_add_executable(blockchain_import ${blockchain_import_sources} - ${blockchain_import_private_headers}) + ${blockchain_import_private_headers} + ${blocksdat}) target_link_libraries(blockchain_import PRIVATE diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index a43e2b4ad..6f908c799 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -32,6 +32,7 @@ #include <fstream> #include <boost/filesystem.hpp> +#include "misc_log_ex.h" #include "bootstrap_file.h" #include "bootstrap_serialization.h" #include "cryptonote_basic/cryptonote_format_utils.h" @@ -39,11 +40,10 @@ #include "serialization/json_utils.h" // dump_json() #include "include_base_utils.h" #include "blockchain_db/db_types.h" +#include "cryptonote_core/cryptonote_core.h" #include <lmdb.h> // for db flag arguments -#include "fake_core.h" - #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "bcutil" @@ -205,20 +205,12 @@ int parse_db_arguments(const std::string& db_arg_str, std::string& db_type, int& } -template <typename FakeCore> -int pop_blocks(FakeCore& simple_core, int num_blocks) +int pop_blocks(cryptonote::core& core, int num_blocks) { - bool use_batch = false; - if (opt_batch) - { - if (simple_core.support_batch) - use_batch = true; - else - MWARNING("WARNING: batch transactions enabled but unsupported or unnecessary for this database type - ignoring"); - } + bool use_batch = opt_batch; if (use_batch) - simple_core.batch_start(); + core.get_blockchain_storage().get_db().batch_start(); int quit = 0; block popped_block; @@ -226,12 +218,11 @@ int pop_blocks(FakeCore& simple_core, int num_blocks) for (int i=0; i < num_blocks; ++i) { // simple_core.m_storage.pop_block_from_blockchain() is private, so call directly through db - simple_core.m_storage.get_db().pop_block(popped_block, popped_txs); + core.get_blockchain_storage().get_db().pop_block(popped_block, popped_txs); quit = 1; } - if (use_batch) { if (quit > 1) @@ -241,24 +232,73 @@ int pop_blocks(FakeCore& simple_core, int num_blocks) } else { - simple_core.batch_stop(); + core.get_blockchain_storage().get_db().batch_stop(); } - simple_core.m_storage.get_db().show_stats(); + core.get_blockchain_storage().get_db().show_stats(); } return num_blocks; } -template <typename FakeCore> -int import_from_file(FakeCore& simple_core, const std::string& import_file_path, uint64_t block_stop=0) +int check_flush(cryptonote::core &core, std::list<block_complete_entry> &blocks, bool force) { - if (std::is_same<fake_core_db, FakeCore>::value) + if (blocks.empty()) + return 0; + if (!force && blocks.size() < db_batch_size) + return 0; + + core.prepare_handle_incoming_blocks(blocks); + + for(const block_complete_entry& block_entry: blocks) { - // Reset stats, in case we're using newly created db, accumulating stats - // from addition of genesis block. - // This aligns internal db counts with importer counts. - simple_core.m_storage.get_db().reset_stats(); - } + // process transactions + for(auto& tx_blob: block_entry.txs) + { + tx_verification_context tvc = AUTO_VAL_INIT(tvc); + core.handle_incoming_tx(tx_blob, tvc, true, true, false); + if(tvc.m_verifivation_failed) + { + MERROR("transaction verification failed, tx_id = " + << epee::string_tools::pod_to_hex(get_blob_hash(tx_blob))); + core.cleanup_handle_incoming_blocks(); + return 1; + } + } + + // process block + + block_verification_context bvc = boost::value_initialized<block_verification_context>(); + + core.handle_incoming_block(block_entry.block, bvc, false); // <--- process block + + if(bvc.m_verifivation_failed) + { + MERROR("Block verification failed, id = " + << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block))); + core.cleanup_handle_incoming_blocks(); + return 1; + } + if(bvc.m_marked_as_orphaned) + { + MERROR("Block received at sync phase was marked as orphaned"); + core.cleanup_handle_incoming_blocks(); + return 1; + } + + } // each download block + core.cleanup_handle_incoming_blocks(); + + blocks.clear(); + return 0; +} + +int import_from_file(cryptonote::core& core, const std::string& import_file_path, uint64_t block_stop=0) +{ + // Reset stats, in case we're using newly created db, accumulating stats + // from addition of genesis block. + // This aligns internal db counts with importer counts. + core.get_blockchain_storage().get_db().reset_stats(); + boost::filesystem::path fs_import_file_path(import_file_path); boost::system::error_code ec; if (!boost::filesystem::exists(fs_import_file_path, ec)) @@ -300,7 +340,7 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, uint64_t start_height = 1; if (opt_resume) - start_height = simple_core.m_storage.get_current_blockchain_height(); + start_height = core.get_blockchain_storage().get_current_blockchain_height(); // Note that a new blockchain will start with block number 0 (total blocks: 1) // due to genesis block being added at initialization. @@ -315,21 +355,16 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, MINFO("start block: " << start_height << " stop block: " << block_stop); - bool use_batch = false; - if (opt_batch) - { - if (simple_core.support_batch) - use_batch = true; - else - MWARNING("WARNING: batch transactions enabled but unsupported or unnecessary for this database type - ignoring"); - } + bool use_batch = opt_batch && !opt_verify; if (use_batch) - simple_core.batch_start(db_batch_size); + core.get_blockchain_storage().get_db().batch_start(db_batch_size); MINFO("Reading blockchain from bootstrap file..."); std::cout << ENDL; + std::list<block_complete_entry> blocks; + // Within the loop, we skip to start_height before we start adding. // TODO: Not a bottleneck, but we can use what's done in count_blocks() and // only do the chunk size reads, skipping the chunk content reads until we're @@ -424,67 +459,34 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, << std::flush; } - std::vector<transaction> txs; - std::vector<transaction> archived_txs; - - archived_txs = bp.txs; - - // std::cout << refresh_string; - // MDEBUG("txs: " << archived_txs.size()); - - // if archived_txs is invalid - // { - // std::cout << refresh_string; - // MFATAL("exception while de-archiving txs, height=" << h); - // quit = 1; - // break; - // } - - // tx number 1: coinbase tx - // tx number 2 onwards: archived_txs - unsigned int tx_num = 1; - for (transaction tx : archived_txs) + if (opt_verify) { - ++tx_num; - // if tx is invalid - // { - // MFATAL("exception while indexing tx from txs, height=" << h <<", tx_num=" << tx_num); - // quit = 1; - // break; - // } - - // std::cout << refresh_string; - // MDEBUG("tx hash: " << get_transaction_hash(tx)); - - // crypto::hash hsh = null_hash; - // size_t blob_size = 0; - // NOTE: all tx hashes except for coinbase tx are available in the block data - // get_transaction_hash(tx, hsh, blob_size); - // MDEBUG("tx " << tx_num << " " << hsh << " : " << ENDL); - // MDEBUG(obj_to_json_str(tx) << ENDL); - - // add blocks with verification. - // for Blockchain and blockchain_storage add_new_block(). - if (opt_verify) + cryptonote::blobdata block; + cryptonote::block_to_blob(bp.block, block); + std::list<cryptonote::blobdata> txs; + for (const auto &tx: bp.txs) { - // crypto::hash hsh = null_hash; - // size_t blob_size = 0; - // get_transaction_hash(tx, hsh, blob_size); + txs.push_back(cryptonote::blobdata()); + cryptonote::tx_to_blob(tx, txs.back()); + } + blocks.push_back({block, txs}); + int ret = check_flush(core, blocks, false); + if (ret) + break; + } + else + { + std::vector<transaction> txs; + std::vector<transaction> archived_txs; + archived_txs = bp.txs; - uint8_t version = simple_core.m_storage.get_current_hard_fork_version(); - tx_verification_context tvc = AUTO_VAL_INIT(tvc); - bool r = true; - r = simple_core.m_pool.add_tx(tx, tvc, true, true, false, version); - if (!r) - { - MFATAL("failed to add transaction to transaction pool, height=" << h <<", tx_num=" << tx_num); - quit = 1; - break; - } - } - else + // tx number 1: coinbase tx + // tx number 2 onwards: archived_txs + for (transaction tx : archived_txs) { + // add blocks with verification. + // for Blockchain and blockchain_storage add_new_block(). // for add_block() method, without (much) processing. // don't add coinbase transaction to txs. // @@ -493,34 +495,7 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, // then a for loop for the transactions in txs. txs.push_back(tx); } - } - if (opt_verify) - { - block_verification_context bvc = boost::value_initialized<block_verification_context>(); - simple_core.m_storage.add_new_block(b, bvc); - - if (bvc.m_verifivation_failed) - { - MFATAL("Failed to add block to blockchain, verification failed, height = " << h); - MFATAL("skipping rest of file"); - // ok to commit previously batched data because it failed only in - // verification of potential new block with nothing added to batch - // yet - quit = 1; - break; - } - if (! bvc.m_added_to_main_chain) - { - MFATAL("Failed to add block to blockchain, height = " << h); - MFATAL("skipping rest of file"); - // make sure we don't commit partial block data - quit = 2; - break; - } - } - else - { size_t block_size; difficulty_type cumulative_difficulty; uint64_t coins_generated; @@ -529,14 +504,9 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, cumulative_difficulty = bp.cumulative_difficulty; coins_generated = bp.coins_generated; - // std::cout << refresh_string; - // MDEBUG("block_size: " << block_size); - // MDEBUG("cumulative_difficulty: " << cumulative_difficulty); - // MDEBUG("coins_generated: " << coins_generated); - try { - simple_core.add_block(b, block_size, cumulative_difficulty, coins_generated, txs); + core.get_blockchain_storage().get_db().add_block(b, block_size, cumulative_difficulty, coins_generated, txs); } catch (const std::exception& e) { @@ -545,22 +515,22 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, quit = 2; // make sure we don't commit partial block data break; } - } - ++num_imported; - if (use_batch) - { - if ((h-1) % db_batch_size == 0) + if (use_batch) { - std::cout << refresh_string; - // zero-based height - std::cout << ENDL << "[- batch commit at height " << h-1 << " -]" << ENDL; - simple_core.batch_stop(); - simple_core.batch_start(db_batch_size); - std::cout << ENDL; - simple_core.m_storage.get_db().show_stats(); + if ((h-1) % db_batch_size == 0) + { + std::cout << refresh_string; + // zero-based height + std::cout << ENDL << "[- batch commit at height " << h-1 << " -]" << ENDL; + core.get_blockchain_storage().get_db().batch_stop(); + core.get_blockchain_storage().get_db().batch_start(db_batch_size); + std::cout << ENDL; + core.get_blockchain_storage().get_db().show_stats(); + } } } + ++num_imported; } } catch (const std::exception& e) @@ -573,6 +543,13 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, import_file.close(); + if (opt_verify) + { + int ret = check_flush(core, blocks, true); + if (ret) + return ret; + } + if (use_batch) { if (quit > 1) @@ -582,14 +559,16 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, } else { - simple_core.batch_stop(); + core.get_blockchain_storage().get_db().batch_stop(); } - simple_core.m_storage.get_db().show_stats(); - MINFO("Number of blocks imported: " << num_imported); - if (h > 0) - // TODO: if there was an error, the last added block is probably at zero-based height h-2 - MINFO("Finished at block: " << h-1 << " total blocks: " << h); } + + core.get_blockchain_storage().get_db().show_stats(); + MINFO("Number of blocks imported: " << num_imported); + if (h > 0) + // TODO: if there was an error, the last added block is probably at zero-based height h-2 + MINFO("Finished at block: " << h-1 << " total blocks: " << h); + std::cout << ENDL; return 0; } @@ -649,10 +628,10 @@ int main(int argc, char* argv[]) const command_line::arg_descriptor<bool> arg_resume = {"resume", "Resume from current height if output database already exists", true}; - 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, 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, arg_input_file); - command_line::add_arg(desc_cmd_sett, arg_testnet_on); + //command_line::add_arg(desc_cmd_sett, 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_batch_size); @@ -673,6 +652,7 @@ int main(int argc, char* argv[]) po::options_description desc_options("Allowed options"); desc_options.add(desc_cmd_only).add(desc_cmd_sett); + cryptonote::core::init_options(desc_options); po::variables_map vm; bool r = command_line::handle_error_helper(desc_options, [&]() @@ -818,26 +798,34 @@ int main(int argc, char* argv[]) return 1; } - // for multi_db_compile: - fake_core_db simple_core(m_config_folder, opt_testnet, opt_batch, db_type, db_flags); + cryptonote::cryptonote_protocol_stub pr; //TODO: stub only for this kind of test, make real validation of relayed objects + cryptonote::core core(&pr); + core.disable_dns_checkpoints(true); + if (!core.init(vm, NULL)) + { + std::cerr << "Failed to initialize core" << ENDL; + return 1; + } + core.get_blockchain_storage().get_db().set_batch_transactions(true); if (! vm["pop-blocks"].defaulted()) { num_blocks = command_line::get_arg(vm, arg_pop_blocks); - MINFO("height: " << simple_core.m_storage.get_current_blockchain_height()); - pop_blocks(simple_core, num_blocks); - MINFO("height: " << simple_core.m_storage.get_current_blockchain_height()); + MINFO("height: " << core.get_blockchain_storage().get_current_blockchain_height()); + pop_blocks(core, num_blocks); + MINFO("height: " << core.get_blockchain_storage().get_current_blockchain_height()); return 0; } if (! vm["drop-hard-fork"].defaulted()) { MINFO("Dropping hard fork tables..."); - simple_core.m_storage.get_db().drop_hard_fork_info(); + core.get_blockchain_storage().get_db().drop_hard_fork_info(); + core.deinit(); return 0; } - import_from_file(simple_core, import_file_path, block_stop); + import_from_file(core, import_file_path, block_stop); } catch (const DB_ERROR& e) diff --git a/src/blockchain_utilities/fake_core.h b/src/blockchain_utilities/fake_core.h deleted file mode 100644 index 809c6fe43..000000000 --- a/src/blockchain_utilities/fake_core.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2014-2017, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#include <boost/filesystem.hpp> -#include "cryptonote_core/blockchain.h" // BlockchainDB -#include "cryptonote_core/tx_pool.h" -#include "blockchain_db/blockchain_db.h" -#include "blockchain_db/lmdb/db_lmdb.h" -#if defined(BERKELEY_DB) -#include "blockchain_db/berkeleydb/db_bdb.h" -#endif - -using namespace cryptonote; - -namespace -{ - // NOTE: These values should match blockchain.cpp - // TODO: Refactor - const uint64_t mainnet_hard_fork_version_1_till = 1009826; - const uint64_t testnet_hard_fork_version_1_till = 624633; -} - - -struct fake_core_db -{ - Blockchain m_storage; - HardFork* m_hardfork = nullptr; - tx_memory_pool m_pool; - bool support_batch; - bool support_add_block; - - // for multi_db_runtime: - fake_core_db(const boost::filesystem::path &path, const bool use_testnet=false, const bool do_batch=true, const std::string& db_type="lmdb", const int db_flags=0) : m_pool(m_storage), m_storage(m_pool) - { - BlockchainDB* db = nullptr; - if (db_type == "lmdb") - db = new BlockchainLMDB(); -#if defined(BERKELEY_DB) - else if (db_type == "berkeley") - db = new BlockchainBDB(); -#endif - else - { - LOG_ERROR("Attempted to use non-existent database type: " << db_type); - throw std::runtime_error("Attempting to use non-existent database type"); - } - - boost::filesystem::path folder(path); - - folder /= db->get_db_name(); - - LOG_PRINT_L0("Loading blockchain from folder " << folder.string() << " ..."); - - const std::string filename = folder.string(); - try - { - db->open(filename, db_flags); - } - catch (const std::exception& e) - { - LOG_PRINT_L0("Error opening database: " << e.what()); - throw; - } - - db->check_hard_fork_info(); - - uint64_t hard_fork_version_1_till = use_testnet ? testnet_hard_fork_version_1_till : mainnet_hard_fork_version_1_till; - m_hardfork = new HardFork(*db, 1, hard_fork_version_1_till); - - m_storage.init(db, m_hardfork, use_testnet); - - m_pool.init(); - - if (do_batch) - m_storage.get_db().set_batch_transactions(do_batch); - support_batch = true; - support_add_block = true; - } - ~fake_core_db() - { - m_storage.get_db().check_hard_fork_info(); - m_storage.deinit(); - } - - uint64_t add_block(const block& blk - , const size_t& block_size - , const difficulty_type& cumulative_difficulty - , const uint64_t& coins_generated - , const std::vector<transaction>& txs - ) - { - return m_storage.get_db().add_block(blk, block_size, cumulative_difficulty, coins_generated, txs); - } - - bool batch_start(uint64_t batch_num_blocks = 0) - { - return m_storage.get_db().batch_start(batch_num_blocks); - } - - void batch_stop() - { - m_storage.get_db().batch_stop(); - } - -}; - diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp index ab38cbbae..e7ff11c5c 100644 --- a/src/common/dns_utils.cpp +++ b/src/common/dns_utils.cpp @@ -26,12 +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. -#include "common/command_line.h" -#include "common/i18n.h" #include "common/dns_utils.h" +#include "common/i18n.h" #include "cryptonote_basic/cryptonote_basic_impl.h" -#include <cstring> -#include <sstream> // check local first (in the event of static or in-source compilation of libunbound) #include "unbound.h" @@ -307,12 +304,8 @@ DNSResolver& DNSResolver::instance() { boost::lock_guard<boost::mutex> lock(instance_lock); - static DNSResolver* staticInstance = NULL; - if (staticInstance == NULL) - { - staticInstance = new DNSResolver(); - } - return *staticInstance; + static DNSResolver staticInstance; + return staticInstance; } DNSResolver DNSResolver::create() @@ -405,7 +398,7 @@ std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec return addresses; } -std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, bool cli_confirm) +std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm) { // attempt to get address from dns query auto addresses = addresses_from_url(url, dnssec_valid); @@ -414,44 +407,7 @@ std::string get_account_address_as_str_from_url(const std::string& url, bool& dn LOG_ERROR("wrong address: " << url); return {}; } - // for now, move on only if one address found - if (addresses.size() > 1) - { - LOG_ERROR("not yet supported: Multiple Monero addresses found for given URL: " << url); - return {}; - } - if (!cli_confirm) - return addresses[0]; - // prompt user for confirmation. - // inform user of DNSSEC validation status as well. - std::string dnssec_str; - if (dnssec_valid) - { - dnssec_str = tr("DNSSEC validation passed"); - } - else - { - dnssec_str = tr("WARNING: DNSSEC validation was unsuccessful, this address may not be correct!"); - } - std::stringstream prompt; - prompt << tr("For URL: ") << url - << ", " << dnssec_str << std::endl - << tr(" Monero Address = ") << addresses[0] - << std::endl - << 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()); - if (std::cin.eof()) - { - return {}; - } - if (!command_line::is_yes(confirm_dns_ok)) - { - std::cout << tr("you have cancelled the transfer request") << std::endl; - return {}; - } - return addresses[0]; + return dns_confirm(url, addresses, dnssec_valid); } namespace diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h index 53c0c1c7b..f19584516 100644 --- a/src/common/dns_utils.h +++ b/src/common/dns_utils.h @@ -29,7 +29,7 @@ #include <vector> #include <string> -#include "cryptonote_basic/cryptonote_basic.h" +#include <functional> namespace tools { @@ -101,7 +101,7 @@ public: * * @return A vector of strings containing a TXT record; or an empty vector */ - // TODO: modify this to accomodate DNSSEC + // TODO: modify this to accommodate DNSSEC std::vector<std::string> get_txt_record(const std::string& url, bool& dnssec_available, bool& dnssec_valid); /** @@ -142,7 +142,7 @@ private: * * @return A vector of strings containing the requested record; or an empty vector */ - // TODO: modify this to accomodate DNSSEC + // TODO: modify this to accommodate DNSSEC std::vector<std::string> get_record(const std::string& url, int record_type, std::string (*reader)(const char *,size_t), bool& dnssec_available, bool& dnssec_valid); /** @@ -163,7 +163,7 @@ namespace dns_utils std::string address_from_txt_record(const std::string& s); std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec_valid); -std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, bool cli_confirm = true); +std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> confirm_dns); bool load_txt_records_from_dns(std::vector<std::string> &records, const std::vector<std::string> &dns_urls); diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h index 56662ff24..bc8e05800 100644 --- a/src/common/perf_timer.h +++ b/src/common/perf_timer.h @@ -46,9 +46,9 @@ extern __thread std::vector<PerformanceTimer*> *performance_timers; class PerformanceTimer { public: - PerformanceTimer(const std::string &s, el::Level l = el::Level::Debug): name(s), level(l), started(false) + PerformanceTimer(const std::string &s, uint64_t unit, el::Level l = el::Level::Debug): name(s), unit(unit), level(l), started(false) { - ticks = epee::misc_utils::get_tick_count(); + ticks = epee::misc_utils::get_ns_count(); if (!performance_timers) { MLOG(level, "PERF ----------"); @@ -69,9 +69,9 @@ public: ~PerformanceTimer() { performance_timers->pop_back(); - ticks = epee::misc_utils::get_tick_count() - ticks; + ticks = epee::misc_utils::get_ns_count() - ticks; char s[12]; - snprintf(s, sizeof(s), "%8llu ", (unsigned long long)ticks); + snprintf(s, sizeof(s), "%8llu ", (unsigned long long)ticks / (1000000000 / unit)); MLOG(level, "PERF " << s << std::string(performance_timers->size() * 2, ' ') << " " << name); if (performance_timers->empty()) { @@ -82,6 +82,7 @@ public: private: std::string name; + uint64_t unit; el::Level level; uint64_t ticks; bool started; @@ -89,7 +90,9 @@ private: void set_performance_timer_log_level(el::Level level); -#define PERF_TIMER(name) tools::PerformanceTimer pt_##name(#name, tools::performance_timer_log_level) -#define PERF_TIMER_L(name, l) tools::PerformanceTimer pt_##name(#name, l) +#define PERF_TIMER_UNIT(name, unit) tools::PerformanceTimer pt_##name(#name, unit, tools::performance_timer_log_level) +#define PERF_TIMER_UNIT_L(name, unit, l) tools::PerformanceTimer pt_##name(#name, unit, l) +#define PERF_TIMER(name) PERF_TIMER_UNIT(name, 1000) +#define PERF_TIMER_L(name, l) PERF_TIMER_UNIT_L(name, 1000, l) } diff --git a/src/common/scoped_message_writer.h b/src/common/scoped_message_writer.h index 7ee4f1379..e31f8f0b2 100644 --- a/src/common/scoped_message_writer.h +++ b/src/common/scoped_message_writer.h @@ -91,7 +91,7 @@ public: { m_flush = false; - MCLOG(m_log_level, "msgwriter", m_oss.str()); + MCLOG_FILE(m_log_level, "msgwriter", m_oss.str()); if (epee::console_color_default == m_color) { diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp index ef64c20c5..6fdf4dd47 100644 --- a/src/common/stack_trace.cpp +++ b/src/common/stack_trace.cpp @@ -30,8 +30,7 @@ #define USE_UNWIND #endif -#include "common/stack_trace.h" -#include "misc_log_ex.h" +#include <stdexcept> #ifdef USE_UNWIND #define UNW_LOCAL_ONLY #include <libunwind.h> @@ -40,6 +39,8 @@ #ifndef STATICLIB #include <dlfcn.h> #endif +#include "common/stack_trace.h" +#include "misc_log_ex.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "stacktrace" diff --git a/src/common/stack_trace.h b/src/common/stack_trace.h index 25eec9fb3..0f6bdc08b 100644 --- a/src/common/stack_trace.h +++ b/src/common/stack_trace.h @@ -29,7 +29,6 @@ #ifndef MONERO_EXCEPTION_H #define MONERO_EXCEPTION_H -#include <stdexcept> #include <string> namespace tools diff --git a/src/common/updates.cpp b/src/common/updates.cpp index 5b1acf5fa..8a057b1cf 100644 --- a/src/common/updates.cpp +++ b/src/common/updates.cpp @@ -26,6 +26,7 @@ // 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. +#include "misc_log_ex.h" #include "util.h" #include "dns_utils.h" #include "updates.h" diff --git a/src/common/util.h b/src/common/util.h index 4291d7e18..2452bc9d5 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -40,7 +40,6 @@ #include <string> #include "crypto/hash.h" -#include "p2p/p2p_protocol_defs.h" /*! \brief Various Tools * @@ -108,14 +107,6 @@ namespace tools bool sanitize_locale(); - inline crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust& pot) - { - std::string s; - s.append(reinterpret_cast<const char*>(&pot.peer_id), sizeof(pot.peer_id)); - s.append(reinterpret_cast<const char*>(&pot.time), sizeof(pot.time)); - return crypto::cn_fast_hash(s.data(), s.size()); - } - /*! \brief Defines a signal handler for win32 and *nix */ class signal_handler diff --git a/src/cryptonote_basic/connection_context.h b/src/cryptonote_basic/connection_context.h index 8d739900e..06f66120b 100644 --- a/src/cryptonote_basic/connection_context.h +++ b/src/cryptonote_basic/connection_context.h @@ -39,6 +39,8 @@ namespace cryptonote struct cryptonote_connection_context: public epee::net_utils::connection_context_base { + cryptonote_connection_context(): m_state(state_befor_handshake), m_remote_blockchain_height(0), m_last_response_height(0), + m_last_known_hash(cryptonote::null_hash) {} enum state { @@ -53,7 +55,9 @@ namespace cryptonote std::unordered_set<crypto::hash> m_requested_objects; uint64_t m_remote_blockchain_height; uint64_t m_last_response_height; + boost::posix_time::ptime m_last_request_time; epee::copyable_atomic m_callback_request_count; //in debug purpose: problem with double callback rise + crypto::hash m_last_known_hash; //size_t m_score; TODO: add score calculations }; diff --git a/src/cryptonote_basic/cryptonote_basic_impl.cpp b/src/cryptonote_basic/cryptonote_basic_impl.cpp index edd67793f..a59f96956 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.cpp +++ b/src/cryptonote_basic/cryptonote_basic_impl.cpp @@ -308,13 +308,13 @@ namespace cryptonote { , crypto::hash8& payment_id , bool testnet , const std::string& str_or_url - , bool cli_confirm + , std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm ) { if (get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, str_or_url)) return true; bool dnssec_valid; - std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(str_or_url, dnssec_valid, cli_confirm); + std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(str_or_url, dnssec_valid, dns_confirm); return !address_str.empty() && get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, address_str); } @@ -323,12 +323,12 @@ namespace cryptonote { cryptonote::account_public_address& address , bool testnet , const std::string& str_or_url - , bool cli_confirm + , std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm ) { bool has_payment_id; crypto::hash8 payment_id; - return get_account_address_from_str_or_url(address, has_payment_id, payment_id, testnet, str_or_url, cli_confirm); + return get_account_address_from_str_or_url(address, has_payment_id, payment_id, testnet, str_or_url, dns_confirm); } //-------------------------------------------------------------------------------- bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b) { diff --git a/src/cryptonote_basic/cryptonote_basic_impl.h b/src/cryptonote_basic/cryptonote_basic_impl.h index 14c03ac4c..9838fcb47 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.h +++ b/src/cryptonote_basic/cryptonote_basic_impl.h @@ -67,6 +67,15 @@ namespace cryptonote { }; #pragma pack (pop) + namespace + { + std::string return_first_address(const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid) + { + if (addresses.empty()) + return {}; + return addresses[0]; + } + } /************************************************************************/ /* Cryptonote helper functions */ @@ -109,14 +118,14 @@ namespace cryptonote { , crypto::hash8& payment_id , bool testnet , const std::string& str_or_url - , bool cli_confirm = true + , std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm = return_first_address ); bool get_account_address_from_str_or_url( cryptonote::account_public_address& address , bool testnet , const std::string& str_or_url - , bool cli_confirm = true + , std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm = return_first_address ); bool is_coinbase(const transaction& tx); diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h index 5c10907fd..d8ccf8eec 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.h +++ b/src/cryptonote_basic/cryptonote_format_utils.h @@ -35,7 +35,6 @@ #include "include_base_utils.h" #include "crypto/crypto.h" #include "crypto/hash.h" -#include "ringct/rctOps.h" namespace cryptonote { diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index cd0943618..b14532d44 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -382,7 +382,7 @@ namespace cryptonote boost::thread::attributes attrs; attrs.set_stack_size(THREAD_STACK_SIZE); - start(m_mine_address, m_threads_total, attrs, get_is_background_mining_enabled()); + start(m_mine_address, m_threads_total, attrs, get_is_background_mining_enabled(), get_ignore_battery()); } } //----------------------------------------------------------------------------------------------------- @@ -846,40 +846,100 @@ namespace cryptonote #elif defined(__linux__) - // i've only tested on UBUNTU, these paths might be different on other systems - // need to figure out a way to make this more flexible - std::string power_supply_path = ""; - const std::string POWER_SUPPLY_STATUS_PATHS[] = - { - "/sys/class/power_supply/ACAD/online", - "/sys/class/power_supply/AC/online", - "/sys/class/power_supply/AC0/online", - "/sys/class/power_supply/ADP0/online" - }; + // Use the power_supply class http://lxr.linux.no/#linux+v4.10.1/Documentation/power/power_supply_class.txt + std::string power_supply_class_path = "/sys/class/power_supply"; - for(const std::string& path : POWER_SUPPLY_STATUS_PATHS) + boost::tribool on_battery = boost::logic::tribool(boost::logic::indeterminate); + if (boost::filesystem::is_directory(power_supply_class_path)) { - if( epee::file_io_utils::is_file_exist(path) ) + const boost::filesystem::directory_iterator end_itr; + for (boost::filesystem::directory_iterator iter(power_supply_class_path); iter != end_itr; ++iter) { - power_supply_path = path; - break; + const boost::filesystem::path& power_supply_path = iter->path(); + if (boost::filesystem::is_directory(power_supply_path)) + { + std::ifstream power_supply_present_stream((power_supply_path / "present").string()); + if (power_supply_present_stream.fail()) + { + LOG_PRINT_L0("Unable to read from " << power_supply_path << " to check if power supply present"); + continue; + } + + if (power_supply_present_stream.get() != '1') + { + LOG_PRINT_L4("Power supply not present at " << power_supply_path); + continue; + } + + boost::filesystem::path power_supply_type_path = power_supply_path / "type"; + if (boost::filesystem::is_regular_file(power_supply_type_path)) + { + std::ifstream power_supply_type_stream(power_supply_type_path.string()); + if (power_supply_type_stream.fail()) + { + LOG_PRINT_L0("Unable to read from " << power_supply_type_path << " to check power supply type"); + continue; + } + + std::string power_supply_type; + std::getline(power_supply_type_stream, power_supply_type); + + // If there is an AC adapter that's present and online we can break early + if (boost::starts_with(power_supply_type, "Mains")) + { + boost::filesystem::path power_supply_online_path = power_supply_path / "online"; + if (boost::filesystem::is_regular_file(power_supply_online_path)) + { + std::ifstream power_supply_online_stream(power_supply_online_path.string()); + if (power_supply_online_stream.fail()) + { + LOG_PRINT_L0("Unable to read from " << power_supply_online_path << " to check ac power supply status"); + continue; + } + + if (power_supply_online_stream.get() == '1') + { + return boost::logic::tribool(false); + } + } + } + else if (boost::starts_with(power_supply_type, "Battery") && boost::logic::indeterminate(on_battery)) + { + boost::filesystem::path power_supply_status_path = power_supply_path / "status"; + if (boost::filesystem::is_regular_file(power_supply_status_path)) + { + std::ifstream power_supply_status_stream(power_supply_status_path.string()); + if (power_supply_status_stream.fail()) + { + LOG_PRINT_L0("Unable to read from " << power_supply_status_path << " to check battery power supply status"); + continue; + } + + // Possible status are Charging, Full, Discharging, Not Charging, and Unknown + // We are only need to handle negative states right now + std::string power_supply_status; + std::getline(power_supply_status_stream, power_supply_status); + if (boost::starts_with(power_supply_status, "Charging") || boost::starts_with(power_supply_status, "Full")) + { + on_battery = boost::logic::tribool(false); + } + + if (boost::starts_with(power_supply_status, "Discharging")) + { + on_battery = boost::logic::tribool(true); + } + } + } + } + } } } - if( power_supply_path.empty() ) + if (boost::logic::indeterminate(on_battery)) { - LOG_ERROR("Couldn't find battery/power status file, can't determine if plugged in!"); - return boost::logic::tribool(boost::logic::indeterminate);; + LOG_ERROR("couldn't query power status from " << power_supply_class_path); } - - std::ifstream power_stream(power_supply_path); - if( power_stream.fail() ) - { - LOG_ERROR("failed to open '" << power_supply_path << "'"); - return boost::logic::tribool(boost::logic::indeterminate);; - } - - return boost::logic::tribool( (power_stream.get() != '1') ); + return on_battery; #endif diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 745608b9f..d1f5f0dcd 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -118,6 +118,8 @@ static const struct { { 3, 800500, 0, 1472415034 }, { 4, 801219, 0, 1472415035 }, { 5, 802660, 0, 1472415036 + 86400*180 }, // add 5 months on testnet to shut the update warning up since there's a large gap to v6 + + { 6, 971400, 0, 1501709789 }, }; static const uint64_t testnet_hard_fork_version_1_till = 624633; @@ -279,7 +281,8 @@ uint64_t Blockchain::get_current_blockchain_height() const bool Blockchain::init(BlockchainDB* db, const bool testnet, const cryptonote::test_options *test_options) { LOG_PRINT_L3("Blockchain::" << __func__); - CRITICAL_REGION_LOCAL(m_blockchain_lock); + CRITICAL_REGION_LOCAL(m_tx_pool); + CRITICAL_REGION_LOCAL1(m_blockchain_lock); bool fakechain = test_options != NULL; @@ -2254,8 +2257,8 @@ bool Blockchain::check_tx_inputs(transaction& tx, uint64_t& max_used_block_heigh TIME_MEASURE_FINISH(a); if(m_show_time_stats) { - size_t mixin = tx.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(tx.vin[0]).key_offsets.size() - 1 : 0; - MINFO("HASH: " << "-" << " I/M/O: " << tx.vin.size() << "/" << mixin << "/" << tx.vout.size() << " H: " << 0 << " chcktx: " << a); + size_t ring_size = tx.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(tx.vin[0]).key_offsets.size() : 0; + MINFO("HASH: " << "-" << " I/M/O: " << tx.vin.size() << "/" << ring_size << "/" << tx.vout.size() << " H: " << 0 << " chcktx: " << a); } return true; } @@ -2266,8 +2269,8 @@ bool Blockchain::check_tx_inputs(transaction& tx, uint64_t& max_used_block_heigh TIME_MEASURE_FINISH(a); if(m_show_time_stats) { - size_t mixin = tx.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(tx.vin[0]).key_offsets.size() - 1 : 0; - MINFO("HASH: " << get_transaction_hash(tx) << " I/M/O: " << tx.vin.size() << "/" << mixin << "/" << tx.vout.size() << " H: " << max_used_block_height << " ms: " << a + m_fake_scan_time << " B: " << get_object_blobsize(tx)); + size_t ring_size = tx.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(tx.vin[0]).key_offsets.size() : 0; + MINFO("HASH: " << get_transaction_hash(tx) << " I/M/O: " << tx.vin.size() << "/" << ring_size << "/" << tx.vout.size() << " H: " << max_used_block_height << " ms: " << a + m_fake_scan_time << " B: " << get_object_blobsize(tx)); } if (!res) return false; @@ -2459,13 +2462,13 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, { if (n_unmixable == 0) { - MERROR_VER("Tx " << get_transaction_hash(tx) << " has too low mixin (" << mixin << "), and no unmixable inputs"); + MERROR_VER("Tx " << get_transaction_hash(tx) << " has too low ring size (" << (mixin + 1) << "), and no unmixable inputs"); tvc.m_low_mixin = true; return false; } if (n_mixable > 1) { - MERROR_VER("Tx " << get_transaction_hash(tx) << " has too low mixin (" << mixin << "), and more than one mixable input with unmixable inputs"); + MERROR_VER("Tx " << get_transaction_hash(tx) << " has too low ring size (" << (mixin + 1) << "), and more than one mixable input with unmixable inputs"); tvc.m_low_mixin = true; return false; } @@ -3097,6 +3100,8 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash& CRITICAL_REGION_LOCAL(m_blockchain_lock); TIME_MEASURE_START(t1); + static bool seen_future_version = false; + m_db->block_txn_start(true); if(bl.prev_id != get_tail_id()) { @@ -3106,6 +3111,18 @@ leave: return false; } + // warn users if they're running an old version + if (!seen_future_version && bl.major_version > m_hardfork->get_ideal_version()) + { + seen_future_version = true; + const el::Level level = el::Level::Warning; + MCLOG_RED(level, "global", "**********************************************************************"); + MCLOG_RED(level, "global", "A block was seen on the network with a version higher than the last"); + MCLOG_RED(level, "global", "known one. This may be an old version of the daemon, and a software"); + MCLOG_RED(level, "global", "update may be required to sync further. Try running: update check"); + MCLOG_RED(level, "global", "**********************************************************************"); + } + // this is a cheap test if (!m_hardfork->check(bl)) { @@ -3541,19 +3558,17 @@ void Blockchain::set_enforce_dns_checkpoints(bool enforce_checkpoints) } //------------------------------------------------------------------ -void Blockchain::block_longhash_worker(const uint64_t height, const std::vector<block> &blocks, std::unordered_map<crypto::hash, crypto::hash> &map) const +void Blockchain::block_longhash_worker(uint64_t height, const std::vector<block> &blocks, std::unordered_map<crypto::hash, crypto::hash> &map) const { TIME_MEASURE_START(t); slow_hash_allocate_state(); - //FIXME: height should be changing here, as get_block_longhash expects - // the height of the block passed to it for (const auto & block : blocks) { if (m_cancel) - return; + break; crypto::hash id = get_block_hash(block); - crypto::hash pow = get_block_longhash(block, height); + crypto::hash pow = get_block_longhash(block, height++); map.emplace(id, pow); } @@ -3745,9 +3760,11 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::list<block_complete_e if (!blocks_exist) { m_blocks_longhash_table.clear(); + uint64_t thread_height = height; for (uint64_t i = 0; i < threads; i++) { - thread_list.push_back(new boost::thread(attrs, boost::bind(&Blockchain::block_longhash_worker, this, height + (i * batches), std::cref(blocks[i]), std::ref(maps[i])))); + thread_list.push_back(new boost::thread(attrs, boost::bind(&Blockchain::block_longhash_worker, this, thread_height, std::cref(blocks[i]), std::ref(maps[i])))); + thread_height += blocks[i].size(); } for (size_t j = 0; j < thread_list.size(); j++) @@ -3866,17 +3883,17 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::list<block_complete_e offset_map[in_to_key.amount].push_back(offset); } - - // sort and remove duplicate absolute_offsets in offset_map - for (auto &offsets : offset_map) - { - std::sort(offsets.second.begin(), offsets.second.end()); - auto last = std::unique(offsets.second.begin(), offsets.second.end()); - offsets.second.erase(last, offsets.second.end()); - } } } + // sort and remove duplicate absolute_offsets in offset_map + for (auto &offsets : offset_map) + { + std::sort(offsets.second.begin(), offsets.second.end()); + auto last = std::unique(offsets.second.begin(), offsets.second.end()); + offsets.second.erase(last, offsets.second.end()); + } + // [output] stores all transactions for each tx_out_index::hash found std::vector<std::unordered_map<crypto::hash, cryptonote::transaction>> transactions(amounts.size()); @@ -4154,6 +4171,15 @@ void Blockchain::load_compiled_in_block_hashes() } #endif +bool Blockchain::is_within_compiled_block_hash_area(uint64_t height) const +{ +#if defined(PER_BLOCK_CHECKPOINT) + return height < m_blocks_hash_check.size(); +#else + return false; +#endif +} + void Blockchain::lock() { m_blockchain_lock.lock(); diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 4f2e4f0d3..aa61dc034 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -746,6 +746,15 @@ namespace cryptonote uint8_t get_ideal_hard_fork_version(uint64_t height) const { return m_hardfork->get_ideal_version(height); } /** + * @brief returns the actual hardfork version for a given block height + * + * @param height the height for which to check version info + * + * @return the version + */ + uint8_t get_hard_fork_version(uint64_t height) const { return m_hardfork->get(height); } + + /** * @brief get information about hardfork voting for a version * * @param version the version in question @@ -846,7 +855,7 @@ namespace cryptonote * @param blocks the blocks to be hashed * @param map return-by-reference the hashes for each block */ - void block_longhash_worker(const uint64_t height, const std::vector<block> &blocks, + void block_longhash_worker(uint64_t height, const std::vector<block> &blocks, std::unordered_map<crypto::hash, crypto::hash> &map) const; /** @@ -865,6 +874,9 @@ namespace cryptonote cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const; bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false) const; + bool is_within_compiled_block_hash_area(uint64_t height) const; + bool is_within_compiled_block_hash_area() const { return is_within_compiled_block_hash_area(m_db->height()); } + void lock(); void unlock(); diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 4cfa52441..13e5badd1 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -37,6 +37,7 @@ using namespace epee; #include "common/util.h" #include "common/updates.h" #include "common/download.h" +#include "common/task_region.h" #include "warnings.h" #include "crypto/crypto.h" #include "cryptonote_config.h" @@ -76,6 +77,8 @@ namespace cryptonote m_checkpoints_path(""), m_last_dns_checkpoints_update(0), m_last_json_checkpoints_update(0), + m_disable_dns_checkpoints(false), + m_threadpool(tools::thread_group::optimal()), m_update_download(0) { m_checkpoints_updating.clear(); @@ -106,7 +109,7 @@ namespace cryptonote //----------------------------------------------------------------------------------------------- bool core::update_checkpoints() { - if (m_testnet || m_fakechain) return true; + if (m_testnet || m_fakechain || m_disable_dns_checkpoints) return true; if (m_checkpoints_updating.test_and_set()) return true; @@ -414,6 +417,8 @@ namespace cryptonote if (block_sync_size == 0) block_sync_size = BLOCKS_SYNCHRONIZING_DEFAULT_COUNT; + MGINFO("Loading checkpoints"); + // load json & DNS checkpoints, and verify them // with respect to what blocks we already have CHECK_AND_ASSERT_MES(update_checkpoints(), false, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints."); @@ -483,11 +488,9 @@ namespace cryptonote return false; } //----------------------------------------------------------------------------------------------- - bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) + bool core::handle_incoming_tx_pre(const blobdata& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, crypto::hash &tx_prefixt_hash, bool keeped_by_block, bool relayed, bool do_not_relay) { tvc = boost::value_initialized<tx_verification_context>(); - //want to process all transactions sequentially - CRITICAL_REGION_LOCAL(m_incoming_tx_lock); if(tx_blob.size() > get_max_tx_size()) { @@ -497,9 +500,8 @@ namespace cryptonote return false; } - crypto::hash tx_hash = null_hash; - crypto::hash tx_prefixt_hash = null_hash; - transaction tx; + tx_hash = null_hash; + tx_prefixt_hash = null_hash; if(!parse_tx_from_blob(tx, tx_hash, tx_prefixt_hash, tx_blob)) { @@ -509,15 +511,18 @@ namespace cryptonote } //std::cout << "!"<< tx.vin.size() << std::endl; + bad_semantics_txes_lock.lock(); for (int idx = 0; idx < 2; ++idx) { if (bad_semantics_txes[idx].find(tx_hash) != bad_semantics_txes[idx].end()) { + bad_semantics_txes_lock.unlock(); LOG_PRINT_L1("Transaction already seen with bad semantics, rejected"); tvc.m_verifivation_failed = true; return false; } } + bad_semantics_txes_lock.unlock(); uint8_t version = m_blockchain_storage.get_current_hard_fork_version(); const size_t max_tx_version = version == 1 ? 1 : 2; @@ -528,18 +533,11 @@ namespace cryptonote return false; } - if(m_mempool.have_tx(tx_hash)) - { - LOG_PRINT_L2("tx " << tx_hash << "already have transaction in tx_pool"); - return true; - } - - if(m_blockchain_storage.have_tx(tx_hash)) - { - LOG_PRINT_L2("tx " << tx_hash << " already have transaction in blockchain"); - return true; - } - + return true; + } + //----------------------------------------------------------------------------------------------- + bool core::handle_incoming_tx_post(const blobdata& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, crypto::hash &tx_prefixt_hash, bool keeped_by_block, bool relayed, bool do_not_relay) + { if(!check_tx_syntax(tx)) { LOG_PRINT_L1("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " syntax, rejected"); @@ -564,27 +562,92 @@ namespace cryptonote rv.outPk[n].dest = rct::pk2rct(boost::get<txout_to_key>(tx.vout[n].target).key); } - if(!check_tx_semantic(tx, keeped_by_block)) + if (keeped_by_block && get_blockchain_storage().is_within_compiled_block_hash_area()) + { + MTRACE("Skipping semantics check for tx kept by block in embedded hash area"); + } + else if(!check_tx_semantic(tx, keeped_by_block)) { LOG_PRINT_L1("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " semantic, rejected"); tvc.m_verifivation_failed = true; + bad_semantics_txes_lock.lock(); bad_semantics_txes[0].insert(tx_hash); if (bad_semantics_txes[0].size() >= BAD_SEMANTICS_TXES_MAX_SIZE) { std::swap(bad_semantics_txes[0], bad_semantics_txes[1]); bad_semantics_txes[0].clear(); } + bad_semantics_txes_lock.unlock(); return false; } - bool r = add_new_tx(tx, tx_hash, tx_prefixt_hash, tx_blob.size(), tvc, keeped_by_block, relayed, do_not_relay); - if(tvc.m_verifivation_failed) - {MERROR_VER("Transaction verification failed: " << tx_hash);} - else if(tvc.m_verifivation_impossible) - {MERROR_VER("Transaction verification impossible: " << tx_hash);} + return true; + } + //----------------------------------------------------------------------------------------------- + bool core::handle_incoming_txs(const std::list<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) + { + struct result { bool res; cryptonote::transaction tx; crypto::hash hash; crypto::hash prefix_hash; bool in_txpool; bool in_blockchain; }; + std::vector<result> results(tx_blobs.size()); + + tvc.resize(tx_blobs.size()); + tools::task_region(m_threadpool, [&] (tools::task_region_handle& region) { + std::list<blobdata>::const_iterator it = tx_blobs.begin(); + for (size_t i = 0; i < tx_blobs.size(); i++, ++it) { + region.run([&, i, it] { + results[i].res = handle_incoming_tx_pre(*it, tvc[i], results[i].tx, results[i].hash, results[i].prefix_hash, keeped_by_block, relayed, do_not_relay); + }); + } + }); + tools::task_region(m_threadpool, [&] (tools::task_region_handle& region) { + std::list<blobdata>::const_iterator it = tx_blobs.begin(); + for (size_t i = 0; i < tx_blobs.size(); i++, ++it) { + if (!results[i].res) + continue; + if(m_mempool.have_tx(results[i].hash)) + { + LOG_PRINT_L2("tx " << results[i].hash << "already have transaction in tx_pool"); + } + else if(m_blockchain_storage.have_tx(results[i].hash)) + { + LOG_PRINT_L2("tx " << results[i].hash << " already have transaction in blockchain"); + } + else + { + region.run([&, i, it] { + results[i].res = handle_incoming_tx_post(*it, tvc[i], results[i].tx, results[i].hash, results[i].prefix_hash, keeped_by_block, relayed, do_not_relay); + }); + } + } + }); + + bool ok = true; + std::list<blobdata>::const_iterator it = tx_blobs.begin(); + for (size_t i = 0; i < tx_blobs.size(); i++, ++it) { + if (!results[i].res) + { + ok = false; + continue; + } - if(tvc.m_added_to_pool) - MDEBUG("tx added: " << tx_hash); + ok &= add_new_tx(results[i].tx, results[i].hash, results[i].prefix_hash, it->size(), tvc[i], keeped_by_block, relayed, do_not_relay); + if(tvc[i].m_verifivation_failed) + {MERROR_VER("Transaction verification failed: " << results[i].hash);} + else if(tvc[i].m_verifivation_impossible) + {MERROR_VER("Transaction verification impossible: " << results[i].hash);} + + if(tvc[i].m_added_to_pool) + MDEBUG("tx added: " << results[i].hash); + } + return ok; + } + //----------------------------------------------------------------------------------------------- + bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) + { + std::list<cryptonote::blobdata> tx_blobs; + tx_blobs.push_back(tx_blob); + std::vector<tx_verification_context> tvcv(1); + bool r = handle_incoming_txs(tx_blobs, tvcv, keeped_by_block, relayed, do_not_relay); + tvc = tvcv[0]; return r; } //----------------------------------------------------------------------------------------------- @@ -660,6 +723,12 @@ namespace cryptonote return false; } + if (!check_tx_inputs_ring_members_diff(tx)) + { + MERROR_VER("tx uses duplicate ring members"); + return false; + } + if (!check_tx_inputs_keyimages_domain(tx)) { MERROR_VER("tx uses key image not in the valid domain"); @@ -752,6 +821,22 @@ namespace cryptonote return true; } //----------------------------------------------------------------------------------------------- + bool core::check_tx_inputs_ring_members_diff(const transaction& tx) const + { + const uint8_t version = m_blockchain_storage.get_current_hard_fork_version(); + if (version >= 6) + { + for(const auto& in: tx.vin) + { + CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, false); + for (size_t n = 1; n < tokey_in.key_offsets.size(); ++n) + if (tokey_in.key_offsets[n] == 0) + return false; + } + } + return true; + } + //----------------------------------------------------------------------------------------------- bool core::check_tx_inputs_keyimages_domain(const transaction& tx) const { std::unordered_set<crypto::key_image> ki; diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index e5fbf7f91..171c3cb98 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -40,6 +40,7 @@ #include "cryptonote_protocol/cryptonote_protocol_handler_common.h" #include "storages/portable_storage_template_helper.h" #include "common/download.h" +#include "common/thread_group.h" #include "tx_pool.h" #include "blockchain.h" #include "cryptonote_basic/miner.h" @@ -115,6 +116,22 @@ namespace cryptonote bool handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay); /** + * @brief handles a list of incoming transactions + * + * Parses incoming transactions and, if nothing is obviously wrong, + * passes them along to the transaction pool + * + * @param tx_blobs the txs to handle + * @param tvc metadata about the transactions' validity + * @param keeped_by_block if the transactions have been in a block + * @param relayed whether or not the transactions were relayed to us + * @param do_not_relay whether to prevent the transactions from being relayed + * + * @return true if the transactions made it to the transaction pool, otherwise false + */ + bool handle_incoming_txs(const std::list<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay); + + /** * @brief handles an incoming block * * periodic update to checkpoints is triggered here @@ -390,6 +407,13 @@ namespace cryptonote void set_enforce_dns_checkpoints(bool enforce_dns); /** + * @brief set whether or not to enable or disable DNS checkpoints + * + * @param disble whether to disable DNS checkpoints + */ + void disable_dns_checkpoints(bool disable = true) { m_disable_dns_checkpoints = disable; } + + /** * @copydoc tx_memory_pool::have_tx * * @note see tx_memory_pool::have_tx @@ -753,6 +777,9 @@ namespace cryptonote */ bool check_tx_semantic(const transaction& tx, bool keeped_by_block) const; + bool handle_incoming_tx_pre(const blobdata& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, crypto::hash &tx_prefixt_hash, bool keeped_by_block, bool relayed, bool do_not_relay); + bool handle_incoming_tx_post(const blobdata& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, crypto::hash &tx_prefixt_hash, bool keeped_by_block, bool relayed, bool do_not_relay); + /** * @copydoc miner::on_block_chain_update * @@ -781,6 +808,15 @@ namespace cryptonote bool check_tx_inputs_keyimages_diff(const transaction& tx) const; /** + * @brief verify that each ring uses distinct members + * + * @param tx the transaction to check + * + * @return false if any ring uses duplicate members, true otherwise + */ + bool check_tx_inputs_ring_members_diff(const transaction& tx) const; + + /** * @brief verify that each input key image in a transaction is in * the valid domain * @@ -853,12 +889,16 @@ namespace cryptonote time_t m_last_json_checkpoints_update; //!< time when json checkpoints were last updated std::atomic_flag m_checkpoints_updating; //!< set if checkpoints are currently updating to avoid multiple threads attempting to update at once + bool m_disable_dns_checkpoints; size_t block_sync_size; time_t start_time; std::unordered_set<crypto::hash> bad_semantics_txes[2]; + boost::mutex bad_semantics_txes_lock; + + tools::thread_group m_threadpool; enum { UPDATES_DISABLED, diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 26d5fb767..94f069827 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -265,7 +265,7 @@ namespace cryptonote // "Shuffle" outs std::vector<tx_destination_entry> shuffled_dsts(destinations); - std::sort(shuffled_dsts.begin(), shuffled_dsts.end(), [](const tx_destination_entry& de1, const tx_destination_entry& de2) { return de1.amount < de2.amount; } ); + std::random_shuffle(shuffled_dsts.begin(), shuffled_dsts.end(), [](unsigned int i) { return crypto::rand<unsigned int>() % i; }); uint64_t summary_outs_money = 0; //fill outputs @@ -371,7 +371,7 @@ namespace cryptonote // enforce same mixin for all outputs for (size_t i = 1; i < sources.size(); ++i) { if (n_total_outs != sources[i].outputs.size()) { - LOG_ERROR("Non-simple ringct transaction has varying mixin"); + LOG_ERROR("Non-simple ringct transaction has varying ring size"); return false; } } diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index 933070e1e..7aa7c280d 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -32,6 +32,7 @@ #include "cryptonote_basic/cryptonote_format_utils.h" #include <boost/serialization/vector.hpp> #include <boost/serialization/utility.hpp> +#include "ringct/rctOps.h" namespace cryptonote { diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 1858ccdd8..47a41d070 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -493,7 +493,6 @@ private: */ std::unordered_set<crypto::hash> m_timed_out_transactions; - std::string m_config_folder; //!< the folder to save state to Blockchain& m_blockchain; //!< reference to the Blockchain object }; } diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp new file mode 100644 index 000000000..4f760582b --- /dev/null +++ b/src/cryptonote_protocol/block_queue.cpp @@ -0,0 +1,385 @@ +// Copyright (c) 2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#include <vector> +#include <unordered_map> +#include <boost/uuid/nil_generator.hpp> +#include "cryptonote_protocol_defs.h" +#include "block_queue.h" + +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "cn.block_queue" + +namespace std { + static_assert(sizeof(size_t) <= sizeof(boost::uuids::uuid), "boost::uuids::uuid too small"); + template<> struct hash<boost::uuids::uuid> { + std::size_t operator()(const boost::uuids::uuid &_v) const { + return reinterpret_cast<const std::size_t &>(_v); + } + }; +} + +namespace cryptonote +{ + +void block_queue::add_blocks(uint64_t height, std::list<cryptonote::block_complete_entry> bcel, const boost::uuids::uuid &connection_id, float rate, size_t size) +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + remove_span(height); + blocks.insert(span(height, std::move(bcel), connection_id, rate, size)); +} + +void block_queue::add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time) +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + blocks.insert(span(height, nblocks, connection_id, time)); +} + +void block_queue::flush_spans(const boost::uuids::uuid &connection_id, bool all) +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + block_map::iterator i = blocks.begin(); + while (i != blocks.end()) + { + block_map::iterator j = i++; + if (j->connection_id == connection_id && (all || j->blocks.size() == 0)) + { + blocks.erase(j); + } + } +} + +void block_queue::flush_stale_spans(const std::set<boost::uuids::uuid> &live_connections) +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + block_map::iterator i = blocks.begin(); + if (i != blocks.end() && is_blockchain_placeholder(*i)) + ++i; + while (i != blocks.end()) + { + block_map::iterator j = i++; + if (live_connections.find(j->connection_id) == live_connections.end() && j->blocks.size() == 0) + { + blocks.erase(j); + } + } +} + +void block_queue::remove_span(uint64_t start_block_height) +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + for (block_map::iterator i = blocks.begin(); i != blocks.end(); ++i) + { + if (i->start_block_height == start_block_height) + { + blocks.erase(i); + return; + } + } +} + +void block_queue::remove_spans(const boost::uuids::uuid &connection_id, uint64_t start_block_height) +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + for (block_map::iterator i = blocks.begin(); i != blocks.end(); ) + { + block_map::iterator j = i++; + if (j->connection_id == connection_id && j->start_block_height <= start_block_height) + { + blocks.erase(j); + } + } +} + +uint64_t block_queue::get_max_block_height() const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + uint64_t height = 0; + for (const auto &span: blocks) + { + const uint64_t h = span.start_block_height + span.nblocks - 1; + if (h > height) + height = h; + } + return height; +} + +void block_queue::print() const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + MDEBUG("Block queue has " << blocks.size() << " spans"); + for (const auto &span: blocks) + MDEBUG(" " << span.start_block_height << " - " << (span.start_block_height+span.nblocks-1) << " (" << span.nblocks << ") - " << (is_blockchain_placeholder(span) ? "blockchain" : span.blocks.empty() ? "scheduled" : "filled ") << " " << span.connection_id << " (" << ((unsigned)(span.rate*10/1024.f))/10.f << " kB/s)"); +} + +std::string block_queue::get_overview() const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + if (blocks.empty()) + return "[]"; + block_map::const_iterator i = blocks.begin(); + std::string s = std::string("[") + std::to_string(i->start_block_height + i->nblocks - 1) + ":"; + while (++i != blocks.end()) + s += i->blocks.empty() ? "." : "o"; + s += "]"; + return s; +} + +bool block_queue::requested(const crypto::hash &hash) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + for (const auto &span: blocks) + { + for (const auto &h: span.hashes) + if (h == hash) + return true; + } + return false; +} + +std::pair<uint64_t, uint64_t> block_queue::reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, const std::list<crypto::hash> &block_hashes, boost::posix_time::ptime time) +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + + if (last_block_height < first_block_height || max_blocks == 0) + { + MDEBUG("reserve_span: early out: first_block_height " << first_block_height << ", last_block_height " << last_block_height << ", max_blocks " << max_blocks); + return std::make_pair(0, 0); + } + + uint64_t span_start_height = last_block_height - block_hashes.size() + 1; + std::list<crypto::hash>::const_iterator i = block_hashes.begin(); + while (i != block_hashes.end() && requested(*i)) + { + ++i; + ++span_start_height; + } + uint64_t span_length = 0; + std::list<crypto::hash> hashes; + while (i != block_hashes.end() && span_length < max_blocks) + { + hashes.push_back(*i); + ++i; + ++span_length; + } + if (span_length == 0) + return std::make_pair(0, 0); + MDEBUG("Reserving span " << span_start_height << " - " << (span_start_height + span_length - 1) << " for " << connection_id); + add_blocks(span_start_height, span_length, connection_id, time); + set_span_hashes(span_start_height, connection_id, hashes); + return std::make_pair(span_start_height, span_length); +} + +bool block_queue::is_blockchain_placeholder(const span &span) const +{ + static const boost::uuids::uuid uuid0 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + return span.connection_id == uuid0; +} + +std::pair<uint64_t, uint64_t> block_queue::get_start_gap_span() const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + if (blocks.empty()) + return std::make_pair(0, 0); + block_map::const_iterator i = blocks.begin(); + if (!is_blockchain_placeholder(*i)) + return std::make_pair(0, 0); + uint64_t current_height = i->start_block_height + i->nblocks - 1; + ++i; + if (i == blocks.end()) + return std::make_pair(0, 0); + uint64_t first_span_height = i->start_block_height; + if (first_span_height <= current_height + 1) + return std::make_pair(0, 0); + MDEBUG("Found gap at start of spans: last blockchain block height " << current_height << ", first span's block height " << first_span_height); + print(); + return std::make_pair(current_height + 1, first_span_height - current_height - 1); +} + +std::pair<uint64_t, uint64_t> block_queue::get_next_span_if_scheduled(std::list<crypto::hash> &hashes, boost::uuids::uuid &connection_id, boost::posix_time::ptime &time) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + if (blocks.empty()) + return std::make_pair(0, 0); + block_map::const_iterator i = blocks.begin(); + if (is_blockchain_placeholder(*i)) + ++i; + if (i == blocks.end()) + return std::make_pair(0, 0); + if (!i->blocks.empty()) + return std::make_pair(0, 0); + hashes = i->hashes; + connection_id = i->connection_id; + time = i->time; + return std::make_pair(i->start_block_height, i->nblocks); +} + +void block_queue::set_span_hashes(uint64_t start_height, const boost::uuids::uuid &connection_id, std::list<crypto::hash> hashes) +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + for (block_map::iterator i = blocks.begin(); i != blocks.end(); ++i) + { + if (i->start_block_height == start_height && i->connection_id == connection_id) + { + span s = *i; + blocks.erase(i); + s.hashes = std::move(hashes); + blocks.insert(s); + return; + } + } +} + +bool block_queue::get_next_span(uint64_t &height, std::list<cryptonote::block_complete_entry> &bcel, boost::uuids::uuid &connection_id, bool filled) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + if (blocks.empty()) + return false; + block_map::const_iterator i = blocks.begin(); + if (is_blockchain_placeholder(*i)) + ++i; + for (; i != blocks.end(); ++i) + { + if (!filled || !i->blocks.empty()) + { + height = i->start_block_height; + bcel = i->blocks; + connection_id = i->connection_id; + return true; + } + } + return false; +} + +size_t block_queue::get_data_size() const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + size_t size = 0; + for (const auto &span: blocks) + size += span.size; + return size; +} + +size_t block_queue::get_num_filled_spans_prefix() const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + + if (blocks.empty()) + return 0; + block_map::const_iterator i = blocks.begin(); + if (is_blockchain_placeholder(*i)) + ++i; + size_t size = 0; + while (i != blocks.end() && !i->blocks.empty()) + { + ++i; + ++size; + } + return size; +} + +size_t block_queue::get_num_filled_spans() const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + size_t size = 0; + for (const auto &span: blocks) + if (!span.blocks.empty()) + ++size; + return size; +} + +crypto::hash block_queue::get_last_known_hash(const boost::uuids::uuid &connection_id) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + crypto::hash hash = cryptonote::null_hash; + uint64_t highest_height = 0; + for (const auto &span: blocks) + { + if (span.connection_id != connection_id) + continue; + uint64_t h = span.start_block_height + span.nblocks - 1; + if (h > highest_height && span.hashes.size() == span.nblocks) + { + hash = span.hashes.back(); + highest_height = h; + } + } + return hash; +} + +float block_queue::get_speed(const boost::uuids::uuid &connection_id) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + std::unordered_map<boost::uuids::uuid, float> speeds; + for (const auto &span: blocks) + { + if (span.blocks.empty()) + continue; + // note that the average below does not average over the whole set, but over the + // previous pseudo average and the latest rate: this gives much more importance + // to the latest measurements, which is fine here + std::unordered_map<boost::uuids::uuid, float>::iterator i = speeds.find(span.connection_id); + if (i == speeds.end()) + speeds.insert(std::make_pair(span.connection_id, span.rate)); + else + i->second = (i->second + span.rate) / 2; + } + float conn_rate = -1, best_rate = 0; + for (auto i: speeds) + { + if (i.first == connection_id) + conn_rate = i.second; + if (i.second > best_rate) + best_rate = i.second; + } + + if (conn_rate <= 0) + return 1.0f; // not found, assume good speed + if (best_rate == 0) + return 1.0f; // everything dead ? Can't happen, but let's trap anyway + + const float speed = conn_rate / best_rate; + MTRACE(" Relative speed for " << connection_id << ": " << speed << " (" << conn_rate << "/" << best_rate); + return speed; +} + +bool block_queue::foreach(std::function<bool(const span&)> f, bool include_blockchain_placeholder) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + block_map::const_iterator i = blocks.begin(); + if (!include_blockchain_placeholder && i != blocks.end() && is_blockchain_placeholder(*i)) + ++i; + while (i != blocks.end()) + if (!f(*i++)) + return false; + return true; +} + +} diff --git a/src/cryptonote_protocol/block_queue.h b/src/cryptonote_protocol/block_queue.h new file mode 100644 index 000000000..9a211ac47 --- /dev/null +++ b/src/cryptonote_protocol/block_queue.h @@ -0,0 +1,97 @@ +// Copyright (c) 2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#pragma once + +#include <string> +#include <list> +#include <set> +#include <boost/thread/recursive_mutex.hpp> +#include <boost/uuid/uuid.hpp> + +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "cn.block_queue" + +namespace cryptonote +{ + struct block_complete_entry; + + class block_queue + { + public: + struct span + { + uint64_t start_block_height; + std::list<crypto::hash> hashes; + std::list<cryptonote::block_complete_entry> blocks; + boost::uuids::uuid connection_id; + uint64_t nblocks; + float rate; + size_t size; + boost::posix_time::ptime time; + + span(uint64_t start_block_height, std::list<cryptonote::block_complete_entry> blocks, const boost::uuids::uuid &connection_id, float rate, size_t size): + start_block_height(start_block_height), blocks(std::move(blocks)), connection_id(connection_id), nblocks(this->blocks.size()), rate(rate), size(size), time() {} + span(uint64_t start_block_height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time): + start_block_height(start_block_height), connection_id(connection_id), nblocks(nblocks), rate(0.0f), size(0), time(time) {} + + bool operator<(const span &s) const { return start_block_height < s.start_block_height; } + }; + typedef std::set<span> block_map; + + public: + void add_blocks(uint64_t height, std::list<cryptonote::block_complete_entry> bcel, const boost::uuids::uuid &connection_id, float rate, size_t size); + void add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time = boost::date_time::min_date_time); + void flush_spans(const boost::uuids::uuid &connection_id, bool all = false); + void flush_stale_spans(const std::set<boost::uuids::uuid> &live_connections); + void remove_span(uint64_t start_block_height); + void remove_spans(const boost::uuids::uuid &connection_id, uint64_t start_block_height); + uint64_t get_max_block_height() const; + void print() const; + std::string get_overview() const; + std::pair<uint64_t, uint64_t> reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, const std::list<crypto::hash> &block_hashes, boost::posix_time::ptime time = boost::posix_time::microsec_clock::universal_time()); + bool is_blockchain_placeholder(const span &span) const; + std::pair<uint64_t, uint64_t> get_start_gap_span() const; + std::pair<uint64_t, uint64_t> get_next_span_if_scheduled(std::list<crypto::hash> &hashes, boost::uuids::uuid &connection_id, boost::posix_time::ptime &time) const; + void set_span_hashes(uint64_t start_height, const boost::uuids::uuid &connection_id, std::list<crypto::hash> hashes); + bool get_next_span(uint64_t &height, std::list<cryptonote::block_complete_entry> &bcel, boost::uuids::uuid &connection_id, bool filled = true) const; + size_t get_data_size() const; + size_t get_num_filled_spans_prefix() const; + size_t get_num_filled_spans() const; + crypto::hash get_last_known_hash(const boost::uuids::uuid &connection_id) const; + float get_speed(const boost::uuids::uuid &connection_id) const; + bool foreach(std::function<bool(const span&)> f, bool include_blockchain_placeholder = false) const; + bool requested(const crypto::hash &hash) const; + + private: + block_map blocks; + mutable boost::recursive_mutex mutex; + }; +} diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h index 6f6c1a803..6e6c83f04 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_defs.h +++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h @@ -74,6 +74,10 @@ namespace cryptonote uint32_t support_flags; + boost::uuids::uuid connection_id; + + uint64_t height; + BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(incoming) KV_SERIALIZE(localhost) @@ -94,6 +98,8 @@ namespace cryptonote KV_SERIALIZE(avg_upload) KV_SERIALIZE(current_upload) KV_SERIALIZE(support_flags) + KV_SERIALIZE_VAL_POD_AS_BLOB(connection_id) + KV_SERIALIZE(height) END_KV_SERIALIZE_MAP() }; @@ -192,10 +198,12 @@ namespace cryptonote { uint64_t current_height; crypto::hash top_id; + uint8_t top_version; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(current_height) KV_SERIALIZE_VAL_POD_AS_BLOB(top_id) + KV_SERIALIZE_OPT(top_version, (uint8_t)0) END_KV_SERIALIZE_MAP() }; diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp b/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp index e31276031..3bda50c22 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp +++ b/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp @@ -49,8 +49,8 @@ #include "syncobj.h" -#include "../../contrib/epee/include/net/net_utils_base.h" -#include "../../contrib/epee/include/misc_log_ex.h" +#include "net/net_utils_base.h" +#include "misc_log_ex.h" #include <boost/lambda/bind.hpp> #include <boost/lambda/lambda.hpp> #include <boost/uuid/random_generator.hpp> @@ -69,10 +69,10 @@ #include <boost/asio/basic_socket.hpp> #include <boost/asio/ip/unicast.hpp> -#include "../../src/cryptonote_protocol/cryptonote_protocol_handler.h" -#include "../../src/p2p/network_throttle.hpp" +#include "cryptonote_protocol_handler.h" +#include "p2p/network_throttle.hpp" -#include "../../../src/cryptonote_core/cryptonote_core.h" // e.g. for the send_stop_signal() +#include "cryptonote_core/cryptonote_core.h" // e.g. for the send_stop_signal() #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.cn" @@ -120,10 +120,6 @@ cryptonote_protocol_handler_base::~cryptonote_protocol_handler_base() { } void cryptonote_protocol_handler_base::handler_request_blocks_history(std::list<crypto::hash>& ids) { - using namespace epee::net_utils; - MDEBUG("### ~~~RRRR~~~~ ### sending request (type 2), limit = " << ids.size()); - MDEBUG("RATE LIMIT NOT IMPLEMENTED HERE YET (download at unlimited speed?)"); - // TODO } void cryptonote_protocol_handler_base::handler_response_blocks_now(size_t packet_size) { diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index 9d8bc43c2..dcee03f66 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -42,6 +42,7 @@ #include "warnings.h" #include "cryptonote_protocol_defs.h" #include "cryptonote_protocol_handler_common.h" +#include "block_queue.h" #include "cryptonote_basic/connection_context.h" #include "cryptonote_basic/cryptonote_stat_info.h" #include "cryptonote_basic/verification_context.h" @@ -107,6 +108,7 @@ namespace cryptonote bool is_synchronized(){return m_synchronized;} void log_connections(); std::list<connection_info> get_connections(); + const block_queue &get_block_queue() const { return m_block_queue; } void stop(); private: //----------------- commands handlers ---------------------------------------------- @@ -124,18 +126,19 @@ namespace cryptonote virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& exclude_context); //---------------------------------------------------------------------------------- //bool get_payload_sync_data(HANDSHAKE_DATA::request& hshd, cryptonote_connection_context& context); - bool request_missing_objects(cryptonote_connection_context& context, bool check_having_blocks); + bool request_missing_objects(cryptonote_connection_context& context, bool check_having_blocks, bool force_next_span = false); size_t get_synchronizing_connections_count(); bool on_connection_synchronized(); + bool should_download_next_span(cryptonote_connection_context& context) const; t_core& m_core; nodetool::p2p_endpoint_stub<connection_context> m_p2p_stub; nodetool::i_p2p_endpoint<connection_context>* m_p2p; std::atomic<uint32_t> m_syncronized_connections_count; std::atomic<bool> m_synchronized; - bool m_one_request = true; std::atomic<bool> m_stopping; - epee::critical_section m_sync_lock; + boost::mutex m_sync_lock; + block_queue m_block_queue; boost::mutex m_buffer_mutex; double get_avg_block_size(); diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index c5bc834ad..0e79c0e48 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -41,13 +41,17 @@ #include "cryptonote_basic/cryptonote_format_utils.h" #include "profile_tools.h" -#include "../../src/p2p/network_throttle-detail.hpp" +#include "p2p/network_throttle-detail.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.cn" #define MLOG_P2P_MESSAGE(x) MCINFO("net.p2p.msg", context << x) +#define BLOCK_QUEUE_NBLOCKS_THRESHOLD 10 // chunks of N blocks +#define BLOCK_QUEUE_SIZE_THRESHOLD (100*1024*1024) // MB +#define REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD (5 * 1000000) // microseconds + namespace cryptonote { @@ -208,7 +212,7 @@ namespace cryptonote cnx.recv_idle_time = timestamp - cntxt.m_last_recv; cnx.send_count = cntxt.m_send_cnt; - cnx.send_idle_time = timestamp; + cnx.send_idle_time = timestamp - cntxt.m_last_send; cnx.state = get_protocol_state_string(cntxt.m_state); @@ -233,6 +237,10 @@ namespace cryptonote cnx.current_download = cntxt.m_current_speed_down / 1024; cnx.current_upload = cntxt.m_current_speed_up / 1024; + cnx.connection_id = cntxt.m_connection_id; + + cnx.height = cntxt.m_remote_blockchain_height; + connections.push_back(cnx); return true; @@ -250,6 +258,16 @@ namespace cryptonote if(context.m_state == cryptonote_connection_context::state_synchronizing) return true; + // from v6, if the peer advertises a top block version, reject if it's not what it should be (will only work if no voting) + const uint8_t version = m_core.get_blockchain_storage().get_ideal_hard_fork_version(hshd.current_height - 1); + if (version >= 6 && version != hshd.top_version) + { + LOG_DEBUG_CC(context, "Ignoring due to wrong top version (" << hshd.top_version << ", expected " << version); + return false; + } + + context.m_remote_blockchain_height = hshd.current_height; + uint64_t target = m_core.get_target_blockchain_height(); if (target == 0) target = m_core.get_current_blockchain_height(); @@ -270,7 +288,7 @@ namespace cryptonote m_core.set_target_blockchain_height(static_cast<int64_t>(hshd.current_height)); int64_t diff = static_cast<int64_t>(hshd.current_height) - static_cast<int64_t>(m_core.get_current_blockchain_height()); int64_t max_block_height = max(static_cast<int64_t>(hshd.current_height),static_cast<int64_t>(m_core.get_current_blockchain_height())); - int64_t last_block_v1 = 1009826; + int64_t last_block_v1 = m_core.get_testnet() ? 624633 : 1009826; int64_t diff_v2 = max_block_height > last_block_v1 ? 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 " << std::abs(diff) << " blocks (" << ((abs(diff) - diff_v2) / (24 * 60 * 60 / DIFFICULTY_TARGET_V1)) + (diff_v2 / (24 * 60 * 60 / DIFFICULTY_TARGET_V2)) << " days) " @@ -279,7 +297,6 @@ namespace cryptonote } LOG_PRINT_L1("Remote blockchain height: " << hshd.current_height << ", id: " << hshd.top_id); context.m_state = cryptonote_connection_context::state_synchronizing; - context.m_remote_blockchain_height = hshd.current_height; //let the socket to send response to handshake, but request callback, to let send request data after response LOG_PRINT_CCONTEXT_L2("requesting callback"); ++context.m_callback_request_count; @@ -291,6 +308,7 @@ namespace cryptonote bool t_cryptonote_protocol_handler<t_core>::get_payload_sync_data(CORE_SYNC_DATA& hshd) { m_core.get_blockchain_top(hshd.current_height, hshd.top_id); + hshd.top_version = m_core.get_blockchain_storage().get_hard_fork_version(hshd.current_height); hshd.current_height +=1; return true; } @@ -310,6 +328,11 @@ namespace cryptonote MLOG_P2P_MESSAGE("Received NOTIFY_NEW_BLOCK (hop " << arg.hop << ", " << arg.b.txs.size() << " txes)"); if(context.m_state != cryptonote_connection_context::state_normal) return 1; + if(!is_synchronized()) // can happen if a peer connection goes to normal but another thread still hasn't finished adding queued blocks + { + LOG_DEBUG_CC(context, "Received new block while syncing, ignored"); + return 1; + } m_core.pause_mine(); std::list<block_complete_entry> blocks; blocks.push_back(arg.b); @@ -324,6 +347,7 @@ namespace cryptonote m_p2p->drop_connection(context); m_core.cleanup_handle_incoming_blocks(); m_core.resume_mine(); + m_block_queue.flush_spans(context.m_connection_id); return 1; } } @@ -336,6 +360,8 @@ namespace cryptonote { LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection"); m_p2p->drop_connection(context); + m_p2p->add_host_fail(context.m_remote_address); + m_block_queue.flush_spans(context.m_connection_id); return 1; } if(bvc.m_added_to_main_chain) @@ -361,6 +387,11 @@ namespace cryptonote MLOG_P2P_MESSAGE("Received NOTIFY_NEW_FLUFFY_BLOCK (height " << arg.current_blockchain_height << ", hop " << arg.hop << ", " << arg.b.txs.size() << " txes)"); if(context.m_state != cryptonote_connection_context::state_normal) return 1; + if(!is_synchronized()) // can happen if a peer connection goes to normal but another thread still hasn't finished adding queued blocks + { + LOG_DEBUG_CC(context, "Received new block while syncing, ignored"); + return 1; + } m_core.pause_mine(); @@ -384,6 +415,7 @@ namespace cryptonote ); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); m_core.resume_mine(); return 1; } @@ -417,6 +449,7 @@ namespace cryptonote ); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); m_core.resume_mine(); return 1; } @@ -431,6 +464,7 @@ namespace cryptonote ); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); m_core.resume_mine(); return 1; } @@ -455,6 +489,7 @@ namespace cryptonote ); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); m_core.resume_mine(); return 1; } @@ -472,6 +507,7 @@ namespace cryptonote { LOG_PRINT_CCONTEXT_L1("Block verification failed: transaction verification failed, dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); m_core.resume_mine(); return 1; } @@ -494,6 +530,7 @@ namespace cryptonote ); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); m_core.resume_mine(); return 1; } @@ -514,6 +551,7 @@ namespace cryptonote ); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); m_core.resume_mine(); return 1; } @@ -591,6 +629,8 @@ namespace cryptonote { LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection"); m_p2p->drop_connection(context); + m_p2p->add_host_fail(context.m_remote_address); + m_block_queue.flush_spans(context.m_connection_id); return 1; } if( bvc.m_added_to_main_chain ) @@ -624,6 +664,7 @@ namespace cryptonote m_core.resume_mine(); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } @@ -644,6 +685,7 @@ namespace cryptonote { LOG_ERROR_CCONTEXT("failed to find block: " << arg.block_hash << ", dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } @@ -671,6 +713,7 @@ namespace cryptonote ); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } } @@ -682,6 +725,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX, " << "failed to get requested transactions"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } if (!missed.empty() || txs.size() != txids.size()) @@ -689,6 +733,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX, " << missed.size() << " requested transactions not found" << ", dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } @@ -732,6 +777,7 @@ namespace cryptonote { LOG_PRINT_CCONTEXT_L1("Tx verification failed, dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } if(tvc.m_should_be_relayed) @@ -758,6 +804,8 @@ namespace cryptonote { LOG_ERROR_CCONTEXT("failed to handle request NOTIFY_REQUEST_GET_OBJECTS, dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); + return 1; } LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size() << ", rsp.m_current_blockchain_height=" << rsp.current_blockchain_height << ", missed_ids.size()=" << rsp.missed_ids.size()); @@ -770,21 +818,15 @@ namespace cryptonote template<class t_core> - double t_cryptonote_protocol_handler<t_core>::get_avg_block_size() { - // return m_core.get_blockchain_storage().get_avg_block_size(count); // this does not count too well the actuall network-size of data we need to download - + double t_cryptonote_protocol_handler<t_core>::get_avg_block_size() + { CRITICAL_REGION_LOCAL(m_buffer_mutex); - double avg = 0; - if (m_avg_buffer.size() == 0) { - _warn("m_avg_buffer.size() == 0"); + if (m_avg_buffer.empty()) { + MWARNING("m_avg_buffer.size() == 0"); return 500; } - - const bool dbg_poke_lock = 0; // debug: try to trigger an error by poking around with locks. TODO: configure option - long int dbg_repeat=0; - do { - for (auto element : m_avg_buffer) avg += element; - } while(dbg_poke_lock && (dbg_repeat++)<100000); // in debug/poke mode, repeat this calculation to trigger hidden locking error if there is one + double avg = 0; + for (const auto &element : m_avg_buffer) avg += element; return avg / m_avg_buffer.size(); } @@ -794,31 +836,30 @@ namespace cryptonote { MLOG_P2P_MESSAGE("Received NOTIFY_RESPONSE_GET_OBJECTS (" << arg.blocks.size() << " blocks, " << arg.txs.size() << " txes)"); - // calculate size of request - mainly for logging/debug + bool force_next_span = false; + + // calculate size of request size_t size = 0; - for (auto element : arg.txs) size += element.size(); + for (const auto &element : arg.txs) size += element.size(); - for (auto element : arg.blocks) { - size += element.block.size(); - for (auto tx : element.txs) - size += tx.size(); + size_t blocks_size = 0; + for (const auto &element : arg.blocks) { + blocks_size += element.block.size(); + for (const auto &tx : element.txs) + blocks_size += tx.size(); } + size += blocks_size; - for (auto element : arg.missed_ids) + for (const auto &element : arg.missed_ids) size += sizeof(element.data); size += sizeof(arg.current_blockchain_height); { CRITICAL_REGION_LOCAL(m_buffer_mutex); m_avg_buffer.push_back(size); - - const bool dbg_poke_lock = 0; // debug: try to trigger an error by poking around with locks. TODO: configure option - long int dbg_repeat=0; - do { - m_avg_buffer.push_back(666); // a test value - m_avg_buffer.erase_end(1); - } while(dbg_poke_lock && (dbg_repeat++)<100000); // in debug/poke mode, repeat this calculation to trigger hidden locking error if there is one } + MDEBUG(context << " downloaded " << size << " bytes worth of blocks"); + /*using namespace boost::chrono; auto point = steady_clock::now(); auto time_from_epoh = point.time_since_epoch(); @@ -831,14 +872,17 @@ namespace cryptonote LOG_ERROR_CCONTEXT("sent wrong NOTIFY_HAVE_OBJECTS: arg.m_current_blockchain_height=" << arg.current_blockchain_height << " < m_last_response_height=" << context.m_last_response_height << ", dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } context.m_remote_blockchain_height = arg.current_blockchain_height; - size_t count = 0; std::vector<crypto::hash> block_hashes; block_hashes.reserve(arg.blocks.size()); + const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); + uint64_t start_height = std::numeric_limits<uint64_t>::max(); + cryptonote::block b; for(const block_complete_entry& block_entry: arg.blocks) { if (m_stopping) @@ -846,35 +890,33 @@ namespace cryptonote return 1; } - ++count; - block b; if(!parse_and_validate_block_from_blob(block_entry.block, b)) { LOG_ERROR_CCONTEXT("sent wrong block: failed to parse and validate block: " << epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } - //to avoid concurrency in core between connections, suspend connections which delivered block later then first one - const crypto::hash block_hash = get_block_hash(b); - if(count == 2) + if (b.miner_tx.vin.size() != 1 || b.miner_tx.vin.front().type() != typeid(txin_gen)) { - if(m_core.have_block(block_hash)) - { - context.m_state = cryptonote_connection_context::state_idle; - context.m_needed_objects.clear(); - context.m_requested_objects.clear(); - LOG_PRINT_CCONTEXT_L1("Connection set to idle state."); - return 1; - } + LOG_ERROR_CCONTEXT("sent wrong block: block: miner tx does not have exactly one txin_gen input" + << epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection"); + m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); + return 1; } + if (start_height == std::numeric_limits<uint64_t>::max()) + start_height = boost::get<txin_gen>(b.miner_tx.vin[0]).height; + const crypto::hash block_hash = get_block_hash(b); auto req_it = context.m_requested_objects.find(block_hash); if(req_it == context.m_requested_objects.end()) { LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) << " wasn't requested, dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } if(b.tx_hashes.size() != block_entry.txs.size()) @@ -882,6 +924,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) << ", tx_hashes.size()=" << b.tx_hashes.size() << " mismatch with block_complete_entry.m_txs.size()=" << block_entry.txs.size() << ", dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } @@ -894,114 +937,223 @@ namespace cryptonote MERROR("returned not all requested objects (context.m_requested_objects.size()=" << context.m_requested_objects.size() << "), dropping connection"); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } + // get the last parsed block, which should be the highest one + if(m_core.have_block(cryptonote::get_block_hash(b))) + { + const uint64_t subchain_height = start_height + arg.blocks.size(); + LOG_DEBUG_CC(context, "These are old blocks, ignoring: blocks " << start_height << " - " << (subchain_height-1) << ", blockchain height " << m_core.get_current_blockchain_height()); + goto skip; + } { - MLOG_YELLOW(el::Level::Debug, "Got NEW BLOCKS inside of " << __FUNCTION__ << ": size: " << arg.blocks.size()); + MLOG_YELLOW(el::Level::Debug, context << " Got NEW BLOCKS inside of " << __FUNCTION__ << ": size: " << arg.blocks.size() + << ", blocks: " << start_height << " - " << (start_height + arg.blocks.size() - 1)); + + // add that new span to the block queue + const boost::posix_time::time_duration dt = now - context.m_last_request_time; + const float rate = size * 1e6 / (dt.total_microseconds() + 1); + MDEBUG(context << " adding span: " << arg.blocks.size() << " at height " << start_height << ", " << dt.total_microseconds()/1e6 << " seconds, " << (rate/1e3) << " kB/s, size now " << (m_block_queue.get_data_size() + blocks_size) / 1048576.f << " MB"); + m_block_queue.add_blocks(start_height, arg.blocks, context.m_connection_id, rate, blocks_size); + + context.m_last_known_hash = cryptonote::get_blob_hash(arg.blocks.back().block); if (m_core.get_test_drop_download() && m_core.get_test_drop_download_height()) { // DISCARD BLOCKS for testing - // we lock all the rest to avoid having multiple connections redo a lot - // of the same work, and one of them doing it for nothing: subsequent - // connections will wait until the current one's added its blocks, then - // will add any extra it has, if any - CRITICAL_REGION_LOCAL(m_sync_lock); + // We try to lock the sync lock. If we can, it means no other thread is + // currently adding blocks, so we do that for as long as we can from the + // block queue. Then, we go back to download. + const boost::unique_lock<boost::mutex> sync{m_sync_lock, boost::try_to_lock}; + if (!sync.owns_lock()) + { + MINFO("Failed to lock m_sync_lock, going back to download"); + goto skip; + } + MDEBUG(context << " lock m_sync_lock, adding blocks to chain..."); m_core.pause_mine(); epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler( boost::bind(&t_core::resume_mine, &m_core)); - const uint64_t previous_height = m_core.get_current_blockchain_height(); - - // dismiss what another connection might already have done (likely everything) - uint64_t top_height; - crypto::hash top_hash; - if (m_core.get_blockchain_top(top_height, top_hash)) { - uint64_t dismiss = 1; - for (const auto &h: block_hashes) { - if (top_hash == h) { - LOG_DEBUG_CC(context, "Found current top block in synced blocks, dismissing " - << dismiss << "/" << arg.blocks.size() << " blocks"); - while (dismiss--) - arg.blocks.pop_front(); - break; - } - ++dismiss; + while (1) + { + const uint64_t previous_height = m_core.get_current_blockchain_height(); + uint64_t start_height; + std::list<cryptonote::block_complete_entry> blocks; + boost::uuids::uuid span_connection_id; + if (!m_block_queue.get_next_span(start_height, blocks, span_connection_id)) + { + MDEBUG(context << " no next span found, going back to download"); + break; } - } - - if (arg.blocks.empty()) - goto skip; + MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1) + << ", we need " << previous_height); - m_core.prepare_handle_incoming_blocks(arg.blocks); - for(const block_complete_entry& block_entry: arg.blocks) - { - if (m_stopping) + block new_block; + if (!parse_and_validate_block_from_blob(blocks.front().block, new_block)) { - m_core.cleanup_handle_incoming_blocks(); + MERROR("Failed to parse block, but it should already have been parsed"); + break; + } + bool parent_known = m_core.have_block(new_block.prev_id); + if (!parent_known) + { + // it could be: + // - later in the current chain + // - later in an alt chain + // - orphan + // if it was requested, then it'll be resolved later, otherwise it's an orphan + bool parent_requested = false; + m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{ + if (context.m_requested_objects.find(new_block.prev_id) != context.m_requested_objects.end()) + { + parent_requested = true; + return false; + } + return true; + }); + if (!parent_requested) + { + LOG_ERROR_CCONTEXT("Got block with unknown parent which was not requested - dropping connection"); + // in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it + m_block_queue.remove_spans(span_connection_id, start_height); return 1; + } + + // parent was requested, so we wait for it to be retrieved + MINFO(context << " parent was requested, we'll get back to it"); + break; } - // process transactions - TIME_MEASURE_START(transactions_process_time); - for(auto& tx_blob: block_entry.txs) + const boost::posix_time::ptime start = boost::posix_time::microsec_clock::universal_time(); + + m_core.prepare_handle_incoming_blocks(blocks); + + uint64_t block_process_time_full = 0, transactions_process_time_full = 0; + size_t num_txs = 0; + for(const block_complete_entry& block_entry: blocks) { - tx_verification_context tvc = AUTO_VAL_INIT(tvc); - m_core.handle_incoming_tx(tx_blob, tvc, true, true, false); - if(tvc.m_verifivation_failed) + if (m_stopping) { - LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_OBJECTS, tx_id = " - << epee::string_tools::pod_to_hex(get_blob_hash(tx_blob)) << ", dropping connection"); - m_p2p->drop_connection(context); + m_core.cleanup_handle_incoming_blocks(); + return 1; + } + + // process transactions + TIME_MEASURE_START(transactions_process_time); + num_txs += block_entry.txs.size(); + std::vector<tx_verification_context> tvc; + m_core.handle_incoming_txs(block_entry.txs, tvc, true, true, false); + std::list<blobdata>::const_iterator it = block_entry.txs.begin(); + for (size_t i = 0; i < tvc.size(); ++i, ++it) + { + if(tvc[i].m_verifivation_failed) + { + if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ + LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_OBJECTS, tx_id = " + << epee::string_tools::pod_to_hex(get_blob_hash(*it)) << ", dropping connection"); + m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id, true); + return true; + })) + LOG_ERROR_CCONTEXT("span connection id not found"); + + m_core.cleanup_handle_incoming_blocks(); + // in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it + m_block_queue.remove_spans(span_connection_id, start_height); + return 1; + } + } + TIME_MEASURE_FINISH(transactions_process_time); + transactions_process_time_full += transactions_process_time; + + // process block + + TIME_MEASURE_START(block_process_time); + block_verification_context bvc = boost::value_initialized<block_verification_context>(); + + m_core.handle_incoming_block(block_entry.block, bvc, false); // <--- process block + + if(bvc.m_verifivation_failed) + { + if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ + LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection"); + m_p2p->drop_connection(context); + m_p2p->add_host_fail(context.m_remote_address); + m_block_queue.flush_spans(context.m_connection_id, true); + return true; + })) + LOG_ERROR_CCONTEXT("span connection id not found"); + m_core.cleanup_handle_incoming_blocks(); + // in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it + m_block_queue.remove_spans(span_connection_id, start_height); return 1; } - } - TIME_MEASURE_FINISH(transactions_process_time); + if(bvc.m_marked_as_orphaned) + { + if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ + LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection"); + m_p2p->drop_connection(context); + m_p2p->add_host_fail(context.m_remote_address); + m_block_queue.flush_spans(context.m_connection_id, true); + return true; + })) + LOG_ERROR_CCONTEXT("span connection id not found"); - // process block + m_core.cleanup_handle_incoming_blocks(); + // in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it + m_block_queue.remove_spans(span_connection_id, start_height); + return 1; + } - TIME_MEASURE_START(block_process_time); - block_verification_context bvc = boost::value_initialized<block_verification_context>(); + TIME_MEASURE_FINISH(block_process_time); + block_process_time_full += block_process_time; - m_core.handle_incoming_block(block_entry.block, bvc, false); // <--- process block + } // each download block - if(bvc.m_verifivation_failed) - { - LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection"); - m_p2p->drop_connection(context); - m_p2p->add_host_fail(context.m_remote_address); - m_core.cleanup_handle_incoming_blocks(); - return 1; - } - if(bvc.m_marked_as_orphaned) - { - LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection"); - m_p2p->drop_connection(context); - m_p2p->add_host_fail(context.m_remote_address); - m_core.cleanup_handle_incoming_blocks(); - return 1; - } + MCINFO("sync-info", "Block process time (" << blocks.size() << " blocks, " << num_txs << " txs): " << block_process_time_full + transactions_process_time_full << " (" << transactions_process_time_full << "/" << block_process_time_full << ") ms"); - TIME_MEASURE_FINISH(block_process_time); - LOG_PRINT_CCONTEXT_L2("Block process time: " << block_process_time + transactions_process_time << "(" << transactions_process_time << "/" << block_process_time << ")ms"); + m_core.cleanup_handle_incoming_blocks(); - } // each download block - m_core.cleanup_handle_incoming_blocks(); + m_block_queue.remove_spans(span_connection_id, start_height); - if (m_core.get_current_blockchain_height() > previous_height) - { - MGINFO_YELLOW(context << " Synced " << m_core.get_current_blockchain_height() << "/" << m_core.get_target_blockchain_height()); + if (m_core.get_current_blockchain_height() > previous_height) + { + const boost::posix_time::time_duration dt = boost::posix_time::microsec_clock::universal_time() - start; + std::string timing_message = ""; + if (ELPP->vRegistry()->allowed(el::Level::Info, "sync-info")) + timing_message = std::string(" (") + std::to_string(dt.total_microseconds()/1e6) + " sec, " + + std::to_string((m_core.get_current_blockchain_height() - previous_height) * 1e6 / dt.total_microseconds()) + + " blocks/sec), " + std::to_string(m_block_queue.get_data_size() / 1048576.f) + " MB queued"; + if (ELPP->vRegistry()->allowed(el::Level::Debug, "sync-info")) + timing_message += std::string(": ") + m_block_queue.get_overview(); + MGINFO_YELLOW(context << " Synced " << m_core.get_current_blockchain_height() << "/" << m_core.get_target_blockchain_height() + << timing_message); + } } } // if not DISCARD BLOCK - + if (should_download_next_span(context)) + { + context.m_needed_objects.clear(); + context.m_last_response_height = 0; + force_next_span = true; + } } + skip: - request_missing_objects(context, true); + if (!request_missing_objects(context, true, force_next_span)) + { + LOG_ERROR_CCONTEXT("Failed to request missing objects, dropping connection"); + m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); + return 1; + } return 1; } //------------------------------------------------------------------------------------------------------------------------ @@ -1020,6 +1172,7 @@ skip: { LOG_ERROR_CCONTEXT("Failed to handle NOTIFY_REQUEST_CHAIN."); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); return 1; } LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_RESPONSE_CHAIN_ENTRY: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_block_ids.size()); @@ -1028,54 +1181,260 @@ skip: } //------------------------------------------------------------------------------------------------------------------------ template<class t_core> - bool t_cryptonote_protocol_handler<t_core>::request_missing_objects(cryptonote_connection_context& context, bool check_having_blocks) + bool t_cryptonote_protocol_handler<t_core>::should_download_next_span(cryptonote_connection_context& context) const { - //if (!m_one_request == false) - //return true; - m_one_request = false; - // save request size to log (dr monero) - /*using namespace boost::chrono; - auto point = steady_clock::now(); - auto time_from_epoh = point.time_since_epoch(); - auto sec = duration_cast< seconds >( time_from_epoh ).count();*/ + std::list<crypto::hash> hashes; + boost::uuids::uuid span_connection_id; + boost::posix_time::ptime request_time; + std::pair<uint64_t, uint64_t> span = m_block_queue.get_next_span_if_scheduled(hashes, span_connection_id, request_time); + + // if the next span is not scheduled (or there is none) + if (span.second == 0) + { + // we might be in a weird case where there is a filled next span, + // but it starts higher than the current height + uint64_t height; + std::list<cryptonote::block_complete_entry> bcel; + if (!m_block_queue.get_next_span(height, bcel, span_connection_id, true)) + return false; + if (height > m_core.get_current_blockchain_height()) + { + MDEBUG(context << " we should download it as the next block isn't scheduled"); + return true; + } + return false; + } + // if it was scheduled by this particular peer + if (span_connection_id == context.m_connection_id) + return false; + + float span_speed = m_block_queue.get_speed(span_connection_id); + float speed = m_block_queue.get_speed(context.m_connection_id); + MDEBUG(context << " next span is scheduled for " << span_connection_id << ", speed " << span_speed << ", ours " << speed); + + // we try for that span too if: + // - we're substantially faster, or: + // - we're the fastest and the other one isn't (avoids a peer being waaaay slow but yet unmeasured) + // - the other one asked at least 5 seconds ago + if (span_speed < .25 && speed > .75f) + { + MDEBUG(context << " we should download it as we're substantially faster"); + return true; + } + if (speed == 1.0f && span_speed != 1.0f) + { + MDEBUG(context << " we should download it as we're the fastest peer"); + return true; + } + const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); + if ((now - request_time).total_microseconds() > REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD) + { + MDEBUG(context << " we should download it as this span was requested long ago"); + return true; + } + return false; + } + //------------------------------------------------------------------------------------------------------------------------ + template<class t_core> + bool t_cryptonote_protocol_handler<t_core>::request_missing_objects(cryptonote_connection_context& context, bool check_having_blocks, bool force_next_span) + { + // flush stale spans + std::set<boost::uuids::uuid> live_connections; + m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{ + live_connections.insert(context.m_connection_id); + return true; + }); + m_block_queue.flush_stale_spans(live_connections); + + // if we don't need to get next span, and the block queue is full enough, wait a bit + bool start_from_current_chain = false; + if (!force_next_span) + { + bool first = true; + while (1) + { + size_t nblocks = m_block_queue.get_num_filled_spans(); + size_t size = m_block_queue.get_data_size(); + if (nblocks < BLOCK_QUEUE_NBLOCKS_THRESHOLD || size < BLOCK_QUEUE_SIZE_THRESHOLD) + { + if (!first) + { + LOG_DEBUG_CC(context, "Block queue is " << nblocks << " and " << size << ", resuming"); + } + break; + } + + if (should_download_next_span(context)) + { + MDEBUG(context << " we should try for that next span too, we think we could get it faster, resuming"); + force_next_span = true; + break; + } + + if (first) + { + LOG_DEBUG_CC(context, "Block queue is " << nblocks << " and " << size << ", pausing"); + first = false; + } + for (size_t n = 0; n < 50; ++n) + { + if (m_stopping) + return 1; + boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); + } + } + } - if(context.m_needed_objects.size()) + MDEBUG(context << " request_missing_objects: check " << check_having_blocks << ", force_next_span " << force_next_span << ", m_needed_objects " << context.m_needed_objects.size() << " lrh " << context.m_last_response_height << ", chain " << m_core.get_current_blockchain_height()); + if(context.m_needed_objects.size() || force_next_span) { //we know objects that we need, request this objects NOTIFY_REQUEST_GET_OBJECTS::request req; + bool is_next = false; size_t count = 0; - auto it = context.m_needed_objects.begin(); - const size_t count_limit = m_core.get_block_sync_size(); - MDEBUG("Setting count_limit: " << count_limit); - while(it != context.m_needed_objects.end() && count < count_limit) + std::pair<uint64_t, uint64_t> span = std::make_pair(0, 0); + if (force_next_span) { - if( !(check_having_blocks && m_core.have_block(*it))) + MDEBUG(context << " force_next_span is true, trying next span"); + span = m_block_queue.get_start_gap_span(); + if (span.second > 0) + { + const uint64_t first_block_height_known = context.m_last_response_height - context.m_needed_objects.size() + 1; + const uint64_t last_block_height_known = context.m_last_response_height; + const uint64_t first_block_height_needed = span.first; + const uint64_t last_block_height_needed = span.first + std::min(span.second, (uint64_t)count_limit) - 1; + MDEBUG(context << " gap found, span: " << span.first << " - " << span.first + span.second - 1 << " (" << last_block_height_needed << ")"); + MDEBUG(context << " current known hashes from from " << first_block_height_known << " to " << last_block_height_known); + if (first_block_height_needed < first_block_height_known || last_block_height_needed > last_block_height_known) + { + MDEBUG(context << " we are missing some of the necessary hashes for this gap, requesting chain again"); + context.m_needed_objects.clear(); + context.m_last_response_height = 0; + start_from_current_chain = true; + goto skip; + } + MDEBUG(context << " we have the hashes for this gap"); + } + if (span.second == 0) { - req.blocks.push_back(*it); - ++count; - context.m_requested_objects.insert(*it); + std::list<crypto::hash> hashes; + boost::uuids::uuid span_connection_id; + boost::posix_time::ptime time; + span = m_block_queue.get_next_span_if_scheduled(hashes, span_connection_id, time); + if (span.second > 0) + { + is_next = true; + for (const auto &hash: hashes) + { + req.blocks.push_back(hash); + context.m_requested_objects.insert(hash); + } + } } - context.m_needed_objects.erase(it++); } - LOG_PRINT_CCONTEXT_L1("-->>NOTIFY_REQUEST_GET_OBJECTS: blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size() - << "requested blocks count=" << count << " / " << count_limit); - //epee::net_utils::network_throttle_manager::get_global_throttle_inreq().logger_handle_net("log/dr-monero/net/req-all.data", sec, get_avg_block_size()); + if (span.second == 0) + { + MDEBUG(context << " span size is 0"); + if (context.m_last_response_height + 1 < context.m_needed_objects.size()) + { + MERROR(context << " ERROR: inconsistent context: lrh " << context.m_last_response_height << ", nos " << context.m_needed_objects.size()); + context.m_needed_objects.clear(); + context.m_last_response_height = 0; + goto skip; + } + // take out blocks we already have + while (!context.m_needed_objects.empty() && m_core.have_block(context.m_needed_objects.front())) + { + context.m_needed_objects.pop_front(); + } + const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1; + span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, context.m_needed_objects); + MDEBUG(context << " span from " << first_block_height << ": " << span.first << "/" << span.second); + } + if (span.second == 0 && !force_next_span) + { + MDEBUG(context << " still no span reserved, we may be in the corner case of next span scheduled and everything else scheduled/filled"); + std::list<crypto::hash> hashes; + boost::uuids::uuid span_connection_id; + boost::posix_time::ptime time; + span = m_block_queue.get_next_span_if_scheduled(hashes, span_connection_id, time); + if (span.second > 0) + { + is_next = true; + for (const auto &hash: hashes) + { + req.blocks.push_back(hash); + context.m_requested_objects.insert(hash); + } + } + } + MDEBUG(context << " span: " << span.first << "/" << span.second << " (" << span.first << " - " << (span.first + span.second - 1) << ")"); + if (span.second > 0) + { + if (!is_next) + { + const uint64_t first_context_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1; + uint64_t skip = span.first - first_context_block_height; + if (skip > context.m_needed_objects.size()) + { + MERROR("ERROR: skip " << skip << ", m_needed_objects " << context.m_needed_objects.size() << ", first_context_block_height" << first_context_block_height); + return false; + } + while (skip--) + context.m_needed_objects.pop_front(); + if (context.m_needed_objects.size() < span.second) + { + MERROR("ERROR: span " << span.first << "/" << span.second << ", m_needed_objects " << context.m_needed_objects.size()); + return false; + } + + std::list<crypto::hash> hashes; + auto it = context.m_needed_objects.begin(); + for (size_t n = 0; n < span.second; ++n) + { + req.blocks.push_back(*it); + ++count; + context.m_requested_objects.insert(*it); + hashes.push_back(*it); + auto j = it++; + context.m_needed_objects.erase(j); + } + } - post_notify<NOTIFY_REQUEST_GET_OBJECTS>(req, context); - }else if(context.m_last_response_height < context.m_remote_blockchain_height-1) + context.m_last_request_time = boost::posix_time::microsec_clock::universal_time(); + LOG_PRINT_CCONTEXT_L1("-->>NOTIFY_REQUEST_GET_OBJECTS: blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size() + << "requested blocks count=" << count << " / " << count_limit << " from " << span.first); + //epee::net_utils::network_throttle_manager::get_global_throttle_inreq().logger_handle_net("log/dr-monero/net/req-all.data", sec, get_avg_block_size()); + + post_notify<NOTIFY_REQUEST_GET_OBJECTS>(req, context); + return true; + } + } + +skip: + context.m_needed_objects.clear(); + if(context.m_last_response_height < context.m_remote_blockchain_height-1) {//we have to fetch more objects ids, request blockchain entry NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>(); m_core.get_short_chain_history(r.block_ids); + + if (!start_from_current_chain) + { + // we'll want to start off from where we are on that peer, which may not be added yet + if (context.m_last_known_hash != cryptonote::null_hash && r.block_ids.front() != context.m_last_known_hash) + r.block_ids.push_front(context.m_last_known_hash); + } + handler_request_blocks_history( r.block_ids ); // change the limit(?), sleep(?) //std::string blob; // for calculate size of request //epee::serialization::store_t_to_binary(r, blob); //epee::net_utils::network_throttle_manager::get_global_throttle_inreq().logger_handle_net("log/dr-monero/net/req-all.data", sec, get_avg_block_size()); - LOG_PRINT_CCONTEXT_L1("r = " << 200); + //LOG_PRINT_CCONTEXT_L1("r = " << 200); - LOG_PRINT_CCONTEXT_L1("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() ); + LOG_PRINT_CCONTEXT_L1("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() << ", start_from_current_chain " << start_from_current_chain); post_notify<NOTIFY_REQUEST_CHAIN>(r, context); }else { @@ -1089,8 +1448,18 @@ skip: << "\r\non connection [" << epee::net_utils::print_connection_context_short(context)<< "]"); context.m_state = cryptonote_connection_context::state_normal; - MGINFO_GREEN("SYNCHRONIZED OK"); - on_connection_synchronized(); + if (context.m_remote_blockchain_height >= m_core.get_target_blockchain_height()) + { + if (m_core.get_current_blockchain_height() >= m_core.get_target_blockchain_height()) + { + MGINFO_GREEN("SYNCHRONIZED OK"); + on_connection_synchronized(); + } + } + else + { + MINFO(context << " we've reached this peer's blockchain height"); + } } return true; } @@ -1134,15 +1503,7 @@ skip: LOG_ERROR_CCONTEXT("sent empty m_block_ids, dropping connection"); m_p2p->drop_connection(context); m_p2p->add_host_fail(context.m_remote_address); - return 1; - } - - if(!m_core.have_block(arg.m_block_ids.front())) - { - LOG_ERROR_CCONTEXT("sent m_block_ids starting from unknown id: " - << epee::string_tools::pod_to_hex(arg.m_block_ids.front()) << " , dropping connection"); - m_p2p->drop_connection(context); - m_p2p->add_host_fail(context.m_remote_address); + m_block_queue.flush_spans(context.m_connection_id); return 1; } @@ -1154,15 +1515,22 @@ skip: << ", m_start_height=" << arg.start_height << ", m_block_ids.size()=" << arg.m_block_ids.size()); m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); + return 1; } for(auto& bl_id: arg.m_block_ids) { - if(!m_core.have_block(bl_id)) - context.m_needed_objects.push_back(bl_id); + context.m_needed_objects.push_back(bl_id); } - request_missing_objects(context, false); + if (!request_missing_objects(context, false)) + { + LOG_ERROR_CCONTEXT("Failed to request missing objects, dropping connection"); + m_p2p->drop_connection(context); + m_block_queue.flush_spans(context.m_connection_id); + return 1; + } return 1; } //------------------------------------------------------------------------------------------------------------------------ diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index a7caeeffc..d949a57b1 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -256,7 +256,8 @@ bool t_command_parser_executor::start_mining(const std::vector<std::string>& arg if(!cryptonote::get_account_integrated_address_from_str(adr, has_payment_id, payment_id, true, args.front())) { bool dnssec_valid; - std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(args.front(), dnssec_valid); + std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(args.front(), dnssec_valid, + [](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid){return addresses[0];}); if(!cryptonote::get_account_integrated_address_from_str(adr, has_payment_id, payment_id, false, address_str)) { if(!cryptonote::get_account_integrated_address_from_str(adr, has_payment_id, payment_id, true, address_str)) @@ -578,4 +579,11 @@ bool t_command_parser_executor::relay_tx(const std::vector<std::string>& args) return m_executor.relay_tx(txid); } +bool t_command_parser_executor::sync_info(const std::vector<std::string>& args) +{ + if (args.size() != 0) return false; + + return m_executor.sync_info(); +} + } // namespace daemonize diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h index a453553f1..f301ef14a 100644 --- a/src/daemon/command_parser_executor.h +++ b/src/daemon/command_parser_executor.h @@ -134,6 +134,8 @@ public: bool update(const std::vector<std::string>& args); bool relay_tx(const std::vector<std::string>& args); + + bool sync_info(const std::vector<std::string>& args); }; } // namespace daemonize diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index f47891fdd..12f7c5fa4 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -253,6 +253,11 @@ t_command_server::t_command_server( , std::bind(&t_command_parser_executor::relay_tx, &m_parser, p::_1) , "Relay a given transaction by its txid" ); + m_command_lookup.set_handler( + "sync_info" + , std::bind(&t_command_parser_executor::sync_info, &m_parser, p::_1) + , "Print information about blockchain sync state" + ); } bool t_command_server::process_command_str(const std::string& cmd) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 241cb3883..683eaf4ff 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -41,7 +41,7 @@ #include "daemon/rpc.h" #include "daemon/command_server.h" #include "version.h" -#include "../../contrib/epee/include/syncobj.h" +#include "syncobj.h" using namespace epee; diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 5d8d95b03..995fee484 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -111,6 +111,13 @@ namespace { return base; return base + " -- " + status; } + + std::string pad(std::string s, size_t n) + { + if (s.size() < n) + s.append(n - s.size(), ' '); + return s; + } } t_rpc_command_executor::t_rpc_command_executor( @@ -1583,6 +1590,7 @@ bool t_rpc_command_executor::print_blockchain_dynamic_stats(uint64_t nblocks) double avgreward = 0; std::vector<uint64_t> sizes; sizes.reserve(nblocks); + uint64_t earliest = std::numeric_limits<uint64_t>::max(), latest = 0; std::vector<unsigned> major_versions(256, 0), minor_versions(256, 0); for (const auto &bhr: bhres.headers) { @@ -1594,12 +1602,14 @@ bool t_rpc_command_executor::print_blockchain_dynamic_stats(uint64_t nblocks) static_assert(sizeof(bhr.minor_version) == 1, "major_version expected to be uint8_t"); major_versions[(unsigned)bhr.major_version]++; minor_versions[(unsigned)bhr.minor_version]++; + earliest = std::min(earliest, bhr.timestamp); + latest = std::max(latest, bhr.timestamp); } avgdiff /= nblocks; avgnumtxes /= nblocks; avgreward /= nblocks; uint64_t median_block_size = epee::misc_utils::median(sizes); - tools::msg_writer() << "Last " << nblocks << ": avg. diff " << (uint64_t)avgdiff << ", avg num txes " << avgnumtxes + tools::msg_writer() << "Last " << nblocks << ": avg. diff " << (uint64_t)avgdiff << ", " << (latest - earliest) / nblocks << " avg sec/block, avg num txes " << avgnumtxes << ", avg. reward " << cryptonote::print_money(avgreward) << ", median block size " << median_block_size; unsigned int max_major = 256, max_minor = 256; @@ -1694,4 +1704,65 @@ bool t_rpc_command_executor::relay_tx(const std::string &txid) return true; } +bool t_rpc_command_executor::sync_info() +{ + cryptonote::COMMAND_RPC_SYNC_INFO::request req; + cryptonote::COMMAND_RPC_SYNC_INFO::response res; + std::string fail_message = "Unsuccessful"; + epee::json_rpc::error error_resp; + + if (m_is_rpc) + { + if (!m_rpc_client->json_rpc_request(req, res, "sync_info", fail_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_sync_info(req, res, error_resp) || res.status != CORE_RPC_STATUS_OK) + { + tools::fail_msg_writer() << make_error(fail_message, res.status); + return true; + } + } + + uint64_t target = res.target_height < res.height ? res.height : res.target_height; + tools::success_msg_writer() << "Height: " << res.height << ", target: " << target << " (" << (100.0 * res.height / target) << "%)"; + uint64_t current_download = 0; + for (const auto &p: res.peers) + current_download += p.info.current_download; + tools::success_msg_writer() << "Downloading at " << current_download << " kB/s"; + + tools::success_msg_writer() << std::to_string(res.peers.size()) << " peers"; + for (const auto &p: res.peers) + { + std::string address = pad(p.info.address, 24); + uint64_t nblocks = 0, size = 0; + for (const auto &s: res.spans) + if (s.rate > 0.0f && s.connection_id == p.info.connection_id) + nblocks += s.nblocks, size += s.size; + tools::success_msg_writer() << address << " " << p.info.peer_id << " " << p.info.height << " " << p.info.current_download << " kB/s, " << nblocks << " blocks / " << size/1e6 << " MB queued"; + } + + uint64_t total_size = 0; + for (const auto &s: res.spans) + total_size += s.size; + tools::success_msg_writer() << std::to_string(res.spans.size()) << " spans, " << total_size/1e6 << " MB"; + for (const auto &s: res.spans) + { + std::string address = pad(s.remote_address, 24); + if (s.size == 0) + { + tools::success_msg_writer() << address << " " << s.nblocks << " (" << s.start_block_height << " - " << (s.start_block_height + s.nblocks - 1) << ") -"; + } + else + { + tools::success_msg_writer() << address << " " << s.nblocks << " (" << s.start_block_height << " - " << (s.start_block_height + s.nblocks - 1) << ", " << (uint64_t)(s.size/1e3) << " kB) " << (unsigned)(s.rate/1e3) << " kB/s (" << s.speed/100.0f << ")"; + } + } + + return true; +} + }// namespace daemonize diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index 3f551bd14..fc0b39654 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -42,10 +42,7 @@ #include "common/common_fwd.h" #include "common/rpc_client.h" -#include "misc_log_ex.h" -#include "cryptonote_core/cryptonote_core.h" -#include "cryptonote_protocol/cryptonote_protocol_handler.h" -#include "p2p/net_node.h" +#include "cryptonote_basic/cryptonote_basic.h" #include "rpc/core_rpc_server.h" #undef MONERO_DEFAULT_LOG_CATEGORY @@ -155,6 +152,8 @@ public: bool update(const std::string &command); bool relay_tx(const std::string &txid); + + bool sync_info(); }; } // namespace daemonize diff --git a/src/daemonizer/posix_daemonizer.inl b/src/daemonizer/posix_daemonizer.inl index f8be15dda..506c7766f 100644 --- a/src/daemonizer/posix_daemonizer.inl +++ b/src/daemonizer/posix_daemonizer.inl @@ -43,6 +43,10 @@ namespace daemonizer "detach" , "Run as daemon" }; + const command_line::arg_descriptor<std::string> arg_pidfile = { + "pidfile" + , "File path to write the daemon's PID to (optional, requires --detach)" + }; const command_line::arg_descriptor<bool> arg_non_interactive = { "non-interactive" , "Run non-interactive" @@ -55,6 +59,7 @@ namespace daemonizer ) { command_line::add_arg(normal_options, arg_detach); + command_line::add_arg(normal_options, arg_pidfile); command_line::add_arg(normal_options, arg_non_interactive); } @@ -80,7 +85,12 @@ namespace daemonizer if (command_line::has_arg(vm, arg_detach)) { tools::success_msg_writer() << "Forking to background..."; - posix::fork(); + std::string pidfile; + if (command_line::has_arg(vm, arg_pidfile)) + { + pidfile = command_line::get_arg(vm, arg_pidfile); + } + posix::fork(pidfile); auto daemon = executor.create_daemon(vm); return daemon.run(); } diff --git a/src/daemonizer/posix_fork.cpp b/src/daemonizer/posix_fork.cpp index d9b4a6d0e..4dff04f3f 100644 --- a/src/daemonizer/posix_fork.cpp +++ b/src/daemonizer/posix_fork.cpp @@ -21,15 +21,43 @@ namespace posix { namespace { - void quit(std::string const & message) + void quit(const std::string & message) { LOG_ERROR(message); throw std::runtime_error(message); } } -void fork() +void fork(const std::string & pidfile) { + // If a PID file is specified, we open the file here, because + // we can't report errors after the fork operation. + // When we fork, we close thise file in each of the parent + // processes. + // Only in the final child process do we write the PID to the + // file (and close it). + std::ofstream pidofs; + if (! pidfile.empty ()) + { + int oldpid; + std::ifstream pidrifs; + pidrifs.open(pidfile, std::fstream::in); + if (! pidrifs.fail()) + { + // Read the PID and send signal 0 to see if the process exists. + if (pidrifs >> oldpid && oldpid > 1 && kill(oldpid, 0) == 0) + { + quit("PID file " + pidfile + " already exists and the PID therein is valid"); + } + pidrifs.close(); + } + + pidofs.open(pidfile, std::fstream::out | std::fstream::trunc); + if (pidofs.fail()) + { + quit("Failed to open specified PID file for writing"); + } + } // Fork the process and have the parent exit. If the process was started // from a shell, this returns control to the user. Forking a new process is // also a prerequisite for the subsequent call to setsid(). @@ -38,7 +66,7 @@ void fork() if (pid > 0) { // We're in the parent process and need to exit. - // + pidofs.close(); // When the exit() function is used, the program terminates without // invoking local variables' destructors. Only global variables are // destroyed. @@ -59,6 +87,7 @@ void fork() { if (pid > 0) { + pidofs.close(); exit(0); } else @@ -67,6 +96,13 @@ void fork() } } + if (! pidofs.fail()) + { + int pid = ::getpid(); + pidofs << pid << std::endl; + pidofs.close(); + } + // Close the standard streams. This decouples the daemon from the terminal // that started it. close(0); diff --git a/src/daemonizer/posix_fork.h b/src/daemonizer/posix_fork.h index 459417d25..77ef4cb19 100644 --- a/src/daemonizer/posix_fork.h +++ b/src/daemonizer/posix_fork.h @@ -1,21 +1,21 @@ // Copyright (c) 2014-2017, The Monero Project -// +// // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other // materials provided with the distribution. -// +// // 3. Neither the name of the copyright holder nor the names of its contributors may be // used to endorse or promote products derived from this software without specific // prior written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL @@ -27,12 +27,13 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma once +#include <string> #ifndef WIN32 namespace posix { -void fork(); +void fork(const std::string & pidfile); } diff --git a/src/p2p/connection_basic.cpp b/src/p2p/connection_basic.cpp index df34379e2..d4fbc79e1 100644 --- a/src/p2p/connection_basic.cpp +++ b/src/p2p/connection_basic.cpp @@ -53,8 +53,8 @@ #include "syncobj.h" -#include "../../contrib/epee/include/net/net_utils_base.h" -#include "../../contrib/epee/include/misc_log_ex.h" +#include "net/net_utils_base.h" +#include "misc_log_ex.h" #include <boost/lambda/bind.hpp> #include <boost/lambda/lambda.hpp> #include <boost/uuid/random_generator.hpp> @@ -74,11 +74,11 @@ #include <boost/asio/basic_socket.hpp> #include <boost/asio/ip/unicast.hpp> -#include "../../contrib/epee/include/net/abstract_tcp_server2.h" +#include "net/abstract_tcp_server2.h" // TODO: -#include "../../src/p2p/network_throttle-detail.hpp" -#include "../../src/cryptonote_core/cryptonote_core.h" +#include "network_throttle-detail.hpp" +#include "cryptonote_core/cryptonote_core.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.p2p" diff --git a/src/p2p/connection_basic.hpp b/src/p2p/connection_basic.hpp index bea2df1cd..16de469a7 100644 --- a/src/p2p/connection_basic.hpp +++ b/src/p2p/connection_basic.hpp @@ -59,8 +59,8 @@ #include <memory> -#include "../../contrib/epee/include/net/net_utils_base.h" -#include "../../contrib/epee/include/syncobj.h" +#include "net/net_utils_base.h" +#include "syncobj.h" namespace epee { diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 8798a52e0..4e1e60d27 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -61,8 +61,11 @@ namespace nodetool template<class base_type> struct p2p_connection_context_t: base_type //t_payload_net_handler::connection_context //public net_utils::connection_context_base { + p2p_connection_context_t(): peer_id(0), support_flags(0), m_in_timedsync(false) {} + peerid_type peer_id; uint32_t support_flags; + bool m_in_timedsync; }; template<class t_payload_net_handler> @@ -186,6 +189,7 @@ namespace nodetool virtual bool drop_connection(const epee::net_utils::connection_context_base& context); virtual void request_callback(const epee::net_utils::connection_context_base& context); virtual void for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f); + virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f); virtual bool add_host_fail(const epee::net_utils::network_address &address); //----------------- i_connection_filter -------------------------------------------------------- virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address); diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index b23090c7d..58a7f3563 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -200,6 +200,14 @@ namespace nodetool } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::for_connection(const boost::uuids::uuid &connection_id, std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f) + { + return m_net_server.get_config_object().for_connection(connection_id, [&](p2p_connection_context& cntx){ + return f(cntx, cntx.peer_id, cntx.support_flags); + }); + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::is_remote_host_allowed(const epee::net_utils::network_address &address) { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); @@ -444,11 +452,11 @@ namespace nodetool std::vector<std::vector<std::string>> dns_results; dns_results.resize(m_seed_nodes_list.size()); - std::list<boost::thread*> dns_threads; + std::list<boost::thread> dns_threads; uint64_t result_index = 0; for (const std::string& addr_str : m_seed_nodes_list) { - boost::thread* th = new boost::thread([=, &dns_results, &addr_str] + boost::thread th = boost::thread([=, &dns_results, &addr_str] { MDEBUG("dns_threads[" << result_index << "] created for: " << addr_str); // TODO: care about dnssec avail/valid @@ -474,19 +482,19 @@ namespace nodetool dns_results[result_index] = addr_list; }); - dns_threads.push_back(th); + dns_threads.push_back(std::move(th)); ++result_index; } MDEBUG("dns_threads created, now waiting for completion or timeout of " << CRYPTONOTE_DNS_TIMEOUT_MS << "ms"); boost::chrono::system_clock::time_point deadline = boost::chrono::system_clock::now() + boost::chrono::milliseconds(CRYPTONOTE_DNS_TIMEOUT_MS); uint64_t i = 0; - for (boost::thread* th : dns_threads) + for (boost::thread& th : dns_threads) { - if (! th->try_join_until(deadline)) + if (! th.try_join_until(deadline)) { MWARNING("dns_threads[" << i << "] timed out, sending interrupt"); - th->interrupt(); + th.interrupt(); } ++i; } @@ -714,6 +722,14 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::send_stop_signal() { + std::list<boost::uuids::uuid> connection_ids; + m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { + connection_ids.push_back(cntxt.m_connection_id); + return true; + }); + for (const auto &connection_id: connection_ids) + m_net_server.get_config_object().close(connection_id); + m_payload_handler.stop(); m_net_server.send_stop_signal(); MDEBUG("[node] Stop signal sent"); @@ -1382,7 +1398,7 @@ namespace nodetool } crypto::public_key pk = AUTO_VAL_INIT(pk); epee::string_tools::hex_to_pod(::config::P2P_REMOTE_DEBUG_TRUSTED_PUB_KEY, pk); - crypto::hash h = tools::get_proof_of_trust_hash(tr); + crypto::hash h = get_proof_of_trust_hash(tr); if(!crypto::check_signature(h, pk, tr.sign)) { LOG_ERROR("check_trust failed: sign check failed"); @@ -1662,6 +1678,7 @@ namespace nodetool //associate peer_id with this connection context.peer_id = arg.node_data.peer_id; + context.m_in_timedsync = false; if(arg.node_data.peer_id != m_config.m_peer_id && arg.node_data.my_port) { diff --git a/src/p2p/net_node_common.h b/src/p2p/net_node_common.h index 42de2655d..26bad7c72 100644 --- a/src/p2p/net_node_common.h +++ b/src/p2p/net_node_common.h @@ -51,6 +51,7 @@ namespace nodetool virtual void request_callback(const epee::net_utils::connection_context_base& context)=0; virtual uint64_t get_connections_count()=0; virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0; + virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0; virtual bool block_host(const epee::net_utils::network_address &address, time_t seconds = 0)=0; virtual bool unblock_host(const epee::net_utils::network_address &address)=0; virtual std::map<std::string, time_t> get_blocked_hosts()=0; @@ -88,6 +89,10 @@ namespace nodetool { } + virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(t_connection_context&,peerid_type,uint32_t)> f) + { + return false; + } virtual uint64_t get_connections_count() { diff --git a/src/p2p/network_throttle-detail.cpp b/src/p2p/network_throttle-detail.cpp index 0747b6f36..1df48ee26 100644 --- a/src/p2p/network_throttle-detail.cpp +++ b/src/p2p/network_throttle-detail.cpp @@ -51,8 +51,8 @@ #include "syncobj.h" -#include "../../contrib/epee/include/net/net_utils_base.h" -#include "../../contrib/epee/include/misc_log_ex.h" +#include "net/net_utils_base.h" +#include "misc_log_ex.h" #include <boost/lambda/bind.hpp> #include <boost/lambda/lambda.hpp> #include <boost/uuid/random_generator.hpp> @@ -71,10 +71,10 @@ #include <boost/asio/basic_socket.hpp> #include <boost/asio/ip/unicast.hpp> -#include "../../contrib/epee/include/net/abstract_tcp_server2.h" +#include "net/abstract_tcp_server2.h" // TODO: -#include "../../src/p2p/network_throttle-detail.hpp" +#include "network_throttle-detail.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.throttle" diff --git a/src/p2p/network_throttle-detail.hpp b/src/p2p/network_throttle-detail.hpp index c514db450..27caa85d3 100644 --- a/src/p2p/network_throttle-detail.hpp +++ b/src/p2p/network_throttle-detail.hpp @@ -36,7 +36,7 @@ #ifndef INCLUDED_src_p2p_throttle_detail_hpp #define INCLUDED_src_p2p_throttle_detail_hpp -#include "../../src/p2p/network_throttle.hpp" +#include "network_throttle.hpp" namespace epee { diff --git a/src/p2p/network_throttle.cpp b/src/p2p/network_throttle.cpp index 6d68f3286..74b20376d 100644 --- a/src/p2p/network_throttle.cpp +++ b/src/p2p/network_throttle.cpp @@ -54,7 +54,7 @@ Throttling work by: // 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. -#include "../../src/p2p/network_throttle-detail.hpp" +#include "network_throttle-detail.hpp" namespace epee { @@ -77,28 +77,22 @@ int network_throttle_manager::xxx; // ================================================================================================ // methods: i_network_throttle & network_throttle_manager::get_global_throttle_in() { - boost::call_once(m_once_get_global_throttle_in, [] { m_obj_get_global_throttle_in.reset(new network_throttle("in/all","<<< global-IN",10)); } ); - return * m_obj_get_global_throttle_in; + static network_throttle obj_get_global_throttle_in("in/all","<<< global-IN",10); + return obj_get_global_throttle_in; } -boost::once_flag network_throttle_manager::m_once_get_global_throttle_in; -std::unique_ptr<i_network_throttle> network_throttle_manager::m_obj_get_global_throttle_in; i_network_throttle & network_throttle_manager::get_global_throttle_inreq() { - boost::call_once(m_once_get_global_throttle_inreq, [] { m_obj_get_global_throttle_inreq.reset(new network_throttle("inreq/all", "<== global-IN-REQ",10)); } ); - return * m_obj_get_global_throttle_inreq; + static network_throttle obj_get_global_throttle_inreq("inreq/all", "<== global-IN-REQ",10); + return obj_get_global_throttle_inreq; } -boost::once_flag network_throttle_manager::m_once_get_global_throttle_inreq; -std::unique_ptr<i_network_throttle> network_throttle_manager::m_obj_get_global_throttle_inreq; i_network_throttle & network_throttle_manager::get_global_throttle_out() { - boost::call_once(m_once_get_global_throttle_out, [] { m_obj_get_global_throttle_out.reset(new network_throttle("out/all", ">>> global-OUT",10)); } ); - return * m_obj_get_global_throttle_out; + static network_throttle obj_get_global_throttle_out("out/all", ">>> global-OUT",10); + return obj_get_global_throttle_out; } -boost::once_flag network_throttle_manager::m_once_get_global_throttle_out; -std::unique_ptr<i_network_throttle> network_throttle_manager::m_obj_get_global_throttle_out; diff --git a/src/p2p/network_throttle.hpp b/src/p2p/network_throttle.hpp index a747cdd71..9853df5e1 100644 --- a/src/p2p/network_throttle.hpp +++ b/src/p2p/network_throttle.hpp @@ -54,8 +54,8 @@ #include "syncobj.h" -#include "../../contrib/epee/include/net/net_utils_base.h" -#include "../../contrib/epee/include/misc_log_ex.h" +#include "net/net_utils_base.h" +#include "misc_log_ex.h" #include <boost/lambda/bind.hpp> #include <boost/lambda/lambda.hpp> #include <boost/uuid/random_generator.hpp> @@ -111,13 +111,6 @@ class network_throttle_manager { //protected: public: // XXX - // [[note1]] - static boost::once_flag m_once_get_global_throttle_in; - static boost::once_flag m_once_get_global_throttle_inreq; // [[note2]] - static boost::once_flag m_once_get_global_throttle_out; - static std::unique_ptr<i_network_throttle> m_obj_get_global_throttle_in; - static std::unique_ptr<i_network_throttle> m_obj_get_global_throttle_inreq; - static std::unique_ptr<i_network_throttle> m_obj_get_global_throttle_out; static boost::mutex m_lock_get_global_throttle_in; static boost::mutex m_lock_get_global_throttle_inreq; diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h index a471211a6..f38615def 100644 --- a/src/p2p/p2p_protocol_defs.h +++ b/src/p2p/p2p_protocol_defs.h @@ -35,7 +35,9 @@ #include "net/net_utils_base.h" #include "misc_language.h" #include "cryptonote_config.h" +#ifdef ALLOW_DEBUG_COMMANDS #include "crypto/crypto.h" +#endif namespace nodetool { @@ -440,6 +442,14 @@ namespace nodetool #endif + inline crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust& pot) + { + std::string s; + s.append(reinterpret_cast<const char*>(&pot.peer_id), sizeof(pot.peer_id)); + s.append(reinterpret_cast<const char*>(&pot.time), sizeof(pot.time)); + return crypto::cn_fast_hash(s.data(), s.size()); + } + } diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 97fe18696..a5de36118 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -227,6 +227,28 @@ namespace cryptonote res.status = CORE_RPC_STATUS_OK; return true; } + bool core_rpc_server::on_get_alt_blocks_hashes(const COMMAND_RPC_GET_ALT_BLOCKS_HASHES::request& req, COMMAND_RPC_GET_ALT_BLOCKS_HASHES::response& res) + { + CHECK_CORE_BUSY(); + std::list<block> blks; + + if(!m_core.get_alternative_blocks(blks)) + { + res.status = "Failed"; + return false; + } + + res.blks_hashes.reserve(blks.size()); + + for (auto const& blk: blks) + { + res.blks_hashes.push_back(epee::string_tools::pod_to_hex(get_block_hash(blk))); + } + + MDEBUG("on_get_alt_blocks_hashes: " << blks.size() << " blocks " ); + res.status = CORE_RPC_STATUS_OK; + return true; + } //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_get_blocks_by_height(const COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::response& res) { @@ -608,7 +630,7 @@ namespace cryptonote } res.status = "Failed"; if ((res.low_mixin = tvc.m_low_mixin)) - res.reason = "mixin too low"; + res.reason = "ring size too small"; if ((res.double_spend = tvc.m_double_spend)) res.reason = "double spend"; if ((res.invalid_input = tvc.m_invalid_input)) @@ -1668,6 +1690,41 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_sync_info(const COMMAND_RPC_SYNC_INFO::request& req, COMMAND_RPC_SYNC_INFO::response& res, epee::json_rpc::error& error_resp) + { + if(!check_core_busy()) + { + error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY; + error_resp.message = "Core is busy."; + return false; + } + + crypto::hash top_hash; + if (!m_core.get_blockchain_top(res.height, top_hash)) + { + res.status = "Failed"; + return false; + } + ++res.height; // turn top block height into blockchain height + res.target_height = m_core.get_target_blockchain_height(); + + for (const auto &c: m_p2p.get_payload_object().get_connections()) + res.peers.push_back({c}); + const cryptonote::block_queue &block_queue = m_p2p.get_payload_object().get_block_queue(); + block_queue.foreach([&](const cryptonote::block_queue::span &span) { + uint32_t speed = (uint32_t)(100.0f * block_queue.get_speed(span.connection_id) + 0.5f); + std::string address = ""; + for (const auto &c: m_p2p.get_payload_object().get_connections()) + if (c.connection_id == span.connection_id) + address = c.address; + res.spans.push_back({span.start_block_height, span.nblocks, span.connection_id, (uint32_t)(span.rate + 0.5f), speed, span.size, address}); + return true; + }); + + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_bind_port = { "rpc-bind-port" diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 44ac6f07a..1d1d9da66 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -81,6 +81,7 @@ namespace cryptonote MAP_URI_AUTO_BIN2("/get_outs.bin", on_get_outs_bin, COMMAND_RPC_GET_OUTPUTS_BIN) MAP_URI_AUTO_BIN2("/getrandom_rctouts.bin", on_get_random_rct_outs, COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS) MAP_URI_AUTO_JON2("/gettransactions", on_get_transactions, COMMAND_RPC_GET_TRANSACTIONS) + MAP_URI_AUTO_JON2("/get_alt_blocks_hashes", on_get_alt_blocks_hashes, COMMAND_RPC_GET_ALT_BLOCKS_HASHES) MAP_URI_AUTO_JON2("/is_key_image_spent", on_is_key_image_spent, COMMAND_RPC_IS_KEY_IMAGE_SPENT) MAP_URI_AUTO_JON2("/sendrawtransaction", on_send_raw_tx, COMMAND_RPC_SEND_RAW_TX) MAP_URI_AUTO_JON2_IF("/start_mining", on_start_mining, COMMAND_RPC_START_MINING, !m_restricted) @@ -123,11 +124,13 @@ namespace cryptonote MAP_JON_RPC_WE("get_fee_estimate", on_get_per_kb_fee_estimate, COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE) MAP_JON_RPC_WE_IF("get_alternate_chains",on_get_alternate_chains, COMMAND_RPC_GET_ALTERNATE_CHAINS, !m_restricted) MAP_JON_RPC_WE_IF("relay_tx", on_relay_tx, COMMAND_RPC_RELAY_TX, !m_restricted) + MAP_JON_RPC_WE_IF("sync_info", on_sync_info, COMMAND_RPC_SYNC_INFO, !m_restricted) END_JSON_RPC_MAP() END_URI_MAP2() bool on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res); bool on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res); + bool on_get_alt_blocks_hashes(const COMMAND_RPC_GET_ALT_BLOCKS_HASHES::request& req, COMMAND_RPC_GET_ALT_BLOCKS_HASHES::response& res); bool on_get_blocks_by_height(const COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::response& res); bool on_get_hashes(const COMMAND_RPC_GET_HASHES_FAST::request& req, COMMAND_RPC_GET_HASHES_FAST::response& res); bool on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res); @@ -178,6 +181,7 @@ namespace cryptonote bool on_get_per_kb_fee_estimate(const COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp); bool on_get_alternate_chains(const COMMAND_RPC_GET_ALTERNATE_CHAINS::request& req, COMMAND_RPC_GET_ALTERNATE_CHAINS::response& res, epee::json_rpc::error& error_resp); bool on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp); + bool on_sync_info(const COMMAND_RPC_SYNC_INFO::request& req, COMMAND_RPC_SYNC_INFO::response& res, epee::json_rpc::error& error_resp); //----------------------- private: diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 7a1f5a963..c413f9af8 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -49,7 +49,7 @@ namespace cryptonote // advance which version they will stop working with // Don't go over 32767 for any of these #define CORE_RPC_VERSION_MAJOR 1 -#define CORE_RPC_VERSION_MINOR 12 +#define CORE_RPC_VERSION_MINOR 13 #define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR) @@ -146,6 +146,25 @@ namespace cryptonote }; }; + struct COMMAND_RPC_GET_ALT_BLOCKS_HASHES + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::vector<std::string> blks_hashes; + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(blks_hashes) + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; struct COMMAND_RPC_GET_HASHES_FAST { @@ -1587,4 +1606,60 @@ namespace cryptonote END_KV_SERIALIZE_MAP() }; }; + + struct COMMAND_RPC_SYNC_INFO + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct peer + { + connection_info info; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(info) + END_KV_SERIALIZE_MAP() + }; + + struct span + { + uint64_t start_block_height; + uint64_t nblocks; + boost::uuids::uuid connection_id; + uint32_t rate; + uint32_t speed; + uint64_t size; + std::string remote_address; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(start_block_height) + KV_SERIALIZE(nblocks) + KV_SERIALIZE_VAL_POD_AS_BLOB(connection_id) + KV_SERIALIZE(rate) + KV_SERIALIZE(speed) + KV_SERIALIZE(size) + KV_SERIALIZE(remote_address) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + uint64_t height; + uint64_t target_height; + std::list<peer> peers; + std::list<span> spans; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + KV_SERIALIZE(height) + KV_SERIALIZE(target_height) + KV_SERIALIZE(peers) + KV_SERIALIZE(spans) + END_KV_SERIALIZE_MAP() + }; + }; } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 29d31c7a5..4dc34d6e6 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -115,6 +115,7 @@ namespace const command_line::arg_descriptor<std::string> arg_generate_new_wallet = {"generate-new-wallet", sw::tr("Generate new wallet and save it to <arg>"), ""}; const command_line::arg_descriptor<std::string> arg_generate_from_view_key = {"generate-from-view-key", sw::tr("Generate incoming-only wallet from view key"), ""}; const command_line::arg_descriptor<std::string> arg_generate_from_keys = {"generate-from-keys", sw::tr("Generate wallet from private keys"), ""}; + const command_line::arg_descriptor<std::string> arg_generate_from_multisig_keys = {"generate-from-multisig-keys", sw::tr("Generate a master wallet from multisig wallet keys"), ""}; const auto arg_generate_from_json = wallet_args::arg_generate_from_json(); const command_line::arg_descriptor<std::string> arg_electrum_seed = {"electrum-seed", sw::tr("Specify Electrum seed for wallet recovery/creation"), ""}; const command_line::arg_descriptor<bool> arg_restore_deterministic_wallet = {"restore-deterministic-wallet", sw::tr("Recover wallet using Electrum-style mnemonic seed"), false}; @@ -281,6 +282,42 @@ namespace { return boost::lexical_cast<std::string>(version >> 16) + "." + boost::lexical_cast<std::string>(version & 0xffff); } + + std::string oa_prompter(const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid) + { + if (addresses.empty()) + return {}; + // prompt user for confirmation. + // inform user of DNSSEC validation status as well. + std::string dnssec_str; + if (dnssec_valid) + { + dnssec_str = tr("DNSSEC validation passed"); + } + else + { + dnssec_str = tr("WARNING: DNSSEC validation was unsuccessful, this address may not be correct!"); + } + std::stringstream prompt; + prompt << tr("For URL: ") << url + << ", " << dnssec_str << std::endl + << tr(" Monero Address = ") << addresses[0] + << std::endl + << 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()); + if (std::cin.eof()) + { + return {}; + } + if (!command_line::is_yes(confirm_dns_ok)) + { + std::cout << tr("you have cancelled the transfer request") << std::endl; + return {}; + } + return addresses[0]; + } } @@ -460,7 +497,7 @@ bool simple_wallet::set_store_tx_info(const std::vector<std::string> &args/* = s return true; } -bool simple_wallet::set_default_mixin(const std::vector<std::string> &args/* = std::vector<std::string>()*/) +bool simple_wallet::set_default_ring_size(const std::vector<std::string> &args/* = std::vector<std::string>()*/) { if (m_wallet->watch_only()) { @@ -471,34 +508,34 @@ bool simple_wallet::set_default_mixin(const std::vector<std::string> &args/* = s { if (strchr(args[1].c_str(), '-')) { - fail_msg_writer() << tr("mixin must be an integer >= 2"); + fail_msg_writer() << tr("ring size must be an integer >= 3"); return true; } - uint32_t mixin = boost::lexical_cast<uint32_t>(args[1]); - if (mixin < 2 && mixin != 0) + uint32_t ring_size = boost::lexical_cast<uint32_t>(args[1]); + if (ring_size < 3 && ring_size != 0) { - fail_msg_writer() << tr("mixin must be an integer >= 2"); + fail_msg_writer() << tr("ring size must be an integer >= 3"); return true; } - if (mixin == 0) - mixin = DEFAULT_MIX; + if (ring_size == 0) + ring_size = DEFAULT_MIX + 1; const auto pwd_container = get_and_verify_password(); if (pwd_container) { - m_wallet->default_mixin(mixin); + m_wallet->default_mixin(ring_size - 1); m_wallet->rewrite(m_wallet_file, pwd_container->password()); } return true; } catch(const boost::bad_lexical_cast &) { - fail_msg_writer() << tr("mixin must be an integer >= 2"); + fail_msg_writer() << tr("ring size must be an integer >= 3"); return true; } catch(...) { - fail_msg_writer() << tr("could not change default mixin"); + fail_msg_writer() << tr("could not change default ring size"); return true; } } @@ -703,12 +740,12 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, _1), tr("payments <PID_1> [<PID_2> ... <PID_N>] - Show payments for given payment ID[s]")); m_cmd_binder.set_handler("bc_height", boost::bind(&simple_wallet::show_blockchain_height, this, _1), tr("Show blockchain height")); m_cmd_binder.set_handler("transfer_original", boost::bind(&simple_wallet::transfer, this, _1), tr("Same as transfer, but using an older transaction building algorithm")); - m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer_new, this, _1), tr("transfer [<priority>] [<mixin_count>] <address> <amount> [<payment_id>] - Transfer <amount> to <address>. <priority> is the priority of the transaction. The higher the priority, the higher the fee of the transaction. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. <mixin_count> is the number of extra inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)")); - m_cmd_binder.set_handler("locked_transfer", boost::bind(&simple_wallet::locked_transfer, this, _1), tr("locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]")); - m_cmd_binder.set_handler("sweep_unmixable", boost::bind(&simple_wallet::sweep_unmixable, this, _1), tr("Send all unmixable outputs to yourself with mixin 0")); - m_cmd_binder.set_handler("sweep_all", boost::bind(&simple_wallet::sweep_all, this, _1), tr("sweep_all [mixin] address [payment_id] - Send all unlocked balance to an address")); - m_cmd_binder.set_handler("sweep_below", boost::bind(&simple_wallet::sweep_below, this, _1), tr("sweep_below <amount_threshold> [mixin] address [payment_id] - Send all unlocked outputs below the threshold to an address")); - m_cmd_binder.set_handler("donate", boost::bind(&simple_wallet::donate, this, _1), tr("donate [<mixin_count>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)")); + m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer_new, this, _1), tr("transfer [<priority>] [<ring_size>] <address> <amount> [<payment_id>] - Transfer <amount> to <address>. <priority> is the priority of the transaction. The higher the priority, the higher the fee of the transaction. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)")); + m_cmd_binder.set_handler("locked_transfer", boost::bind(&simple_wallet::locked_transfer, this, _1), tr("locked_transfer [<ring_size>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]")); + m_cmd_binder.set_handler("sweep_unmixable", boost::bind(&simple_wallet::sweep_unmixable, this, _1), tr("Send all unmixable outputs to yourself with ring_size 1")); + m_cmd_binder.set_handler("sweep_all", boost::bind(&simple_wallet::sweep_all, this, _1), tr("sweep_all [ring_size] address [payment_id] - Send all unlocked balance to an address")); + m_cmd_binder.set_handler("sweep_below", boost::bind(&simple_wallet::sweep_below, this, _1), tr("sweep_below <amount_threshold> [ring_size] address [payment_id] - Send all unlocked outputs below the threshold to an address")); + m_cmd_binder.set_handler("donate", boost::bind(&simple_wallet::donate, this, _1), tr("donate [<ring_size>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)")); m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), tr("Sign a transaction from a file")); m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), tr("Submit a signed transaction from a file")); m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), tr("set_log <level>|<categories> - Change current log detail (level must be <0-4>)")); @@ -720,7 +757,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), tr("Display private view key")); m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this, _1), tr("Display private spend key")); m_cmd_binder.set_handler("seed", boost::bind(&simple_wallet::seed, this, _1), tr("Display Electrum-style mnemonic seed")); - m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), tr("Available options: seed language - set wallet seed language; always-confirm-transfers <1|0> - whether to confirm unsplit txes; print-ring-members <1|0> - whether to print detailed information about ring members during confirmation; store-tx-info <1|0> - whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference; default-mixin <n> - set default mixin (default is 4); auto-refresh <1|0> - whether to automatically sync new blocks from the daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - set wallet refresh behaviour; priority [0|1|2|3|4] - default/unimportant/normal/elevated/priority fee; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - set default monero (sub-)unit; min-outputs-count [n] - try to keep at least that many outputs of value at least min-outputs-value; min-outputs-value [n] - try to keep at least min-outputs-count outputs of at least that value; merge-destinations <1|0> - whether to merge multiple payments to the same destination address")); + m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), tr("Available options: seed language - set wallet seed language; always-confirm-transfers <1|0> - whether to confirm unsplit txes; print-ring-members <1|0> - whether to print detailed information about ring members during confirmation; store-tx-info <1|0> - whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference; default-ring-size <n> - set default ring size (default is 5); auto-refresh <1|0> - whether to automatically sync new blocks from the daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - set wallet refresh behaviour; priority [0|1|2|3|4] - default/unimportant/normal/elevated/priority fee; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - set default monero (sub-)unit; min-outputs-count [n] - try to keep at least that many outputs of value at least min-outputs-value; min-outputs-value [n] - try to keep at least min-outputs-count outputs of at least that value; merge-destinations <1|0> - whether to merge multiple payments to the same destination address")); m_cmd_binder.set_handler("rescan_spent", boost::bind(&simple_wallet::rescan_spent, this, _1), tr("Rescan blockchain for spent outputs")); m_cmd_binder.set_handler("get_tx_key", boost::bind(&simple_wallet::get_tx_key, this, _1), tr("Get transaction key (r) for a given <txid>")); m_cmd_binder.set_handler("check_tx_key", boost::bind(&simple_wallet::check_tx_key, this, _1), tr("Check amount going to <address> in <txid>")); @@ -752,7 +789,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args) success_msg_writer() << "always-confirm-transfers = " << m_wallet->always_confirm_transfers(); success_msg_writer() << "print-ring-members = " << m_wallet->print_ring_members(); success_msg_writer() << "store-tx-info = " << m_wallet->store_tx_info(); - success_msg_writer() << "default-mixin = " << m_wallet->default_mixin(); + success_msg_writer() << "default-ring-size = " << (m_wallet->default_mixin() ? m_wallet->default_mixin() + 1 : 0); success_msg_writer() << "auto-refresh = " << m_wallet->auto_refresh(); success_msg_writer() << "refresh-type = " << get_refresh_type_name(m_wallet->get_refresh_type()); success_msg_writer() << "priority = " << m_wallet->get_default_priority(); @@ -797,7 +834,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args) CHECK_SIMPLE_VARIABLE("always-confirm-transfers", set_always_confirm_transfers, tr("0 or 1")); CHECK_SIMPLE_VARIABLE("print-ring-members", set_print_ring_members, tr("0 or 1")); CHECK_SIMPLE_VARIABLE("store-tx-info", set_store_tx_info, tr("0 or 1")); - CHECK_SIMPLE_VARIABLE("default-mixin", set_default_mixin, tr("integer >= 2")); + CHECK_SIMPLE_VARIABLE("default-ring-size", set_default_ring_size, tr("integer >= 3")); CHECK_SIMPLE_VARIABLE("auto-refresh", set_auto_refresh, tr("0 or 1")); CHECK_SIMPLE_VARIABLE("refresh-type", set_refresh_type, tr("full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)")); CHECK_SIMPLE_VARIABLE("priority", set_default_priority, tr("0, 1, 2, 3, or 4")); @@ -932,12 +969,12 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) if (!handle_command_line(vm)) return false; - if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_view_key.empty()) + (!m_generate_from_keys.empty()) + (!m_generate_from_json.empty()) > 1) + if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_view_key.empty()) + (!m_generate_from_keys.empty()) + (!m_generate_from_multisig_keys.empty()) + (!m_generate_from_json.empty()) > 1) { - fail_msg_writer() << tr("can't specify more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\", --generate-from-view-key=\"wallet_name\", --generate-from-json=\"jsonfilename\" and --generate-from-keys=\"wallet_name\""); + fail_msg_writer() << tr("can't specify more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\", --generate-from-view-key=\"wallet_name\", --generate-from-keys=\"wallet_name\", --generate-from-multisig-keys=\"wallet_name\" and --generate-from-json=\"jsonfilename\""); return false; } - else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_view_key.empty() && m_generate_from_keys.empty() && m_generate_from_json.empty()) + else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_view_key.empty() && m_generate_from_keys.empty() && m_generate_from_multisig_keys.empty() && m_generate_from_json.empty()) { if(!ask_wallet_create_if_needed()) return false; } @@ -1110,6 +1147,143 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) bool r = new_wallet(vm, address, spendkey, viewkey); CHECK_AND_ASSERT_MES(r, false, tr("account creation failed")); } + + // Asks user for all the data required to merge secret keys from multisig wallets into one master wallet, which then gets full control of the multisig wallet. The resulting wallet will be the same as any other regular wallet. + else if (!m_generate_from_multisig_keys.empty()) + { + m_wallet_file = m_generate_from_multisig_keys; + unsigned int multisig_m; + 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): "); + if (std::cin.eof()) + return false; + if (multisig_type_string.empty()) + { + fail_msg_writer() << tr("No data supplied, cancelled"); + return false; + } + if (sscanf(multisig_type_string.c_str(), "%u/%u", &multisig_m, &multisig_n) != 2) + { + fail_msg_writer() << tr("Error: expected M/N, but got: ") << multisig_type_string; + return false; + } + if (multisig_m <= 1 || multisig_m > multisig_n) + { + fail_msg_writer() << tr("Error: expected N > 1 and N <= M, but got: ") << multisig_type_string; + return false; + } + if (multisig_m != multisig_n) + { + fail_msg_writer() << tr("Error: M/N is currently unsupported. "); + return false; + } + 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: "); + if (std::cin.eof()) + return false; + if (address_string.empty()) { + fail_msg_writer() << tr("No data supplied, cancelled"); + return false; + } + cryptonote::account_public_address address; + bool has_payment_id; + crypto::hash8 new_payment_id; + if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, tools::wallet2::has_testnet_option(vm), address_string)) + { + fail_msg_writer() << tr("failed to parse address"); + return false; + } + + // parse secret view key + std::string viewkey_string = command_line::input_line("Secret view key: "); + if (std::cin.eof()) + return false; + if (viewkey_string.empty()) + { + fail_msg_writer() << tr("No data supplied, cancelled"); + return false; + } + cryptonote::blobdata viewkey_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key)) + { + fail_msg_writer() << tr("failed to parse secret view key"); + return false; + } + crypto::secret_key viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data()); + + // check that the view key matches the given address + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(viewkey, pkey)) + { + fail_msg_writer() << tr("failed to verify secret view key"); + return false; + } + if (address.m_view_public_key != pkey) + { + fail_msg_writer() << tr("view key does not match standard address"); + return false; + } + + // parse multisig spend keys + crypto::secret_key spendkey; + // parsing N/N + if(multisig_m == multisig_n) + { + std::vector<crypto::secret_key> multisig_secret_spendkeys(multisig_n); + std::string spendkey_string; + cryptonote::blobdata spendkey_data; + // 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())); + if (std::cin.eof()) + return false; + if (spendkey_string.empty()) + { + fail_msg_writer() << tr("No data supplied, cancelled"); + return false; + } + if(!epee::string_tools::parse_hexstr_to_binbuff(spendkey_string, spendkey_data) || spendkey_data.size() != sizeof(crypto::secret_key)) + { + fail_msg_writer() << tr("failed to parse spend key secret key"); + return false; + } + multisig_secret_spendkeys[i] = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data()); + } + + // sum the spend keys together to get the master spend key + spendkey = multisig_secret_spendkeys[0]; + for(unsigned int i=1; i<multisig_n; ++i) + sc_add(reinterpret_cast<unsigned char*>(&spendkey), reinterpret_cast<unsigned char*>(&spendkey), reinterpret_cast<unsigned char*>(&multisig_secret_spendkeys[i])); + } + // parsing M/N + else + { + fail_msg_writer() << tr("Error: M/N is currently unsupported"); + return false; + } + + // check that the spend key matches the given address + if (!crypto::secret_key_to_public_key(spendkey, pkey)) + { + fail_msg_writer() << tr("failed to verify spend key secret key"); + return false; + } + if (address.m_spend_public_key != pkey) + { + fail_msg_writer() << tr("spend key does not match standard address"); + return false; + } + + // create wallet + bool r = new_wallet(vm, address, spendkey, viewkey); + CHECK_AND_ASSERT_MES(r, false, tr("account creation failed")); + } + else if (!m_generate_from_json.empty()) { m_wallet_file = m_generate_from_json; @@ -1235,6 +1409,7 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_ m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet); m_generate_from_view_key = command_line::get_arg(vm, arg_generate_from_view_key); m_generate_from_keys = command_line::get_arg(vm, arg_generate_from_keys); + m_generate_from_multisig_keys = command_line::get_arg(vm, arg_generate_from_multisig_keys); m_generate_from_json = command_line::get_arg(vm, arg_generate_from_json); m_electrum_seed = command_line::get_arg(vm, arg_electrum_seed); m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet); @@ -1244,6 +1419,7 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_ m_restore_height = command_line::get_arg(vm, arg_restore_height); m_restoring = !m_generate_from_view_key.empty() || !m_generate_from_keys.empty() || + !m_generate_from_multisig_keys.empty() || !m_generate_from_json.empty() || m_restore_deterministic_wallet; @@ -2134,7 +2310,8 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri size_t fake_outs_count; if(local_args.size() > 0) { - if(!epee::string_tools::get_xtype_from_string(fake_outs_count, local_args[0])) + size_t ring_size; + if(!epee::string_tools::get_xtype_from_string(ring_size, local_args[0])) { fake_outs_count = m_wallet->default_mixin(); if (fake_outs_count == 0) @@ -2142,6 +2319,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri } else { + fake_outs_count = ring_size - 1; local_args.erase(local_args.begin()); } } @@ -2215,7 +2393,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri cryptonote::tx_destination_entry de; bool has_payment_id; crypto::hash8 new_payment_id; - if (!cryptonote::get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[i])) + if (!cryptonote::get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[i], oa_prompter)) { fail_msg_writer() << tr("failed to parse address"); return true; @@ -2375,7 +2553,8 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri { auto & ptx = ptx_vector.back(); m_wallet->commit_tx(ptx); - success_msg_writer(true) << tr("Money successfully sent, transaction ") << get_transaction_hash(ptx.tx); + success_msg_writer(true) << tr("Transaction successfully submitted, transaction ") << get_transaction_hash(ptx.tx) << ENDL + << tr("You can check its status by using the `show_transfers` command."); // if no exception, remove element from vector ptx_vector.pop_back(); @@ -2417,10 +2596,10 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri catch (const tools::error::not_enough_outs_to_mix& e) { auto writer = fail_msg_writer(); - writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":"; + 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 mix") << " = " << outs_for_amount.second; + 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&) @@ -2594,10 +2773,10 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_) catch (const tools::error::not_enough_outs_to_mix& e) { auto writer = fail_msg_writer(); - writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":"; + 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 mix") << " = " << outs_for_amount.second; + 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&) @@ -2657,7 +2836,8 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a size_t fake_outs_count; if(local_args.size() > 0) { - if(!epee::string_tools::get_xtype_from_string(fake_outs_count, local_args[0])) + size_t ring_size; + if(!epee::string_tools::get_xtype_from_string(ring_size, local_args[0])) { fake_outs_count = m_wallet->default_mixin(); if (fake_outs_count == 0) @@ -2665,6 +2845,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a } else { + fake_outs_count = ring_size - 1; local_args.erase(local_args.begin()); } } @@ -2713,7 +2894,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a bool has_payment_id; crypto::hash8 new_payment_id; cryptonote::account_public_address address; - if (!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[0])) + if (!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[0], oa_prompter)) { fail_msg_writer() << tr("failed to parse address"); return true; @@ -2857,10 +3038,10 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a catch (const tools::error::not_enough_outs_to_mix& e) { auto writer = fail_msg_writer(); - writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":"; + 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 mix") << " = " << outs_for_amount.second; + 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&) @@ -2939,7 +3120,7 @@ bool simple_wallet::donate(const std::vector<std::string> &args_) fail_msg_writer() << tr("wrong number of arguments"); return true; } - std::string mixin_str; + std::string ring_size_str; // Hardcode Monero's donation address (see #1447) const std::string address_str = "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A"; std::string amount_str; @@ -2953,17 +3134,17 @@ bool simple_wallet::donate(const std::vector<std::string> &args_) payment_id_str = local_args.back(); local_args.pop_back(); } - // check mixin + // check ring size if (local_args.size() > 1) { - mixin_str = local_args[0]; + ring_size_str = local_args[0]; local_args.erase(local_args.begin()); } amount_str = local_args[0]; // refill args as necessary local_args.clear(); - if (!mixin_str.empty()) - local_args.push_back(mixin_str); + if (!ring_size_str.empty()) + local_args.push_back(ring_size_str); local_args.push_back(address_str); local_args.push_back(amount_str); if (!payment_id_str.empty()) @@ -2977,40 +3158,74 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, { // gather info to ask the user uint64_t amount = 0, amount_to_dests = 0, change = 0; - size_t min_mixin = ~0; - std::unordered_map<std::string, uint64_t> dests; + size_t min_ring_size = ~0; + std::unordered_map<std::string, std::pair<std::string, uint64_t>> dests; const std::string wallet_address = m_wallet->get_account().get_public_address_str(m_wallet->testnet()); int first_known_non_zero_change_index = -1; + std::string payment_id_string = ""; for (size_t n = 0; n < get_num_txes(); ++n) { const tools::wallet2::tx_construction_data &cd = get_tx(n); + + std::vector<tx_extra_field> tx_extra_fields; + bool has_encrypted_payment_id = false; + crypto::hash8 payment_id8 = cryptonote::null_hash8; + if (cryptonote::parse_tx_extra(cd.extra, tx_extra_fields)) + { + tx_extra_nonce extra_nonce; + if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce)) + { + crypto::hash payment_id; + if(get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8)) + { + if (!payment_id_string.empty()) + payment_id_string += ", "; + payment_id_string = std::string("encrypted payment ID ") + epee::string_tools::pod_to_hex(payment_id8); + has_encrypted_payment_id = true; + } + else if (get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) + { + if (!payment_id_string.empty()) + payment_id_string += ", "; + payment_id_string = std::string("unencrypted payment ID ") + epee::string_tools::pod_to_hex(payment_id); + } + } + } + for (size_t s = 0; s < cd.sources.size(); ++s) { amount += cd.sources[s].amount; - size_t mixin = cd.sources[s].outputs.size() - 1; - if (mixin < min_mixin) - min_mixin = mixin; + size_t ring_size = cd.sources[s].outputs.size(); + if (ring_size < min_ring_size) + min_ring_size = ring_size; } for (size_t d = 0; d < cd.splitted_dsts.size(); ++d) { const tx_destination_entry &entry = cd.splitted_dsts[d]; - std::string address = get_account_address_as_str(m_wallet->testnet(), entry.addr); - std::unordered_map<std::string,uint64_t>::iterator i = dests.find(address); + std::string address, standard_address = get_account_address_as_str(m_wallet->testnet(), entry.addr); + if (has_encrypted_payment_id) + { + address = get_account_integrated_address_as_str(m_wallet->testnet(), entry.addr, payment_id8); + address += std::string(" (" + standard_address + " with encrypted payment id " + epee::string_tools::pod_to_hex(payment_id8) + ")"); + } + else + address = standard_address; + std::unordered_map<std::string,std::pair<std::string,uint64_t>>::iterator i = dests.find(standard_address); if (i == dests.end()) - dests.insert(std::make_pair(address, entry.amount)); + dests.insert(std::make_pair(standard_address, std::make_pair(address, entry.amount))); else - i->second += entry.amount; + i->second.second += entry.amount; amount_to_dests += entry.amount; } if (cd.change_dts.amount > 0) { - std::unordered_map<std::string, uint64_t>::iterator it = dests.find(get_account_address_as_str(m_wallet->testnet(), cd.change_dts.addr)); + std::unordered_map<std::string, std::pair<std::string, uint64_t>>::iterator it = dests.find(get_account_address_as_str(m_wallet->testnet(), cd.change_dts.addr)); if (it == dests.end()) { fail_msg_writer() << tr("Claimed change does not go to a paid address"); return false; } - if (it->second < cd.change_dts.amount) + if (it->second.second < cd.change_dts.amount) { fail_msg_writer() << tr("Claimed change is larger than payment to the change address"); return false; @@ -3026,15 +3241,19 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, } } change += cd.change_dts.amount; - it->second -= cd.change_dts.amount; - if (it->second == 0) + it->second.second -= cd.change_dts.amount; + if (it->second.second == 0) dests.erase(get_account_address_as_str(m_wallet->testnet(), cd.change_dts.addr)); } } + + if (payment_id_string.empty()) + payment_id_string = "no payment ID"; + std::string dest_string; - for (std::unordered_map<std::string, uint64_t>::const_iterator i = dests.begin(); i != dests.end(); ) + for (std::unordered_map<std::string, std::pair<std::string, uint64_t>>::const_iterator i = dests.begin(); i != dests.end(); ) { - dest_string += (boost::format(tr("sending %s to %s")) % print_money(i->second) % i->first).str(); + dest_string += (boost::format(tr("sending %s to %s")) % print_money(i->second.second) % i->second.first).str(); ++i; if (i != dests.end()) dest_string += ", "; @@ -3052,7 +3271,7 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, change_string += tr("no change"); 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 mixin %lu. %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_mixin % extra_message).str(); + 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)); } //---------------------------------------------------------------------------------------------------- @@ -3170,10 +3389,10 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args_) catch (const tools::error::not_enough_outs_to_mix& e) { auto writer = fail_msg_writer(); - writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":"; + 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 mix") << " = " << outs_for_amount.second; + 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&) @@ -3273,7 +3492,7 @@ bool simple_wallet::get_tx_proof(const std::vector<std::string> &args) cryptonote::account_public_address address; bool has_payment_id; crypto::hash8 payment_id; - if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), args[1])) + if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), args[1], oa_prompter)) { fail_msg_writer() << tr("failed to parse address"); return true; @@ -3375,7 +3594,7 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_) cryptonote::account_public_address address; bool has_payment_id; crypto::hash8 payment_id; - if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), local_args[2])) + if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), local_args[2], oa_prompter)) { fail_msg_writer() << tr("failed to parse address"); return true; @@ -3527,7 +3746,7 @@ bool simple_wallet::check_tx_proof(const std::vector<std::string> &args) cryptonote::account_public_address address; bool has_payment_id; crypto::hash8 payment_id; - if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), args[1])) + if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), args[1], oa_prompter)) { fail_msg_writer() << tr("failed to parse address"); return true; @@ -3648,6 +3867,22 @@ static std::string get_human_readable_timestamp(uint64_t ts) return std::string(buffer); } //---------------------------------------------------------------------------------------------------- +static std::string get_human_readable_timespan(std::chrono::seconds seconds) +{ + uint64_t ts = seconds.count(); + if (ts < 60) + return std::to_string(ts) + tr(" seconds"); + if (ts < 3600) + return std::to_string((uint64_t)(ts / 60)) + tr(" minutes"); + if (ts < 3600 * 24) + return std::to_string((uint64_t)(ts / 3600)) + tr(" hours"); + if (ts < 3600 * 24 * 30.5) + return std::to_string((uint64_t)(ts / (3600 * 24))) + tr(" days"); + if (ts < 3600 * 24 * 365.25) + return std::to_string((uint64_t)(ts / (3600 * 24 * 365.25))) + tr(" months"); + return tr("a long time"); +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::show_transfers(const std::vector<std::string> &args_) { std::vector<std::string> local_args = args_; @@ -4057,7 +4292,7 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v cryptonote::account_public_address address; bool has_payment_id; crypto::hash8 payment_id8; - if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), args[1])) + if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), args[1], oa_prompter)) { fail_msg_writer() << tr("failed to parse address"); return true; @@ -4248,7 +4483,7 @@ bool simple_wallet::verify(const std::vector<std::string> &args) cryptonote::account_public_address address; bool has_payment_id; crypto::hash8 payment_id; - if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), address_string)) + if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), address_string, oa_prompter)) { fail_msg_writer() << tr("failed to parse address"); return true; @@ -4466,6 +4701,8 @@ bool simple_wallet::show_transfer(const std::vector<std::string> &args) } crypto::hash txid = *reinterpret_cast<const crypto::hash*>(txid_data.data()); + const uint64_t last_block_height = m_wallet->get_blockchain_current_height(); + std::list<std::pair<crypto::hash, tools::wallet2::payment_details>> payments; m_wallet->get_payments(payments, 0); for (std::list<std::pair<crypto::hash, tools::wallet2::payment_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) { @@ -4480,6 +4717,23 @@ bool simple_wallet::show_transfer(const std::vector<std::string> &args) success_msg_writer() << "Timestamp: " << get_human_readable_timestamp(pd.m_timestamp); success_msg_writer() << "Amount: " << print_money(pd.m_amount); success_msg_writer() << "Payment ID: " << payment_id; + if (pd.m_unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER) + { + uint64_t bh = std::max(pd.m_unlock_time, pd.m_block_height + CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE); + if (bh >= last_block_height) + success_msg_writer() << "Locked: " << (bh - last_block_height) << " blocks to unlock"; + else + success_msg_writer() << std::to_string(last_block_height - bh) << " confirmations"; + } + else + { + uint64_t current_time = static_cast<uint64_t>(time(NULL)); + uint64_t threshold = current_time + (m_wallet->use_fork_rules(2, 0) ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1); + if (threshold >= pd.m_unlock_time) + success_msg_writer() << "unlocked for " << get_human_readable_timespan(std::chrono::seconds(threshold - pd.m_unlock_time)); + else + success_msg_writer() << "locked for " << get_human_readable_timespan(std::chrono::seconds(pd.m_unlock_time - threshold)); + } success_msg_writer() << "Note: " << m_wallet->get_tx_note(txid); return true; } @@ -4597,6 +4851,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_generate_new_wallet); command_line::add_arg(desc_params, arg_generate_from_view_key); command_line::add_arg(desc_params, arg_generate_from_keys); + command_line::add_arg(desc_params, arg_generate_from_multisig_keys); command_line::add_arg(desc_params, arg_generate_from_json); command_line::add_arg(desc_params, arg_command); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index b473953e0..cca5d4928 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -111,7 +111,7 @@ namespace cryptonote bool set_always_confirm_transfers(const std::vector<std::string> &args = std::vector<std::string>()); bool set_print_ring_members(const std::vector<std::string> &args = std::vector<std::string>()); bool set_store_tx_info(const std::vector<std::string> &args = std::vector<std::string>()); - bool set_default_mixin(const std::vector<std::string> &args = std::vector<std::string>()); + bool set_default_ring_size(const std::vector<std::string> &args = std::vector<std::string>()); bool set_auto_refresh(const std::vector<std::string> &args = std::vector<std::string>()); bool set_refresh_type(const std::vector<std::string> &args = std::vector<std::string>()); bool set_confirm_missing_payment_id(const std::vector<std::string> &args = std::vector<std::string>()); @@ -265,6 +265,7 @@ namespace cryptonote std::string m_generate_new; std::string m_generate_from_view_key; std::string m_generate_from_keys; + std::string m_generate_from_multisig_keys; std::string m_generate_from_json; std::string m_import_path; diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp index 9798d66c6..c98a599e7 100644 --- a/src/wallet/api/pending_transaction.cpp +++ b/src/wallet/api/pending_transaction.cpp @@ -102,6 +102,7 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite) } // Commit tx else { + m_wallet.pauseRefresh(); while (!m_pending_tx.empty()) { auto & ptx = m_pending_tx.back(); m_wallet.m_wallet->commit_tx(ptx); @@ -133,6 +134,7 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite) m_status = Status_Error; } + m_wallet.startRefresh(); return m_status == Status_Ok; } diff --git a/src/wallet/api/transaction_history.cpp b/src/wallet/api/transaction_history.cpp index 85f2b05ce..23d3905b2 100644 --- a/src/wallet/api/transaction_history.cpp +++ b/src/wallet/api/transaction_history.cpp @@ -132,6 +132,7 @@ void TransactionHistoryImpl::refresh() ti->m_blockheight = pd.m_block_height; ti->m_timestamp = pd.m_timestamp; ti->m_confirmations = wallet_height - pd.m_block_height; + ti->m_unlock_time = pd.m_unlock_time; m_history.push_back(ti); /* output.insert(std::make_pair(pd.m_block_height, std::make_pair(true, (boost::format("%20.20s %s %s %s") diff --git a/src/wallet/api/transaction_info.cpp b/src/wallet/api/transaction_info.cpp index 79a8fe9b5..171272265 100644 --- a/src/wallet/api/transaction_info.cpp +++ b/src/wallet/api/transaction_info.cpp @@ -50,6 +50,7 @@ TransactionInfoImpl::TransactionInfoImpl() , m_blockheight(0) , m_timestamp(0) , m_confirmations(0) + , m_unlock_time(0) { } @@ -115,6 +116,11 @@ uint64_t TransactionInfoImpl::confirmations() const return m_confirmations; } +uint64_t TransactionInfoImpl::unlockTime() const +{ + return m_unlock_time; +} + } // namespace namespace Bitmonero = Monero; diff --git a/src/wallet/api/transaction_info.h b/src/wallet/api/transaction_info.h index 16fa5da7a..ee56b859f 100644 --- a/src/wallet/api/transaction_info.h +++ b/src/wallet/api/transaction_info.h @@ -56,6 +56,7 @@ public: virtual std::string paymentId() const; virtual const std::vector<Transfer> &transfers() const; virtual uint64_t confirmations() const; + virtual uint64_t unlockTime() const; private: int m_direction; @@ -69,6 +70,7 @@ private: std::string m_paymentid; std::vector<Transfer> m_transfers; uint64_t m_confirmations; + uint64_t m_unlock_time; friend class TransactionHistoryImpl; diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp index 1d9ef5d7c..961bd772a 100644 --- a/src/wallet/api/unsigned_transaction.cpp +++ b/src/wallet/api/unsigned_transaction.cpp @@ -101,7 +101,7 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_nu { // gather info to ask the user uint64_t amount = 0, amount_to_dests = 0, change = 0; - size_t min_mixin = ~0; + size_t min_ring_size = ~0; std::unordered_map<std::string, uint64_t> dests; const std::string wallet_address = m_wallet.m_wallet->get_account().get_public_address_str(m_wallet.m_wallet->testnet()); int first_known_non_zero_change_index = -1; @@ -111,9 +111,9 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_nu for (size_t s = 0; s < cd.sources.size(); ++s) { amount += cd.sources[s].amount; - size_t mixin = cd.sources[s].outputs.size() - 1; - if (mixin < min_mixin) - min_mixin = mixin; + size_t ring_size = cd.sources[s].outputs.size(); + if (ring_size < min_ring_size) + min_ring_size = ring_size; } for (size_t d = 0; d < cd.splitted_dsts.size(); ++d) { @@ -178,7 +178,7 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_nu else change_string += tr("no change"); uint64_t fee = amount - amount_to_dests; - m_confirmationMessage = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. %s")) % (unsigned long)get_num_txes() % cryptonote::print_money(amount) % cryptonote::print_money(fee) % dest_string % change_string % (unsigned long)min_mixin % extra_message).str(); + m_confirmationMessage = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu. %s")) % (unsigned long)get_num_txes() % cryptonote::print_money(amount) % cryptonote::print_money(fee) % dest_string % change_string % (unsigned long)min_ring_size % extra_message).str(); return true; } diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 6a0e1727c..a2bb44cfe 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -99,7 +99,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback } } - virtual void on_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount) + virtual void on_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount) { std::string tx_hash = epee::string_tools::pod_to_hex(txid); @@ -114,7 +114,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback } } - virtual void on_unconfirmed_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount) + virtual void on_unconfirmed_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount) { std::string tx_hash = epee::string_tools::pod_to_hex(txid); @@ -129,8 +129,8 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback } } - virtual void on_money_spent(uint64_t height, const crypto::hash &txid, uint64_t amount, - const cryptonote::transaction& spend_tx) + virtual void on_money_spent(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& in_tx, + uint64_t amount, const cryptonote::transaction& spend_tx) { // TODO; std::string tx_hash = epee::string_tools::pod_to_hex(txid); @@ -1009,9 +1009,9 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const } catch (const tools::error::not_enough_outs_to_mix& e) { std::ostringstream writer; - writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":"; + writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":"; for (const 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 mix") << " = " << outs_for_amount.second; + writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second; } m_errorString = writer.str(); m_status = Status_Error; @@ -1103,9 +1103,9 @@ PendingTransaction *WalletImpl::createSweepUnmixableTransaction() } catch (const tools::error::not_enough_outs_to_mix& e) { std::ostringstream writer; - writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":"; + writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":"; for (const 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 mix") << " = " << outs_for_amount.second; + writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second; } m_errorString = writer.str(); m_status = Status_Error; diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index e9e2cc580..07b0f063b 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -98,6 +98,7 @@ public: void setAutoRefreshInterval(int millis); int autoRefreshInterval() const; void setRefreshFromBlockHeight(uint64_t refresh_from_block_height); + uint64_t getRefreshFromBlockHeight() const { return m_wallet->get_refresh_from_block_height(); }; void setRecoveringFromSeed(bool recoveringFromSeed); bool watchOnly() const; bool rescanSpent(); diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index b2f947972..a23533530 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -125,6 +125,10 @@ bool WalletManagerImpl::walletExists(const std::string &path) return false; } +bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool watch_only) const +{ + return tools::wallet2::verify_password(keys_file_name, password, watch_only); +} std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path) { diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h index 033e8108f..aa6ea439e 100644 --- a/src/wallet/api/wallet_manager.h +++ b/src/wallet/api/wallet_manager.h @@ -50,6 +50,7 @@ public: const std::string &spendKeyString = ""); virtual bool closeWallet(Wallet *wallet); bool walletExists(const std::string &path); + bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool watch_only) const; std::vector<std::string> findWallets(const std::string &path); std::string errorString() const; void setDaemonAddress(const std::string &address); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index bb8cdaf63..51c772d29 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1097,6 +1097,7 @@ void wallet2::process_outgoing(const crypto::hash &txid, const cryptonote::trans } entry.first->second.m_block_height = height; entry.first->second.m_timestamp = ts; + entry.first->second.m_unlock_time = tx.unlock_time; } //---------------------------------------------------------------------------------------------------- void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const crypto::hash& bl_id, uint64_t height, const cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices &o_indices) @@ -1388,7 +1389,7 @@ void wallet2::pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_hei } } //---------------------------------------------------------------------------------------------------- -void wallet2::update_pool_state() +void wallet2::update_pool_state(bool refreshed) { MDEBUG("update_pool_state start"); @@ -1424,13 +1425,14 @@ void wallet2::update_pool_state() // a tx is removed from the pool due to being found in a new block, but // just before the block is visible by refresh. So we keep a boolean, so // that the first time we don't see the tx, we set that boolean, and only - // delete it the second time it is checked + // delete it the second time it is checked (but only when refreshed, so + // we're sure we've seen the blockchain state first) if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending) { LOG_PRINT_L1("Pending txid " << txid << " not in pool, marking as not in pool"); pit->second.m_state = wallet2::unconfirmed_transfer_details::pending_not_in_pool; } - else if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending_not_in_pool) + else if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending_not_in_pool && refreshed) { LOG_PRINT_L1("Pending txid " << txid << " not in pool, marking as failed"); pit->second.m_state = wallet2::unconfirmed_transfer_details::failed; @@ -1459,24 +1461,30 @@ void wallet2::update_pool_state() MDEBUG("update_pool_state done first loop"); // remove pool txes to us that aren't in the pool anymore - std::unordered_map<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin(); - while (uit != m_unconfirmed_payments.end()) + // but only if we just refreshed, so that the tx can go in + // the in transfers list instead (or nowhere if it just + // disappeared without being mined) + if (refreshed) { - const crypto::hash &txid = uit->second.m_tx_hash; - bool found = false; - for (const auto &it2: res.tx_hashes) + std::unordered_map<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin(); + while (uit != m_unconfirmed_payments.end()) { - if (it2 == txid) + const crypto::hash &txid = uit->second.m_tx_hash; + bool found = false; + for (const auto &it2: res.tx_hashes) { - found = true; - break; + if (it2 == txid) + { + found = true; + break; + } + } + auto pit = uit++; + if (!found) + { + MDEBUG("Removing " << txid << " from unconfirmed payments, not found in pool"); + m_unconfirmed_payments.erase(pit); } - } - auto pit = uit++; - if (!found) - { - MDEBUG("Removing " << txid << " from unconfirmed payments, not found in pool"); - m_unconfirmed_payments.erase(pit); } } MDEBUG("update_pool_state done second loop"); @@ -1490,7 +1498,16 @@ void wallet2::update_pool_state() LOG_PRINT_L2("Already seen " << txid << ", skipped"); continue; } - if (m_unconfirmed_payments.find(txid) == m_unconfirmed_payments.end()) + bool txid_found_in_up = false; + for (const auto &up: m_unconfirmed_payments) + { + if (up.second.m_tx_hash == txid) + { + txid_found_in_up = true; + break; + } + } + if (!txid_found_in_up) { LOG_PRINT_L1("Found new pool tx: " << txid); bool found = false; @@ -1685,6 +1702,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re uint64_t blocks_start_height; std::list<cryptonote::block_complete_entry> blocks; std::vector<COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> o_indices; + bool refreshed = false; // pull the first set of blocks get_short_chain_history(short_chain_history); @@ -1726,6 +1744,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re if(blocks_start_height == next_blocks_start_height) { m_node_rpc_proxy.set_height(m_blockchain.size()); + refreshed = true; break; } @@ -1764,7 +1783,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re { // If stop() is called we don't need to check pending transactions if(m_run.load(std::memory_order_relaxed)) - update_pool_state(); + update_pool_state(refreshed); } catch (...) { @@ -1940,6 +1959,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const std::string& p value2.SetInt(m_merge_destinations ? 1 :0); json.AddMember("merge_destinations", value2, json.GetAllocator()); + value2.SetInt(m_testnet ? 1 :0); + json.AddMember("testnet", value2, json.GetAllocator()); + // Serialize the JSON object rapidjson::StringBuffer buffer; rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); @@ -2081,6 +2103,11 @@ bool wallet2::load_keys(const std::string& keys_file_name, const std::string& pa m_min_output_value = field_min_output_value; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, merge_destinations, int, Int, false, false); m_merge_destinations = field_merge_destinations; + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, testnet, int, Int, false, m_testnet); + // Wallet is being opened with testnet flag, but is saved as a mainnet wallet + THROW_WALLET_EXCEPTION_IF(m_testnet && !field_testnet, error::wallet_internal_error, "Mainnet wallet can not be opened as testnet wallet"); + // Wallet is being opened without testnet flag but is saved as a testnet wallet. + THROW_WALLET_EXCEPTION_IF(!m_testnet && field_testnet, error::wallet_internal_error, "Testnet wallet can not be opened as mainnet wallet"); } const cryptonote::account_keys& keys = m_account.get_keys(); @@ -2095,6 +2122,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const std::string& pa /*! * \brief verify password for default wallet keys file. * \param password Password to verify + * \return true if password is correct * * for verification only * should not mutate state, unlike load_keys() @@ -2103,7 +2131,23 @@ bool wallet2::load_keys(const std::string& keys_file_name, const std::string& pa */ bool wallet2::verify_password(const std::string& password) const { - const std::string keys_file_name = m_keys_file; + return verify_password(m_keys_file, password, m_watch_only); +} + +/*! + * \brief verify password for specified wallet keys file. + * \param keys_file_name Keys file to verify password for + * \param password Password to verify + * \param watch_only If set = only verify view keys, otherwise also spend keys + * \return true if password is correct + * + * for verification only + * should not mutate state, unlike load_keys() + * can be used prior to rewriting wallet keys file, to ensure user has entered the correct password + * + */ +bool wallet2::verify_password(const std::string& keys_file_name, const std::string& password, bool watch_only) +{ wallet2::keys_file_data keys_file_data; std::string buf; bool r = epee::file_io_utils::load_file_to_string(keys_file_name, buf); @@ -2136,7 +2180,7 @@ bool wallet2::verify_password(const std::string& password) const const cryptonote::account_keys& keys = account_data_check.get_keys(); r = r && verify_keys(keys.m_view_secret_key, keys.m_account_address.m_view_public_key); - if(!m_watch_only) + if(!watch_only) r = r && verify_keys(keys.m_spend_secret_key, keys.m_account_address.m_spend_public_key); return r; } @@ -3252,7 +3296,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_f for (size_t n = 0; n < exported_txs.txes.size(); ++n) { const tools::wallet2::tx_construction_data &sd = exported_txs.txes[n]; - LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, mixin " << (sd.sources[0].outputs.size()-1)); + LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, ring size " << sd.sources[0].outputs.size()); signed_txes.ptx.push_back(pending_tx()); tools::wallet2::pending_tx &ptx = signed_txes.ptx.back(); crypto::secret_key tx_key; @@ -4119,7 +4163,7 @@ static size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs) // txnFee size += 4; - LOG_PRINT_L2("estimated rct tx size for " << n_inputs << " at mixin " << mixin << " and " << n_outputs << ": " << size << " (" << ((32 * n_inputs/*+1*/) + 2 * 32 * (mixin+1) * n_inputs + 32 * n_outputs) << " saved)"); + LOG_PRINT_L2("estimated rct tx size for " << n_inputs << " with ring size " << (mixin+1) << " and " << n_outputs << ": " << size << " (" << ((32 * n_inputs/*+1*/) + 2 * 32 * (mixin+1) * n_inputs + 32 * n_outputs) << " saved)"); return size; } @@ -4359,7 +4403,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp // try to pick outputs not from the same block. We will get two outputs, one for // the destination, and one for change. LOG_PRINT_L2("checking preferred"); - std::vector<size_t> prefered_inputs; + std::vector<size_t> preferred_inputs; uint64_t rct_outs_needed = 2 * (fake_outs_count + 1); rct_outs_needed += 100; // some fudge factor since we don't know how many are locked if (use_rct && get_num_rct_outputs() >= rct_outs_needed) @@ -4367,12 +4411,12 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp // this is used to build a tx that's 1 or 2 inputs, and 2 outputs, which // will get us a known fee. uint64_t estimated_fee = calculate_fee(fee_per_kb, estimate_rct_tx_size(2, fake_outs_count + 1, 2), fee_multiplier); - prefered_inputs = pick_preferred_rct_inputs(needed_money + estimated_fee); - if (!prefered_inputs.empty()) + preferred_inputs = pick_preferred_rct_inputs(needed_money + estimated_fee); + if (!preferred_inputs.empty()) { string s; - for (auto i: prefered_inputs) s += boost::lexical_cast<std::string>(i) + "(" + print_money(m_transfers[i].amount()) + ") "; - LOG_PRINT_L1("Found prefered rct inputs for rct tx: " << s); + for (auto i: preferred_inputs) s += boost::lexical_cast<std::string>(i) + "(" + print_money(m_transfers[i].amount()) + ") "; + LOG_PRINT_L1("Found preferred rct inputs for rct tx: " << s); } } LOG_PRINT_L2("done checking preferred"); @@ -4427,8 +4471,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp } pop_if_present(unused_transfers_indices, idx); pop_if_present(unused_dust_indices, idx); - } else if (!prefered_inputs.empty()) { - idx = pop_back(prefered_inputs); + } else if (!preferred_inputs.empty()) { + idx = pop_back(preferred_inputs); pop_if_present(unused_transfers_indices, idx); pop_if_present(unused_dust_indices, idx); } else @@ -4521,7 +4565,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp { uint64_t new_paid_amount = i->amount /*+ test_ptx.fee*/ - needed_fee; LOG_PRINT_L2("Adjusting amount paid to " << get_account_address_as_str(m_testnet, i->addr) << " from " << - print_money(i->amount) << " to " << print_money(new_paid_amount) << " to accomodate " << + print_money(i->amount) << " to " << print_money(new_paid_amount) << " to accommodate " << print_money(needed_fee) << " fee"); dsts[0].amount += i->amount - new_paid_amount; i->amount = new_paid_amount; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 96dea2e40..ba9abacf5 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -129,6 +129,8 @@ namespace tools //! Just parses variables. static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm); + static bool verify_password(const std::string& keys_file_name, const std::string& password, bool watch_only); + wallet2(bool testnet = false, bool restricted = false) : m_run(true), m_callback(0), m_testnet(testnet), m_always_confirm_transfers(true), m_print_ring_members(false), m_store_tx_info(true), m_default_mixin(0), m_default_priority(0), m_refresh_type(RefreshOptimizeCoinbase), m_auto_refresh(true), m_refresh_from_block_height(0), m_confirm_missing_payment_id(true), m_ask_password(true), m_min_output_count(0), m_min_output_value(0), m_merge_destinations(false), m_is_initialized(false), m_restricted(restricted), is_old_file_format(false), m_node_rpc_proxy(m_http_client, m_daemon_rpc_mutex) {} struct transfer_details @@ -199,10 +201,11 @@ namespace tools std::vector<cryptonote::tx_destination_entry> m_dests; crypto::hash m_payment_id; uint64_t m_timestamp; + uint64_t m_unlock_time; - confirmed_transfer_details(): m_amount_in(0), m_amount_out(0), m_change((uint64_t)-1), m_block_height(0), m_payment_id(cryptonote::null_hash) {} + confirmed_transfer_details(): m_amount_in(0), m_amount_out(0), m_change((uint64_t)-1), m_block_height(0), m_payment_id(cryptonote::null_hash), m_timestamp(0), m_unlock_time(0) {} confirmed_transfer_details(const unconfirmed_transfer_details &utd, uint64_t height): - m_amount_in(utd.m_amount_in), m_amount_out(utd.m_amount_out), m_change(utd.m_change), m_block_height(height), m_dests(utd.m_dests), m_payment_id(utd.m_payment_id), m_timestamp(utd.m_timestamp) {} + m_amount_in(utd.m_amount_in), m_amount_out(utd.m_amount_out), m_change(utd.m_change), m_block_height(height), m_dests(utd.m_dests), m_payment_id(utd.m_payment_id), m_timestamp(utd.m_timestamp), m_unlock_time(utd.m_tx.unlock_time) {} }; struct tx_construction_data @@ -585,7 +588,7 @@ namespace tools uint64_t import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, uint64_t &spent, uint64_t &unspent); uint64_t import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent); - void update_pool_state(); + void update_pool_state(bool refreshed = false); std::string encrypt(const std::string &plaintext, const crypto::secret_key &skey, bool authenticated = true) const; std::string encrypt_with_view_secret_key(const std::string &plaintext, bool authenticated = true) const; @@ -706,7 +709,7 @@ BOOST_CLASS_VERSION(tools::wallet2, 18) BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 7) BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1) BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 6) -BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 3) +BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 4) BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 16) BOOST_CLASS_VERSION(tools::wallet2::unsigned_tx_set, 0) BOOST_CLASS_VERSION(tools::wallet2::signed_tx_set, 0) @@ -881,6 +884,13 @@ namespace boost x.m_amount_out += x.m_change; } } + if (ver < 4) + { + if (!typename Archive::is_saving()) + x.m_unlock_time = 0; + return; + } + a & x.m_unlock_time; } template <class Archive> diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index a136954f0..b7483ef8c 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -156,6 +156,7 @@ struct TransactionInfo virtual uint64_t fee() const = 0; virtual uint64_t blockHeight() const = 0; virtual uint64_t confirmations() const = 0; + virtual uint64_t unlockTime() const = 0; //! transaction_id virtual std::string hash() const = 0; virtual std::time_t timestamp() const = 0; @@ -380,6 +381,12 @@ struct Wallet virtual void setRefreshFromBlockHeight(uint64_t refresh_from_block_height) = 0; /*! + * \brief getRestoreHeight - get wallet creation height + * + */ + virtual uint64_t getRefreshFromBlockHeight() const = 0; + + /*! * \brief setRecoveringFromSeed - set state recover form seed * * \param recoveringFromSeed - true/false @@ -662,11 +669,20 @@ struct WalletManager /*! * @brief TODO: delme walletExists - check if the given filename is the wallet * @param path - filename - * @return + * @return - true if wallet exists */ virtual bool walletExists(const std::string &path) = 0; /*! + * @brief verifyWalletPassword - check if the given filename is the wallet + * @param keys_file_name - location of keys file + * @param password - password to verify + * @param watch_only - verify only view keys? + * @return - true if password is correct + */ + virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool watch_only) const = 0; + + /*! * \brief findWallets - searches for the wallet files by given path name recursively * \param path - starting point to search * \return - list of strings with found wallets (absolute paths); diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp index 1508f3791..34c5a2a5d 100644 --- a/src/wallet/wallet_args.cpp +++ b/src/wallet/wallet_args.cpp @@ -149,8 +149,10 @@ namespace wallet_args if (command_line::get_arg(vm, command_line::arg_help)) { - tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; - tools::msg_writer() << wallet_args::tr("Usage:") << ' ' << usage; + 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" + "daemon to work correctly.") << ENDL; + tools::msg_writer() << wallet_args::tr("Usage:") << ENDL << " " << usage; tools::msg_writer() << desc_all; return boost::none; } diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index 16807e045..2e5acc8cb 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -417,7 +417,7 @@ namespace tools typedef std::unordered_map<uint64_t, uint64_t> scanty_outs_t; explicit not_enough_outs_to_mix(std::string&& loc, const scanty_outs_t& scanty_outs, size_t mixin_count) - : transfer_error(std::move(loc), "not enough outputs to mix") + : transfer_error(std::move(loc), "not enough outputs to use") , m_scanty_outs(scanty_outs) , m_mixin_count(mixin_count) { @@ -429,7 +429,7 @@ namespace tools std::string to_string() const { std::ostringstream ss; - ss << transfer_error::to_string() << ", mixin_count = " << m_mixin_count << ", scanty_outs:"; + ss << transfer_error::to_string() << ", ring size = " << (m_mixin_count + 1) << ", scanty_outs:"; for (const auto& out: m_scanty_outs) { ss << '\n' << cryptonote::print_money(out.first) << " - " << out.second; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index e7b9b5a71..da55c2141 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -236,6 +236,7 @@ namespace tools entry.height = pd.m_block_height; entry.timestamp = pd.m_timestamp; entry.amount = pd.m_amount; + entry.unlock_time = pd.m_unlock_time; entry.fee = 0; // TODO entry.note = m_wallet->get_tx_note(pd.m_tx_hash); entry.type = "in"; @@ -249,6 +250,7 @@ namespace tools entry.payment_id = entry.payment_id.substr(0,16); entry.height = pd.m_block_height; entry.timestamp = pd.m_timestamp; + entry.unlock_time = pd.m_unlock_time; entry.fee = pd.m_amount_in - pd.m_amount_out; uint64_t change = pd.m_change == (uint64_t)-1 ? 0 : pd.m_change; // change may not be known entry.amount = pd.m_amount_in - change - entry.fee; @@ -276,6 +278,7 @@ namespace tools entry.timestamp = pd.m_timestamp; entry.fee = pd.m_amount_in - pd.m_amount_out; entry.amount = pd.m_amount_in - pd.m_change - entry.fee; + entry.unlock_time = pd.m_tx.unlock_time; entry.note = m_wallet->get_tx_note(txid); entry.type = is_failed ? "failed" : "pending"; } @@ -289,6 +292,7 @@ namespace tools entry.height = 0; entry.timestamp = pd.m_timestamp; entry.amount = pd.m_amount; + entry.unlock_time = pd.m_unlock_time; entry.fee = 0; // TODO entry.note = m_wallet->get_tx_note(pd.m_tx_hash); entry.type = "pool"; @@ -352,10 +356,25 @@ namespace tools cryptonote::tx_destination_entry de; bool has_payment_id; crypto::hash8 new_payment_id; - if(!get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), it->address, false)) + er.message = ""; + if(!get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), it->address, + [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string { + if (!dnssec_valid) + { + er.message = std::string("Invalid DNSSEC for ") + url; + return {}; + } + if (addresses.empty()) + { + er.message = std::string("No Monero address found at ") + url; + return {}; + } + return addresses[0]; + })) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; - er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address; + if (er.message.empty()) + er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address; return false; } de.amount = it->amount; @@ -441,7 +460,7 @@ namespace tools { uint64_t mixin = req.mixin; if (mixin < 2 && m_wallet->use_fork_rules(2, 10)) { - LOG_PRINT_L1("Requested mixin " << req.mixin << " too low for hard fork 2, using 2"); + LOG_PRINT_L1("Requested ring size " << (req.mixin + 1) << " too low for hard fork 2, using 3"); mixin = 2; } std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, req.priority, extra, m_trusted_daemon); @@ -454,7 +473,8 @@ namespace tools return false; } - m_wallet->commit_tx(ptx_vector); + if (!req.do_not_relay) + m_wallet->commit_tx(ptx_vector); // populate response with tx hash res.tx_hash = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx_vector.back().tx)); @@ -463,6 +483,13 @@ namespace tools res.tx_key = epee::string_tools::pod_to_hex(ptx_vector.back().tx_key); } res.fee = ptx_vector.back().fee; + + if (req.get_tx_hex) + { + cryptonote::blobdata blob; + tx_to_blob(ptx_vector.back().tx, blob); + res.tx_blob = epee::string_tools::buff_to_hex_nodelimer(blob); + } return true; } catch (const tools::error::daemon_busy& e) @@ -511,7 +538,7 @@ namespace tools uint64_t mixin = req.mixin; uint64_t ptx_amount; if (mixin < 2 && m_wallet->use_fork_rules(2, 10)) { - LOG_PRINT_L1("Requested mixin " << req.mixin << " too low for hard fork 2, using 2"); + LOG_PRINT_L1("Requested ring size " << (req.mixin + 1) << " too low for hard fork 2, using 3"); mixin = 2; } std::vector<wallet2::pending_tx> ptx_vector; @@ -519,9 +546,12 @@ namespace tools ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, req.priority, extra, m_trusted_daemon); LOG_PRINT_L2("on_transfer_split called create_transactions_2"); - LOG_PRINT_L2("on_transfer_split calling commit_tx"); - m_wallet->commit_tx(ptx_vector); - LOG_PRINT_L2("on_transfer_split called commit_tx"); + if (!req.do_not_relay) + { + LOG_PRINT_L2("on_transfer_split calling commit_tx"); + m_wallet->commit_tx(ptx_vector); + LOG_PRINT_L2("on_transfer_split called commit_tx"); + } // populate response with tx hashes for (auto & ptx : ptx_vector) @@ -538,6 +568,13 @@ namespace tools res.amount_list.push_back(ptx_amount); res.fee_list.push_back(ptx.fee); + + if (req.get_tx_hex) + { + cryptonote::blobdata blob; + tx_to_blob(ptx.tx, blob); + res.tx_blob_list.push_back(epee::string_tools::buff_to_hex_nodelimer(blob)); + } } return true; @@ -577,7 +614,8 @@ namespace tools { std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_unmixable_sweep_transactions(m_trusted_daemon); - m_wallet->commit_tx(ptx_vector); + if (!req.do_not_relay) + m_wallet->commit_tx(ptx_vector); // populate response with tx hashes for (auto & ptx : ptx_vector) @@ -588,6 +626,12 @@ namespace tools res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key)); } res.fee_list.push_back(ptx.fee); + if (req.get_tx_hex) + { + cryptonote::blobdata blob; + tx_to_blob(ptx.tx, blob); + res.tx_blob_list.push_back(epee::string_tools::buff_to_hex_nodelimer(blob)); + } } return true; @@ -640,7 +684,8 @@ namespace tools { std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, req.mixin, req.unlock_time, req.priority, extra, m_trusted_daemon); - m_wallet->commit_tx(ptx_vector); + if (!req.do_not_relay) + m_wallet->commit_tx(ptx_vector); // populate response with tx hashes for (auto & ptx : ptx_vector) @@ -650,7 +695,12 @@ namespace tools { res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key)); } - res.fee_list.push_back(ptx.fee); + if (req.get_tx_hex) + { + cryptonote::blobdata blob; + tx_to_blob(ptx.tx, blob); + res.tx_blob_list.push_back(epee::string_tools::buff_to_hex_nodelimer(blob)); + } } return true; @@ -1018,10 +1068,23 @@ namespace tools cryptonote::account_public_address address; bool has_payment_id; crypto::hash8 payment_id; - if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), req.address, false)) + er.message = ""; + if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), req.address, + [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string { + if (!dnssec_valid) + { + er.message = std::string("Invalid DNSSEC for ") + url; + return {}; + } + if (addresses.empty()) + { + er.message = std::string("No Monero address found at ") + url; + return {}; + } + return addresses[0]; + })) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; - er.message = ""; return false; } @@ -1412,10 +1475,25 @@ namespace tools bool has_payment_id; crypto::hash8 payment_id8; crypto::hash payment_id = cryptonote::null_hash; - if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), req.address, false)) + er.message = ""; + if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), req.address, + [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string { + if (!dnssec_valid) + { + er.message = std::string("Invalid DNSSEC for ") + url; + return {}; + } + if (addresses.empty()) + { + er.message = std::string("No Monero address found at ") + url; + return {}; + } + return addresses[0]; + })) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; - er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address; + if (er.message.empty()) + er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address; return false; } if (has_payment_id) diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 12ac281e4..fa5c154de 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -119,6 +119,8 @@ namespace wallet_rpc uint64_t unlock_time; std::string payment_id; bool get_tx_key; + bool do_not_relay; + bool get_tx_hex; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(destinations) @@ -127,6 +129,8 @@ namespace wallet_rpc KV_SERIALIZE(unlock_time) KV_SERIALIZE(payment_id) KV_SERIALIZE(get_tx_key) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) END_KV_SERIALIZE_MAP() }; @@ -136,12 +140,14 @@ namespace wallet_rpc std::string tx_key; std::list<std::string> amount_keys; uint64_t fee; + std::string tx_blob; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(tx_hash) KV_SERIALIZE(tx_key) KV_SERIALIZE(amount_keys) KV_SERIALIZE(fee) + KV_SERIALIZE(tx_blob) END_KV_SERIALIZE_MAP() }; }; @@ -156,6 +162,8 @@ namespace wallet_rpc uint64_t unlock_time; std::string payment_id; bool get_tx_keys; + bool do_not_relay; + bool get_tx_hex; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(destinations) @@ -164,6 +172,8 @@ namespace wallet_rpc KV_SERIALIZE(unlock_time) KV_SERIALIZE(payment_id) KV_SERIALIZE(get_tx_keys) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) END_KV_SERIALIZE_MAP() }; @@ -182,12 +192,14 @@ namespace wallet_rpc std::list<std::string> tx_key_list; std::list<uint64_t> amount_list; std::list<uint64_t> fee_list; + std::list<std::string> tx_blob_list; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(tx_hash_list) KV_SERIALIZE(tx_key_list) KV_SERIALIZE(amount_list) KV_SERIALIZE(fee_list) + KV_SERIALIZE(tx_blob_list) END_KV_SERIALIZE_MAP() }; }; @@ -197,9 +209,13 @@ namespace wallet_rpc struct request { bool get_tx_keys; + bool do_not_relay; + bool get_tx_hex; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(get_tx_keys) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) END_KV_SERIALIZE_MAP() }; @@ -217,11 +233,13 @@ namespace wallet_rpc std::list<std::string> tx_hash_list; std::list<std::string> tx_key_list; std::list<uint64_t> fee_list; + std::list<std::string> tx_blob_list; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(tx_hash_list) KV_SERIALIZE(tx_key_list) KV_SERIALIZE(fee_list) + KV_SERIALIZE(tx_blob_list) END_KV_SERIALIZE_MAP() }; }; @@ -237,6 +255,8 @@ namespace wallet_rpc std::string payment_id; bool get_tx_keys; uint64_t below_amount; + bool do_not_relay; + bool get_tx_hex; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(address) @@ -246,6 +266,8 @@ namespace wallet_rpc KV_SERIALIZE(payment_id) KV_SERIALIZE(get_tx_keys) KV_SERIALIZE(below_amount) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) END_KV_SERIALIZE_MAP() }; @@ -263,11 +285,13 @@ namespace wallet_rpc std::list<std::string> tx_hash_list; std::list<std::string> tx_key_list; std::list<uint64_t> fee_list; + std::list<std::string> tx_blob_list; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(tx_hash_list) KV_SERIALIZE(tx_key_list) KV_SERIALIZE(fee_list) + KV_SERIALIZE(tx_blob_list) END_KV_SERIALIZE_MAP() }; }; @@ -536,6 +560,7 @@ namespace wallet_rpc std::string note; std::list<transfer_destination> destinations; std::string type; + uint64_t unlock_time; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(txid); @@ -547,6 +572,7 @@ namespace wallet_rpc KV_SERIALIZE(note); KV_SERIALIZE(destinations); KV_SERIALIZE(type); + KV_SERIALIZE(unlock_time) END_KV_SERIALIZE_MAP() }; diff --git a/tests/core_proxy/core_proxy.cpp b/tests/core_proxy/core_proxy.cpp index c12b8e9a7..366937e1d 100644 --- a/tests/core_proxy/core_proxy.cpp +++ b/tests/core_proxy/core_proxy.cpp @@ -185,6 +185,19 @@ bool tests::proxy_core::handle_incoming_tx(const cryptonote::blobdata& tx_blob, return true; } +bool tests::proxy_core::handle_incoming_txs(const std::list<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) +{ + tvc.resize(tx_blobs.size()); + size_t i = 0; + for (const auto &tx_blob: tx_blobs) + { + if (!handle_incoming_tx(tx_blob, tvc[i], keeped_by_block, relayed, do_not_relay)) + return false; + ++i; + } + return true; +} + bool tests::proxy_core::handle_incoming_block(const cryptonote::blobdata& block_blob, cryptonote::block_verification_context& bvc, bool update_miner_blocktemplate) { block b = AUTO_VAL_INIT(b); diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h index 58645edb5..35e88081b 100644 --- a/tests/core_proxy/core_proxy.h +++ b/tests/core_proxy/core_proxy.h @@ -75,6 +75,7 @@ namespace tests bool have_block(const crypto::hash& id); bool get_blockchain_top(uint64_t& height, crypto::hash& top_id); bool handle_incoming_tx(const cryptonote::blobdata& tx_blob, cryptonote::tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay); + bool handle_incoming_txs(const std::list<cryptonote::blobdata>& tx_blobs, std::vector<cryptonote::tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay); bool handle_incoming_block(const cryptonote::blobdata& block_blob, cryptonote::block_verification_context& bvc, bool update_miner_blocktemplate = true); void pause_mine(){} void resume_mine(){} diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index da95a97a9..2f62dc2aa 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -31,6 +31,7 @@ set(unit_tests_sources ban.cpp base58.cpp blockchain_db.cpp + block_queue.cpp block_reward.cpp canonical_amounts.cpp chacha8.cpp @@ -72,6 +73,7 @@ add_executable(unit_tests target_link_libraries(unit_tests PRIVATE ringct + cryptonote_protocol cryptonote_core blockchain_db rpc diff --git a/tests/unit_tests/ban.cpp b/tests/unit_tests/ban.cpp index 432d5bbf3..694d733ec 100644 --- a/tests/unit_tests/ban.cpp +++ b/tests/unit_tests/ban.cpp @@ -52,6 +52,7 @@ public: bool have_block(const crypto::hash& id) const {return true;} bool get_blockchain_top(uint64_t& height, crypto::hash& top_id)const{height=0;top_id=cryptonote::null_hash;return true;} bool handle_incoming_tx(const cryptonote::blobdata& tx_blob, cryptonote::tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { return true; } + bool handle_incoming_txs(const std::list<cryptonote::blobdata>& tx_blob, std::vector<cryptonote::tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { return true; } bool handle_incoming_block(const cryptonote::blobdata& block_blob, cryptonote::block_verification_context& bvc, bool update_miner_blocktemplate = true) { return true; } void pause_mine(){} void resume_mine(){} diff --git a/tests/unit_tests/block_queue.cpp b/tests/unit_tests/block_queue.cpp new file mode 100644 index 000000000..f05d5487a --- /dev/null +++ b/tests/unit_tests/block_queue.cpp @@ -0,0 +1,87 @@ +// Copyright (c) 2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <boost/uuid/uuid.hpp> +#include "gtest/gtest.h" +#include "crypto/crypto.h" +#include "cryptonote_protocol/cryptonote_protocol_defs.h" +#include "cryptonote_protocol/block_queue.h" + +static const boost::uuids::uuid &uuid1() +{ + static const boost::uuids::uuid uuid = crypto::rand<boost::uuids::uuid>(); + return uuid; +} + +static const boost::uuids::uuid &uuid2() +{ + static const boost::uuids::uuid uuid = crypto::rand<boost::uuids::uuid>(); + return uuid; +} + +TEST(block_queue, empty) +{ + cryptonote::block_queue bq; + ASSERT_EQ(bq.get_max_block_height(), 0); +} + +TEST(block_queue, add_stepwise) +{ + cryptonote::block_queue bq; + bq.add_blocks(0, 200, uuid1()); + ASSERT_EQ(bq.get_max_block_height(), 199); + bq.add_blocks(200, 200, uuid1()); + ASSERT_EQ(bq.get_max_block_height(), 399); + bq.add_blocks(401, 200, uuid1()); + ASSERT_EQ(bq.get_max_block_height(), 600); + bq.add_blocks(400, 10, uuid1()); + ASSERT_EQ(bq.get_max_block_height(), 600); +} + +TEST(block_queue, flush_uuid) +{ + cryptonote::block_queue bq; + + bq.add_blocks(0, 200, uuid1()); + ASSERT_EQ(bq.get_max_block_height(), 199); + bq.add_blocks(200, 200, uuid2()); + ASSERT_EQ(bq.get_max_block_height(), 399); + bq.flush_spans(uuid2()); + ASSERT_EQ(bq.get_max_block_height(), 199); + bq.flush_spans(uuid1()); + ASSERT_EQ(bq.get_max_block_height(), 0); + + bq.add_blocks(0, 200, uuid1()); + ASSERT_EQ(bq.get_max_block_height(), 199); + bq.add_blocks(200, 200, uuid2()); + ASSERT_EQ(bq.get_max_block_height(), 399); + bq.flush_spans(uuid1()); + ASSERT_EQ(bq.get_max_block_height(), 399); + bq.add_blocks(0, 200, uuid1()); + ASSERT_EQ(bq.get_max_block_height(), 399); +} diff --git a/translations/monero.ts b/translations/monero.ts index 9137bf607..c65013f12 100644 --- a/translations/monero.ts +++ b/translations/monero.ts @@ -451,1162 +451,1178 @@ <context> <name>cryptonote::simple_wallet</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="280"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="290"/> <source>Commands: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> <source>failed to read wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1325"/> <source>invalid password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="687"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="697"/> <source>start_mining [<number_of_threads>] - Start mining in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="698"/> <source>Stop mining in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="689"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="699"/> <source>Save current blockchain data</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="691"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="701"/> <source>Show current wallet balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="694"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="704"/> <source>Show blockchain height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="705"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> <source>Show current wallet public address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="732"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> <source>Show this help</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="776"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="788"/> <source>set seed: needs an argument. available options: language</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="811"/> <source>set: unrecognized argument(s)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1438"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1442"/> <source>wallet file path not valid: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="851"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="863"/> <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="416"/> <source>usage: payment_id</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="710"/> <source>sweep_below <amount_threshold> [mixin] address [payment_id] - Send all unlocked outputs below the threshold to an address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="731"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="743"/> <source>Generate a new random full size payment id - these will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="762"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="774"/> <source>needs an argument</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="785"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="786"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="787"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="789"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="792"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="793"/> <location filename="../src/simplewallet/simplewallet.cpp" line="797"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="798"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="801"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="805"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="809"/> <source>0 or 1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="788"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="800"/> <source>integer >= 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="791"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="803"/> <source>0, 1, 2, 3, or 4</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="795"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> <source>unsigned integer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="912"/> <source>PLEASE NOTE: the following 25 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="948"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="958"/> <source>--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="963"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="973"/> <source>specify a recovery parameter with the --electrum-seed="words list here"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1113"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1123"/> <source>specify a wallet path with --generate-new-wallet (not --wallet-file)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1257"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1261"/> <source>wallet failed to connect to daemon: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1265"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1269"/> <source>Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1284"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1288"/> <source>List of available languages for your wallet's seed:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1297"/> <source>Enter the number corresponding to the language of your choice: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1354"/> <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1364"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1368"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1425"/> <source>Generated new wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1370"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1426"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1374"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1430"/> <source>failed to generate new wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1453"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1457"/> <source>Opened watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1453"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1457"/> <source>Opened wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1466"/> <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1477"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1481"/> <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1485"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1489"/> <source>failed to load wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1493"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1497"/> <source>Use "help" command to see the list of available commands. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1537"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1541"/> <source>Wallet data saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> <source>Mining started in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1607"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1615"/> <source>mining has NOT been started: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1622"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1634"/> <source>Mining stopped in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1624"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1636"/> <source>mining has NOT been stopped: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1655"/> <source>Blockchain saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1654"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1671"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1683"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1687"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1699"/> <source>Height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1655"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1672"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1684"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1671"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1700"/> <source>transaction </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1656"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1672"/> <source>received </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1673"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1689"/> <source>spent </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1685"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> <source>unsupported transaction format</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1718"/> <source>Starting refresh...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1731"/> <source>Refresh done, blocks received: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2681"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2701"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2181"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2201"/> <source>bad locked_blocks parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2186"/> - <source>Locked blocks too high, max 1000000 (Ë4 yrs)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2208"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2706"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2228"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> <source>a single transaction cannot use more than one payment id: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2217"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2237"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2735"/> <source>failed to set up payment id, though it was decoded correctly</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2242"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2335"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2513"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2729"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2774"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2262"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2533"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2794"/> <source>transaction cancelled.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2303"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2323"/> <source>Sending %s. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2306"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2326"/> <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2312"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2332"/> <source>The transaction fee is %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2315"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2335"/> <source>, of which %s is dust from change</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2316"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2336"/> <source>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2316"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2336"/> <source>A total of %s from dust change will be sent to dust address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2321"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2341"/> <source>. This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2347"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2785"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2367"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2544"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2805"/> <source>Failed to write transaction(s) to file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2351"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2528"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2789"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2548"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2809"/> <source>Unsigned transaction(s) successfully written to file: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2386"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2563"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2824"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3137"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2583"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2844"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3157"/> <source>Not enough money in unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2395"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2833"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3146"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2415"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> <source>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</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2415"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2435"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2612"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2873"/> <source>Reason: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2427"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2604"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2624"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> <source>failed to find a suitable way to split transactions</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2483"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2503"/> <source>No unmixable outputs found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2689"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2709"/> <source>No address given</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2921"/> <source>missing amount threshold</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2906"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> <source>invalid amount threshold</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2988"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3008"/> <source>Claimed change does not go to a paid address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2993"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3013"/> <source>Claimed change is larger than payment to the change address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3015"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3035"/> <source>sending %s to %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3021"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3041"/> <source>with no destinations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3068"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> <source>Failed to sign transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3094"/> <source>Failed to sign transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3100"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3120"/> <source>Failed to load transaction from file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3117"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3137"/> <source>daemon is busy. Please try later</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1729"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1975"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2375"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2552"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2813"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1745"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1995"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2833"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3146"/> <source>RPC error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="312"/> <source>wallet is watch-only and has no spend key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="380"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="390"/> <source>Your original password was incorrect.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="394"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="404"/> <source>Error with wallet rewrite: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="503"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="513"/> <source>priority must be 0, 1, 2, 3, or 4 </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="515"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="525"/> <source>priority must be 0, 1, 2, 3,or 4</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="530"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="540"/> <source>priority must be 0, 1, 2 3,or 4</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="613"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="623"/> <source>invalid unit</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="631"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="641"/> <source>invalid count: must be an unsigned integer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="649"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> <source>invalid value</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="705"/> <source>Same as transfer, but using an older transaction building algorithm</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="699"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="709"/> <source>sweep_all [mixin] address [payment_id] - Send all unlocked balance to an address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="701"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="711"/> <source>donate [<mixin_count>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="704"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="714"/> <source>set_log <level>|<categories> - Change current log detail (level must be <0-4>)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="707"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> <source>address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)] - Print all entries in the address book, optionally adding/deleting an entry to/from it</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> <source>show_transfers [in|out|pending|failed|pool] [<min_height> [<max_height>]] - Show incoming/outgoing transfers within an optional height range</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="741"/> <source>Show information about a transfer to/from this address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="730"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="742"/> <source>Change wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="820"/> <source>usage: set_log <log_level_number_0-4> | <categories></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="874"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="886"/> <source>(Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1149"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1157"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1184"/> <source>bad m_restore_height parameter: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1162"/> <source>date format must be YYYY-MM-DD</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1167"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1175"/> <source>Restore height is: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1168"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2348"/> <source>Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1212"/> <source>Daemon is local, assuming trusted</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1549"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1553"/> <source>Password for new watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1596"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1604"/> <source>invalid arguments. Please use start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery], <number_of_threads> should be from 1 to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1739"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2437"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2614"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2875"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3185"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1755"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2457"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2634"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2895"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3205"/> <source>internal error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1744"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1980"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2442"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2619"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2880"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2000"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3210"/> <source>unexpected error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1749"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1985"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2447"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2624"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2005"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2467"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3215"/> <source>unknown error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1770"/> <source>refresh failed: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1770"/> <source>Blocks received: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1779"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1795"/> <source>unlocked balance: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="796"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> <source>spent</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> <source>global index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> <source>tx id</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1850"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1868"/> <source>No incoming transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1854"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1872"/> <source>No incoming available transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1858"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> <source>No incoming unavailable transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1869"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1887"/> <source>expected at least one payment_id</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>payment</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>unlock time</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1888"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1908"/> <source>No payments with id </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1940"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2006"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2260"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1960"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2026"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2280"/> <source>failed to get blockchain height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2016"/> <source>failed to connect to the daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2014"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2034"/> <source> Transaction %llu/%llu: txid=%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2044"/> <source> Input %llu/%llu: amount=%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2040"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2060"/> <source>failed to get output: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2048"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2068"/> <source>output key's originating block height shouldn't be higher than the blockchain height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2052"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2072"/> <source> Originating block heights: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2087"/> <source> |</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2067"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2087"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3915"/> <source>| </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2084"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2104"/> <source> Warning: Some input keys being spent are from </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2086"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2132"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2152"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2937"/> <source>wrong number of arguments</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2237"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2257"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2744"/> <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2278"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2742"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2298"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2762"/> <source>No outputs found, or daemon is not ready</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2379"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2556"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2817"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3130"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2837"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3150"/> <source>failed to get random outputs to mix: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2498"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2759"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2518"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2779"/> <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2504"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2949"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2969"/> <source>Donating </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3033"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3053"/> <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. %sIs this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3057"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3077"/> <source>This is a watch only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4220"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4443"/> <source>usage: show_transfer <txid></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4334"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4557"/> <source>Transaction ID not found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="227"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="237"/> <source>true</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="256"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="266"/> <source>failed to parse refresh type</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="320"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="352"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="330"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="362"/> <source>wallet is watch-only and has no seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="343"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="357"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="367"/> <source>wallet is non-deterministic and has no seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="440"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="457"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="467"/> <source>wallet is watch-only and cannot transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="464"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="470"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="486"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="480"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="496"/> <source>mixin must be an integer >= 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="491"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="501"/> <source>could not change default mixin</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="535"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="545"/> <source>could not change default priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="690"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> <source>Synchronize transactions and balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="702"/> <source>incoming_transfers [available|unavailable] - Show incoming transfers, all or filtered by availability</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="693"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="703"/> <source>payments <PID_1> [<PID_2> ... <PID_N>] - Show payments for given payment ID[s]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="696"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="706"/> <source>transfer [<priority>] [<mixin_count>] <address> <amount> [<payment_id>] - Transfer <amount> to <address>. <priority> is the priority of the transaction. The higher the priority, the higher the fee of the transaction. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <mixin_count> is the number of extra inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="697"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="707"/> <source>locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="698"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="708"/> <source>Send all unmixable outputs to yourself with mixin 0</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> <source>Sign a transaction from a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="703"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="713"/> <source>Submit a signed transaction from a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="706"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="716"/> <source>integrated_address [PID] - Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="708"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="718"/> <source>Save wallet data</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="709"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="719"/> <source>Save a watch-only keys file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="710"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> <source>Display private view key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="711"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> <source>Display private spend key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="722"/> <source>Display Electrum-style mnemonic seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="713"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="723"/> <source>Available options: seed language - set wallet seed language; always-confirm-transfers <1|0> - whether to confirm unsplit txes; print-ring-members <1|0> - whether to print detailed information about ring members during confirmation; store-tx-info <1|0> - whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference; default-mixin <n> - set default mixin (default is 4); auto-refresh <1|0> - whether to automatically sync new blocks from the daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - set wallet refresh behaviour; priority [0|1|2|3|4] - default/unimportant/normal/elevated/priority fee; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - set default monero (sub-)unit; min-outputs-count [n] - try to keep at least that many outputs of value at least min-outputs-value; min-outputs-value [n] - try to keep at least min-outputs-count outputs of at least that value; merge-destinations <1|0> - whether to merge multiple payments to the same destination address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="714"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="724"/> <source>Rescan blockchain for spent outputs</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="725"/> <source>Get transaction key (r) for a given <txid></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="716"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> <source>Check amount going to <address> in <txid></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="718"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="727"/> + <source>Generate a signature to prove payment to <address> in <txid> using the transaction secret key (r) without revealing it</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="728"/> + <source>Check tx proof for payment going to <address> in <txid></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="730"/> <source>unspent_outputs [<min_amount> <max_amount>] - Show unspent outputs within an optional amount range</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="719"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="731"/> <source>Rescan blockchain from scratch</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="732"/> <source>Set an arbitrary string note for a txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="733"/> <source>Get a string note for a txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="722"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="734"/> <source>Show wallet status information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="735"/> <source>Sign the contents of a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="736"/> <source>Verify a signature on the contents of a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="725"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="737"/> <source>Export a signed set of key images</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="738"/> <source>Import signed key images list and verify their spent status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="727"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="739"/> <source>Export a set of outputs owned by this wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="728"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="740"/> <source>Import set of outputs owned by this wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="790"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="802"/> <source>full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="806"/> <source>monero, millinero, micronero, nanonero, piconero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="851"/> <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="856"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> <source>Wallet and key files found, loading...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="862"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="874"/> <source>Key file found but not wallet file. Regenerating...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> <source>Key file not found. Failed to open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="882"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="894"/> <source>Generating new wallet...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="937"/> <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-json="jsonfilename" and --generate-from-keys="wallet_name"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="943"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="953"/> <source>can't specify both --restore-deterministic-wallet and --non-deterministic</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="972"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="982"/> <source>Electrum-style word list failed verification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="984"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1001"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1053"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1046"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1063"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1079"/> <source>No data supplied, cancelled</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="992"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1044"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2200"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2698"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3277"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3825"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1002"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1054"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2220"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2718"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3276"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3530"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4048"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4239"/> <source>failed to parse address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1075"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1017"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> <source>failed to parse view key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1017"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1103"/> <source>failed to verify view key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1097"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1031"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1107"/> <source>view key does not match standard address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1026"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1118"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1128"/> <source>account creation failed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1059"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> <source>failed to parse spend key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1095"/> <source>failed to verify spend key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1099"/> <source>spend key does not match standard address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1191"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1199"/> <source>failed to open account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1258"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1203"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1579"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1626"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3348"/> + <source>wallet is null</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1262"/> <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or restart the wallet with the correct daemon address.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1302"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1307"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1311"/> <source>invalid language choice passed. Please try again. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1366"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1370"/> <source>View key: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1381"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1385"/> <source>Your wallet has been generated! To start synchronizing with the daemon, use "refresh" command. Use "help" command to see the list of available commands. @@ -1617,634 +1633,707 @@ your wallet again (your wallet keys are NOT at risk in any case). <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1488"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1492"/> <source>You may want to remove the file "%s" and try again</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1518"/> <source>failed to deinitialize wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1566"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1948"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1570"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1968"/> <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1641"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1657"/> <source>blockchain can't be saved: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1962"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2366"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2543"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1736"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1982"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2563"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2824"/> <source>daemon is busy. Please try again later.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1724"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1966"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2370"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2547"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1740"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1986"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2390"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2567"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2828"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1734"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1750"/> <source>refresh error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1778"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1794"/> <source>Balance: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1827"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> <source>pubkey</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1827"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> <source>key image</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1838"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> <source>unlocked</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> <source>ringct</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1837"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> <source>T</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1837"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> <source>F</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1838"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> <source>locked</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1857"/> <source>RingCT</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1857"/> <source>-</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1909"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1970"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1990"/> <source>failed to get spent status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> <source>the same transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> <source>blocks that are temporally very close</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3771"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2206"/> + <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3258"/> + <source>usage: get_tx_proof <txid> <dest_address> [<tx_key>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3289"/> + <source>failed to parse tx_key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3298"/> + <source>Tx secret key was found for the given txid, but you've also provided another tx secret key which doesn't match the found one.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3306"/> + <source>Tx secret key wasn't found in the wallet file. Provide it as the optional third parameter if you have it elsewhere.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3330"/> + <source>Signature: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3508"/> + <source>usage: check_tx_proof <txid> <address> <signature></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3539"/> + <source>Signature header check error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3550"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3560"/> + <source>Signature decoding error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3602"/> + <source>Tx pubkey was not found</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3609"/> + <source>Good signature</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3613"/> + <source>Bad signature</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3621"/> + <source>failed to generate key derivation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3994"/> <source>usage: integrated_address [payment ID]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4017"/> <source>Integrated address: account %s, payment ID %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4022"/> <source>Standard address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4027"/> <source>failed to parse payment ID or address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3815"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4038"/> <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3847"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4070"/> <source>failed to parse payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4088"/> <source>failed to parse index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3873"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4096"/> <source>Address book is empty.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3879"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4102"/> <source>Index: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3880"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4103"/> <source>Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3881"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4104"/> <source>Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3882"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4105"/> <source>Description: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3892"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4115"/> <source>usage: set_tx_note [txid] free text note</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3920"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4143"/> <source>usage: get_tx_note [txid]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3970"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4193"/> <source>usage: sign <filename></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3975"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4198"/> <source>wallet is watch-only and cannot sign</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3984"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4151"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4207"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4374"/> <source>failed to read file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4219"/> <source>usage: verify <filename> <address> <signature></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4023"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4246"/> <source>Bad signature from </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4250"/> <source>Good signature from </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4259"/> <source>usage: export_key_images <filename></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4041"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4264"/> <source>wallet is watch-only and cannot export key images</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4051"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4274"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4346"/> <source>failed to save file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4062"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4285"/> <source>Signed key images exported to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4070"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4293"/> <source>usage: import_key_images <filename></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4100"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4323"/> <source>usage: export_outputs <filename></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4134"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4357"/> <source>Outputs exported to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4142"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4365"/> <source>usage: import_outputs <filename></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3595"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2246"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3818"/> <source>amount is wrong: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2227"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3596"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2247"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3819"/> <source>expected number from 0 to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2358"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2378"/> <source>Money successfully sent, transaction </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3141"/> <source>no connection to daemon. Please, make sure daemon is running.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2577"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2838"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3151"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2597"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2858"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3171"/> <source>not enough outputs for specified mixin_count</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2403"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2580"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2841"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3174"/> <source>output amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2403"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2580"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2841"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3174"/> <source>found outputs to mix</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2408"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2585"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2846"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3159"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2428"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3179"/> <source>transaction was not constructed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2412"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2589"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2850"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3163"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> <source>transaction %s was rejected by daemon with status: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3171"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2443"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2620"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2881"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3191"/> <source>one of destinations is zero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3175"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> <source>Failed to find a suitable way to split transactions</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2870"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2452"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2629"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2890"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3200"/> <source>unknown transfer error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2496"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2516"/> <source>Sweeping </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2785"/> <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2535"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2796"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3109"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2816"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3129"/> <source>Money successfully sent, transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3002"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3022"/> <source>Change goes to more than one address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3047"/> <source>%s change to %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3030"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3050"/> <source>no change</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> <source>Transaction successfully signed to file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3206"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3226"/> <source>usage: get_tx_key <txid></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3214"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3251"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3899"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3927"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4227"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3354"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4122"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4150"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4450"/> <source>failed to parse txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3225"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3245"/> <source>Tx key: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3230"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3250"/> <source>no tx keys found for this txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3240"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3339"/> <source>usage: check_tx_key <txid> <txkey> <address></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3260"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3267"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3361"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3368"/> <source>failed to parse tx key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3287"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3573"/> <source>failed to get transaction from daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3298"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3584"/> <source>failed to parse transaction from daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3305"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3591"/> <source>failed to validate transaction from daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3596"/> <source>failed to get the right transaction from daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3317"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3385"/> <source>failed to generate key derivation from supplied parameters</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3373"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3471"/> <source>error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3379"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3477"/> <source>received</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3379"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3477"/> <source>in txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3383"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> <source>received nothing in txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3387"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3485"/> <source>WARNING: this transaction is not yet included in the blockchain!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3396"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3494"/> <source>This transaction has %u confirmations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3498"/> <source>WARNING: failed to determine number of confirmations!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3440"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> <source>usage: show_transfers [in|out|all|pending|failed] [<min_height> [<max_height>]]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3479"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3700"/> <source>bad min_height parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3491"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3712"/> <source>bad max_height parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3537"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3760"/> <source>in</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3537"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> <source>out</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> <source>failed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> <source>pending</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3809"/> <source>usage: unspent_outputs [<min_amount> <max_amount>]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3601"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3824"/> <source><min_amount> should be smaller than <max_amount></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3633"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3633"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> <source>, number of keys: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3638"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3861"/> <source> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3866"/> <source> Min block height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3867"/> <source> Max block height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3868"/> <source> Min amount found: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3646"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3869"/> <source> Max amount found: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3870"/> <source> Total count: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3687"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3910"/> <source> Bin size: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3911"/> <source> Outputs per *: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3690"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3913"/> <source>count ^ </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3915"/> <source> |</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3694"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> <source> +</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3694"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> <source>+--> block height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3918"/> <source> ^</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3918"/> <source>^ </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3696"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3919"/> <source> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3746"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3969"/> <source>wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="410"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3777"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4000"/> <source>Random payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3778"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4001"/> <source>Matching integrated address: </source> <translation type="unfinished"></translation> </message> @@ -2252,67 +2341,67 @@ Outputs per *: </source> <context> <name>sw</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="116"/> <source>Generate new wallet and save it to <arg></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="107"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="117"/> <source>Generate incoming-only wallet from view key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="108"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> <source>Generate wallet from private keys</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="110"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="120"/> <source>Specify Electrum seed for wallet recovery/creation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> <source>Recover wallet using Electrum-style mnemonic seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="112"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> <source>Create non-deterministic view and spend keys</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="113"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> <source>Enable commands which rely on a trusted daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="114"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> <source>Allow communicating with a daemon that uses a different RPC version</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> <source>Restore from specific blockchain height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> <source>daemon is busy. Please try again later.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="145"/> <source>possibly lost connection to daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="216"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="226"/> <source>Error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4391"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4614"/> <source>Failed to initialize wallet</source> <translation type="unfinished"></translation> </message> @@ -2502,7 +2591,7 @@ Outputs per *: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="5197"/> + <location filename="../src/wallet/wallet2.cpp" line="5205"/> <source>failed to read file </source> <translation type="unfinished"></translation> </message> @@ -2545,59 +2634,59 @@ Outputs per *: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1741"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1748"/> <source>Can't specify more than one of --wallet-file and --generate-from-json</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1753"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1760"/> <source>Must specify --wallet-file or --generate-from-json or --wallet-dir</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1757"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1764"/> <source>Loading wallet...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1782"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1807"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1789"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1814"/> <source>Storing wallet...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1784"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1809"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1791"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1816"/> <source>Stored ok</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1787"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1794"/> <source>Loaded ok</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1791"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1798"/> <source>Wallet initialization failed: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1798"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1805"/> <source>Failed to initialize wallet rpc server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1802"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1809"/> <source>Starting wallet rpc server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1804"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1811"/> <source>Stopped wallet rpc server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1813"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1820"/> <source>Failed to store wallet: </source> <translation type="unfinished"></translation> </message> @@ -2605,8 +2694,8 @@ Outputs per *: </source> <context> <name>wallet_args</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4357"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1708"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4580"/> <source>Wallet options</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero_fr.ts b/translations/monero_fr.ts index 5f712744b..58fcc17e1 100644 --- a/translations/monero_fr.ts +++ b/translations/monero_fr.ts @@ -451,82 +451,82 @@ <context> <name>cryptonote::simple_wallet</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="280"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="290"/> <source>Commands: </source> <translation>Commandes : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> <source>failed to read wallet password</source> <translation>échec de la lecture du mot de passe du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1325"/> <source>invalid password</source> <translation>mot de passe invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="687"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="697"/> <source>start_mining [<number_of_threads>] - Start mining in daemon</source> <translation>start_mining [<nombre_de_threads>] - Démarrer l'extraction minière dans le démon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="698"/> <source>Stop mining in daemon</source> <translation>Stopper l'extraction minière dans le démon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="689"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="699"/> <source>Save current blockchain data</source> <translation>Sauvegarder les données actuelles de la chaîne de blocs</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="691"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="701"/> <source>Show current wallet balance</source> <translation>Afficher le solde actuel du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="694"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="704"/> <source>Show blockchain height</source> <translation>Afficher la hauteur de la chaîne de blocs</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="705"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> <source>Show current wallet public address</source> <translation>Afficher l'adresse publique du portefeuille actuel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="732"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> <source>Show this help</source> <translation>Afficher cette aide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="776"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="788"/> <source>set seed: needs an argument. available options: language</source> <translation>set seed : requiert un argument. options disponibles : language</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="811"/> <source>set: unrecognized argument(s)</source> <translation>set : argument(s) non reconnu(s)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1438"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1442"/> <source>wallet file path not valid: </source> <translation>chemin du fichier portefeuille non valide : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="851"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="863"/> <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> <translation>Tentative de génération ou de restauration d'un portefeuille, mais le fichier spécifié existe déjà. Sortie pour ne pas risquer de l'écraser.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="416"/> <source>usage: payment_id</source> <translation>usage : payment_id</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="710"/> <source>sweep_below <amount_threshold> [mixin] address [payment_id] - Send all unlocked outputs below the threshold to an address</source> <translation>sweep_below <montant_seuil> [mixin] adresse [ID_paiement] - Envoyer toutes les sorties débloquées sous le seuil vers une adresse</translation> </message> @@ -535,33 +535,33 @@ <translation type="obsolete">Options disponibles : seed language - définir la langue de la graine du portefeuille; always-confirm-transfers <1|0> - confirmer ou non les transactions non scindées; print-ring-members <1|0> - afficher ou non des informations détaillées sur les membres du cercle pendant la confirmation; store-tx-info <1|0> - sauvegarder ou non les informations des transactions sortantes (adresse de destination, ID de paiement, clé secrète de transaction) pour référence future; default-mixin <n> - définir le mixin par défaut (4 par défaut); auto-refresh <1|0> - synchroniser automatiquement ou non les nouveau blocs du démon; refresh-type <full|optimize-coinbase|no-coinbase|default> - définir le comportement du rafraîchissement du portefeuille; priority [0|1|2|3|4] - frais de transaction par défault/peu important/normal/élevé/prioritaire; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - définir la (sous-)unité monero par défaut; min-outputs-count [n] - essayer de garder au moins ce nombre de sortie d'une valeur d'au moins min-outputs-value; min-outputs-value [n] - essayer de garder au moins min-outputs-count sorties d'une valeur d'au moins ce montant; merge-destinations <1|0> - fusionner ou non de multiples paiements à une même adresse de destination</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="731"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="743"/> <source>Generate a new random full size payment id - these will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids</source> <translation>Générer un nouvel ID de paiement long aléatoire - ceux-ci seront non cryptés dans la chaîne de blocs, voir integrated_address pour les IDs de paiement courts cryptés</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="762"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="774"/> <source>needs an argument</source> <translation>requiert un argument</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="785"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="786"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="787"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="789"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="792"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="793"/> <location filename="../src/simplewallet/simplewallet.cpp" line="797"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="798"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="801"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="805"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="809"/> <source>0 or 1</source> <translation>0 ou 1</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="788"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="800"/> <source>integer >= 2</source> <translation>entier >= 2</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="791"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="803"/> <source>0, 1, 2, 3, or 4</source> <translation>0, 1, 2, 3 ou 4</translation> </message> @@ -570,439 +570,438 @@ <translation type="obsolete">monero, millinero, micronero, nanonero, piconero</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="795"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> <source>unsigned integer</source> <translation>entier non signé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="912"/> <source>PLEASE NOTE: the following 25 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. </source> <translation>VEUILLEZ NOTER : les 25 mots suivants peuvent être utilisés pour restaurer votre portefeuille. Veuillez les écrire sur papier et les garder dans un endroit sûr. Ne les gardez pas dans un courriel ou dans un service de stockage de fichiers hors de votre contrôle. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="948"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="958"/> <source>--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file</source> <translation>--restore-deterministic-wallet utilise --generate-new-wallet, pas --wallet-file</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="963"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="973"/> <source>specify a recovery parameter with the --electrum-seed="words list here"</source> <translation>spécifiez un paramètre de récupération avec --electrum-seed="liste de mots ici"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1113"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1123"/> <source>specify a wallet path with --generate-new-wallet (not --wallet-file)</source> <translation>spécifiez un chemin de portefeuille avec --generate-new-wallet (pas --wallet-file)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1257"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1261"/> <source>wallet failed to connect to daemon: </source> <translation>échec de la connexion du portefeuille au démon : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1265"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1269"/> <source>Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.</source> <translation>Le démon utilise une version majeure de RPC (%u) différente de celle du portefeuille (%u) : %s. Mettez l'un des deux à jour, ou utilisez --allow-mismatched-daemon-version.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1284"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1288"/> <source>List of available languages for your wallet's seed:</source> <translation>Liste des langues disponibles pour la graine de votre portefeuille :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1297"/> <source>Enter the number corresponding to the language of your choice: </source> <translation>Entrez le nombre correspondant à la langue de votre choix : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1354"/> <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. </source> <translation>Vous avez utilisé une version obsolète du portefeuille. Veuillez dorénavant utiliser la nouvelle graine que nous fournissons. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1364"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1368"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1425"/> <source>Generated new wallet: </source> <translation>Nouveau portefeuille généré : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1370"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1426"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1374"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1430"/> <source>failed to generate new wallet: </source> <translation>échec de la génération du nouveau portefeuille : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1453"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1457"/> <source>Opened watch-only wallet</source> <translation>Ouverture du portefeuille d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1453"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1457"/> <source>Opened wallet</source> <translation>Ouverture du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1466"/> <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. </source> <translation>Vous avez utilisé une version obsolète du portefeuille. Veuillez procéder à la mise à jour de votre portefeuille. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1477"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1481"/> <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. </source> <translation>Vous avez utilisé une version obsolète du portefeuille. Le format de votre fichier portefeuille est en cours de mise à jour. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1485"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1489"/> <source>failed to load wallet: </source> <translation>échec du chargement du portefeuille : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1493"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1497"/> <source>Use "help" command to see the list of available commands. </source> <translation>Utilisez la commande "help" pour voir la liste des commandes disponibles. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1537"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1541"/> <source>Wallet data saved</source> <translation>Données du portefeuille sauvegardées</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> <source>Mining started in daemon</source> <translation>L'extraction minière dans le démon a démarré</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1607"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1615"/> <source>mining has NOT been started: </source> <translation>l'extraction minière n'a PAS démarré : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1622"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1634"/> <source>Mining stopped in daemon</source> <translation>L'extraction minière dans le démon a été stoppée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1624"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1636"/> <source>mining has NOT been stopped: </source> <translation>l'extraction minière n'a PAS été stoppée : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1655"/> <source>Blockchain saved</source> <translation>Chaîne de blocs sauvegardée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1654"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1671"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1683"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1687"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1699"/> <source>Height </source> <translation>Hauteur </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1655"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1672"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1684"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1671"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1700"/> <source>transaction </source> <translation>transaction </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1656"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1672"/> <source>received </source> <translation>reçu </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1673"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1689"/> <source>spent </source> <translation>dépensé </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1685"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> <source>unsupported transaction format</source> <translation>format de transaction non supporté</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1718"/> <source>Starting refresh...</source> <translation>Démarrage du rafraîchissement...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1731"/> <source>Refresh done, blocks received: </source> <translation>Rafraîchissement effectué, blocs reçus : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2681"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2701"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation>format d'identifiant de paiement invalide, 16 ou 64 caractères hexadécimaux attendus : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2181"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2201"/> <source>bad locked_blocks parameter:</source> <translation>mauvais paramètre locked_blocks :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2186"/> <source>Locked blocks too high, max 1000000 (Ë4 yrs)</source> - <translation variants="yes"> + <translation type="vanished" variants="yes"> <lengthvariant>Blocs vérrouillés trop élevé, 1000000 maximum (Ë</lengthvariant> <lengthvariant>4 ans)</lengthvariant> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2208"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2706"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2228"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> <source>a single transaction cannot use more than one payment id: </source> <translation>une unique transaction ne peut pas utiliser plus d'un ID de paiement : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2217"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2237"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2735"/> <source>failed to set up payment id, though it was decoded correctly</source> <translation>échec de la définition de l'ID de paiement, bien qu'il ait été décodé correctement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2242"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2335"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2513"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2729"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2774"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2262"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2533"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2794"/> <source>transaction cancelled.</source> <translation>transaction annulée.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2303"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2323"/> <source>Sending %s. </source> <translation>Envoi de %s. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2306"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2326"/> <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s</source> <translation>Votre transaction doit être scindée en %llu transactions. Il en résulte que des frais de transaction doivent être appliqués à chaque transaction, pour un total de %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2312"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2332"/> <source>The transaction fee is %s</source> <translation>Les frais de transaction sont de %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2315"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2335"/> <source>, of which %s is dust from change</source> <translation>, dont %s est de la poussière de monnaie rendue</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2316"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2336"/> <source>.</source> <translation>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2316"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2336"/> <source>A total of %s from dust change will be sent to dust address</source> <translation>Un total de %s de poussière de monnaie rendue sera envoyé à une adresse de poussière</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2321"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2341"/> <source>. This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> <translation>. Cette transaction sera déverrouillée au bloc %llu, dans approximativement %s jours (en supposant 2 minutes par bloc)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2347"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2785"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2367"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2544"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2805"/> <source>Failed to write transaction(s) to file</source> <translation>Échec de l'écriture de(s) transaction(s) dans le fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2351"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2528"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2789"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2548"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2809"/> <source>Unsigned transaction(s) successfully written to file: </source> <translation>Transaction(s) non signée(s) écrite(s) dans le fichier avec succès : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2386"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2563"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2824"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3137"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2583"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2844"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3157"/> <source>Not enough money in unlocked balance</source> <translation>Pas assez de fonds dans le solde débloqué</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2395"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2833"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3146"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2415"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> <source>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</source> <translation>Échec de la recherche d'une façon de créer les transactions. Ceci est généralement dû à de la poussière si petite qu'elle de peut pas payer ses propre frais, à une tentative d'envoi d'un montant supérieur au solde débloqué, ou parce qu'il n'en reste pas assez pour les frais de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2415"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2435"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2612"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2873"/> <source>Reason: </source> <translation>Raison : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2427"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2604"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2624"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> <source>failed to find a suitable way to split transactions</source> <translation>échec de la recherche d'une façon adéquate de scinder les transactions</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2483"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2503"/> <source>No unmixable outputs found</source> <translation>Aucune sortie non mélangeable trouvée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2689"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2709"/> <source>No address given</source> <translation>Aucune adresse fournie</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2921"/> <source>missing amount threshold</source> <translation>montant seuil manquant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2906"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> <source>invalid amount threshold</source> <translation>montant seuil invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2988"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3008"/> <source>Claimed change does not go to a paid address</source> <translation>La monnaie réclamée ne va pas à une adresse payée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2993"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3013"/> <source>Claimed change is larger than payment to the change address</source> <translation>La monnaie réclamée est supérieure au paiement à l'adresse de monnaie</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3015"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3035"/> <source>sending %s to %s</source> <translation>envoi de %s à %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3021"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3041"/> <source>with no destinations</source> <translation>sans destination</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3068"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> <source>Failed to sign transaction</source> <translation>Échec de signature de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3094"/> <source>Failed to sign transaction: </source> <translation>Échec de signature de transaction : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3100"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3120"/> <source>Failed to load transaction from file</source> <translation>Échec du chargement de la transaction du fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3117"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3137"/> <source>daemon is busy. Please try later</source> <translation>le démon est occupé. Veuillez réessayer plus tard</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1729"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1975"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2375"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2552"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2813"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1745"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1995"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2833"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3146"/> <source>RPC error: </source> <translation>Erreur RPC : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="312"/> <source>wallet is watch-only and has no spend key</source> <translation>c'est un portefeuille d'audit et il n'a pas de clé de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="380"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="390"/> <source>Your original password was incorrect.</source> <translation>Votre mot de passe original est incorrect.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="394"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="404"/> <source>Error with wallet rewrite: </source> <translation>Erreur avec la réécriture du portefeuille : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="503"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="513"/> <source>priority must be 0, 1, 2, 3, or 4 </source> <translation>la priorité doit être 0, 1, 2, 3 ou 4 </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="515"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="525"/> <source>priority must be 0, 1, 2, 3,or 4</source> <translation>la priorité doit être 0, 1, 2, 3 ou 4</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="530"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="540"/> <source>priority must be 0, 1, 2 3,or 4</source> <translation>la priorité doit être 0, 1, 2, 3 ou 4</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="613"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="623"/> <source>invalid unit</source> <translation>unité invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="631"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="641"/> <source>invalid count: must be an unsigned integer</source> <translation>nombre invalide : un entier non signé est attendu</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="649"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> <source>invalid value</source> <translation>valeur invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="705"/> <source>Same as transfer, but using an older transaction building algorithm</source> <translation>Comme transfer, mais utilise an algorithme de construction de transaction plus ancien</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="699"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="709"/> <source>sweep_all [mixin] address [payment_id] - Send all unlocked balance to an address</source> <translation>sweep_all [mixin] adresse [ID_paiement] - Envoyer tout le solde débloqué à une adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="701"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="711"/> <source>donate [<mixin_count>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)</source> <translation>donate [<mixin>] <montant> [ID_paiement] - Donner <montant> à l'équipe de développement (donate.getmonero.org)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="704"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="714"/> <source>set_log <level>|<categories> - Change current log detail (level must be <0-4>)</source> <translation>set_log <niveau>|<catégories> - Changer les détails du journal (niveau entre <0-4>)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="707"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> <source>address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)] - Print all entries in the address book, optionally adding/deleting an entry to/from it</source> <translation>address_book [(add (<adresse> [pid <ID de paiement long ou court>])|<adresse integrée> [<description avec des espaces possible>])|(delete <index>)] - Afficher toutes les entrées du carnet d'adresses, éventuellement en y ajoutant/supprimant une entrée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> <source>show_transfers [in|out|pending|failed|pool] [<min_height> [<max_height>]] - Show incoming/outgoing transfers within an optional height range</source> <translation>show_transfers [in|out|pending|failed|pool] [<hauteur_minimum> [<hauteur_maximum>]] - Afficher les transferts entrants/sortants en précisant éventuellement un intervalle de hauteurs</translation> </message> @@ -1011,630 +1010,651 @@ Cette transaction sera déverrouillée au bloc %llu, dans approximativement %s j <translation type="obsolete">unspent_outputs [<montant_minimum> <montant_maximum>] - Afficher les sorties non dépensées en précisant éventuellement un intervalle de montants</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="741"/> <source>Show information about a transfer to/from this address</source> <translation>Afficher les informations à propos d'un transfert vers/de cette adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="730"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="742"/> <source>Change wallet password</source> <translation>Changer le mot de passe du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="820"/> <source>usage: set_log <log_level_number_0-4> | <categories></source> <translation>usage : set_log <niveau_de_journalisation_0-4> | <catégories></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="874"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="886"/> <source>(Y/Yes/N/No): </source> <translation>(Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1149"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1157"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1184"/> <source>bad m_restore_height parameter: </source> <translation>mauvais paramètre m_restore_height : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1162"/> <source>date format must be YYYY-MM-DD</source> <translation>le format de date doit être AAAA-MM-JJ</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1167"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1175"/> <source>Restore height is: </source> <translation>La hauteur de restauration est : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1168"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2348"/> <source>Is this okay? (Y/Yes/N/No): </source> <translation>Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1212"/> <source>Daemon is local, assuming trusted</source> <translation>Le démon est local, supposons qu'il est de confiance</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1549"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1553"/> <source>Password for new watch-only wallet</source> <translation>Mot de passe pour le nouveau portefeuille d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1596"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1604"/> <source>invalid arguments. Please use start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery], <number_of_threads> should be from 1 to </source> <translation>arguments invalides. Veuillez utiliser start_mining [<nombre_de_threads>] [mine_en_arrière_plan] [ignorer_batterie], <nombre_de_threads> devrait être entre 1 et </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1739"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2437"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2614"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2875"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3185"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1755"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2457"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2634"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2895"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3205"/> <source>internal error: </source> <translation>erreur interne : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1744"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1980"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2442"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2619"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2880"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2000"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3210"/> <source>unexpected error: </source> <translation>erreur inattendue : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1749"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1985"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2447"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2624"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2005"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2467"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3215"/> <source>unknown error</source> <translation>erreur inconnue</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1770"/> <source>refresh failed: </source> <translation>échec du rafraîchissement : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1770"/> <source>Blocks received: </source> <translation>Blocs reçus : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1779"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1795"/> <source>unlocked balance: </source> <translation>solde débloqué : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="796"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>amount</source> <translation>montant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> <source>spent</source> <translation>dépensé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> <source>global index</source> <translation>index global</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> <source>tx id</source> <translation>ID de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1850"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1868"/> <source>No incoming transfers</source> <translation>Aucun transfert entrant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1854"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1872"/> <source>No incoming available transfers</source> <translation>Aucun transfert entrant disponible</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1858"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> <source>No incoming unavailable transfers</source> <translation>Aucun transfert entrant non disponible</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1869"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1887"/> <source>expected at least one payment_id</source> <translation>au moins un ID de paiement attendu</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>payment</source> <translation>paiement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>transaction</source> <translation>transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>height</source> <translation>hauteur</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>unlock time</source> <translation>durée de déverrouillage</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1888"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1908"/> <source>No payments with id </source> <translation>Aucun paiement avec l'ID </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1940"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2006"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2260"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1960"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2026"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2280"/> <source>failed to get blockchain height: </source> <translation>échec de la récupération de la hauteur de la chaîne de blocs : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2016"/> <source>failed to connect to the daemon</source> <translation>échec de la connexion au démon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2014"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2034"/> <source> Transaction %llu/%llu: txid=%s</source> <translation> Transaction %llu/%llu : ID=%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2044"/> <source> Input %llu/%llu: amount=%s</source> <translation> Entrée %llu/%llu : montant=%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2040"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2060"/> <source>failed to get output: </source> <translation>échec de la récupération de la sortie : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2048"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2068"/> <source>output key's originating block height shouldn't be higher than the blockchain height</source> <translation>la hauteur du bloc d'origine de la clé de la sortie ne devrait pas être supérieure à celle de la chaîne de blocs</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2052"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2072"/> <source> Originating block heights: </source> <translation> Hauteurs des blocs d'origine : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2087"/> <source> |</source> <translation> |</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2067"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2087"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3915"/> <source>| </source> <translation>| </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2084"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2104"/> <source> Warning: Some input keys being spent are from </source> <translation> Attention : Certaines clés d'entrées étant dépensées sont issues de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2086"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> <translation>, ce qui peut casser l'anonymat du cercle de signature. Assurez-vous que c'est intentionnel !</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2132"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2152"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2937"/> <source>wrong number of arguments</source> <translation>mauvais nombre d'arguments</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2237"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2257"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2744"/> <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> <translation>Aucun ID de paiement n'est inclus dans cette transaction. Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2278"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2742"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2298"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2762"/> <source>No outputs found, or daemon is not ready</source> <translation>Aucune sortie trouvée, ou le démon n'est pas prêt</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2379"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2556"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2817"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3130"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2837"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3150"/> <source>failed to get random outputs to mix: </source> <translation>échec de la récupération de sorties aléatoires à mélanger : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2498"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2759"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2518"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2779"/> <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation>Balayage de %s dans %llu transactions pour des frais totaux de %s. Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2504"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation>Balayage de %s pour des frais totaux de %s. Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2949"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2969"/> <source>Donating </source> <translation>Don de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3033"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3053"/> <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. %sIs this okay? (Y/Yes/N/No): </source> <translation>Chargement de %lu transactions, pour %s, %s de frais, %s. %s, avec mixin minimum de %lu. %sEst-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3057"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3077"/> <source>This is a watch only wallet</source> <translation>Ceci est un portefeuille d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4220"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4443"/> <source>usage: show_transfer <txid></source> <translation>usage : show_transfer <ID_de_transaction></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4334"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4557"/> <source>Transaction ID not found</source> <translation>ID de transaction non trouvé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="227"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="237"/> <source>true</source> <translation>vrai</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="256"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="266"/> <source>failed to parse refresh type</source> <translation>échec de l'analyse du type de rafraîchissement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="320"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="352"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="330"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="362"/> <source>wallet is watch-only and has no seed</source> <translation>c'est un portefeuille d'audit et il n'a pas de graine</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="343"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="357"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="367"/> <source>wallet is non-deterministic and has no seed</source> <translation>c'est un portefeuille non déterministe et il n'a pas de graine</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="440"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="457"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="467"/> <source>wallet is watch-only and cannot transfer</source> <translation>c'est un portefeuille d'audit et il ne peut pas transférer</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="464"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="470"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="486"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="480"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="496"/> <source>mixin must be an integer >= 2</source> <translation>mixin doit être un entier >= 2</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="491"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="501"/> <source>could not change default mixin</source> <translation>échec du changement du mixin par défaut</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="535"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="545"/> <source>could not change default priority</source> <translation>échec du changement de la priorité par défaut</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="690"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> <source>Synchronize transactions and balance</source> <translation>Synchroniser les transactions et le solde</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="702"/> <source>incoming_transfers [available|unavailable] - Show incoming transfers, all or filtered by availability</source> <translation>incoming_transfers [available|unavailable] - Afficher les transferts entrants, soit tous soit filtrés par disponibilité</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="693"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="703"/> <source>payments <PID_1> [<PID_2> ... <PID_N>] - Show payments for given payment ID[s]</source> <translation>payments <PID_1> [<PID_2> ... <PID_N>] - Affichier les paiements pour certains ID de paiement donnés</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="696"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="706"/> <source>transfer [<priority>] [<mixin_count>] <address> <amount> [<payment_id>] - Transfer <amount> to <address>. <priority> is the priority of the transaction. The higher the priority, the higher the fee of the transaction. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <mixin_count> is the number of extra inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> <translation>transfer [<priorité>] [<mixin>] <adresse> <montant> [<ID_paiement>] - Transférer <montant> à <adresse>. <priorité> est la priorité de la transaction. Plus la priorité est élevée, plues les frais de transaction seront élévés. Les valeurs de priorité valies sont dans l'ordre (de la plus basse à la plus élevée) : unimportant, normal, elevated, priority. Si ce paramètre est omis, la valeur par défaut (voir la commande "set priority") est utilisée. <mixin> est le nombre d'entrées supplémentaires à inclure pour l'intraçabilité. De multiples paiements peuvent être effectués d'un coup en ajoutant <adresse_2> <montant_2> et cetera (avant l'ID de paiement, s'il est inclus)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="697"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="707"/> <source>locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]</source> <translation>locked_transfer [<mixin>] <adresse> <montant> <blocs_vérrous>(Nombre de blocs pendant lequel vérrouiller la transaction, maximum 1000000) [<ID_paiement>]</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="698"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="708"/> <source>Send all unmixable outputs to yourself with mixin 0</source> <translation>Envoyer toutes les sorties non méleangeables à vous-même avec un mixin de 0</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> <source>Sign a transaction from a file</source> <translation>Signer une transaction d'un fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="703"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="713"/> <source>Submit a signed transaction from a file</source> <translation>Soumettre une transaction signée d'un fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="706"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="716"/> <source>integrated_address [PID] - Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID</source> <translation>integrated_address [PID] - Encoder un ID de paiement dans une adresse intégrée pour l'adresse publique du portefeuille actuel (sans argument un ID de paiement aléatoire est utilisé), ou décoder une adresse intégrée en une adresse standard et un ID de paiement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="708"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="718"/> <source>Save wallet data</source> <translation>Sauvegarder les données du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="709"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="719"/> <source>Save a watch-only keys file</source> <translation>Sauvegarder un fichier de clés d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="710"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> <source>Display private view key</source> <translation>Afficher la clé privée d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="711"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> <source>Display private spend key</source> <translation>Afficher la clé privée de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="722"/> <source>Display Electrum-style mnemonic seed</source> <translation>Afficher la graine mnémonique de style Electrum</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="713"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="723"/> <source>Available options: seed language - set wallet seed language; always-confirm-transfers <1|0> - whether to confirm unsplit txes; print-ring-members <1|0> - whether to print detailed information about ring members during confirmation; store-tx-info <1|0> - whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference; default-mixin <n> - set default mixin (default is 4); auto-refresh <1|0> - whether to automatically sync new blocks from the daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - set wallet refresh behaviour; priority [0|1|2|3|4] - default/unimportant/normal/elevated/priority fee; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - set default monero (sub-)unit; min-outputs-count [n] - try to keep at least that many outputs of value at least min-outputs-value; min-outputs-value [n] - try to keep at least min-outputs-count outputs of at least that value; merge-destinations <1|0> - whether to merge multiple payments to the same destination address</source> <translation>Options disponibles : seed language - définir la langue de la graine du portefeuille; always-confirm-transfers <1|0> - confirmer ou non les transactions non scindées; print-ring-members <1|0> - afficher ou non des informations détaillées sur les membres du cercle pendant la confirmation; store-tx-info <1|0> - sauvegarder ou non les informations des transactions sortantes (adresse de destination, ID de paiement, clé secrète de transaction) pour référence future; default-mixin <n> - définir le mixin par défaut (4 par défaut); auto-refresh <1|0> - synchroniser automatiquement ou non les nouveau blocs du démon; refresh-type <full|optimize-coinbase|no-coinbase|default> - définir le comportement du rafraîchissement du portefeuille; priority [0|1|2|3|4] - frais de transaction par défault/peu important/normal/élevé/prioritaire; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - définir la (sous-)unité monero par défaut; min-outputs-count [n] - essayer de garder au moins ce nombre de sortie d'une valeur d'au moins min-outputs-value; min-outputs-value [n] - essayer de garder au moins min-outputs-count sorties d'une valeur d'au moins ce montant; merge-destinations <1|0> - fusionner ou non de multiples paiements à une même adresse de destination</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="714"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="724"/> <source>Rescan blockchain for spent outputs</source> <translation>Réexaminer la chaîne de blocs pour trouver les sorties dépensées</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="725"/> <source>Get transaction key (r) for a given <txid></source> <translation>Obtenir la clé de transaction (r) pour un <ID_de_transaction> donné</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="716"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> <source>Check amount going to <address> in <txid></source> <translation>Vérifier le montant allant à <adresse> dans <ID_de_transaction></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="718"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="727"/> + <source>Generate a signature to prove payment to <address> in <txid> using the transaction secret key (r) without revealing it</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="728"/> + <source>Check tx proof for payment going to <address> in <txid></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="730"/> <source>unspent_outputs [<min_amount> <max_amount>] - Show unspent outputs within an optional amount range</source> <translation>unspent_outputs [<montant_minimum> <montant_maximum>] - Afficher les sorties non dépensées en précisant éventuellement un intervalle de montants</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="719"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="731"/> <source>Rescan blockchain from scratch</source> <translation>Réexaminer la chaîne de blocs depuis le début</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="732"/> <source>Set an arbitrary string note for a txid</source> <translation>Définir une note arbitraire pour un ID de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="733"/> <source>Get a string note for a txid</source> <translation>Obtenir une note pour un ID de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="722"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="734"/> <source>Show wallet status information</source> <translation>Afficher les informations sur le statut du portefuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="735"/> <source>Sign the contents of a file</source> <translation>Signer le contenu d'un fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="736"/> <source>Verify a signature on the contents of a file</source> <translation>Vérifier une signature du contenu d'un fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="725"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="737"/> <source>Export a signed set of key images</source> <translation>Exporter un ensemble signé d'images de clé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="738"/> <source>Import signed key images list and verify their spent status</source> <translation>Importer un ensemble signé d'images de clé et vérifier leurs statuts de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="727"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="739"/> <source>Export a set of outputs owned by this wallet</source> <translation>Exporter un ensemble de sorties possédées par ce portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="728"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="740"/> <source>Import set of outputs owned by this wallet</source> <translation>Importer un ensemble de sorties possédées par ce portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="790"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="802"/> <source>full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)</source> <translation>full (le plus lent, aucune supposition); optimize-coinbase (rapide, suppose que la récompense de bloc est payée à une unique adresse); no-coinbase (le plus rapide, suppose que l'on ne reçoit aucune récompense de bloc), default (comme optimize-coinbase)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="806"/> <source>monero, millinero, micronero, nanonero, piconero</source> <translation>monero, millinero, micronero, nanonero, piconero</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="851"/> <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> <translation>Nom de portefeuille non valide. Veuillez réessayer ou utilisez Ctrl-C pour quitter.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="856"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> <source>Wallet and key files found, loading...</source> <translation>Fichier portefeuille et fichier de clés trouvés, chargement...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="862"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="874"/> <source>Key file found but not wallet file. Regenerating...</source> <translation>Fichier de clés trouvé mais pas le fichier portefeuille. Régénération...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> <source>Key file not found. Failed to open wallet: </source> <translation>Fichier de clés non trouvé. Échec de l'ouverture du portefeuille : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="882"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="894"/> <source>Generating new wallet...</source> <translation>Génération du nouveau portefeuille...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="937"/> <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-json="jsonfilename" and --generate-from-keys="wallet_name"</source> <translation>impossible de spécifier plus d'une option parmis --generate-new-wallet="nom_du_portefeuille", --wallet-file="nom_du_portefeuille", --generate-from-view-key="nom_du_portefeuille", --generate-from-json="nom_du_fichier_json" et --generate-from-keys="nom_du_portefeuille"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="943"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="953"/> <source>can't specify both --restore-deterministic-wallet and --non-deterministic</source> <translation>impossible de spécifier à la fois --restore-deterministic-wallet et --non-deterministic</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="972"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="982"/> <source>Electrum-style word list failed verification</source> <translation>Échec de la vérification de la liste de mots de style Electrum</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="984"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1001"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1053"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1046"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1063"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1079"/> <source>No data supplied, cancelled</source> <translation>Pas de données fournies, annulation</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="992"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1044"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2200"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2698"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3277"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3825"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1002"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1054"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2220"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2718"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3276"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3530"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4048"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4239"/> <source>failed to parse address</source> <translation>échec de l'analyse de l'adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1075"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1017"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> <source>failed to parse view key secret key</source> <translation>échec de l'analyse de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1017"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1103"/> <source>failed to verify view key secret key</source> <translation>échec de la vérification de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1097"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1031"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1107"/> <source>view key does not match standard address</source> <translation>la clé d'audit ne correspond pas à l'adresse standard</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1026"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1118"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1128"/> <source>account creation failed</source> <translation>échec de la création du compte</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1059"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> <source>failed to parse spend key secret key</source> <translation>échec de l'analyse de la clé secrète de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1095"/> <source>failed to verify spend key secret key</source> <translation>échec de la vérification de la clé secrète de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1099"/> <source>spend key does not match standard address</source> <translation>la clé de dépense ne correspond pas à l'adresse standard</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1191"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1199"/> <source>failed to open account</source> <translation>échec de l'ouverture du compte</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1258"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1203"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1579"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1626"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3348"/> + <source>wallet is null</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1262"/> <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or restart the wallet with the correct daemon address.</source> <translation>Le démon n'est pas démarré ou un mauvais port a été passé. Veuillez vous assurer que le démon fonctionne ou redémarrez le portefeuille avec l'adresse de démon correcte.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1302"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1307"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1311"/> <source>invalid language choice passed. Please try again. </source> <translation>choix de langue passé invalide. Veuillez réessayer. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1366"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1370"/> <source>View key: </source> <translation>Clé d'audit : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1381"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1385"/> <source>Your wallet has been generated! To start synchronizing with the daemon, use "refresh" command. Use "help" command to see the list of available commands. @@ -1651,592 +1671,665 @@ votre portefeuille à nouveau (mais les clés de votre portefeuille ne risquent </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1488"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1492"/> <source>You may want to remove the file "%s" and try again</source> <translation>Vous pourriez vouloir supprimer le fichier "%s" et réessayer</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1518"/> <source>failed to deinitialize wallet</source> <translation>échec de la désinitialisation du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1566"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1948"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1570"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1968"/> <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> <translation>cette commande requiert un démon de confiance. Activer avec --trusted-daemon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1641"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1657"/> <source>blockchain can't be saved: </source> <translation>la chaîne de blocs ne peut pas être sauvegardée : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1962"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2366"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2543"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1736"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1982"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2563"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2824"/> <source>daemon is busy. Please try again later.</source> <translation>le démon est occupé. Veuillez réessayer plus tard.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1724"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1966"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2370"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2547"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1740"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1986"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2390"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2567"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2828"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>pas de connexion au démon. Veuillez vous assurer que le démon fonctionne.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1734"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1750"/> <source>refresh error: </source> <translation>erreur du rafraîchissement : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1778"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1794"/> <source>Balance: </source> <translation>Solde : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1827"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> <source>pubkey</source> <translation>clé publique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1827"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> <source>key image</source> <translation>image de clé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1838"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> <source>unlocked</source> <translation>déverrouillé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> <source>ringct</source> <translation>ringct</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1837"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> <source>T</source> <translation>V</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1837"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> <source>F</source> <translation>F</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1838"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> <source>locked</source> <translation>vérrouillé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1857"/> <source>RingCT</source> <translation>RingCT</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1857"/> <source>-</source> <translation>-</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1909"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> <translation>format d'identifiant de paiement invalide, 16 ou 64 caractères hexadécimaux attendus : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1970"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1990"/> <source>failed to get spent status</source> <translation>échec de la récupération du statut de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> <source>the same transaction</source> <translation>la même transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> <source>blocks that are temporally very close</source> <translation>blocs très proches dans le temps</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3771"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2206"/> + <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3258"/> + <source>usage: get_tx_proof <txid> <dest_address> [<tx_key>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3289"/> + <source>failed to parse tx_key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3298"/> + <source>Tx secret key was found for the given txid, but you've also provided another tx secret key which doesn't match the found one.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3306"/> + <source>Tx secret key wasn't found in the wallet file. Provide it as the optional third parameter if you have it elsewhere.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3330"/> + <source>Signature: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3508"/> + <source>usage: check_tx_proof <txid> <address> <signature></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3539"/> + <source>Signature header check error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3550"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3560"/> + <source>Signature decoding error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3602"/> + <source>Tx pubkey was not found</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3609"/> + <source>Good signature</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3613"/> + <source>Bad signature</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3621"/> + <source>failed to generate key derivation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3994"/> <source>usage: integrated_address [payment ID]</source> <translation>usage : integrated_address [ID paiement]</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4017"/> <source>Integrated address: account %s, payment ID %s</source> <translation>Adresse intégrée : compte %s, ID de paiement %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4022"/> <source>Standard address: </source> <translation>Adresse standard : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4027"/> <source>failed to parse payment ID or address</source> <translation>échec de l'analyse de l'ID de paiement ou de l'adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3815"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4038"/> <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> <translation>usage : address_book [(add (<adresse> [pid <ID de paiement long ou court>])|<adresse integrée> [<description avec des espaces possible>])|(delete <index>)]</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3847"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4070"/> <source>failed to parse payment ID</source> <translation>échec de l'analyse de l'ID de paiement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4088"/> <source>failed to parse index</source> <translation>échec de l'analyse de l'index</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3873"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4096"/> <source>Address book is empty.</source> <translation>Le carnet d'adresses est vide.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3879"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4102"/> <source>Index: </source> <translation>Index : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3880"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4103"/> <source>Address: </source> <translation>Adresse : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3881"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4104"/> <source>Payment ID: </source> <translation>ID de paiement : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3882"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4105"/> <source>Description: </source> <translation>Description : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3892"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4115"/> <source>usage: set_tx_note [txid] free text note</source> <translation>usage : set_tx_note [ID transaction] note de texte libre</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3920"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4143"/> <source>usage: get_tx_note [txid]</source> <translation>usage : get_tx_note [ID transaction]</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3970"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4193"/> <source>usage: sign <filename></source> <translation>usage : sign <fichier></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3975"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4198"/> <source>wallet is watch-only and cannot sign</source> <translation>c'est un portefeuille d'audit et il ne peut pas signer</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3984"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4151"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4207"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4374"/> <source>failed to read file </source> <translation>échec de la lecture du fichier </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4219"/> <source>usage: verify <filename> <address> <signature></source> <translation>usage : verify <fichier> <adresse> <signature></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4023"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4246"/> <source>Bad signature from </source> <translation>Mauvaise signature de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4250"/> <source>Good signature from </source> <translation>Bonne signature de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4259"/> <source>usage: export_key_images <filename></source> <translation>usage : export_key_images <fichier></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4041"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4264"/> <source>wallet is watch-only and cannot export key images</source> <translation>c'est un portefeuille d'audit et il ne peut pas exporter les images de clé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4051"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4274"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4346"/> <source>failed to save file </source> <translation>échec de l'enregistrement du fichier </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4062"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4285"/> <source>Signed key images exported to </source> <translation>Images de clé signées exportées vers </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4070"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4293"/> <source>usage: import_key_images <filename></source> <translation>usage : import_key_images <fichier></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4100"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4323"/> <source>usage: export_outputs <filename></source> <translation>usage : export_outputs <fichier></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4134"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4357"/> <source>Outputs exported to </source> <translation>Sorties exportées vers </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4142"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4365"/> <source>usage: import_outputs <filename></source> <translation>usage : import_outputs <fichier></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3595"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2246"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3818"/> <source>amount is wrong: </source> <translation>montant erroné : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2227"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3596"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2247"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3819"/> <source>expected number from 0 to </source> <translation>attend un nombre de 0 à </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2358"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2378"/> <source>Money successfully sent, transaction </source> <translation>Fonds envoyés avec succès, transaction </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3141"/> <source>no connection to daemon. Please, make sure daemon is running.</source> <translation>pas de connexion au démon. Veuillez vous assurer que le démon fonctionne.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2577"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2838"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3151"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2597"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2858"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3171"/> <source>not enough outputs for specified mixin_count</source> <translation>pas assez de sorties pour le mixin spécifié</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2403"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2580"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2841"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3174"/> <source>output amount</source> <translation>montant de la sortie</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2403"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2580"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2841"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3174"/> <source>found outputs to mix</source> <translation>sorties à mélanger trouvées</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2408"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2585"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2846"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3159"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2428"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3179"/> <source>transaction was not constructed</source> <translation>la transaction n'a pas été construite</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2412"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2589"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2850"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3163"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> <source>transaction %s was rejected by daemon with status: </source> <translation>la transaction %s a été rejetée par le démon avec le statut : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3171"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2443"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2620"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2881"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3191"/> <source>one of destinations is zero</source> <translation>une des destinations est zéro</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3175"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> <source>Failed to find a suitable way to split transactions</source> <translation>Échec de la recherche d'une façon adéquate de scinder les transactions</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2870"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2452"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2629"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2890"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3200"/> <source>unknown transfer error: </source> <translation>erreur de transfert inconnue : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2496"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2516"/> <source>Sweeping </source> <translation>Balayage de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2785"/> <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No)</source> <translation>Balayage de %s pour des frais totaux de %s. Est-ce correct ? (Y/Yes/Oui/N/No/Non)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2535"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2796"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3109"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2816"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3129"/> <source>Money successfully sent, transaction: </source> <translation>Fonds envoyés avec succès, transaction : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3002"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3022"/> <source>Change goes to more than one address</source> <translation>La monnaie rendue va à plus d'une adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3047"/> <source>%s change to %s</source> <translation>%s de monnaie rendue à %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3030"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3050"/> <source>no change</source> <translation>sans monnaie rendue</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> <source>Transaction successfully signed to file </source> <translation>Transaction signée avec succès dans le fichier </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3206"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3226"/> <source>usage: get_tx_key <txid></source> <translation>usage : get_tx_key <ID transaction></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3214"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3251"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3899"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3927"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4227"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3354"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4122"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4150"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4450"/> <source>failed to parse txid</source> <translation>échec de l'analyse de l'ID de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3225"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3245"/> <source>Tx key: </source> <translation>Clé de transaction : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3230"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3250"/> <source>no tx keys found for this txid</source> <translation>aucune clé de transaction trouvée pour cet ID de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3240"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3339"/> <source>usage: check_tx_key <txid> <txkey> <address></source> <translation>usage : check_tx_key <ID transaction> <clé transaction> <adresse></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3260"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3267"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3361"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3368"/> <source>failed to parse tx key</source> <translation>échec de l'analyse de la clé de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3287"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3573"/> <source>failed to get transaction from daemon</source> <translation>échec de la récupération de la transaction du démon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3298"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3584"/> <source>failed to parse transaction from daemon</source> <translation>échec de l'analyse de la transaction du démon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3305"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3591"/> <source>failed to validate transaction from daemon</source> <translation>échec de la validation de la transaction du démon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3596"/> <source>failed to get the right transaction from daemon</source> <translation>échec de la récupération de la bonne transaction du démon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3317"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3385"/> <source>failed to generate key derivation from supplied parameters</source> <translation>échec de la génération de la dérivation de clé à partir des paramètres fournis</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3373"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3471"/> <source>error: </source> <translation>erreur : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3379"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3477"/> <source>received</source> <translation>a reçu</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3379"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3477"/> <source>in txid</source> <translation>dans la transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3383"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> <source>received nothing in txid</source> <translation>n'a rien reçu dans la transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3387"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3485"/> <source>WARNING: this transaction is not yet included in the blockchain!</source> <translation>ATTENTION : cette transaction n'est pas encore inclue dans la chaîne de blocs !</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3396"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3494"/> <source>This transaction has %u confirmations</source> <translation>Cette transaction a %u confirmations</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3498"/> <source>WARNING: failed to determine number of confirmations!</source> <translation>ATTENTION : échec de la détermination du nombre de confirmations !</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3440"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> <source>usage: show_transfers [in|out|all|pending|failed] [<min_height> [<max_height>]]</source> <translation>usage : show_transfers [in|out|all|pending|failed] [<hauteur_minimum> [<hauteur_maximum>]]</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3479"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3700"/> <source>bad min_height parameter:</source> <translation>mauvais paramètre hauteur_minimum :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3491"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3712"/> <source>bad max_height parameter:</source> <translation>mauvais paramètre hauteur_maximum :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3537"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3760"/> <source>in</source> <translation>reçu</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3537"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> <source>out</source> <translation>payé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> <source>failed</source> <translation>échoué</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> <source>pending</source> <translation>en attente</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3809"/> <source>usage: unspent_outputs [<min_amount> <max_amount>]</source> <translation>usage : unspent_outputs [<montant_minimum> <montant_maximum>]</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3601"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3824"/> <source><min_amount> should be smaller than <max_amount></source> <translation><montant_minimum> doit être inférieur à <montant_maximum></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3633"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> <source> Amount: </source> <translation> Montant : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3633"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> <source>, number of keys: </source> <translation>, nombre de clés : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3638"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3861"/> <source> </source> <translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3866"/> <source> Min block height: </source> <translation> Hauteur de bloc minimum : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3867"/> <source> Max block height: </source> <translation> Hauteur de bloc maximum : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3868"/> <source> Min amount found: </source> <translation> Montant minimum trouvé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3646"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3869"/> <source> Max amount found: </source> <translation> Montant maximum trouvé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3870"/> <source> Total count: </source> <translation> Compte total : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3687"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3910"/> <source> Bin size: </source> <translation> Taille de classe : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3911"/> <source> Outputs per *: </source> <translation> Sorties par * : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3690"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3913"/> <source>count ^ </source> @@ -2245,52 +2338,52 @@ Sorties par * : </translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3915"/> <source> |</source> <translation> |</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3694"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> <source> +</source> <translation> +</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3694"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> <source>+--> block height </source> <translation>+--> hauteur de bloc </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3918"/> <source> ^</source> <translation> ^</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3918"/> <source>^ </source> <translation>^ </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3696"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3919"/> <source> </source> <translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3746"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3969"/> <source>wallet</source> <translation>portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="410"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3777"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4000"/> <source>Random payment ID: </source> <translation>ID de paiement aléatoire : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3778"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4001"/> <source>Matching integrated address: </source> <translation>Adresse intégrée correspondante : </translation> </message> @@ -2298,67 +2391,67 @@ Sorties par * : </translation> <context> <name>sw</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="116"/> <source>Generate new wallet and save it to <arg></source> <translation>Générer un nouveau portefeuille et le sauvegarder dans <arg></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="107"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="117"/> <source>Generate incoming-only wallet from view key</source> <translation>Générer un portefeuille d'audit à partir d'une clé d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="108"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> <source>Generate wallet from private keys</source> <translation>Générer un portefeuille à partir de clés privées</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="110"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="120"/> <source>Specify Electrum seed for wallet recovery/creation</source> <translation>Spécifier la graine Electrum pour la récupération/création d'un portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> <source>Recover wallet using Electrum-style mnemonic seed</source> <translation>Récupérer un portefeuille en utilisant une graine mnémonique de style Electrum</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="112"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> <source>Create non-deterministic view and spend keys</source> <translation>Créer des clés d'audit et de dépense non déterministes</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="113"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> <source>Enable commands which rely on a trusted daemon</source> <translation>Activer les commandes qui dépendent d'un démon de confiance</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="114"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> <source>Allow communicating with a daemon that uses a different RPC version</source> <translation>Autoriser la communication avec un démon utilisant une version de RPC différente</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> <source>Restore from specific blockchain height</source> <translation>Restaurer à partir d'une hauteur de bloc spécifique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> <source>daemon is busy. Please try again later.</source> <translation>le démon est occupé. Veuillez réessayer plus tard.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="145"/> <source>possibly lost connection to daemon</source> <translation>connexion avec le démon peut-être perdue</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="216"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="226"/> <source>Error: </source> <translation>Erreur : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4391"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4614"/> <source>Failed to initialize wallet</source> <translation>Échec de l'initialisation du portefeuille</translation> </message> @@ -2548,7 +2641,7 @@ Sorties par * : </translation> <translation>échec de la génération du nouveau portefeuille : </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="5197"/> + <location filename="../src/wallet/wallet2.cpp" line="5205"/> <source>failed to read file </source> <translation>échec de la lecture du fichier </translation> </message> @@ -2591,59 +2684,59 @@ Sorties par * : </translation> <translation>nom_utilisateur/mot_de_passe RPC sauvegardé dans le fichier </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1741"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1748"/> <source>Can't specify more than one of --wallet-file and --generate-from-json</source> <translation>Impossible de spécifier plus d'une option parmis --wallet-file et --generate-from-json</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1753"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1760"/> <source>Must specify --wallet-file or --generate-from-json or --wallet-dir</source> <translation>--wallet-file, --generate-from-json ou --wallet-dir doit être spécifié</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1757"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1764"/> <source>Loading wallet...</source> <translation>Chargement du portefeuille...</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1782"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1807"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1789"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1814"/> <source>Storing wallet...</source> <translation>Sauvegarde du portefeuille...</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1784"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1809"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1791"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1816"/> <source>Stored ok</source> <translation>Sauvegarde OK</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1787"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1794"/> <source>Loaded ok</source> <translation>Chargement OK</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1791"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1798"/> <source>Wallet initialization failed: </source> <translation>Échec de l'initialisation du portefeuille : </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1798"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1805"/> <source>Failed to initialize wallet rpc server</source> <translation>Échec de l'initialisation du serveur RPC du portefeuille</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1802"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1809"/> <source>Starting wallet rpc server</source> <translation>Démarrage du serveur RPC du portefeuille</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1804"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1811"/> <source>Stopped wallet rpc server</source> <translation>Arrêt du serveur RPC du portefeuille</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1813"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1820"/> <source>Failed to store wallet: </source> <translation>Échec de la sauvegarde du portefeuille : </translation> </message> @@ -2651,8 +2744,8 @@ Sorties par * : </translation> <context> <name>wallet_args</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4357"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="1708"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4580"/> <source>Wallet options</source> <translation>Options du portefeuille</translation> </message> diff --git a/translations/monero_it.ts b/translations/monero_it.ts new file mode 100644 index 000000000..c30413219 --- /dev/null +++ b/translations/monero_it.ts @@ -0,0 +1,2761 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="it" sourcelanguage="en"> +<context> + <name>Monero::AddressBookImpl</name> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="55"/> + <source>Invalid destination address</source> + <translation>Indirizzo destinatario invalido</translation> + </message> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="65"/> + <source>Invalid payment ID. Short payment ID should only be used in an integrated address</source> + <translation>ID pagamento invalido. Il pagamento id corto dovrebbe essere usato solo in un indirizzo integrato</translation> + </message> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="72"/> + <source>Invalid payment ID</source> + <translation>ID pagamento invalido</translation> + </message> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="79"/> + <source>Integrated address and long payment id can't be used at the same time</source> + <translation>Indirizzo integrato e ID pagamento lungo non possono essere usati nello stesso momento</translation> + </message> +</context> +<context> + <name>Monero::PendingTransactionImpl</name> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="90"/> + <source>Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:</source> + <translation>Sto tentando di salvare la transazione nel file, ma il file specificato esiste già. Sto uscendo per non rischiare di sovrascriverlo. File:</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="97"/> + <source>Failed to write transaction(s) to file</source> + <translation>Impossibile scrivere transazione/i su file</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="114"/> + <source>daemon is busy. Please try again later.</source> + <translation>Il daemon è impegnato. Prova più tardi.</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="117"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation>Nessuna connessione con il daemon. Controlla che sia operativo.</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="121"/> + <source>transaction %s was rejected by daemon with status: </source> + <translation>La transazione %s è stata respinta dal daemon con status: </translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="126"/> + <source>. Reason: </source> + <translation>Motivo: </translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="128"/> + <source>Unknown exception: </source> + <translation>Eccezione sconosciuta: </translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="131"/> + <source>Unhandled exception</source> + <translation>Eccezione non gestita</translation> + </message> +</context> +<context> + <name>Monero::UnsignedTransactionImpl</name> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="75"/> + <source>This is a watch only wallet</source> + <translation>Questo è un portafoglio solo-vista</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="85"/> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="92"/> + <source>Failed to sign transaction</source> + <translation>Firma transazione fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="135"/> + <source>Claimed change does not go to a paid address</source> + <translation>Il cambiamento richiesto non porta a un indirizzo pagato</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="141"/> + <source>Claimed change is larger than payment to the change address</source> + <translation>Il cambiamento richiesto è più largo del pagamento all'indirizzo di cambio</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="151"/> + <source>Change goes to more than one address</source> + <translation>Il cambiamento ha effetto su più di un in indirizzo</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="164"/> + <source>sending %s to %s</source> + <translation>Inviando %s a %s</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="170"/> + <source>with no destinations</source> + <translation>senza destinazioni</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="176"/> + <source>%s change to %s</source> + <translation>%s cambia in %s</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="179"/> + <source>no change</source> + <translation>nessun cambiamento</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="181"/> + <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. %s</source> + <translation>Caricato %lu transazioni, per %s, tassa %s, %s, %s, %s, con mixin %lu. %s</translation> + </message> +</context> +<context> + <name>Monero::WalletImpl</name> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="942"/> + <source>payment id has invalid format, expected 16 or 64 character hex string: </source> + <translation>L'id pagamento è in un formato invalido, dovrebbe essere una stringa hex di 16 o 64 caratteri: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="952"/> + <source>Failed to add short payment id: </source> + <translation>Impossibile aggiungere id pagamento corto</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="978"/> + <location filename="../src/wallet/api/wallet.cpp" line="1072"/> + <source>daemon is busy. Please try again later.</source> + <translation>il daemon è impegnato. Prova più tardi</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="981"/> + <location filename="../src/wallet/api/wallet.cpp" line="1075"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation>nessuna connessione con il daemon. Accertati che sia operativo</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="984"/> + <location filename="../src/wallet/api/wallet.cpp" line="1078"/> + <source>RPC error: </source> + <translation>errore RPC: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1081"/> + <source>failed to get random outputs to mix</source> + <translation>Impossibile raccogliere outputs random da mixare</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="994"/> + <location filename="../src/wallet/api/wallet.cpp" line="1088"/> + <source>not enough money to transfer, available only %s, sent amount %s</source> + <translation>non hai abbastanza soldi da trasferire, sono disponibili solo %s, ammontare inviato %s</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="403"/> + <source>failed to parse address</source> + <translation>Analisi(parse) indirizzo fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="415"/> + <source>failed to parse secret spend key</source> + <translation>Impossibile analizzare(parse) la chiave segreta spendibile</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="425"/> + <source>No view key supplied, cancelled</source> + <translation>Non è stata fornita nessuna chiave per visualizzazione</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="432"/> + <source>failed to parse secret view key</source> + <translation>Impossibile analizzare(parse) la chiave segreta per visualizzazione</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="442"/> + <source>failed to verify secret spend key</source> + <translation>impossibile verificare chiave segreta spendibile</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="447"/> + <source>spend key does not match address</source> + <translation>la chiave spendibile non corrisponde all'indirizzo</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="453"/> + <source>failed to verify secret view key</source> + <translation>verifica chiave segreta per visualizzazione fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="458"/> + <source>view key does not match address</source> + <translation>La chiave per visualizzazione non corrisponde all'indirizzo</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="477"/> + <source>failed to generate new wallet: </source> + <translation>impossibile generare nuovo portafoglio: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="799"/> + <source>Failed to load unsigned transactions</source> + <translation>Caricamento transazioni non firmate fallito</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="820"/> + <source>Failed to load transaction from file</source> + <translation>Caricamento transazione da file fallito</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="838"/> + <source>Wallet is view only</source> + <translation>Il portafoglio è di tipo solo visualizzazione</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="847"/> + <source>failed to save file </source> + <translation>impossibile salvare il file </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="874"/> + <source>Failed to import key images: </source> + <translation>Impossibile importare immagini chiave: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="987"/> + <source>failed to get random outputs to mix: %s</source> + <translation>impossibile recuperare outputs casuali da mixare: %s</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1003"/> + <location filename="../src/wallet/api/wallet.cpp" line="1097"/> + <source>not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)</source> + <translation>Non hai abbastanza ssoldi da trasferire, disponibili solo %s, ammontare transazione %s = %s + %s (tassa)</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1012"/> + <location filename="../src/wallet/api/wallet.cpp" line="1106"/> + <source>not enough outputs for specified mixin_count</source> + <translation>outputs insufficienti per il numero di mixaggi specificato </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1014"/> + <location filename="../src/wallet/api/wallet.cpp" line="1108"/> + <source>output amount</source> + <translation>ammontare output</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1014"/> + <location filename="../src/wallet/api/wallet.cpp" line="1108"/> + <source>found outputs to mix</source> + <translation>trovati outputs da mixare</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1019"/> + <location filename="../src/wallet/api/wallet.cpp" line="1113"/> + <source>transaction was not constructed</source> + <translation>transazione non costruita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1023"/> + <location filename="../src/wallet/api/wallet.cpp" line="1117"/> + <source>transaction %s was rejected by daemon with status: </source> + <translation>la transazione %s è stata rifiutata dal daemon con status: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1030"/> + <location filename="../src/wallet/api/wallet.cpp" line="1124"/> + <source>one of destinations is zero</source> + <translation>una delle destinazioni è zero</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1033"/> + <location filename="../src/wallet/api/wallet.cpp" line="1127"/> + <source>failed to find a suitable way to split transactions</source> + <translation>impossibile trovare un modo per dividere le transazioni</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1036"/> + <location filename="../src/wallet/api/wallet.cpp" line="1130"/> + <source>unknown transfer error: </source> + <translation>errore trasferimento sconosciuto: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1039"/> + <location filename="../src/wallet/api/wallet.cpp" line="1133"/> + <source>internal error: </source> + <translation>errore interno: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1042"/> + <location filename="../src/wallet/api/wallet.cpp" line="1136"/> + <source>unexpected error: </source> + <translation>errore insaspettato: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1045"/> + <location filename="../src/wallet/api/wallet.cpp" line="1139"/> + <source>unknown error</source> + <translation>errore sconosciuto</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1419"/> + <source>Rescan spent can only be used with a trusted daemon</source> + <translation>"riscannerizza spesi" può essere utilizzato solo da un daemon fidato</translation> + </message> +</context> +<context> + <name>Monero::WalletManagerImpl</name> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="192"/> + <source>failed to parse txid</source> + <translation>analisi(parse) txid fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="199"/> + <location filename="../src/wallet/api/wallet_manager.cpp" line="206"/> + <source>failed to parse tx key</source> + <translation>analisi(parse) chiave tx fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="217"/> + <source>failed to parse address</source> + <translation>analisi(parse) indirizzo fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="227"/> + <source>failed to get transaction from daemon</source> + <translation>impossibile recuperare transazione da daemon</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="238"/> + <source>failed to parse transaction from daemon</source> + <translation>impossibile analizzare(parse) transazione dal daemon</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="245"/> + <source>failed to validate transaction from daemon</source> + <translation>convalida transazione da daemon fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="250"/> + <source>failed to get the right transaction from daemon</source> + <translation>Impossibile recuperare la giusta transazione dal daemon</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="257"/> + <source>failed to generate key derivation from supplied parameters</source> + <translation>impossibile generare derivazione chiave dai parametri forniti</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="313"/> + <source>error: </source> + <translation>errore: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="319"/> + <source>received</source> + <translation>ricevuto</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="319"/> + <source>in txid</source> + <translation>in txid</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="323"/> + <source>received nothing in txid</source> + <translation>ricevuto nulla in txid</translation> + </message> +</context> +<context> + <name>Wallet</name> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="212"/> + <source>Failed to parse address</source> + <translation>Analisi(parse) indirizzo fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="219"/> + <source>Failed to parse key</source> + <translation>Analisi(parse) key fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="227"/> + <source>failed to verify key</source> + <translation>verifica key fallita</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="237"/> + <source>key does not match address</source> + <translation>la chiave non corrisponde all'indirizzo</translation> + </message> +</context> +<context> + <name>command_line</name> + <message> + <location filename="../src/common/command_line.cpp" line="76"/> + <source>yes</source> + <translation>sì</translation> + </message> +</context> +<context> + <name>cryptonote::rpc_args</name> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="38"/> + <source>Specify ip to bind rpc server</source> + <translation>Specificare ip da associare al server rpc</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="39"/> + <source>Specify username[:password] required for RPC server</source> + <translation>Specifica username[:password] richiesta per server RPC</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="40"/> + <source>Confirm rpc-bind-ip value is NOT a loopback (local) IP</source> + <translation>Conferma valore rpc-bind-ip NON è un loopback IP (locale)</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="66"/> + <source>Invalid IP address given for --</source> + <translation>Invalido indirizzo IP dato per --</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="74"/> + <source> permits inbound unencrypted external connections. Consider SSH tunnel or SSL proxy instead. Override with --</source> + <translation>permette connessioni esterne non criptate in entrata. Considera in alternativa un tunnel SSH o un proxy SSL. Sovrascrivi con --</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="89"/> + <source>Username specified with --</source> + <translation>Nome utente specificato con --</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="89"/> + <source> cannot be empty</source> + <translation> non puoò essere vuoto</translation> + </message> +</context> +<context> + <name>cryptonote::simple_wallet</name> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="290"/> + <source>Commands: </source> + <translation>Comandi: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> + <source>failed to read wallet password</source> + <translation>impossibile leggere password portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1325"/> + <source>invalid password</source> + <translation>password non valida</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="697"/> + <source>start_mining [<number_of_threads>] - Start mining in daemon</source> + <translation>inizia a minare [<number_of_threads>] - Inizia a minare nel daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="698"/> + <source>Stop mining in daemon</source> + <translation>interrompi mining nel daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="699"/> + <source>Save current blockchain data</source> + <translation>Salva dati correnti blockchain</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="701"/> + <source>Show current wallet balance</source> + <translation>Mostra bilancio portafoglio attuale</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="704"/> + <source>Show blockchain height</source> + <translation>Mostra "altezza" blockchain</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> + <source>Show current wallet public address</source> + <translation>Mostra indirizzo pubblico del corrente portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> + <source>Show this help</source> + <translation>Mostra questo aiuto</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="788"/> + <source>set seed: needs an argument. available options: language</source> + <translation>imposta seme: richiede una definizione. opzioni disponibili: lingua</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="811"/> + <source>set: unrecognized argument(s)</source> + <translation>imposta: definizione/i non riconosciuta/e</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1442"/> + <source>wallet file path not valid: </source> + <translation>percorso file portafoglio non valido: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="863"/> + <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> + <translation>Sto tentando di generare o ripristinare il portafoglio, ma i(l) file specificato/i esiste/esistono già. Sto uscendo per non rischiare di sovrascrivere.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="416"/> + <source>usage: payment_id</source> + <translation>uso: payment_id</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="710"/> + <source>sweep_below <amount_threshold> [mixin] address [payment_id] - Send all unlocked outputs below the threshold to an address</source> + <translation>sweep_below <amount_threshold> [mixin] address [payment_id] - Invia tutti gli outputs sbloccati sotto la soglia specificata a un indirizzo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="727"/> + <source>Generate a signature to prove payment to <address> in <txid> using the transaction secret key (r) without revealing it</source> + <translation>Genera una firma per provare un pagamento a <address> in <txid> usando la chiave di transazione (r) senza rivelarla</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="728"/> + <source>Check tx proof for payment going to <address> in <txid></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="743"/> + <source>Generate a new random full size payment id - these will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="774"/> + <source>needs an argument</source> + <translation>ha bisogno di un argomento</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="797"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="798"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="801"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="805"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="809"/> + <source>0 or 1</source> + <translation>0 o 1</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="800"/> + <source>integer >= 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="803"/> + <source>0, 1, 2, 3, or 4</source> + <translation>0, 1, 2, 3, o 4</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> + <source>unsigned integer</source> + <translation>integrale non firmato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="912"/> + <source>PLEASE NOTE: the following 25 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. +</source> + <translation>ATTENZIONE: le seguenti 25 parole possono essere usate per ripristinare il tuo portafoglio. Scrivile e conservale da qualche parte al sicuro.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="973"/> + <source>specify a recovery parameter with the --electrum-seed="words list here"</source> + <translation>Specificare un parametro di ripristino con --electrum-seed="lista parole qui"</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1261"/> + <source>wallet failed to connect to daemon: </source> + <translation>impossibile connettere portafoglio a daemon: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1269"/> + <source>Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.</source> + <translation>Il daemon usa una versione principale RPC (%u) diversa da quella del portafoglio (%u): %s. Aggiorna una delle due, o usa --allow-mismatched-daemon-version.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1288"/> + <source>List of available languages for your wallet's seed:</source> + <translation>Lista delle lingue disponibili per il seme del tuo portafoglio:</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1297"/> + <source>Enter the number corresponding to the language of your choice: </source> + <translation>Inserisci il numero corrispondente al linguaggio da te scelto: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1354"/> + <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. +</source> + <translation>Hai usato una versione obsoleta del portafoglio. Per favore usa il nuovo seme che ti abbiamo fornito.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1368"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1425"/> + <source>Generated new wallet: </source> + <translation>Nuovo portafoglio generato: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1374"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1430"/> + <source>failed to generate new wallet: </source> + <translation>impossibile generare nuovo portafoglio: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1457"/> + <source>Opened watch-only wallet</source> + <translation>Portafoglio solo-vista aperto</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1457"/> + <source>Opened wallet</source> + <translation>Portafoglio aperto</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1466"/> + <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. +</source> + <translation>Stai utilizzando una versione disapprovata del portafoglio. Per favore procedi nell'upgrade del portafoglio.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1481"/> + <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. +</source> + <translation>Stai utilizzando una versione disapprovata del portafoglio. Il formato del tuo portafoglio sta venendo aggiornato adesso.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1489"/> + <source>failed to load wallet: </source> + <translation>impossibile caricare portafoglio: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1497"/> + <source>Use "help" command to see the list of available commands. +</source> + <translation>Usa il comando "help" per visualizzare la lista dei comandi disponibili.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1541"/> + <source>Wallet data saved</source> + <translation>Dati del portafoglio salvati</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> + <source>Mining started in daemon</source> + <translation>Mining partito nel daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1615"/> + <source>mining has NOT been started: </source> + <translation>il mining NON è partito: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1634"/> + <source>Mining stopped in daemon</source> + <translation>Mining nel daemon interrotto</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1636"/> + <source>mining has NOT been stopped: </source> + <translation>Il mining NON è stato interrotto: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1655"/> + <source>Blockchain saved</source> + <translation>Blockchain salvata</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1687"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1699"/> + <source>Height </source> + <translation>Blocco </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1671"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1700"/> + <source>transaction </source> + <translation>transazione </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1672"/> + <source>received </source> + <translation>ricevuto/i </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1689"/> + <source>spent </source> + <translation>speso/i</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> + <source>unsupported transaction format</source> + <translation>formato transazione non supportato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1718"/> + <source>Starting refresh...</source> + <translation>Iniziando refresh...</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1731"/> + <source>Refresh done, blocks received: </source> + <translation>Refresh finito, blocchi ricevuti: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2701"/> + <source>payment id has invalid format, expected 16 or 64 character hex string: </source> + <translation>l'id pagamento ha un formato invalido, dovrebbe essere una stringa hex di 16 o 64 caratteri: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2201"/> + <source>bad locked_blocks parameter:</source> + <translation>parametro locked_blocks difettoso:</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2228"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> + <source>a single transaction cannot use more than one payment id: </source> + <translation>una singola transazione non può usare più di un id pagamento: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2237"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2735"/> + <source>failed to set up payment id, though it was decoded correctly</source> + <translation>impossibile impostare id pagamento, anche se è stato decodificado correttamente</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2262"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2533"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2794"/> + <source>transaction cancelled.</source> + <translation>transazione cancellata.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2323"/> + <source>Sending %s. </source> + <translation>Inviando %s. </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2326"/> + <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s</source> + <translation>La tua transazione deve essere divisa in %llu transazioni. Una tassa verrà applicata per ogni transazione, per un totale di %s tasse</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2332"/> + <source>The transaction fee is %s</source> + <translation>la tassa per la transazione è %s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2335"/> + <source>, of which %s is dust from change</source> + <translation>, della quale %s è polvere dovuta allo scambio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2336"/> + <source>.</source> + <translation>.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2336"/> + <source>A total of %s from dust change will be sent to dust address</source> + <translation>Un totale di %s in polvere verrà inviato all'indirizzo della polvere</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2341"/> + <source>. +This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> + <translation>Questa transazione verrà sbloccata al blocco %llu, in approssimativamente %s giorni (supponendo 2 minuti per blocco)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2367"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2544"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2805"/> + <source>Failed to write transaction(s) to file</source> + <translation>Impossibile scrivere transazione/i su file</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2548"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2809"/> + <source>Unsigned transaction(s) successfully written to file: </source> + <translation>Transazioni/e non firmata/e scritte/a con successo su file: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2583"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2844"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3157"/> + <source>Not enough money in unlocked balance</source> + <translation>Non hai abbastanza fondi nel bilancio sbloccato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2415"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> + <source>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</source> + <translation>Impossibile creare transazioni. Questo succede di solito perchè l'ammontare di polvere è così piccolo da non poter pagare le proprie tasse, oppure stai provando a mandare più soldi di quelli che possiedi nel bilancio sbloccato, o non hai aggiunto abbastanza tasse</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2435"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2612"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2873"/> + <source>Reason: </source> + <translation>Motivo: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2624"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> + <source>failed to find a suitable way to split transactions</source> + <translation>Impossibile trovare un modo adatto per dividere le transazioni</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2503"/> + <source>No unmixable outputs found</source> + <translation>Nessun output non-mixabile trovato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2709"/> + <source>No address given</source> + <translation>Non è stato fornito nessun indirizzo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3008"/> + <source>Claimed change does not go to a paid address</source> + <translation>Il cambiamento richiesto non porta a un indirizzo pagato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3013"/> + <source>Claimed change is larger than payment to the change address</source> + <translation>Il cambiamento richiesto è più largo del pagamento all'indirizzo di cambio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3035"/> + <source>sending %s to %s</source> + <translation>mandando %s a %s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3041"/> + <source>with no destinations</source> + <translation>senza destinazioni</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> + <source>Failed to sign transaction</source> + <translation>Impossibile firmare transazione</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3094"/> + <source>Failed to sign transaction: </source> + <translation>Impossibile firmare transazione: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3120"/> + <source>Failed to load transaction from file</source> + <translation>caricamento transazione da file fallito</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3137"/> + <source>daemon is busy. Please try later</source> + <translation>il daemon è occupato. Prova più tardi</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1745"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1995"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2833"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3146"/> + <source>RPC error: </source> + <translation>errore RPC: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="312"/> + <source>wallet is watch-only and has no spend key</source> + <translation>il portafoglio è solo-vista e non ha una chiave spendibile</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="390"/> + <source>Your original password was incorrect.</source> + <translation>La tua password originale era scorretta</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="404"/> + <source>Error with wallet rewrite: </source> + <translation>Errore riscrittura wallet: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="513"/> + <source>priority must be 0, 1, 2, 3, or 4 </source> + <translation>la priorità deve essere 0, 1, 2, 3, or 4 </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="525"/> + <source>priority must be 0, 1, 2, 3,or 4</source> + <translation>la priorità deve essere 0, 1, 2, 3,or 4</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="540"/> + <source>priority must be 0, 1, 2 3,or 4</source> + <translation>la priorità deve essere 0, 1, 2 3, or 4</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="623"/> + <source>invalid unit</source> + <translation>unità invalida</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="641"/> + <source>invalid count: must be an unsigned integer</source> + <translation>conteggio invalido: deve essere un integrale non firmato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> + <source>invalid value</source> + <translation>valore invalido</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="705"/> + <source>Same as transfer, but using an older transaction building algorithm</source> + <translation>Lo stesso di transfer, ma usando un vecchio algoritmo per costruire la transazione</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="709"/> + <source>sweep_all [mixin] address [payment_id] - Send all unlocked balance to an address</source> + <translation>sweep_all [mixin] address [payment_id] - Manda tutto il bilancio sbloccato ad un indirizzo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="711"/> + <source>donate [<mixin_count>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)</source> + <translation>donate [<mixin_count>] <amount> [payment_id] - Dona <amount> al team di sviluppo (donate.getmonero.org)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="714"/> + <source>set_log <level>|<categories> - Change current log detail (level must be <0-4>)</source> + <translation>set_log <level>|<categories> - Cambia livello dettaglio log (il livello deve essere <0-4>)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> + <source>address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)] - Print all entries in the address book, optionally adding/deleting an entry to/from it</source> + <translation>address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)] - Mostra tutte le voci nella rubrica, hai l'opzione di aggiungere/eliminare delle voci</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> + <source>show_transfers [in|out|pending|failed|pool] [<min_height> [<max_height>]] - Show incoming/outgoing transfers within an optional height range</source> + <translation>show_transfers [in|out|pending|failed|pool] [<min_height> [<max_height>]] - Mostra trasferimenti in entrata/uscita entro un altezza del blocco opzionale</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="741"/> + <source>Show information about a transfer to/from this address</source> + <translation>Mostra informazioni riguardo un trasferimento da/per questo indirizzo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="742"/> + <source>Change wallet password</source> + <translation>Cambia password portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="820"/> + <source>usage: set_log <log_level_number_0-4> | <categories></source> + <translation>uso: set_log <log_level_number_0-4> | <categories></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="886"/> + <source>(Y/Yes/N/No): </source> + <translation>(S/Sì/N/No): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1157"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1184"/> + <source>bad m_restore_height parameter: </source> + <translation>parametro m_restore_height scorretto: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1162"/> + <source>date format must be YYYY-MM-DD</source> + <translation>il formato della data deve essere YYYY-MM-DD</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1175"/> + <source>Restore height is: </source> + <translation>ripristina altezza è: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2348"/> + <source>Is this okay? (Y/Yes/N/No): </source> + <translation>va bene? (S/Sì/N/No): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1212"/> + <source>Daemon is local, assuming trusted</source> + <translation>Il daemon è locale, assunto per fidato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1553"/> + <source>Password for new watch-only wallet</source> + <translation>Password per il nuovo portafoglio solo-vista</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1604"/> + <source>invalid arguments. Please use start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery], <number_of_threads> should be from 1 to </source> + <translation>argomenti invalidi. Usa start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery], <number_of_threads> dovrebbe risultare da 1 a </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1755"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2457"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2634"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2895"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3205"/> + <source>internal error: </source> + <translation>errore interno: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2000"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3210"/> + <source>unexpected error: </source> + <translation>errore inaspettato: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2005"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2467"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3215"/> + <source>unknown error</source> + <translation>errore sconosciuto</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1770"/> + <source>refresh failed: </source> + <translation>refresh fallito: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1770"/> + <source>Blocks received: </source> + <translation>Blocchi ricevuti: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1795"/> + <source>unlocked balance: </source> + <translation>bilancio sbloccato: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>amount</source> + <translation>ammontare</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <source>spent</source> + <translation>spesi</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <source>global index</source> + <translation>indice globale</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <source>tx id</source> + <translation>tx id</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1868"/> + <source>No incoming transfers</source> + <translation>nessun trasferimento in entrata</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1872"/> + <source>No incoming available transfers</source> + <translation>nessun trasferimento in entrata disponibile</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <source>No incoming unavailable transfers</source> + <translation>Nessun trasferimento indisponibile in entrata</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1887"/> + <source>expected at least one payment_id</source> + <translation>deve esserci almeno un payment_id</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>payment</source> + <translation>pagamento</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>transaction</source> + <translation>transazione</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>height</source> + <translation>blocco</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>unlock time</source> + <translation>tempo sbloccato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1908"/> + <source>No payments with id </source> + <translation>nessun pagamento con id </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1960"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2026"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2280"/> + <source>failed to get blockchain height: </source> + <translation>impossibile recuperare dalla </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2016"/> + <source>failed to connect to the daemon</source> + <translation>impossibile connettersi al daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2034"/> + <source> +Transaction %llu/%llu: txid=%s</source> + <translation>Transazione %llu/%llu: txid=%s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2044"/> + <source> +Input %llu/%llu: amount=%s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2060"/> + <source>failed to get output: </source> + <translation>impossibile recuperare output: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2068"/> + <source>output key's originating block height shouldn't be higher than the blockchain height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2072"/> + <source> +Originating block heights: </source> + <translation>Originando blocchi: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2087"/> + <source> +|</source> + <translation> +|</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2087"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3915"/> + <source>| +</source> + <translation>| +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2104"/> + <source> +Warning: Some input keys being spent are from </source> + <translation>Avvertimento: alcune chiavi di input spese vengono da </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> + <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> + <translation>, che potrebbe rempere l'anonimità delle firme ad anello. Assicurati di farlo intenzionalmente!</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2152"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2937"/> + <source>wrong number of arguments</source> + <translation>errato numero di argomenti</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2257"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2744"/> + <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> + <translation>Nessun id pagamento incluso in questa transazione. Questo è corretto? (S/Sì/N/No): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2298"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2762"/> + <source>No outputs found, or daemon is not ready</source> + <translation>Nessun output trovato, o il daemon non è pronto</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2837"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3150"/> + <source>failed to get random outputs to mix: </source> + <translation>impossibile recuperare output casuali da mixare: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2518"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2779"/> + <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> + <translation>Eseguendo lo sweep di %s nelle transazioni %llu per un totale di tasse di %s. Va bene? (S/Sì/N/No): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> + <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> + <translation>Eseguendo lo sweep di %s per un totale di tasse di %s. Va bene? (S/Sì/N/No): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2969"/> + <source>Donating </source> + <translation>Donando </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3053"/> + <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. %sIs this okay? (Y/Yes/N/No): </source> + <translation>Caricate %lu transazioni, per %s, tasse %s, %s, %s, con mixaggio %lu. %sQuesto è corretto? (S/Sì/N/No): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3077"/> + <source>This is a watch only wallet</source> + <translation>questo è un portafoglio solo-vista</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4443"/> + <source>usage: show_transfer <txid></source> + <translation>uso: show_transfer <txid></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4557"/> + <source>Transaction ID not found</source> + <translation>ID transazione non trovato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="237"/> + <source>true</source> + <translation>vero</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="266"/> + <source>failed to parse refresh type</source> + <translation>impossibile analizzare (parse) tipo di refresh</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="330"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="362"/> + <source>wallet is watch-only and has no seed</source> + <translation>il portafoglio è solo-vista e non possiede un seme</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="367"/> + <source>wallet is non-deterministic and has no seed</source> + <translation>il portafoglio è non-deterministico e non possiede un seme</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="467"/> + <source>wallet is watch-only and cannot transfer</source> + <translation>il portafoglio è solo-vista e non può eseguire trasferimenti</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="480"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="496"/> + <source>mixin must be an integer >= 2</source> + <translation>mixin deve essere un integrale >= 2</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="501"/> + <source>could not change default mixin</source> + <translation>impossibile cambiare mixxaggio standard</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="545"/> + <source>could not change default priority</source> + <translation>impossibile cambiare priorità standard</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> + <source>Synchronize transactions and balance</source> + <translation>Sincronizzare transazioni e bilancio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="702"/> + <source>incoming_transfers [available|unavailable] - Show incoming transfers, all or filtered by availability</source> + <translation>incoming_transfers [available|unavailable] - Mostra trasferimenti in entrata, tutti o filtrati per disponibilità</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="703"/> + <source>payments <PID_1> [<PID_2> ... <PID_N>] - Show payments for given payment ID[s]</source> + <translation>payments <PID_1> [<PID_2> ... <PID_N>] - Mostra pagamenti per gli/l' ID fornito/i</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="706"/> + <source>transfer [<priority>] [<mixin_count>] <address> <amount> [<payment_id>] - Transfer <amount> to <address>. <priority> is the priority of the transaction. The higher the priority, the higher the fee of the transaction. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <mixin_count> is the number of extra inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <translation>transfer [<priority>] [<mixin_count>] <address> <amount> [<payment_id>] - Transfer <amount> to <address>. <priority> è la priorità della transazione. Maggiore è la priorità, maggiori saranno le tasse per la transazione. Valori validi in ordini di priorità (dal più basso al più alto) sono:unimportant, normal, elevated, priority. se omesso, verrà usato il valore standard (vedi il comando "set priority"). <mixin_count> è il numero di inputs extra da inludere per intracciabilità. Puoi eseguire pagamenti multipli in una volta aggiungendo <address_2> <amount_2> etcetera (prima dell' ID pagamento, se incluso)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="707"/> + <source>locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="708"/> + <source>Send all unmixable outputs to yourself with mixin 0</source> + <translation>Manda tutti gli outputs non spendibili a te stesso con mixaggio 0</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> + <source>Sign a transaction from a file</source> + <translation>Firma una transazione da file</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="713"/> + <source>Submit a signed transaction from a file</source> + <translation>Invia una transazione dirmata da file</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="716"/> + <source>integrated_address [PID] - Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="718"/> + <source>Save wallet data</source> + <translation>Salva i dati del portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="719"/> + <source>Save a watch-only keys file</source> + <translation>Salva una chiave solo-vista</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> + <source>Display private view key</source> + <translation>Visualizza chiave di visualizzazione privata</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> + <source>Display private spend key</source> + <translation>Visualizza chiave privata spendibile</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="722"/> + <source>Display Electrum-style mnemonic seed</source> + <translation>Visualizza il seme mnemonico in stile Electrum</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="723"/> + <source>Available options: seed language - set wallet seed language; always-confirm-transfers <1|0> - whether to confirm unsplit txes; print-ring-members <1|0> - whether to print detailed information about ring members during confirmation; store-tx-info <1|0> - whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference; default-mixin <n> - set default mixin (default is 4); auto-refresh <1|0> - whether to automatically sync new blocks from the daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - set wallet refresh behaviour; priority [0|1|2|3|4] - default/unimportant/normal/elevated/priority fee; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - set default monero (sub-)unit; min-outputs-count [n] - try to keep at least that many outputs of value at least min-outputs-value; min-outputs-value [n] - try to keep at least min-outputs-count outputs of at least that value; merge-destinations <1|0> - whether to merge multiple payments to the same destination address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="724"/> + <source>Rescan blockchain for spent outputs</source> + <translation>Riscannerizza blockchain in cerca di outputs non spesi</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="725"/> + <source>Get transaction key (r) for a given <txid></source> + <translation>Ricevi una chiave transazione (r) per ogni <txid></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> + <source>Check amount going to <address> in <txid></source> + <translation>Controlla l'ammontare che va da <address> a <txid></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="730"/> + <source>unspent_outputs [<min_amount> <max_amount>] - Show unspent outputs within an optional amount range</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="731"/> + <source>Rescan blockchain from scratch</source> + <translation>Riscannerizza blockchain dal principio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="732"/> + <source>Set an arbitrary string note for a txid</source> + <translation>Imposta una stringa arbitraria per un txid</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="733"/> + <source>Get a string note for a txid</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="734"/> + <source>Show wallet status information</source> + <translation>Visualizza informazioni sulla stato del portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="735"/> + <source>Sign the contents of a file</source> + <translation>Firma il contenuto di un file</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="736"/> + <source>Verify a signature on the contents of a file</source> + <translation>Verifica firma sul contesto del file</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="737"/> + <source>Export a signed set of key images</source> + <translation>Esporta un set di chiavi firmate</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="738"/> + <source>Import signed key images list and verify their spent status</source> + <translation>Importa immagine firmata della lista chiavi e verifica lo status degli spesi</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="739"/> + <source>Export a set of outputs owned by this wallet</source> + <translation>Esporta un set di outputs posseduti da questo portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="740"/> + <source>Import set of outputs owned by this wallet</source> + <translation>Importa un set di outputs posseduti da questo portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="802"/> + <source>full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="806"/> + <source>monero, millinero, micronero, nanonero, piconero</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="851"/> + <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> + <translation>Nome del portafoglio non valido. Prova di nuovo o usa Ctrl-C per uscire</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> + <source>Wallet and key files found, loading...</source> + <translation>Portafoglio e chiavi trovatr, sto caricando...</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="874"/> + <source>Key file found but not wallet file. Regenerating...</source> + <translation>Ho trovato la chiave ma non il portafoglio. Rigenerando...</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> + <source>Key file not found. Failed to open wallet: </source> + <translation>Chiave non trovata. Impossibile aprire portafoglio: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="894"/> + <source>Generating new wallet...</source> + <translation>Sto generando un nuovo portafoglio...</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="937"/> + <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-json="jsonfilename" and --generate-from-keys="wallet_name"</source> + <translation>non puoi specificare più di un --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-json="jsonfilename" e --generate-from-keys="wallet_name"</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="953"/> + <source>can't specify both --restore-deterministic-wallet and --non-deterministic</source> + <translation>impossibile specificare sia --restore-deterministic-wallet che --non-deterministic</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="958"/> + <source>--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file</source> + <translation>--restore-deterministic-wallet usa --generate-new-wallet, non --wallet-file</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="982"/> + <source>Electrum-style word list failed verification</source> + <translation>La lista di parole stile Electrum ha fallito la verifica</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1046"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1063"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1079"/> + <source>No data supplied, cancelled</source> + <translation>Nessun dato fornito, cancellato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1002"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1054"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2220"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2718"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3276"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3530"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4048"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4239"/> + <source>failed to parse address</source> + <translation>impossibile analizzare(parse) indirizzo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1017"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> + <source>failed to parse view key secret key</source> + <translation>impossibile analizzare(parse) chiave per visualizzazione chiave segreta</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1103"/> + <source>failed to verify view key secret key</source> + <translation>impossibile verificare chiave segreta vista</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1031"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1107"/> + <source>view key does not match standard address</source> + <translation>la chiave per visualizzazione non corrisponde all'indirizzo standard</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1128"/> + <source>account creation failed</source> + <translation>creazione dell'account fallita</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> + <source>failed to parse spend key secret key</source> + <translation>impossibile analizzare (parse) chiave spendibile chiave segreta</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1095"/> + <source>failed to verify spend key secret key</source> + <translation>impossibile verificare chiave spendibile chiave segreta</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1099"/> + <source>spend key does not match standard address</source> + <translation>la chiave spendibile non corrisponde all'indirizzo standard</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1123"/> + <source>specify a wallet path with --generate-new-wallet (not --wallet-file)</source> + <translation>specifica un nuovo percorso per il portafoglio con --generate-new-wallet (non --wallet-file)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1199"/> + <source>failed to open account</source> + <translation>impossibile aprire account</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1203"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1579"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1626"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3348"/> + <source>wallet is null</source> + <translation>il portafoglio è nullo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1262"/> + <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or restart the wallet with the correct daemon address.</source> + <translation>Il daemon non è partito o è settato con la porta sbagliata. Assicurati che il daemon stia funzionando o fai ripartire il wallet con l'indirizzo corretto del daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1311"/> + <source>invalid language choice passed. Please try again. +</source> + <translation>linguaggio selezionato scorretto. Prova di nuovo.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1370"/> + <source>View key: </source> + <translation>Chiave per visualizzazione: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1385"/> + <source>Your wallet has been generated! +To start synchronizing with the daemon, use "refresh" command. +Use "help" command to see the list of available commands. +Always use "exit" command when closing monero-wallet-cli to save your +current session's state. Otherwise, you might need to synchronize +your wallet again (your wallet keys are NOT at risk in any case). +</source> + <translation>Il tuo portafoglio è stato generato! +Per iniziare a sincronizzarlo con il daemon, usa il comando "refresh". +Usa il comando "help" per vedere la lista dei comandi disponibili. +Usa sempre il comando "exit" quando chiudi monero-wallet-cli per salvare +lo stato della tua sessione 's corrente. Altrimenti potresti dover sincronizzare +di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in sessun caso).</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1492"/> + <source>You may want to remove the file "%s" and try again</source> + <translation>Potresti voler rimuovere il file "%s" e provare di nuovo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1518"/> + <source>failed to deinitialize wallet</source> + <translation>deinizializzazione portafoglio fallita</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1570"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1968"/> + <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> + <translation>questo comando richiede un daemon fidato. Abilita questa opzione con --trusted-daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1657"/> + <source>blockchain can't be saved: </source> + <translation>impossibile salvare blockchain: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1736"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1982"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2563"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2824"/> + <source>daemon is busy. Please try again later.</source> + <translation>il daemon è impegnato. Prova più tardi</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1740"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1986"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2390"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2567"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2828"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation>nessuna connessione con il daemon. Assicurati che sia in funzione</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1750"/> + <source>refresh error: </source> + <translation>refresh errore: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1794"/> + <source>Balance: </source> + <translation>Bilancio: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> + <source>pubkey</source> + <translation>pubkey</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> + <source>key image</source> + <translation>immagine chiave</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> + <source>unlocked</source> + <translation>sbloccato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <source>ringct</source> + <translation>ringct</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> + <source>T</source> + <translation>T</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> + <source>F</source> + <translation>F</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> + <source>locked</source> + <translation>bloccato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1857"/> + <source>RingCT</source> + <translation>RingCT</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1857"/> + <source>-</source> + <translation>-</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> + <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> + <translation>l'id pagamento è in un formato invalido, dovrebbe essere una stringa hex di 16 o 64 caratteri</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1990"/> + <source>failed to get spent status</source> + <translation>impossibile recuperare status spesi</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> + <source>the same transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> + <source>blocks that are temporally very close</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2206"/> + <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2921"/> + <source>missing amount threshold</source> + <translation>manca la soglia massima dell'ammontare</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> + <source>invalid amount threshold</source> + <translation>ammontare soglia invalido</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3022"/> + <source>Change goes to more than one address</source> + <translation>Il cambiamento va a più di un indirizzo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3258"/> + <source>usage: get_tx_proof <txid> <dest_address> [<tx_key>]</source> + <translation>uso: get_tx_proof <txid> <dest_address> [<tx_key>]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3289"/> + <source>failed to parse tx_key</source> + <translation>impossibile analizzare (parse) tx_key</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3298"/> + <source>Tx secret key was found for the given txid, but you've also provided another tx secret key which doesn't match the found one.</source> + <translation>Una chiave tx segreta è stata trovata per il txid fornito, ma hai anche fornito un'altra chiave segreta tx che non corrsisponde a quella trovata.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3306"/> + <source>Tx secret key wasn't found in the wallet file. Provide it as the optional third parameter if you have it elsewhere.</source> + <translation>Chiave segreta tx non trovata nel file del portafoglio. Forniscila come terzo parametro opzionale se la conservi da qualche altra parte.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3330"/> + <source>Signature: </source> + <translation>Firma: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3508"/> + <source>usage: check_tx_proof <txid> <address> <signature></source> + <translation>uso: check_tx_proof <txid> <address> <signature></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3539"/> + <source>Signature header check error</source> + <translation>errore controllo firma intestazione</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3550"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3560"/> + <source>Signature decoding error</source> + <translation>Errore decodificazione firma</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3602"/> + <source>Tx pubkey was not found</source> + <translation>Chiave pubblica tx non trovata</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3609"/> + <source>Good signature</source> + <translation>Firma valida</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3613"/> + <source>Bad signature</source> + <translation>Firma invalida</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3621"/> + <source>failed to generate key derivation</source> + <translation>generazione derivazione chiave fallita</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3994"/> + <source>usage: integrated_address [payment ID]</source> + <translation>uso: integrated_address [ID pagamento]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4017"/> + <source>Integrated address: account %s, payment ID %s</source> + <translation>Indirizzo integrato: account %s, ID pagamento %s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4022"/> + <source>Standard address: </source> + <translation>Indirizzo standard: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4027"/> + <source>failed to parse payment ID or address</source> + <translation>impossibile analizzare (parse) ID pagamento o indirizzo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4038"/> + <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> + <translation>uso: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4070"/> + <source>failed to parse payment ID</source> + <translation>impossibile analizzare (parse) ID pagamento</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4088"/> + <source>failed to parse index</source> + <translation>impossibile analizzare (parse) indice</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4096"/> + <source>Address book is empty.</source> + <translation>La rubrica è vuota.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4102"/> + <source>Index: </source> + <translation>Indice: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4103"/> + <source>Address: </source> + <translation>Indirizzo: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4104"/> + <source>Payment ID: </source> + <translation>ID Pagamento: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4105"/> + <source>Description: </source> + <translation>Descrizione: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4115"/> + <source>usage: set_tx_note [txid] free text note</source> + <translation>uso: set_tx_note [txid] free text note</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4143"/> + <source>usage: get_tx_note [txid]</source> + <translation>uso: get_tx_note [txid]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4193"/> + <source>usage: sign <filename></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4198"/> + <source>wallet is watch-only and cannot sign</source> + <translation>il portafoglio è solo-vista e non può firmare</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4207"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4374"/> + <source>failed to read file </source> + <translation>impossibile leggere file </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4219"/> + <source>usage: verify <filename> <address> <signature></source> + <translation>uso: verify <filename> <address> <signature></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4246"/> + <source>Bad signature from </source> + <translation>Firma invalida da </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4250"/> + <source>Good signature from </source> + <translation>Firma valida da </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4259"/> + <source>usage: export_key_images <filename></source> + <translation>uso: export_key_images <filename></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4264"/> + <source>wallet is watch-only and cannot export key images</source> + <translation>il portafoglio è solo-vista e non può esportare immagini chiave</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4274"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4346"/> + <source>failed to save file </source> + <translation>impossibile salvare file </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4285"/> + <source>Signed key images exported to </source> + <translation>Chiave immagine firmata esportata in </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4293"/> + <source>usage: import_key_images <filename></source> + <translation>uso: import_key_images <filename></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4323"/> + <source>usage: export_outputs <filename></source> + <translation>usage: export_outputs <filename></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4357"/> + <source>Outputs exported to </source> + <translation>Outputs esportati in </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4365"/> + <source>usage: import_outputs <filename></source> + <translation>uso: import_outputs <filename></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2246"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3818"/> + <source>amount is wrong: </source> + <translation>l'ammontare è scorretto: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2247"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3819"/> + <source>expected number from 0 to </source> + <translation>deve essere un numero da 0 a </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2378"/> + <source>Money successfully sent, transaction </source> + <translation>Fondi inviati con successo, transazione </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3141"/> + <source>no connection to daemon. Please, make sure daemon is running.</source> + <translation>nessuna connessione con il daemon, assicurati che stia funzionando.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2597"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2858"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3171"/> + <source>not enough outputs for specified mixin_count</source> + <translation>non ci sono abbastanza output per lo specificato mixin_count</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3174"/> + <source>output amount</source> + <translation>ammontare output</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3174"/> + <source>found outputs to mix</source> + <translation>trovati outputs da mixare</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2428"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3179"/> + <source>transaction was not constructed</source> + <translation>la transazione non è stata costruita</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> + <source>transaction %s was rejected by daemon with status: </source> + <translation>la transazione %s è stata respinta dal daemon con status: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2443"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2620"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2881"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3191"/> + <source>one of destinations is zero</source> + <translation>una delle destinazioni è zero</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> + <source>Failed to find a suitable way to split transactions</source> + <translation>Impossibile trovare un modo corretto per dividere transazioni</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2452"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2629"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2890"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3200"/> + <source>unknown transfer error: </source> + <translation>errore trasferimento sconosciuto: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2516"/> + <source>Sweeping </source> + <translation>Pulendo (sweeping) </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2785"/> + <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No)</source> + <translation>Eseguendo lo sweeping di %s per un totale di tasse di %s. Va bene? (S/Sì/N/No)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2816"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3129"/> + <source>Money successfully sent, transaction: </source> + <translation>Soldi inviati con successo, transazione: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3047"/> + <source>%s change to %s</source> + <translation>%s cambia in %s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3050"/> + <source>no change</source> + <translation>nessun cambiamento</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> + <source>Transaction successfully signed to file </source> + <translation>Transazione firmata con successo nel file </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3226"/> + <source>usage: get_tx_key <txid></source> + <translation>uso: get_tx_key <txid></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3354"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4122"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4150"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4450"/> + <source>failed to parse txid</source> + <translation>analisi(parse) txid fallita</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3245"/> + <source>Tx key: </source> + <translation>Chiave Tx: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3250"/> + <source>no tx keys found for this txid</source> + <translation>nessuna chiave tx trovata per questo txid</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3339"/> + <source>usage: check_tx_key <txid> <txkey> <address></source> + <translation>uso: check_tx_key <txid> <txkey> <address></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3361"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3368"/> + <source>failed to parse tx key</source> + <translation>impossibile analizzare (parse) chiave tx</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3573"/> + <source>failed to get transaction from daemon</source> + <translation>impossibil recuperare transazione dal daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3584"/> + <source>failed to parse transaction from daemon</source> + <translation>impossibile analizzare (parse) la transazione dal daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3591"/> + <source>failed to validate transaction from daemon</source> + <translation>convalida transazione dal daemon fallita</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3596"/> + <source>failed to get the right transaction from daemon</source> + <translation>impossibile recuperare la corretta transazione dal daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3385"/> + <source>failed to generate key derivation from supplied parameters</source> + <translation>impossibile generare chiave derivazione dai parametri forniti</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3471"/> + <source>error: </source> + <translation>errore: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3477"/> + <source>received</source> + <translation>ricevuto/i</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3477"/> + <source>in txid</source> + <translation>in txid</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> + <source>received nothing in txid</source> + <translation>ricevuto niente in txid</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3485"/> + <source>WARNING: this transaction is not yet included in the blockchain!</source> + <translation>AVVERTIMENTO: questa transazione non è ancora inclusa nella blockchain!</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3494"/> + <source>This transaction has %u confirmations</source> + <translation>Questa transazione ha %u conferme</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3498"/> + <source>WARNING: failed to determine number of confirmations!</source> + <translation>AVVERTIMENTO: impossibile determinare numero di conferme!</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <source>usage: show_transfers [in|out|all|pending|failed] [<min_height> [<max_height>]]</source> + <translation>uso: show_transfers [in|out|all|pending|failed] [<min_height> [<max_height>]]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3700"/> + <source>bad min_height parameter:</source> + <translation>parametro min_height scorretto:</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3712"/> + <source>bad max_height parameter:</source> + <translation>parametro max_height scorretto:</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3760"/> + <source>in</source> + <translation>in</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> + <source>out</source> + <translation>out</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> + <source>failed</source> + <translation>fallito</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> + <source>pending</source> + <translation>in attesa</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3809"/> + <source>usage: unspent_outputs [<min_amount> <max_amount>]</source> + <translation>uso: unspent_outputs [<min_amount> <max_amount>]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3824"/> + <source><min_amount> should be smaller than <max_amount></source> + <translation><min_amount> dovrebbe essere più piccolo di <max_amount></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> + <source> +Amount: </source> + <translation>Ammontare: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> + <source>, number of keys: </source> + <translation>, numero di chiavi: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3861"/> + <source> </source> + <translation> </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3866"/> + <source> +Min block height: </source> + <translation>Altezza minima blocco: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3867"/> + <source> +Max block height: </source> + <translation>Altezza massima blocco: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3868"/> + <source> +Min amount found: </source> + <translation>Ammontare minimo trovato: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3869"/> + <source> +Max amount found: </source> + <translation>Ammontare massimo trovato: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3870"/> + <source> +Total count: </source> + <translation>Conto totale: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3910"/> + <source> +Bin size: </source> + <translation>Dimensione Bin</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3911"/> + <source> +Outputs per *: </source> + <translation></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3913"/> + <source>count + ^ +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3915"/> + <source> |</source> + <translation> |</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> + <source> +</source> + <translation> +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> + <source>+--> block height +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3918"/> + <source> ^</source> + <translation> ^</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3918"/> + <source>^ +</source> + <translation>^ +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3919"/> + <source> </source> + <translation> </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3969"/> + <source>wallet</source> + <translation>portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4000"/> + <source>Random payment ID: </source> + <translation>ID pagamento casuale: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4001"/> + <source>Matching integrated address: </source> + <translation>Indirizzo integrato corrispondente: </translation> + </message> +</context> +<context> + <name>sw</name> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="116"/> + <source>Generate new wallet and save it to <arg></source> + <translation>Genera un nuovo portafoglio e salvalo in <arg></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="117"/> + <source>Generate incoming-only wallet from view key</source> + <translation>Genera un portafoglio solo-ricezione da chiave per visualizzazione</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> + <source>Generate wallet from private keys</source> + <translation>Genera portafoglio da chiavi private</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="120"/> + <source>Specify Electrum seed for wallet recovery/creation</source> + <translation>Specifica il seme stile Electrum per recuperare/creare il portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> + <source>Recover wallet using Electrum-style mnemonic seed</source> + <translation>Recupera portafoglio usando il seme mnemonico stile-Electrum</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> + <source>Create non-deterministic view and spend keys</source> + <translation>Crea chiavi per visualizzione e chiavi spendibili non-deterministiche</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> + <source>Enable commands which rely on a trusted daemon</source> + <translation>Abilita comandi dipendenti da un daemon fidato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> + <source>Allow communicating with a daemon that uses a different RPC version</source> + <translation>Permetti comunicazioni con un daemon che usa una versione RPC differente</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> + <source>Restore from specific blockchain height</source> + <translation>Ripristina da specifico blocco</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> + <source>daemon is busy. Please try again later.</source> + <translation>il daemon è occupato. Prova più tardi.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="145"/> + <source>possibly lost connection to daemon</source> + <translation>possibile perdita di connessione con il daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="226"/> + <source>Error: </source> + <translation>Errore: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4614"/> + <source>Failed to initialize wallet</source> + <translation>Inizializzazione wallet fallita</translation> + </message> +</context> +<context> + <name>tools::dns_utils</name> + <message> + <location filename="../src/common/dns_utils.cpp" line="430"/> + <source>DNSSEC validation passed</source> + <translation>Convalida DNSSEC passata</translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="434"/> + <source>WARNING: DNSSEC validation was unsuccessful, this address may not be correct!</source> + <translation>AVVERTIMENTO: convalida DNSSEC fallita, questo indirizzo potrebbe non essere corretto!</translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="437"/> + <source>For URL: </source> + <translation>Per URL: </translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="439"/> + <source> Monero Address = </source> + <translation>Indirizzo Monero = </translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="441"/> + <source>Is this OK? (Y/n) </source> + <translation>Va bene? (S/n) </translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="451"/> + <source>you have cancelled the transfer request</source> + <translation>hai cancelliato la richiesta di transferimento</translation> + </message> +</context> +<context> + <name>tools::wallet2</name> + <message> + <location filename="../src/wallet/wallet2.cpp" line="106"/> + <source>Use daemon instance at <host>:<port></source> + <translation>Usa instanza daemon in <host>:<port></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="107"/> + <source>Use daemon instance at host <arg> instead of localhost</source> + <translation>Usa istanza daemon all'host <arg> invece che localhost</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="460"/> + <source>Wallet password</source> + <translation>Password portafoglio</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="109"/> + <source>Wallet password file</source> + <translation>File password portafoglio</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="110"/> + <source>Use daemon instance at port <arg> instead of 18081</source> + <translation>Usa istanza daemon alla porta <arg> invece che alla 18081</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="112"/> + <source>For testnet. Daemon must also be launched with --testnet flag</source> + <translation>Per testnet. Il Daemon può anche essere lanciato con la flag --testnet</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="113"/> + <source>Restricts to view-only commands</source> + <translation>Restringi i comandi a solo-vista</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="152"/> + <source>can't specify daemon host or port more than once</source> + <translation>non puoi specificare la porta o l'host del daemon più di una volta</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="188"/> + <source>can't specify more than one of --password and --password-file</source> + <translation>non puoi specificare più di un --password e --password-file</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="204"/> + <source>the password file specified could not be read</source> + <translation>il file password specificato non può essere letto</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="460"/> + <source>Enter new wallet password</source> + <translation>Inserisci una nuova password per il portafoglio</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="464"/> + <source>failed to read wallet password</source> + <translation>impossibile leggere password portafoglio</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="227"/> + <source>Failed to load file </source> + <translation>Impossibile caricare file </translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="108"/> + <source>Wallet password (escape/quote as needed)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="111"/> + <source>Specify username[:password] for daemon RPC client</source> + <translation>Specificare username[:password] per client del daemon RPC</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="233"/> + <source>Failed to parse JSON</source> + <translation>Impossibile analizzare (parse) JSON</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="240"/> + <source>Version %u too new, we can only grok up to %u</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="258"/> + <source>failed to parse view key secret key</source> + <translation>impossibile analizzare (parse) chiave per visualizzazione chiave segreta</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="264"/> + <location filename="../src/wallet/wallet2.cpp" line="331"/> + <location filename="../src/wallet/wallet2.cpp" line="373"/> + <source>failed to verify view key secret key</source> + <translation>impossibile verificare chiave per visualizzazione chiave segreta</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="276"/> + <source>failed to parse spend key secret key</source> + <translation>impossibile analizzare (parse) chiave spendibile chiave segreta</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="282"/> + <location filename="../src/wallet/wallet2.cpp" line="343"/> + <location filename="../src/wallet/wallet2.cpp" line="394"/> + <source>failed to verify spend key secret key</source> + <translation>impossibile verificare chiave spendibile chiave segreta</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="295"/> + <source>Electrum-style word list failed verification</source> + <translation>verifica lista di parole stile-Electrum fallita</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="306"/> + <source>At least one of Electrum-style word list and private view key must be specified</source> + <translation></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="311"/> + <source>Both Electrum-style word list and private key(s) specified</source> + <translation>Specificate entrambe lista parole stile-Electrum e chiave/i privata/e </translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="324"/> + <source>invalid address</source> + <translation>indirizzo invalido</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="335"/> + <source>view key does not match standard address</source> + <translation>la chiave per visualizzazione non corrisponde all'indirizzo standard</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="347"/> + <source>spend key does not match standard address</source> + <translation>la chiave spendibile non corrisponde all'indirizzo standard</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="356"/> + <source>Cannot create deprecated wallets from JSON</source> + <translation>Impossibile creare portafogli disapprovati da JSON</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="403"/> + <source>failed to generate new wallet: </source> + <translation>impossibile generare nuovo portafoglio: </translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="5205"/> + <source>failed to read file </source> + <translation>lettura file fallita</translation> + </message> +</context> +<context> + <name>tools::wallet_rpc_server</name> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="151"/> + <source>Daemon is local, assuming trusted</source> + <translation>Il daemon è locale, assunto per fidato</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="171"/> + <source>Cannot specify --</source> + <translation>Impossibile specificare --</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="171"/> + <source> and --</source> + <translation> e --</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="198"/> + <source>Failed to create file </source> + <translation>Impossibile creare file </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="198"/> + <source>. Check permissions or remove file</source> + <translation>. Controlla permessi o rimuovi il file</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="209"/> + <source>Error writing to file </source> + <translation>Errore durante scrittura su file </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="212"/> + <source>RPC username/password is stored in file </source> + <translation>Username/password RPC conservate nel file </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1748"/> + <source>Can't specify more than one of --wallet-file and --generate-from-json</source> + <translation>Non puoi specificare più di un --wallet-file e --generate-from-json</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1760"/> + <source>Must specify --wallet-file or --generate-from-json or --wallet-dir</source> + <translation>Devi specificare --wallet-file o --generate-from-json o --wallet-dir</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1764"/> + <source>Loading wallet...</source> + <translation>Caricando il portafoglio...</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1789"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1814"/> + <source>Storing wallet...</source> + <translation>Conservando il portafoglio...</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1791"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1816"/> + <source>Stored ok</source> + <translation>Conservato con successo</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1794"/> + <source>Loaded ok</source> + <translation>Caricato con successo</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1798"/> + <source>Wallet initialization failed: </source> + <translation>Inizializzazione portafoglio fallita: </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1805"/> + <source>Failed to initialize wallet rpc server</source> + <translation>Inizializzazione server rpc portafoglio fallita</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1809"/> + <source>Starting wallet rpc server</source> + <translation>Server RPC portafoglio in partenza</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1811"/> + <source>Stopped wallet rpc server</source> + <translation>Server RPC portafoglio arrestato</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1820"/> + <source>Failed to store wallet: </source> + <translation>Impossibile conservare portafoglio: </translation> + </message> +</context> +<context> + <name>wallet_args</name> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4580"/> + <source>Wallet options</source> + <translation>Opzioni portafoglio</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="59"/> + <source>Generate wallet from JSON format file</source> + <translation>Genera portafoglio da file JSON</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="63"/> + <source>Use wallet <arg></source> + <translation>Usa portafoglio <arg></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="87"/> + <source>Max number of threads to use for a parallel job</source> + <translation>Numero massimo di threads da utilizzare per un lavoro parallelo</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="88"/> + <source>Specify log file</source> + <translation>Specificare log file</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="89"/> + <source>Config file</source> + <translation>File configurazione</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="98"/> + <source>General options</source> + <translation>Opzioni generali</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="128"/> + <source>Can't find config file </source> + <translation>Impossibile trovare file configurazione </translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="172"/> + <source>Logging to: </source> + <translation>Loggando in: </translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="173"/> + <source>Logging to %s</source> + <translation>Loggando in %s</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="153"/> + <source>Usage:</source> + <translation>Uso:</translation> + </message> +</context> +</TS> diff --git a/utils/build_scripts/android32.Dockerfile b/utils/build_scripts/android32.Dockerfile new file mode 100644 index 000000000..da81b6435 --- /dev/null +++ b/utils/build_scripts/android32.Dockerfile @@ -0,0 +1,81 @@ +FROM debian:jessie + +RUN apt-get update && apt-get install -y unzip automake build-essential curl file pkg-config git python + +WORKDIR /opt/android +## INSTALL ANDROID SDK +RUN curl -s -O http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz \ + && tar --no-same-owner -xzf android-sdk_r24.4.1-linux.tgz \ + && rm -f android-sdk_r24.4.1-linux.tgz + +## INSTALL ANDROID NDK +ENV ANDROID_NDK_REVISION 14 +RUN curl -s -O https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \ + && unzip android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \ + && rm -f android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip + +ENV WORKDIR /opt/android +ENV ANDROID_SDK_ROOT ${WORKDIR}/android-sdk-linux +ENV ANDROID_NDK_ROOT ${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION} + +## INSTALL BOOST +ENV BOOST_VERSION 1_62_0 +ENV BOOST_VERSION_DOT 1.62.0 +RUN curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2/download \ + && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ + && rm -f /usr/boost_${BOOST_VERSION}.tar.bz2 \ + && cd boost_${BOOST_VERSION} \ + && ./bootstrap.sh + +ENV TOOLCHAIN_DIR ${WORKDIR}/toolchain-arm +RUN ${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py \ + --arch arm \ + --api 21 \ + --install-dir $TOOLCHAIN_DIR \ + --stl=libc++ +ENV PATH $TOOLCHAIN_DIR/arm-linux-androideabi/bin:$TOOLCHAIN_DIR/bin:$PATH + +## Build BOOST +RUN cd boost_${BOOST_VERSION} \ + && ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android32 --stagedir=android32 toolset=clang threading=multi threadapi=pthread target-os=android stage + +#INSTALL cmake (avoid 3.7 : https://github.com/android-ndk/ndk/issues/254) +ENV CMAKE_VERSION 3.6.3 +RUN cd /usr \ + && curl -s -O https://cmake.org/files/v3.6/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \ + && tar -xzf /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \ + && rm -f /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz +ENV PATH /usr/cmake-${CMAKE_VERSION}-Linux-x86_64/bin:$PATH + +#Note : we build openssl because the default lacks DSA1 + +# download, configure and make Zlib +ENV ZLIB_VERSION 1.2.11 +RUN curl -s -O http://zlib.net/zlib-${ZLIB_VERSION}.tar.gz \ + && tar -xzf zlib-${ZLIB_VERSION}.tar.gz \ + && rm zlib-${ZLIB_VERSION}.tar.gz \ + && mv zlib-${ZLIB_VERSION} zlib \ + && cd zlib && CC=clang CXX=clang++ ./configure --static \ + && make +# open ssl +ENV OPENSSL_VERSION 1.0.2j +RUN curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \ + && tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \ + && rm openssl-${OPENSSL_VERSION}.tar.gz \ + && cd openssl-${OPENSSL_VERSION} \ + && sed -i -e "s/mandroid/target\ armv7\-none\-linux\-androideabi/" Configure \ + && CC=clang CXX=clang++ \ + ./Configure android-armv7 \ + no-asm \ + no-shared --static \ + --with-zlib-include=${WORKDIR}/zlib/include --with-zlib-lib=${WORKDIR}/zlib/lib \ + && make build_crypto build_ssl \ + && cd .. && mv openssl-${OPENSSL_VERSION} openssl + +RUN git clone https://github.com/monero-project/monero.git \ + && cd monero \ + && mkdir -p build/release \ + && CC=clang CXX=clang++ \ + BOOST_ROOT=${WORKDIR}/boost_${BOOST_VERSION} BOOST_LIBRARYDIR=${WORKDIR}/boost_${BOOST_VERSION}/android32/lib/ \ + OPENSSL_ROOT_DIR=${WORKDIR}/openssl/ \ + make release-static-android diff --git a/utils/build_scripts/android64.Dockerfile b/utils/build_scripts/android64.Dockerfile new file mode 100644 index 000000000..5e6bc05af --- /dev/null +++ b/utils/build_scripts/android64.Dockerfile @@ -0,0 +1,83 @@ +FROM debian:jessie + +RUN apt-get update && apt-get install -y unzip automake build-essential curl file pkg-config git python + +WORKDIR /opt/android +## INSTALL ANDROID SDK +RUN curl -s -O http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz \ + && tar --no-same-owner -xzf android-sdk_r24.4.1-linux.tgz \ + && rm -f android-sdk_r24.4.1-linux.tgz + +## INSTALL ANDROID NDK +ENV ANDROID_NDK_REVISION 14 +RUN curl -s -O https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \ + && unzip android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \ + && rm -f android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip + +ENV WORKDIR /opt/android +ENV ANDROID_SDK_ROOT ${WORKDIR}/android-sdk-linux +ENV ANDROID_NDK_ROOT ${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION} + +## INSTALL BOOST +ENV BOOST_VERSION 1_62_0 +ENV BOOST_VERSION_DOT 1.62.0 +RUN curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2/download \ + && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ + && rm -f /usr/boost_${BOOST_VERSION}.tar.bz2 \ + && cd boost_${BOOST_VERSION} \ + && ./bootstrap.sh + +ENV TOOLCHAIN_DIR ${WORKDIR}/toolchain-arm +RUN ${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py \ + --arch arm64 \ + --api 21 \ + --install-dir $TOOLCHAIN_DIR \ + --stl=libc++ +ENV PATH $TOOLCHAIN_DIR/aarch64-linux-android/bin:$TOOLCHAIN_DIR/bin:$PATH + +## Build BOOST +RUN cd boost_${BOOST_VERSION} \ + && ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android64 --stagedir=android64 toolset=clang threading=multi threadapi=pthread target-os=android stage + +#INSTALL cmake (avoid 3.7 : https://github.com/android-ndk/ndk/issues/254) +ENV CMAKE_VERSION 3.6.3 +RUN cd /usr \ + && curl -s -O https://cmake.org/files/v3.6/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \ + && tar -xzf /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \ + && rm -f /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz +ENV PATH /usr/cmake-${CMAKE_VERSION}-Linux-x86_64/bin:$PATH + +#Note : we build openssl because the default lacks DSA1 + +# download, configure and make Zlib +ENV ZLIB_VERSION 1.2.11 +RUN curl -s -O http://zlib.net/zlib-${ZLIB_VERSION}.tar.gz \ + && tar -xzf zlib-${ZLIB_VERSION}.tar.gz \ + && rm zlib-${ZLIB_VERSION}.tar.gz \ + && mv zlib-${ZLIB_VERSION} zlib \ + && cd zlib && CC=clang CXX=clang++ ./configure --static \ + && make +# open ssl +ENV OPENSSL_VERSION 1.0.2j +RUN curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \ + && tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \ + && rm openssl-${OPENSSL_VERSION}.tar.gz \ + && cd openssl-${OPENSSL_VERSION} \ + && sed -i -e "s/mandroid/target\ aarch64\-none\-linux\-android/" Configure \ + && CC=clang CXX=clang++ \ + ./Configure android \ + no-asm \ + no-shared --static \ + --with-zlib-include=${WORKDIR}/zlib/include --with-zlib-lib=${WORKDIR}/zlib/lib \ + && make build_crypto build_ssl \ + && cd .. && mv openssl-${OPENSSL_VERSION} openssl + +RUN git clone https://github.com/monero-project/monero.git \ + && cd monero \ + && mkdir -p build/release \ + && cd build/release \ + && CC=clang CXX=clang++ \ + BOOST_ROOT=${WORKDIR}/boost_${BOOST_VERSION} BOOST_LIBRARYDIR=${WORKDIR}/boost_${BOOST_VERSION}/android64/lib/ \ + OPENSSL_ROOT_DIR=${WORKDIR}/openssl/ \ + cmake -D BUILD_TESTS=OFF -D ARCH="armv8-a" -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG="android" ../.. \ + && make -j3 diff --git a/utils/systemd/monerod.service b/utils/systemd/monerod.service index 182878ebb..12395eb8c 100644 --- a/utils/systemd/monerod.service +++ b/utils/systemd/monerod.service @@ -8,15 +8,10 @@ Group=monero WorkingDirectory=~ Type=forking -ExecStart=/usr/bin/monerod --config-file /etc/monerod.conf --detach +PIDFile=/var/run/monerod.pid -# This is necessary because monerod does not yet support -# writing a PID file, which means systemd tries to guess the PID -# by default, but it guesses wrong (sometimes, depending on -# random timing of events), because the daemon forks twice. -# The ultimate fix is for the daemon to write a PID file, and -# a workaround is to disable the guessing feature in systemd. -GuessMainPID=no +ExecStart=/usr/bin/monerod --config-file /etc/monerod.conf \ + --detach --pidfile /var/run/monerod.pid [Install] WantedBy=multi-user.target |